Здравствуйте ServerMouse, Вы писали:
SM>Люди, покажите ошибку! Я просто хочу скидывать в лог-файл сообщения. SM>W2k намертво синеет при виде вот такого кода: SM>
SM>// Ну и конечно же это kernel-mode, ring0 и всё такое....
SM>#define DEFAULT_LOG_FILE_NAME L"\\??\\C:\\tmp\\drv.log"
SM>BOOLEAN LogMessage(PCHAR szFormat, ...)
SM>{
SM> ULONG Length;
SM> char messagebuf[256];
SM> va_list va;
SM> IO_STATUS_BLOCK IoStatus;
SM> OBJECT_ATTRIBUTES objectAttributes;
SM> NTSTATUS status;
SM> HANDLE FileHandle;
SM> UNICODE_STRING fileName;
SM> //format the string
SM> va_start(va,szFormat);
SM> vsprintf(messagebuf,szFormat,va);
SM> va_end(va);
SM> //get a handle to the log file object
SM> fileName.Buffer = NULL;
SM> fileName.Length = 0;
SM> fileName.MaximumLength = sizeof(DEFAULT_LOG_FILE_NAME) + sizeof(UNICODE_NULL);
SM> fileName.Buffer = ExAllocatePool(PagedPool,
SM> fileName.MaximumLength);
SM> if (!fileName.Buffer) return FALSE;
SM>
SM> RtlZeroMemory(fileName.Buffer, fileName.MaximumLength);
SM> status = RtlAppendUnicodeToString(&fileName, (PWSTR)DEFAULT_LOG_FILE_NAME);
SM>
SM> InitializeObjectAttributes (&objectAttributes,
SM> (PUNICODE_STRING)&fileName,
SM> OBJ_CASE_INSENSITIVE,
SM> NULL,
SM> NULL );
SM> status = ZwCreateFile(&FileHandle,
SM> FILE_APPEND_DATA,
SM> &objectAttributes,
SM> &IoStatus,
SM> 0,
SM> FILE_ATTRIBUTE_NORMAL,
SM> FILE_SHARE_WRITE,
SM> FILE_OPEN_IF,
SM> FILE_SYNCHRONOUS_IO_NONALERT,
SM> NULL,
SM> 0 );
SM> if(NT_SUCCESS(status))
SM> {
SM> CHAR buf[300];
SM> LARGE_INTEGER time;
SM> KeQuerySystemTime(&time);
SM> //put a time stamp on the output message
SM> sprintf(buf,"%10u-%10u %s",time.HighPart,time.LowPart,messagebuf);
SM> //format the string to make sure it appends a newline carrage-return to the
SM> //end of the string.
SM> Length=strlen(buf);
SM> if(buf[Length-1]=='\n')
SM> {
SM> buf[Length-1]='\r';
SM> strcat(buf,"\n");
SM> Length++;
SM> }
SM> else
SM> {
SM> strcat(buf,"\r\n");
SM> Length+=2;
SM> }
SM> ZwWriteFile(FileHandle,
SM> NULL,
SM> NULL,
SM> NULL,
SM> &IoStatus,
SM> buf,
SM> Length,
SM> NULL,
SM> NULL );
SM> ZwClose(FileHandle);
SM> }
SM> if (fileName.Buffer)
SM> ExFreePool (fileName.Buffer);
SM> return STATUS_SUCCESS;
SM>}
SM>
SM>И вызываю эту ф-цию вот так: SM>
LogMessage("TEST")
SM>
Хоть бы текст ошибки вывел (с экрана).
IRQL_NOT_LESS_OR_EQUAL скорее всего.
Ну и порно... RtlInitUnicodeString(&fileName,DEFAULT_LOG_FILE_NAME).
или прямо руками
fileName.Buffer = DEFAULT_LOG_FILE_NAME;
fileName.Length = wcslen(DEFAULT_LOG_FILE_NAME)*sizeof(WCHAR);
fileName.MaximumLength = fileName.Length +sizeof(WCHAR);
и DEFAULT_LOG_FILE_NAME опиши не через define, а как WCHAR DEFAULT_LOG_FILE_NAME[] = L"\\Device\\HarddiskVolume1\\...";
Здравствуйте vasketsov, Вы писали:
V>Здравствуйте ServerMouse, Вы писали:
SM>>Да, и ошибка-то: IRQL_NOT_LESS_OR_EQUAL.
V>Значится так.
V>1)
SM>> fileName.Buffer = NULL; SM>> fileName.Length = 0; SM>> fileName.MaximumLength = sizeof(DEFAULT_LOG_FILE_NAME) + sizeof(UNICODE_NULL); SM>> fileName.Buffer = ExAllocatePool(PagedPool, SM>> fileName.MaximumLength); SM>> if (!fileName.Buffer) return FALSE; SM>> SM>> RtlZeroMemory(fileName.Buffer, fileName.MaximumLength); SM>> status = RtlAppendUnicodeToString(&fileName, (PWSTR)DEFAULT_LOG_FILE_NAME);
V>Ну и порно... RtlInitUnicodeString(&fileName,DEFAULT_LOG_FILE_NAME). V>или прямо руками V>fileName.Buffer = DEFAULT_LOG_FILE_NAME; V>fileName.Length = wcslen(DEFAULT_LOG_FILE_NAME)*sizeof(WCHAR); V>fileName.MaximumLength = fileName.Length +sizeof(WCHAR); V>и DEFAULT_LOG_FILE_NAME опиши не через define, а как WCHAR DEFAULT_LOG_FILE_NAME[] = L"\\Device\\HarddiskVolume1\\...";
Ну это вообщем-то я из NTDDK\src\ выдрал. Мой начальный код был куда короче и лаконичней.
А ошибку-то я понял. Это код фильтра клавиатуры. И запись в лог я пытался делать из обработчика IRQ клавы. А так низя-низя-низя! Сейчас работает примерно так:
NTSTATUS CtrlDispatchRead(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp )
{
//............
RetStatus=IoCallDriver( devExt->TopOfStack, Irp );
LogMessage("Key %x\n",ch);
return RetStatus;
}
V>3) у тебя IRQL PASSIVE_LEVEL ?
А что это? Я просто сегодня первый день как за драйверы сел, так что не бейте сильно ногами...
Мне надо драйвером блокировать/разблокировать клавиатуру и мышь.
Люди, ещё посоветуйте как лучше наладить связь с программой из User-mode?
Здравствуйте ServerMouse, Вы писали:
V>>3) у тебя IRQL PASSIVE_LEVEL ?
SM>А что это? Я просто сегодня первый день как за драйверы сел, так что не бейте сильно ногами...
Ну, вобщем-то видно что первый день, только без обид, ладно?
Вообще про это в DDK есть, советую поставить, раз пишешь "дровишки". Внизу описания каждой функции есть ремарка, на каком уровне ее вызывать можно.
SM>Мне надо драйвером блокировать/разблокировать клавиатуру и мышь.
Да хоть коврик сворачивать, это тут пофигу. Главное — на правильном IRQL функции вызывать.
SM>Люди, ещё посоветуйте как лучше наладить связь с программой из User-mode?
IOCTL.
Здравствуйте ServerMouse, Вы писали:
SM>Здравствуйте vasketsov, Вы писали:
SM>>>Люди, ещё посоветуйте как лучше наладить связь с программой из User-mode? V>>IOCTL.
SM>Скажите пжалста, а где можно почитать про эту штуку, лучше на С. SM>Вообщем буду благодарен за ссылку и/или пример.
Я бы посоветовал установить 2000DDK + иметь примеры из NTDDK.
В случае чего, искать на www.filesearch.ru, поиском по строке ddk, размер больше 40 мегов поставить.
А примеры — их море просто, любой драйвер, с прогой взаимодействющий, с исходниками бери и изучай, с sysinternals.com слей regmon и filemon, разберешься — будешь крут
Вот заколбасил я на стороне драйвера обработчик вызовов IRP_MJ_DEVICE_CONTROL.
А вот как из API до него добраться, непонимаю.
Вот так вот драйвер инициализируется:
IoCreateDevice( DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_KEYBOARD,
0,
FALSE,
&device );
//.....
IoAttachDevice( device,
L"\\Device\\KeyboardClass0",
//На самом деле здесь PUNICODE_STRING, но так короче и нагляднее.
&devExt->TopOfStack );
SM>Вот и получаю INVALID_HANDLE_VALUE. А как правильно?
Это потому что Win32 Environment Subsytem добавит к имени "\??\", поэтому в нативную NtCreateFile будет передано неверное имя устройства. Надо создать для устройства symbolic link в ветке "\??\", сделать это можно или из драйвера — IoCreateSymbolicLink, или из приложения — DefineDosDevice
SM>>Вот и получаю INVALID_HANDLE_VALUE. А как правильно?
V>Это потому что Win32 Environment Subsytem добавит к имени "\??\", поэтому в нативную NtCreateFile будет передано неверное имя устройства. Надо создать для устройства symbolic link в ветке "\??\", сделать это можно или из драйвера — IoCreateSymbolicLink, или из приложения — DefineDosDevice
Здравствуйте Vovkos, Вы писали:
V>Это потому что Win32 Environment Subsytem добавит к имени "\??\", поэтому в нативную NtCreateFile будет передано неверное имя устройства. Надо создать для устройства symbolic link в ветке "\??\", сделать это можно или из драйвера — IoCreateSymbolicLink, или из приложения — DefineDosDevice
Ну блин, незнаю. Замучился совсем. Люди, помогите, никак не могу разобраться, в чём ошибка. Вот инициализация в драйвере (новая версия):
Обработку ошибок я опустил. Если что-то не так, драйвер завершает работу, а он гад работает, всё зашибись, но достучаться через IOCTL никак не получается! А стучусь я вот так:
Здравствуйте vasketsov, Вы писали:
V>Здравствуйте ServerMouse, Вы писали:
SM>>RtlInitUnicodeString(&ntDevName,L"KEY_LOCKER"); V>не может быть такого имени девайса. \\??\\ забыл.
Заменил. Результат тот-же. INVALID_HANDLE_VALUE. Я плакалъ.
Здравствуйте ServerMouse, Вы писали:
SM>Здравствуйте vasketsov, Вы писали:
V>>Здравствуйте ServerMouse, Вы писали:
SM>>>RtlInitUnicodeString(&ntDevName,L"KEY_LOCKER"); V>>не может быть такого имени девайса. \\??\\ забыл.
SM>Заменил. Результат тот-же. INVALID_HANDLE_VALUE. Я плакалъ.