|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
regdir.c
Abstract:
Utility to display all or part of the registry directory.
REGDIR [KeyPath]
Will ennumerate and dump out the subkeys and values of KeyPath, and then apply itself recursively to each subkey it finds.
Default KeyPath if none specified is \Registry
Author:
Steve Wood (stevewo) 12-Mar-92
Revision History:
--*/
#include "regutil.h"
void DumpValues( HKEY KeyHandle, PWSTR KeyName, ULONG Depth );
void DumpKeys( HKEY ParentKeyHandle, PWSTR KeyName, ULONG Depth );
BOOLEAN RecurseIntoSubkeys = FALSE;
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, "REGDIR", "[-r] registryPath", "-r specifies to recurse into subdirectories\n" "registryPath specifies where to start displaying.\n" );
RegistryPath = NULL; while (--argc) { s = *++argv; if (*s == '-' || *s == '/') { while (*++s) { switch( tolower( *s ) ) { case 'r': RecurseIntoSubkeys = TRUE; break;
default: CommonSwitchProcessing( &argc, &argv, *s ); break; } } } else if (RegistryPath == NULL) { RegistryPath = GetArgAsUnicode( s ); } else { Usage( "May only specify one registry path to display", 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, 0 );
RTDisconnectFromRegistry( &RegistryContext ); return 0; }
void DumpKeys( HKEY ParentKeyHandle, PWSTR KeyName, ULONG Depth ) { LONG Error; HKEY KeyHandle; ULONG SubKeyIndex; WCHAR SubKeyName[ MAX_PATH ]; ULONG SubKeyNameLength; 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_PTR)KeyName, (ULONG)Error ); }
if (DebugOutput) { fprintf( stderr, "Unable to open key '%ws' (%u)\n", KeyName, (ULONG)Error ); }
return; }
//
// Print name of node we are about to dump out
//
printf( "%.*s%ws", Depth * IndentMultiple, " ", KeyName ); RTFormatKeySecurity( (PREG_OUTPUT_ROUTINE)fprintf, stdout, KeyHandle, NULL ); printf( "\n" );
//
// Print out node's values
//
if (Depth != 1 || RecurseIntoSubkeys) { DumpValues( KeyHandle, KeyName, Depth + 1 ); }
//
// Enumerate node's children and apply ourselves to each one
//
if (Depth == 0 || RecurseIntoSubkeys) { 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; }
DumpKeys( KeyHandle, SubKeyName, Depth + 1 ); } }
RTCloseKey( &RegistryContext, KeyHandle );
return; }
void 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) { RTFormatKeyValue( OutputWidth, (PREG_OUTPUT_ROUTINE)fprintf, stdout, TRUE, Depth * IndentMultiple, ValueName, ValueDataLength, ValueType, OldValueBuffer ); } else if (Error == ERROR_NO_MORE_ITEMS) { return; } else { if (DebugOutput) { fprintf( stderr, "RTEnumerateValueKey( %ws ) failed (%u)\n", KeyName, Error ); }
return; } } }
|