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

📄 pnp.c

📁 win2k kernel 的并口驱动程序模板
💻 C
📖 第 1 页 / 共 5 页
字号:
            PptDumpP( ("START - FAIL - Appears to be PCI card\n") );
            status = PptPnpStartScanPciCardCmResourceList(Extension, Irp, FoundPort, FoundIrq, FoundDma);
            isPci=TRUE;
            goto targetExit;
        }
    }
    
    //
    // Device appears to be traditional / non-PCI card parallel port
    //

    FullResourceDescriptor = &ResourceList->List[0];
    
    if (FullResourceDescriptor) {
        
        Extension->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;
                PptDump2(PARRESOURCE, ("pnp::PptPnpStartScanCmResourceList - start= %I64x , length=%x\n",start, length));

                *FoundPort = TRUE;
                if ((Extension->PortInfo.OriginalController.LowPart == 0) &&
                    (Extension->PortInfo.OriginalController.HighPart == 0)) {
                    
                    PptDump2(PARRESOURCE, ("pnp::PptPnpStartScanCmResourceList - assuming Controller\n"));

                    Extension->PortInfo.OriginalController = PartialResourceDescriptor->u.Port.Start;
                    Extension->PortInfo.SpanOfController   = PartialResourceDescriptor->u.Port.Length;
                    Extension->PortInfo.Controller         = (PUCHAR)(ULONG_PTR)Extension->PortInfo.OriginalController.QuadPart;
                    Extension->AddressSpace                = PartialResourceDescriptor->Flags;
                    
                    if ( (Extension->PortInfo.SpanOfController == 0x1000) && PptIsNecR98Machine() ) {
                        //
                        // Firmware bug with R98 machine.
                        //
                        Extension->PortInfo.SpanOfController = 8;
                    }
                    
                } else if ((Extension->PnpInfo.OriginalEcpController.LowPart == 0) &&
                           (Extension->PnpInfo.OriginalEcpController.HighPart == 0) &&
                           (IsNotNEC_98)) {
                    
                    if ((PartialResourceDescriptor->u.Port.Start.LowPart < Extension->PortInfo.OriginalController.LowPart) &&
                        (PartialResourceDescriptor->u.Port.Start.HighPart < Extension->PortInfo.OriginalController.HighPart)) {
                        
                        //
                        // Swapping address spaces
                        //
                        
                        PptDump2(PARRESOURCE, ("pnp::PptPnpStartScanCmResourceList - assuming Controller - Swapping Controller/EcpController\n"));

                        Extension->PnpInfo.OriginalEcpController = Extension->PortInfo.OriginalController;
                        Extension->PnpInfo.SpanOfEcpController   = Extension->PortInfo.SpanOfController;
                        Extension->PnpInfo.EcpController         = Extension->PortInfo.Controller;
                        Extension->EcpAddressSpace               = Extension->AddressSpace;
                        
                        Extension->PortInfo.OriginalController = PartialResourceDescriptor->u.Port.Start;
                        Extension->PortInfo.SpanOfController   = PartialResourceDescriptor->u.Port.Length;
                        Extension->PortInfo.Controller         = (PUCHAR)(ULONG_PTR)Extension->PortInfo.OriginalController.QuadPart;
                        Extension->AddressSpace                = PartialResourceDescriptor->Flags;
                        
                        if ( (Extension->PortInfo.SpanOfController == 0x1000) && PptIsNecR98Machine() ) {
                            //
                            // Firmware bug with R98 machine.
                            //
                            Extension->PortInfo.SpanOfController = 8;
                        }
                        
                    } else {
                        PptDump2(PARRESOURCE, ("pnp::PptPnpStartScanCmResourceList - assuming EcpController\n"));

                        Extension->PnpInfo.OriginalEcpController = PartialResourceDescriptor->u.Port.Start;
                        Extension->PnpInfo.SpanOfEcpController   = PartialResourceDescriptor->u.Port.Length;
                        Extension->PnpInfo.EcpController         = (PUCHAR)(ULONG_PTR)Extension->PnpInfo.OriginalEcpController.QuadPart;
                        Extension->EcpAddressSpace               = PartialResourceDescriptor->Flags;
                    }
                    
                }
                break;
                
            case CmResourceTypeBusNumber:
                
                Extension->BusNumber = PartialResourceDescriptor->u.BusNumber.Start;
                break;
                
            case CmResourceTypeInterrupt:
                
                *FoundIrq = TRUE;
                Extension->FoundInterrupt       = TRUE;
                Extension->InterruptLevel       = (KIRQL)PartialResourceDescriptor->u.Interrupt.Level;
                Extension->InterruptVector      = PartialResourceDescriptor->u.Interrupt.Vector;
                Extension->InterruptAffinity    = PartialResourceDescriptor->u.Interrupt.Affinity;
                
                if (PartialResourceDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
                    
                    Extension->InterruptMode = Latched;
                    
                } else {
                    
                    Extension->InterruptMode = LevelSensitive;
                }
                break;
                
            case CmResourceTypeDma:
                
                *FoundDma = TRUE;
                Extension->DmaChannel   = PartialResourceDescriptor->u.Dma.Channel;
                Extension->DmaPort      = PartialResourceDescriptor->u.Dma.Port;
                Extension->DmaWidth     = PartialResourceDescriptor->Flags;
                break;
                
            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
        PptDump2(PARRESOURCE, ("pnp::PptPnpStartScanCmResourceList - done, found:\n"));
        PptDump2(PARRESOURCE, ("  OriginalEcpController= %I64x\n", Extension->PnpInfo.OriginalEcpController));
        PptDump2(PARRESOURCE, ("  EcpController        = %p\n",    Extension->PnpInfo.EcpController));
        PptDump2(PARRESOURCE, ("  SpanOfEcpController  = %x\n",    Extension->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

--*/
{
    PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;
    NTSTATUS          status    = STATUS_SUCCESS;

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

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

        if(!extension->PortInfo.Controller) {
            // ( Controller == NULL ) is invalid
            PptLogError(DeviceObject->DriverObject, DeviceObject,
                        extension->PortInfo.OriginalController, PhysicalZero, 0, 0, 0, 10,
                        STATUS_SUCCESS, PAR_REGISTERS_NOT_MAPPED);
            status = STATUS_NONE_MAPPED;
        }
    }
    return status;
}

NTSTATUS
PptPnpFilterResourceRequirements(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
    ) 
/*++dvdf8

Routine Description:

    This function handles PnP IRP_MN_FILTER_RESOURCE_REQUIREMENTS IRPs.

     - Wait for the bus driver and any drivers beneath 
         us in the driver stack to handle this first.
     - Query the registry to find the type of filtering desired.
     - Filter out IRQ resources as specified by the registry setting.

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;
    ULONG                          filterResourceMethod    = PPT_FORCE_USE_NO_IRQ;
    PIO_RESOURCE_REQUIREMENTS_LIST pResourceRequirementsIn;
    NTSTATUS                       status;


    //
    // DDK Rule: Add on the way down, modify on the way up. We are modifying
    //   the resource list so let the drivers beneath us handle this IRP first.
    //
    status    = PptPnpBounceAndCatchPnpIrp(extension, Irp);
    if( !NT_SUCCESS(status) && (status != STATUS_NOT_SUPPORTED) ) {
        // Someone below us in the driver stack explicitly failed the IRP.
        goto targetExit;
    }


    //
    // Find the "real" resource requirments list, either the PnP list
    //   or the list created by another driver in the stack.
    //
    if ( Irp->IoStatus.Information == 0 ) {
        //
        // No one else has created a new resource list. Use the original 
        //   list from the PnP Manager.
        //
        PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation( Irp );
        pResourceRequirementsIn = IrpStack->Parameters.FilterResourceRequirements.IoResourceRequirementList;

        if (pResourceRequirementsIn == NULL) {
            //
            // NULL list, nothing to do.
            //
            goto targetExit;
        }

    } else {
        //
        // Another driver has created a new resource list. Use the list that they created.
        //
        pResourceRequirementsIn = (PIO_RESOURCE_REQUIREMENTS_LIST)Irp->IoStatus.Information;
    }


    //
    // Check the registry to find out the desired type of resource filtering.
    //
    // The following call sets the default value for filterResourceMethod 
    //   if the registry query fails.
    //
    PptRegGetDeviceParameterDword( extension->PhysicalDeviceObject,
                                   (PWSTR)L"FilterResourceMethod",
                                   &filterResourceMethod );

    PptDump2(PARRESOURCE,("filterResourceMethod=%x\n", filterResourceMethod) );
    PptDump2(PARRESOURCE,("ResourceRequirementsList BEFORE Filtering:\n") );
    PptDebugDumpResourceRequirementsList(pResourceRequirementsIn);


    //
    // Do filtering based on registry setting.
    //
    switch( filterResourceMethod ) {

    case PPT_FORCE_USE_NO_IRQ: 
        //
        // Registry setting dictates that we should refuse to accept IRQ resources.
        //
        // * This is the default behavior which means that we make the IRQ available 
        //     for legacy net and sound cards that may not work if they cannot get
        //     the IRQ.
        //
        // - If we find a resource alternative that does not contain an IRQ resource
        //     then we remove those resource alternatives that do contain IRQ 
        //     resources from the list of alternatives.
        //
        // - Otherwise we have to play hardball. Since all resource alternatives
        //     contain IRQ resources we simply "nuke" the IRQ resource descriptors
        //     by changing their resource Type from CmResourceTypeInterrupt to
        //     CmResourceTypeNull.
        //

        PptDump2(PARRESOURCE,("PPT_FORCE_USE_NO_IRQ\n") );

        if( PptPnpFilterExistsNonIrqResourceList( pResourceRequirementsIn ) ) {

            PptDump2(PARRESOURCE,("Found Resource List with No IRQ - Filtering\n") );
            PptPnpFilterRemoveIrqResourceLists( pResourceRequirementsIn );

        } else {

            PptDump2(PARRESOURCE,("Did not find Resource List with No IRQ - Nuking IRQ resource descriptors\n") );
            PptPnpFilterNukeIrqResourceDescriptorsFromAllLists( pResourceRequirementsIn );

        }

        PptDump2(PARRESOURCE,("ResourceRequirementsList AFTER Filtering:\n") );
        PptDebugDumpResourceRequirementsList( pResourceRequirementsIn );
        break;


    case PPT_TRY_USE_NO_IRQ: 
        //
        // Registry setting dictates that we should TRY to give up IRQ resources.
        //
        // - If we find a resource alternative that does not contain an IRQ resource
        //     then we remove those resource alternatives that do contain IRQ 
        //     resources from the list of alternatives.
        //
        // - Otherwise we do nothing.
        //

        PptDump2(PARRESOURCE,("PPT_TRY_USE_NO_IRQ\n") );
        if( PptPnpFilterExistsNonIrqResourceList(pResourceRequirementsIn) ) {

            PptDump2(PARRESOURCE,("Found Resource List with No IRQ - Filtering\n") );
            PptPnpFilterRemoveIrqResourceLists(pResourceRequirementsIn);

            PptDump2(PARRESOURCE,("ResourceRequirementsList AFTER Filtering:\n") );
            PptDebugDumpResourceRequirementsList(pResourceRequirementsIn);

        } else {

            // leave the IO resource list as is
            PptDump2(PARRESOURCE,("Did not find Resource List with No IRQ - Do nothing\n") );

        }
        break;


    case PPT_ACCEPT_IRQ: 
        //
        // Registry setting dictates that we should NOT filter out IRQ resources.
        //
        // - Do nothing.
        //
        PptDump2(PARRESOURCE,("PPT_ACCEPT_IRQ\n") );
        break;


    default:
        //
        // Invalid registry setting. 
        //
        // - Do nothing.
        //
        // RMT dvdf - May be desirable to write an error log entry here.
        //
        PptDump2(PARERRORS, ("ERROR:IGNORED: bad filterResourceMethod=%x\n", filterResourceMethod) );
    }

targetExit:

    //
    // Preserve Irp->IoStatus.Information because it may point to a
    //   buffer and we don't want to cause a memory leak.
    //

⌨️ 快捷键说明

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