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. |
|
Durchlaufen Sie die Unterschlüssel des Schlüssels, und untersuchen Sie die Eigenschaften der einzelnen Schlüssel. |
|
Untersuchen Sie die Eigenschaften eines Schlüsselwerts, einschließlich der Daten des Werts. |
|
Durchlaufen Sie die Werte eines Schlüssels, und untersuchen Sie die Eigenschaften der einzelnen Schlüssel. |
|
Legen Sie die Daten für einen Wert fest, der einem Schlüssel zugeordnet ist. |
|
Löscht einen Schlüssel. |
|
Löschen Sie einen Schlüsselwert. |
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.