|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
hivedmp.c
Abstract:
Utility to display all or part of the registry in a format that is suitable for input to the REGINI program.
HIVEDMP [-r] -f filename
Will ennumerate and dump out the subkeys and values of KeyPath, and then apply itself recursively to each subkey it finds.
Handles all value types (e.g. REG_???) defined in ntregapi.h
-r forces ALL value type to be output in RAW (hex) form.
Default KeyPath if none specified is \Registry
Author:
Steve Wood (stevewo) 12-Mar-92
Revision History:
30-Nov-92 bryanwi Add -r switch
--*/
#include "regutil.h"
#include "edithive.h"
void DumpValues( HANDLE HiveHandle, HANDLE KeyHandle, ULONG IndentLevel );
void DumpKeys( HANDLE HiveHandle, HANDLE KeyHandle, PUNICODE_STRING KeyName, ULONG IndentLevel );
void RegDumpKeyValueR( FILE *fh, PKEY_VALUE_FULL_INFORMATION KeyValueInformation, ULONG IndentLevel );
PVOID ValueBuffer; ULONG ValueBufferSize;
BOOLEAN RawOutput = FALSE;
void Usage( void ) { fprintf( stderr, "usage: HIVEDMP [-f hivefile]\n" ); exit( 1 ); }
void __cdecl main( int argc, char *argv[] ) { char *s; ANSI_STRING AnsiString; UNICODE_STRING KeyName; UNICODE_STRING DosName; UNICODE_STRING FileName; UNICODE_STRING RootName; HANDLE HiveHandle = NULL; HANDLE RootKey = NULL; BOOLEAN ArgumentSeen; LPSTR HiveFile=NULL;
ValueBufferSize = VALUE_BUFFER_SIZE; ValueBuffer = VirtualAlloc( NULL, ValueBufferSize, MEM_COMMIT, PAGE_READWRITE ); if (ValueBuffer == NULL) { fprintf( stderr, "REGDMP: Unable to allocate value buffer.\n" ); exit( 1 ); }
ArgumentSeen = FALSE; while (--argc) { s = *++argv; if (*s == '-' || *s == '/') { while (*++s) { switch( tolower( *s ) ) { case 'd': DebugOutput = TRUE; break;
case 's': SummaryOutput = TRUE; break;
case 'r': RawOutput = TRUE; break;
case 'f': if (argc--) { RtlInitString( &AnsiString, *++argv ); RtlAnsiStringToUnicodeString( &DosName, &AnsiString, TRUE ); RtlDosPathNameToNtPathName_U( DosName.Buffer, &FileName, NULL, NULL ); HiveHandle = EhOpenHive( &FileName, &RootKey, &RootName, TYPE_SIMPLE ); ArgumentSeen = TRUE; break; }
default: Usage(); } } } #if 0
else { RtlInitString( &AnsiString, s ); RtlAnsiStringToUnicodeString( &KeyName, &AnsiString, TRUE ); DumpKeys( HiveHandle, RootKey, &KeyName, 0 ); ArgumentSeen = TRUE; } #endif
}
if (ArgumentSeen) { if (HiveHandle != NULL) { DumpKeys( HiveHandle, RootKey, &RootName, 0 ); } else { fprintf(stderr, "Couldn't open hive file %wZ\n",&DosName); } } else { Usage(); }
exit( 0 ); }
void DumpKeys( HANDLE HiveHandle, HANDLE KeyHandle, PUNICODE_STRING KeyName, ULONG IndentLevel ) { NTSTATUS Status; HANDLE SubKeyHandle; WCHAR KeyBuffer[ 512 ]; PKEY_BASIC_INFORMATION KeyInformation; OBJECT_ATTRIBUTES ObjectAttributes; ULONG SubKeyIndex; UNICODE_STRING SubKeyName; ULONG ResultLength;
//
// Print name of node we are about to dump out
//
printf( "%.*s%wZ\n", IndentLevel, " ", KeyName );
//
// Print out node's values
//
DumpValues( HiveHandle, KeyHandle, IndentLevel+4 );
//
// Enumerate node's children and apply ourselves to each one
//
KeyInformation = (PKEY_BASIC_INFORMATION)KeyBuffer; for (SubKeyIndex = 0; TRUE; SubKeyIndex++) { Status = EhEnumerateKey( HiveHandle, KeyHandle, SubKeyIndex, KeyBasicInformation, KeyInformation, sizeof( KeyBuffer ), &ResultLength );
if (Status == STATUS_NO_MORE_ENTRIES) { return; } else if (!NT_SUCCESS( Status )) { fprintf( stderr, "REGDMP: NtEnumerateKey failed - Status ==%08lx\n", Status ); exit( 1 ); }
SubKeyName.Buffer = (PWSTR)&(KeyInformation->Name[0]); SubKeyName.Length = (USHORT)KeyInformation->NameLength; SubKeyName.MaximumLength = (USHORT)KeyInformation->NameLength;
Status = EhOpenChildByName( HiveHandle, KeyHandle, &SubKeyName, &SubKeyHandle ); if (NT_SUCCESS(Status)) { DumpKeys( HiveHandle, SubKeyHandle, &SubKeyName, IndentLevel+4 ); } }
}
void DumpValues( HANDLE HiveHandle, HANDLE KeyHandle, ULONG IndentLevel ) { NTSTATUS Status; PKEY_VALUE_FULL_INFORMATION KeyValueInformation; ULONG ValueIndex; ULONG ResultLength;
KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)ValueBuffer; for (ValueIndex = 0; TRUE; ValueIndex++) { Status = EhEnumerateValueKey( HiveHandle, KeyHandle, ValueIndex, KeyValueFullInformation, KeyValueInformation, ValueBufferSize, &ResultLength ); if (Status == STATUS_NO_MORE_ENTRIES) { return; } else if (!NT_SUCCESS( Status )) { fprintf( stderr, "REGDMP: NtEnumerateValueKey failed - Status == %08lx\n", Status ); exit( 1 ); }
if (RawOutput == TRUE) { RegDumpKeyValueR( stdout, KeyValueInformation, IndentLevel ); } else { RegDumpKeyValue( stdout, KeyValueInformation, IndentLevel ); } } }
void RegDumpKeyValueR( FILE *fh, PKEY_VALUE_FULL_INFORMATION KeyValueInformation, ULONG IndentLevel ) { PULONG p; PWSTR pw, pw1; ULONG i, j, k, m, cbPrefix; UNICODE_STRING ValueName; PUCHAR pbyte;
cbPrefix = fprintf( fh, "%.*s", IndentLevel, " " ); ValueName.Buffer = (PWSTR)&(KeyValueInformation->Name[0]); ValueName.Length = (USHORT)KeyValueInformation->NameLength; ValueName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
if (ValueName.Length) { cbPrefix += fprintf( fh, "%wS ", &ValueName ); } cbPrefix += fprintf( fh, "= " );
if (KeyValueInformation->DataLength == 0) { fprintf( fh, " [no data] \n"); return; }
fprintf( fh, "REG_BINARY 0x%08lx", KeyValueInformation->DataLength ); p = (PULONG)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset); i = (KeyValueInformation->DataLength + 3) / sizeof( ULONG ); for (j=0; j<i; j++) { if ((j % 8) == 0) { fprintf( fh, "\n%.*s", IndentLevel+4, " " ); }
fprintf( fh, "0x%08lx ", *p++ ); } fprintf( fh, "\n" );
fprintf( fh, "\n" ); return; }
|