mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
8.6 KiB
337 lines
8.6 KiB
/*++
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|