次の方法で共有


RtlQueryRegistryValues 関数 (wdm.h)

RtlQueryRegistryValues ルーチンを使用すると、呼び出し元はレジストリ サブツリーから 1 回の呼び出しで複数の値を照会できます。

構文

NTSYSAPI NTSTATUS RtlQueryRegistryValues(
  [in]           ULONG                     RelativeTo,
  [in]           PCWSTR                    Path,
  [in, out]      PRTL_QUERY_REGISTRY_TABLE QueryTable,
  [in, optional] PVOID                     Context,
  [in, optional] PVOID                     Environment
);

パラメーター

[in] RelativeTo

Path が絶対レジストリ パスであるか、または定義済みのパスを基準にするかを次のいずれかの方法で指定します。

価値 意味
RTL_REGISTRY_ABSOLUTE パスは絶対レジストリ パスです。
RTL_REGISTRY_CONTROL パスは、\Registry\Machine\System\CurrentControlSet\Controlに対する相対パスです。
RTL_REGISTRY_DEVICEMAP パスは、\Registry\Machine\Hardware\DeviceMapに対する相対パスです。
RTL_REGISTRY_SERVICES パスは \Registry\Machine\System\CurrentControlSet\Servicesに対する相対パスです。
RTL_REGISTRY_USER パスは、\Registry\User\CurrentUserに対する相対パスです。 (システム プロセスの場合、これは \User\ です。既定の.)
RTL_REGISTRY_WINDOWS_NT パスは、\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersionに対する相対パスです。

RelativeTo 値は、次のいずれかのフラグを使用してビットごとの ORing によって変更できます。

意味
RTL_REGISTRY_OPTIONAL このパラメーターと Path パラメーターによって参照されるキーが省略可能であることを指定します。
RTL_REGISTRY_HANDLE Path パラメーターが実際に使用するレジストリ ハンドルであることを指定します。

[in] Path

RelativeTo パラメーターで指定された既知の場所を基準とする絶対レジストリ パスまたはパスへのポインター。 このようなパス内のキーの名前は、パスの最後のキーを含め、呼び出し元に認識されている必要があることに注意してください。 RTL_REGISTRY_HANDLE フラグが指定されている場合、このパラメーターは、既に開かれているキーを直接照会するためのレジストリ ハンドルです。

[in, out] QueryTable

呼び出し元が関心を持つ 1 つ以上の値名とサブキー名のテーブルへのポインター。 各テーブル エントリには、呼び出し元が指定した QueryRoutine 関数のアドレスが含まれています。この関数は、レジストリに存在する値の名前ごとに呼び出されます。 テーブルは、NULL テーブル エントリで終了する必要があります。これは、NULLQueryRoutine メンバーと NULLName メンバーを持つテーブル エントリです。 クエリ テーブル エントリの構造は、次のように定義されます。

typedef struct _RTL_QUERY_REGISTRY_TABLE {
    PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
    ULONG Flags;
    PWSTR Name;
    PVOID EntryContext;
    ULONG DefaultType;
    PVOID DefaultData;
    ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;

呼び出し元が、QueryTable パラメーターが指すクエリ テーブルにストレージを割り当てる場合、呼び出し元は、呼び出しが返 RtlQueryRegistryValues の後にこのストレージを解放します。

QueryRoutine

レジストリ値の名前、型、データ、およびデータ長で呼び出される QueryRoutine 関数のアドレス。 このメンバーと Name メンバーの両方が NULL場合は、テーブルの末尾をマークします。

QueryRoutine 関数は、次のように宣言されます。

NTSTATUS
QueryRoutine (
    IN PWSTR ValueName,
    IN ULONG ValueType,
    IN PVOID ValueData,
    IN ULONG ValueLength,
    IN PVOID Context,
    IN PVOID EntryContext
    );

詳細については、「QueryRoutineの を参照してください。

フラグ

RTL_QUERY_REGISTRY_TABLE 構造体の残りのメンバーの解釈方法を制御するフラグ。 このメンバーには、次のフラグ ビットが定義されています。

価値 意味
RTL_QUERY_REGISTRY_SUBKEY このテーブル エントリの はレジストリ キーへの別のパスであり、次のすべてのテーブル エントリは、Path パラメーターで指定されたキーではなく、そのキー用です。 このフォーカスの変更は、テーブルの終わりまで、または別のRTL_REGISTRY_SUBKEYまたはRTL_QUERY_REGISTRY_TOPKEYエントリが表示されるまで続きます。 このような各エントリでは、RtlQueryRegistryValuesの呼び出しで指定された Path を基準とするパス 指定する必要があります。
RTL_QUERY_REGISTRY_TOPKEY 現在のレジストリ キー ハンドルを、RelativeTo および Path パラメーターで指定された元のレジストリ キー ハンドルにリセットします。 これは、RTL_QUERY_REGISTRY_SUBKEY フラグを使用してサブキーに降りた後に元のノードに戻る場合に便利です。
RTL_QUERY_REGISTRY_REQUIRED DefaultType = REG_NONE 場合、このレジストリ値が存在する必要があることを指定します。見つからない場合は、RtlQueryRegistryValues 状態コードSTATUS_OBJECT_NAME_NOT_FOUNDですぐに終了します。 この終了は、Name メンバーが NULL 、現在のキーにサブキーがない場合、または存在しないサブキー Name が指定されている場合に発生します。 (このフラグが指定されていない場合、NULLNameに一致するものが見つからない場合、ルーチンは DefaultValue メンバーを値として使用します。名前 が NULL され、現在のキーにサブキーがない場合、ルーチンはそのテーブル エントリをスキップするだけです)。
RTL_QUERY_REGISTRY_NOVALUE このテーブル エントリに 名前 がない場合でも、すべての呼び出し元が必要とするコールバックを指定します。つまり、呼び出し元が現在のキーのすべての値を列挙する必要はありません。 QueryRoutine は、ValueDataの場合 NULLValueTypeの場合は REG_NONE、ValueLengthの場合は 0 呼び出されます。
RTL_QUERY_REGISTRY_NOEXPAND REG_EXPAND_SZ型またはREG_MULTI_SZ型のレジストリ値の場合、このフラグは既定の動作をオーバーライドします。これは、QueryRoutine ルーチンを呼び出す前にレジストリ値を前処理することです。 既定では、RtlQueryRegistryValues は、環境変数の参照をREG_EXPAND_SZ値で展開し、個別の QueryRoutine 呼び出しでREG_MULTI_SZ値内の各 null 終端文字列を列挙し、同じ ValueNameを持つREG_SZ値として文字列が表示されるようにします。 このフラグが設定されている場合、QueryRoutine レジストリから生のREG_EXPAND_SZまたはREG_MULTI_SZ値を受け取ります。 これらの値のデータ形式の詳細については、KEY_VALUE_BASIC_INFORMATIONを参照してください。
RTL_QUERY_REGISTRY_DIRECT QueryRoutine メンバーは使用されず (また、NULLする必要があります)、EntryContext は値を格納するためにバッファーを指します。 呼び出し元がこのフラグを設定した場合、呼び出し元は、バッファー オーバーフローから保護するために、さらに RTL_QUERY_REGISTRY_TYPECHECK フラグを設定する必要があります。 詳細については、「解説」セクションを参照してください。
RTL_QUERY_REGISTRY_TYPECHECK このフラグをRTL_QUERY_REGISTRY_DIRECT フラグと共に使用して、格納されているレジストリ値のREG_XXX 型が呼び出し元が期待する型と一致することを確認します。 型が一致しない場合、呼び出しは失敗します。 詳細については、「解説」セクションを参照してください。
RTL_QUERY_REGISTRY_DELETE このフラグは、クエリが実行された後に値キーを削除するために使用されます。

Windows 2000 以降では、RTL_QUERY_REGISTRY_TYPECHECKを除き、前の表のすべてのフラグ ビットに対して受信トレイのサポートが提供されます。 RTL_QUERY_REGISTRY_TYPECHECKの受信トレイサポートは、Windows 8 以降で利用できます。 以前のバージョンの Windows では、RTL_QUERY_REGISTRY_TYPECHECKのサポートは Windows Update を通じて提供されます。 詳細については、「解説」を参照してください。

名前

これは、呼び出し元が照会した値の名前です。 名前 が NULL場合、現在のレジストリ キーに関連付けられているすべての値に対して、このテーブル エントリに指定された QueryRoutine 関数が呼び出されます。 RTL_QUERY_REGISTRY_DIRECT フラグが設定されている場合は、Name に対して、以外の NULL 値を指定する必要があります。

EntryContext

RTL_QUERY_REGISTRY_DIRECT フラグが設定されている場合、これは、このキーのクエリ操作の結果を格納するバッファーへのポインターです。 それ以外の場合、この値は QueryRoutineの EntryContext パラメーター 渡されます。

DefaultType

このメンバーの最下位バイトは、一致するキーが見つからず、RTL_QUERY_REGISTRY_REQUIRED フラグが指定されていない場合に、返されるデータのREG_XXX 型を指定します。 既定の型を指定しない場合は、REG_NONEを指定します。 RTL_QUERY_REGISTRY_TYPECHECK フラグが設定されている場合、このメンバーの最上位バイトは、呼び出し元が期待する格納されているレジストリ値のREG_XXX 型を指定します。 このメンバーのビット 8 から 23 は予約されており、ゼロにする必要があります。

DefaultData

一致するキーが見つからず、RTL_QUERY_REGISTRY_REQUIRED フラグが指定されていない場合に返される既定値へのポインター。 DefaultType = REG_NONE 場合、このメンバーは無視されます。 それ以外の場合、DefaultData が指すデータの型は、DefaultType メンバーで指定されたレジストリ値の型に準拠している必要があります。 レジストリ値型の詳細については、KEY_VALUE_BASIC_INFORMATIONType パラメーターの定義を参照してください。

DefaultLength

DefaultData メンバーの長さをバイト単位で指定します。 DefaultType がREG_SZ、REG_EXPAND_SZ、またはREG_MULTI_SZ 場合、呼び出し元は必要に応じて 0 を指定して、RtlQueryRegistryValues 既定のデータ値に基づいて長さを計算する必要があることを示すことができます。 DefaultType = REG_NONEの場合、このメンバーは無視されます。

[in, optional] Context

呼び出されるたびに、QueryRoutine 関数の Context パラメーターとして渡される値を指定します。

[in, optional] Environment

REG_EXPAND_SZレジストリ値の変数値を展開するときに使用する環境へのポインター、または NULL ポインター (省略可能)。

戻り値

RtlQueryRegistryValues NTSTATUS コードを返します。 可能な戻り値は次のとおりです。

リターン コード 形容
STATUS_SUCCESS クエリ テーブル全体が正常に処理されました。
STATUS_INVALID_PARAMETER 無効なテーブル エントリで終了したクエリ テーブルの処理。 指定したフラグで、QueryRoutine または Name メンバーが非NULLである必要があるが、NULL 値が指定されている場合、テーブル エントリは無効になる可能性があります。
STATUS_OBJECT_NAME_NOT_FOUND Path パラメーターが有効なキーと一致しないか、RTL_QUERY_REGISTRY_REQUIRED フラグが設定され、一致するキーが見つからないエントリで終了したクエリ テーブルの処理。 これは、Name メンバーが NULL であり、現在のキーにサブキーがない場合、または存在しないサブキー Name 指定されている場合に発生します。
STATUS_BUFFER_TOO_SMALL RTL_QUERY_REGISTRY_DIRECT フラグが設定され、EntryContext で指定されたバッファーが小さすぎてキー値データを保持できません。
STATUS_OBJECT_TYPE_MISMATCH RTL_QUERY_REGISTRY_TYPECHECK フラグが設定され、格納されているレジストリ値の型が呼び出し元が予期する型と一致しません。

RtlQueryRegistryValues は、テーブル エントリの QueryRoutine 関数が NTSTATUS エラー コードを返し、そのエラー コードを結果として返す場合にも、テーブルの処理を終了します。 (ただし、QueryRoutine がSTATUS_BUFFER_TOO_SMALLを返した場合、エラー コードは無視されます)。

備考

呼び出し元は、初期キー パスとテーブルを指定します。 テーブルには、呼び出し元が関心を持つキー値とサブキー名を記述する 1 つ以上のエントリが含まれています。 テーブルは、NULLQueryRoutine メンバーと NULLName メンバーを持つエントリによって終了されます。 テーブルは、非ページ プールから割り当てる必要があります。

カーネル モード ドライバーは、環境変数ルーチンの呼び出しを防ぐために、RTL_QUERY_REGISTRY_NOEXPAND フラグを指定する必要があります。 これらのルーチンは安全ではないため、カーネル モード ドライバーでは使用しないでください。

注意

RTL_QUERY_REGISTRY_DIRECT フラグを使用すると、信頼されていないユーザー モード アプリケーションでバッファー オーバーフローが発生する可能性があります。 バッファー オーバーフローは、ドライバーがこのフラグを使用して、間違った型が割り当てられているレジストリ値を読み取る場合に発生する可能性があります。 いずれの場合も、RTL_QUERY_REGISTRY_DIRECT フラグを使用するドライバーでは、このようなオーバーフローを防ぐために、RTL_QUERY_REGISTRY_TYPECHECK フラグを使用する必要があります。

RTL_QUERY_REGISTRY_TYPECHECK フラグがテーブル エントリに設定されている場合、呼び出し元は、テーブル エントリの 32 ビット DefaultType メンバーの 8 つの最上位ビット (MSB) で、予期されるREG_XXX 型を指定する必要があります。 次のコード例に示すように、RTL_QUERY_REGISTRY_TYPECHECK_SHIFT定数は 24 と定義されており、予期されるREG_XXX 型を DefaultType メンバーの 8 MSB に配置するために必要なシフト数として使用できます。

RTL_QUERY_REGISTRY_TABLE QueryRegTable[2];    
...
QueryRegTable[0].DefaultType = (REG_SZ << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
...
QueryRegTable[1].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
...

Windows 8 以降では、RtlQueryRegistryValues 呼び出しが信頼されていないハイブにアクセスし、呼び出し元がこの呼び出しにRTL_QUERY_REGISTRY_DIRECT フラグを設定した場合、呼び出し元はRTL_QUERY_REGISTRY_TYPECHECK フラグを追加で設定する必要があります。 ユーザー モードからの呼び出しによってこの規則に違反すると、例外が発生します。 カーネル モードからの呼び出しによってこの規則に違反すると、0x139バグ チェック (KERNEL_SECURITY_CHECK_FAILURE) が発生します。

システム ハイブのみが信頼されます。 システム ハイブにアクセスする RtlQueryRegistryValues 呼び出しでは、RTL_QUERY_REGISTRY_DIRECT フラグが設定されていて、RTL_QUERY_REGISTRY_TYPECHECK フラグが設定されていない場合、例外やバグ チェックは発生しません。 ただし、ベスト プラクティスとして、RTL_QUERY_REGISTRY_DIRECT フラグが設定されている場合は、常にRTL_QUERY_REGISTRY_TYPECHECK フラグを設定する必要があります。

同様に、Windows 8 より前のバージョンの Windows では、ベスト プラクティスとして、RTL_QUERY_REGISTRY_DIRECT フラグを設定する rtlQueryRegistryValues 呼び出し 、さらにRTL_QUERY_REGISTRY_TYPECHECK フラグを設定する必要があります。 ただし、この推奨事項に従わないと、例外やバグ チェックは発生しません。

システム ハイブの一覧を次に示します。

  • \REGISTRY\MACHINE\HARDWARE

  • \REGISTRY\MACHINE\SOFTWARE

  • \REGISTRY\MACHINE\SYSTEM

  • \REGISTRY\MACHINE\SECURITY

  • \REGISTRY\MACHINE\SAM

RTL_QUERY_REGISTRY_TYPECHECK フラグのサポートは、Windows 7、Windows Vista、Windows Server 2003、および Windows XP の Windows Update を通じて利用できます。 この更新プログラムの詳細については、「Windows カーネルの脆弱性により、特権の昇格 (2393802)を参照してください。 この更新プログラムがないこれらのオペレーティング システムのバージョンでは、呼び出し元は RTL_QUERY_REGISTRY_TYPECHECK フラグを使用できます。 ただし、このフラグは、RtlQueryRegistryValues ルーチンでは無視されます。

Windows Driver Kit (WDK) 8 以降では、RTL_QUERY_REGISTRY_TYPECHECK フラグは Wdm.h ヘッダー ファイルで次のように定義されています。

#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100

エントリで RTL_QUERY_REGISTRY_DIRECT フラグが指定されていない場合、RtlQueryRegistryValues は、指定された QueryRoutine 関数を使用して、値の名前、型、データ、およびデータ長をバイト単位で呼び出し元に報告します。 エントリの Name メンバーが NULL場合、RtlQueryRegistryValues キーのすべての直接サブキーが報告。 キーの種類がREG_MULTI_SZされ、RTL_QUERY_REGISTRY_NOEXPAND フラグが指定されていない場合、ルーチンは個々の文字列に対して個別 QueryRoutine を呼び出します。それ以外の場合、ルーチンは単一の値として報告します。 エントリが RTL_QUERY_REGISTRY_DIRECT フラグを指定 場合、RtlQueryRegistryValues エントリの EntryContext メンバーが指すバッファーにキーの値を格納します。 返されるデータの形式は次のとおりです。

キー データ型 データの返し方
null で終わる Unicode 文字列 (REG_SZ、REG_EXPAND_SZ など)。 EntryContext は、初期化された UNICODE_STRING 構造体を指す必要があります。 UNICODE_STRINGBuffer メンバーが NULL場合、ルーチンは文字列データにストレージを割り当てます。 それ以外の場合は、バッファー が指すバッファー 文字列データが格納されます。
REG_MULTI_SZ このキー データ型には、RTL_QUERY_REGISTRY_NOEXPAND フラグを指定する必要があります。 EntryContext は、初期化された UNICODE_STRING 構造体を指します。 ルーチンは、キー値を 1 つの文字列値として格納します。 文字列内の各コンポーネントは、0 で終了します。 UNICODE_STRINGBuffer メンバーが NULL場合、ルーチンは文字列データにストレージを割り当てます。 それ以外の場合は、バッファー が指すバッファー 文字列データが格納されます。
サイズがバイト単位の非文字列データ (<= sizeof(ULONG) この値は、EntryContextで指定されたメモリ位置に格納されます。
size、バイト単位、>sizeof(ULONG) の非文字列データ EntryContext が指すバッファーは、符号付き LONG 値で始まる必要があります。 値の大きさは、バッファーのサイズ (バイト単位) を指定する必要があります。 値の符号が負の場合、RtlQueryRegistryValues キー値のデータのみが格納されます。 それ以外の場合は、バッファー内の最初の ULONG を使用して値の長さをバイト単位で記録し、2 番目の ULONG を使用して値の型を記録し、残りのバッファーを使用して値データを格納します。

クエリ テーブルの処理の任意の段階でエラーが発生した場合は、RtlQueryRegistryValues テーブルの処理を停止し、エラーの状態を返します。

可能なREG_XXX 値の説明については、ZwSetValueKey の を参照してください。

必要条件

要件 価値
ターゲット プラットフォーム の 万国
ヘッダー wdm.h (Wdm.h、Ntddk.h、Ntifs.h を含む)
ライブラリ Ntoskrnl.lib
DLL Ntoskrnl.exe
IRQL PASSIVE_LEVEL

関連項目

QueryRoutine

RtlZeroMemory の

UNICODE_STRING

ZwEnumerateKey

ZwEnumerateValueKey

ZwSetValueKey