Compartir a través de


Función RtlQueryRegistryValues (wdm.h)

La rutina RtlQueryRegistryValues permite al autor de la llamada consultar varios valores del subárbol del Registro con una sola llamada.

Sintaxis

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

Parámetros

[in] RelativeTo

Especifica si ruta de acceso es una ruta de acceso absoluta del Registro o es relativa a una ruta de acceso predefinida como una de las siguientes.

Valor Significado
RTL_REGISTRY_ABSOLUTE Path es una ruta de acceso absoluta del Registro.
RTL_REGISTRY_CONTROL La ruta de acceso es relativa a \Registry\Machine\System\CurrentControlSet\Control.
RTL_REGISTRY_DEVICEMAP La ruta de acceso es relativa a \Registry\Machine\Hardware\DeviceMap.
RTL_REGISTRY_SERVICES La ruta de acceso es relativa a \Registry\Machine\System\CurrentControlSet\Services.
RTL_REGISTRY_USER La ruta de acceso es relativa a \Registry\User\CurrentUser. (Para un proceso del sistema, se \User\. Valor predeterminado).
RTL_REGISTRY_WINDOWS_NT La ruta de acceso es relativa a \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion.

El valor RelativeTo se puede modificar mediante ORing bit a bit con una de las marcas siguientes.

Bandera Significado
RTL_REGISTRY_OPTIONAL Especifica que la clave a la que hace referencia este parámetro y el parámetro Path son opcionales.
RTL_REGISTRY_HANDLE Especifica que el parámetro Path es realmente un identificador del Registro que se va a usar.

[in] Path

Puntero a una ruta de acceso absoluta del Registro o a una ruta de acceso relativa a la ubicación conocida especificada por el parámetro RelativeTo . Tenga en cuenta que los nombres de las claves de dicha ruta de acceso deben conocerse al autor de la llamada, incluida la última clave de la ruta de acceso. Si se especifica la marca RTL_REGISTRY_HANDLE, este parámetro es un identificador del Registro para que se consulte directamente una clave ya abierta.

[in, out] QueryTable

Puntero a una tabla de uno o varios nombres de valor y nombres de subclave en los que está interesado el autor de la llamada. Cada entrada de tabla contiene la dirección de una función QueryRoutine proporcionada por el autor de la llamada que se llamará para cada nombre de valor que exista en el Registro. La tabla debe terminarse con una entrada de tabla NULL NULL, que es una entrada de tabla con un miembroQueryRoutine NULL y un miembroNombreNULL. La estructura de las entradas de la tabla de consulta se define de la siguiente manera:

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 el autor de la llamada asigna almacenamiento para la tabla de consulta a la que apunta el parámetro QueryTable, el autor de la llamada es responsable de liberar este almacenamiento después de que el RtlQueryRegistryValues devolución de llamada.

QueryRoutine

Dirección de una función de QueryRoutine a la que se llama con el nombre, el tipo, los datos y la longitud de los datos de un valor del Registro. Si este miembro y el miembro Name son NULL, marca el final de la tabla.

Una función queryRoutine se declara de la siguiente manera:

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

Para obtener más información, consulte QueryRoutine.

Banderas

Marcas para controlar cómo se van a interpretar los miembros restantes de la estructura RTL_QUERY_REGISTRY_TABLE. Los siguientes bits de marca se definen para este miembro.

Valor Significado
RTL_QUERY_REGISTRY_SUBKEY El Nombre de de esta entrada de tabla es otra ruta de acceso a una clave del Registro y todas las entradas de tabla siguientes son para esa clave en lugar de la clave especificada por el parámetro Path. Este cambio de foco dura hasta el final de la tabla o hasta que se vea otra entrada RTL_REGISTRY_SUBKEY o RTL_QUERY_REGISTRY_TOPKEY. Cada entrada de este tipo debe especificar una ruta de acceso relativa a la ruta de acceso especificada en la llamada a RtlQueryRegistryValues.
RTL_QUERY_REGISTRY_TOPKEY Restablece el identificador de clave del Registro actual al original especificado por los parámetros RelativeTo y Path. Esto es útil para volver al nodo original después de descender en subclaves con la marca RTL_QUERY_REGISTRY_SUBKEY.
RTL_QUERY_REGISTRY_REQUIRED Especifica que este valor del Registro debe existir si DefaultType = REG_NONE; De lo contrario, si no se encuentra, RtlQueryRegistryValues sale inmediatamente con un código de estado de STATUS_OBJECT_NAME_NOT_FOUND. Esta salida se produce si el miembro Name es NULL y la clave actual no tiene subclaves, o si Nombre especifica una subclave inexistente. (Si no se especifica esta marca, cuando no se encuentra ninguna coincidencia para unnullName, la rutina usa el miembro DefaultValue como valor. Cuando nombre es NULL y la clave actual no tiene subclaves, la rutina simplemente omite esa entrada de tabla).
RTL_QUERY_REGISTRY_NOVALUE Especifica que aunque no haya Nombre para esta entrada de tabla, todo lo que el autor de la llamada quiere es una devolución de llamada: es decir, el autor de la llamada no quiere enumerar todos los valores de la clave actual. se llama a queryRoutine con NULL para ValueData, REG_NONE para ValueTypey cero para ValueLength.
RTL_QUERY_REGISTRY_NOEXPAND Para un valor del Registro de tipo REG_EXPAND_SZ o REG_MULTI_SZ, esta marca invalida el comportamiento predeterminado, que es preprocesar el valor del Registro antes de llamar a la rutina queryRoutine . De forma predeterminada, RtlQueryRegistryValues expande las referencias de variables de entorno en valores REG_EXPAND_SZ y enumera cada cadena terminada en null en un valor de REG_MULTI_SZ en una llamada QueryRoutine independiente, de modo que las cadenas se presentan como valores REG_SZ que tienen el mismo valor ValueName. Si se establece esta marca, QueryRoutine recibe el REG_EXPAND_SZ sin procesar o REG_MULTI_SZ valor del Registro. Para obtener más información sobre los formatos de datos de estos valores, consulte KEY_VALUE_BASIC_INFORMATION.
RTL_QUERY_REGISTRY_DIRECT No se usa el miembro QueryRoutine (y debe ser NULL) y el EntryContext de apunta al búfer para almacenar el valor. Si el autor de la llamada establece esta marca, el autor de la llamada debe establecer además la marca RTL_QUERY_REGISTRY_TYPECHECK para protegerse contra el desbordamiento del búfer. Para obtener más información, vea la sección Comentarios.
RTL_QUERY_REGISTRY_TYPECHECK Use esta marca con la marca RTL_QUERY_REGISTRY_DIRECT para comprobar que el REG_XXX tipo del valor del Registro almacenado coincide con el tipo esperado por el autor de la llamada. Si los tipos no coinciden, se produce un error en la llamada. Para obtener más información, vea la sección Comentarios.
RTL_QUERY_REGISTRY_DELETE Esta marca se usa para eliminar las claves de valor después de que se hayan consultado.

A partir de Windows 2000, la compatibilidad con la bandeja de entrada se proporciona para todos los bits de marca de la tabla anterior, a excepción de RTL_QUERY_REGISTRY_TYPECHECK. La compatibilidad con bandeja de entrada para RTL_QUERY_REGISTRY_TYPECHECK está disponible a partir de Windows 8. Para versiones anteriores de Windows, la compatibilidad con RTL_QUERY_REGISTRY_TYPECHECK se proporciona a través de Windows Update. Para obtener más información, vea Comentarios.

Nombre

Este es el nombre de un valor que el autor de la llamada ha consultado. Si nombre es null, se llama a la función queryRoutine especificada para esta entrada de tabla para todos los valores asociados a la clave del Registro actual. Si se establece la marca RTL_QUERY_REGISTRY_DIRECT, se debe proporcionar un valor null que no seaNULL para Nombre.

EntryContext

Si se establece la marca RTL_QUERY_REGISTRY_DIRECT, se trata de un puntero al búfer para almacenar el resultado de la operación de consulta para esta clave. De lo contrario, este valor se pasa como parámetro EntryContext de QueryRoutine.

DefaultType

El byte menos significativo de este miembro especifica el REG_XXX tipo de datos que se va a devolver, si no se encuentra ninguna clave coincidente y no se especifica la marca RTL_QUERY_REGISTRY_REQUIRED. Especifique REG_NONE para ningún tipo predeterminado. Si se establece la marca RTL_QUERY_REGISTRY_TYPECHECK, el byte más significativo de este miembro especifica el REG_XXX tipo del valor del Registro almacenado que espera el autor de la llamada. Los bits de 8 a 23 de este miembro están reservados y deben ser cero.

DefaultData

Puntero al valor predeterminado que se va a devolver si no se encuentra ninguna clave coincidente y no se especifica la marca RTL_QUERY_REGISTRY_REQUIRED. Este miembro se omite si DefaultType = REG_NONE. De lo contrario, el tipo de datos al que apunta defaultData debe ajustarse al tipo de valor del Registro especificado por el miembro DefaultType. Para obtener más información sobre los tipos de valor del Registro, consulte la definición del parámetro Type de en KEY_VALUE_BASIC_INFORMATION.

DefaultLength

Especifica la longitud, en bytes, del miembro DefaultData. Si DefaultType es REG_SZ, REG_EXPAND_SZ o REG_MULTI_SZ, los autores de llamadas pueden especificar opcionalmente cero para indicar RtlQueryRegistryValues debe calcular la longitud en función del valor de datos predeterminado. Si DefaultType = REG_NONE, se omite este miembro.

[in, optional] Context

Especifica el valor pasado como parámetro de Context de una función QueryRoutine cada vez que se llama a ella.

[in, optional] Environment

Puntero al entorno que se usa al expandir valores de variable en REG_EXPAND_SZ valores del Registro o un puntero NULL (opcional).

Valor devuelto

RtlQueryRegistryValues devuelve un código NTSTATUS. Entre los valores devueltos posibles se incluyen:

Código devuelto Descripción
STATUS_SUCCESS Toda la tabla de consulta se procesó correctamente.
STATUS_INVALID_PARAMETER El procesamiento de la tabla de consulta finalizó con una entrada de tabla no válida. Una entrada de tabla puede no ser válida si las marcas especificadas requieren el QueryRoutine de o miembro Name que no seaNULL, pero se proporcionó un NULL.
STATUS_OBJECT_NAME_NOT_FOUND El parámetro Path no coincide con una clave válida o el procesamiento de la tabla de consulta terminado con una entrada con la marca RTL_QUERY_REGISTRY_REQUIRED establecida y no se encuentra ninguna clave coincidente. Esto ocurre si el miembro nombre de es null y la clave actual no tiene subclaves, o si Nombre especifica una subclave inexistente.
STATUS_BUFFER_TOO_SMALL Se establece la marca RTL_QUERY_REGISTRY_DIRECT y el búfer especificado por EntryContext es demasiado pequeño para contener los datos del valor de clave.
STATUS_OBJECT_TYPE_MISMATCH La marca RTL_QUERY_REGISTRY_TYPECHECK se establece y el tipo del valor del Registro almacenado no coincide con el tipo esperado por el autor de la llamada.

RtlQueryRegistryValues también finaliza el procesamiento de la tabla si la función QueryRoutine para una entrada de tabla devuelve un código de error NTSTATUS y devuelve ese código de error como resultado. (Con una excepción: si queryRoutine devuelve STATUS_BUFFER_TOO_SMALL, se omite el código de error).

Observaciones

El autor de la llamada especifica una ruta de acceso de clave inicial y una tabla. La tabla contiene una o varias entradas que describen los valores de clave y los nombres de subclave en los que está interesado el autor de la llamada. La tabla finaliza mediante una entrada con un miembroQueryRoutineNULL y un miembro NULLName. La tabla debe asignarse desde un grupo no paginado.

Los controladores en modo kernel deben especificar la marca de RTL_QUERY_REGISTRY_NOEXPAND para evitar la llamada a rutinas de variables de entorno. Estas rutinas no son seguras, por lo que los controladores en modo kernel no deben usarlos.

Cautela

Si usa la marca RTL_QUERY_REGISTRY_DIRECT, es posible que una aplicación en modo de usuario que no sea de confianza pueda provocar un desbordamiento del búfer. Se puede producir un desbordamiento de búfer si un controlador usa esta marca para leer un valor del Registro al que se asigna el tipo incorrecto. En todos los casos, un controlador que use la marca RTL_QUERY_REGISTRY_DIRECT también debe usar la marca RTL_QUERY_REGISTRY_TYPECHECK para evitar dichos desbordamientos.

Si la marca RTL_QUERY_REGISTRY_TYPECHECK está establecida en una entrada de tabla, el autor de la llamada debe especificar el tipo de REG_ XXX esperado en los 8 bits más significativos (MSB) del DefaultType miembro de la entrada de tabla. Como se muestra en el ejemplo de código siguiente, la constante RTL_QUERY_REGISTRY_TYPECHECK_SHIFT, que se define como 24, se puede usar como recuento de turnos necesario para colocar el tipo de REG_ XXX esperado en los 8 MSB del miembro 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 partir de Windows 8, si un RtlQueryRegistryValues llamada accede a un subárbol que no es de confianza y el autor de la llamada establece la marca RTL_QUERY_REGISTRY_DIRECT para esta llamada, el autor de la llamada también debe establecer la marca RTL_QUERY_REGISTRY_TYPECHECK. Una infracción de esta regla por una llamada desde el modo de usuario provoca una excepción. Una infracción de esta regla por una llamada desde el modo kernel provoca una comprobación de errores de 0x139 (KERNEL_SECURITY_CHECK_FAILURE).

Solo los subárboles del sistema son de confianza. Una llamada RtlQueryRegistryValues que tiene acceso a un subárbol del sistema no produce una excepción o una comprobación de errores si se establece la marca RTL_QUERY_REGISTRY_DIRECT y no se establece la marca RTL_QUERY_REGISTRY_TYPECHECK. Sin embargo, como procedimiento recomendado, la marca RTL_QUERY_REGISTRY_TYPECHECK siempre debe establecerse si se establece la marca RTL_QUERY_REGISTRY_DIRECT.

Del mismo modo, en versiones de Windows anteriores a Windows 8, como procedimiento recomendado, una RtlQueryRegistryValues llamada que establece la marca de RTL_QUERY_REGISTRY_DIRECT también debe establecer la marca de RTL_QUERY_REGISTRY_TYPECHECK. Sin embargo, si no se sigue esta recomendación, no se produce una excepción ni una comprobación de errores.

A continuación se muestra una lista de subárboles del sistema:

  • \REGISTRY\MACHINE\HARDWARE

  • \REGISTRY\MACHINE\SOFTWARE

  • \REGISTRY\MACHINE\SYSTEM

  • \REGISTRY\MACHINE\SECURITY

  • \REGISTRY\MACHINE\SAM

La compatibilidad con la marca RTL_QUERY_REGISTRY_TYPECHECK está disponible a través de Windows Update para Windows 7, Windows Vista, Windows Server 2003 y Windows XP. Para obtener más información sobre esta actualización, vea Vulnerabilidades en el kernel de Windows Podría permitir la elevación de privilegios (2393802). En versiones de estos sistemas operativos que no tienen esta actualización, el autor de la llamada puede usar la marca RTL_QUERY_REGISTRY_TYPECHECK. Sin embargo, la rutina RtlQueryRegistryValue s omite esta marca.

A partir del Kit de controladores de Windows (WDK) 8, la marca RTL_QUERY_REGISTRY_TYPECHECK se define en el archivo de encabezado Wdm.h de la siguiente manera:

#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100

Si una entrada no especifica la marca RTL_QUERY_REGISTRY_DIRECT, RtlQueryRegistryValues usa la función QueryRoutine especificada para notificar el nombre de valor, el tipo, los datos y la longitud de los datos, en bytes, al autor de la llamada. Si el miembro Name de la entrada es NULL, RtlQueryRegistryValues notifica cada subclave directo de la clave. Si se REG_MULTI_SZ el tipo de clave y no se especifica la marca RTL_QUERY_REGISTRY_NOEXPAND, la rutina llama a QueryRoutine por separado para cada cadena individual; de lo contrario, la rutina lo informa como un solo valor. Si una entrada especifica la marca de RTL_QUERY_REGISTRY_DIRECT, RtlQueryRegistryValues almacena el valor de la clave en el búfer al que apunta el miembro EntryContext de la entrada. El formato de los datos devueltos es el siguiente.

Tipo de datos clave Cómo se devuelven los datos
Cadena Unicode terminada en null (como REG_SZ, REG_EXPAND_SZ). EntryContext debe apuntar a una estructura de UNICODE_STRING inicializada. Si el miembro buffer de UNICODE_STRING es NULL, la rutina asigna almacenamiento para los datos de cadena. De lo contrario, almacena los datos de cadena en el búfer al que apunta buffer.
REG_MULTI_SZ Debe especificar la marca RTL_QUERY_REGISTRY_NOEXPAND para este tipo de datos de clave. entryContext apunta a una estructura de UNICODE_STRING inicializada. La rutina almacena el valor de clave como un valor de cadena único. Cada componente individual dentro de la cadena finaliza en cero. Si el miembro buffer de UNICODE_STRING es NULL, la rutina asigna almacenamiento para los datos de cadena. De lo contrario, almacena los datos de cadena en el búfer al que apunta buffer.
Datos que no son de cadena con tamaño, en bytes, <= sizeof(ULONG) El valor se almacena en la ubicación de memoria especificada por EntryContext.
Datos que no son de cadena con tamaño, en bytes, >tamaño de(ULONG) El búfer al que apunta EntryContext debe comenzar con un valor LONG firmado. La magnitud del valor debe especificar el tamaño, en bytes, del búfer. Si el signo del valor es negativo, RtlQueryRegistryValues solo almacenará los datos del valor de clave. De lo contrario, usará el primer ULONG del búfer para registrar la longitud del valor, en bytes, la segunda ULONG para registrar el tipo de valor y el resto del búfer para almacenar los datos de valor.

Si se produce un error en cualquier fase del procesamiento de la tabla de consulta, RtlQueryRegistryValues deja de procesar la tabla y devuelve el estado del error.

Consulte ZwSetValueKey para obtener una descripción de los posibles valores de XXX REG_.

Requisitos

Requisito Valor
de la plataforma de destino de Universal
encabezado de wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
biblioteca de Ntoskrnl.lib
DLL de Ntoskrnl.exe
irQL PASSIVE_LEVEL

Consulte también

QueryRoutine de

RtlZeroMemory

UNICODE_STRING

ZwEnumerateKey

ZwEnumerateValueKey

ZwSetValueKey