📄 usbfx2lk_pnp.cpp
字号:
//
// Return our allocated resources...
//
OsrReturnResources(devExt);
//
// Indicate that we've successfully processed the IRP,
// since we can't fail it anyway (our hardware is GONE,
// what would failing this Irp mean??)...
//
Irp->IoStatus.Status = STATUS_SUCCESS;
//
// Don't wait for the Irp to finish, don't set a completion
// routine and don't complete the Irp! Just foist it off to the
// PDO and propogate the returned status
//
IoSkipCurrentIrpStackLocation(Irp);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO,
("OsrPnp: Finished! Leaving with state %s\n",
OsrPrintState(devExt)));
status = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);
//
// We're done with this request
//
OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
return status;
}
//
// STATE: REMOVE_PENDING or STATE_NEVER_STARTED
// IRP_MN: _REMOVE
//
// We're here if we've received an IRP_MN_REMOVE_DEVICE IRP
// after receiving a QUERY_REMOVE or if our Start Device
// failed. This is the preferred, "everything is going dandy"
// route for being removed.
//
case (STATE_NEVER_STARTED + IRP_MN_REMOVE_DEVICE):
case (STATE_REMOVE_PENDING + IRP_MN_REMOVE_DEVICE): {
//
// We handle this request before the bus driver
//
//
// We're removed...
//
OsrUpdateDeviceState(devExt, STATE_REMOVED);
//
// Deregister with WMI.
//
status = UsbFx2LkWmiDeRegistration(devExt);
if (!NT_SUCCESS(status)) {
//
// Eh, big deal. Just print out some info and
// keep going...
//
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO,
("OsrPnp: UsbFx2LkWmiDeRegistration failed! Returned status 0x%8.8x (%s)\n",
status, OsrNtStatusToString(status)));
}
//
// Tell the thread that we have out there to terminate itself
//
KeSetEvent(&devExt->SSSubmissionThreadTerminateEvent,
EVENT_INCREMENT, FALSE);
//
// And wait for the thread to terminate
//
(VOID)OsrWaitForSingleObject(devExt->SSSubmissionThreadObject);
//
// Close the HANDLE that we opened to the thread
//
ZwClose(devExt->SSSubmissionThread);
//
// And drop our reference to the object
//
ObDereferenceObject(devExt->SSSubmissionThreadObject);
//
// We need to cancel our outstanding wait wake operation if there
// is one
//
if(devExt->WaitWakeEnable) {
CancelWaitWake(devExt);
}
//
// Because we registered a device interface we need to disable
// it now...
//
status = IoSetDeviceInterfaceState(&devExt->InterfaceName,
FALSE);
if (!NT_SUCCESS(status)) {
//
// Eh, big deal. Just print out some info and
// keep going...
//
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO,
("OsrPnp: IoSetDeviceInterfaceState failed! Returned status 0x%8.8x (%s)\n",
status, OsrNtStatusToString(status)));
}
//
// Delete the Interface Name that was allocated for us
//
if(devExt->InterfaceName.Buffer) {
RtlFreeUnicodeString(&devExt->InterfaceName);
}
//
// Fail any queued I/O requests...
//
OsrClearQueues(devExt);
//
// Return our hardware resources...
//
OsrReturnResources(devExt);
//
// Note that the OutStandingIoCount has to be
// decremented here to account for the
//
OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
//
// Release our lock.and wait for any in progress I/O to finish...
//
OsrDecrementOutstandingIoCountAndWait(devExt);
//
// A remove constitutes a power down, we change
// our internal power state and notify the Power manager.
//
devExt->DevicePowerState = PowerDeviceD3;
powerState.DeviceState = PowerDeviceD3;
PoSetPowerState(DeviceObject, DevicePowerState, powerState);
//
// Indicate that we've successfully processed the IRP
//
Irp->IoStatus.Status = STATUS_SUCCESS;
//
// Don't wait for the Irp to finish, don't set a completion
// routine and don't complete the Irp! Just foist it off to the
// PDO and propogate the returned status
//
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);
//
// Detach from the device below us. Since it never hurts
// to point out the obvious...Make sure this is done
// AFTER the call to IoCallDriver!
//
IoDetachDevice(devExt->DeviceToSendIrpsTo);
//
// Cleanup Tracing for W2k
//
#ifdef WPP_TRACING
#ifdef W2K
W2KCleanupWPPTracing(devExt->FunctionalDeviceObject);
#endif // W2K
#endif // WPP_TRACING
//
// Return our device object
//
IoDeleteDevice(devExt->FunctionalDeviceObject);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO,
("OsrPnp: Finished! Leaving with state %s\n",
OsrPrintState(devExt)));
return status;
}
//
// STATE: SURPRISE_REMOVED
// IRP_MN: _REMOVE_DEVICE
//
// We're here because we've previously received notification
// of a "surprise" removal.
//
case (STATE_SURPRISE_REMOVED + IRP_MN_REMOVE_DEVICE): {
//
// If we were surprise removed, all I/O has been
// finished, our symbolic link has been deleted,
// our interface disabled and our resources
// returned so we don't need to do it again here...
//
//
// Deregister with WMI.
//
status = UsbFx2LkWmiDeRegistration(devExt);
if (!NT_SUCCESS(status)) {
//
// Eh, big deal. Just print out some info and
// keep going...
//
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO,
("OsrPnp: UsbFx2LkWmiDeRegistration failed! Returned status 0x%8.8x (%s)\n",
status, OsrNtStatusToString(status)));
}
//
// We're removed...
//
OsrUpdateDeviceState(devExt, STATE_REMOVED);
//
// A remove constitutes a power down, we change
// our internal power state and notify the Power manager.
//
devExt->DevicePowerState = PowerDeviceD3;
powerState.DeviceState = PowerDeviceD3;
PoSetPowerState(DeviceObject, DevicePowerState, powerState);
//
// The only Irps outstanding are going to be power, PnP, clean up, or
// close Irps. All I/O Irps between the _SURPRISE_REMOVAL and
// REMOVE_DEVICE have been failed (good thing cause our hardware is
// gone...)
//
//
// Note that the OutStandingIoCount has to be
// decremented here to account for the OsrIncrementOutstandingIoCount call
// at the beginning of the routine.
//
OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
//
// Release our lock.and wait for any in progress I/O to finish...
//
OsrDecrementOutstandingIoCountAndWait(devExt);
//
// Indicate that we've successfully processed the IRP
//
Irp->IoStatus.Status = STATUS_SUCCESS;
//
// Don't wait for the Irp to finish, don't set a completion
// routine and don't complete the Irp! Just foist it off to the
// PDO and propogate the returned status
//
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->DeviceToSendIrpsTo, Irp);
//
// Detach from the device below us. Since it never hurts
// to point out the obvious...Make sure this is done
// AFTER the call to IoCallDriver!
//
IoDetachDevice(devExt->DeviceToSendIrpsTo);
//
// Return our device object
//
IoDeleteDevice(devExt->FunctionalDeviceObject);
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO,
("OsrPnp: Finished! Leaving with state %s\n",
OsrPrintState(devExt)));
return status;
}
//
// STATE: STARTED
// IRP_MN: _QUERY_CAPABILITIES
//
// We're here if we're running and the PnP Manager or another
// driver sends us a QUERY_CAPABILITIES request. This will
// happen once the device is enumerated and again once all
// drivers for the device have started. A driver can also
// send this request to get the capabilities for the device.
//
// To proess this QUERY_CAPABILITIES, we just copy the system
// to device power mappings that we'll need for power management
// because we're the power policy owner for the stack. See
// the power management code in POWER.CPP to find out
// what the heck I'm talking about...
//
case (STATE_STARTED + IRP_MN_QUERY_CAPABILITIES): {
PDEVICE_CAPABILITIES deviceCaps;
//
// This is a BUS FIRST Irp.
//
status = OsrForwardIrpSynchronous(devExt,Irp);
if (NT_SUCCESS(status)) {
//
// Get a copy of all of the pnp/power capabilities of
// our device
//
deviceCaps = ioStack->Parameters.DeviceCapabilities.Capabilities;
RtlCopyMemory(&devExt->DeviceCapabilities, deviceCaps,
sizeof(DEVICE_CAPABILITIES));
PrintDeviceCapabilities(&devExt->DeviceCapabilities,(PUCHAR) "Received Device Capabilities");
//
// Copy over the array of system power state to
// device power state mappings...
//
OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_PNP_INFO,
("OsrPnp: Copying the System power state to Device power state mappings...\n"));
RtlCopyMemory(devExt->SystemToDevicePowerMappings,
deviceCaps->DeviceState,
sizeof(DEVICE_POWER_STATE) * PowerSystemMaximum);
//
// Iterate over all of the mappings and determine the lowest
// power state that our device supports. We will store this
// away and use it to determine which power state to lower
// our device to when doing selective suspend
//
for(ULONG i = PowerSystemSleeping1; i <= PowerSystemSleeping3; i++) {
if(devExt->DeviceCapabilities.DeviceState[i] < PowerDeviceD3) {
devExt->PowerDownLevel =
devExt->DeviceCapabilities.DeviceState[i];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -