即插即用注册表例程

即插即用管理器将某些注册表项与驱动程序、其设备及其设备接口实例相关联。 驱动程序可以使用这些密钥来存储与驱动程序关联的永久性属性,或者与特定设备或设备接口实例关联的属性。

驱动程序不得直接访问这些密钥。 Windows 的未来版本可能会将信息存储在注册表中的不同位置,或完全存储在注册表外部。 驱动程序不得直接访问以下树中的任何密钥:

  • HKLM\SYSTEM\CurrentControlSet\Control\Class

  • HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses

  • HKLM\SYSTEM\CurrentControlSet\Enum

  • HKLM\SYSTEM\CurrentControlSet\Hardware Profiles

相反,驱动程序使用 IoOpenDeviceRegistryKeyIoOpenDeviceInterfaceRegistryKey 例程来访问其 PnP 密钥。

PnP 管理器为驱动程序分配一个密钥(称为驱动程序的软件密钥),为每个设备分配一个密钥(称为设备的硬件密钥)。 IoOpenDeviceRegistryKey 例程可用于打开任一键。 DevInstKeyType 参数的值确定要打开的键。 指定PLUGPLAY_REGKEY_DRIVER以打开软件密钥,或PLUGPLAY_REGKEY_DEVICE硬件密钥。 DeviceObject 参数指定设备或驱动程序。 (驱动程序还可以通过 ANDing PLUGPLAY_REGKEY_CURRENT_HWPROFILE DevInstKeyType.) 访问相对于当前硬件配置文件的硬件和软件密钥

IoOpenDeviceInterfaceRegistryKey 将打开与特定设备接口实例关联的密钥。 实例由其名称标识,该名称是 IoGetDeviceInterfacesIoGetDeviceInterfaceAliasIoRegisterDeviceInterface 返回的UNICODE_STRING。 字符串作为 SymbolicLinkValue 参数传递到 IoOpenDeviceInterfaceRegistryKey

这些键也可以在 INF 文件中设置,也可以使用 SetupDiXxx 例程进行设置。 有关详细信息,请参阅 驱动程序的注册表项

IoOpenDeviceRegistryKeyIoOpenDeviceInterfaceRegistryKey 都提供一个打开的密钥句柄,其访问权限由 DesiredAccess 参数指定。 驱动程序随后使用 ZwXxx 注册表例程(如 ZwQueryValueKeyZwSetValueKey)来访问和操作密钥。 驱动程序不再使用句柄后,驱动程序通过调用 ZwClose 关闭句柄。 有关详细信息,请参阅 使用 Registry-Key 对象的句柄

以下代码示例演示如何使用 IoOpenDeviceRegistryKeyZwSetValueKey 设置与设备硬件密钥下名为“Value”的值关联的数据。

PDEVICE_OBJECT pDeviceObject; // A pointer to the PDO for the device.
HANDLE handle;
UNICODE_STRING ValueName;
ULONG Value = 109; // This is the value we're setting the key to.
NTSTATUS status;

RtlInitUnicodeString(&ValueName, L"Value");

status = IoOpenDeviceRegistryKey(pDeviceObject, PLUGPLAY_REGKEY_DEVICE, KEY_READ, &handle);

if (NTSUCCESS(status)) {
  status = ZwSetValueKey(handle, ValueName, 0, REG_DWORD, &Value, sizeof(ULONG));
  if (NTSUCCESS(status) {
    ZwClose(handle);
  } else {
    // Handle error.
  }
  // Handle error.
}

请注意,对注册表项的访问可能会受到限制,因此调用 IoOpenDeviceRegistryKeyIoOpenDeviceInterfaceRegistryKey 应指定 DesiredAccess 所需的最低权限。 如果驱动程序请求不允许的访问权限,则任一例程都返回STATUS_ACCESS_DENIED。 具体而言,驱动程序不应指定KEY_ALL_ACCESS。