Funzione RtlQueryRegistryValues (wdm.h)

La routine RtlQueryRegistryValues consente al chiamante di eseguire query su diversi valori dal sottoalbero del Registro di sistema con una singola chiamata.

Sintassi

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

Parametri

[in] RelativeTo

Specifica se Path è un percorso del Registro di sistema assoluto o è relativo a un percorso predefinito come uno dei seguenti.

Valore Significato
RTL_REGISTRY_ABSOLUTE Percorso è un percorso del Registro di sistema assoluto.
RTL_REGISTRY_CONTROL Il percorso è relativo a \Registry\Machine\System\CurrentControlSet\Control.
RTL_REGISTRY_DEVICEMAP Il percorso è relativo a \Registry\Machine\Hardware\DeviceMap.
RTL_REGISTRY_SERVICES Il percorso è relativo a \Registry\Machine\System\CurrentControlSet\Services.
RTL_REGISTRY_USER Il percorso è relativo a \Registry\User\CurrentUser. Per un processo di sistema, questo è \User\. Impostazione predefinita.
RTL_REGISTRY_WINDOWS_NT Il percorso è relativo a \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion.

Il valore RelativeTo può essere modificato in bit per bit-ORing con uno dei flag seguenti.

Contrassegno Significato
RTL_REGISTRY_OPTIONAL Specifica che la chiave a cui fa riferimento questo parametro e il parametro Path è facoltativo.
RTL_REGISTRY_HANDLE Specifica che il parametro Path è effettivamente un handle del Registro di sistema da usare.

[in] Path

Puntatore a un percorso del Registro di sistema assoluto o a un percorso relativo alla posizione nota specificata dal parametro RelativeTo . Si noti che i nomi di chiavi in tale percorso devono essere noti al chiamante, inclusa l'ultima chiave nel percorso. Se viene specificato il flag RTL_REGISTRY_HANDLE, questo parametro è un handle del Registro di sistema per una chiave già aperta da eseguire direttamente.

[in, out] QueryTable

Puntatore a una tabella di uno o più nomi di valori e sottochiave in cui il chiamante è interessato. Ogni voce di tabella contiene l'indirizzo di una funzione QueryRoutine fornita dal chiamante che verrà chiamata per ogni nome di valore presente nel Registro di sistema. La tabella deve essere terminata con una voce di tabella NULL, ovvero una voce di tabella con un membro QueryRoutineNULL e un membro NULLName. La struttura per le voci della tabella di query è definita come segue:

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;

Se il chiamante alloca l'archiviazione per la tabella di query a cui punta il parametro QueryTable , il chiamante è responsabile del rilascio dell'archiviazione dopo la restituzione della chiamata RtlQueryRegistryValues .

QueryRoutine

Indirizzo di una funzione QueryRoutine chiamata con il nome, il tipo, i dati e la lunghezza dei dati di un valore del Registro di sistema. Se questo membro e il membro Name sono entrambi NULL, contrassegna la fine della tabella.

Una funzione QueryRoutine viene dichiarata come segue:

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

Per altre informazioni, vedere QueryRoutine.

Flags

Flag per controllare come devono essere interpretati i membri rimanenti della struttura RTL_QUERY_REGISTRY_TABLE . I bit di flag seguenti sono definiti per questo membro.

Valore Significato
RTL_QUERY_REGISTRY_SUBKEY Il nome di questa voce di tabella è un altro percorso di una chiave del Registro di sistema e tutte le voci di tabella seguenti sono per tale chiave anziché la chiave specificata dal parametro Path. Questa modifica dello stato attivo dura fino alla fine della tabella o fino a quando viene visualizzata un'altra RTL_REGISTRY_SUBKEY o RTL_QUERY_REGISTRY_TOPKEY voce. Ogni voce di questo tipo deve specificare un percorso relativo al percorso specificato nella chiamata a RtlQueryRegistryValues.
RTL_QUERY_REGISTRY_TOPKEY Reimposta l'handle della chiave del Registro di sistema corrente a quello originale specificato dai parametri RelativeTo e Path . Ciò è utile per tornare al nodo originale dopo aver decrescente in sottochiave con il flag di RTL_QUERY_REGISTRY_SUBKEY.
RTL_QUERY_REGISTRY_REQUIRED Specifica che questo valore del Registro di sistema deve esistere se DefaultType = REG_NONE; in caso contrario, se non viene trovato, RtlQueryRegistryValues termina immediatamente con un codice di stato di STATUS_OBJECT_NAME_NOT_FOUND. Questa uscita si verifica se il membro Name è NULL e la chiave corrente non ha sottochiave o se Name specifica una sottochiave inesistente. Se questo flag non è specificato, quando non viene trovata alcuna corrispondenza per un nome non NULL, la routine usa il membro DefaultValue come valore. Quando Name è NULL e la chiave corrente non ha sottochiave, la routine ignora semplicemente la voce della tabella.
RTL_QUERY_REGISTRY_NOVALUE Specifica che, anche se non esiste alcun nome per questa voce di tabella, tutto il chiamante vuole essere un callback: ovvero, il chiamante non vuole enumerare tutti i valori sotto la chiave corrente. QueryRoutine viene chiamato con NULL per ValueData, REG_NONE per ValueType e zero per ValueLength.
RTL_QUERY_REGISTRY_NOEXPAND Per un valore del Registro di sistema di tipo REG_EXPAND_SZ o REG_MULTI_SZ, questo flag esegue l'override del comportamento predefinito, ovvero pre-elaborare il valore del Registro di sistema prima di chiamare la routine QueryRoutine . Per impostazione predefinita, RtlQueryRegistryValues espande i riferimenti alle variabili di ambiente nei valori REG_EXPAND_SZ ed enumera ogni stringa con terminazione null in un valore REG_MULTI_SZ in una chiamata QueryRoutine separata, in modo che le stringhe vengano presentate come valori REG_SZ con lo stesso ValoreName. Se questo flag è impostato, QueryRoutine riceve il valore di REG_EXPAND_SZ o REG_MULTI_SZ non elaborato dal Registro di sistema. Per altre informazioni sui formati di dati per questi valori, vedere KEY_VALUE_BASIC_INFORMATION.
RTL_QUERY_REGISTRY_DIRECT Il membro QueryRoutine non viene usato (e deve essere NULL) e il buffer EntryContext punta al buffer per archiviare il valore. Se il chiamante imposta questo flag, il chiamante deve inoltre impostare il flag di RTL_QUERY_REGISTRY_TYPECHECK per proteggere il overflow del buffer. Per altre informazioni, vedere la sezione Osservazioni.
RTL_QUERY_REGISTRY_TYPECHECK Usare questo flag con il flag RTL_QUERY_REGISTRY_DIRECT per verificare che il tipo REG_ XXX del valore del Registro di sistema archiviato corrisponda al tipo previsto dal chiamante. Se i tipi non corrispondono, la chiamata ha esito negativo. Per altre informazioni, vedere la sezione Osservazioni.
RTL_QUERY_REGISTRY_DELETE Questo flag viene usato per eliminare le chiavi di valore dopo la query.

A partire da Windows 2000, il supporto per la posta in arrivo viene fornito per tutti i bit di flag nella tabella precedente, ad eccezione di RTL_QUERY_REGISTRY_TYPECHECK. Il supporto della posta in arrivo per RTL_QUERY_REGISTRY_TYPECHECK è disponibile a partire da Windows 8. Per le versioni precedenti di Windows, il supporto per RTL_QUERY_REGISTRY_TYPECHECK viene fornito tramite Windows Update. Per altre informazioni, vedere la sezione Osservazioni.

Nome

Si tratta del nome di un valore sottoposto a query dal chiamante. Se Name è NULL, la funzione QueryRoutine specificata per questa voce di tabella viene chiamata per tutti i valori associati alla chiave del Registro di sistema corrente. Se il flag RTL_QUERY_REGISTRY_DIRECT è impostato, è necessario specificare un valore non NULL per Name .

EntryContext

Se il flag RTL_QUERY_REGISTRY_DIRECT è impostato, si tratta di un puntatore al buffer per archiviare il risultato dell'operazione di query per questa chiave. In caso contrario, questo valore viene passato come parametro EntryContext di QueryRoutine.

DefaultType

Il byte meno significativo di questo membro specifica il tipo REG_ XXX dei dati da restituire, se non viene trovata alcuna chiave corrispondente e il flag RTL_QUERY_REGISTRY_REQUIRED non è specificato. Specificare REG_NONE per nessun tipo predefinito. Se il flag RTL_QUERY_REGISTRY_TYPECHECK è impostato, il byte più significativo di questo membro specifica il tipo REG_ XXX del valore del Registro di sistema archiviato previsto dal chiamante. I bit da 8 a 23 di questo membro sono riservati e devono essere zero.

DefaultData

Puntatore al valore predefinito da restituire se non viene trovata alcuna chiave corrispondente e il flag di RTL_QUERY_REGISTRY_REQUIRED non viene specificato. Questo membro viene ignorato se DefaultType = REG_NONE. In caso contrario, il tipo di dati puntato da DefaultData deve essere conforme al tipo di valore del Registro di sistema specificato dal membro DefaultType . Per altre informazioni sui tipi di valore del Registro di sistema, vedere la definizione del parametro Type in KEY_VALUE_BASIC_INFORMATION.

DefaultLength

Specifica la lunghezza, in byte, del membro DefaultData . Se DefaultType è REG_SZ, REG_EXPAND_SZ o REG_MULTI_SZ, i chiamanti possono specificare facoltativamente zero per indicare che RtlQueryRegistryValues deve calcolare la lunghezza in base al valore predefinito dei dati. Se DefaultType = REG_NONE, questo membro viene ignorato.

[in, optional] Context

Specifica il valore passato come parametro Context di una funzione QueryRoutine ogni volta che viene chiamato.

[in, optional] Environment

Puntatore all'ambiente usato durante l'espansione dei valori delle variabili nei valori del Registro di sistema REG_EXPAND_SZ o un puntatore NULL (facoltativo).

Valore restituito

RtlQueryRegistryValues restituisce un codice NTSTATUS. I valori restituiti possibili includono:

Codice restituito Descrizione
STATUS_SUCCESS L'intera tabella di query è stata elaborata correttamente.
STATUS_INVALID_PARAMETER Elaborazione della tabella di query terminata con una voce di tabella non valida. Una voce di tabella può non essere valida se i flag specificati richiedono che il membro QueryRoutine o Name non sia NULL, ma è stato specificato un valore NULL .
STATUS_OBJECT_NAME_NOT_FOUND Il parametro Path non corrisponde a una chiave valida o all'elaborazione della tabella di query terminata con una voce con il flag di RTL_QUERY_REGISTRY_REQUIRED impostato e non viene trovata alcuna chiave corrispondente. Ciò si verifica se il membro Name è NULL e la chiave corrente non ha sottochiave o se Name specifica una sottochiave inesistente.
STATUS_BUFFER_TOO_SMALL Il flag RTL_QUERY_REGISTRY_DIRECT è impostato e il buffer specificato da EntryContext è troppo piccolo per contenere i dati del valore della chiave.
STATUS_OBJECT_TYPE_MISMATCH Il flag RTL_QUERY_REGISTRY_TYPECHECK è impostato e il tipo del valore del Registro di sistema archiviato non corrisponde al tipo previsto dal chiamante.

RtlQueryRegistryValues termina anche l'elaborazione della tabella se la funzione QueryRoutine per una voce di tabella restituisce un codice di errore NTSTATUS e restituisce tale codice di errore come risultato. Con un'eccezione: se QueryRoutine restituisce STATUS_BUFFER_TOO_SMALL, il codice di errore viene ignorato.

Commenti

Il chiamante specifica un percorso di chiave iniziale e una tabella. La tabella contiene una o più voci che descrivono i valori chiave e i nomi di sottochiave in cui è interessato il chiamante. La tabella viene terminata da una voce con un membro QueryRoutineNULL e un membro NULLName. La tabella deve essere allocata dal pool non con pagine.

I driver in modalità kernel devono specificare il flag RTL_QUERY_REGISTRY_NOEXPAND per impedire le routine delle variabili di ambiente chiamanti. Queste routine non sono sicure, quindi i driver in modalità kernel non devono usarli.

Attenzione

Se si usa il flag RTL_QUERY_REGISTRY_DIRECT, un'applicazione in modalità utente non attendibile potrebbe essere in grado di causare un overflow del buffer. Un overflow del buffer può verificarsi se un driver usa questo flag per leggere un valore del Registro di sistema a cui viene assegnato il tipo errato. In tutti i casi, un driver che usa il flag di RTL_QUERY_REGISTRY_DIRECT deve inoltre usare il flag di RTL_QUERY_REGISTRY_TYPECHECK per impedire tali overflow.

Se il flag RTL_QUERY_REGISTRY_TYPECHECK è impostato in una voce di tabella, il chiamante deve specificare il tipo REG_ XXX previsto nei 8 bit più significativi (MSBS) del membro DefaultType a 32 bit della voce della tabella. Come illustrato nell'esempio di codice seguente, la costante RTL_QUERY_REGISTRY_TYPECHECK_SHIFT, definita come 24, può essere usata come numero di maiusc necessari per inserire il tipo REG_ XXX previsto nei 8 MB del membro 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;
...

A partire da Windows 8, se una chiamata RtlQueryRegistryValues accede a un hive non attendibile e il chiamante imposta il flag di RTL_QUERY_REGISTRY_DIRECT per questa chiamata, il chiamante deve inoltre impostare il flag di RTL_QUERY_REGISTRY_TYPECHECK. Una violazione di questa regola da una chiamata dalla modalità utente causa un'eccezione. Una violazione di questa regola da una chiamata dalla modalità kernel causa un controllo di bug 0x139 (KERNEL_SECURITY_CHECK_FAILURE).

Solo gli hive di sistema sono attendibili. Una chiamata RtlQueryRegistryValues che accede a un hive di sistema non causa un'eccezione o un bug verifica se il flag di RTL_QUERY_REGISTRY_DIRECT è impostato e il flag di RTL_QUERY_REGISTRY_TYPECHECK non è impostato. Tuttavia, come procedura consigliata, il flag di RTL_QUERY_REGISTRY_TYPECHECK deve essere sempre impostato se il flag di RTL_QUERY_REGISTRY_DIRECT è impostato.

Analogamente, nelle versioni di Windows prima di Windows 8, come procedura consigliata, una chiamata RtlQueryRegistryValues che imposta il flag di RTL_QUERY_REGISTRY_DIRECT deve inoltre impostare il flag di RTL_QUERY_REGISTRY_TYPECHECK. Tuttavia, non è possibile seguire questa raccomandazione non causa un'eccezione o un controllo di bug.

Di seguito è riportato un elenco di hives di sistema:

  • \REGISTRY\MACHINE\HARDWARE

  • \REGISTRY\MACHINE\SOFTWARE

  • \REGISTRY\MACHINE\SYSTEM

  • \REGISTRY\MACHINE\SECURITY

  • \REGISTRY\MACHINE\SAM

Il supporto per il flag RTL_QUERY_REGISTRY_TYPECHECK è disponibile tramite Windows Update per Windows 7, Windows Vista, Windows Server 2003 e Windows XP. Per altre informazioni su questo aggiornamento, vedere Vulnerabilità nel kernel di Windows potrebbe consentire l'elevazione dei privilegi (2393802). Nelle versioni di questi sistemi operativi che non hanno questo aggiornamento, il chiamante può usare il flag di RTL_QUERY_REGISTRY_TYPECHECK. Tuttavia, questo flag viene ignorato dalla routine RtlQueryRegistryValues .

A partire da Windows Driver Kit (WDK) 8, il flag di RTL_QUERY_REGISTRY_TYPECHECK viene definito nel file di intestazione Wdm.h come segue:

#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100

Se una voce non specifica il flag RTL_QUERY_REGISTRY_DIRECT, RtlQueryRegistryValues usa la funzione QueryRoutine specificata per segnalare il nome del valore, il tipo, i dati e la lunghezza dei dati, in byte, al chiamante. Se il membro Name della voce è NULL, RtlQueryRegistryValues segnala ogni sottochiave diretta della chiave. Se il tipo di chiave è REG_MULTI_SZ e il flag di RTL_QUERY_REGISTRY_NOEXPAND non viene specificato, la routine chiama QueryRoutine separatamente per ogni singola stringa; in caso contrario, la routine lo segnala come singolo valore. Se una voce specifica il flag RTL_QUERY_REGISTRY_DIRECT, RtlQueryRegistryValues archivia il valore della chiave nel buffer a cui punta il membro EntryContext della voce. Il formato dei dati restituiti è il seguente.

Tipo di dati chiave Modalità di restituzione dei dati
Stringa Unicode con terminazione null, ad esempio REG_SZ, REG_EXPAND_SZ. EntryContext deve puntare a una struttura di UNICODE_STRING inizializzata. Se il membro buffer di UNICODE_STRING è NULL, la routine alloca l'archiviazione per i dati stringa. In caso contrario, archivia i dati stringa nel buffer a cui punta Buffer .
REG_MULTI_SZ È necessario specificare il flag di RTL_QUERY_REGISTRY_NOEXPAND per questo tipo di dati chiave. EntryContext punta a una struttura di UNICODE_STRING inizializzata. La routine archivia il valore della chiave come singolo valore stringa. Ogni singolo componente all'interno della stringa viene terminato da zero. Se il membro buffer di UNICODE_STRING è NULL, la routine alloca l'archiviazione per i dati stringa. In caso contrario, archivia i dati stringa nel buffer a cui punta Buffer .
Dati non constring con dimensioni, in byte, <= sizeof(ULONG) Il valore viene archiviato nel percorso di memoria specificato da EntryContext.
Dati senza stringa con dimensioni, in byte, >sizeof(ULONG) Il buffer a cui punta EntryContext deve iniziare con un valore LONG firmato. La grandezza del valore deve specificare le dimensioni, in byte, del buffer. Se il segno del valore è negativo, RtlQueryRegistryValues archivierà solo i dati del valore della chiave. In caso contrario, userà il primo ULONG nel buffer per registrare la lunghezza del valore, in byte, il secondo ULONG per registrare il tipo di valore e il resto del buffer per archiviare i dati del valore.

Se si verifica un errore in qualsiasi fase di elaborazione della tabella di query, RtlQueryRegistryValues arresta l'elaborazione della tabella e restituisce lo stato di errore.

Per una descrizione dei possibili valori REG_XXX, vedere ZwSetValueKey.

Requisiti

Requisito Valore
Piattaforma di destinazione Universale
Intestazione wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
Libreria Ntoskrnl.lib
DLL Ntoskrnl.exe
IRQL PASSIVE_LEVEL

Vedi anche

QueryRoutine

RtlZeroMemory

UNICODE_STRING

ZwEnumerateKey

ZwEnumerateValueKey

ZwSetValueKey