Partager via


Fonction RtlQueryRegistryValues (wdm.h)

La routine RtlQueryRegistryValues permet à l’appelant d’interroger plusieurs valeurs à partir de la sous-arborescence du Registre avec un seul appel.

Syntaxe

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

Paramètres

[in] RelativeTo

Spécifie si path est un chemin de Registre absolu ou est relatif à un chemin prédéfini comme suit.

Valeur Signification
RTL_REGISTRY_ABSOLUTE Path est un chemin d’accès absolu au Registre.
RTL_REGISTRY_CONTROL Le chemin d’accès est relatif à \Registry\Machine\System\CurrentControlSet\Control.
RTL_REGISTRY_DEVICEMAP Le chemin d’accès est relatif à \Registry\Machine\Hardware\DeviceMap.
RTL_REGISTRY_SERVICES Le chemin d’accès est relatif à \Registry\Machine\System\CurrentControlSet\Services.
RTL_REGISTRY_USER Le chemin d’accès est relatif à \Registry\User\CurrentUser. (Pour un processus système, il s’agit de \User\. Par défaut.)
RTL_REGISTRY_WINDOWS_NT Le chemin d’accès est relatif à \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion.

La valeur RelativeTo peut être modifiée par oRing au niveau du bit avec l’un des indicateurs suivants.

Indicateur Signification
RTL_REGISTRY_OPTIONAL Spécifie que la clé référencée par ce paramètre et le paramètre Path sont facultatifs.
RTL_REGISTRY_HANDLE Spécifie que le paramètre Path est en fait un handle de Registre à utiliser.

[in] Path

Pointeur vers un chemin de Registre absolu ou un chemin relatif à l’emplacement connu spécifié par le paramètre RelativeTo . Notez que les noms des clés d’un tel chemin d’accès doivent être connus de l’appelant, y compris la dernière clé du chemin. Si l’indicateur RTL_REGISTRY_HANDLE est spécifié, ce paramètre est un handle de Registre pour qu’une clé déjà ouverte soit interrogée directement.

[in, out] QueryTable

Pointeur vers une table d’un ou plusieurs noms de valeurs et de sous-clés qui intéressent l’appelant. Chaque entrée de table contient l’adresse d’une fonction QueryRoutine fournie par l’appelant qui sera appelée pour chaque nom de valeur existant dans le Registre. La table doit être terminée par une entrée de table NULL, qui est une entrée de table avec un membre QueryRoutineNULL et un membre NomNULL. La structure des entrées de table de requête est définie comme suit :

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;

Si l’appelant alloue du stockage pour la table de requête pointée vers le paramètre QueryTable , l’appelant est chargé de libérer ce stockage après le retour de l’appel RtlQueryRegistryValues .

QueryRoutine

Adresse d’une fonction QueryRoutine appelée avec le nom, le type, les données et la longueur des données d’une valeur de Registre. Si ce membre et le membre Name sont tous les deux NULL, cela marque la fin de la table.

Une fonction QueryRoutine est déclarée comme suit :

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

Pour plus d’informations, consultez QueryRoutine.

Indicateurs

Indicateurs permettant de contrôler la façon dont les membres restants de la structure RTL_QUERY_REGISTRY_TABLE doivent être interprétés. Les bits d’indicateur suivants sont définis pour ce membre.

Valeur Signification
RTL_QUERY_REGISTRY_SUBKEY Le Nom de cette entrée de table est un autre chemin d’accès à une clé de Registre, et toutes les entrées de table suivantes sont destinées à cette clé plutôt que la clé spécifiée par le paramètre Path . Ce changement de focus dure jusqu’à la fin de la table ou jusqu’à ce qu’une autre entrée RTL_REGISTRY_SUBKEY ou RTL_QUERY_REGISTRY_TOPKEY s’affiche. Chaque entrée de ce type doit spécifier un chemin relatif au chemin spécifié dans l’appel à RtlQueryRegistryValues.
RTL_QUERY_REGISTRY_TOPKEY Réinitialise le handle de clé de Registre actuel à celui d’origine spécifié par les paramètres RelativeTo et Path . Cela est utile pour revenir au nœud d’origine après être descendu dans les sous-clés avec l’indicateur RTL_QUERY_REGISTRY_SUBKEY.
RTL_QUERY_REGISTRY_REQUIRED Spécifie que cette valeur de Registre doit exister si DefaultType = REG_NONE ; sinon, s’il est introuvable, RtlQueryRegistryValues se ferme immédiatement avec un code status de STATUS_OBJECT_NAME_NOT_FOUND. Cette sortie se produit si le membre Name a la valeur NULL et que la clé actuelle n’a pas de sous-clés, ou si Name spécifie une sous-clé inexistante. (Si cet indicateur n’est pas spécifié, quand aucune correspondance n’est trouvée pour un nom non NULL, la routine utilise le membre DefaultValue comme valeur. Lorsque Name a la valeur NULL et que la clé actuelle n’a pas de sous-clés, la routine ignore simplement cette entrée de table.)
RTL_QUERY_REGISTRY_NOVALUE Spécifie que même s’il n’y a pas de nom pour cette entrée de table, tout ce que l’appelant souhaite est un rappel : autrement dit, l’appelant ne souhaite pas énumérer toutes les valeurs sous la clé actuelle. QueryRoutine est appelé avec NULL pour ValueData, REG_NONE pour ValueType et zéro pour ValueLength.
RTL_QUERY_REGISTRY_NOEXPAND Pour une valeur de Registre de type REG_EXPAND_SZ ou REG_MULTI_SZ, cet indicateur remplace le comportement par défaut, qui consiste à prétraiter la valeur de Registre avant d’appeler la routine QueryRoutine . Par défaut, RtlQueryRegistryValues développe les références de variables d’environnement dans REG_EXPAND_SZ valeurs et énumère chaque chaîne terminée par null dans une valeur REG_MULTI_SZ dans un appel QueryRoutine distinct, de sorte que les chaînes soient présentées en tant que valeurs REG_SZ qui ont le même ValueName. Si cet indicateur est défini, QueryRoutine reçoit la valeur REG_EXPAND_SZ brute ou REG_MULTI_SZ du Registre. Pour plus d’informations sur les formats de données de ces valeurs, consultez KEY_VALUE_BASIC_INFORMATION.
RTL_QUERY_REGISTRY_DIRECT Le membre QueryRoutine n’est pas utilisé (et doit être NULL), et entryContext pointe vers la mémoire tampon pour stocker la valeur. Si l’appelant définit cet indicateur, l’appelant doit également définir l’indicateur RTL_QUERY_REGISTRY_TYPECHECK pour se protéger contre le dépassement de mémoire tampon. Pour plus d'informations, consultez la section Notes.
RTL_QUERY_REGISTRY_TYPECHECK Utilisez cet indicateur avec l’indicateur RTL_QUERY_REGISTRY_DIRECT pour vérifier que le type REG_XXX de la valeur de Registre stockée correspond au type attendu par l’appelant. Si les types ne correspondent pas, l’appel échoue. Pour plus d'informations, consultez la section Notes.
RTL_QUERY_REGISTRY_DELETE Cet indicateur est utilisé pour supprimer les clés de valeur une fois qu’elles ont été interrogées.

À compter de Windows 2000, la prise en charge de la boîte de réception est fournie pour tous les bits d’indicateur dans le tableau précédent, à l’exception de RTL_QUERY_REGISTRY_TYPECHECK. La prise en charge de la boîte de réception pour RTL_QUERY_REGISTRY_TYPECHECK est disponible à partir de Windows 8. Pour les versions antérieures de Windows, la prise en charge de RTL_QUERY_REGISTRY_TYPECHECK est fournie via Windows Update. Pour plus d'informations, consultez la section Notes.

Nom

Il s’agit du nom d’une valeur que l’appelant a interrogée. Si Name a la valeur NULL, la fonction QueryRoutine spécifiée pour cette entrée de table est appelée pour toutes les valeurs associées à la clé de Registre actuelle. Si l’indicateur RTL_QUERY_REGISTRY_DIRECT est défini, une valeur non NULL doit être fournie pour Name .

EntryContext

Si l’indicateur RTL_QUERY_REGISTRY_DIRECT est défini, il s’agit d’un pointeur vers la mémoire tampon pour stocker le résultat de l’opération de requête pour cette clé. Sinon, cette valeur est passée en tant que paramètre EntryContext de QueryRoutine.

DefaultType

L’octet le moins significatif de ce membre spécifie le type REG_XXX des données à retourner, si aucune clé correspondante n’est trouvée et que l’indicateur RTL_QUERY_REGISTRY_REQUIRED n’est pas spécifié. Spécifiez REG_NONE pour aucun type par défaut. Si l’indicateur RTL_QUERY_REGISTRY_TYPECHECK est défini, l’octet le plus significatif de ce membre spécifie le type REG_XXX de la valeur de Registre stockée attendue par l’appelant. Les bits 8 à 23 de ce membre sont réservés et doivent être zéro.

DefaultData

Pointeur vers la valeur par défaut à retourner si aucune clé correspondante n’est trouvée et que l’indicateur RTL_QUERY_REGISTRY_REQUIRED n’est pas spécifié. Ce membre est ignoré si DefaultType = REG_NONE. Sinon, le type de données pointé par DefaultData doit être conforme au type de valeur de Registre spécifié par le membre DefaultType . Pour plus d’informations sur les types de valeurs de Registre, consultez la définition du paramètre Type dans KEY_VALUE_BASIC_INFORMATION.

DefaultLength

Spécifie la longueur, en octets, du membre DefaultData . Si DefaultType est REG_SZ, REG_EXPAND_SZ ou REG_MULTI_SZ, les appelants peuvent éventuellement spécifier zéro pour indiquer que RtlQueryRegistryValues doit calculer la longueur en fonction de la valeur de données par défaut. Si DefaultType = REG_NONE, ce membre est ignoré.

[in, optional] Context

Spécifie la valeur passée en tant que paramètre Context d’une fonction QueryRoutine chaque fois qu’elle est appelée.

[in, optional] Environment

Pointeur vers l’environnement utilisé lors du développement de valeurs de variable dans REG_EXPAND_SZ valeurs de Registre, ou un pointeur NULL (facultatif).

Valeur retournée

RtlQueryRegistryValues retourne un code NTSTATUS. Les valeurs de retour possibles sont les suivantes :

Code de retour Description
STATUS_SUCCESS La table de requête entière a été traitée avec succès.
STATUS_INVALID_PARAMETER Le traitement de la table de requête s’est terminé avec une entrée de table non valide. Une entrée de table peut être non valide si les indicateurs spécifiés nécessitent que le membre QueryRoutine ou Name soit non NULL, mais qu’une valeur NULL a été fournie.
STATUS_OBJECT_NAME_NOT_FOUND Le paramètre Path ne correspond pas à une clé valide ou le traitement de la table de requête s’est terminé avec une entrée avec l’indicateur RTL_QUERY_REGISTRY_REQUIRED défini et aucune clé correspondante n’est trouvée. Cela se produit si le membre Name a la valeur NULL et que la clé actuelle n’a pas de sous-clés, ou si Name spécifie une sous-clé inexistante.
STATUS_BUFFER_TOO_SMALL L’indicateur RTL_QUERY_REGISTRY_DIRECT est défini et la mémoire tampon spécifiée par EntryContext est trop petite pour contenir les données de valeur de clé.
STATUS_OBJECT_TYPE_MISMATCH L’indicateur RTL_QUERY_REGISTRY_TYPECHECK est défini et le type de la valeur de Registre stockée ne correspond pas au type attendu par l’appelant.

RtlQueryRegistryValues met également fin au traitement de la table si la fonction QueryRoutine d’une entrée de table retourne un code d’erreur NTSTATUS et retourne ce code d’erreur comme résultat. (À une exception près : si QueryRoutine retourne STATUS_BUFFER_TOO_SMALL, le code d’erreur est ignoré.)

Remarques

L’appelant spécifie un chemin d’accès de clé initial et une table. La table contient une ou plusieurs entrées qui décrivent les valeurs de clé et les noms de sous-clés qui intéressent l’appelant. La table est terminée par une entrée avec un membre NullQueryRoutineet un membreNULL Name . La table doit être allouée à partir d’un pool non paginé.

Les pilotes en mode noyau doivent spécifier l’indicateur RTL_QUERY_REGISTRY_NOEXPAND pour empêcher l’appel de routines de variables d’environnement. Ces routines étant dangereuses, les pilotes en mode noyau ne doivent pas les utiliser.

Attention

Si vous utilisez l’indicateur RTL_QUERY_REGISTRY_DIRECT, une application en mode utilisateur non approuvée peut provoquer un dépassement de mémoire tampon. Un dépassement de mémoire tampon peut se produire si un pilote utilise cet indicateur pour lire une valeur de Registre à laquelle le type incorrect est attribué. Dans tous les cas, un pilote qui utilise l’indicateur RTL_QUERY_REGISTRY_DIRECT doit également utiliser l’indicateur RTL_QUERY_REGISTRY_TYPECHECK pour empêcher de tels dépassements de capacité.

Si l’indicateur RTL_QUERY_REGISTRY_TYPECHECK est défini dans une entrée de table, l’appelant doit spécifier le type REG_XXX attendu dans les 8 bits les plus significatifs du membre DefaultType 32 bits de l’entrée de table. Comme le montre l’exemple de code suivant, la constante RTL_QUERY_REGISTRY_TYPECHECK_SHIFT, définie sur 24, peut être utilisée comme nombre de décalages requis pour placer le type REG_XXX attendu dans les 8 MMB du membre DefaultType .

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

À compter de Windows 8, si un appel RtlQueryRegistryValues accède à une ruche non approuvée et que l’appelant définit l’indicateur RTL_QUERY_REGISTRY_DIRECT pour cet appel, l’appelant doit également définir l’indicateur RTL_QUERY_REGISTRY_TYPECHECK. Une violation de cette règle par un appel du mode utilisateur entraîne une exception. Une violation de cette règle par un appel en mode noyau entraîne un bogue 0x139 case activée (KERNEL_SECURITY_CHECK_FAILURE).

Seules les ruches système sont approuvées. Un appel RtlQueryRegistryValues qui accède à une ruche système ne provoque pas d’exception ou de bogue case activée si l’indicateur RTL_QUERY_REGISTRY_DIRECT est défini et que l’indicateur RTL_QUERY_REGISTRY_TYPECHECK n’est pas défini. Toutefois, comme bonne pratique, l’indicateur RTL_QUERY_REGISTRY_TYPECHECK doit toujours être défini si l’indicateur RTL_QUERY_REGISTRY_DIRECT est défini.

De même, dans les versions de Windows antérieures à Windows 8, comme bonne pratique, un appel RtlQueryRegistryValues qui définit l’indicateur RTL_QUERY_REGISTRY_DIRECT doit également définir l’indicateur RTL_QUERY_REGISTRY_TYPECHECK. Toutefois, le fait de ne pas suivre cette recommandation ne provoque pas d’exception ou de bogue case activée.

Voici la liste des ruches système :

  • \REGISTRY\MACHINE\HARDWARE

  • \REGISTRY\MACHINE\SOFTWARE

  • \REGISTRY\MACHINE\SYSTEM

  • \REGISTRY\MACHINE\SECURITY

  • \REGISTRY\MACHINE\SAM

La prise en charge de l’indicateur RTL_QUERY_REGISTRY_TYPECHECK est disponible via Windows Update pour Windows 7, Windows Vista, Windows Server 2003 et Windows XP. Pour plus d’informations sur cette mise à jour, consultez Vulnérabilités dans le noyau Windows pouvant permettre l’élévation de privilèges (2393802). Dans les versions de ces systèmes d’exploitation qui n’ont pas cette mise à jour, l’appelant peut utiliser l’indicateur RTL_QUERY_REGISTRY_TYPECHECK. Toutefois, cet indicateur est ignoré par la routine RtlQueryRegistryValues .

À compter du Kit de pilotes Windows (WDK) 8, l’indicateur RTL_QUERY_REGISTRY_TYPECHECK est défini dans le fichier d’en-tête Wdm.h comme suit :

#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100

Si une entrée ne spécifie pas l’indicateur RTL_QUERY_REGISTRY_DIRECT, RtlQueryRegistryValues utilise la fonction QueryRoutine spécifiée pour signaler le nom de la valeur, le type, les données et la longueur des données, en octets, à l’appelant. Si le membre Name de l’entrée a la valeur NULL, RtlQueryRegistryValues signale chaque sous-clé directe de la clé. Si le type de clé est REG_MULTI_SZ et que l’indicateur RTL_QUERY_REGISTRY_NOEXPAND n’est pas spécifié, la routine appelle QueryRoutine séparément pour chaque chaîne individuelle ; sinon, la routine le signale comme une valeur unique. Si une entrée spécifie l’indicateur RTL_QUERY_REGISTRY_DIRECT, RtlQueryRegistryValues stocke la valeur de la clé dans la mémoire tampon vers laquelle pointe le membre EntryContext de l’entrée. Le format des données retournées est le suivant.

Type de données clé Comment les données sont retournées
Chaîne Unicode terminée par null (par exemple, REG_SZ, REG_EXPAND_SZ). EntryContext doit pointer vers une structure UNICODE_STRING initialisée. Si le membre Buffer de UNICODE_STRING a la valeur NULL, la routine alloue le stockage pour les données de chaîne. Sinon, il stocke les données de chaîne dans la mémoire tampon vers laquelle la mémoire tampon pointe.
REG_MULTI_SZ Vous devez spécifier l’indicateur RTL_QUERY_REGISTRY_NOEXPAND pour ce type de données clé. EntryContext pointe vers une structure UNICODE_STRING initialisée. La routine stocke la valeur de clé sous la forme d’une seule valeur de chaîne. Chaque composant individuel au sein de la chaîne est terminé par un zéro. Si le membre Buffer de UNICODE_STRING a la valeur NULL, la routine alloue le stockage pour les données de chaîne. Sinon, il stocke les données de chaîne dans la mémoire tampon vers laquelle la mémoire tampon pointe.
Données non chaînes avec taille, en octets, <= sizeof(ULONG) La valeur est stockée dans l’emplacement de mémoire spécifié par EntryContext.
Données non chaînes avec taille, en octets, >sizeof (ULONG) La mémoire tampon pointée par EntryContext doit commencer par une valeur LONG signée. La magnitude de la valeur doit spécifier la taille, en octets, de la mémoire tampon. Si le signe de la valeur est négatif, RtlQueryRegistryValues stocke uniquement les données de la valeur de clé. Sinon, il utilise le premier ULONG de la mémoire tampon pour enregistrer la longueur de la valeur, en octets, le second ULONG pour enregistrer le type de valeur et le reste de la mémoire tampon pour stocker les données de valeur.

Si une erreur se produit à une étape quelconque du traitement de la table de requête, RtlQueryRegistryValues arrête le traitement de la table et retourne l’erreur status.

Pour obtenir une description des valeurs possibles REG_XXX, consultez ZwSetValueKey.

Configuration requise

Condition requise Valeur
Plateforme cible Universal
En-tête wdm.h (inclure Wdm.h, Ntddk.h, Ntifs.h)
Bibliothèque Ntoskrnl.lib
DLL Ntoskrnl.exe
IRQL PASSIVE_LEVEL

Voir aussi

QueryRoutine

RtlZeroMemory

UNICODE_STRING

ZwEnumerateKey

ZwEnumerateValueKey

ZwSetValueKey