📄 testpnp.c
字号:
KeSetEvent ((PKEVENT) Context, 1, FALSE);
// No special priority
// No Wait
return STATUS_MORE_PROCESSING_REQUIRED; // Keep this IRP
}
// ==================================================================
NTSTATUS
Test98_PnPRemove (
PDEVICE_OBJECT Device,
PPDO_DEVICE_DATA PdoData
)
/*++
The PnP manager has instructed that this driver should be removed.
We should therefore complete any requests queued in the driver
and IoDeleteDevice. and Return from the dispatch routine.
--*/
{
PdoData->Removed = TRUE;
//
// Complete any outsanding requests with STATUS_DELETE_PENDING.
//
if (PdoData->Attached) {
return STATUS_SUCCESS;
}
//
// Free any resources.
//
ExFreePool (PdoData->HardwareIDs);
Test98_KdPrint(PdoData, TEST_DBG_PNP_INFO,
("IoDeleteDevice2: 0x%x\n", Device));
IoDeleteDevice (Device);
return STATUS_SUCCESS;
}
// ==================================================================
NTSTATUS
Test98_StartFdo (
IN PFDO_DEVICE_DATA FdoData,
IN PCM_PARTIAL_RESOURCE_LIST PartialResourceList,
IN PCM_PARTIAL_RESOURCE_LIST PartialResourceListTranslated
)
/*
starting our FDO...
*/
{
ULONG i;
NTSTATUS status = STATUS_SUCCESS;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resourceTrans;
Test98_KdPrint (FdoData, TEST_DBG_PNP_TRACE, ("StartFdo\n"));
for (i = 0,
resource = &PartialResourceList->PartialDescriptors[0],
resourceTrans = &PartialResourceListTranslated->PartialDescriptors[0];
i < PartialResourceList->Count && NT_SUCCESS(status);
i++, resource++, resourceTrans++) {
switch (resource->Type) {
case CmResourceTypePort:
FdoData->PhysicalAddress = resource->u.Port.Start;
Test98_KdPrint (FdoData, TEST_DBG_PNP_INFO,
("HardwareResource: Port (%x) ->",
FdoData->PhysicalAddress.LowPart));
switch (resourceTrans->Type) {
case CmResourceTypePort:
ASSERT (1 == resourceTrans->u.Port.Length);
// Nothing to do here but note the address;
FdoData->TestPortAddress =
(PVOID) resourceTrans->u.Port.Start.LowPart;
break;
case CmResourceTypeMemory:
//
// We need to map the memory
//
ASSERT (1 == resourceTrans->u.Memory.Length);
FdoData->TestPortAddress =
MmMapIoSpace (resourceTrans->u.Memory.Start,
resourceTrans->u.Memory.Length,
MmNonCached);
FdoData->MappedPorts = TRUE;
Test98_KdPrint_Cont (FdoData, TEST_DBG_PNP_INFO,
("Mem: (%x)\n", FdoData->TestPortAddress));
break;
default:
Test98_KdPrint_Cont (FdoData, TEST_DBG_PNP_INFO,
("Unknown \n", FdoData->TestPortAddress));
}
break;
case CmResourceTypeMemory:
ASSERT (CmResourceTypeMemory == resourceTrans->Type);
FdoData->PhysicalAddress = resource->u.Memory.Start;
FdoData->TestPortAddress =
MmMapIoSpace (resourceTrans->u.Memory.Start,
resourceTrans->u.Memory.Length,
MmNonCached);
FdoData->MappedPorts = TRUE;
ASSERT (1 == resource->u.Memory.Length);
Test98_KdPrint (FdoData, TEST_DBG_PNP_INFO,
("HardwareResource: Memory (%x) -> Mem (%x)",
FdoData->PhysicalAddress.LowPart,
FdoData->TestPortAddress));
break;
case CmResourceTypeInterrupt:
default:
Test98_KdPrint (FdoData, TEST_DBG_PNP_ERROR,
("Unhandled resource type (0x%x)\n",
resource->Type));
status = STATUS_UNSUCCESSFUL;
}
}
return status;
}
// ==================================================================
NTSTATUS
Test98_Remove (
PTEST98_REMOVE_HARDWARE Remove,
PFDO_DEVICE_DATA FdoData
)
/*
to remove the FDO and then tell Plug and Play about it.
*/
{
KIRQL irql;
PLIST_ENTRY entry;
PPDO_DEVICE_DATA pdoData;
BOOLEAN found = FALSE;
PVOID handle = NULL;
KeAcquireSpinLock (&FdoData->Spin, &irql);
for (entry = FdoData->PDOs.Flink;
entry != &FdoData->PDOs;
entry = entry->Flink) {
pdoData = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link);
if (!handle) {
handle = pdoData->Self;
}
if (handle == Remove->HardwareHandle) {
pdoData->Attached = FALSE;
RemoveEntryList (&pdoData->Link);
FdoData->NumPDOs--;
found = TRUE;
}
}
KeReleaseSpinLock (&FdoData->Spin, irql);
if (found) {
IoInvalidateDeviceRelations (FdoData->UnderlyingPDO, BusRelations);
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
}
// ==================================================================
NTSTATUS
Test98_Power (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*
We do nothing special for power;
*/
{
PIO_STACK_LOCATION irpStack;
NTSTATUS status;
PCOMMON_DEVICE_DATA commonData;
PAGED_CODE ();
status = STATUS_SUCCESS;
irpStack = IoGetCurrentIrpStackLocation (Irp);
ASSERT (IRP_MJ_POWER == irpStack->MajorFunction);
commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
status = Test98_FDO_Power ((PFDO_DEVICE_DATA) DeviceObject->DeviceExtension,
Irp);
return status;
}
// ==================================================================
NTSTATUS
Test98_PowerComplete (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
// ==================================================================
NTSTATUS
Test98_FDO_Power (
PFDO_DEVICE_DATA Data,
PIRP Irp
)
{
NTSTATUS status;
BOOLEAN hookit = FALSE;
POWER_STATE powerState;
POWER_STATE_TYPE powerType;
PIO_STACK_LOCATION stack;
stack = IoGetCurrentIrpStackLocation (Irp);
powerType = stack->Parameters.Power.Type;
powerState = stack->Parameters.Power.State;
PAGED_CODE ();
status = Test98_IncIoCount (Data);
if (!NT_SUCCESS (status)) {
PoStartNextPowerIrp (Irp);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
switch (stack->MinorFunction) {
case IRP_MN_SET_POWER:
Test98_KdPrint(Data,
TEST_DBG_PNP_TRACE,
("Test-PnP Setting %s state to %d\n",
((powerType == SystemPowerState) ? "System" : "Device"),
powerState.SystemState));
switch (powerType) {
case DevicePowerState:
status = Irp->IoStatus.Status = STATUS_SUCCESS;
if (Data->DeviceState == powerState.DeviceState) {
break;
} else if (Data->DeviceState < powerState.DeviceState) {
//
// Powering down
//
PoSetPowerState (Data->Self, powerType, powerState);
Data->DeviceState = powerState.DeviceState;
} else {
//
// Powering Up
//
hookit = TRUE;
}
break;
case SystemPowerState:
if (Data->PowerQueryLock) {
//
// The reception of a power irp resolves the query lock.
//
Data->PowerQueryLock = FALSE;
} else {
ASSERT (Data->SystemState != powerState.SystemState);
}
status = Irp->IoStatus.Status = STATUS_SUCCESS;
if (Data->SystemState == powerState.SystemState) {
break;
} else if (Data->SystemState < powerState.SystemState) {
//
// Powering down
//
Data->SystemState = powerState.SystemState;
powerState.DeviceState = PowerDeviceD3;
PoRequestPowerIrp (Data->Self,
IRP_MN_SET_POWER,
powerState,
NULL, // no completion function
NULL, // and no context
NULL);
} else {
//
// Powering Up
//
hookit = TRUE;
}
break;
}
break;
case IRP_MN_QUERY_POWER:
//
Data->PowerQueryLock = TRUE;
status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
default:
break;
}
IoCopyCurrentIrpStackLocationToNext (Irp);
if (hookit) {
status = Test98_IncIoCount (Data);
ASSERT (STATUS_SUCCESS == status);
IoSetCompletionRoutine (Irp,
Test98_PowerComplete,
NULL,
TRUE,
TRUE,
TRUE);
status = PoCallDriver (Data->TopOfStack, Irp);
} else {
//
// Power IRPS come synchronously; drivers must call
// PoStartNextPowerIrp, when they are ready for the next power
// irp. This can be called here, or in the completion routine
//
PoStartNextPowerIrp (Irp);
status = PoCallDriver (Data->TopOfStack, Irp);
}
Test98_DecIoCount (Data);
return status;
}
// ==================================================================
NTSTATUS
Test98_PowerComplete (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
POWER_STATE powerState;
POWER_STATE_TYPE powerType;
PIO_STACK_LOCATION stack;
PFDO_DEVICE_DATA data;
UNREFERENCED_PARAMETER (Context);
data = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;
stack = IoGetCurrentIrpStackLocation (Irp);
powerType = stack->Parameters.Power.Type;
powerState = stack->Parameters.Power.State;
switch (stack->MinorFunction) {
case IRP_MN_SET_POWER:
switch (powerType) {
case DevicePowerState:
ASSERT (powerState.DeviceState < data->DeviceState);
data->DeviceState = powerState.DeviceState;
PoSetPowerState (data->Self, powerType, powerState);
break;
case SystemPowerState:
//
// the work of requesting the Device Power IRP on
// behalf of the SystemPower Irp is work done by the FDO
//
ASSERT (powerState.SystemState < data->SystemState);
data->SystemState = powerState.SystemState;
powerState.DeviceState = PowerDeviceD0;
PoRequestPowerIrp (data->Self,
IRP_MN_SET_POWER,
powerState,
NULL, // no completion function
NULL, // and no context
NULL);
break;
}
break;
case IRP_MN_QUERY_POWER:
ASSERT (IRP_MN_QUERY_POWER != stack->MinorFunction);
break;
default:
ASSERT (0xBADBAD == IRP_MN_QUERY_POWER);
break;
}
PoStartNextPowerIrp (Irp);
Test98_DecIoCount (data);
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -