Share via


Usar un identificador para un objeto Registry-Key

En la tabla siguiente se enumeran las operaciones que los controladores pueden realizar en una clave abierta, así como las rutinas adecuadas que se deben llamar.

Operación Rutina a la que llamar

Examine las propiedades de la clave, como su nombre o el número de sus subclaves.

ZwQueryKey

Recorra en iteración las subclaves de la clave y examine las propiedades de cada una.

ZwEnumerateKey

Examine las propiedades de un valor de clave, incluidos los datos del valor.

ZwQueryValueKey

Recorra en iteración los valores de una clave y examine las propiedades de cada una.

ZwEnumerateValueKey

Establezca los datos de un valor asociado a una clave.

ZwSetValueKey

Elimina una clave.

ZwDeleteKey

Elimine un valor de clave.

ZwDeleteValueKey

Una vez que el controlador haya terminado sus manipulaciones, debe llamar a ZwClose para cerrar el identificador, incluso si ya ha llamado ZwDeleteKey para eliminar la clave. (Una vez eliminada una clave, todos los identificadores abiertos se convierten en no válidos, pero el controlador todavía debe cerrar el identificador).

En el ejemplo de código siguiente se muestra cómo abrir un identificador para una clave denominada \Registry\Machine\Software\MyCompany\MyApp y, a continuación, recuperar los datos de clave y cerrar el identificador.

//
// Get the frame location from the registry key
// HKLM\SOFTWARE\MyCompany\MyApp.
// For example: "FrameLocation"="X:\\MyApp\\Frames"
// 
HANDLE              handleRegKey = NULL;
for (int n = 0; n < 1; n++) 
{
    NTSTATUS           status = NULL;
    UNICODE_STRING     RegistryKeyName;
    OBJECT_ATTRIBUTES  ObjectAttributes;

    RtlInitUnicodeString(&RegistryKeyName, L"\\Registry\\Machine\\Software\\MyCompany\\MyApp");
    InitializeObjectAttributes(&ObjectAttributes, 
                               &RegistryKeyName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,    // handle
                               NULL);
    status = ZwOpenKey(&handleRegKey, KEY_READ, &ObjectAttributes);

    // If the driver cannot open the key, the driver cannot continue. 
    // In this situation, the driver was probably set up incorrectly 
    // and worst case, the driver cannot stream.
    if( NT_SUCCESS(status) == FALSE ) 
    {
        break;
    }
    // The driver obtained the registry key.
    PKEY_VALUE_FULL_INFORMATION  pKeyInfo = NULL;
    UNICODE_STRING               ValueName;
    ULONG                        ulKeyInfoSize = 0;
    ULONG                        ulKeyInfoSizeNeeded = 0;

    // The driver requires the following value.
    RtlInitUnicodeString(&ValueName, L"FrameLocation");

    // Determine the required size of keyInfo.
    status = ZwQueryValueKey( handleRegKey,
                              &ValueName,
                              KeyValueFullInformation,
                              pKeyInfo,
                              ulKeyInfoSize,
                              &ulKeyInfoSizeNeeded );

    // The driver expects one of the following errors.
    if( (status == STATUS_BUFFER_TOO_SMALL) || (status == STATUS_BUFFER_OVERFLOW) )
    {
        // Allocate the memory required for the key.
        ulKeyInfoSize = ulKeyInfoSizeNeeded;
        pKeyInfo = (PKEY_VALUE_FULL_INFORMATION) ExAllocatePoolWithTag( NonPagedPool, ulKeyInfoSizeNeeded, g_ulTag);
        if( NULL == pKeyInfo )
        {
            break;
        }
        RtlZeroMemory( pKeyInfo, ulKeyInfoSize );

        // Get the key data.
        status = ZwQueryValueKey( handleRegKey,
                                  &ValueName,
                                  KeyValueFullInformation,
                                  pKeyInfo,
                                  ulKeyInfoSize,
                                  &ulKeyInfoSizeNeeded );
        if( (status != STATUS_SUCCESS) || (ulKeyInfoSizeNeeded != ulKeyInfoSize) || (NULL == pKeyInfo) )
        {
            break;
        }

        // Fill in the frame location if it has not been filled in already.
        if ( NULL == m_szwFramePath )
        {
            m_ulFramePathLength = pKeyInfo->DataLength;
            ULONG_PTR   pSrc = NULL;

            pSrc = (ULONG_PTR) ( (PBYTE) pKeyInfo + pKeyInfo->DataOffset);

            m_szwFramePath = (LPWSTR) ExAllocatePoolWithTag( NonPagedPool, m_ulFramePathLength, g_ulTag);
            if ( NULL == m_szwFramePath )
            {
                m_ulFramePathLength = 0;
                break;
            }

            // Copy the frame path.
            RtlCopyMemory(m_szwFramePath, (PVOID) pSrc, m_ulFramePathLength);
        }
        // The driver is done with the pKeyInfo.
        xFreePoolWithTag(pKeyInfo, g_ulTag);

    } // if( (status == STATUS_BUFFER_TOO_SMALL) || (status == STATUS_BUFFER_OVERFLOW) )
} // Get the Frame location from the registry key.

// All done with the registry.
if (NULL != handleRegKey)
{
    ZwClose(handleRegKey);
}

El sistema almacena en caché los cambios de clave en la memoria y los escribe en el disco cada pocos segundos. Para forzar un cambio de clave en el disco, llame a ZwFlushKey.

Para manipular el registro a través de una interfaz más sencilla, los controladores también pueden llamar a las rutinas RtlXxxRegistryXxx . Para obtener más información, vea Rutinas de biblioteca de Run-Time del Registro.