Bagikan melalui


Menggunakan Handle pada Objek Registry-Key

Tabel berikut mencantumkan operasi yang dapat dilakukan driver pada kunci terbuka serta rutinitas yang sesuai untuk dipanggil.

Operasi Rutinitas untuk memanggil

Periksa properti kunci, seperti namanya atau jumlah subkuntusnya.

ZwQueryKey

Telusuri setiap subkunci dari kunci tersebut, memeriksa properti masing-masing.

ZwEnumerateKey

Periksa sifat dari nilai kunci, termasuk data dari nilai tersebut.

ZwQueryValueKey

Iterasi melalui nilai kunci, memeriksa properti masing-masing.

ZwEnumerateValueKey

Atur data untuk nilai yang terkait dengan kunci.

ZwSetValueKey

Menghapus kunci.

ZwDeleteKey

Menghapus nilai kunci.

ZwDeleteValueKey

Setelah driver selesai dengan manipulasi, itu harus memanggil ZwClose untuk menutup handle—bahkan jika sudah memanggil ZwDeleteKey untuk menghapus kunci. (Setelah kunci dihapus, semua handle yang terkait dengannya menjadi tidak valid, namun driver masih harus menutup handle.)

Contoh kode berikut menggambarkan cara membuka handel untuk kunci bernama \Registry\Machine\Software\MyCompany\MyApp, lalu mengambil data kunci dan menutup handel.

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

Sistem menyimpan perubahan kunci dalam memori dan menulisnya ke disk setiap beberapa detik. Untuk memaksa perubahan kunci ke disk, panggil ZwFlushKey.

Untuk memanipulasi registri melalui antarmuka yang lebih sederhana, driver juga dapat memanggil rutinitas RtlXxxRegistryXxx . Untuk informasi selengkapnya, lihat Registri Run-Time Rutinitas Pustaka.