|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
merge.c
Abstract:
Registry merge code
Author:
Jim Schmidt (jimschm) 17-Feb-1997
Revision History:
jimschm 23-Sep-1998 String mapping mechanism jimschm 24-Mar-1998 Added more complex hkcr processing
--*/
#include "pch.h"
#include "mergep.h"
static PCTSTR g_InfFileName;
BOOL g_ProcessRenameTable = FALSE; DWORD g_ProgressBarCounter; HKEY g_DuHandle;
BOOL pForceCopy ( HINF InfFile );
BOOL pForceCopyFromMemDb ( VOID );
BOOL pCreateRenameTable ( IN HINF InfFile, OUT PVOID *RenameTablePtr );
BOOL pProcessRenameTable ( IN PVOID RenameTable );
BOOL pSpecialConversion ( IN HINF InfFile, IN PCTSTR User, IN PVOID RenameTable );
BOOL pProcessSuppressList ( IN HINF InfFile, IN PCTSTR SectionName );
BOOL pProcessHardwareSuppressList ( IN HINF InfFile );
BOOL pSuppressNTDefaults ( IN HINF InfFile, IN PCTSTR SectionName );
BOOL pDontCombineWithDefaults ( IN HINF InfFile, IN PCTSTR SectionName );
BOOL pForceNTDefaults ( IN HINF InfFile, IN PCTSTR SectionName );
BOOL pForceNTDefaultsHack ( IN HINF InfFile, IN PCTSTR SectionName );
BOOL pMergeWin95WithUser ( IN PVOID RenameTable );
BOOL pSpecialConversionNT ( IN HINF InfFile, IN PCTSTR User, IN BOOL PerUser );
BOOL pMergeNTDefaultsWithUser ( IN HINF InfFile );
BOOL pCopyWin95ToSystem ( VOID );
BOOL pMergeWin95WithSystem ( VOID );
BOOL pDeleteAfterMigration ( IN HINF InfFile );
FILTERRETURN SuppressFilter95 ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT DestObjectPtr, OPTIONAL IN FILTERTYPE FilterType, IN PVOID DontCare );
//
// Globals
//
POOLHANDLE g_TempPool; POOLHANDLE g_RenamePool; PMAPSTRUCT g_CompleteMatchMap; PMAPSTRUCT g_SubStringMap;
BOOL WINAPI Merge_Entry ( IN HINSTANCE hinstDLL, IN DWORD dwReason, IN PVOID lpv )
/*++
Routine Description:
DllMain is called after the C runtime is initialized, and its purpose is to initialize the globals for this process.
Arguments:
hinstDLL - (OS-supplied) Instance handle for the DLL dwReason - (OS-supplied) Type of initialization or termination lpv - (OS-supplied) Unused
Return Value:
TRUE because DLL always initializes properly.
--*/
{ switch (dwReason) { case DLL_PROCESS_ATTACH: if(!pSetupInitializeUtils()) { return FALSE; } g_CompleteMatchMap = CreateStringMapping(); g_SubStringMap = CreateStringMapping(); break;
case DLL_PROCESS_DETACH: DestroyStringMapping (g_CompleteMatchMap); DestroyStringMapping (g_SubStringMap); pSetupUninitializeUtils(); break; }
return TRUE; }
BOOL MergeRegistry ( IN PCTSTR FileName, IN PCTSTR User ) { HINF hInf; // handle to the INF being processed
BOOL b = FALSE; // Return value
PVOID RenameTable = NULL; BOOL LogonAccount = FALSE; BOOL DefaultUserAccount = FALSE;
g_ProgressBarCounter = 0;
//
// Open the INF
//
g_InfFileName = FileName; hInf = InfOpenInfFile (FileName);
if (hInf == INVALID_HANDLE_VALUE) { LOG ((LOG_ERROR, "MergeRegistry: SetupOpenInfFile failed for %s", FileName)); return FALSE; }
g_TempPool = PoolMemInitNamedPool ("Merge: temp pool"); g_RenamePool = PoolMemInitNamedPool ("Merge: Rename pool");
if (!g_TempPool || !g_RenamePool) { DEBUGMSG ((DBG_ERROR, "MergeRegistry: Can't init pool")); goto c0; }
PoolMemSetMinimumGrowthSize (g_TempPool, 16384);
if (User) { SetCurrentUserW (g_FixedUserName); }
//
// Perform forced copy of Win95 registry, build rename table,
// execute registry value conversions, convert types, and mark
// specified keys as suppressed.
//
if (!pForceCopy (hInf)) { goto c0; }
if (!User) { if (!pForceCopyFromMemDb ()) { goto c0; } }
if (!pCreateRenameTable (hInf, &RenameTable)) { goto c0; }
//
// Identify the logon account or default user account
//
if (User) { if (*User == 0 || StringIMatch (User, S_DOT_DEFAULT)) {
DEBUGMSG ((DBG_NAUSEA, "The logon user account is indicated by user name '%s'", User)); LogonAccount = TRUE;
} else if (StringIMatch (User, S_DEFAULT_USER)) {
DEBUGMSG ((DBG_NAUSEA, "The default user account template is indicated by user name '%s'", User)); DefaultUserAccount = TRUE; } }
//
// Prepare flags for registry merging
//
if (!pProcessSuppressList (hInf, S_MERGE_WIN9X_SUPPRESS)) { goto c0; }
if (User) { //
// These functions read usermig.inf and set flags
// for the keys, key trees or values, as specified in
// the INF.
//
if (!pSuppressNTDefaults (hInf, S_MERGE_WINNT_SUPPRESS)) { goto c0; }
if (!pDontCombineWithDefaults (hInf, S_MERGE_DONT_COMBINE_WITH_DEFAULT)) { goto c0; }
if (!pForceNTDefaults (hInf, S_MERGE_FORCE_NT_DEFAULTS)) { goto c0; }
if (LogonAccount) { if (!pProcessSuppressList (hInf, S_MERGE_WIN9X_SUPPRESS_LU)) { goto c0; } }
if (DefaultUserAccount) { if (!pProcessSuppressList (hInf, S_MERGE_WIN9X_SUPPRESS_DU)) { goto c0; } }
g_DuHandle = OpenRegKeyStr (L"hklm\\" S_MAPPED_DEFAULT_USER_KEY);
} else { if (!pForceNTDefaults (hInf, S_MERGE_FORCE_NT_DEFAULTS)) { goto c0; }
if (!pProcessHardwareSuppressList (hInf)) { goto c0; } }
if (!pSpecialConversion (hInf, User, RenameTable)) { goto c0; }
//
// Perform merge
//
if (User) { // User merge
if (!pMergeWin95WithUser (RenameTable)) { goto c0; }
if (!pSpecialConversionNT (hInf, User, TRUE)) { goto c0; }
if (!LogonAccount && !DefaultUserAccount) { // Non-default user, not logon prompt account
if (!pMergeNTDefaultsWithUser (hInf)) { goto c0; } } } else { // Workstation merge
if (!pCopyWin95ToSystem()) { goto c0; }
if (!pForceNTDefaultsHack (hInf, S_MERGE_FORCE_NT_DEFAULTS)) { goto c0; }
if (!pMergeWin95WithSystem()) { goto c0; }
if (!CopyHardwareProfiles (hInf)) { goto c0; } TickProgressBar ();
if (!pSpecialConversionNT (hInf, NULL, FALSE)) { goto c0; } TickProgressBar (); }
g_ProcessRenameTable = TRUE;
b = pProcessRenameTable (RenameTable); TickProgressBar ();
g_ProcessRenameTable = FALSE;
//
// Once we are done with the complete registry merge, process the special section
// [Delete After Migration]
//
if (!pDeleteAfterMigration (hInf)) { LOG((LOG_ERROR,"Registry Merge: Delete After Migration failed.")); goto c0; }
c0: if (RenameTable) { pSetupStringTableDestroy (RenameTable); }
if (User) { SetCurrentUserW (NULL); }
if (g_TempPool) { PoolMemDestroyPool (g_TempPool); } if (g_RenamePool) { PoolMemDestroyPool (g_RenamePool); }
if (g_DuHandle) { CloseRegKey (g_DuHandle); g_DuHandle = NULL; }
InfCloseInfFile (hInf);
return b; }
PTSTR pGetStringFromObjectData ( IN CPDATAOBJECT ObPtr ) { PTSTR p; PTSTR end;
//
// Value type has to be a registry object
//
if (!DoesObjectHaveValue (ObPtr) || !IsRegistryTypeSpecified (ObPtr) ) { return NULL; }
if (ObPtr->Type == REG_DWORD) { return NULL; }
if (ObPtr->Value.Size & 1) { return NULL; }
p = (PTSTR) ObPtr->Value.Buffer; end = (PTSTR) ((PBYTE) p + ObPtr->Value.Size);
if ((end - p) >= MAX_PATH) { return NULL; }
if (ObPtr->Type == REG_SZ || ObPtr->Type == REG_EXPAND_SZ) { return p; }
//
// For REG_NONE and REG_BINARY, give it a try by looking for a terminated string
//
if (*(end - 1)) { return NULL; }
return p; }
BOOL SetObjectStringFlag ( IN PCTSTR ObjectStr, IN DWORD Flag, IN DWORD RemoveFlag ) { DWORD Val;
if (!MemDbGetValue (ObjectStr, &Val)) { Val = 0; }
if (Val & RemoveFlag) { if (Val & RemoveFlag & (~Flag)) { DEBUGMSG ((DBG_WARNING, "SetObjectStringFlag: Removing flag %x from val %x in %s", Val & RemoveFlag, Val, ObjectStr)); Val = Val & (~RemoveFlag); } }
Val |= Flag; return MemDbSetValue (ObjectStr, Val); }
BOOL SetObjectStructFlag ( IN CPDATAOBJECT ObPtr, DWORD Flag, DWORD RemoveFlag ) { TCHAR EncodedObject[MAX_ENCODED_RULE];
CreateObjectString (ObPtr, EncodedObject); return SetObjectStringFlag (EncodedObject, Flag, RemoveFlag); }
BOOL CreateRenamedObjectStruct ( IN PVOID RenameTable, IN PDATAOBJECT InObPtr, OUT PDATAOBJECT OutObPtr )
// returns TRUE when OutObPtr is different than InObPtr
{ LONG rc; PCTSTR NewPtr; PTSTR p; PCTSTR Tail; PCTSTR RealValueName; TCHAR EncodedObject[MAX_ENCODED_RULE]; TCHAR CopyOfEncodedObject[MAX_ENCODED_RULE]; PTSTR NewEncodedObject; BOOL b = FALSE;
ZeroMemory (OutObPtr, sizeof (DATAOBJECT));
if (InObPtr->KeyPtr) { // Look for HKR\sub\key
InObPtr->ObjectType &= ~(OT_TREE); RealValueName = InObPtr->ValueName; InObPtr->ValueName = NULL;
CreateObjectString (InObPtr, EncodedObject); StringCopy (CopyOfEncodedObject, EncodedObject);
InObPtr->ValueName = RealValueName;
rc = pSetupStringTableLookUpStringEx (RenameTable, EncodedObject, STRTAB_CASE_INSENSITIVE, (PBYTE) &NewPtr, sizeof (NewPtr) ); if (rc != -1) { CreateObjectStruct (NewPtr, OutObPtr, WINNTOBJECT); b = TRUE; } else if (*EncodedObject) { // Look for HKR\sub\key\*, HKR\sub\* and HKR\*
p = GetEndOfString (EncodedObject); do { StringCopy (p, TEXT("\\*"));
rc = pSetupStringTableLookUpStringEx (RenameTable, EncodedObject, STRTAB_CASE_INSENSITIVE, (PBYTE) &NewPtr, sizeof (NewPtr) ); if (rc != -1) { Tail = CopyOfEncodedObject + (p - EncodedObject); NewEncodedObject = JoinPaths (NewPtr, Tail); CreateObjectStruct (NewEncodedObject, OutObPtr, WINNTOBJECT); FreePathString (NewEncodedObject); b = TRUE; break; }
do { // _tcsdec is fixed in strings.h
p = _tcsdec2 (EncodedObject, p); } while (p && _tcsnextc (p) != TEXT('\\')); } while (p); } }
if (InObPtr->ValueName) { if (InObPtr->KeyPtr) { // Look for HKR\sub\key\[value]
CreateObjectString (InObPtr, EncodedObject);
rc = pSetupStringTableLookUpStringEx (RenameTable, EncodedObject, STRTAB_CASE_INSENSITIVE, (PBYTE) &NewPtr, sizeof (NewPtr) ); if (rc != -1) { CreateObjectStruct (NewPtr, OutObPtr, WINNTOBJECT); b = TRUE; } } }
if (!b) { // If rename not found, copy in object to out object
CopyMemory (OutObPtr, InObPtr, sizeof (DATAOBJECT)); }
return b; }
BOOL CreateRenamedObjectString ( IN PVOID RenameTable, IN PCTSTR InObStr, OUT PTSTR OutObStr ) { DATAOBJECT InObject, OutObject; BOOL b;
if (!CreateObjectStruct (InObStr, &InObject, WIN95OBJECT)) { return FALSE; }
b = CreateRenamedObjectStruct (RenameTable, &InObject, &OutObject);
CreateObjectString (&OutObject, OutObStr);
FreeObjectStruct (&InObject); if (b) { FreeObjectStruct (&OutObject); }
return b; }
BOOL pForceCopy ( HINF InfFile ) { INFCONTEXT ic; TCHAR SrcObjectStr[MAX_ENCODED_RULE]; TCHAR DestObjectStr[MAX_ENCODED_RULE]; DATAOBJECT SrcObject, DestObject, DupObject; BOOL b = TRUE; FILTERRETURN fr;
//
// Look in INF for [ForceCopy] section
//
if (SetupFindFirstLine (InfFile, S_MERGE_FORCECOPY, NULL, &ic)) { //
// For each line in this section, get the encoded object in
// field 0 (the source) and copy it to the encoded object in
// field 1 (the destination).
//
do { *DestObjectStr = 0; if (SetupGetStringField (&ic, 0, SrcObjectStr, MAX_ENCODED_RULE, NULL) && SetupGetStringField (&ic, 1, DestObjectStr, MAX_ENCODED_RULE, NULL) ) { if (!(*DestObjectStr)) { StringCopy (DestObjectStr, SrcObjectStr); }
if (!CreateObjectStruct (SrcObjectStr, &SrcObject, WIN95OBJECT)) { DEBUGMSG ((DBG_WARNING, "pForceCopy: Source object invalid (Section line %u of %s)", ic.Line, g_InfFileName)); continue; }
if (!CreateObjectStruct (DestObjectStr, &DestObject, WINNTOBJECT)) { DEBUGMSG ((DBG_WARNING, "pForceCopy: Destination object invalid (Section line %u of %s)", ic.Line, g_InfFileName)); FreeObjectStruct (&SrcObject); continue; }
if (b = DuplicateObjectStruct (&DupObject, &SrcObject)) { if (b = CombineObjectStructs (&DupObject, &DestObject)) { //
// Copy source to dest
//
fr = CopyObject (&SrcObject, &DupObject, NULL, NULL); if (fr == FILTER_RETURN_FAIL) { LOG ((LOG_ERROR, "Force Copy: CopyObject failed for %s=%s in %s", SrcObjectStr, DestObjectStr, g_InfFileName)); b = FALSE; } }
FreeObjectStruct (&DupObject); }
FreeObjectStruct (&SrcObject); FreeObjectStruct (&DestObject); } else { LOG ((LOG_ERROR, "Force Copy: syntax error in line %u of section %s in %s", ic.Line, S_MERGE_FORCECOPY, g_InfFileName)); }
TickProgressBar ();
} while (b && SetupFindNextLine (&ic, &ic)); }
return TRUE; }
BOOL pForceCopyFromMemDb ( VOID ) { MEMDB_ENUM e; TCHAR key [MEMDB_MAX]; TCHAR SrcObjectStr[MAX_ENCODED_RULE]; TCHAR DestObjectStr[MAX_ENCODED_RULE]; DATAOBJECT SrcObject, DestObject, DupObject; BOOL b = TRUE; FILTERRETURN fr;
//
// Look in MemDb for ForceCopy tree
//
MemDbBuildKey (key, MEMDB_CATEGORY_FORCECOPY, TEXT("*"), NULL, NULL); if (MemDbEnumFirstValue (&e, key, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) { //
// For each key here the offset points to the destination
//
do { if (e.dwValue != 0) { StringCopy (SrcObjectStr, e.szName);
if (MemDbBuildKeyFromOffset (e.dwValue, DestObjectStr, 1, NULL)) {
if (!(*DestObjectStr)) { StringCopy (DestObjectStr, SrcObjectStr); }
if (!CreateObjectStruct (SrcObjectStr, &SrcObject, WIN95OBJECT)) { DEBUGMSG ((DBG_WARNING, "pForceCopyFromMemDb: Source object invalid %s", SrcObjectStr)); continue; }
if (!CreateObjectStruct (DestObjectStr, &DestObject, WINNTOBJECT)) { DEBUGMSG ((DBG_WARNING, "pForceCopyFromMemDb: Destination object invalid %s", DestObjectStr)); FreeObjectStruct (&SrcObject); continue; }
if (b = DuplicateObjectStruct (&DupObject, &SrcObject)) { if (b = CombineObjectStructs (&DupObject, &DestObject)) { //
// Copy source to dest
//
fr = CopyObject (&SrcObject, &DupObject, NULL, NULL); if (fr == FILTER_RETURN_FAIL) { LOG ((LOG_ERROR, "Force Copy from MemDb: CopyObject failed for %s=%s", SrcObjectStr, DestObjectStr)); b = FALSE; } }
FreeObjectStruct (&DupObject); }
FreeObjectStruct (&SrcObject); FreeObjectStruct (&DestObject); } } TickProgressBar ();
} while (b && MemDbEnumNextValue (&e)); }
return TRUE; }
#define S_MERGE_DELETEAFTERMIGRATION TEXT("Delete After Migration")
BOOL pDeleteAfterMigration ( IN HINF InfFile ) { BOOL rSuccess = TRUE; TCHAR objectString[MAX_ENCODED_RULE]; DATAOBJECT object; INFCONTEXT ic; HKEY key;
//
// Look in INF for [DeleteAfterMigration] section
//
if (SetupFindFirstLine (InfFile, S_MERGE_DELETEAFTERMIGRATION, NULL, &ic)) {
//
// For each line in this section, get the encoded object in
// field 0 and delete it from the registry.
//
do {
if (SetupGetStringField(&ic,0,objectString,MAX_ENCODED_RULE,NULL)) {
FixUpUserSpecifiedObject(objectString);
if (!CreateObjectStruct(objectString,&object,WINNTOBJECT)) { LOG(( LOG_ERROR, "Delete After Migration: ObjectString invalid. (Section line %u of %s)", ic.Line, g_InfFileName ));
continue; }
//
// We have a good object. Delete it!
//
if (object.ValueName) {
//
// Value is specified. Delete it.
//
if (!RegDeleteValue(object.KeyPtr->OpenKey,object.ValueName)) { DEBUGMSG((DBG_WARNING,"pDeleteAfterMigration: RegDeleteValue failed for %s [%s]", object.KeyPtr->KeyString, object.ValueName ? object.ValueName : TEXT("<DEFAULT>") )); } } else {
key = GetRootKeyFromOffset (object.RootItem); pSetupRegistryDelnode (key == HKEY_ROOT ? g_hKeyRootNT : key, object.KeyPtr->KeyString);
}
//
// Free our resources.
//
FreeObjectStruct(&object); }
} while (SetupFindNextLine(&ic,&ic)); }
return rSuccess; }
BOOL pCreateRenameTable ( IN HINF InfFile, OUT PVOID *RenameTablePtr ) { INFCONTEXT ic; TCHAR SrcObjectStr[MAX_ENCODED_RULE]; TCHAR DestObjectStr[MAX_ENCODED_RULE]; LONG rc; DATAOBJECT OrgOb; DATAOBJECT NewOb; PCTSTR DestStr;
//
// Look in INF for [Rename] section
//
if (SetupFindFirstLine (InfFile, S_MERGE_RENAME, NULL, &ic)) { //
// Create string table
//
*RenameTablePtr = pSetupStringTableInitializeEx (sizeof (PCTSTR), 0); if (!(*RenameTablePtr)) { LOG ((LOG_ERROR, "Create Rename Table: Cannot allocate a string table")); return FALSE; }
do { if (SetupGetStringField (&ic, 0, SrcObjectStr, MAX_ENCODED_RULE, NULL) && SetupGetStringField (&ic, 1, DestObjectStr, MAX_ENCODED_RULE, NULL) ) { // Ignore bad lines
FixUpUserSpecifiedObject (SrcObjectStr); FixUpUserSpecifiedObject (DestObjectStr);
if (!CreateObjectStruct (SrcObjectStr, &OrgOb, WIN95OBJECT)) { DEBUGMSG ((DBG_WARNING, "pCreateRenameTable: Source object invalid (Section line %u of %s)", ic.Line, g_InfFileName)); continue; }
if (!CreateObjectStruct (DestObjectStr, &NewOb, WINNTOBJECT)) { FreeObjectStruct (&OrgOb); DEBUGMSG ((DBG_WARNING, "pCreateRenameTable: Dest object invalid (Section line %u of %s)", ic.Line, g_InfFileName)); continue; }
//
// Convert DestObjectStr into complete object string
//
if (!CombineObjectStructs (&OrgOb, &NewOb)) { FreeObjectStruct (&NewOb); FreeObjectStruct (&OrgOb);
DEBUGMSG ((DBG_WARNING, "pCreateRenameTable: Can't perform the rename (Section line %u in %s)", ic.Line, g_InfFileName)); continue; }
// Disable tree for destination object
OrgOb.ObjectType &= ~OT_TREE;
CreateObjectString (&OrgOb, DestObjectStr); FreeObjectStruct (&NewOb); FreeObjectStruct (&OrgOb);
DestStr = PoolMemDuplicateString (g_RenamePool, DestObjectStr); if (!DestStr) { break; }
rc = pSetupStringTableAddStringEx ( *RenameTablePtr, (PTSTR) SrcObjectStr, STRTAB_CASE_INSENSITIVE, (PBYTE) &DestStr, sizeof (PCTSTR) );
if (rc == -1) { SetLastError (rc); LOG ((LOG_ERROR, "Create Rename Table: Cannot add string to string table")); break; }
SetObjectStringFlag (SrcObjectStr, REGMERGE_95_RENAME, REGMERGE_95_RENAME); SetObjectStringFlag (DestStr, REGMERGE_NT_SUPPRESS, REGMERGE_NT_MASK); } else { LOG ((LOG_ERROR, "Create Rename Table: syntax error in line %u of section %s in %s", ic.Line, S_MERGE_RENAME, g_InfFileName)); }
TickProgressBar ();
} while (SetupFindNextLine (&ic, &ic)); } else { return FALSE; }
return TRUE; }
BOOL CopyRenameTableEntry ( PVOID StringTable, LONG StringID, PCTSTR SrcObjectStr, PVOID ExtraData, UINT ExtraDataSize, LPARAM lParam ) { PCTSTR DestObjectStr = *((PCTSTR *) ExtraData); DATAOBJECT SrcOb, DestOb; FILTERRETURN fr = FILTER_RETURN_FAIL; DWORD Val;
// See if src has been processed
if (MemDbGetValue (SrcObjectStr, &Val) && (Val & REGMERGE_95_RENAME_SUPPRESS)) { return TRUE; }
// If not, copy Win95 src to WinNT dest
if (CreateObjectStruct (SrcObjectStr, &SrcOb, WIN95OBJECT)) { if (CreateObjectStruct (DestObjectStr, &DestOb, WINNTOBJECT)) { fr = CopyObject (&SrcOb, &DestOb, SuppressFilter95, NULL); FreeObjectStruct (&DestOb); } FreeObjectStruct (&SrcOb); }
return fr != FILTER_RETURN_FAIL; }
BOOL pProcessRenameTable ( IN PVOID RenameTable ) { PCTSTR DataBuf;
return pSetupStringTableEnum (RenameTable, (PVOID) &DataBuf, sizeof (DataBuf), CopyRenameTableEntry, 0); }
BOOL pSpecialConversion ( IN HINF InfFile, IN PCTSTR User, IN PVOID RenameTable ) { INFCONTEXT ic; TCHAR FunctionStr[MAX_ENCODED_RULE]; TCHAR SrcObjectStr[MAX_ENCODED_RULE]; TCHAR RenamedObjectStr[MAX_ENCODED_RULE]; PROCESSINGFN Fn; PVOID Arg;
//
// Look in INF for [SpecialConversion] section
//
if (SetupFindFirstLine (InfFile, S_MERGE_WIN9X_CONVERSION, NULL, &ic)) { //
// For each line, get the function and the source object, then call
// the function.
//
do { if (SetupGetStringField (&ic, 0, FunctionStr, MAX_ENCODED_RULE, NULL) && SetupGetStringField (&ic, 1, SrcObjectStr, MAX_ENCODED_RULE, NULL) ) { FixUpUserSpecifiedObject (SrcObjectStr);
Fn = RuleHlpr_GetFunctionAddr (FunctionStr, &Arg); if (!Fn) { LOG ((LOG_ERROR, "Special Conversion: Invalid function %s in %s", FunctionStr, g_InfFileName)); continue; }
CreateRenamedObjectString (RenameTable, SrcObjectStr, RenamedObjectStr);
if (!Fn (SrcObjectStr, RenamedObjectStr, User, Arg)) { if (GetLastError () == ERROR_SUCCESS) { continue; }
LOG ((LOG_ERROR, "Processing of Special Conversion was aborted because %s failed.", FunctionStr)); break; }
SetObjectStringFlag ( SrcObjectStr, REGMERGE_95_SUPPRESS|REGMERGE_95_RENAME_SUPPRESS, REGMERGE_95_SUPPRESS|REGMERGE_95_RENAME_SUPPRESS );
SetObjectStringFlag (RenamedObjectStr, REGMERGE_NT_SUPPRESS, REGMERGE_NT_MASK);
} else { LOG ((LOG_ERROR, "Special Conversion: syntax error in line %u of section %s in %s", ic.Line, S_MERGE_WIN9X_CONVERSION, g_InfFileName)); }
TickProgressBar ();
} while (SetupFindNextLine (&ic, &ic)); }
return TRUE; }
BOOL SetFlagsForObject ( IN HINF InfFile, IN PCTSTR Section, IN DWORD Flag, IN DWORD RemoveFlag ) { INFCONTEXT ic; TCHAR SrcObjectStr[MAX_ENCODED_RULE];
//
// Look in INF for section
//
if (SetupFindFirstLine (InfFile, Section, NULL, &ic)) { //
// For each line, get the object and mark it as suppressed.
//
do { if (SetupGetStringField (&ic, 1, SrcObjectStr, MAX_ENCODED_RULE, NULL) ) { FixUpUserSpecifiedObject (SrcObjectStr); SetObjectStringFlag (SrcObjectStr, Flag, RemoveFlag); } else { LOG ((LOG_ERROR, "Set Flags For Object: syntax error in line %u of section %s in %s", ic.Line, Section, g_InfFileName)); } TickProgressBar (); } while (SetupFindNextLine (&ic, &ic)); } else { DEBUGMSG ((DBG_VERBOSE, "SetFlagsForObject: Section %s can't be found", Section)); }
return TRUE; }
BOOL pProcessSuppressList ( IN HINF InfFile, IN PCTSTR SectionName ) { return SetFlagsForObject ( InfFile, SectionName, REGMERGE_95_SUPPRESS, REGMERGE_95_SUPPRESS ); }
BOOL pProcessHardwareSuppressList ( IN HINF InfFile ) { return SetFlagsForObject (InfFile, S_MERGE_WIN9X_SUPPRESS_HW, REGMERGE_95_SUPPRESS, REGMERGE_95_SUPPRESS); }
BOOL pSuppressNTDefaults ( IN HINF InfFile, IN PCTSTR SectionName ) { //
// The objects listed in Suppress WinNT Settings are enumerated,
// and they are blocked from being transferred from the NT default
// user to the new user.
//
return SetFlagsForObject ( InfFile, SectionName, REGMERGE_NT_SUPPRESS, REGMERGE_NT_SUPPRESS ); }
BOOL pDontCombineWithDefaults ( IN HINF InfFile, IN PCTSTR SectionName ) { //
// The objects listed in Merge WinNT with Win9x are enumerated,
// and they are blocked from being transferred from the NT default
// user to the new user. In addition, they are put in a list
// to be processed at the end of user registry migration. This
// last step uses CombineFilter to make sure the NT values do
// not overwrite the 9x values.
//
return SetFlagsForObject ( InfFile, SectionName, REGMERGE_NT_IGNORE_DEFAULTS, REGMERGE_NT_IGNORE_DEFAULTS ); }
BOOL pForceNTDefaults ( IN HINF InfFile, IN PCTSTR SectionName ) { //
// The objects listed in Force WinNT Settings are enumerated,
// and they are blocked from being processed during the general
// 9x to NT copy. In addition, they are put in a list to be
// processed at the end of user registry migration. This last
// step forces the entire key to be copied from the default
// user to the new user, overwriting any previously migrated
// settings.
//
// It is important to note that the special conversion functions
// are not suppressed here, but the converted settings may be
// overwritten.
//
return SetFlagsForObject ( InfFile, SectionName, REGMERGE_NT_PRIORITY_NT|REGMERGE_95_SUPPRESS, REGMERGE_NT_PRIORITY_NT|REGMERGE_95_SUPPRESS ); }
BOOL pForceNTDefaultsHack ( IN HINF InfFile, IN PCTSTR SectionName ) { //
// Take away the REGMERGE_95_SUPPRESS flag now, because the general
// 9x merge has completed, but we get confused between an actual
// suppress and a suppress done for the priority-nt case.
//
return SetFlagsForObject ( InfFile, SectionName, REGMERGE_NT_PRIORITY_NT, REGMERGE_NT_PRIORITY_NT|REGMERGE_95_SUPPRESS ); }
FILTERRETURN SuppressFilter95 ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT DestObjectPtr, OPTIONAL IN FILTERTYPE FilterType, IN PVOID DontCare ) { TCHAR ObStr[MAX_ENCODED_RULE]; DWORD Val; PTSTR p, q, r; TCHAR Node[MEMDB_MAX];
if (FilterType == FILTER_CREATE_KEY) { //
// Check if this tree is suppressed
//
MYASSERT (SrcObjectPtr->ObjectType & OT_TREE); MYASSERT (SrcObjectPtr->KeyPtr); MYASSERT (!(SrcObjectPtr->ValueName));
// Query setting for HKR\Sub\Key\*
CreateObjectString (SrcObjectPtr, ObStr); if (MemDbGetValue (ObStr, &Val)) { if (Val & REGMERGE_95_SUPPRESS) { return FILTER_RETURN_DONE; }
if (!g_ProcessRenameTable && (Val & REGMERGE_95_RENAME)) { return FILTER_RETURN_DONE; } }
// If key is a GUID and GUID is suppressed, suppress the tree
p = (PTSTR) SrcObjectPtr->ChildKey; if (p && _tcsnextc (p) == TEXT('{')) { // Look for matching curly brace
q = _tcschr (p, TEXT('}')); if (q) { q = _tcsinc (q);
// Create GUIDS\{a-b-c-d-e}
*Node = 0; r = _tcsappend (Node, MEMDB_CATEGORY_GUIDS); r = _tcsappend (r, TEXT("\\")); StringCopyAB (r, p, q);
// Look for match
if (MemDbGetValue (Node, NULL)) { DEBUGMSG ((DBG_VERBOSE, "Suppressed %s found in %s", Node, ObStr)); return FILTER_RETURN_DONE; } } } }
else if (FilterType == FILTER_PROCESS_VALUES) { //
// Check if this node is suppressed
//
MYASSERT (!(SrcObjectPtr->ObjectType & OT_TREE)); MYASSERT (SrcObjectPtr->KeyPtr); MYASSERT (!(SrcObjectPtr->ValueName)); CreateObjectString (SrcObjectPtr, ObStr);
// Query setting for HKR\Sub\Key
if (!MemDbGetValue (ObStr, &Val)) { Val = 0; }
if (Val & REGMERGE_95_SUPPRESS) { return FILTER_RETURN_HANDLED; }
if (!g_ProcessRenameTable && (Val & REGMERGE_95_RENAME)) { return FILTER_RETURN_HANDLED; }
}
else if (FilterType == FILTER_VALUENAME_ENUM) { //
// Check if this value is suppressed
//
MYASSERT (!(SrcObjectPtr->ObjectType & OT_TREE)); MYASSERT (SrcObjectPtr->KeyPtr); MYASSERT (SrcObjectPtr->ValueName); CreateObjectString (SrcObjectPtr, ObStr);
// If value name is a GUID and GUID is suppressed, suppress the value
p = (PTSTR) SrcObjectPtr->ValueName; if (_tcsnextc (p) == TEXT('{')) { MemDbBuildKey (Node, MEMDB_CATEGORY_GUIDS, NULL, NULL, p); if (MemDbGetValue (Node, NULL)) { return FILTER_RETURN_HANDLED; } }
if (!MemDbGetValue (ObStr, &Val)) { Val = 0; }
if (Val & REGMERGE_95_SUPPRESS) { return FILTER_RETURN_HANDLED; }
if (!g_ProcessRenameTable && (Val & REGMERGE_95_RENAME)) { return FILTER_RETURN_HANDLED; }
}
else if (FilterType == FILTER_VALUE_COPY) { //
// Don't copy if value has a suppressed GUID
//
p = pGetStringFromObjectData (SrcObjectPtr);
if (p && _tcsnextc (p) == TEXT('{')) { MemDbBuildKey (Node, MEMDB_CATEGORY_GUIDS, NULL, NULL, p); if (MemDbGetValue (Node, NULL)) { return FILTER_RETURN_HANDLED; } } }
return FILTER_RETURN_CONTINUE; }
FILTERRETURN SuppressFilterNT ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT DestObjectPtr, OPTIONAL IN FILTERTYPE FilterType, IN PVOID DontCare ) { TCHAR ObStr[MAX_ENCODED_RULE]; DWORD Val; PTSTR p;
if (FilterType == FILTER_CREATE_KEY) { //
// Check if this tree is suppressed
//
MYASSERT (DestObjectPtr->ObjectType & OT_TREE); MYASSERT (DestObjectPtr->KeyPtr); MYASSERT (!(DestObjectPtr->ValueName)); CreateObjectString (DestObjectPtr, ObStr);
if (MemDbGetValue (ObStr, &Val) && (Val & REGMERGE_NT_MASK)) { return FILTER_RETURN_DONE; } }
else if (FilterType == FILTER_PROCESS_VALUES) { DATAOBJECT CopyOfDestOb; DWORD rc; DWORD ValueCount;
//
// Does destination already exist?
//
CopyMemory (&CopyOfDestOb, DestObjectPtr, sizeof (DATAOBJECT)); if (OpenObject (&CopyOfDestOb)) { //
// Does it have values?
//
MYASSERT (!IsWin95Object (&CopyOfDestOb));
rc = RegQueryInfoKey ( CopyOfDestOb.KeyPtr->OpenKey, NULL, // class
NULL, // class size
NULL, // reserved
NULL, // subkey count
NULL, // max subkey length
NULL, // max class length
&ValueCount, NULL, // max value name size
NULL, // max value size
NULL, // security
NULL // last changed time
);
if (rc == ERROR_SUCCESS && ValueCount > 0) { CloseObject (&CopyOfDestOb); return FILTER_RETURN_HANDLED; } }
//
// Check if this node is suppressed
//
MYASSERT (DestObjectPtr->ObjectType & OT_TREE); MYASSERT (DestObjectPtr->KeyPtr); MYASSERT (!(DestObjectPtr->ValueName));
CreateObjectString (DestObjectPtr, ObStr); p = _tcsrchr (ObStr, TEXT('\\')); if (p) { *p = 0; }
if (MemDbGetValue (ObStr, &Val) && (Val & REGMERGE_NT_MASK)) { return FILTER_RETURN_HANDLED; } }
else if (FilterType == FILTER_VALUENAME_ENUM) { //
// Check if this value is suppressed
//
MYASSERT (!(DestObjectPtr->ObjectType & OT_TREE)); MYASSERT (DestObjectPtr->KeyPtr); MYASSERT (DestObjectPtr->ValueName); CreateObjectString (DestObjectPtr, ObStr);
if (MemDbGetValue (ObStr, &Val) && (Val & REGMERGE_NT_MASK)) { return FILTER_RETURN_HANDLED; } }
return FILTER_RETURN_CONTINUE; }
FILTERRETURN CombineFilter ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT DestObjectPtr, OPTIONAL IN FILTERTYPE FilterType, IN PVOID DontCare ) { BOOL b;
if (FilterType == FILTER_VALUE_COPY) { //
// Check if destination already exists in the registry
//
MYASSERT (!(SrcObjectPtr->ObjectType & OT_TREE)); MYASSERT (SrcObjectPtr->KeyPtr); MYASSERT (SrcObjectPtr->ValueName); MYASSERT (!(DestObjectPtr->ObjectType & OT_TREE)); MYASSERT (DestObjectPtr->KeyPtr); MYASSERT (DestObjectPtr->ValueName);
b = CheckIfNtKeyExists (DestObjectPtr);
if (b) { return FILTER_RETURN_HANDLED; } else if (GetLastError() != ERROR_SUCCESS) { return FILTER_RETURN_FAIL; } }
return FILTER_RETURN_CONTINUE; }
FILTERRETURN pSuppressDefaultUserFilter ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT DestObjectPtr, OPTIONAL IN FILTERTYPE FilterType, IN PVOID DontCare ) { TCHAR ObStr[MAX_ENCODED_RULE]; DWORD Val; PTSTR p;
if (FilterType == FILTER_CREATE_KEY) { //
// Check if this tree is suppressed
//
MYASSERT (DestObjectPtr->ObjectType & OT_TREE); MYASSERT (DestObjectPtr->KeyPtr); MYASSERT (!(DestObjectPtr->ValueName));
CreateObjectString (DestObjectPtr, ObStr);
if (MemDbGetValue (ObStr, &Val) && (Val & REGMERGE_NT_IGNORE_DEFAULTS)) { return FILTER_RETURN_DONE; } }
else if (FilterType == FILTER_PROCESS_VALUES) { //
// Check if this node is suppressed
//
MYASSERT (DestObjectPtr->ObjectType & OT_TREE); MYASSERT (DestObjectPtr->KeyPtr); MYASSERT (!(DestObjectPtr->ValueName));
CreateObjectString (DestObjectPtr, ObStr); p = _tcsrchr (ObStr, TEXT('\\')); if (p) { *p = 0; }
if (MemDbGetValue (ObStr, &Val) && (Val & REGMERGE_NT_IGNORE_DEFAULTS)) { return FILTER_RETURN_HANDLED; }
}
else if (FilterType == FILTER_VALUENAME_ENUM) { //
// Check if this value is suppressed
//
MYASSERT (!(DestObjectPtr->ObjectType & OT_TREE)); MYASSERT (DestObjectPtr->KeyPtr); MYASSERT (DestObjectPtr->ValueName);
CreateObjectString (DestObjectPtr, ObStr);
if (MemDbGetValue (ObStr, &Val) && (Val & REGMERGE_NT_IGNORE_DEFAULTS)) { return FILTER_RETURN_HANDLED; } }
return CombineFilter (SrcObjectPtr, DestObjectPtr, FilterType, DontCare); }
FILTERRETURN CopyNoOverwriteFilter ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT DestObjectPtr, OPTIONAL IN FILTERTYPE FilterType, IN PVOID DontCare ) { FILTERRETURN fr;
fr = SuppressFilter95 (SrcObjectPtr, DestObjectPtr, FilterType, DontCare); if (fr != FILTER_RETURN_CONTINUE) { return fr; }
return CombineFilter (SrcObjectPtr, DestObjectPtr, FilterType, DontCare); }
BOOL pMergeWin95WithUser ( IN PVOID RenameTable ) { DATAOBJECT SrcOb, DestOb; BOOL b; FILTERRETURN fr;
//
// Copy unsuppressed Win95 keys to NT user hive
//
b = CreateObjectStruct (TEXT("HKR\\*"), &SrcOb, WIN95OBJECT); MYASSERT (b);
b = CreateObjectStruct (TEXT("HKR\\*"), &DestOb, WINNTOBJECT); MYASSERT (b);
fr = CopyObject (&SrcOb, &DestOb, SuppressFilter95, NULL);
FreeObjectStruct (&SrcOb); FreeObjectStruct (&DestOb);
if (fr == FILTER_RETURN_FAIL) { LOG ((LOG_ERROR, "Merge Win95 With User: CopyObject failed")); return FALSE; }
return TRUE; }
VOID RegistryCombineWorker ( DWORD Flag, FILTERFUNCTION FilterFn, PCTSTR MemDbRoot, PCTSTR SrcRoot, DWORD SrcObjectType ) { MEMDB_ENUM e; TCHAR SrcRegKey[MEMDB_MAX]; TCHAR DestRegKey[MEMDB_MAX]; PTSTR SrcPtr, DestPtr; DATAOBJECT SrcOb, DestOb; FILTERRETURN fr; TCHAR Pattern[32];
wsprintf (Pattern, TEXT("%s\\*"), MemDbRoot);
//
// Enumerate all keys in memdb and call CopyObject for them
//
*SrcRegKey = 0; *DestRegKey = 0;
SrcPtr = _tcsappend (SrcRegKey, SrcRoot); SrcPtr = _tcsappend (SrcPtr, TEXT("\\"));
DestPtr = _tcsappend (DestRegKey, MemDbRoot); DestPtr = _tcsappend (DestPtr, TEXT("\\"));
if (MemDbEnumFirstValue ( &e, Pattern, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY )) {
do { if ((e.dwValue & REGMERGE_NT_MASK) & Flag) { StringCopy (SrcPtr, e.szName); StringCopy (DestPtr, e.szName);
if (!CreateObjectStruct (SrcRegKey, &SrcOb, SrcObjectType)) { LOG ((LOG_ERROR, "Merge NT Defaults With User: Can't create object for %s", SrcRegKey)); continue; }
if (!CreateObjectStruct (DestRegKey, &DestOb, WINNTOBJECT)) { FreeObjectStruct (&SrcOb); LOG ((LOG_ERROR, "Merge NT Defaults With User: Can't create object for %s", SrcRegKey)); continue; }
fr = CopyObject (&SrcOb, &DestOb, FilterFn, NULL); if (fr == FILTER_RETURN_FAIL) { LOG ((LOG_ERROR, "Merge NT Defaults With User: Can't copy %s to %s", SrcRegKey, DestRegKey)); }
FreeObjectStruct (&SrcOb); FreeObjectStruct (&DestOb); }
TickProgressBar ();
} while (MemDbEnumNextValue (&e)); } }
BOOL pMergeNTDefaultsWithUser ( HINF hInf ) { DATAOBJECT SrcOb, DestOb; FILTERRETURN fr; BOOL b;
//
// Copy unsuppressed NT defaults to NT user hive
//
b = CreateObjectStruct ( TEXT("HKLM\\") S_MAPPED_DEFAULT_USER_KEY TEXT("\\*"), &SrcOb, WINNTOBJECT );
MYASSERT (b);
b = CreateObjectStruct (TEXT("HKR\\*"), &DestOb, WINNTOBJECT); MYASSERT (b);
__try { b = FALSE;
fr = CopyObject (&SrcOb, &DestOb, SuppressFilterNT, NULL);
if (fr == FILTER_RETURN_FAIL) { LOG ((LOG_ERROR, "Merge NT Defaults With User: CopyObject failed")); __leave; }
//
// Copy forced NT defaults to NT user hive, then copy all NT defaults
// that need to be combined with Win95 settings.
//
RegistryCombineWorker ( REGMERGE_NT_PRIORITY_NT, NULL, TEXT("HKR"), TEXT("HKLM\\") S_MAPPED_DEFAULT_USER_KEY, WINNTOBJECT );
fr = CopyObject (&SrcOb, &DestOb, pSuppressDefaultUserFilter, NULL);
if (fr == FILTER_RETURN_FAIL) { LOG ((LOG_ERROR, "Combine NT Defaults With User: CopyObject failed")); __leave; }
b = TRUE; }
__finally { FreeObjectStruct (&SrcOb); FreeObjectStruct (&DestOb); }
return b; }
BOOL pCopyWin9xValuesNotInNt ( HINF hInf ) { DATAOBJECT SrcOb, DestOb; FILTERRETURN fr; BOOL b;
//
// Copy Win9x values that NT does not have
//
b = CreateObjectStruct ( TEXT("HKLM\\*"), &SrcOb, WIN95OBJECT );
MYASSERT (b);
b = CreateObjectStruct (TEXT("HKR\\*"), &DestOb, WINNTOBJECT); MYASSERT (b);
__try { b = FALSE;
fr = CopyObject (&SrcOb, &DestOb, SuppressFilterNT, NULL);
if (fr == FILTER_RETURN_FAIL) { LOG ((LOG_ERROR, "Merge NT Defaults With User: CopyObject failed")); __leave; }
//
// Copy forced NT defaults to NT user hive, then copy all NT defaults
// that need to be combined with Win95 settings.
//
RegistryCombineWorker ( REGMERGE_NT_PRIORITY_NT, NULL, TEXT("HKR"), TEXT("HKLM\\") S_MAPPED_DEFAULT_USER_KEY, WINNTOBJECT );
fr = CopyObject (&SrcOb, &DestOb, pSuppressDefaultUserFilter, NULL);
if (fr == FILTER_RETURN_FAIL) { LOG ((LOG_ERROR, "Combine NT Defaults With User: CopyObject failed")); __leave; }
b = TRUE; }
__finally { FreeObjectStruct (&SrcOb); FreeObjectStruct (&DestOb); }
return b; }
BOOL pMergeWin95WithSystem ( VOID )
/*++
Routine Description:
pMergeWin95WithSystem copies the Win95 registry to NT, skipping values that already exist on NT.
Arguments:
none
Return Value:
TRUE if success, FALSE if failure.
--*/
{ RegistryCombineWorker ( REGMERGE_NT_PRIORITY_NT, CopyNoOverwriteFilter, TEXT("HKLM"), // memdb root and dest root
TEXT("HKLM"), // source root
WIN95OBJECT );
return TRUE; }
BOOL pCopyWin95ToSystem ( VOID )
/*++
Routine Description:
pCopyWin95ToSystem copies all Win95 settings to NT, unless the setting is supressed. This achieves a copy with overwrite capability.
Arguments:
none
Return Value:
TRUE if success, FALSE if failure.
--*/
{ DATAOBJECT SrcOb, DestOb; BOOL b; FILTERRETURN fr;
b = CreateObjectStruct (TEXT("HKLM\\*"), &SrcOb, WIN95OBJECT); MYASSERT (b);
b = CreateObjectStruct (TEXT("HKLM\\*"), &DestOb, WINNTOBJECT); MYASSERT (b);
fr = CopyObject (&SrcOb, &DestOb, SuppressFilter95, NULL);
FreeObjectStruct (&SrcOb); FreeObjectStruct (&DestOb);
if (fr == FILTER_RETURN_FAIL) { LOG ((LOG_ERROR, "Copy Win95 To System: CopyObject failed")); return FALSE; }
return TRUE; }
BOOL pSpecialConversionNT ( IN HINF InfFile, IN PCTSTR User, IN BOOL PerUser ) { INFCONTEXT ic; DATAOBJECT SrcOb, DestOb; TCHAR FunctionStr[MAX_ENCODED_RULE]; TCHAR SrcObjectStr[MAX_ENCODED_RULE]; TCHAR DestObjectStr[MAX_ENCODED_RULE]; PROCESSINGFN Fn; PVOID Arg;
//
// Look in INF for [SpecialConversionNT] section
//
if (SetupFindFirstLine (InfFile, S_MERGE_WINNT_CONVERSION, NULL, &ic)) { //
// For each line, get the function and the source object, then call
// the function.
//
do { if (SetupGetStringField (&ic, 0, FunctionStr, MAX_ENCODED_RULE, NULL) && SetupGetStringField (&ic, 1, DestObjectStr, MAX_ENCODED_RULE, NULL) ) { FixUpUserSpecifiedObject (DestObjectStr);
Fn = RuleHlpr_GetFunctionAddr (FunctionStr, &Arg);
if (!Fn) { LOG ((LOG_ERROR, "Special Conversion: Invalid function %s in %s", FunctionStr, g_InfFileName)); continue; }
if (PerUser) { //
// Make source off of HKLM\MappedDefaultUser
//
if (!CreateObjectStruct (DestObjectStr, &SrcOb, WINNTOBJECT)) { continue; }
if (!(SrcOb.RootItem)) { LOG ((LOG_ERROR, "Special Conversion NT: Invalid function object %s", DestObjectStr)); FreeObjectStruct (&SrcOb); continue; }
CreateObjectStruct (TEXT("HKLM"), &DestOb, WINNTOBJECT); CombineObjectStructs (&SrcOb, &DestOb);
StringCopy (SrcObjectStr, S_MAPPED_DEFAULT_USER_KEY TEXT("\\")); CreateObjectString (&SrcOb, GetEndOfString (SrcObjectStr));
FreeObjectStruct (&DestOb); FreeObjectStruct (&SrcOb);
} else {
if (!CreateObjectStruct (DestObjectStr, &SrcOb, WINNTOBJECT)) { continue; }
if (!(SrcOb.RootItem)) { LOG ((LOG_ERROR, "Special Conversion NT: Invalid function object %s", DestObjectStr)); FreeObjectStruct (&SrcOb); continue; }
CreateObjectString (&SrcOb, SrcObjectStr); FreeObjectStruct (&SrcOb);
}
if (!Fn (SrcObjectStr, PerUser ? DestObjectStr : SrcObjectStr, User, Arg)) { if (GetLastError () == ERROR_SUCCESS) { continue; }
LOG ((LOG_ERROR, "Processing of Special Conversion was aborted because %s failed.", FunctionStr)); break; }
SetObjectStringFlag (SrcObjectStr, REGMERGE_NT_SUPPRESS, REGMERGE_NT_MASK); } else { LOG ((LOG_ERROR, "Special Conversion NT: syntax error in line %u of section %s in %s", ic.Line, S_MERGE_WINNT_CONVERSION, g_InfFileName)); }
TickProgressBar ();
} while (SetupFindNextLine (&ic, &ic)); }
return TRUE; }
BOOL SuppressWin95Object ( IN PCTSTR ObjectStr ) { return SetObjectStringFlag (ObjectStr, REGMERGE_95_SUPPRESS, REGMERGE_95_SUPPRESS); }
BOOL CheckIfNtKeyExists ( IN CPDATAOBJECT SrcObjectPtr )
/*++
Routine Description:
CheckIfNtKeyExists takes a 9x object and tests to see if the same NT setting exists. The 9x object must have a key and value name.
Arguments:
SrcObjectPtr - Specifies the 9x object to test.
Return Value:
TRUE if the object exists in NT, FALSE if it doesn't or if an error occurs. GetLastError indicates the error (if any).
--*/
{ DATAOBJECT NtObject; BOOL b; PCSTR value1; PCSTR value2; PCWSTR value3; PCWSTR oldValueName; HKEY oldRoot;
if (!DuplicateObjectStruct (&NtObject, SrcObjectPtr)) { LOG ((LOG_ERROR, "Combine Filter: destination is invalid")); return FALSE; }
SetPlatformType (&NtObject, FALSE);
b = OpenObject (&NtObject);
if (!b && g_DuHandle) {
oldRoot = GetRegRoot(); SetRegRoot (g_DuHandle);
b = OpenObject (&NtObject);
SetRegRoot (oldRoot); }
if (b) { b = ReadObject (&NtObject);
if (!b) { if (OurGetACP() == 932) { //
// Katakana special case
//
oldValueName = NtObject.ValueName; value1 = ConvertWtoA (NtObject.ValueName); value2 = ConvertSBtoDB (NULL, value1, NULL); value3 = ConvertAtoW (value2); NtObject.ValueName = value3; FreeObjectVal (&NtObject); b = ReadObject (&NtObject); FreeConvertedStr (value3); FreePathStringA (value2); FreeConvertedStr (value1); NtObject.ValueName = oldValueName; } } }
FreeObjectStruct (&NtObject); SetLastError (ERROR_SUCCESS);
return b; }
|