windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/tools/regrep/regrep.c
2020-09-26 16:20:57 +08:00

596 lines
12 KiB
C

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
regrep.c
Abstract:
Implements a registry search/replace tool.
Author:
Jim Schmidt (jimschm) 19-Apr-1999
Revision History:
<full name> (<alias>) <date> <comments>
--*/
#include "pch.h"
HANDLE g_hHeap;
HINSTANCE g_hInst;
#ifdef DEBUG
#pragma message ("WARNING: Checked builds are very slow")
#endif
BOOL WINAPI MigUtil_Entry (HINSTANCE, DWORD, PVOID);
BOOL
pCallEntryPoints (
DWORD Reason
)
{
HINSTANCE Instance;
//
// Simulate DllMain
//
Instance = g_hInst;
//
// Initialize the common libs
//
if (!MigUtil_Entry (Instance, Reason, NULL)) {
return FALSE;
}
return TRUE;
}
BOOL
Init (
VOID
)
{
g_hHeap = GetProcessHeap();
g_hInst = GetModuleHandle (NULL);
return pCallEntryPoints (DLL_PROCESS_ATTACH);
}
VOID
Terminate (
VOID
)
{
pCallEntryPoints (DLL_PROCESS_DETACH);
}
VOID
HelpAndExit (
VOID
)
{
//
// This routine is called whenever command line args are wrong
//
_ftprintf (
stderr,
TEXT("Command Line Syntax:\n\n")
TEXT(" regrep <srch> <rep> [-r:root] [-p]\n")
TEXT("\nDescription:\n\n")
TEXT(" RegRep implements a registry search and replace. It updates\n")
TEXT(" all instances of <srch> with <rep>.\n")
TEXT("\nArguments:\n\n")
TEXT(" <srch> Specifies the search text\n")
TEXT(" <rep> Specifies the replace text\n")
TEXT(" -r Specifies the root key to process, such as HKLM\\Software.\n")
TEXT(" If not specified, the entire registry is processed.\n")
TEXT(" -p Enables progress output\n")
);
exit (1);
}
VOID
pUpdateKeyNames (
IN PCTSTR Search,
IN PCTSTR Replace,
IN PCTSTR RootKey
);
VOID
pUpdateValueNames (
IN PCTSTR Search,
IN PCTSTR Replace,
IN PCTSTR RootKey
);
VOID
pUpdateValueData (
IN PCTSTR Search,
IN PCTSTR Replace,
IN PCTSTR RootKey
);
BOOL g_ShowProgress = FALSE;
VOID
pProgress (
VOID
)
{
static CHAR String[] = "...... ";
static DWORD Ticks = 0;
PSTR p;
if (GetTickCount() - Ticks < 500) {
return;
}
Ticks = GetTickCount();
if (!g_ShowProgress) {
return;
}
p = strchr (String, ' ');
*p = '.';
p++;
if (!*p) {
p = String;
}
*p = ' ';
printf ("%s\r", String);
}
INT
__cdecl
_tmain (
INT argc,
PCTSTR argv[]
)
{
INT i;
PCTSTR Root = NULL;
PCTSTR Search = NULL;
PCTSTR Replace = NULL;
//
// TODO: Parse command line here
//
for (i = 1 ; i < argc ; i++) {
if (argv[i][0] == TEXT('/') || argv[i][0] == TEXT('-')) {
switch (_totlower (_tcsnextc (&argv[i][1]))) {
case TEXT('r'):
if (Root) {
HelpAndExit();
}
if (argv[i][2] == TEXT(':')) {
Root = &argv[i][3];
} else if (i + 1 < argc) {
Root = argv[++i];
} else {
HelpAndExit();
}
break;
case TEXT('p'):
if (g_ShowProgress) {
HelpAndExit();
}
g_ShowProgress = TRUE;
break;
default:
HelpAndExit();
}
} else {
//
// Parse other args that don't require / or -
//
if (!Search) {
Search = argv[i];
} else if (!Replace) {
Replace = argv[i];
} else {
HelpAndExit();
}
}
}
if (!Replace) {
HelpAndExit();
}
//
// Begin processing
//
if (!Init()) {
return 0;
}
//
// Pass one - fix all the registry key names
//
if (!Root) {
pUpdateKeyNames (Search, Replace, TEXT("HKLM"));
pUpdateKeyNames (Search, Replace, TEXT("HKU"));
} else {
pUpdateKeyNames (Search, Replace, Root);
}
//
// Pass two - fix all value names
//
if (!Root) {
pUpdateValueNames (Search, Replace, TEXT("HKLM"));
pUpdateValueNames (Search, Replace, TEXT("HKU"));
} else {
pUpdateValueNames (Search, Replace, Root);
}
//
// Pass three - fix all value data
//
if (!Root) {
pUpdateValueData (Search, Replace, TEXT("HKLM"));
pUpdateValueData (Search, Replace, TEXT("HKU"));
} else {
pUpdateValueData (Search, Replace, Root);
}
//
// End of processing
//
Terminate();
return 0;
}
VOID
pMoveKey (
IN PCTSTR SourceKey,
IN PCTSTR DestKey
)
{
HKEY Src;
HKEY Dest;
REGVALUE_ENUM e;
DWORD Size;
PBYTE Data;
LONG rc;
GROWBUFFER Buf = GROWBUF_INIT;
Src = OpenRegKeyStr (SourceKey);
Dest = CreateRegKeyStr (DestKey);
pProgress();
if (Src && Dest) {
if (EnumFirstRegValue (&e, Src)) {
Buf.End = 0;
Data = GrowBuffer (&Buf, e.DataSize);
if (Data) {
Size = e.DataSize;
rc = RegQueryValueEx (
Src,
e.ValueName,
NULL,
NULL,
Data,
&Size
);
if (rc == ERROR_SUCCESS) {
rc = RegSetValueEx (Dest, e.ValueName, 0, e.Type, Data, Size);
}
}
}
}
CloseRegKey (Src);
CloseRegKey (Dest);
FreeGrowBuffer (&Buf);
}
VOID
pMoveKeyTree (
IN PCTSTR SourceKey,
IN PCTSTR DestKey
)
{
REGTREE_ENUM e;
TCHAR DestSubKey[MAX_REGISTRY_KEY];
PTSTR p;
GROWLIST List = GROWLIST_INIT;
UINT Count;
UINT u;
PCTSTR Item;
DWORD Len;
StringCopy (DestSubKey, DestKey);
p = AppendWack (DestSubKey);
if (EnumFirstRegKeyInTree (&e, SourceKey)) {
do {
StringCopy (p, (PCTSTR) ((PBYTE) e.FullKeyName + e.EnumBaseBytes));
pMoveKey (e.FullKeyName, DestSubKey);
GrowListAppendString (&List, e.FullKeyName);
} while (EnumNextRegKeyInTree (&e));
}
Count = GrowListGetSize (&List);
u = Count;
while (u > 0) {
u--;
Item = GrowListGetString (&List, u);
ConvertRootStringToKey (Item, &Len);
RegDeleteKey (ConvertRootStringToKey (Item, NULL), Item + Len);
}
FreeGrowList (&List);
}
VOID
pUpdateKeyNames (
IN PCTSTR Search,
IN PCTSTR Replace,
IN PCTSTR RootKey
)
{
REGTREE_ENUM e;
GROWLIST List = GROWLIST_INIT;
UINT Count;
UINT u;
PCTSTR OldKey;
PCTSTR NewKey;
if (g_ShowProgress) {
_tprintf ("Scanning for keys to update\n");
}
if (EnumFirstRegKeyInTree (&e, RootKey)) {
do {
pProgress();
if (_tcsistr (e.CurrentKey->KeyName, Search)) {
GrowListAppendString (&List, e.FullKeyName);
}
} while (EnumNextRegKeyInTree (&e));
}
Count = GrowListGetSize (&List);
u = Count;
if (g_ShowProgress) {
_tprintf ("Updating %u keys\n", Count);
}
while (u > 0) {
u--;
_tprintf (TEXT("%s\n"), GrowListGetString (&List, u));
OldKey = GrowListGetString (&List, u);
NewKey = StringSearchAndReplace (
OldKey,
Search,
Replace
);
pMoveKeyTree (OldKey, NewKey);
}
FreeGrowList (&List);
}
VOID
pUpdateValueNames (
IN PCTSTR Search,
IN PCTSTR Replace,
IN PCTSTR RootKey
)
{
REGTREE_ENUM e;
REGVALUE_ENUM ev;
GROWLIST List = GROWLIST_INIT;
HKEY Key;
UINT Count;
UINT u;
PBYTE Data;
DWORD Type;
DWORD Size;
PCTSTR ValueName;
PCTSTR NewValueName;
BOOL b;
LONG rc;
if (g_ShowProgress) {
_tprintf ("Processing all value names in the keys\n");
}
if (EnumFirstRegKeyInTree (&e, RootKey)) {
do {
pProgress();
Key = OpenRegKeyStr (e.FullKeyName);
if (Key) {
if (EnumFirstRegValue (&ev, Key)) {
do {
if (_tcsistr (ev.ValueName, Search)) {
GrowListAppendString (&List, ev.ValueName);
}
} while (EnumNextRegValue (&ev));
Count = GrowListGetSize (&List);
u = Count;
while (u > 0) {
u--;
ValueName = GrowListGetString (&List, u);
b = FALSE;
if (GetRegValueTypeAndSize (Key, ValueName, &Type, &Size)) {
Data = GetRegValueData (Key, ValueName);
if (Data) {
NewValueName = StringSearchAndReplace (
ValueName,
Search,
Replace
);
rc = RegSetValueEx (Key, NewValueName, 0, Type, Data, Size);
if (rc == ERROR_SUCCESS) {
if (!StringIMatch (ValueName, NewValueName)) {
rc = RegDeleteValue (Key, ValueName);
}
}
MemFree (g_hHeap, 0, Data);
FreePathString (NewValueName);
SetLastError (rc);
b = (rc == ERROR_SUCCESS);
}
}
if (b) {
_tprintf (TEXT("%s [%s]\n"), e.FullKeyName, ValueName);
} else {
_ftprintf (stderr, TEXT("Error %u updating %s [%s]\n"), GetLastError(), e.FullKeyName, ValueName);
}
}
}
FreeGrowList (&List);
CloseRegKey (Key);
} else {
_ftprintf (stderr, TEXT("Can't open %s\n"), Key);
}
} while (EnumNextRegKeyInTree (&e));
}
}
VOID
pUpdateValueData (
IN PCTSTR Search,
IN PCTSTR Replace,
IN PCTSTR RootKey
)
{
REGTREE_ENUM e;
REGVALUE_ENUM ev;
HKEY Key;
PCTSTR Data;
PCTSTR NewData;
LONG rc;
if (g_ShowProgress) {
_tprintf ("Processing all value data\n");
}
if (EnumFirstRegKeyInTree (&e, RootKey)) {
do {
pProgress();
Key = OpenRegKeyStr (e.FullKeyName);
if (Key) {
if (EnumFirstRegValue (&ev, Key)) {
do {
Data = GetRegValueString (Key, ev.ValueName);
if (Data) {
if (_tcsistr (Data, Search)) {
NewData = StringSearchAndReplace (Data, Search, Replace);
rc = RegSetValueEx (Key, ev.ValueName, 0, ev.Type, NewData, SizeOfString (NewData));
if (rc == ERROR_SUCCESS) {
_tprintf (TEXT("%s [%s] %s\n"), e.FullKeyName, ev.ValueName, Data);
} else {
_ftprintf (stderr, TEXT("Error %u updating %s [%s] %s\n"), GetLastError(), e.FullKeyName, ev.ValueName, Data);
}
FreePathString (NewData);
}
MemFree (g_hHeap, 0, Data);
}
} while (EnumNextRegValue (&ev));
}
CloseRegKey (Key);
} else {
_ftprintf (stderr, TEXT("Can't open %s\n"), Key);
}
} while (EnumNextRegKeyInTree (&e));
}
}