다음을 통해 공유


Registry-Key 개체에 핸들 사용

다음 표에서는 드라이버가 열려 있는 키에서 수행할 수 있는 작업과 호출할 적절한 루틴을 나열합니다.

작업 호출할 루틴

키의 이름 또는 하위 키 수와 같은 키의 속성을 검사합니다.

ZwQueryKey

키의 하위 키를 반복하여 각 키의 속성을 검사합니다.

ZwEnumerateKey

값의 데이터를 포함하여 키 값의 속성을 검사합니다.

ZwQueryValueKey

키의 값을 반복하여 각 키의 속성을 검사합니다.

ZwEnumerateValueKey

키와 연결된 값에 대한 데이터를 설정합니다.

ZwSetValueKey

키를 삭제합니다.

ZwDeleteKey

키 값을 삭제합니다.

ZwDeleteValueKey

드라이버가 조작을 완료한 후에는 ZwClose 를 호출하여 키를 삭제하기 위해 ZwDeleteKey 를 이미 호출한 경우에도 핸들을 닫아야 합니다. 키가 삭제되면 키가 열려 있는 모든 핸들이 유효하지 않지만 드라이버는 핸들을 닫아야 합니다.

다음 코드 예제에서는 \Registry\Machine\Software\MyCompany\MyApp이라는 키에 대한 핸들을 연 다음 키 데이터를 검색하고 핸들을 닫는 방법을 보여 줍니다.

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

시스템은 메모리의 키 변경 내용을 캐시하고 몇 초마다 디스크에 씁니다. 키를 강제로 디스크로 변경하려면 ZwFlushKey를 호출합니다.

더 간단한 인터페이스를 통해 레지스트리를 조작하기 위해 드라이버는 RtlXxx레지스트리Xxx 루틴을 호출할 수도 있습니다. 자세한 내용은 레지스트리 Run-Time 라이브러리 루틴을 참조하세요.