?? d12xp.c
字號:
deviceExtension->PowerDownLevel = deviceExtension->DeviceCapabilities.DeviceWake;
if ( ( PowerDeviceD0 == deviceExtension->CurrentDevicePowerState ) ||
( deviceExtension->DeviceCapabilities.DeviceWake > deviceExtension->CurrentDevicePowerState ) ) {
// If a driver fails this IRP, it should complete the IRP immediately without
// passing the IRP to the next-lower driver.
ntStatus = STATUS_INVALID_DEVICE_STATE;
Irp->IoStatus.Status = ntStatus;
IoCompleteRequest (Irp,IO_NO_INCREMENT );
DbgPrint("Exit D12_ProcessPowerIrp(), ntStatus STATUS_INVALID_DEVICE_STATE\n" ) ;
D12_DecrementIoCount(DeviceObject);
return ntStatus;
}
// flag we're enabled for wakeup
deviceExtension->EnabledForWakeup = TRUE;
// init an event for our completion routine to signal when PDO is done with this Irp
KeInitializeEvent(&event, NotificationEvent, FALSE);
// If not failing outright, pass this on to our PDO for further handling
IoCopyCurrentIrpStackLocationToNext(Irp);
// Set a completion routine so it can signal our event when
// the PDO is done with the Irp
IoSetCompletionRoutine(Irp,
D12_IrpCompletionRoutine,
&event, // pass the event to the completion routine as the Context
TRUE, // invoke on success
TRUE, // invoke on error
TRUE); // invoke on cancellation
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
// if PDO is not done yet, wait for the event to be set in our completion routine
if (ntStatus == STATUS_PENDING) {
// wait for irp to complete
NTSTATUS waitStatus = KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL);
DbgPrint("D12_ProcessPowerIrp() done waiting for PDO to finish IRP_MN_WAIT_WAKE\n");
}
// now tell the device to actually wake up
D12_SelfSuspendOrActivate( DeviceObject, FALSE );
// flag we're done with wakeup irp
deviceExtension->EnabledForWakeup = FALSE;
D12_DecrementIoCount(DeviceObject);
DbgPrint("D12_ProcessPowerIrp() Exit IRP_MN_WAIT_WAKE\n");
break;
/* case IRP_MN_WAIT_WAKE:
D12_KdPrint(("D12TEST.SYS: IRP_MN_WAIT_WAKE\n"));
//
// someone is enabling us for wakeup
//
TRAP(); // never seen this before?
// pass this on to our PDO
break;*/
case IRP_MN_SET_POWER:
{
if(deviceExtension->PendingIoCount>0)
{
IoCopyCurrentIrpStackLocationToNext(Irp);
D12_KdPrint(("Test Point .....................\n"));
PoStartNextPowerIrp(Irp);
/* ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);*/
D12_DecrementIoCount(DeviceObject);
break;
}
else{
switch (irpStack->Parameters.Power.Type) {
case SystemPowerState:
//
// find the device power state equivalent to the given system state
//
{
POWER_STATE powerState;
D12_KdPrint(("D12TEST.SYS: Set Power, SystemPowerState (%d)\n",
irpStack->Parameters.Power.State.SystemState));
if (irpStack->Parameters.Power.State.SystemState ==
PowerSystemWorking) {
powerState.DeviceState = PowerDeviceD0;
} else if (/* deviceExtension->EnabledForWakeup*/FALSE) {
// BUGBUG for now act as if we are always enabled for wakeup
D12_KdPrint(("D12TEST.SYS: D12 always enabled for wakeup\n"));
powerState.DeviceState =
deviceExtension->DeviceCapabilities.DeviceState[
irpStack->Parameters.Power.State.SystemState];
} else {
//
// wakeup not enabled, just go in to the 'OFF' state.
//
powerState.DeviceState = PowerDeviceD3;
} //irpStack->Parameters.Power.State.SystemState
//
// are we already in this state?
//
if (powerState.DeviceState !=
deviceExtension->CurrentDevicePowerState) {
// No,
// request that we be put into this state
deviceExtension->PowerIrp = Irp;
ntStatus = PoRequestPowerIrp(deviceExtension->PhysicalDeviceObject,
IRP_MN_SET_POWER,
powerState,
D12_PoRequestCompletion,
DeviceObject,
NULL);
} else {
// Yes,
// just pass it on
IoCopyCurrentIrpStackLocationToNext(Irp);
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
}
}
break;
case DevicePowerState:
ntStatus = D12_SetDevicePowerState(DeviceObject,
irpStack->Parameters.Power.State.DeviceState,
&hookIt);
IoCopyCurrentIrpStackLocationToNext(Irp);
if (hookIt) {
D12_KdPrint(("D12TEST.SYS: Set PowerIrp Completion Routine\n"));
IoSetCompletionRoutine(Irp,
D12_PowerIrp_Complete,
// always pass FDO to completion routine
DeviceObject,
hookIt,
hookIt,
hookIt);
}
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
break;
} /* case irpStack->Parameters.Power.Type */
}
}
break; /* IRP_MN_SET_POWER */
case IRP_MN_QUERY_POWER:
D12_KdPrint(("D12TEST.SYS: IRP_MN_QUERY_POWER\n"));
IoCopyCurrentIrpStackLocationToNext(Irp);
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
break; /* IRP_MN_QUERY_POWER */
default:
D12_KdPrint(("D12TEST.SYS: UNKNOWN POWER MESSAGE (%x)\n", irpStack->MinorFunction));
//
// All unahndled PnP messages are passed on to the PDO
//
IoCopyCurrentIrpStackLocationToNext(Irp);
//
// All PNP_POWER POWER messages get passed to
// TopOfStackDeviceObject and some are handled in the completion routine
//
// pass on to our PDO
PoStartNextPowerIrp(Irp);
ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
} /* irpStack->MinorFunction */
return ntStatus;
}
NTSTATUS
D12_Dispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Process the IRPs sent to this device.
Arguments:
DeviceObject - pointer to a device object
Irp - pointer to an I/O Request Packet
Return Value:
--*/
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT stackDeviceObject;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation (Irp);
//
// Get a pointer to the device extension
//
deviceExtension = DeviceObject->DeviceExtension;
stackDeviceObject = deviceExtension->TopOfStackDeviceObject;
D12_IncrementIoCount(DeviceObject);
switch (irpStack->MajorFunction) {
case IRP_MJ_SYSTEM_CONTROL:
D12_KdPrint (("D12TEST.SYS: IRP_MJ_SYSTEM_CONTROL\n"));
IoCopyCurrentIrpStackLocationToNext(Irp);
D12_KdPrint (("D12TEST.SYS: Passing SysCtrl Irp down\n"));
D12_DecrementIoCount(DeviceObject);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
goto D12_Dispatch_Done;
break;
case IRP_MJ_PNP:
D12_KdPrint (("D12TEST.SYS: IRP_MJ_PNP\n"));
switch (irpStack->MinorFunction) {
case IRP_MN_START_DEVICE:
{
KEVENT event;
D12_KdPrint (("D12TEST.SYS: IRP_MN_START_DEVICE\n"));
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
D12_DeferIrpCompletion,
&event,
TRUE,
TRUE,
TRUE);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
if (ntStatus == STATUS_PENDING) {
// wait for irp to complete
TRAP(); // first time we hit this
KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL);
}
ntStatus = D12_StartDevice(DeviceObject);
Irp->IoStatus.Status = ntStatus;
goto D12_Dispatch_CompleteRequest;
}
break;
case IRP_MN_STOP_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_STOP_DEVICE\n"));
ntStatus = D12_StopDevice(DeviceObject);
break;
case IRP_MN_REMOVE_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_REMOVE_DEVICE\n"));
// match the inc at the begining of the dispatch
// routine
D12_DecrementIoCount(DeviceObject);
//
// ounce this flag is set no irps will be pased
// down the stack to lower drivers
//
deviceExtension->AcceptingRequests = FALSE;
if (deviceExtension->UserEvent != NULL) {
KeSetEvent(deviceExtension->UserEvent,
1,
FALSE);
}
if (NT_SUCCESS(ntStatus)) {
LONG pendingIoCount;
IoCopyCurrentIrpStackLocationToNext(Irp);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
//
// final decrement will trigger the remove
//
pendingIoCount = D12_DecrementIoCount(DeviceObject);
{
NTSTATUS status;
// wait for any io request pending in our driver to
// complete for finishing the remove
status = KeWaitForSingleObject(
&deviceExtension->RemoveEvent,
Suspended,
KernelMode,
FALSE,
NULL);
// TRAP();
}
//
// Delete the link and FDO we created
//
D12_RemoveDevice(DeviceObject);
D12_KdPrint (("D12TEST.SYS: Detaching from %08X\n",
deviceExtension->TopOfStackDeviceObject));
IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
D12_KdPrint (("D12TEST.SYS: Deleting %08X\n",
DeviceObject));
IoDeleteDevice (DeviceObject);
goto D12_Dispatch_Done;
}
break;
case IRP_MN_QUERY_STOP_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_QUERY_STOP_DEVICE\n"));
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_QUERY_REMOVE_DEVICE\n"));
break;
case IRP_MN_CANCEL_STOP_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_CANCEL_STOP_DEVICE\n"));
break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
D12_KdPrint (("D12TEST.SYS: IRP_MN_CANCEL_REMOVE_DEVICE\n"));
break;
default:
D12_KdPrint (("D12TEST.SYS: PnP IOCTL not handled\n"));
} /* case MinorFunction, MajorFunction == IRP_MJ_PNP_POWER */
if (!NT_SUCCESS(ntStatus)) {
Irp->IoStatus.Status = ntStatus;
goto D12_Dispatch_CompleteRequest;
}
IoCopyCurrentIrpStackLocationToNext(Irp);
//
// All PNP_POWER messages get passed to the TopOfStackDeviceObject
// we were given in PnPAddDevice
//
D12_KdPrint (("D12TEST.SYS: Passing PnP Irp down, status = %x\n", ntStatus));
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
D12_DecrementIoCount(DeviceObject);
goto D12_Dispatch_Done;
break; // IRP_MJ_PNP
default:
D12_KdPrint (("D12TEST.SYS: MAJOR IOCTL not handled\n"));
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
} /* case MajorFunction */
ntStatus = Irp->IoStatus.Status;
D12_Dispatch_CompleteRequest:
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
D12_DecrementIoCount(DeviceObject);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -