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

📄 pnp.c

📁 win2k kernel 的并口驱动程序模板
💻 C
📖 第 1 页 / 共 5 页
字号:
    Irp->IoStatus.Status = status;
    PptCompleteRequest(Irp, IO_NO_INCREMENT);

    PptReleaseRemoveLock(&extension->RemoveLock, Irp);

    return status;
}

BOOLEAN
PptPnpFilterExistsNonIrqResourceList(
    IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList
    )
/*++dvdf8

Routine Description:

    This function is a helper function called by 
      PptPnpFilterResourceRequirements(). 

    This function scans the IO_RESOURCE_REQUIREMENTS_LIST to determine
      whether there exists any resource alternatives that do NOT contain
      an IRQ resource descriptor. The method used to filter out IRQ
      resources may differ based on whether or not there exists a
      resource alternative that does not contain an IRQ resource
      descriptor.

Arguments:

    ResourceRequirementsList - The list to scan.

Return Value:

    TRUE  - There exists at least one resource alternative in the list that
              does not contain an IRQ resource descriptor.
    FALSE - Otherwise.           

--*/
{
    ULONG listCount = ResourceRequirementsList->AlternativeLists;
    PIO_RESOURCE_LIST curList;
    ULONG i;

    PptDump2(PARRESOURCE,("Enter PptPnpFilterExistsNonIrqResourceList() - AlternativeLists= %d\n", listCount));

    i=0;
    curList = ResourceRequirementsList->List;
    while( i < listCount ) {
        PptDump2(PARRESOURCE,("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 ) {
                PptDump2(PARRESOURCE,(" curDesc= %x , remain=%d\n", curDesc, remain));
                if(curDesc->Type == CmResourceTypeInterrupt) {
                    PptDump2(PARRESOURCE,(" 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.
                //
                PptDump2(PARRESOURCE,(" 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.
    //
    PptDump2(PARRESOURCE,("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;

    PptDump2(PARRESOURCE,("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 ) {

        PptDump2(PARRESOURCE,("\n"));
        PptDump2(PARRESOURCE,("TopOfLoop: i=%d listCount=%d curList= %#x , curEndOfRRL= %#x\n",
                              i,listCount,curList,currentEndOfResourceRequirementsList));

        if( PptPnpListContainsIrqResourceDescriptor(curList) ) {
            //
            // The current list contains IRQ, remove it by shifting the 
            //   remaining lists into its place and decrementing the list count.
            //

            PptDump2(PARRESOURCE,("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.
            //
            PptDump2(PARRESOURCE,("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;

    PptDump2(PARRESOURCE,("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;

    PptDump2(PARRESOURCE,("Enter PptPnpFilterNukeIrqResourceDescriptorsFromAllLists()"
                          " - AlternativeLists= %d\n", listCount));

    //
    // Walk through the list of IO_RESOURCE_LISTs in the IO_RESOURCE_REQUIREMENTS list.
    //
    while( i < listCount ) {
        PptDump2(PARRESOURCE,("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;
            PptDump2(PARRESOURCE,(" - giving up IRQ resource - MinimumVector: %d MaximumVector: %d\n",
                       pIoResourceDescriptorIn->u.Interrupt.MinimumVector,
                       pIoResourceDescriptorIn->u.Interrupt.MaximumVector) );
        }
        ++pIoResourceDescriptorIn;
    }
}

NTSTATUS
PptPnpQueryDeviceRelations(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
    )
/*++

Routine Description:

    This function handles PnP IRP_MN_QUERY_DEVICE_RELATIONS.

Arguments:

    DeviceObject - The target device for the IRP
    Irp          - The IRP

Return Value:

    STATUS_SUCCESS              - on success,
    an appropriate error status - otherwise

--*/
{
    PDEVICE_EXTENSION    extension = DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION   irpSp     = IoGetCurrentIrpStackLocation( Irp );
    DEVICE_RELATION_TYPE type      = irpSp->Parameters.QueryDeviceRelations.Type;
    PDEVICE_RELATIONS    removalRelations;
    
    switch( type ) {
    case RemovalRelations:
        PptDump2(PARPNP1, ("pnp::PptPnpQueryDeviceRelations - RemovalRelations\n") );
        PptDumpRemovalRelationsList( extension );
        if( Irp->IoStatus.Information ) {
            // someone above us has already handled this - dvdf RMT
            PptDump2(PARPNP1, ("pnp::PptPnpQueryDeviceRelations - RemovalRelations - handled above us\n"));
        } else {
            removalRelations = PptPnpBuildRemovalRelations( extension );
            if( removalRelations ) {
                // report devices
                PptDump2(PARPNP1, ("pnp::PptPnpQueryDeviceRelations - RemovalRelations - reporting relations\n"));
                Irp->IoStatus.Status = STATUS_SUCCESS;
                Irp->IoStatus.Information = (ULONG_PTR)removalRelations;
            } else {
                // no devices to report
                PptDump2(PARPNP1, ("pnp::PptPnpQueryDeviceRelations - RemovalRelations - empty list - nothing to report\n"));
            }
        }

        break;
    case BusRelations:
        PptDump2(PARPNP1, ("pnp::PptPnpQueryDeviceRelations - BusRelations\n") );
        break;
    case EjectionRelations:
        PptDump2(PARPNP1, ("pnp::PptPnpQueryDeviceRelations - EjectionRelations\n") );
        break;
    case PowerRelations:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -