📄 pnputils.c
字号:
DD(NULL,DDT,"Searching List i=%d for an IRQ, curList= %x\n", i,curList);
{
ULONG remain = curList->Count;
PIO_RESOURCE_DESCRIPTOR curDesc = curList->Descriptors;
BOOLEAN foundIrq = FALSE;
while( remain ) {
DD(NULL,DDT," curDesc= %x , remain=%d\n", curDesc, remain);
if(curDesc->Type == CmResourceTypeInterrupt) {
DD(NULL,DDT," Found IRQ - skip to next list\n");
foundIrq = TRUE;
break;
}
++curDesc;
--remain;
}
if( foundIrq == FALSE ) {
//
// We found a resource list that does not contain an IRQ resource.
// Our search is over.
//
DD(NULL,DDT," Found a list with NO IRQ - return TRUE from PptPnpFilterExistsNonIrqResourceList\n");
return TRUE;
}
}
//
// The next list starts immediately after the last descriptor of the current list.
//
curList = (PIO_RESOURCE_LIST)(curList->Descriptors + curList->Count);
++i;
}
//
// All resource alternatives contain at least one IRQ resource descriptor.
//
DD(NULL,DDT,"all lists contain IRQs - return FALSE from PptPnpFilterExistsNonIrqResourceList\n");
return FALSE;
}
VOID
PptPnpFilterRemoveIrqResourceLists(
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
)
/*++dvdf8
Routine Description:
This function is a helper function called by
PptPnpFilterResourceRequirements().
This function removes all resource alternatives (IO_RESOURCE_LISTs)
that contain IRQ resources from the IO_RESOURCE_REQUIREMENTS_LIST
Arguments:
ResourceRequirementsList - The list to process.
Return Value:
none.
--*/
{
ULONG listCount = ResourceRequirementsList->AlternativeLists;
PIO_RESOURCE_LIST curList;
PIO_RESOURCE_LIST nextList;
ULONG i;
PCHAR currentEndOfResourceRequirementsList;
LONG bytesToMove;
DD(NULL,DDT,"Enter PptPnpFilterRemoveIrqResourceLists() - AlternativeLists= %d\n", listCount);
//
// We use the end of the list to compute the size of the memory
// block to move when we remove a resource alternative from the
// list of lists.
//
currentEndOfResourceRequirementsList = PptPnpFilterGetEndOfResourceRequirementsList(ResourceRequirementsList);
i=0;
curList = ResourceRequirementsList->List;
//
// Walk through the IO_RESOURCE_LISTs.
//
while( i < listCount ) {
if( PptPnpListContainsIrqResourceDescriptor(curList) ) {
//
// The current list contains IRQ, remove it by shifting the
// remaining lists into its place and decrementing the list count.
//
DD(NULL,DDT,"list contains an IRQ - Removing List\n");
//
// Get a pointer to the start of the next list.
//
nextList = (PIO_RESOURCE_LIST)(curList->Descriptors + curList->Count);
//
// compute the number of bytes to move
//
bytesToMove = (LONG)(currentEndOfResourceRequirementsList - (PCHAR)nextList);
//
// if (currentEndOfResourceRequirementsList == next list),
// then this is the last list so there is nothing to move.
//
if( bytesToMove > 0 ) {
//
// More lists remain - shift them into the hole.
//
RtlMoveMemory(curList, nextList, bytesToMove);
//
// Adjust the pointer to the end of of the
// IO_RESOURCE_REQUIREMENTS_LIST (list of lists) due to the shift.
//
currentEndOfResourceRequirementsList -= ( (PCHAR)nextList - (PCHAR)curList );
}
//
// Note that we removed an IO_RESOURCE_LIST from the IO_RESOURCE_REQUIREMENTS_LIST.
//
--listCount;
} else {
//
// The current list does not contain an IRQ resource, advance to next list.
//
DD(NULL,DDT,"list does not contain an IRQ - i=%d listCount=%d curList= %#x\n", i,listCount,curList);
curList = (PIO_RESOURCE_LIST)(curList->Descriptors + curList->Count);
++i;
}
}
//
// Note the post filtered list count in the ResourceRequirementsList.
//
ResourceRequirementsList->AlternativeLists = listCount;
DD(NULL,DDT,"Leave PptPnpFilterRemoveIrqResourceLists() - AlternativeLists= %d\n", listCount);
return;
}
PVOID
PptPnpFilterGetEndOfResourceRequirementsList(
IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
)
/*++dvdf8
Routine Description:
This function is a helper function called by PptPnpFilterRemoveIrqResourceLists()
This function finds the end of an IO_RESOURCE_REQUIREMENTS_LIST
(list of IO_RESOURCE_LISTs).
Arguments:
ResourceRequirementsList - The list to scan.
Return Value:
Pointer to the next address past the end of the IO_RESOURCE_REQUIREMENTS_LIST.
--*/
{
ULONG listCount = ResourceRequirementsList->AlternativeLists;
PIO_RESOURCE_LIST curList;
ULONG i;
i=0;
curList = ResourceRequirementsList->List;
while( i < listCount ) {
//
// Pointer arithmetic based on the size of an IO_RESOURCE_DESCRIPTOR.
//
curList = (PIO_RESOURCE_LIST)(curList->Descriptors + curList->Count);
++i;
}
return (PVOID)curList;
}
VOID
PptPnpFilterNukeIrqResourceDescriptorsFromAllLists(
PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
)
/*++dvdf8
Routine Description:
This function is a helper function called by
PptPnpFilterResourceRequirements().
This function "nukes" all IRQ resources descriptors
in the IO_RESOURCE_REQUIREMENTS_LIST by changing the descriptor
types from CmResourceTypeInterrupt to CmResourceTypeNull.
Arguments:
ResourceRequirementsList - The list to process.
Return Value:
none.
--*/
{
ULONG listCount = ResourceRequirementsList->AlternativeLists;
ULONG i = 0;
PIO_RESOURCE_LIST curList = ResourceRequirementsList->List;
DD(NULL,DDT,"Enter PptPnpFilterNukeIrqResourceDescriptorsFromAllLists() - AlternativeLists= %d\n", listCount);
//
// Walk through the list of IO_RESOURCE_LISTs in the IO_RESOURCE_REQUIREMENTS list.
//
while( i < listCount ) {
DD(NULL,DDT,"Nuking IRQs from List i=%d, curList= %x\n", i,curList);
//
// Nuke all IRQ resources from the current IO_RESOURCE_LIST.
//
PptPnpFilterNukeIrqResourceDescriptors( curList );
curList = (PIO_RESOURCE_LIST)(curList->Descriptors + curList->Count);
++i;
}
}
VOID
PptPnpFilterNukeIrqResourceDescriptors(
PIO_RESOURCE_LIST IoResourceList
)
/*++dvdf8
Routine Description:
This function is a helper function called by
PptPnpFilterNukeIrqResourceDescriptorsFromAllLists().
This function "nukes" all IRQ resources descriptors
in the IO_RESOURCE_LIST by changing the descriptor
types from CmResourceTypeInterrupt to CmResourceTypeNull.
Arguments:
IoResourceList - The list to process.
Return Value:
none.
--*/
{
PIO_RESOURCE_DESCRIPTOR pIoResourceDescriptorIn = IoResourceList->Descriptors;
ULONG i;
//
// Scan the descriptor list for Interrupt descriptors.
//
for (i = 0; i < IoResourceList->Count; ++i) {
if (pIoResourceDescriptorIn->Type == CmResourceTypeInterrupt) {
//
// Found one - change resource type from Interrupt to Null.
//
pIoResourceDescriptorIn->Type = CmResourceTypeNull;
DD(NULL,DDT," - giving up IRQ resource - MinimumVector: %d MaximumVector: %d\n",
pIoResourceDescriptorIn->u.Interrupt.MinimumVector,
pIoResourceDescriptorIn->u.Interrupt.MaximumVector);
}
++pIoResourceDescriptorIn;
}
}
BOOLEAN
PptPnpListContainsIrqResourceDescriptor(
IN PIO_RESOURCE_LIST List
)
{
ULONG i;
PIO_RESOURCE_DESCRIPTOR curDesc = List->Descriptors;
for(i=0; i<List->Count; ++i) {
if(curDesc->Type == CmResourceTypeInterrupt) {
return TRUE;
} else {
++curDesc;
}
}
return FALSE;
}
NTSTATUS
PptPnpBounceAndCatchPnpIrp(
PFDO_EXTENSION Fdx,
PIRP Irp
)
/*++
Pass a PnP IRP down the stack to our parent and catch it on the way back
up after it has been handled by the drivers below us in the driver stack.
--*/
{
NTSTATUS status;
KEVENT event;
PDEVICE_OBJECT parentDevObj = Fdx->ParentDeviceObject;
DD((PCE)Fdx,DDT,"PptBounceAndCatchPnpIrp()\n");
// setup
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, PptSynchCompletionRoutine, &event, TRUE, TRUE, TRUE);
// send
status = IoCallDriver(parentDevObj, Irp);
// wait for completion routine to signal that it has caught the IRP on
// its way back out
KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
if (status == STATUS_PENDING) {
// If IoCallDriver returned STATUS_PENDING, then we must
// extract the "real" status from the IRP
status = Irp->IoStatus.Status;
}
return status;
}
NTSTATUS
PptPnpPassThroughPnpIrpAndReleaseRemoveLock(
IN PFDO_EXTENSION Fdx,
IN PIRP Irp
)
/*++
Pass a PnP IRP down the stack to our parent,
release RemoveLock, and return status from IoCallDriver.
--*/
{
NTSTATUS status;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(Fdx->ParentDeviceObject, Irp);
PptReleaseRemoveLock(&Fdx->RemoveLock, Irp);
return status;
}
VOID
P4DestroyPdo(
IN PDEVICE_OBJECT Pdo
)
{
PPDO_EXTENSION pdx = Pdo->DeviceExtension;
PDEVICE_OBJECT fdo = pdx->Fdo;
PFDO_EXTENSION fdx = fdo->DeviceExtension;
DD((PCE)pdx,DDT,"P4DestroyPdo\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -