Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

оброботка сообщение при записи диска [D7, Win2k, WinXP]


menart ©   (2006-01-11 11:51:00) 

Можно ли как-то перехватить или проверить состояние привода когда он пишет диск или простаивает?
Заранее всем спасибо и с прошедшими праздниками!


menart   (2006-01-12 10:39:00) [1]

спасибо! Вечером попробую!


VirEx   (2006-01-11 19:50:00) [2]

забыл, надо в uses добавить mmsystem

а вот так можно узнать какие приводы сейчас есть:
procedure TForm1.Button3Click(Sender: TObject);
var
 i, mask : integer;
 s : string;
begin
//находим все устройства
mask := GetLogicalDrives;
i := 0;
while mask<>0 do begin
s:= chr( ord('a') + i ) + ':\';
if (mask and 1) <> 0 then
case GetDriveType(PChar(s)) of
 0               : Memo1.Lines.Add(s + ' unknown.');
 1               : Memo1.Lines.Add(s + ' not exist.');
 DRIVE_REMOVABLE : Memo1.Lines.Add(s + ' removable.'); // floppy,zip
 DRIVE_FIXED     : Memo1.Lines.Add(s + ' fixed.');
 DRIVE_REMOTE    : Memo1.Lines.Add(s + ' network.');
 DRIVE_CDROM     : Memo1.Lines.Add(s + ' CD-ROM.');
 DRIVE_RAMDISK   : Memo1.Lines.Add(s + ' RAM.');
end;
inc(i); mask := mask shr 1;
end;

end;


VirEx   (2006-01-11 19:47:00) [3]

блин, дык а что маяться, сделай таймер который будет проверять статус CDROM'а:
procedure TForm1.Button2Click(Sender: TObject);
var
o:MCI_OPEN_PARMS;
 s:MCI_STATUS_PARMS;
 
 i:Cardinal;
 str:PChar;
begin
GetMem(str,1024);

// тип устройства
o.lpstrDeviceType:='cdaudio';

//имя устройства в системе (в этом случае диск E:\)
o.lpstrElementName:='e';

i:=mciSendCommand(0,MCI_OPEN,MCI_OPEN_ELEMENT or MCI_OPEN_TYPE,LongInt(@o));
mciGetErrorString(i,PChar(str),1024);
memo1.Lines.Add(str);

//читаем состояние устройства
s.dwItem:=MCI_STATUS_MODE;
i:=mciSendCommand(o.wDeviceID,MCI_STATUS,MCI_STATUS_ITEM or MCI_WAIT ,LongInt(@s));
mciGetErrorString(i,PChar(str),1024);
memo1.Lines.Add(str);

i:=mciSendCommand(o.wDeviceID,MCI_CLOSE,0,0);
mciGetErrorString(i,PChar(str),1024);
memo1.Lines.Add(str);

FreeMem(str,1024);

//выводим в memo
case s.dwReturn of
MCI_MODE_NOT_READY: memo1.Lines.Add('NOT_READY');
MCI_MODE_PAUSE:     memo1.Lines.Add('PAUSE');
MCI_MODE_PLAY:      memo1.Lines.Add('PLAY');
MCI_MODE_STOP:      memo1.Lines.Add('STOP');
MCI_MODE_OPEN:      memo1.Lines.Add('OPEN');
MCI_MODE_RECORD:    memo1.Lines.Add('RECORD');
MCI_MODE_SEEK:      memo1.Lines.Add('SEEK');
end;

end;


VirEx   (2006-01-11 19:45:00) [4]

уф... это надо ведь всё вспоминать (у меня был диплом по созданию драйверов в Win):) вобщем вот такая штука:
программа может "общаться" с драйвером через DeviceIoControl, открыть драйвер можно через CreateFile(PChar('\\.\'+
вот пример:
//процедура распечатки ошибки
procedure PrintError;
var
 lpMsgBuf:PChar;
begin
// данная функция позволяет перевести ЛЮБОЙ номер ошибки в строку
FormatMessage(
   FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
   nil,
   GetLastError,   //номер ошибки
   0,              //Язык по умолчанию, можно записать как LANG_NEUTRAL and SUBLANG_DEFAULT
   @lpMsgBuf,      //буфер для записи строки ошибки
   0,              //размер для буфера (т.к. стоит флаг FORMAT_MESSAGE_ALLOCATE_BUFFER, то устанавливаем в 0)
   nil
);

//"добираемся" до объекта Memo через глобальный объект Form1,
//т.к. эта процедура не объявлена в форме Form1
Form1.Memo1.Lines.Add('error: '+lpMsgBuf);

// Освобождаем буфер сообщения
LocalFree( Cardinal(lpMsgBuf) );
end;

procedure TForm1.BtOpenDriverClick(Sender: TObject);
begin
//открытие драйвера
drv := CreateFile(PChar('\\.\'+EdDriverName.Text),      // имя драйвера
                   GENERIC_READ    or GENERIC_WRITE,   // тип доступа
                   FILE_SHARE_READ or FILE_SHARE_WRITE,// атрибуты доступа
                   nil,                                // опции безопасности
                   OPEN_EXISTING,                      // атрибуты открытия
                   FILE_ATTRIBUTE_NORMAL,              // атрибуты типа объекта
                   0);

if drv<>INVALID_HANDLE_VALUE then  // если десткиптор драйвера не ошибочный, то
 Memo1.Lines.Add('=== Driver Open === '+TimeToStr(Now));// добавляем в лог

end;

procedure TForm1.BtCloseDriverClick(Sender: TObject);
begin
//загрытие драйвера
if (drv>0) and (drv<>INVALID_HANDLE_VALUE) then begin
 CloseHandle(drv);//закрываем дескриптор
 Memo1.Lines.Add('=== Driver Close === '+TimeToStr(Now));
 end;

end;

procedure TForm1.BtSendCommandClick(Sender: TObject);
var
 InBuffer,OutBuffer  : array of byte;
 BytesReturned  : cardinal;
begin
//посылка пользовательского кода драйверу,
//если в драйвере не зарегистрирована функция обработки IOCTRL запросов
//(DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=MyCTRLFunction)
//то будет ошибка

//пользовательский код, обрабатываемый в драйвере,
//должна "знать" пользовательская программа, работающая с драйвером
//(или драйвер, также работающий с этим драйвером)
 DeviceIoControl( drv,
                  StrToInt(EdCommand.Text),//пользовательский код
                  InBuffer, sizeof(InBuffer),
                  OutBuffer, sizeof(OutBuffer),
                  BytesReturned,
                  nil );
 if GetLastError=NO_ERROR then begin
   memo1.Lines.Add('Send Command result: In='+PChar(@InBuffer)+' Out='+PChar(@OutBuffer));
   end else
   PrintError;
end;

procedure TForm1.BtReadClick(Sender: TObject);
var
 buffer:Pointer;    //буфер
 readcout:cardinal; //сколько в действительности прочитано байт
 len:cardinal;      //длина буфера
begin
GetMem(buffer,StrToInt(EdReadCount.Text));//выделяем память для буфера
len:=StrToInt(EdReadCount.Text);          //кол-во байт (размер буфера)

ReadFile(drv,buffer^,len,readcout,nil);   //драйверу посылается код IRP_MJ_READ
                                         //и он обрабатывает в соответствующей функции
                                         //зарегестрированной в DriverEntry
                                         //(DriverObject->MajorFunction[IRP_MJ_READ] = MyReadFunction)
if GetLastError=NO_ERROR then
 Memo1.Lines.Add('Read bytes cout='+IntToStr(readcout)+', bytes:'+PChar(buffer))
 else
 PrintError;
FreeMem(buffer);//очищаем буфер
end;

procedure TForm1.BtWriteClick(Sender: TObject);
var
 buffer:Pointer;    //буфер
 writtencout:cardinal; //сколько в действительности записано байт
 len:cardinal;      //длина буфера
begin
GetMem(buffer,StrToInt(EdReadCount.Text)); //выделяем память для буфера
len:=StrToInt(EdReadCount.Text);           //размер буфера = 1 байт
WriteFile(drv,buffer^,len,writtencout,nil);
if GetLastError=NO_ERROR then
 Memo1.Lines.Add('written bytes cout='+IntToStr(writtencout)+', bytes:'+PChar(@buffer))
 else
 PrintError;
FreeMem(buffer);//очищаем буфер
end;


menart   (2006-01-11 19:21:00) [5]


> VirEx ©   (11.01.06 19:11) [7]
>
> >  menart ©   (11.01.06 11:51)
>
> надо просто обслужавать сообщения файлового драйвера


С этого места места поподробнее можно? я просто профан в этом деле


VirEx   (2006-01-11 19:11:00) [6]


>  menart ©   (11.01.06 11:51)

надо просто обслужавать сообщения файлового драйвера


menart   (2006-01-11 18:12:00) [7]


> Игорь Шевченко ©   (11.01.06 17:55) [4]
> Пираты маст дай

Не обязательно :)
Это небольшая фотостудия по оцифровки видие и фото и записи на диск и копирование дисков (в том числе и дисков клиентов).

Все таки можно проверить как-то состояние диска, что он пишет или обробатывать сообщение что диск записан. Или какие могут быть идеи.
Просто я сам иногда пользуюсь его услугами и как бы хочется его отблагодарить ;)


Deka   (2006-01-11 18:01:00) [8]

Так тебе CD надо... Я думал хард. Наверное надо разораться как делается запись на CD и перехватить соотвествующие функции. А так как сессий записи на один диск теоретически может быть несколько, то надо еще учитывать выброс диска из привода. Думаю что так. А знакомому напечатай плакатик "Вас снимает скрытая камера!" и делов-то... ;)


Игорь Шевченко   (2006-01-11 17:55:00) [9]

Пираты маст дай


menart   (2006-01-11 17:42:00) [10]

Да нет... Меня один знакомый попросил утилитку сделать для кантроля за продавцами сколько дисков за день записали. Просто его продавцы люди хитрые и крадут деньги. :(


Deka   (2006-01-11 14:10:00) [11]

Это что-ли для программного индикатора занятости диска надо?


Игорь Шевченко   (2006-01-11 11:53:00) [12]

При записи диска сообщений не посылается. Да и кому их посылать ?


Наверх

Титульная страница Поиск, карта сайта Написать письмо