void DumpKeys( HKEY ParentKeyHandle, PWSTR KeyName, PWSTR FullPath, ULONG Depth ) { LONG Error; HKEY KeyHandle; ULONG SubKeyIndex; WCHAR SubKeyName[ MAX_PATH ]; ULONG SubKeyNameLength; WCHAR ComputeFullPath[ MAX_PATH ]; FILETIME LastWriteTime; Error = RTOpenKey( &RegistryContext, ParentKeyHandle, KeyName, MAXIMUM_ALLOWED, REG_OPTION_OPEN_LINK, &KeyHandle ); if (Error != NO_ERROR) { if (Depth == 0) { FatalError( "Unable to open key '%ws' (%u)\n", (ULONG)KeyName, (ULONG)Error ); } return; } // // Print name of node we are about to dump out // if (!FullPathOutput) { RTFormatKeyName( (PREG_OUTPUT_ROUTINE)fprintf, stdout, Depth * IndentMultiple, KeyName ); RTFormatKeySecurity( (PREG_OUTPUT_ROUTINE)fprintf, stdout, KeyHandle, NULL ); printf( "\n" ); } // // Print out node's values // if (FullPathOutput) DumpValues( KeyHandle, FullPath, 0 ); else DumpValues( KeyHandle, KeyName, Depth + 1 ); // // Enumerate node's children and apply ourselves to each one // for (SubKeyIndex = 0; TRUE; SubKeyIndex++) { SubKeyNameLength = sizeof( SubKeyName ); Error = RTEnumerateKey( &RegistryContext, KeyHandle, SubKeyIndex, &LastWriteTime, &SubKeyNameLength, SubKeyName ); if (Error != NO_ERROR) { if (Error != ERROR_NO_MORE_ITEMS && Error != ERROR_ACCESS_DENIED) { fprintf( stderr, "RTEnumerateKey( %ws ) failed (%u), skipping\n", KeyName, Error ); } break; } if (FullPathOutput) { wcscpy(ComputeFullPath, FullPath); wcscat(ComputeFullPath, L"\\"); wcscat(ComputeFullPath, SubKeyName); } DumpKeys( KeyHandle, SubKeyName, ComputeFullPath, Depth + 1 ); } RTCloseKey( &RegistryContext, KeyHandle ); return; }
void Dump( HANDLE Handle ) { NTSTATUS status; PKEY_BASIC_INFORMATION KeyInformation; OBJECT_ATTRIBUTES ObjectAttributes; ULONG NamePos; ULONG index; STRING enumname; HANDLE WorkHandle; ULONG ResultLength; static char buffer[WORK_SIZE]; PUCHAR p; KeyInformation = (PKEY_BASIC_INFORMATION)buffer; NamePos = WorkName.Length; // // Print name of node we are about to dump out // print(&WorkName); printf("::\n\n"); // // Print out node's values // DumpValues(Handle); // // Enumerate node's children and apply ourselves to each one // for (index = 0; TRUE; index++) { RtlZeroMemory(KeyInformation, WORK_SIZE); status = NtEnumerateKey( Handle, index, KeyBasicInformation, KeyInformation, WORK_SIZE, &ResultLength ); if (status == STATUS_NO_MORE_ENTRIES) { WorkName.Length = NamePos; return; } else if (!NT_SUCCESS(status)) { printf("rtdmp: dump1: status = %08lx\n", status); exit(1); } enumname.Buffer = &(KeyInformation->Name[0]); enumname.Length = KeyInformation->NameLength; enumname.MaximumLength = KeyInformation->NameLength; p = WorkName.Buffer; p += WorkName.Length; *p = '\\'; p++; *p = '\0'; WorkName.Length += 2; RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&enumname); InitializeObjectAttributes( &ObjectAttributes, &enumname, 0, Handle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; status = NtOpenKey( &WorkHandle, MAXIMUM_ALLOWED, &ObjectAttributes ); if (!NT_SUCCESS(status)) { printf("rtdmp: dump2: %08lx\n", status); exit(1); } Dump(WorkHandle); NtClose(WorkHandle); WorkName.Length = NamePos; } }