Condividi tramite


Uso di un handle per un oggetto Registry-Key

Nella tabella seguente sono elencate le operazioni che i driver possono eseguire su una chiave aperta e sulle routine appropriate da chiamare.

Operazione Routine da chiamare

Esaminare le proprietà della chiave, ad esempio il nome o il numero di sottochiave.

ZwQueryKey

Eseguire l'iterazione delle sottochiave della chiave, esaminando le proprietà di ognuno di essi.

ZwEnumerateKey

Esaminare le proprietà di un valore chiave, inclusi i dati del valore.

ZwQueryValueKey

Eseguire l'iterazione dei valori di una chiave, esaminando le proprietà di ognuno di essi.

ZwEnumerateValueKey

Impostare i dati per un valore associato a una chiave.

ZwSetValueKey

Eliminare una chiave.

ZwDeleteKey

Eliminare un valore di chiave.

ZwDeleteValueKey

Al termine delle modifiche, il driver deve chiamare ZwClose per chiudere l'handle, anche se ha già chiamato ZwDeleteKey per eliminare la chiave. Una volta eliminata una chiave, tutti gli handle aperti per diventano non validi, tuttavia il driver deve comunque chiudere l'handle.

Nell'esempio di codice seguente viene illustrato come aprire un handle per una chiave denominata \Registry\Machine\Software\MyCompany\MyApp, quindi recuperare i dati delle chiavi e chiudere l'handle.

//
// 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);
}

Il sistema memorizza nella cache le modifiche della chiave nella memoria e li scrive su disco ogni pochi secondi. Per forzare una modifica della chiave su disco, chiamare ZwFlushKey.

Per modificare il Registro di sistema tramite un'interfaccia più semplice, i driver possono anche chiamare le routine RtlXxxRegistroXxx . Per altre informazioni, vedere Routine di libreria Run-Time Registro di sistema.