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

📄 pnputils.c

📁 鼠标Windows驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
            case CmResourceTypeDma:
                
                // we don't do anything with DMA - fall through to default case
                
            default:

                break;

            } // end switch( PartialResourceDescriptor->Type )
        } // end for(... ; i < PartialResourceList->Count ; ...)
    } // end if( FullResourceDescriptor )
    
    return status;
}

BOOLEAN PptIsPci(
    PFDO_EXTENSION Fdx, 
    PIRP              Irp 
)
/*++

Does this look like a PCI card? Return TRUE if yes, FALSE otherwise

--*/
{
    PIO_STACK_LOCATION              irpStack = IoGetCurrentIrpStackLocation( Irp );
    PCM_RESOURCE_LIST               ResourceList;
    PCM_FULL_RESOURCE_DESCRIPTOR    FullResourceDescriptor;
    PCM_PARTIAL_RESOURCE_LIST       PartialResourceList;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
    ULONG                           i;
    ULONG                           portResourceDescriptorCount = 0;
    BOOLEAN                         largePortRangeFound         = FALSE;
    ULONG                           rangeLength;
    
    //
    // If there are more than 2 IO resource descriptors, or if any IO resource
    //   descriptor has a range > 8 bytes, then assume that this is a PCI device
    //   and requires non-traditional handling.
    //

    ResourceList = irpStack->Parameters.StartDevice.AllocatedResourcesTranslated;
    
    if (ResourceList == NULL) {
        // we weren't given any resources
        return FALSE;
    }

    FullResourceDescriptor = &ResourceList->List[0];
    
    if (FullResourceDescriptor) {
        
        PartialResourceList = &FullResourceDescriptor->PartialResourceList;
        
        for (i = 0; i < PartialResourceList->Count; i++) {
            
            PartialResourceDescriptor = &PartialResourceList->PartialDescriptors[i];
            
            switch (PartialResourceDescriptor->Type) {
                
            case CmResourceTypePort:
                
                rangeLength = PartialResourceDescriptor->u.Port.Length;
                DD((PCE)Fdx,DDT,"pnp::PptIsPCI - CmResourceTypePort - Start= %I64x, Length= %x , \n",
                                       PartialResourceDescriptor->u.Port.Start.QuadPart, rangeLength);

                ++portResourceDescriptorCount;

                if( rangeLength > 8 ) {
                    largePortRangeFound = TRUE;
                }
                break;
                
            default:
                ;
            } // end switch( PartialResourceDescriptor->Type )
        } // end for(... ; i < PartialResourceList->Count ; ...)
    } // end if( FullResourceDescriptor )
    
    if( (portResourceDescriptorCount > 2) || (TRUE == largePortRangeFound) ) {
        // looks like PCI
        return TRUE;
    } else {
        // does not look like PCI
        return FALSE;
    }
}

NTSTATUS
PptPnpStartScanCmResourceList(
    IN  PFDO_EXTENSION Fdx,
    IN  PIRP              Irp, 
    OUT PBOOLEAN          FoundPort,
    OUT PBOOLEAN          FoundIrq,
    OUT PBOOLEAN          FoundDma
    )
/*++dvdf3

Routine Description:

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

    This function scans the CM_RESOURCE_LIST supplied with the Pnp 
      IRP_MN_START_DEVICE IRP, extracts the resources from the list, 
      and saves them in the device Fdx.

Arguments:

    Fdx    - The device extension of the target of the START IRP
    Irp          - The IRP
    FoundPort    - Did we find a  Port resource?
    FoundIrq     - Did we find an IRQ  resource?
    FoundDma     - Did we find a  DMA  resource?

Return Value:

    STATUS_SUCCESS                - if we were given a resource list,
    STATUS_INSUFFICIENT_RESOURCES - otherwise

--*/
{
    NTSTATUS                        status   = STATUS_SUCCESS;
    PIO_STACK_LOCATION              irpStack = IoGetCurrentIrpStackLocation( Irp );
    PCM_RESOURCE_LIST               ResourceList;
    PCM_FULL_RESOURCE_DESCRIPTOR    FullResourceDescriptor;
    PCM_PARTIAL_RESOURCE_LIST       PartialResourceList;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
    ULONG                           i;
    PHYSICAL_ADDRESS                start;
    ULONG                           length;
    BOOLEAN                         isPci = FALSE;
    
    *FoundPort = FALSE;
    *FoundIrq  = FALSE;
    *FoundDma  = FALSE;
    
    ResourceList = irpStack->Parameters.StartDevice.AllocatedResourcesTranslated;
    
    if (ResourceList == NULL) {
        // we weren't given any resources, bail out
        DD((PCE)Fdx,DDT,"START - FAIL - No Resources - AllocatedResourcesTranslated == NULL\n");
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto targetExit;
    }

    if( TRUE == PptIsPci( Fdx, Irp ) ) {
        // This appears to be a PCI card
        status = PptPnpStartScanPciCardCmResourceList(Fdx, Irp, FoundPort, FoundIrq, FoundDma);
        isPci=TRUE;
        goto targetExit;
    }
    
    //
    // Device appears to be traditional / non-PCI card parallel port
    //

    FullResourceDescriptor = &ResourceList->List[0];
    
    if (FullResourceDescriptor) {
        
        Fdx->InterfaceType = FullResourceDescriptor->InterfaceType;
        
        PartialResourceList = &FullResourceDescriptor->PartialResourceList;
        
        for (i = 0; i < PartialResourceList->Count; i++) {
            
            PartialResourceDescriptor = &PartialResourceList->PartialDescriptors[i];
            
            switch (PartialResourceDescriptor->Type) {
                
            case CmResourceTypePort:
                
                start  = PartialResourceDescriptor->u.Port.Start;
                length = PartialResourceDescriptor->u.Port.Length;
                DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - start= %I64x , length=%x\n",start, length);

                *FoundPort = TRUE;
                if ((Fdx->PortInfo.OriginalController.LowPart == 0) &&
                    (Fdx->PortInfo.OriginalController.HighPart == 0)) {
                    
                    DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - assuming Controller\n");

                    Fdx->PortInfo.OriginalController = PartialResourceDescriptor->u.Port.Start;
                    Fdx->PortInfo.SpanOfController   = PartialResourceDescriptor->u.Port.Length;
                    Fdx->PortInfo.Controller         = (PUCHAR)(ULONG_PTR)Fdx->PortInfo.OriginalController.QuadPart;
                    Fdx->AddressSpace                = PartialResourceDescriptor->Flags;
                    
                } else if ((Fdx->PnpInfo.OriginalEcpController.LowPart == 0) &&
                           (Fdx->PnpInfo.OriginalEcpController.HighPart == 0) &&
                           (IsNotNEC_98)) {
                    
                    if ((PartialResourceDescriptor->u.Port.Start.LowPart < Fdx->PortInfo.OriginalController.LowPart) &&
                        (PartialResourceDescriptor->u.Port.Start.HighPart < Fdx->PortInfo.OriginalController.HighPart)) {
                        
                        //
                        // Swapping address spaces
                        //
                        
                        DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - assuming Controller - Swapping Controller/EcpController\n");

                        Fdx->PnpInfo.OriginalEcpController = Fdx->PortInfo.OriginalController;
                        Fdx->PnpInfo.SpanOfEcpController   = Fdx->PortInfo.SpanOfController;
                        Fdx->PnpInfo.EcpController         = Fdx->PortInfo.Controller;
                        Fdx->EcpAddressSpace               = Fdx->AddressSpace;
                        
                        Fdx->PortInfo.OriginalController = PartialResourceDescriptor->u.Port.Start;
                        Fdx->PortInfo.SpanOfController   = PartialResourceDescriptor->u.Port.Length;
                        Fdx->PortInfo.Controller         = (PUCHAR)(ULONG_PTR)Fdx->PortInfo.OriginalController.QuadPart;
                        Fdx->AddressSpace                = PartialResourceDescriptor->Flags;
                        
                    } else {
                        DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - assuming EcpController\n");

                        Fdx->PnpInfo.OriginalEcpController = PartialResourceDescriptor->u.Port.Start;
                        Fdx->PnpInfo.SpanOfEcpController   = PartialResourceDescriptor->u.Port.Length;
                        Fdx->PnpInfo.EcpController         = (PUCHAR)(ULONG_PTR)Fdx->PnpInfo.OriginalEcpController.QuadPart;
                        Fdx->EcpAddressSpace               = PartialResourceDescriptor->Flags;
                    }
                    
                }
                break;
                
            case CmResourceTypeBusNumber:
                
                Fdx->BusNumber = PartialResourceDescriptor->u.BusNumber.Start;
                break;
                
            case CmResourceTypeInterrupt:
                
                *FoundIrq = TRUE;
                Fdx->FoundInterrupt       = TRUE;
                Fdx->InterruptLevel       = (KIRQL)PartialResourceDescriptor->u.Interrupt.Level;
                Fdx->InterruptVector      = PartialResourceDescriptor->u.Interrupt.Vector;
                Fdx->InterruptAffinity    = PartialResourceDescriptor->u.Interrupt.Affinity;
                
                if (PartialResourceDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
                    
                    Fdx->InterruptMode = Latched;
                    
                } else {
                    
                    Fdx->InterruptMode = LevelSensitive;
                }
                break;
                
            case CmResourceTypeDma:

                // we don't do anything with DMA - fall through to default case

            default:

                break;

            } // end switch( PartialResourceDescriptor->Type )
        } // end for(... ; i < PartialResourceList->Count ; ...)
    } // end if( FullResourceDescriptor )
    
targetExit:

    if( FALSE == isPci ) {
        // we scanned the resources - dump what we found
        DD((PCE)Fdx,DDT,"pnp::PptPnpStartScanCmResourceList - done, found:\n");
        DD((PCE)Fdx,DDT,"  OriginalEcpController= %I64x\n", Fdx->PnpInfo.OriginalEcpController);
        DD((PCE)Fdx,DDT,"  EcpController        = %p\n",    Fdx->PnpInfo.EcpController);
        DD((PCE)Fdx,DDT,"  SpanOfEcpController  = %x\n",    Fdx->PnpInfo.SpanOfEcpController);
    }
    return status;
}

NTSTATUS
PptPnpStartValidateResources(
    IN PDEVICE_OBJECT    DeviceObject,                              
    IN BOOLEAN           FoundPort,
    IN BOOLEAN           FoundIrq,
    IN BOOLEAN           FoundDma
    )
/*++dvdf3

Routine Description:

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

    This function does a sanity check of the resources saved in our
      extension by PptPnpStartScanCmResourceList() to determine 
      if those resources appear to be valid. Checks for for Irq 
      and Dma resource validity are anticipated in a future version.

Arguments:

    DeviceObject - The target of the START IRP
    FoundPort    - Did we find a  Port resource?
    FoundIrq     - Did we find an IRQ  resource?
    FoundDma     - Did we find a  DMA  resource?

Return Value:

    STATUS_SUCCESS        - on success,
    STATUS_NO_SUCH_DEVICE - if we weren't given a port resource,
    STATUS_NONE_MAPPED    - if we were given a port resource but our 
                              port address is NULL

--*/
{
    PFDO_EXTENSION fdx = DeviceObject->DeviceExtension;
    NTSTATUS          status    = STATUS_SUCCESS;

    UNREFERENCED_PARAMETER( FoundIrq ); // future use
    UNREFERENCED_PARAMETER( FoundDma ); // future use

    if( !FoundPort ) {
        status = STATUS_NO_SUCH_DEVICE;
    } else {
//         fdx->PortInfo.Controller = (PUCHAR)(ULONG_PTR)fdx->PortInfo.OriginalController.LowPart;
        fdx->PortInfo.Controller = (PUCHAR)(ULONG_PTR)fdx->PortInfo.OriginalController.QuadPart;

        if(!fdx->PortInfo.Controller) {
            // ( Controller == NULL ) is invalid
            PptLogError(DeviceObject->DriverObject, DeviceObject,
                        fdx->PortInfo.OriginalController, PhysicalZero, 0, 0, 0, 10,
                        STATUS_SUCCESS, PAR_REGISTERS_NOT_MAPPED);
            status = STATUS_NONE_MAPPED;
        }
    }
    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;

    i=0;
    curList = ResourceRequirementsList->List;
    while( i < listCount ) {

⌨️ 快捷键说明

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