windows-nt/Source/XPSP1/NT/sdktools/regini/regdir.c
2020-09-26 16:20:57 +08:00

270 lines
6.7 KiB
C

/*++
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;
}
}
}