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

📄 plugplay.c

📁 本压缩包为作者截取的PCI9054的WDM官方驱动源码。欢迎下载。
💻 C
📖 第 1 页 / 共 2 页
字号:
    return DefaultPnpHandler(
               fdo,
               pIrp
               );
}




/******************************************************************************
 *
 * Function   :  HandleCancelRemoveDevice
 *
 * Description:  Handle the IRP_MN_CANCEL_REMOVE_DEVICE PnP request
 *
 ******************************************************************************/
NTSTATUS
HandleCancelRemoveDevice(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    // We must succeed the IRP and pass it to the parent
    pIrp->IoStatus.Status = STATUS_SUCCESS;

    // Forward to parent driver
    return DefaultPnpHandler(
               fdo,
               pIrp
               );
}




/******************************************************************************
 *
 * Function   :  HandleRemoveDevice
 *
 * Description:  Handle the IRP_MN_REMOVE_DEVICE PnP request
 *
 ******************************************************************************/
NTSTATUS
HandleRemoveDevice(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    NTSTATUS          status;
    DEVICE_EXTENSION *pdx;


    // Wait for any pending I/O operations to complete

    pdx           = fdo->DeviceExtension;
    pdx->removing = TRUE;

    PlxUnlockDevice(pdx);            // once for LockDevice at start of dispatch
    PlxUnlockDevice(pdx);            // once for initialization during AddDevice

    KeWaitForSingleObject(
        &pdx->evRemove,
        Executive,
        KernelMode,
        FALSE,
        NULL
        );

    // Halt the device and release its resources
    StopDevice(
        fdo
        );

    // Succeed the IRP and pass to next driver
    pIrp->IoStatus.Status = STATUS_SUCCESS;

    // Pass to next driver in stack
    status =
        DefaultPnpHandler(
            fdo,
            pIrp
            );

    // Remove the device object
    RemoveDevice(
        fdo
        );

    return status;
}




/******************************************************************************
 *
 * Function   :  HandleStartDevice
 *
 * Description:  Handle the IRP_MN_START_DEVICE PnP request
 *
 ******************************************************************************/
NTSTATUS
HandleStartDevice(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    NTSTATUS           status;
    PIO_STACK_LOCATION stack;


    /********************************************************
     * First let all lower-level drivers handle this request,
     * which is typically just the physical device object
     * created by the bus driver.
     *******************************************************/

    status =
        ForwardAndWait(
            fdo,
            pIrp
            );

    if (!NT_SUCCESS(status))
    {
        return PlxCompleteIrp(
                   pIrp,
                   status
                   );
    }

    stack =
        IoGetCurrentIrpStackLocation(
            pIrp
            );

    // Assign resources to the devices
    status =
        StartDevice(
            fdo,
            &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList,
            &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList
            );

    return PlxCompleteIrpWithInformation(
               pIrp,
               status,
               0
               );
}




/******************************************************************************
 *
 * Function   :  HandleStopDevice
 *
 * Description:  Handle the IRP_MN_STOP_DEVICE PnP request
 *
 ******************************************************************************/
NTSTATUS
HandleStopDevice(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    NTSTATUS status;


    status =
        DefaultPnpHandler(
            fdo,
            pIrp
            );

    StopDevice(
        fdo
        );

    return status;
}




/******************************************************************************
 *
 * Function   :  HandleQueryDeviceRelations
 *
 * Description:  Handle the IRP_MN_QUERY_DEVICE_RELATIONS PnP request
 *
 ******************************************************************************/
NTSTATUS
HandleQueryDeviceRelations(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    U32                 MemNeeded;
    PDEVICE_OBJECT      pdo;
    PDEVICE_OBJECT      pDevice;
    DEVICE_EXTENSION   *pdx;
    DEVICE_RELATIONS   *pDeviceRelations;
    PIO_STACK_LOCATION  stack;


    /********************************************************
     * When a query for device relations is received and the
     * request is for "RemovalRelations", the driver may
     * report to the PnP manager a list of device relations.
     * 
     * Since the first device loaded by the driver (PciXxx-0)
     * is responsible for the common buffer, all subsequently
     * owned devices are related to it.  An attempt to remove
     * the primary device requires the driver to report that
     * all other devices must be removed first.  The PnP
     * manager determines this by the device relations
     * provided by this driver.
     *******************************************************/

    pdx = fdo->DeviceExtension;

    // Get I/O Stack
    stack =
        IoGetCurrentIrpStackLocation(
            pIrp
            );

    // Check if this is for removal and more than one device is owned
    if ((stack->Parameters.QueryDeviceRelations.Type == RemovalRelations) &&
        (Gbl_DeviceCount > 1))
    {
        DebugPrintf((
            "Query for: RemovalRelations\n"
            ));

        // This is not the only device left, check if it's the primary device
        if (_stricmp(
                PLX_DRIVER_NAME "-0",
                pdx->Device.SerialNumber
                ) == 0)
        {
            /********************************************************
             * Calculate memory needed for device relations
             *
             * The default DEVICE_RELATIONS structure includes space
             * for one device object.  Therefore, the memory needed
             * is the total # of devices minus 2.  One since the
             * primary device is not reported and one for memory
             * already provided in the structure.
             *******************************************************/
            MemNeeded = sizeof(DEVICE_RELATIONS) +
                        ((Gbl_DeviceCount - 2) * sizeof(PDEVICE_OBJECT));

            // Allocate memory for device relations structure
            pDeviceRelations =
                ExAllocatePoolWithTag(
                    PagedPool,
                    MemNeeded,
                    (ULONG)' XLP'       // "PLX " in reverse order
                    );

            // Report other devices
            DebugPrintf((
                "Following device(s) must be removed first:\n"
                ));

            // Get first device object
            pDevice = fdo->DriverObject->DeviceObject;

            // Reset device count
            pDeviceRelations->Count = 0;

            // Traverse driver owned devices to build relations
            while (pDevice != NULL)
            {
                if (pDevice->DeviceExtension != pdx)
                {
                    // Get the physical device object
                    pdo = ((DEVICE_EXTENSION*)(pDevice->DeviceExtension))->pPhysicalDeviceObject;

                    DebugPrintf_NoInfo((
                        "           * %s (pdo=0x%p)\n",
                        ((DEVICE_EXTENSION*)(pDevice->DeviceExtension))->Device.SerialNumber,
                        pdo
                        ));

                    // Increment the reference count to the PDO
                    ObReferenceObject(
                        pdo
                        );

                    // Add PDO to device relations
                    pDeviceRelations->Objects[pDeviceRelations->Count] = pdo;

                    // Increment number of objects
                    pDeviceRelations->Count++;
                }

                // Jump to next device
                pDevice = pDevice->NextDevice;
            }

            DebugPrintf_NoInfo((
                "\n"
                ));

            // Return address of device relations structure
            return PlxCompleteIrpWithInformation(
                       pIrp,
                       STATUS_SUCCESS,
                       (PLX_UINT_PTR)pDeviceRelations
                       );
        }
    }

    // Just pass to parent
    return DefaultPnpHandler(
               fdo,
               pIrp
               );
}




/******************************************************************************
 *
 * Function   :  OnRequestComplete
 *
 * Description:  Set an event when a lower driver complete an IRP
 *
 ******************************************************************************/
NTSTATUS
OnRequestComplete(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp,
    PKEVENT        pKEvent
    )
{
    KeSetEvent(
       pKEvent,
       0,
       FALSE
       );

    return STATUS_MORE_PROCESSING_REQUIRED;
}




/******************************************************************************
 *
 * Function   :  ForwardAndWait
 *
 * Description:  Forward request to lower level and await completion, used
 *               in PnP's IRP_MN_START_DEVICE
 *
 ******************************************************************************/
NTSTATUS
ForwardAndWait(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    KEVENT    event;
    NTSTATUS  status;


    /* 
       Initialize a kernel event object to use in waiting for the lower-level
       driver to finish processing the object. It's a little known fact that the
       kernel stack *can* be paged, but only while someone is waiting in user 
       mode for an event to finish. Since neither we nor a completion routine 
       can be in the forbidden state, it's okay to put the event object on the 
       stack.
    */
    KeInitializeEvent(
        &event,
        NotificationEvent,
        FALSE
        );

    IoCopyCurrentIrpStackLocationToNext(
        pIrp
        );

    IoSetCompletionRoutine(
        pIrp,
        (PIO_COMPLETION_ROUTINE) OnRequestComplete,
        (PVOID) &event,
        TRUE,
        TRUE,
        TRUE
        );

    status =
        IoCallDriver(
            ((DEVICE_EXTENSION *) fdo->DeviceExtension)->pLowerDeviceObject,
            pIrp
            );

    if (status == STATUS_PENDING)
    {
        // Wait for completion
        KeWaitForSingleObject(
            &event,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

        return pIrp->IoStatus.Status;
    }

    return status;
}

⌨️ 快捷键说明

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