![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
оброботка сообщение при записи диска [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]При записи диска сообщений не посылается. Да и кому их посылать ?