返回

如何从设备名称获取 DEVICE_OBJECT?——从内核角度深入解读

windows

从设备名称获取 DEVICE_OBJECT:深入指南

概述

设备对象 (DEVICE_OBJECT) 是 Windows 内核中表示设备的对象。它包含有关设备的信息,例如名称、类型和状态。在与设备交互时,获取 DEVICE_OBJECT 至关重要。本文将深入探讨从设备名称获取 DEVICE_OBJECT 的方法,并提供一个详细的代码示例。

步骤

要从设备名称获取 DEVICE_OBJECT,请按照以下步骤操作:

  1. 打开物理设备对象 (PDO) :PDO 表示物理设备。使用 IoCreateDevice 函数打开 PDO。
  2. 从 PDO 获取功能设备对象 (FDO) :FDO 表示设备功能的 PDO 子对象。使用 IoGetAttachedDeviceReference 函数获取 FDO。
  3. 从 FDO 获取 DEVICE_OBJECT :DEVICE_OBJECT 是 FDO 的父对象。使用 IoGetDeviceAttachmentBaseRef 函数获取 DEVICE_OBJECT。

示例代码

下面的代码示例演示了如何从设备名称获取 DEVICE_OBJECT:

NTSTATUS GetDeviceObjectFromName(PUNICODE_STRING deviceName, PDEVICE_OBJECT *deviceObject)
{
    NTSTATUS status;
    PDEVICE_OBJECT pdo, fdo;

    // 打开 PDO
    status = IoCreateDevice(driverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, &pdo);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    // 从 PDO 获取 FDO
    status = IoGetAttachedDeviceReference(pdo, &fdo);
    if (!NT_SUCCESS(status))
    {
        IoDeleteDevice(pdo);
        return status;
    }

    // 从 FDO 获取 DEVICE_OBJECT
    status = IoGetDeviceAttachmentBaseRef(fdo, deviceObject);
    if (!NT_SUCCESS(status))
    {
        IoDetachDevice(fdo);
        IoDeleteDevice(pdo);
        return status;
    }

    // 释放句柄
    IoDetachDevice(fdo);
    IoDeleteDevice(pdo);

    return status;
}

注意事项

  • 使用完 DEVICE_OBJECT 后,必须使用 IoDetachDevice 函数将其释放。
  • 如果设备名称不存在,IoCreateDevice 函数会失败。
  • 如果设备已被打开,IoCreateDevice 函数也会失败。

结论

通过遵循本文所述的步骤,你可以从设备名称成功获取 DEVICE_OBJECT。掌握这一技术对于与设备交互和管理系统资源至关重要。

常见问题解答

  1. 如何判断设备名称是否有效?

    可以通过调用 IoGetDeviceObjectPointer 函数并检查其返回值是否为非空值来验证设备名称。

  2. 如果设备处于脱机状态,可以获取 DEVICE_OBJECT 吗?

    不可以。DEVICE_OBJECT 仅当设备处于联机状态时才可用。

  3. 为什么需要获取 DEVICE_OBJECT?

    DEVICE_OBJECT 提供了对设备的低级访问,使开发人员能够控制设备的行为和管理资源。

  4. 如何使用 DEVICE_OBJECT 控制设备?

    可以通过使用设备控制 (IOCTL) 代码和调用 ZwDeviceIoControl 函数向 DEVICE_OBJECT 发送命令。

  5. 如何跟踪设备的状态变化?

    可以使用 IoRegisterPlugPlayNotification 函数注册设备状态变化通知,以便在设备状态发生变化时收到回调。