|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
regdmp.c
Abstract:
Utility to display all or part of the registry in a format that is suitable for input to the REGINI program.
REGDMP [KeyPath]
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
Default KeyPath if none specified is \Registry
Author:
Steve Wood (stevewo) 12-Mar-92
Revision History:
--*/
#include "regutil.h"
BOOL DumpValues( HKEY KeyHandle, PWSTR KeyName, ULONG Depth );
void DumpKeys( HKEY ParentKeyHandle, PWSTR KeyName, PWSTR FullPath, ULONG Depth );
BOOLEAN SummaryOutput;
BOOL CtrlCHandler( IN ULONG CtrlType ) { RTDisconnectFromRegistry( &RegistryContext ); return FALSE; }
int __cdecl main( int argc, char *argv[] ) { ULONG n; char *s; LONG Error; PWSTR RegistryPath;
InitCommonCode( CtrlCHandler, "REGDMP", "[-s] [-o outputWidth] registryPath", "-s specifies summary output. Value names, type and first line of data\n" "\n" "registryPath specifies where to start dumping.\n" "\n" "If REGDMP detects any REG_SZ or REG_EXPAND_SZ that is missing the\n" "trailing null character, it will prefix the value string with the\n" "following text: (*** MISSING TRAILING NULL CHARACTER ***)\n" "The REGFIND tool can be used to clean these up, as this is a common\n" "programming error.\n" );
RegistryPath = NULL; while (--argc) { s = *++argv; if (*s == '-' || *s == '/') { while (*++s) { switch( tolower( *s ) ) { case 'f': FullPathOutput = TRUE; break;
case 's': SummaryOutput = TRUE; break;
default: CommonSwitchProcessing( &argc, &argv, *s ); break; } } } else if (RegistryPath == NULL) { RegistryPath = GetArgAsUnicode( s ); } else { Usage( "May only specify one registry path to dump", 0 ); } }
Error = RTConnectToRegistry( MachineName, HiveFileName, HiveRootName, Win95Path, Win95UserPath, &RegistryPath, &RegistryContext ); if (Error != NO_ERROR) { FatalError( "Unable to access registry specifed (%u)", Error, 0 ); }
DumpKeys( RegistryContext.HiveRootHandle, RegistryPath, RegistryPath, 0 );
RTDisconnectFromRegistry( &RegistryContext ); return 0; }
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; BOOL AnyValues;
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_PTR)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) AnyValues = 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 ) / sizeof(WCHAR); 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 ); }
if (FullPathOutput) { if (SubKeyIndex == 0) { if (!AnyValues) { fprintf(stdout, "%ws\n", FullPath ); } } }
RTCloseKey( &RegistryContext, KeyHandle );
return; }
BOOL DumpValues( HKEY KeyHandle, PWSTR KeyName, ULONG Depth ) { LONG Error; DWORD ValueIndex; DWORD ValueType; DWORD ValueNameLength; WCHAR ValueName[ MAX_PATH ]; DWORD ValueDataLength;
for (ValueIndex = 0; TRUE; ValueIndex++) { ValueType = REG_NONE; ValueNameLength = sizeof( ValueName ) / sizeof( WCHAR ); ValueDataLength = OldValueBufferSize; Error = RTEnumerateValueKey( &RegistryContext, KeyHandle, ValueIndex, &ValueType, &ValueNameLength, ValueName, &ValueDataLength, OldValueBuffer ); if (Error == NO_ERROR) {
if (FullPathOutput) { fprintf(stdout, "%ws -> ", KeyName ); }
RTFormatKeyValue( OutputWidth, (PREG_OUTPUT_ROUTINE)fprintf, stdout, SummaryOutput, Depth * IndentMultiple, ValueName, ValueDataLength, ValueType, OldValueBuffer ); } else if (Error == ERROR_NO_MORE_ITEMS) { if (ValueIndex == 0) { return FALSE; } else { return TRUE; } } else { if (DebugOutput) { fprintf( stderr, "RTEnumerateValueKey( %ws ) failed (%u)\n", KeyName, Error ); }
return FALSE; } } }
|