Condividi tramite


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 Percorso è un percorso assoluto del Registro di sistema o è relativo a un percorso predefinito come uno dei seguenti.

Valore Significato
RTL_REGISTRY_ABSOLUTE Path è un percorso assoluto del Registro di sistema.
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, si tratta di \User\. Impostazione predefinita.)
RTL_REGISTRY_WINDOWS_NT Il percorso è relativo a \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion.

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

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

[in] Path

Puntatore a un percorso assoluto del Registro di sistema o a un percorso relativo alla posizione nota specificata dal parametro RelativeTo. Si noti che i nomi delle chiavi in un percorso di questo tipo 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 su cui eseguire una query direttamente.

[in, out] QueryTable

Puntatore a una tabella di uno o più nomi di valori e sottochiavi a cui il chiamante è interessato. Ogni voce di tabella contiene l'indirizzo di un chiamante fornito queryRoutine funzione che verrà chiamata per ogni nome di valore presente nel Registro di sistema. La tabella deve essere terminata con una voce di tabella NULL null, ovvero una voce di tabella con un membro NULLQueryRou tine e un membro NomeNULL . 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 di questa risorsa di archiviazione dopo che il RtlQueryRegistryValues chiamata restituisce.

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 il membro e il membro Nome 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.

Bandiere

Flag per controllare la modalità di interpretazione dei 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 relative a tale chiave anziché alla chiave specificata dal parametro Path . Questa modifica dello stato attivo dura fino alla fine della tabella o fino a quando non viene visualizzata un'altra voce di RTL_REGISTRY_SUBKEY o RTL_QUERY_REGISTRY_TOPKEY. Ogni voce di questo tipo deve specificare un percorso relativo alla Path specificata nella chiamata a RtlQueryRegistryValues.
RTL_QUERY_REGISTRY_TOPKEY Reimposta l'handle della chiave del Registro di sistema corrente su quello originale specificato dai parametri RelativeTo e Path. Ciò è utile per tornare al nodo originale dopo la decrescente in sottochiavi con il flag 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 viene immediatamente chiuso con un codice di stato di STATUS_OBJECT_NAME_NOT_FOUND. Questa uscita si verifica se il membro nome è NULL e la chiave corrente non dispone di sottochiavi oppure se Nome specifica una sottochiave inesistente. Se questo flag non viene specificato, quando non viene trovata alcuna corrispondenza per unNULLName, la routine utilizza il membro DefaultValue come valore. Quando Nome è NULL e la chiave corrente non dispone di sottochiavi, la routine ignora semplicemente la voce della tabella.
RTL_QUERY_REGISTRY_NOVALUE Specifica che, anche se non è presente nome per questa voce di tabella, tutto il chiamante vuole è 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 ValueTypee 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 sostituisce il 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 la stessa ValueName. Se questo flag è impostato, QueryRoutine riceve il valore REG_EXPAND_SZ non elaborato o REG_MULTI_SZ 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 utilizzato (e deve essere NULL) e il EntryContext punta al buffer per archiviare il valore. Se il chiamante imposta questo flag, il chiamante deve inoltre impostare il flag RTL_QUERY_REGISTRY_TYPECHECK per proteggersi dall'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 REG_XXX tipo del valore del Registro di sistema archiviato corrisponda al tipo previsto dal chiamante. Se i tipi non corrispondono, la chiamata non riesce. Per altre informazioni, vedere la sezione Osservazioni.
RTL_QUERY_REGISTRY_DELETE Questo flag viene usato per eliminare le chiavi di valore dopo che sono state sottoposte a query.

A partire da Windows 2000, il supporto della 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 Osservazioni.

Nome

Si tratta del nome di un valore su cui il chiamante ha eseguito una query. Se Name è NULL, viene chiamata la funzione query specificata per questa voce di tabella per tutti i valori associati alla chiave corrente del Registro di sistema. Se il flag RTL_QUERY_REGISTRY_DIRECT è impostato, è necessario specificare un valore di NULL nonper Nome.

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 REG_XXX tipo di dati da restituire, se non viene trovata alcuna chiave corrispondente e il flag RTL_QUERY_REGISTRY_REQUIRED non viene 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 REG_XXX tipo 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 RTL_QUERY_REGISTRY_REQUIRED non viene specificato. Questo membro viene ignorato se DefaultType = REG_NONE. In caso contrario, il tipo di dati a cui punta 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 facoltativamente specificare zero per indicare RtlQueryRegistryValues deve calcolare la lunghezza in base al valore di dati predefinito. Se DefaultType = REG_NONE, questo membro viene ignorato.

[in, optional] Context

Specifica il valore passato come parametro context di di una funzione query ogni volta che viene chiamata.

[in, optional] Environment

Puntatore all'ambiente usato quando si espandono i valori delle variabili nei valori del Registro di sistema REG_EXPAND_SZ o un puntatore NULL NULL (facoltativo).

Valore restituito

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

Codice restituito Descrizione
STATUS_SUCCESS L'intera tabella di query è stata elaborata correttamente.
STATUS_INVALID_PARAMETER Elaborazione della tabella query terminata con una voce di tabella non valida. Una voce di tabella non può essere valida se i flag specificati richiedono che il QueryRoutine o Nome membro nonnull, ma è stato specificato un valore null 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 RTL_QUERY_REGISTRY_REQUIRED impostato e non viene trovata alcuna chiave corrispondente. Ciò si verifica se il membro nome è NULL e la chiave corrente non dispone di sottochiavi o se Nome 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.

Osservazioni

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 a cui è interessato il chiamante. La tabella viene terminata da una voce con un membroQueryRoutineNULL e un membro NULLName. La tabella deve essere allocata dal pool non di paging.

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.

Cautela

Se si usa il flag RTL_QUERY_REGISTRY_DIRECT, un'applicazione in modalità utente non attendibile può 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 è assegnato il tipo errato. In tutti i casi, un driver che usa il flag RTL_QUERY_REGISTRY_DIRECT deve inoltre usare il flag 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 del DefaultType membro 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 turni necessario per inserire il tipo REG_XXX previsto nei 8 MSB 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 un RtlQueryRegistryValues chiama accede a un hive non attendibile e il chiamante imposta il flag RTL_QUERY_REGISTRY_DIRECT per questa chiamata, il chiamante deve inoltre impostare il flag 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. Un RtlQueryRegistryValues chiamata che accede a un hive di sistema non causa un'eccezione o un controllo di bug se il flag RTL_QUERY_REGISTRY_DIRECT è impostato e il flag RTL_QUERY_REGISTRY_TYPECHECK non è impostato. Tuttavia, come procedura consigliata, il flag RTL_QUERY_REGISTRY_TYPECHECK deve essere sempre impostato se è impostato il flag RTL_QUERY_REGISTRY_DIRECT.

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

Di seguito è riportato un elenco di hive 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 dispongono di questo aggiornamento, il chiamante può usare il flag RTL_QUERY_REGISTRY_TYPECHECK. Tuttavia, questo flag viene ignorato dalla routine RtlQueryRegistryValues.

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

#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100

Se una voce non specifica il flag di RTL_QUERY_REGISTRY_DIRECT, RtlQueryRegistryValues usa la funzione QueryRoutine specificata per segnalare al chiamante il nome, il tipo, i dati e la lunghezza dei dati specificati. Se il membro nome 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 un singolo valore. Se una voce specifica il flag di 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 Come vengono restituiti i 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 buffer punta.
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 buffer punta.
Dati non stringa con dimensioni, in byte, <= sizeof(ULONG) Il valore viene archiviato nel percorso di memoria specificato da EntryContext.
Dati non 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à la prima ULONG nel buffer per registrare la lunghezza del valore, in byte, la seconda 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 interrompe l'elaborazione della tabella e restituisce lo stato di errore.

Per una descrizione dei possibili valori REG_XXX, vedere ZwSetValueKey.

Fabbisogno

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

Vedere anche

QueryRoutine

RtlZeroMemory

UNICODE_STRING

ZwEnumerateKey

ZwEnumerateValueKey

ZwSetValueKey