플러그 앤 플레이 레지스트리 루틴
플러그 앤 플레이 관리자는 특정 레지스트리 키를 드라이버, 해당 디바이스 및 해당 디바이스 인터페이스 인스턴스와 연결합니다. 드라이버는 이러한 키를 사용하여 드라이버 또는 특정 디바이스 또는 디바이스 인터페이스 인스턴스와 연결된 영구 속성을 저장할 수 있습니다.
드라이버는 이러한 키에 직접 액세스해서는 안됩니다. 이후 버전의 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_DEVICE PLUGPLAY_REGKEY_DRIVER 지정합니다. DeviceObject 매개 변수는 디바이스 또는 드라이버를 지정합니다. 또한 드라이버는 DEVInstKeyType에 대한 PLUGPLAY_REGKEY_CURRENT_HWPROFILE ANDing을 통해 현재 하드웨어 프로필에 상대적인 하드웨어 및 소프트웨어 키에 액세스할 수도 있습니다.
IoOpenDeviceInterfaceRegistryKey는 특정 디바이스 인터페이스 instance 연결된 키를 엽니다. instance IoGetDeviceInterfaces, IoGetDeviceInterfaceAlias 또는 IoRegisterDeviceInterface에서 반환된 UNICODE_STRING 이름으로 식별됩니다. 문자열은 IoOpenDeviceInterfaceRegistryKey에 SymbolicLinkValue 매개 변수로 전달됩니다.
이러한 키는 INF 파일이나 SetupDiXxx 루틴을 사용하여 설정할 수도 있습니다. 자세한 내용은 드라이버용 레지스트리 키를 참조하세요.
IoOpenDeviceRegistryKey와 IoOpenDeviceInterfaceRegistryKey는 모두 DesiredAccess 매개 변수에 지정된 액세스 권한으로 열린 키 핸들을 제공합니다. 이후 드라이버는 ZwQueryValueKey 및 ZwSetValueKey와 같은 ZwXxx 레지스트리 루틴을 사용하여 키에 액세스하고 조작합니다. 드라이버가 더 이상 핸들을 사용하지 않으면 드라이버는 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 지정해서는 안 됩니다.