Привет всем! Разрабатываю программу для лечения USB-устройств, появились некоторые вопросы: Как из режима ядра определить что вставлено USB-устройство, аналог WM_DEVICECHANGE для ядра, и еще один вопрос, как можно получить управление первым, сразу как была вставлено USB-устройство? Спасибо.
Код (Text): NTSTATUS DiskPerfDispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: Dispatch for PNP Arguments: DeviceObject - Supplies the device object. Irp - Supplies the I/O request packet. Return Value: NTSTATUS --*/ { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status; PDEVICE_EXTENSION deviceExtension; PAGED_CODE(); DebugPrint((2, "DiskPerfDispatchPnp: Device %X Irp %X\n", DeviceObject, Irp)); switch(irpSp->MinorFunction) { case IRP_MN_START_DEVICE: // // Call the Start Routine handler to schedule a completion routine // DebugPrint((3, "DiskPerfDispatchPnp: Schedule completion for START_DEVICE")); status = DiskPerfStartDevice(DeviceObject, Irp); break; case IRP_MN_REMOVE_DEVICE: { // // Call the Remove Routine handler to schedule a completion routine // DebugPrint((3, "DiskPerfDispatchPnp: Schedule completion for REMOVE_DEVICE")); status = DiskPerfRemoveDevice(DeviceObject, Irp); break; } case IRP_MN_DEVICE_USAGE_NOTIFICATION: { PIO_STACK_LOCATION irpStack; ULONG count; BOOLEAN setPagable; DebugPrint((3, "DiskPerfDispatchPnp: Processing DEVICE_USAGE_NOTIFICATION")); irpStack = IoGetCurrentIrpStackLocation(Irp); if (irpStack->Parameters.UsageNotification.Type != DeviceUsageTypePaging) { status = DiskPerfSendToNextDriver(DeviceObject, Irp); break; // out of case statement } deviceExtension = DeviceObject->DeviceExtension; // // wait on the paging path event // status = KeWaitForSingleObject(&deviceExtension->PagingPathCountEvent, Executive, KernelMode, FALSE, NULL); // // if removing last paging device, need to set DO_POWER_PAGABLE // bit here, and possible re-set it below on failure. // setPagable = FALSE; if (!irpStack->Parameters.UsageNotification.InPath && deviceExtension->PagingPathCount == 1 ) { // // removing the last paging file // must have DO_POWER_PAGABLE bits set // if (DeviceObject->Flags & DO_POWER_INRUSH) { DebugPrint((3, "DiskPerfDispatchPnp: last paging file " "removed but DO_POWER_INRUSH set, so not " "setting PAGABLE bit " "for DO %p\n", DeviceObject)); } else { DebugPrint((2, "DiskPerfDispatchPnp: Setting PAGABLE " "bit for DO %p\n", DeviceObject)); DeviceObject->Flags |= DO_POWER_PAGABLE; setPagable = TRUE; } } // // send the irp synchronously // status = DiskPerfForwardIrpSynchronous(DeviceObject, Irp); // // now deal with the failure and success cases. // note that we are not allowed to fail the irp // once it is sent to the lower drivers. // if (NT_SUCCESS(status)) { IoAdjustPagingPathCount( &deviceExtension->PagingPathCount, irpStack->Parameters.UsageNotification.InPath); if (irpStack->Parameters.UsageNotification.InPath) { if (deviceExtension->PagingPathCount == 1) { // // first paging file addition // DebugPrint((3, "DiskPerfDispatchPnp: Clearing PAGABLE bit " "for DO %p\n", DeviceObject)); DeviceObject->Flags &= ~DO_POWER_PAGABLE; } } } else { // // cleanup the changes done above // if (setPagable == TRUE) { DeviceObject->Flags &= ~DO_POWER_PAGABLE; setPagable = FALSE; } } // // set the event so the next one can occur. // KeSetEvent(&deviceExtension->PagingPathCountEvent, IO_NO_INCREMENT, FALSE); // // and complete the irp // IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; break; } default: DebugPrint((3, "DiskPerfDispatchPnp: Forwarding irp")); // // Simply forward all other Irps // return DiskPerfSendToNextDriver(DeviceObject, Irp); } return status; } // end DiskPerfDispatchPnp()