プラグ アンド プレイ レジストリ ルーチン
プラグ アンド プレイ マネージャーは、特定のレジストリ キーをドライバー、そのデバイス、およびそのデバイス インターフェイス インスタンスに関連付けます。 ドライバーはこれらのキーを使用して、そのドライバーに関連付けられているか、または特定のデバイスやデバイス インターフェイス インスタンスに関連付けられている永続的なプロパティを格納できます。
ドライバーでは、これらのキーに直接アクセスしないでください。 今後のバージョンの Windows では、レジストリ内の別の場所、または完全にレジストリの外にある場所に情報が格納される可能性があります。 ドライバーは、次のツリー内のキーに直接アクセスすることはできません。
HKLM\SYSTEM\CurrentControlSet\Control\Class
HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses
HKLM\SYSTEM\CurrentControlSet\Enum
HKLM\SYSTEM\CurrentControlSet\Hardware Profiles
代わりに、ドライバーは、PnP キーにアクセスするために IoOpenDeviceRegistryKey ルーチンと IoOpenDeviceInterfaceRegistryKey ルーチンを使用します。
PnP マネージャーは、ドライバーのソフトウェア キーと呼ばれるキーをドライバーに 1 つ割り当て、デバイスのハードウェア キーと呼ばれるキーをデバイスごとに 1 つずつ割り当てます。 IoOpenDeviceRegistryKey ルーチンを使用して、いずれかのキーを開くことができます。 DevInstKeyType パラメーターの値によって、開くキーが決まります。 ソフトウェア キーを開くには PLUGPLAY_REGKEY_DRIVER を指定し、ハードウェア キーを開くには PLUGPLAY_REGKEY_DEVICE を指定します。 DeviceObject パラメーターは、デバイスまたはドライバーを指定します。 (ドライバーは、PLUGPLAY_REGKEY_CURRENT_HWPROFILE と DevInstKeyType を AND 演算して、現在のハードウェア プロファイルに関連するハードウェア キーとソフトウェア キーにアクセスすることもできます。)
IoOpenDeviceInterfaceRegistryKey は、特定のデバイス インターフェイス インスタンスに関連付けられているキーを開きます。 このインスタンスは、その名前によって識別されます。これは、IoGetDeviceInterfaces、IoGetDeviceInterfaceAlias、または IoRegisterDeviceInterface によって返される UNICODE_STRING です。 文字列は、SymbolicLinkValue パラメーターとして IoOpenDeviceInterfaceRegistryKey に渡されます。
これらのキーは、INF ファイルで設定することも、SetupDiXxx ルーチンを使用して設定することもできます。 詳細については、「ドライバーのレジストリ キー」を参照してください。
IoOpenDeviceRegistryKey と IoOpenDeviceInterfaceRegistryKey はどちらも、DesiredAccess パラメーターで指定したアクセス権でオープン キー ハンドルを提供します。 その後、ドライバーは、ZwQueryValueKey や ZwSetValueKey などの ZwXxx レジストリ ルーチンを使用して、キーにアクセスして操作します。 ドライバーがハンドルを使用しなくなった後、ドライバーは ZwClose を呼び出してハンドルを閉じます。 詳細については、「レジストリ キー オブジェクトのハンドルの使用」を参照してください。
次のコード サンプルでは、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 を指定しないでください。