📄 driverentry.cpp
字号:
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
PoStartNextPowerIrp(Irp); // must be done while we own the IRP
NTSTATUS status;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
IoSkipCurrentIrpStackLocation(Irp);
status = PoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
} // DispatchPower
///////////////////////////////////////////////////////////////////////////////
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchPnp
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
ULONG fcn = stack->MinorFunction;
NTSTATUS status;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
#if DBG
KdPrint((DRIVERNAME " - IRP_MJ_PNP (%s)\n", pnpname[fcn]));
BOOLEAN backend = FALSE;
if (fcn == IRP_MN_START_DEVICE)
{
ReportAssignedResources(stack->Parameters.StartDevice.AllocatedResources,
stack->Parameters.StartDevice.AllocatedResourcesTranslated);
}
else if (fcn == IRP_MN_FILTER_RESOURCE_REQUIREMENTS)
{
PIO_RESOURCE_REQUIREMENTS_LIST list = (PIO_RESOURCE_REQUIREMENTS_LIST) Irp->IoStatus.Information;
if (!list)
list = stack->Parameters.FilterResourceRequirements.IoResourceRequirementList;
ReportRequiredResources(list);
backend = TRUE;
}
else if (fcn == IRP_MN_QUERY_RESOURCE_REQUIREMENTS || fcn == IRP_MN_QUERY_RESOURCES)
backend = TRUE;
// Install a completion routine for diagnostic purposes. Note that using a completion
// routine is not something that filter drivers necessarily have to do here -- I'm
// only doing it so this driver can print some interesting information about
// resource requirements
if (backend)
{ // pass down with completion routine
ASSERT(fcn != IRP_MN_REMOVE_DEVICE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnPnpComplete, (PVOID) pdx, TRUE, TRUE, TRUE);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
} // pass down with completion routine
else
{ // pass down without completion routine
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (fcn == IRP_MN_REMOVE_DEVICE)
{
IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
RemoveDevice(fido);
}
else
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
} // pass down without completion routine
#else // not DBG
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (fcn == IRP_MN_REMOVE_DEVICE)
{
IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
RemoveDevice(fido);
}
else
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
#endif // not DBG
} // DispatchPnp
///////////////////////////////////////////////////////////////////////////////
NTSTATUS DispatchWmi(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchWmi
#if DBG
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
ULONG fcn = stack->MinorFunction;
static char* fcnname[] = {
"IRP_MN_QUERY_ALL_DATA",
"IRP_MN_QUERY_SINGLE_INSTANCE",
"IRP_MN_CHANGE_SINGLE_INSTANCE",
"IRP_MN_CHANGE_SINGLE_ITEM",
"IRP_MN_ENABLE_EVENTS",
"IRP_MN_DISABLE_EVENTS",
"IRP_MN_ENABLE_COLLECTION",
"IRP_MN_DISABLE_COLLECTION",
"IRP_MN_REGINFO",
"IRP_MN_EXECUTE_METHOD",
};
KdPrint((DRIVERNAME " - IRP_MJ_SYSTEM_CONTROL (%s)\n", fcnname[fcn]));
#endif // DBG
NTSTATUS status;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
} // DispatchWmi
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID RemoveDevice(IN PDEVICE_OBJECT fido)
{ // RemoveDevice
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
NTSTATUS status;
if (pdx->LowerDeviceObject)
IoDetachDevice(pdx->LowerDeviceObject);
IoDeleteDevice(fido);
} // RemoveDevice
///////////////////////////////////////////////////////////////////////////////
#pragma INITCODE
BOOLEAN IsWin98()
{ // IsWin98
#ifdef _X86_
return !IoIsWdmVersionAvailable(1, 0x10);
#else // not _X86_
return FALSE;
#endif // not _X86_
} // IsWin98
#if DBG
///////////////////////////////////////////////////////////////////////////////
#ifdef _X86_
#pragma LOCKEDCODE
extern "C" void __declspec(naked) __cdecl _chkesp()
{
_asm je okay
ASSERT(!DRIVERNAME " - Stack pointer mismatch!");
okay:
_asm ret
}
#endif // _X86_
///////////////////////////////////////////////////////////////////////////////
NTSTATUS OnPnpComplete(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx)
{ // OnPnpComplete
if (Irp->PendingReturned)
IoMarkIrpPending(Irp);
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
ULONG fcn = stack->MinorFunction;
DbgPrint(DRIVERNAME " - IRP_MN_PNP (%s) complete\n", pnpname[fcn]);
switch (fcn)
{ // select on subfunction
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
ReportRequiredResources((PIO_RESOURCE_REQUIREMENTS_LIST) Irp->IoStatus.Information);
break;
case IRP_MN_QUERY_RESOURCES:
ReportAssignedResources((PCM_RESOURCE_LIST) Irp->IoStatus.Information, NULL);
break;
} // select on subfunction
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return STATUS_SUCCESS;
} // OnPnpComplete
///////////////////////////////////////////////////////////////////////////////
VOID ReportAssignedResources(PCM_RESOURCE_LIST raw, PCM_RESOURCE_LIST translated)
{ // ReportAssignedResources
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
return; // resource lists are in paged memory
if (raw)
{ // show untranslated resources
DbgPrint(DRIVERNAME " - Resources:\n");
ShowResources(&raw->List[0].PartialResourceList);
} // show untranslated resources
if (translated)
{ // show translated resources
DbgPrint(DRIVERNAME " - Translated Resources:\n");
ShowResources(&translated->List[0].PartialResourceList);
} // show translated resources
} // ReportAssignedResources
///////////////////////////////////////////////////////////////////////////////
VOID ReportRequiredResources(PIO_RESOURCE_REQUIREMENTS_LIST list)
{ // ReportRequiredResources
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
return; // resource lists are in paged memory
if (!list)
return; // nothing to do
ULONG numlists = list->AlternativeLists;
PIO_RESOURCE_LIST reslist = list->List;
while (numlists--)
{ // for each list
DbgPrint(" Requirements list:\n");
PIO_RESOURCE_DESCRIPTOR resource = reslist->Descriptors;
ULONG nres = reslist->Count;
for (; nres; --nres, ++resource)
{ // for each resource
ULONG type = resource->Type;
DbgPrint(" Type %s", type < arraysize(restypes) ? restypes[type] : "unknown");
switch (type)
{ // switch on resource type
case CmResourceTypePort:
case CmResourceTypeMemory:
DbgPrint(" Length %d, Alignment %X, MinimumAddress %8X%8.8lX, MaximumAddress %8X%8.8lX\n",
resource->u.Port.Length, resource->u.Port.Alignment,
resource->u.Port.MinimumAddress, resource->u.Port.MaximumAddress);
break;
case CmResourceTypeInterrupt:
DbgPrint(" MinimumVector %X, MaximumVector %X, shared %d\n",
resource->u.Interrupt.MinimumVector, resource->u.Interrupt.MaximumVector,
resource->ShareDisposition == CmResourceShareShared);
break;
case CmResourceTypeDma:
DbgPrint(" MinimumChannel %d, MaximumChannel %d\n",
resource->u.Dma.MinimumChannel, resource->u.Dma.MaximumChannel);
break;
default:
DbgPrint(" %X %X %X\n", resource->u.DevicePrivate.Data[0],
resource->u.DevicePrivate.Data[1], resource->u.DevicePrivate.Data[2]);
break;
} // switch on resource type
} // for each resource
reslist = (PIO_RESOURCE_LIST) resource;
} // for each list
} // ReportRequiredResources
///////////////////////////////////////////////////////////////////////////////
VOID ShowResources(IN PCM_PARTIAL_RESOURCE_LIST list)
{ // ShowResources
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = list->PartialDescriptors;
ULONG nres = list->Count;
ULONG i;
for (i = 0; i < nres; ++i, ++resource)
{ // for each resource
ULONG type = resource->Type;
KdPrint((" Type %s", type < arraysize(restypes) ? restypes[type] : "unknown"));
switch (type)
{ // select on resource type
case CmResourceTypePort:
case CmResourceTypeMemory:
KdPrint((" start %8X%8.8lX length %X\n",
resource->u.Port.Start.HighPart, resource->u.Port.Start.LowPart,
resource->u.Port.Length));
break;
case CmResourceTypeInterrupt:
KdPrint((" level %X, vector %X, affinity %X, shared %d\n",
resource->u.Interrupt.Level, resource->u.Interrupt.Vector,
resource->u.Interrupt.Affinity, resource->ShareDisposition == CmResourceShareShared));
break;
case CmResourceTypeDma:
KdPrint((" channel %d, port %X\n",
resource->u.Dma.Channel, resource->u.Dma.Port));
break;
default:
KdPrint(("\n"));
break;
} // select on resource type
} // for each resource
} // ShowResources
#endif // DBG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -