⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pnputils.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 + -