есть два драйвера. При загрузке первый создает устройство \Device\MyObject1. Вот код: Код (Text): NTSTATUS CreateMainDevice(IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING device_name; ANSI_STRING Ansidevice_name; UNICODE_STRING device_link; ANSI_STRING Ansidevice_link; NTSTATUS status; PDEVICE_OBJECT device_object; PMYDEVICE_EXTENSION device_extension; HANDLE thread_handle; RtlInitAnsiString( &Ansidevice_name, NTDEVICE_STRING); RtlAnsiStringToUnicodeString( &device_name, &Ansidevice_name, TRUE); RtlInitAnsiString( &Ansidevice_link, LINKNAME_STRING); RtlAnsiStringToUnicodeString( &device_link, &Ansidevice_link, TRUE); status = IoCreateDevice( DriverObject, sizeof(MYDEVICE_EXTENSION), &device_name, FILE_DEVICE_UNKNOWN, 0, FALSE, &device_object ); if (!NT_SUCCESS(status)) { return status; } status = IoCreateSymbolicLink( &device_link, &device_name ); if (!NT_SUCCESS(status) ) { IoDeleteDevice(device_object); return status; } device_object->Flags |= DO_DIRECT_IO; device_object->Flags &= ~DO_DEVICE_INITIALIZING; device_extension = (PMYDEVICE_EXTENSION) device_object->DeviceExtension; InitializeListHead(&device_extension->list_head); KeInitializeSpinLock(&device_extension->list_lock); KeInitializeEvent( &device_extension->request_event, SynchronizationEvent, FALSE ); device_extension->terminate_thread = FALSE; status = PsCreateSystemThread( &thread_handle, (ACCESS_MASK) 0L, NULL, NULL, NULL, FileDiskThread, device_object ); if (!NT_SUCCESS(status)) { IoDeleteSymbolicLink( &device_link ); IoDeleteDevice(device_object); return status; } status = ObReferenceObjectByHandle( thread_handle, THREAD_ALL_ACCESS, NULL, KernelMode, &device_extension->thread_pointer, NULL ); if (!NT_SUCCESS(status)) { ZwClose(thread_handle); device_extension->terminate_thread = TRUE; KeSetEvent( &device_extension->request_event, (KPRIORITY) 0, FALSE ); IoDeleteSymbolicLink( &device_link ); IoDeleteDevice(device_object); return status; } ZwClose(thread_handle); return status; } Второй, также при загрузке, пытается открыть это устройство. Вот код: Код (Text): VOID OpenDevice ( IN PUCHAR Buffer, IN ACCESS_MASK AccessMask, IN ULONG ShareAccess, OUT HANDLE *handle ) { UNICODE_STRING ufile_name; ANSI_STRING AnsiString; NTSTATUS status = STATUS_SUCCESS; IO_STATUS_BLOCK FileStatus; OBJECT_ATTRIBUTES object_attributes; RtlInitAnsiString( &AnsiString, Buffer); RtlAnsiStringToUnicodeString( &ufile_name, &AnsiString, TRUE); InitializeObjectAttributes( &object_attributes, &ufile_name, OBJ_CASE_INSENSITIVE, NULL, NULL ); status = ZwOpenFile( handle, AccessMask, &object_attributes, &FileStatus, ShareAccess, FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_NO_INTERMEDIATE_BUFFERING | FILE_SYNCHRONOUS_IO_NONALERT ); RtlFreeUnicodeString( &ufile_name ); if (!NT_SUCCESS(status)) { *handle = NULL; return; } return; } Но система зависает! Да, система - Windows Vista 32bit. Стоит мне закомментировать ZwOpenFile и все работает! Иначе - зависает! Подскажите, в чем кривость моих рук? Спасибо!
В DriverEntry Код (Text): for (ulIndex = 0, dispatch = DriverObject->MajorFunction; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++, dispatch++) { *dispatch = DiskPerfFilterProc; } Функция-обработчик всех IRP Код (Text): NTSTATUS DiskPerfFilterProc( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PMYDEVICE_EXTENSION MydeviceExtension = DeviceObject->DeviceExtension; IoMarkIrpPending(Irp); ExInterlockedInsertTailList( &(MydeviceExtension->list_head), &(Irp->Tail.Overlay.ListEntry), &(MydeviceExtension->list_lock) ); KeSetEvent( &(MydeviceExtension->request_event), (KPRIORITY) 0, FALSE ); return STATUS_PENDING; } Ну и собственно обработка в отдельном потоке Код (Text): VOID FileDiskThread ( IN PVOID Context ) { PDEVICE_OBJECT device_object; PMYDEVICE_EXTENSION device_extension; PIRP irp; PIO_STACK_LOCATION io_stack; NTSTATUS status; ASSERT(Context != NULL); device_object = (PDEVICE_OBJECT) Context; device_extension = (PMYDEVICE_EXTENSION) device_object->DeviceExtension; for (;;) { KeWaitForSingleObject( &device_extension->request_event, Executive, KernelMode, FALSE, NULL ); if (device_extension->terminate_thread) { PsTerminateSystemThread(STATUS_SUCCESS); } while (request = ExInterlockedRemoveHeadList( &device_extension->list_head, &device_extension->list_lock )) { irp = CONTAINING_RECORD(request, IRP, Tail.Overlay.ListEntry); io_stack = IoGetCurrentIrpStackLocation(irp); irp->IoStatus.Status = STATUS_SUCCESS; switch (io_stack->MajorFunction) { case IRP_MJ_WRITE: DebugPrint((2, "DiskFilter: I am successful WRITE!!!\n")); irp->IoStatus.Status = STATUS_SUCCESS; break; case IRP_MJ_CREATE: case IRP_MJ_CLOSE: DebugPrint((2, "DiskFilter: I am successful opened!!!\n")); irp->IoStatus.Status = STATUS_SUCCESS; irp->IoStatus.Information = FILE_OPENED; break; default: irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR; } IoCompleteRequest( irp, IO_NO_INCREMENT ); } // End of while }//End ForEver }
Во-первых, все эти флаги в ZwOpenFile() обычно не нужны при открытии собственных девайсов неизвестного типа: Во-вторых, если ты указываешь флаг FILE_SYNCHRONOUS_IO_NONALERT, то маска доступа должна содержать флаг SYNCHRONIZE. Вообще, было бы неплохо уточнить, как и когда вызывается функция OpenDevice(). В-третьих, ты уверен, что поток действительно работает и занимается выборкой запросов? Я бы поставил здесь побольше отладочных сообщений и убедился, что запрос на открытие действительно завершается вызовом IoCompleteRequest(). Особых проблем в коде не вижу, за исключением мелких недочётов типа этих: 1. Забыл последнее break; в ветке default: в switch. 2. Зачем перегонять строки из ANSI в Unicode, вообще не понятно. Обычно используют сразу Unicode.