Freigeben über


RtlQueryRegistryValues-Funktion (wdm.h)

Die RtlQueryRegistryValues-Routine ermöglicht es dem Aufrufer, mehrere Werte aus der Registrierungsunterstruktur mit einem einzelnen Aufruf abzufragen.

Syntax

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

Parameter

[in] RelativeTo

Gibt an , ob Path ein absoluter Registrierungspfad ist oder relativ zu einem vordefinierten Pfad ist.

Wert Bedeutung
RTL_REGISTRY_ABSOLUTE Path ist ein absoluter Registrierungspfad.
RTL_REGISTRY_CONTROL Pfad ist relativ zu \Registry\Machine\System\CurrentControlSet\Control.
RTL_REGISTRY_DEVICEMAP Pfad ist relativ zu \Registry\Machine\Hardware\DeviceMap.
RTL_REGISTRY_SERVICES Pfad ist relativ zu \Registry\Machine\System\CurrentControlSet\Services.
RTL_REGISTRY_USER Pfad ist relativ zu \Registry\User\CurrentUser. (Bei einem Systemprozess ist dies \User\. Standard.)
RTL_REGISTRY_WINDOWS_NT Pfad ist relativ zu \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion.

Der RelativeTo-Wert kann durch bitweise-ORing mit einem der folgenden Flags geändert werden.

Flag Bedeutung
RTL_REGISTRY_OPTIONAL Gibt an, dass der Schlüssel, auf den dieser Parameter verweist, und der Path-Parameter optional sind.
RTL_REGISTRY_HANDLE Gibt an, dass der Path-Parameter tatsächlich ein zu verwendende Registrierungshandle ist.

[in] Path

Zeiger auf einen absoluten Registrierungspfad oder einen Pfad relativ zum bekannten Speicherort, der durch den RelativeTo-Parameter angegeben wird. Beachten Sie, dass die Namen der Schlüssel in einem solchen Pfad dem Aufrufer bekannt sein müssen, einschließlich des letzten Schlüssels im Pfad. Wenn das flag RTL_REGISTRY_HANDLE angegeben ist, ist dieser Parameter ein Registrierungshandle für einen bereits geöffneten Schlüssel, der direkt abgefragt werden soll.

[in, out] QueryTable

Zeiger auf eine Tabelle mit mindestens einem Wertnamen und Unterschlüsselnamen, an denen der Aufrufer interessiert ist. Jeder Tabelleneintrag enthält die Adresse einer vom Aufrufer bereitgestellten QueryRoutine-Funktion , die für jeden Wertnamen aufgerufen wird, der in der Registrierung vorhanden ist. Die Tabelle muss mit einem NULL-Tabelleneintrag beendet werden, bei dem es sich um einen Tabelleneintrag mit einem NULLQueryRoutine-Member und einem NULL Name-Member handelt. Die Struktur für Abfragetabelleneinträge ist wie folgt definiert:

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;

Wenn der Aufrufer Speicher für die Abfragetabelle zuweist, auf die der QueryTable-Parameter verweist, ist der Aufrufer für die Freigabe dieses Speichers verantwortlich, nachdem der Aufruf "RtlQueryRegistryValues" zurückgegeben wird.

QueryRoutine

Die Adresse einer QueryRoutine-Funktion , die mit dem Namen, dem Typ, den Daten und der Datenlänge eines Registrierungswerts aufgerufen wird. Wenn dieses Element und das Name-Elementnull sind, markiert es das Ende der Tabelle.

Eine QueryRoutine-Funktion wird wie folgt deklariert:

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

Weitere Informationen finden Sie unter QueryRoutine.

Flags

Flags, um zu steuern, wie die verbleibenden Member der RTL_QUERY_REGISTRY_TABLE-Struktur interpretiert werden sollen. Für dieses Element werden die folgenden Flagbits definiert.

Wert Bedeutung
RTL_QUERY_REGISTRY_SUBKEY Der Name dieses Tabelleneintrags ist ein weiterer Pfad zu einem Registrierungsschlüssel, und alle folgenden Tabelleneinträge gelten für diesen Schlüssel anstelle des durch den Path-Parameter angegebenen Schlüssels. Diese Änderung des Fokus dauert bis zum Ende der Tabelle oder bis ein anderer RTL_REGISTRY_SUBKEY oder RTL_QUERY_REGISTRY_TOPKEY Eintrag angezeigt wird. Jeder dieser Einträge muss einen Pfad angeben , der relativ zu dem Pfad ist, der im Aufruf von RtlQueryRegistryValues angegeben ist.
RTL_QUERY_REGISTRY_TOPKEY Setzt das aktuelle Registrierungsschlüsselhandle auf das ursprüngliche Handle zurück, das durch die Parameter RelativeTo und Path angegeben wurde. Dies ist nützlich, um zum ursprünglichen Knoten zurückzukehren, nachdem sie in Unterschlüssel mit dem flag RTL_QUERY_REGISTRY_SUBKEY absteigen.
RTL_QUERY_REGISTRY_REQUIRED Gibt an, dass dieser Registrierungswert vorhanden sein muss, wenn DefaultType = REG_NONE; Andernfalls wird RtlQueryRegistryValues sofort mit einem status Code von STATUS_OBJECT_NAME_NOT_FOUND beendet, wenn es nicht gefunden wird. Diese Beendigung erfolgt, wenn das Name-ElementNULL ist und der aktuelle Schlüssel keine Unterschlüssel enthält, oder wenn Name einen nicht vorhandenen Unterschlüssel angibt. (Wenn dieses Flag nicht angegeben wird, verwendet die Routine den DefaultValue-Member als Wert, wenn keine Übereinstimmung für einen Nicht-NULL-Namen gefunden wird. Wenn NameNULL ist und der aktuelle Schlüssel keine Unterschlüssel enthält, überspringt die Routine einfach diesen Tabelleneintrag.)
RTL_QUERY_REGISTRY_NOVALUE Gibt an, dass, obwohl kein Name für diesen Tabelleneintrag vorhanden ist, der Aufrufer nur einen Rückruf wünscht: Das heißt, der Aufrufer möchte nicht alle Werte unter dem aktuellen Schlüssel auflisten. QueryRoutine wird mit NULL für ValueData, REG_NONE für ValueType und null für ValueLength aufgerufen.
RTL_QUERY_REGISTRY_NOEXPAND Bei einem Registrierungswert vom Typ REG_EXPAND_SZ oder REG_MULTI_SZ überschreibt dieses Flag das Standardverhalten, das darin besteht, den Registrierungswert vor dem Aufrufen der QueryRoutine-Routine vorzuverarbeiten. Standardmäßig erweitert RtlQueryRegistryValues Umgebungsvariablenverweise in REG_EXPAND_SZ-Werten und listet jede null-beendete Zeichenfolge in einem REG_MULTI_SZ Wert in einem separaten QueryRoutine-Aufruf auf, sodass die Zeichenfolgen als REG_SZ Werte angezeigt werden, die denselben ValueName aufweisen. Wenn dieses Flag festgelegt ist, empfängt QueryRoutine den unformatierten REG_EXPAND_SZ- oder REG_MULTI_SZ-Wert aus der Registrierung. Weitere Informationen zu den Datenformaten für diese Werte finden Sie unter KEY_VALUE_BASIC_INFORMATION.
RTL_QUERY_REGISTRY_DIRECT Der QueryRoutine-Member wird nicht verwendet (und muss NULL sein), und EntryContext verweist auf den Puffer, um den Wert zu speichern. Wenn der Aufrufer dieses Flag festlegt, sollte der Aufrufer zusätzlich das RTL_QUERY_REGISTRY_TYPECHECK-Flag festlegen, um vor Pufferüberlauf zu schützen. Weitere Informationen finden Sie im Abschnitt mit Hinweisen.
RTL_QUERY_REGISTRY_TYPECHECK Verwenden Sie dieses Flag mit dem RTL_QUERY_REGISTRY_DIRECT Flag, um zu überprüfen, ob der REG_XXX-Typ des gespeicherten Registrierungswerts dem vom Aufrufer erwarteten Typ entspricht. Wenn die Typen nicht übereinstimmen, schlägt der Aufruf fehl. Weitere Informationen finden Sie im Abschnitt mit Hinweisen.
RTL_QUERY_REGISTRY_DELETE Dieses Flag wird verwendet, um Wertschlüssel zu löschen, nachdem sie abgefragt wurden.

Ab Windows 2000 wird posteingangsunterstützung für alle Flagbits in der vorherigen Tabelle bereitgestellt, mit Ausnahme von RTL_QUERY_REGISTRY_TYPECHECK. Posteingangsunterstützung für RTL_QUERY_REGISTRY_TYPECHECK ist ab Windows 8 verfügbar. Für frühere Versionen von Windows wird die Unterstützung für RTL_QUERY_REGISTRY_TYPECHECK über Windows Update bereitgestellt. Weitere Informationen finden Sie in den Hinweisen.

Name

Dies ist der Name eines Werts, den der Aufrufer abgefragt hat. Wenn NameNULL ist, wird die für diesen Tabelleneintrag angegebene QueryRoutine-Funktion für alle Werte aufgerufen, die dem aktuellen Registrierungsschlüssel zugeordnet sind. Wenn das RTL_QUERY_REGISTRY_DIRECT-Flag festgelegt ist, muss ein Wert ohne NULL für Name angegeben werden.

EntryContext

Wenn das flag RTL_QUERY_REGISTRY_DIRECT festgelegt ist, ist dies ein Zeiger auf den Puffer, um das Ergebnis des Abfragevorgangs für diesen Schlüssel zu speichern. Andernfalls wird dieser Wert als EntryContext-Parameter von QueryRoutine übergeben.

Defaulttype

Das am wenigsten signifikante Byte dieses Members gibt den REG_XXX-Typ der zurückzugebenden Daten an, wenn kein übereinstimmenden Schlüssel gefunden und das flag RTL_QUERY_REGISTRY_REQUIRED nicht angegeben ist. Geben Sie REG_NONE für keinen Standardtyp an. Wenn das flag RTL_QUERY_REGISTRY_TYPECHECK festgelegt ist, gibt das wichtigste Byte dieses Members den REG_XXX-Typ des gespeicherten Registrierungswerts an, den der Aufrufer erwartet. Die Bits 8 bis 23 dieses Members sind reserviert und sollten 0 sein.

DefaultData

Ein Zeiger auf den Standardwert, der zurückgegeben werden soll, wenn kein übereinstimmenden Schlüssel gefunden und das RTL_QUERY_REGISTRY_REQUIRED-Flag nicht angegeben wird. Dieses Element wird ignoriert, wenn DefaultType = REG_NONE. Andernfalls sollte der Datentyp, auf den von DefaultData verwiesen wird, dem Registrierungswerttyp entsprechen, der vom DefaultType-Element angegeben wird. Weitere Informationen zu Registrierungswerttypen finden Sie in der Definition des Type-Parameters in KEY_VALUE_BASIC_INFORMATION.

DefaultLength

Gibt die Länge des DefaultData-Elements in Bytes an. Wenn DefaultType REG_SZ, REG_EXPAND_SZ oder REG_MULTI_SZ ist, können Aufrufer optional null angeben, um anzugeben, dass RtlQueryRegistryValues die Länge basierend auf dem Standardwert berechnen soll. Wenn DefaultType = REG_NONE, wird dieses Element ignoriert.

[in, optional] Context

Gibt den Wert an, der bei jedem Aufruf als Context-Parameter einer QueryRoutine-Funktion übergeben wird.

[in, optional] Environment

Zeiger auf die Umgebung, die beim Erweitern von Variablenwerten in REG_EXPAND_SZ Registrierungswerten oder einem NULL-Zeiger (optional) verwendet wird.

Rückgabewert

RtlQueryRegistryValues gibt einen NTSTATUS-Code zurück. Zu den möglichen Rückgabewerten gehören:

Rückgabecode Beschreibung
STATUS_SUCCESS Die gesamte Abfragetabelle wurde erfolgreich verarbeitet.
STATUS_INVALID_PARAMETER Verarbeitung der Abfragetabelle, die mit einem ungültigen Tabelleneintrag beendet wird. Ein Tabelleneintrag kann ungültig sein, wenn für die angegebenen Flags erforderlich ist, dass der QueryRoutine - oder Name-Member nicht NULL ist, aber ein NULL-Wert angegeben wurde.
STATUS_OBJECT_NAME_NOT_FOUND Der Path-Parameter stimmt nicht mit einem gültigen Schlüssel überein, oder die Verarbeitung der Abfragetabelle wird mit einem Eintrag mit dem RTL_QUERY_REGISTRY_REQUIRED Flag festgelegt, und es wurde kein übereinstimmenden Schlüssel gefunden. Dies tritt auf, wenn der Name-Member NULL ist und der aktuelle Schlüssel keine Unterschlüssel enthält, oder wenn Name einen nicht vorhandenen Unterschlüssel angibt.
STATUS_BUFFER_TOO_SMALL Das flag RTL_QUERY_REGISTRY_DIRECT ist festgelegt, und der von EntryContext angegebene Puffer ist zu klein, um die Schlüsselwertdaten zu speichern.
STATUS_OBJECT_TYPE_MISMATCH Das RTL_QUERY_REGISTRY_TYPECHECK-Flag ist festgelegt, und der Typ des gespeicherten Registrierungswerts stimmt nicht mit dem vom Aufrufer erwarteten Typ überein.

RtlQueryRegistryValues beendet auch die Verarbeitung der Tabelle, wenn die QueryRoutine-Funktion für einen Tabelleneintrag einen NTSTATUS-Fehlercode zurückgibt und diesen Fehlercode als Ergebnis zurückgibt. (Mit einer Ausnahme: Wenn QueryRoutine STATUS_BUFFER_TOO_SMALL zurückgibt, wird der Fehlercode ignoriert.)

Hinweise

Der Aufrufer gibt einen anfänglichen Schlüsselpfad und eine Tabelle an. Die Tabelle enthält mindestens einen Eintrag, der die Schlüsselwerte und Unterschlüsselnamen beschreibt, an denen der Aufrufer interessiert ist. Die Tabelle wird durch einen Eintrag mit einem NULLQueryRoutine-Member und einem NULL Name-Member beendet. Die Tabelle muss aus einem nicht ausgestellten Pool zugeordnet werden.

Kernelmodustreiber müssen das flag RTL_QUERY_REGISTRY_NOEXPAND angeben, um das Aufrufen von Umgebungsvariablenroutinen zu verhindern. Diese Routinen sind unsicher, daher sollten Kernelmodustreiber sie nicht verwenden.

Achtung

Wenn Sie das Flag RTL_QUERY_REGISTRY_DIRECT verwenden, kann eine nicht vertrauenswürdige Benutzermodusanwendung möglicherweise einen Pufferüberlauf verursachen. Ein Pufferüberlauf kann auftreten, wenn ein Treiber dieses Flag verwendet, um einen Registrierungswert zu lesen, dem der falsche Typ zugewiesen ist. In allen Fällen sollte ein Treiber, der das RTL_QUERY_REGISTRY_DIRECT-Flag verwendet, zusätzlich das RTL_QUERY_REGISTRY_TYPECHECK-Flag verwenden, um solche Überläufe zu verhindern.

Wenn das RTL_QUERY_REGISTRY_TYPECHECK-Flag in einem Tabelleneintrag festgelegt ist, muss der Aufrufer den erwarteten REG_XXX-Typ in den 8 wichtigsten Bits (MSBs) des 32-Bit-Elements DefaultType des Tabelleneintrags angeben. Wie im folgenden Codebeispiel gezeigt, kann die RTL_QUERY_REGISTRY_TYPECHECK_SHIFT Konstante, die als 24 definiert ist, als Schichtanzahl verwendet werden, die erforderlich ist, um den erwarteten REG_XXX-Typ in den 8 MSBs des DefaultType-Members zu platzieren.

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;
...

Wenn ein RtlQueryRegistryValues-Aufruf ab Windows 8 auf eine nicht vertrauenswürdige Struktur zugreift und der Aufrufer das RTL_QUERY_REGISTRY_DIRECT-Flag für diesen Aufruf festlegt, muss der Aufrufer zusätzlich das RTL_QUERY_REGISTRY_TYPECHECK-Flag festlegen. Ein Verstoß gegen diese Regel durch einen Aufruf aus dem Benutzermodus führt zu einer Ausnahme. Ein Verstoß gegen diese Regel durch einen Aufruf aus dem Kernelmodus verursacht eine 0x139 Fehlerprüfung (KERNEL_SECURITY_CHECK_FAILURE).

Nur Systemstrukturen werden vertrauenswürdig. Ein RtlQueryRegistryValues-Aufruf , der auf eine Systemstruktur zugreift, verursacht keine Ausnahme oder Fehlerüberprüfung, wenn das RTL_QUERY_REGISTRY_DIRECT-Flag festgelegt ist und das RTL_QUERY_REGISTRY_TYPECHECK-Flag nicht festgelegt ist. Als bewährte Methode sollte jedoch immer das RTL_QUERY_REGISTRY_TYPECHECK-Flag festgelegt werden, wenn das RTL_QUERY_REGISTRY_DIRECT-Flag festgelegt ist.

Ebenso sollte in Versionen von Windows vor Windows 8 als bewährte Methode ein RtlQueryRegistryValues-Aufruf, der das RTL_QUERY_REGISTRY_DIRECT-Flag festlegt, zusätzlich das RTL_QUERY_REGISTRY_TYPECHECK-Flag festlegen. Die Nichteinhaltung dieser Empfehlung führt jedoch nicht zu einer Ausnahme oder Fehlerüberprüfung.

Im Folgenden ist eine Liste der Systemstrukturen aufgeführt:

  • \REGISTRY\MACHINE\HARDWARE

  • \REGISTRY\MACHINE\SOFTWARE

  • \REGISTRY\MACHINE\SYSTEM

  • \REGISTRY\MACHINE\SECURITY

  • \REGISTRY\MACHINE\SAM

Unterstützung für das RTL_QUERY_REGISTRY_TYPECHECK-Flag ist über Windows Update für Windows 7, Windows Vista, Windows Server 2003 und Windows XP verfügbar. Weitere Informationen zu diesem Update finden Sie unter Sicherheitsrisiken im Windows-Kernel können Rechteerweiterungen (2393802) zulassen. In Versionen dieser Betriebssysteme, die nicht über dieses Update verfügen, kann der Aufrufer das flag RTL_QUERY_REGISTRY_TYPECHECK verwenden. Dieses Flag wird jedoch von der RtlQueryRegistryValues-Routine ignoriert.

Ab Windows Driver Kit (WDK) 8 wird das RTL_QUERY_REGISTRY_TYPECHECK-Flag in der Wdm.h-Headerdatei wie folgt definiert:

#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100

Wenn ein Eintrag das flag "RTL_QUERY_REGISTRY_DIRECT" nicht angibt, verwendet RtlQueryRegistryValues die angegebene QueryRoutine-Funktion , um dem Aufrufer den Wertnamen, den Typ, die Daten und die Datenlänge in Bytes zu melden. Wenn das Element Name des Eintrags NULL ist, meldet RtlQueryRegistryValues jeden direkten Unterschlüssel des Schlüssels. Wenn der Schlüsseltyp REG_MULTI_SZ ist und das RTL_QUERY_REGISTRY_NOEXPAND-Flag nicht angegeben ist, ruft die Routine QueryRoutine separat für jede einzelne Zeichenfolge auf. andernfalls meldet die Routine sie als einzelnen Wert. Wenn ein Eintrag das Flag RTL_QUERY_REGISTRY_DIRECT angibt, speichert RtlQueryRegistryValues den Wert des Schlüssels im Puffer, auf den das EntryContext-Element des Eintrags verweist. Das Format der zurückgegebenen Daten lautet wie folgt.

Schlüsseldatentyp Rückgabe von Daten
Eine Unicode-Zeichenfolge mit Null-Endung (z. B. REG_SZ, REG_EXPAND_SZ). EntryContext muss auf eine initialisierte UNICODE_STRING Struktur verweisen. Wenn der Puffermembervon UNICODE_STRINGNULL ist, weist die Routine Speicher für die Zeichenfolgendaten zu. Andernfalls werden die Zeichenfolgendaten im Puffer gespeichert, auf den Buffer verweist.
REG_MULTI_SZ Sie müssen das RTL_QUERY_REGISTRY_NOEXPAND-Flag für diesen Schlüsseldatentyp angeben. EntryContext verweist auf eine initialisierte UNICODE_STRING-Struktur . In der Routine wird der Schlüsselwert als einzelner Zeichenfolgenwert gespeichert. Jede einzelne Komponente innerhalb der Zeichenfolge wird mit einer Null beendet. Wenn der Puffermembervon UNICODE_STRINGNULL ist, weist die Routine Speicher für die Zeichenfolgendaten zu. Andernfalls werden die Zeichenfolgendaten im Puffer gespeichert, auf den Buffer verweist.
Nicht zeichenfolgenfreie Daten mit der Größe in Bytes = <sizeof(ULONG) Der Wert wird in dem von EntryContext angegebenen Speicherspeicherort gespeichert.
Nicht zeichenfolgenfreie Daten mit size, in Bytes, >sizeof(ULONG) Der Puffer, auf den EntryContext verweist, muss mit einem signierten LONG-Wert beginnen. Die Größe des Werts muss die Größe des Puffers in Bytes angeben. Wenn das Vorzeichen des Werts negativ ist, speichert RtlQueryRegistryValues nur die Daten des Schlüsselwerts. Andernfalls wird die erste ULONG im Puffer verwendet, um die Wertlänge in Bytes, die zweite ULONG zum Aufzeichnen des Werttyps und den Rest des Puffers zum Speichern der Wertdaten aufzuzeichnen.

Wenn in einem beliebigen Verarbeitungsstadium der Abfragetabelle ein Fehler auftritt, beendet RtlQueryRegistryValues die Verarbeitung der Tabelle und gibt den Fehler status zurück.

Eine Beschreibung der möglichen REG_XXX-Werte finden Sie unter ZwSetValueKey.

Anforderungen

Anforderung Wert
Zielplattform Universell
Header wdm.h (einschließlich Wdm.h, Ntddk.h, Ntifs.h)
Bibliothek Ntoskrnl.lib
DLL Ntoskrnl.exe
IRQL PASSIVE_LEVEL

Weitere Informationen

QueryRoutine

RtlZeroMemory

UNICODE_STRING

ZwEnumerateKey

ZwEnumerateValueKey

ZwSetValueKey