使用Registry-Key物件的控制碼
下表列出驅動程式可以在開啟索引鍵上執行的作業,以及要呼叫的適當常式。
作業 | 要呼叫的常式 |
---|---|
檢查索引鍵的屬性,例如其名稱或其子機碼的數目。 |
|
逐一查看索引鍵的子機碼,檢查每個索引鍵的屬性。 |
|
檢查索引鍵值的屬性,包括值的資料。 |
|
逐一查看索引鍵的值,並檢查每個值的屬性。 |
|
設定與索引鍵相關聯之值的資料。 |
|
刪除金鑰。 |
|
刪除索引鍵值。 |
驅動程式完成其操作之後,它必須呼叫 ZwClose 以關閉控制碼,即使它已經呼叫 ZwDeleteKey 來刪除金鑰也一樣。 (刪除金鑰之後,所有開啟的控制碼都會變成無效,不過驅動程式仍然必須關閉 handle。)
下列程式碼範例說明如何開啟名為\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程式庫常式。