sdyxz123 2023-08-01 15:41 采纳率: 36.4%
浏览 19
已结题

WDM驱动 PDO 设备属性疑问

我需要在 WDM 驱动中 获取 PDO 的物理信息 设备属性,如 PhysicalDeviceObjectName HardwareID DevicePropertyDeviceDescription

我知道可以用 IoGetDeviceProperty 获取,但是我的PDO 是ACPI 驱动 创建的 ,我需要获取我PDOI 的 _UID , 但是 IoGetDeviceProperty 只支持如下的信息获取,没有 UID 的类型。

img

我怎么获取PDO设备的_UID 呢?

给一个通过 IRP 请求 获取 UID 的代码示例

  • 写回答

6条回答 默认 最新

  • 2301_79233340 2023-08-01 16:18
    关注

    引用chatgpt内容作答:
    在 WDM 驱动中,您可以使用其他方法来获取 ACPI PDO 设备的 _UID(唯一 ID)。由于 IoGetDeviceProperty 函数不直接提供 _UID 属性的查询,您可以尝试以下方法来获取 _UID:

    1、使用 IRP_MN_QUERY_ID 请求:
    您可以向 ACPI PDO 设备发送 IRP_MN_QUERY_ID 请求,并指定 QueryType 为 BusQueryDeviceID。这将使设备栈返回设备的标识符字符串,其中包含设备的 _UID。

    2、使用 IRP_MN_QUERY_DEVICE_TEXT 请求:
    同样,您可以向 ACPI PDO 设备发送 IRP_MN_QUERY_DEVICE_TEXT 请求,并指定 RequestType 为 DeviceTextDescription。这将使设备栈返回设备的描述字符串,其中可能包含设备的 _UID。

    3、解析 ACPI 配置:
    ACPI 设备对象通常包含一个名为 _HID 的属性,它是硬件 ID。该 ID 通常与设备的 _UID 相对应。您可以通过解析 ACPI 配置来获取这些属性,并从中提取 _UID。

    以下是第一种方法的示例代码:

    NTSTATUS GetAcpiDeviceUid(PDEVICE_OBJECT pdo, PWSTR* pUid)
    {
        NTSTATUS status = STATUS_SUCCESS;
        PIRP irp = NULL;
        KEVENT event;
        IO_STATUS_BLOCK ioStatusBlock;
    
        PAGED_CODE();
    
        *pUid = NULL;
    
        KeInitializeEvent(&event, NotificationEvent, FALSE);
        irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, pdo, NULL, 0, NULL, &event, &ioStatusBlock);
    
        if (irp == NULL)
        {
            return STATUS_INSUFFICIENT_RESOURCES;
        }
    
        PIO_STACK_LOCATION irpSp = IoGetNextIrpStackLocation(irp);
        irpSp->MinorFunction = IRP_MN_QUERY_ID;
        irpSp->Parameters.QueryId.IdType = BusQueryDeviceID;
    
        status = IoCallDriver(pdo, irp);
        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
            status = ioStatusBlock.Status;
        }
    
        if (NT_SUCCESS(status))
        {
            *pUid = ExAllocatePoolWithTag(PagedPool, ioStatusBlock.Information, 'myTag');
            if (*pUid != NULL)
            {
                RtlCopyMemory(*pUid, ioStatusBlock.Information, ioStatusBlock.Information);
            }
            else
            {
                status = STATUS_INSUFFICIENT_RESOURCES;
            }
        }
    
        return status;
    }
    

    这只是获取 ACPI PDO 设备 _UID 的一种方法。在实际实现中,您可能需要根据具体的设备和驱动情况进行适当的调整。同时,记得在使用 ExAllocatePoolWithTag 分配的内存后,在不再使用时使用 ExFreePool 释放它,以避免内存泄漏。

    ACPI 设备的 _UID 并非硬件标识符,而是与 ACPI 设备节点相关的标识符。如果您需要硬件 ID,请使用 IRP_MN_QUERY_ID 请求并指定 QueryType 为 BusQueryHardwareIDs。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 8月1日
  • 已采纳回答 8月1日
  • 赞助了问题酬金20元 8月1日
  • 修改了问题 8月1日
  • 展开全部