417 lines
11 KiB
C
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
|
|
}
|
|
|