Подпрограммы реестра Plug and Play

Диспетчер Plug and Play связывает определенные разделы реестра с драйвером, его устройствами и экземплярами интерфейса устройства. Драйверы могут использовать эти ключи для хранения постоянных свойств, связанных с драйвером, с определенными устройствами или экземплярами интерфейса устройства.

Драйверы никогда не должны получать доступ к этим ключам напрямую. В будущих версиях Windows информация может храниться в другом расположении в реестре или за его пределами. Драйверы не должны напрямую обращаться к ключам в следующих деревьях:

  • HKLM\SYSTEM\CurrentControlSet\Control\Class

  • HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses

  • HKLM\SYSTEM\CurrentControlSet\Enum

  • HKLM\SYSTEM\CurrentControlSet\Hardware Profiles

Вместо этого драйверы используют подпрограммы IoOpenDeviceRegistryKey и IoOpenDeviceInterfaceRegistryKey для доступа к своим ключам PnP.

Диспетчер PnP назначает драйверу один ключ, известный как программный ключ драйвера, и ключ для каждого устройства, известный как аппаратный ключ устройства. Для открытия любого ключа можно использовать подпрограмму IoOpenDeviceRegistryKey . Значение параметра DevInstKeyType определяет, какой ключ следует открыть. Укажите PLUGPLAY_REGKEY_DRIVER для открытия программного ключа или PLUGPLAY_REGKEY_DEVICE к аппаратному ключу. Параметр DeviceObject указывает устройство или драйвер. (Драйвер также может получить доступ к аппаратным и программным ключам относительно текущего профиля оборудования, PLUGPLAY_REGKEY_CURRENT_HWPROFILE AND to DevInstKeyType.)

IoOpenDeviceInterfaceRegistryKey открывает ключ, связанный с определенным экземпляром интерфейса устройства. Экземпляр идентифицируется по его имени, которое представляет собой UNICODE_STRING , возвращенный IoGetDeviceInterfaces, IoGetDeviceInterfaceAlias или IoRegisterDeviceInterface. Строка передается в качестве параметра SymbolicLinkValue в IoOpenDeviceInterfaceRegistryKey.

Эти ключи также можно задать в INF-файле или с помощью подпрограмм SetupDiXxx . Дополнительные сведения см. в разделе Разделы реестра для драйверов.

IoOpenDeviceRegistryKey и IoOpenDeviceInterfaceRegistryKey предоставляют дескриптор открытого ключа с правами доступа, указанными в параметре DesiredAccess. Впоследствии драйвер использует подпрограммы реестра ZwXxx , такие как ZwQueryValueKey и ZwSetValueKey, для доступа к ключу и управления им. После того как драйвер больше не использует дескриптор, драйвер закрывает дескриптор, вызывая ZwClose. Дополнительные сведения см. в разделе Использование дескриптора для объекта Registry-Key.

В следующем примере кода демонстрируется использование IoOpenDeviceRegistryKey и ZwSetValueKey для установки данных, связанных со значением 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.
}

Обратите внимание, что доступ к разделу реестра может быть ограничен, поэтому вызовы IoOpenDeviceRegistryKey и IoOpenDeviceInterfaceRegistryKey должны указывать минимальные права, необходимые для DesiredAccess. Если драйвер запрашивает права доступа, которые не разрешены, любая из подпрограмм возвращает STATUS_ACCESS_DENIED. В частности, драйверы не должны указывать KEY_ALL_ACCESS.