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

417 lines
11 KiB
C

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
regutil.c
Abstract:
Utility routines for use by REGINI and REGDMP programs.
Author:
Steve Wood (stevewo) 10-Mar-92
Revision History:
--*/
#include "regutil.h"
ULONG NumberOfLinesOutput;
BOOLEAN RegBackSwitches;
LPSTR SavedModuleName;
LPSTR SavedModuleUsage1;
LPSTR SavedModuleUsage2;
PHANDLER_ROUTINE SavedCtrlCHandler;
BOOL
CommonCtrlCHandler(
IN ULONG CtrlType
)
{
if (CtrlType == CTRL_C_EVENT || CtrlType == CTRL_BREAK_EVENT) {
if (SavedCtrlCHandler != NULL) {
(*SavedCtrlCHandler)( CtrlType );
}
ExitProcess( 1 );
}
return FALSE;
}
void
InitCommonCode(
PHANDLER_ROUTINE CtrlCHandler,
LPSTR ModuleName,
LPSTR ModuleUsage1,
LPSTR ModuleUsage2
)
{
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
if (!RTInitialize()) {
FatalError( "Unable to initialize registry access functions (%u)",
GetLastError(), 0 );
}
if (_isatty( _fileno( stdout ) )) {
if (GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ),
&ConsoleScreenBufferInfo
)
) {
OutputHeight = ConsoleScreenBufferInfo.srWindow.Bottom -
ConsoleScreenBufferInfo.srWindow.Top + 1;
OutputWidth = ConsoleScreenBufferInfo.srWindow.Right -
ConsoleScreenBufferInfo.srWindow.Left + 1;
}
else {
OutputHeight = 24;
OutputWidth = 80;
}
}
else {
OutputHeight = 0; // Dont pause on redirected output
OutputWidth = 240; // Larger width for redirected output
}
IndentMultiple = 4;
SavedModuleName = ModuleName;
if (!_stricmp( SavedModuleName, "REGBACK" )) {
RegBackSwitches = TRUE;
}
else {
RegBackSwitches = FALSE;
}
SavedModuleUsage1 = ModuleUsage1;
SavedModuleUsage2 = ModuleUsage2;
SetConsoleCtrlHandler( CtrlCHandler, TRUE );
OldValueBufferSize = 30 * 4096;
OldValueBuffer = VirtualAlloc( NULL, OldValueBufferSize, MEM_COMMIT, PAGE_READWRITE );
if (OldValueBuffer == NULL) {
FatalError( "Unable to allocate large value buffer (%u)",
GetLastError(), 0 );
}
return;
}
void
DisplayIndentedString(
ULONG IndentAmount,
PCHAR sBegin
)
{
PCHAR sEnd;
while (sBegin != NULL) {
sEnd = sBegin;
while (*sEnd && *sEnd != '\n') {
sEnd += 1;
}
MsgFprintf( stderr, "%.*s%.*s\n",
IndentAmount,
" ",
sEnd - sBegin, sBegin
);
NumberOfLinesOutput += 1;
if (OutputHeight != 0 && NumberOfLinesOutput >= OutputHeight) {
MsgFprintf( stderr, "more...press any key to continue" );
TSGetch();
MsgFprintf( stderr, "\r \r" );
NumberOfLinesOutput = 2;
}
if (*sEnd == '\0') {
break;
}
else {
sBegin = ++sEnd;
}
}
return;
}
void
Usage(
LPSTR Message,
ULONG_PTR MessageParameter
)
{
ULONG n;
LPSTR sBegin, sEnd;
NumberOfLinesOutput += 1;
n = MsgFprintf( stderr, "usage: %s ", SavedModuleName );
MsgFprintf( stderr, "[-m \\\\machinename" );
if (!RegBackSwitches) {
MsgFprintf( stderr, " | -h hivefile hiveroot | -w Win95 Directory" );
}
MsgFprintf( stderr, "]\n" );
NumberOfLinesOutput += 1;
if (!RegBackSwitches) {
DisplayIndentedString( n, "[-i n] [-o outputWidth]" );
}
DisplayIndentedString( n, SavedModuleUsage1 );
MsgFprintf( stderr, "\n" );
NumberOfLinesOutput += 1;
n = MsgFprintf( stderr, "where: " );
MsgFprintf( stderr, "-m specifies a remote Windows NT machine whose registry is to be manipulated.\n" );
NumberOfLinesOutput += 1;
if (!RegBackSwitches) {
DisplayIndentedString( n,
"-h specifies a specify local hive to manipulate.\n"
"-w specifies the paths to a Windows 95 system.dat and user.dat files\n"
"-i n specifies the display indentation multiple. Default is 4\n"
"-o outputWidth specifies how wide the output is to be. By default the\n"
" outputWidth is set to the width of the console window if standard\n"
" output has not been redirected to a file. In the latter case, an\n"
" outputWidth of 240 is used."
);
MsgFprintf( stderr, "\n" );
NumberOfLinesOutput += 1;
}
DisplayIndentedString( n, SavedModuleUsage2 );
if (!RegBackSwitches) {
DisplayIndentedString( n,
"Whenever specifying a registry path, either on the command line\n"
"or in an input file, the following prefix strings can be used:\n"
"\n"
" HKEY_LOCAL_MACHINE\n"
" HKEY_USERS\n"
" HKEY_CURRENT_USER\n"
" USER:\n"
"\n"
" Each of these strings can stand alone as the key name or be followed\n"
" a backslash and a subkey path."
);
MsgFprintf( stderr, "\n" );
NumberOfLinesOutput += 1;
}
//
// No return from FatalError
//
if (Message != NULL) {
MsgFprintf( stderr, "\n" );
NumberOfLinesOutput += 1;
}
FatalError( Message, MessageParameter, 0 );
}
void
FatalError(
LPSTR Message,
ULONG_PTR MessageParameter1,
ULONG_PTR MessageParameter2
)
{
if (Message != NULL) {
MsgFprintf( stderr, "%s: ", SavedModuleName );
MsgFprintf( stderr, Message, MessageParameter1, MessageParameter2 );
MsgFprintf( stderr, "\n" );
}
if (SavedCtrlCHandler != NULL) {
(*SavedCtrlCHandler)( CTRL_BREAK_EVENT );
}
exit( 1 );
}
void
InputMessage(
PWSTR FileName,
ULONG LineNumber,
BOOLEAN Error,
LPSTR Message,
ULONG_PTR MessageParameter1,
ULONG_PTR MessageParameter2
)
{
MsgFprintf( stderr, "%ws(%u) : %s: ", FileName, LineNumber, Error ? "error" : "warning" );
MsgFprintf( stderr, Message, MessageParameter1, MessageParameter2 );
MsgFprintf( stderr, "\n" );
return;
}
PWSTR
GetArgAsUnicode(
LPSTR s
)
{
ULONG n;
PWSTR ps;
n = strlen( s );
ps = HeapAlloc( GetProcessHeap(),
0,
(n + 1) * sizeof( WCHAR )
);
if (ps == NULL) {
FatalError( "Out of memory", 0, 0 );
}
if (MultiByteToWideChar( CP_ACP,
MB_PRECOMPOSED,
s,
n,
ps,
n
) != (LONG)n
) {
FatalError( "Unable to convert parameter '%s' to Unicode (%u)",
(ULONG_PTR)s, GetLastError() );
}
ps[ n ] = UNICODE_NULL;
return ps;
}
void
CommonSwitchProcessing(
PULONG argc,
PCHAR **argv,
CHAR c
)
{
c = (char)tolower( c );
switch( c ) {
case 'd':
DebugOutput = TRUE;
break;
case 'o':
if (--*argc) {
OutputWidth = atoi( *++(*argv) );
break;
}
else {
Usage( "Missing argument to -o switch", 0 );
}
case 'i':
if (--*argc) {
IndentMultiple = atoi( *++(*argv) );
break;
}
else {
Usage( "Missing parameter for -%c switch", (ULONG)c );
}
case 'm':
if (HiveFileName != NULL || HiveRootName != NULL ||
Win95Path != NULL || Win95UserPath != NULL
) {
Usage( "May only specify one of -h, -m or -w switches", 0 );
}
if (--*argc) {
MachineName = GetArgAsUnicode( *++(*argv) );
if (_wcsnicmp( MachineName, L"\\\\", 2 )) {
FatalError( "Invalid machine name - '%ws'",
(ULONG_PTR)MachineName, 0 );
}
}
else {
Usage( "Missing parameter for -%c switch", (ULONG)c );
}
break;
case 'w':
if (MachineName != NULL || HiveFileName != NULL || HiveRootName != NULL) {
Usage( "May only specify one of -h, -m or -w switches", 0 );
}
if (--*argc && --*argc) {
Win95Path = GetArgAsUnicode( *++(*argv) );
Win95UserPath = GetArgAsUnicode( *++(*argv) );
}
else {
Usage( "Missing parameter(s) for -%c switch", (ULONG)c );
}
break;
case 'h':
if (MachineName != NULL || Win95Path != NULL || Win95UserPath != NULL) {
Usage( "May only specify one of -h, -m or -w switches", 0 );
}
if (--*argc && --*argc) {
HiveFileName = GetArgAsUnicode( *++(*argv) );
HiveRootName = GetArgAsUnicode( *++(*argv) );
}
else {
Usage( "Missing parameter(s) for -%c switch", (ULONG)c );
}
break;
case '?':
Usage( NULL, 0 );
break;
default:
Usage( "Invalid switch (-%c)", (ULONG)c );
break;
}
return;
}
/*
int MsgFprintf (
FILE *str,
LPSTR format,
...
)
if we ever need to display messages for english versions we can add the following portion of code.
[
#ifdef OUTPUT_ENGLISH_MSGS
va_list va;
if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH ) {
va_start(va, format);
i = vfprintf (str, format, va);
va_end(va);
}
#endif // OUTPUT_ENGLISH_MSGS
]
*/
int
__cdecl
MsgFprintf (
FILE *str,
LPSTR format,
...
)
{
int i=0;
#ifndef SILENT_TS_TOOL
va_list va;
va_start(va, format);
i = vfprintf (str, format, va);
va_end(va);
#endif // SILENT_TS_TOOL
return (i);
}
void TSGetch()
{
#ifndef SILENT_TS_TOOL
_getch();
#endif // SILENT_TS_TOOL
}