Freigeben über


Verwenden eines Handles für ein Registry-Key-Objekt

In der folgenden Tabelle sind die Vorgänge aufgeführt, die Treiber für einen geöffneten Schlüssel ausführen können, sowie die entsprechenden Zurufroutinen.

Vorgang Aufrufroutine

Untersuchen Sie die Eigenschaften des Schlüssels, z. B. seinen Namen oder die Anzahl seiner Unterschlüssel.

ZwQueryKey

Durchlaufen Sie die Unterschlüssel des Schlüssels, und untersuchen Sie die Eigenschaften der einzelnen Schlüssel.

ZwEnumerateKey

Untersuchen Sie die Eigenschaften eines Schlüsselwerts, einschließlich der Daten des Werts.

ZwQueryValueKey

Durchlaufen Sie die Werte eines Schlüssels, und untersuchen Sie die Eigenschaften der einzelnen Schlüssel.

ZwEnumerateValueKey

Legen Sie die Daten für einen Wert fest, der einem Schlüssel zugeordnet ist.

ZwSetValueKey

Löscht einen Schlüssel.

ZwDeleteKey

Löschen Sie einen Schlüsselwert.

ZwDeleteValueKey

Sobald der Treiber seine Manipulationen abgeschlossen hat, muss er ZwClose aufrufen, um den Handle zu schließen – auch wenn er bereits ZwDeleteKey aufgerufen hat, um den Schlüssel zu löschen. (Nachdem ein Schlüssel gelöscht wurde, werden alle geöffneten Handles für ihn ungültig, aber der Treiber muss den Handle trotzdem schließen.)

Im folgenden Codebeispiel wird veranschaulicht, wie Sie ein Handle für einen Schlüssel namens \Registry\Machine\Software\MyCompany\MyApp öffnen, dann Schlüsseldaten abrufen und das Handle schließen.

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

Das System speichert Schlüsseländerungen im Arbeitsspeicher zwischen und schreibt sie alle paar Sekunden auf den Datenträger. Rufen Sie ZwFlushKey auf, um eine Schlüsseländerung auf dem Datenträger zu erzwingen.

Um die Registrierung über eine einfachere Schnittstelle zu bearbeiten, können Treiber auch die Xxx-Routinender RtlXxx Registry aufrufen. Weitere Informationen finden Sie unter Registrierung Run-Time Bibliotheksroutinen.