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

📄 pnp.c

📁 win2k kernel 的并口驱动程序模板
💻 C
📖 第 1 页 / 共 5 页
字号:
Return Value:

    none

--*/
{
    //
    // Begin by initializing all entries to point to PptPnpUnhandledIrp() 
    //   and then override the table entries for PnP request types that 
    //   require special handling.
    //

    ULONG i;
    for( i=0 ; i <= MAX_PNP_IRP_MN_HANDLED ; ++i ) {
        PptPnpDispatchFunctionTable[i] = PptPnpUnhandledIrp;
    }

    PptPnpDispatchFunctionTable[ IRP_MN_START_DEVICE                 ] = PptPnpStartDevice;
    PptPnpDispatchFunctionTable[ IRP_MN_FILTER_RESOURCE_REQUIREMENTS ] = PptPnpFilterResourceRequirements;

    PptPnpDispatchFunctionTable[ IRP_MN_QUERY_DEVICE_RELATIONS       ] = PptPnpQueryDeviceRelations;

    PptPnpDispatchFunctionTable[ IRP_MN_QUERY_STOP_DEVICE            ] = PptPnpQueryStopDevice;
    PptPnpDispatchFunctionTable[ IRP_MN_CANCEL_STOP_DEVICE           ] = PptPnpCancelStopDevice;
    PptPnpDispatchFunctionTable[ IRP_MN_STOP_DEVICE                  ] = PptPnpStopDevice;

    PptPnpDispatchFunctionTable[ IRP_MN_QUERY_REMOVE_DEVICE          ] = PptPnpQueryRemoveDevice;
    PptPnpDispatchFunctionTable[ IRP_MN_CANCEL_REMOVE_DEVICE         ] = PptPnpCancelRemoveDevice;
    PptPnpDispatchFunctionTable[ IRP_MN_REMOVE_DEVICE                ] = PptPnpRemoveDevice;

    PptPnpDispatchFunctionTable[ IRP_MN_SURPRISE_REMOVAL             ] = PptPnpSurpriseRemoval;
}

NTSTATUS
PptPnpAddDevice(
    IN PDRIVER_OBJECT pDriverObject,
    IN PDEVICE_OBJECT pPhysicalDeviceObject
    )
/*++dvdf3

Routine Description:

    This routine creates a new parport device object and attaches 
      the device object to the device stack.

Arguments:

    pDriverObject           - pointer to the driver object for this instance of parport.

    pPhysicalDeviceObject   - pointer to the device object that represents the port.

Return Value:

    STATUS_SUCCESS          - if successful.
    Error Status            - otherwise.

--*/
{
    NTSTATUS            status        = STATUS_SUCCESS;
    PDEVICE_OBJECT      parentDevice;
    PDEVICE_OBJECT      pDeviceObject;
    PDEVICE_EXTENSION   Extension;

    DDPnP1(("-- AddDevice\n"));

    PptDump2(PARPNP1, ("pnp::PptPnpAddDevice - Enter - DriverObject = %08x , PDO = %08x\n",
                       pDriverObject, pPhysicalDeviceObject) );

#if DBG
    PptBreak(PAR_BREAK_ON_ADD_DEVICE, ("PptPnpAddDevice(PDRIVER_OBJECT, PDEVICE_OBJECT)\n") );
#endif

    //
    // Create and initialize device object 
    //
    pDeviceObject = PptBuildDeviceObject( pDriverObject, pPhysicalDeviceObject );
    if( NULL == pDeviceObject ) {
        PptDump2(PARERRORS, ("pnp::PptAddDevice - Create DeviceObject FAILED\n") );
        return STATUS_UNSUCCESSFUL;
    }
    Extension = pDeviceObject->DeviceExtension;

    //
    // Register device interface with PnP
    //
    status = IoRegisterDeviceInterface(pPhysicalDeviceObject, &GUID_PARALLEL_DEVICE, NULL, &Extension->SymbolicLinkName);
    if( !NT_SUCCESS( status ) ) {
        PptDump2(PARERRORS, ("pnp::PptAddDevice - IoRegisterDeviceInterface FAILED, status=%x", status) );
        IoDeleteDevice( pDeviceObject );
        return status;
    }

    //
    // Attach device object to device stack
    //
    parentDevice = IoAttachDeviceToDeviceStack( pDeviceObject, pPhysicalDeviceObject );
    if( NULL == parentDevice ) {
        PptDump2(PARERRORS, ("pnp::PptAddDevice - IoAttachDeviceToDeviceStack - FAILED\n") );
        IoDeleteDevice( pDeviceObject );
        return STATUS_UNSUCCESSFUL;
    }
    Extension->ParentDeviceObject = parentDevice;

    //
    // Tell the IO System that we have another parallel port
    //   (This count is used by legacy drivers.)
    //
    IoGetConfigurationInformation()->ParallelCount++;

    //
    // Done initializing - tell IO System that we are ready to receive IRPs
    //
    pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    PptDump2(PARPNP1, ("pnp::PptPnpAddDevice - SUCCESS\n") );

    return STATUS_SUCCESS;
}

NTSTATUS
PptDispatchPnp (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++dvdf8

Routine Description:

    This is the dispatch function for PnP IRPs.

     - Acquire the device's RemoveLock.
     - Forward the request to an appropriate handler.

Note: 

    The handler called by this routine must release the RemoveLock 
      before returning control to this routine!

Arguments:

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

Return Value:

    Status returned by PptAcquireRemoveLockOrFailIrp() - if unable to acquire RemoveLock

    Status returned by the IrpStack->MinorFunction handler - otherwise

--*/
{
    NTSTATUS status;

    //
    // Generate debug trace output useful in tracking PnP IRPs.
    //
    PptDebugDumpPnpIrpInfo( DeviceObject, Irp );


    //
    // Acquire RemoveLock to prevent DeviceObject from being REMOVED
    //   while we are using it. If we are unable to acquire the RemoveLock
    //   then the DeviceObject has already been REMOVED.
    //
    status = PptAcquireRemoveLockOrFailIrp(DeviceObject, Irp);

    if( NT_SUCCESS( status ) ) {

        PIO_STACK_LOCATION irpStack      = IoGetCurrentIrpStackLocation( Irp );
        UCHAR              minorFunction = irpStack->MinorFunction;

        //
        // RemoveLock is held. Forward the request to the appropriate handler.
        //
        // Note that the handler must release the RemoveLock prior to returning
        //   control to this function.
        //

        if( minorFunction > MAX_PNP_IRP_MN_HANDLED ) {
            //
            // Do standard processing for unrecognized PnP requests.
            //
            status = PptPnpUnhandledIrp( DeviceObject, Irp );
        } else {
            //
            // Forward request to appropriate handler based on type of PnP request.
            //
            status = PptPnpDispatchFunctionTable[ minorFunction ]( DeviceObject, Irp );
        }
    }

    return status;
}

NTSTATUS
PptPnpStartDevice(
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP           Irp
) 
/*++dvdf8

Routine Description:

    This function handles PnP IRP_MN_START IRPs.

     - Wait for the bus driver and any drivers beneath 
         us in the driver stack to handle this first.
     - Get, validate, and save the resources given to us by PnP.
     - Assign IDs to and get a count of 1284.3 daisy chain devices
         connected to the port.
     - Determine the capabilities of the chipset (BYTE, EPP, ECP).
     - Set our PnP device interface state to trigger
         an interface arrival callback to anyone listening 
         on our GUID.

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;
    NTSTATUS          status;
    BOOLEAN           foundPort = FALSE;
    BOOLEAN           foundIrq  = FALSE;
    BOOLEAN           foundDma  = FALSE;


    //
    // This IRP must be handled first by the parent bus driver
    //   and then by each higher driver in the device stack.
    //
    status = PptPnpBounceAndCatchPnpIrp(extension, Irp);
    if( !NT_SUCCESS( status ) && ( status != STATUS_NOT_SUPPORTED ) ) {
        // Someone below us in the driver stack explicitly failed the START.
        goto targetExit;
    }


    //
    // Extract resources from CM_RESOURCE_LIST and save them in our extension.
    //
    status = PptPnpStartScanCmResourceList(extension, Irp, &foundPort, &foundIrq, &foundDma);
    if( !NT_SUCCESS( status ) ) {
        goto targetExit;
    }

    //
    // Do our resources appear to be valid?
    //
    status = PptPnpStartValidateResources(DeviceObject, foundPort, foundIrq, foundDma);
    if( !NT_SUCCESS( status ) ) {
        goto targetExit;
    }


    //
    // Initialize the IEEE 1284.3 "bus" by assigning IDs [0..3] to 
    //   the 1284.3 daisy chain devices connected to the port. This
    //   function also gives us a count of the number of such 
    //   devices connected to the port.
    //
    extension->PnpInfo.Ieee1284_3DeviceCount = PptInitiate1284_3( extension );
    
    //
    // Determine the hardware modes supported (BYTE, ECP, EPP) by
    //   the parallel port chipset and save this information in our extension.
    //

    // Check to see if the filter parchip is there and use the modes it can set
    status = PptDetectChipFilter( extension );

    // if filter driver was not found use our own generic port detection
    if ( !NT_SUCCESS( status ) ) {
        PptDetectPortType( extension );
    }

    
    //
    // Register w/WMI
    //
    status = PptWmiInitWmi( DeviceObject );
    if( !NT_SUCCESS( status ) ) {
        goto targetExit;
    }


    //
    // Signal those who registered for PnP interface change notification 
    //   on our GUID that we have STARTED (trigger an INTERFACE_ARRIVAL
    //   PnP callback).
    //
    status = IoSetDeviceInterfaceState(&extension->SymbolicLinkName, TRUE);
    if( !NT_SUCCESS(status) ) {
        status = STATUS_NOT_SUPPORTED;
    }

targetExit:

    if( NT_SUCCESS( status ) ) {
        // 
        // Note in our extension that we have successfully STARTED.
        //
        ExAcquireFastMutex( &extension->ExtensionFastMutex );
        PptSetFlags( extension->DeviceStateFlags, PPT_DEVICE_STARTED );
        ExReleaseFastMutex( &extension->ExtensionFastMutex );
    }

    Irp->IoStatus.Status      = status;
    Irp->IoStatus.Information = 0;
    PptCompleteRequest( Irp, IO_NO_INCREMENT );

    PptReleaseRemoveLock( &extension->RemoveLock, Irp );

    return status;
}

NTSTATUS
PptPnpStartScanCmResourceList(
    IN  PDEVICE_EXTENSION Extension,
    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 extension.

Arguments:

    Extension    - 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
        PptDumpP( ("START - FAIL - No Resources - AllocatedResourcesTranslated == NULL\n") );
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto targetExit;
    }

    if(IsNotNEC_98) {
        // The NEC_98 not have PCI-Parallel.
        if( TRUE == PptIsPci( Extension, Irp ) ) {
            // This appears to be a PCI card

⌨️ 快捷键说明

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