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

303 lines
7.7 KiB
C

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