338 lines
8.6 KiB
C
338 lines
8.6 KiB
C
/*++
|
||
|
||
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;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|