Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

366 lines
10 KiB

/*++
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:
jimschm 26-May-1999 Moved from win9xupg, ported to use different
utilities
Santanuc 14-Feb-2002 Rewrite the RegistrySearchAndReplaceW to use
standard registry api rather than going through
reg & mem wrapper api's.
--*/
#include "pch.h"
UINT
CountInstancesOfSubStringW (
IN PCWSTR SourceString,
IN PCWSTR SearchString,
IN UINT SearchChars
)
{
UINT Count;
UINT SourceChars;
PCWSTR End;
Count = 0;
SourceChars = lstrlenW (SourceString);
End = SourceString + SourceChars - SearchChars;
if (!SearchChars) {
return 0;
}
while (SourceString <= End) {
if (!_wcsnicmp (SourceString, SearchString, SearchChars)) {
Count++;
SourceString += SearchChars;
} else {
SourceString++;
}
}
return Count;
}
PWSTR
StringSearchAndReplaceW (
IN PCWSTR SourceString,
IN PCWSTR SearchString,
IN PCWSTR ReplaceString,
IN DWORD* pcbNewString
)
{
PWSTR NewString;
PBYTE p;
PBYTE Dest;
UINT Count;
UINT Size;
UINT SearchBytes;
UINT ReplaceBytes;
UINT SearchChars;
//
// Count occurances within the string
//
if (pcbNewString) {
*pcbNewString = 0;
}
SearchBytes = ByteCountW (SearchString);
SearchChars = SearchBytes / sizeof (WCHAR);
ReplaceBytes = ByteCountW (ReplaceString);
Count = CountInstancesOfSubStringW (
SourceString,
SearchString,
SearchChars
);
if (!Count) {
return NULL;
}
Size = SizeOfStringW (SourceString) -
Count * SearchBytes +
Count * ReplaceBytes;
NewString = (PWSTR) LocalAlloc(LPTR, Size);
if (!NewString) {
return NULL;
}
if (pcbNewString) {
*pcbNewString = Size;
}
p = (PBYTE) SourceString;
Dest = (PBYTE) NewString;
while (*((PWSTR) p)) {
if (!_wcsnicmp ((PWSTR) p, SearchString, SearchChars)) {
CopyMemory (Dest, ReplaceString, ReplaceBytes);
Dest += ReplaceBytes;
p += SearchBytes;
} else {
*((PWSTR) Dest) = *((PWSTR) p);
p += sizeof (WCHAR);
Dest += sizeof (WCHAR);
}
}
*((PWSTR) Dest) = 0;
return NewString;
}
VOID
RegistrySearchAndReplaceW (
IN HKEY hRoot,
IN PCWSTR szKey,
IN PCWSTR Search,
IN PCWSTR Replace)
{
HKEY hKey = NULL;
HKEY hSubKey = NULL;
DWORD dwType;
DWORD cchMaxSubKeyName, cchNewMaxSubKeyName;
DWORD cchMaxValueName, cchNewMaxValueName, cchLocalValueName;
DWORD cbMaxValue, cbNewMaxValue, cbLocalValue, cbNewLocalValue;
PWSTR szValueName = NULL, szNewValueName = NULL;
PWSTR szSubKeyName = NULL, szNewSubKeyName = NULL;
PBYTE pbValue = NULL, pbNewValue = NULL;
LONG lResult;
DWORD dwIndex;
UNICODE_STRING Unicode_String;
lResult = RegOpenKey(hRoot, szKey, &hKey);
if (ERROR_SUCCESS != lResult) {
DEBUGMSG ((DM_VERBOSE, "Fail to open key %s. Error %d", szKey, lResult));
return;
}
lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL,
&cchMaxSubKeyName, NULL, NULL,
&cchMaxValueName, &cbMaxValue,
NULL, NULL);
if (ERROR_SUCCESS != lResult) {
DEBUGMSG ((DM_VERBOSE, "Fail to query info for key %s. Error %d", szKey, lResult));
goto Exit;
}
cchMaxSubKeyName++; // Include the terminating NULL
cchMaxValueName++; // Include the terminating NULL
//
// Now starts enumerating the value and replace value names &
// string data with "Replace" string in place of "Search" string
//
// Allocate enough memory
szValueName = (LPWSTR) LocalAlloc(LPTR, cchMaxValueName * sizeof(WCHAR));
if (!szValueName) {
goto Exit;
}
pbValue = (LPBYTE) LocalAlloc(LPTR, cbMaxValue);
if (!pbValue) {
goto Exit;
}
dwIndex = 0;
cchLocalValueName = cchMaxValueName;
cbLocalValue = cbMaxValue;
while (RegEnumValue(hKey, dwIndex++, szValueName,
&cchLocalValueName, NULL,
&dwType, pbValue, &cbLocalValue) == ERROR_SUCCESS) {
if (dwType == REG_SZ || dwType == REG_MULTI_SZ || dwType == REG_EXPAND_SZ) {
// Construct the new data value only if it's a string
pbNewValue = (LPBYTE) StringSearchAndReplaceW((PCWSTR)pbValue, Search, Replace, &cbNewLocalValue);
}
// Now construct the new value name by replacing
szNewValueName = StringSearchAndReplaceW(szValueName, Search, Replace, NULL);
// If the value name or data has changed then write a new value
if (szNewValueName || pbNewValue) {
lResult = RegSetValueEx(hKey,
szNewValueName ? szNewValueName : szValueName,
0,
dwType,
pbNewValue ? pbNewValue : pbValue,
pbNewValue ? cbNewLocalValue : cbLocalValue);
}
if (pbNewValue) {
LocalFree(pbNewValue);
pbNewValue = NULL;
}
if (szNewValueName) {
LocalFree(szNewValueName);
szNewValueName = NULL;
if (RegDeleteValue(hKey, szValueName) == ERROR_SUCCESS) {
//
// Start from begining, as enumeration index no longer valid
// with insertion/deletion of value under the key
//
dwIndex = 0;
lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, &cchNewMaxValueName,
&cbNewMaxValue, NULL, NULL);
if (ERROR_SUCCESS != lResult) {
DEBUGMSG ((DM_VERBOSE, "Fail to query info for key %s. Error %d", szKey, lResult));
goto Exit;
}
cchNewMaxValueName++; // Include the terminating NULL
if (cchNewMaxValueName > cchMaxValueName) {
LocalFree(szValueName);
szValueName = NULL;
cchMaxValueName = cchNewMaxValueName;
szValueName = (LPWSTR) LocalAlloc(LPTR, cchMaxValueName * sizeof(WCHAR));
if (!szValueName) {
goto Exit;
}
}
if (cbNewMaxValue > cbMaxValue) {
LocalFree(pbValue);
pbValue = NULL;
cbMaxValue = cbNewMaxValue;
pbValue = (LPBYTE) LocalAlloc(LPTR, cbMaxValue);
if (!pbValue) {
goto Exit;
}
}
}
}
cchLocalValueName = cchMaxValueName;
cbLocalValue = cbMaxValue;
}
LocalFree(szValueName);
szValueName = NULL;
LocalFree(pbValue);
pbValue = NULL;
//
// Now enumerate all the sub keys and replace the name as
// required in a recursive fashion
//
szSubKeyName = (LPWSTR) LocalAlloc(LPTR, cchMaxSubKeyName * sizeof(WCHAR));
if (!szSubKeyName) {
goto Exit;
}
dwIndex = 0;
while (RegEnumKey(hKey, dwIndex++,
szSubKeyName, cchMaxSubKeyName) == ERROR_SUCCESS) {
// recursively replace in the sub key tree
RegistrySearchAndReplaceW(hKey, szSubKeyName, Search, Replace);
szNewSubKeyName = StringSearchAndReplaceW(szSubKeyName, Search, Replace, NULL);
if (szNewSubKeyName) {
if (RegOpenKey(hKey, szSubKeyName, &hSubKey) == ERROR_SUCCESS) {
Unicode_String.Length = ByteCountW(szNewSubKeyName);
Unicode_String.MaximumLength = Unicode_String.Length + sizeof(WCHAR);
Unicode_String.Buffer = szNewSubKeyName;
lResult = NtRenameKey(hSubKey, &Unicode_String);
if (lResult == ERROR_SUCCESS) {
//
// Start from begining, as enumeration index no longer valid
// with rename of sub-keys under the key
//
dwIndex = 0;
lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL,
&cchNewMaxSubKeyName, NULL, NULL,
NULL, NULL, NULL, NULL);
if (ERROR_SUCCESS != lResult) {
DEBUGMSG ((DM_VERBOSE, "Fail to query info for key %s. Error %d", szKey, lResult));
goto Exit;
}
cchNewMaxSubKeyName++; // Include the terminating NULL
if (cchNewMaxSubKeyName > cchMaxSubKeyName) {
LocalFree(szSubKeyName);
szSubKeyName = NULL;
cchMaxSubKeyName = cchNewMaxSubKeyName;
szSubKeyName = (LPWSTR) LocalAlloc(LPTR, cchMaxSubKeyName * sizeof(WCHAR));
if (!szSubKeyName) {
goto Exit;
}
}
}
RegCloseKey(hSubKey);
}
LocalFree(szNewSubKeyName);
szNewSubKeyName = NULL;
}
}
Exit:
if (hKey) {
RegCloseKey(hKey);
}
if (szValueName) {
LocalFree(szValueName);
}
if (pbValue) {
LocalFree(pbValue);
}
if (szSubKeyName) {
LocalFree(szSubKeyName);
}
}