|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
hwprof.c
Abstract:
Hardware profile merge code
Author:
Jim Schmidt (jimschm) 29-May-1997
Revision History:
--*/
#include "pch.h"
#include "mergep.h"
HASHTABLE g_SoftwareDefaultListHash = NULL;
typedef struct _HARDWARE_PROFILE { DWORD NumberOnWin9x; } HARDWARE_PROFILE, *PHARDWARE_PROFILE;
GROWLIST g_HardwareProfileList = GROWLIST_INIT;
BOOL pCreateDefaultKey ( LPCTSTR BaseRegStr );
BOOL pCopyHwProfileProperties ( IN DWORD ProfileSrcId, IN DWORD ProfileDestId );
FILTERRETURN pHwProfileEnumFilter ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT Unused, OPTIONAL IN FILTERTYPE FilterType, IN LPVOID FilterArg OPTIONAL );
BOOL pCopyHwProfileConfigData ( IN DWORD ProfileSrcId, IN DWORD ProfileDestId );
VOID pDeleteProfilesConfigValues( IN DWORD ConfigNumber );
BOOL pDeleteDefaultKey ( IN LPCTSTR BaseRegStr );
DWORD pGetCurrentConfig ( VOID );
BOOL pCopyCurrentConfig ( VOID );
VOID pProcessSoftwareDefaultList( IN HINF InfFile, IN PCTSTR Section );
VOID pFreeSoftwareDefaultList( VOID );
VOID pMigrateHardwareProfiles( VOID );
BOOL CopyHardwareProfiles ( IN HINF InfFile ) { BOOL b; DATAOBJECT Win9xOb;
//
// Move current hardware profile into Default key
//
if (!pCreateDefaultKey (S_IDCONFIGDB_HW_KEY)) { LOG ((LOG_ERROR, "Unable to complete CopyHardwareProfiles")); return FALSE; }
if (!pCreateDefaultKey (S_NT_CONFIG_KEY)) { LOG ((LOG_ERROR, "Unable to complete CopyHardwareProfiles (2)")); return FALSE; }
//
// Enumerate all Win9x hardware profiles and copy each one
//
pProcessSoftwareDefaultList(InfFile, S_MERGE_WIN9X_SUPPRESS_SFT_D);
b = CreateObjectStruct (S_9X_CONFIG_KEY S_TREE, &Win9xOb, WIN95OBJECT); MYASSERT(b);
b = FILTER_RETURN_FAIL != CopyObject (&Win9xOb, NULL, pHwProfileEnumFilter, (PVOID)pGetCurrentConfig());
pFreeSoftwareDefaultList();
pMigrateHardwareProfiles();
//
// Clean up Default key
//
pDeleteDefaultKey (S_IDCONFIGDB_HW_KEY); pDeleteDefaultKey (S_NT_CONFIG_KEY);
//
// Set the current config value
//
// b = pCopyCurrentConfig();
FreeObjectStruct (&Win9xOb);
return b; }
FILTERRETURN pHwProfileSuppressFilter ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT DestObjectPtr, OPTIONAL IN FILTERTYPE FilterType, IN LPVOID UnusedArg OPTIONAL ) { TCHAR ObStr[MAX_ENCODED_RULE]; LPTSTR p; TCHAR Node[MEMDB_MAX];
if (FilterType == FILTER_CREATE_KEY) { // Create empty key is unnecessary
return FILTER_RETURN_HANDLED; }
else if (FilterType == FILTER_KEY_ENUM || FilterType == FILTER_PROCESS_VALUES || FilterType == FILTER_VALUENAME_ENUM ) { // Make p point to HKLM\Config\0001\...
CreateObjectString (SrcObjectPtr, ObStr, ARRAYSIZE(ObStr)); p = ObStr;
// Make p point to \Config\0001\subkey
p = _tcschr (p, TEXT('\\')); if (p) { // Make p point to \0001\subkey
p = _tcschr (_tcsinc (p), TEXT('\\')); if (p) { // Make p point to \subkey
p = _tcschr (_tcsinc (p), TEXT('\\')); if (p) { // Make p point to subkey
p = _tcsinc (p); } else { p = S_EMPTY; } } }
if (!p) { DEBUGMSG (( DBG_WHOOPS, "pHwProfileSuppressFilter: Not a hardware profile key: %s", ObStr ));
return FILTER_RETURN_FAIL; }
//
// If an entry exists in memdb's HKCC category, we have a
// suppression match
//
wsprintf (Node, TEXT("HKCC\\%s"), p); if (MemDbGetValue (Node, NULL)) { return FILTER_RETURN_HANDLED; } }
return FILTER_RETURN_CONTINUE; }
VOID pProcessSoftwareDefaultList( IN HINF InfFile, IN PCTSTR Section ) { INFCONTEXT ic; TCHAR SrcObjectStr[MAX_ENCODED_RULE];
g_SoftwareDefaultListHash = HtAllocW();
if(!g_SoftwareDefaultListHash){ LOG ((LOG_ERROR, "pProcessSoftwareDefaultList: Can't create hash table")); return; }
if(SetupFindFirstLine (InfFile, Section, NULL, &ic)){ do{ if(SetupGetStringField (&ic, 1, SrcObjectStr, MAX_ENCODED_RULE, NULL)){ FixUpUserSpecifiedObject(SrcObjectStr); HtAddString(g_SoftwareDefaultListHash, SrcObjectStr); } else{ LOG ((LOG_ERROR, "pProcessSoftwareDefaultList: syntax error in line %u of section %s in wkstamig.inf", ic.Line, Section)); } } while (SetupFindNextLine (&ic, &ic)); } else{ DEBUGMSG ((DBG_VERBOSE, "pProcessSoftwareDefaultList: Section %s can't be found", Section)); } }
VOID pFreeSoftwareDefaultList( VOID ) { INFCONTEXT ic; TCHAR SrcObjectStr[MAX_ENCODED_RULE];
if(g_SoftwareDefaultListHash){ HtFree(g_SoftwareDefaultListHash); g_SoftwareDefaultListHash = NULL; } }
FILTERRETURN pHwSoftwareDefaultDetectFilter ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT DestObjectPtr, OPTIONAL IN FILTERTYPE FilterType, IN LPVOID Arg ) { TCHAR ObStr[MAX_ENCODED_RULE]; LPTSTR p; TCHAR Node[MEMDB_MAX]; BOOL * notDefault;
if(!Arg){ MYASSERT(FALSE); return FILTER_RETURN_FAIL; }
notDefault = Arg;
if (FilterType == FILTER_VALUENAME_ENUM){ // Make p point to HKLM\Config\0001\...
CreateObjectString (SrcObjectPtr, ObStr, ARRAYSIZE(ObStr)); p = ObStr;
// Make p point to \Config\0001\Software\subkey
p = _tcschr (p, TEXT('\\')); if (p) { // Make p point to \0001\Software\subkey
p = _tcschr (_tcsinc (p), TEXT('\\')); if (p) { // Make p point to \Software\subkey
p = _tcschr (_tcsinc (p), TEXT('\\')); if (p) { // Make p point to \subkey
p = _tcschr (_tcsinc (p), TEXT('\\')); if (p) { // Make p point to subkey
p = _tcsinc (p); } else { p = S_EMPTY; } } } }
if (!p) { DEBUGMSG (( DBG_ERROR, "pHwSoftwareDefaultDetectFilter: Not a hardware profile key: %s", ObStr ));
return FILTER_RETURN_FAIL; }
//
// If an entry exists in memdb's HKCC category, we have a
// suppression match
//
wsprintf (Node, TEXT("HKCC\\Software\\%s"), p); if(MemDbGetValue(Node, NULL)) { return FILTER_RETURN_CONTINUE; } wsprintf (Node, TEXT("HKCCS\\%s"), p); if(HtFindString(g_SoftwareDefaultListHash, Node)){ return FILTER_RETURN_CONTINUE; }
DEBUGMSG((DBG_VERBOSE, "pHwSoftwareDefaultDetectFilter(%s): not-default profile", Node)); *notDefault = TRUE;
return FILTER_RETURN_FAIL; } return FILTER_RETURN_CONTINUE; }
BOOL pIsSoftwareBranchDefault( IN DWORD ConfigNumber ) { BOOL b; DATAOBJECT Win9xOb; TCHAR keyName[MAX_TCHAR_PATH]; BOOL notDefault;
wsprintf(keyName, S_9X_CONFIG_MASK S_SOFTWARE S_TREE, ConfigNumber);
b = CreateObjectStruct(keyName, &Win9xOb, WIN95OBJECT); MYASSERT(b);
if(!b){ return TRUE; }
notDefault = FALSE; CopyObject(&Win9xOb, NULL, pHwSoftwareDefaultDetectFilter, (PVOID)¬Default);
FreeObjectStruct(&Win9xOb);
return !notDefault; }
FILTERRETURN pHwProfileEnumFilter ( IN CPDATAOBJECT SrcObjectPtr, IN CPDATAOBJECT Unused, OPTIONAL IN FILTERTYPE FilterType, IN LPVOID FilterArg OPTIONAL ) { LPCTSTR p; DWORD CurrentConfig = (DWORD)FilterArg; HARDWARE_PROFILE hardwareProfile;
MYASSERT(CurrentConfig);
if (FilterType == FILTER_KEY_ENUM) { // Make p point to 0001\Subkey
p = _tcschr (SrcObjectPtr->KeyPtr->KeyString, TEXT('\\')); if (!p) { // Object string is premature -- keep enumerating
return FILTER_RETURN_CONTINUE; } else { p = _tcsinc (p); }
// Get current configuration number
hardwareProfile.NumberOnWin9x = _ttoi (p);
MYASSERT(hardwareProfile.NumberOnWin9x);
if(hardwareProfile.NumberOnWin9x == CurrentConfig){ if(GrowListGetSize(&g_HardwareProfileList)){ GrowListInsert(&g_HardwareProfileList, 0, (PBYTE)&hardwareProfile, sizeof(hardwareProfile)); } else{ GrowListAppend(&g_HardwareProfileList, (PBYTE)&hardwareProfile, sizeof(hardwareProfile)); } } else if(!pIsSoftwareBranchDefault(hardwareProfile.NumberOnWin9x)){ GrowListAppend(&g_HardwareProfileList, (PBYTE)&hardwareProfile, sizeof(hardwareProfile)); } } return FILTER_RETURN_HANDLED; }
/*
� The current hardware profile is used as the "default" hardware profile. The Windows NT key Hardware Profiles\0001 is renamed to Hardware Profiles\Default for temporary use. � The Windows NT defaults are used as the base of all upgraded profiles. For each hardware profile on Windows 9x, a Hardware Profiles\<n> key is created, where <n> is the numeric identifier of the Windows 9x hardware profile. All values and subkeys of Hardware Profiles\Default are copied to this new key. � The Windows 9x settings are copied to NT. For each hardware profile on Windows 9x, the entire registry tree in Config\<n> is copied to Hardware Profiles\<n>, where <n> is the four-digit hardware profile numeric identifier. � The default settings are deleted. Setup removes the Hardware Profiles\Default key. */
BOOL pCreateDefaultKey ( LPCTSTR BaseRegStr ) { DATAOBJECT SrcOb, DestOb; TCHAR SrcObStr[MAX_ENCODED_RULE]; TCHAR DestObStr[MAX_ENCODED_RULE]; BOOL b;
wsprintf (SrcObStr, TEXT("%s\\%s\\*") , BaseRegStr, S_HW_ID_0001); b = CreateObjectStruct (SrcObStr, &SrcOb, WINNTOBJECT); MYASSERT(b);
wsprintf (DestObStr, TEXT("%s\\%s\\*"), BaseRegStr, S_HW_DEFAULT); b = CreateObjectStruct (DestObStr, &DestOb, WINNTOBJECT); MYASSERT(b);
b = RenameDataObject (&SrcOb, &DestOb);
FreeObjectStruct (&SrcOb); FreeObjectStruct (&DestOb);
if (!b) { LOG ((LOG_ERROR, "CreateDefaultKey: Could not rename %s to %s", SrcObStr, DestObStr)); }
return b; }
VOID pDeleteProfilesConfigValues( IN DWORD ConfigNumber ) { DATAOBJECT Object; TCHAR ObStr[MAX_ENCODED_RULE]; BOOL bResult; UINT i; static PCTSTR ObjectsValue[] = { TEXT("Aliasable"), TEXT("Cloned"), TEXT("HwProfileGuid") };
for(i = 0; i < ARRAYSIZE(ObjectsValue); i++){ wsprintf (ObStr, S_NT_HW_ID_MASK TEXT("\\[%s]"), ConfigNumber, ObjectsValue[i]); bResult = CreateObjectStruct (ObStr, &Object, WINNTOBJECT); if(!bResult){ MYASSERT(FALSE); continue; } bResult = DeleteDataObjectValue (&Object); MYASSERT(bResult); FreeObjectStruct (&Object); } return; }
BOOL pDeleteDefaultKey ( IN LPCTSTR BaseRegStr ) { DATAOBJECT Object; TCHAR ObStr[MAX_ENCODED_RULE]; BOOL b;
wsprintf (ObStr, TEXT("%s\\%s\\*"), BaseRegStr, S_HW_DEFAULT); b = CreateObjectStruct (ObStr, &Object, WINNTOBJECT); MYASSERT(b);
b = DeleteDataObject (&Object);
FreeObjectStruct (&Object);
if (!b) { LOG ((LOG_ERROR, "CreateDefaultKey: Could not delete %s", ObStr)); }
return b; }
BOOL pCopyHwProfileConfigData ( IN DWORD ProfileSrcId, IN DWORD ProfileDestId ) { DATAOBJECT DefaultOb, SrcConfigOb, DestOb; BOOL b; TCHAR Buf[MAX_TCHAR_PATH];
ZeroMemory (&DefaultOb, sizeof (DefaultOb)); ZeroMemory (&SrcConfigOb, sizeof (SrcConfigOb)); ZeroMemory (&DestOb, sizeof (DestOb));
//
// DefaultOb struct points to the default NT hardware profile
// configuration (i.e. HKLM\System\CCS\Hardware Profiles\Default)
//
b = CreateObjectStruct (S_NT_DEFAULT_HW_KEY S_TREE, &DefaultOb, WINNTOBJECT); MYASSERT(b);
//
// SrcConfigOb struct points to the reg key holding the Win9x
// configuration settings (i.e. HKLM\Config\<ProfileId>)
//
wsprintf (Buf, S_9X_CONFIG_MASK S_TREE, ProfileSrcId); b = b && CreateObjectStruct (Buf, &SrcConfigOb, WIN95OBJECT); MYASSERT(b);
//
// DestOb struct points to the reg key to receive combined WinNT
// and Win9x settings (i.e. HKLM\System\CCS\Hardware Profiles\<n>)
//
wsprintf (Buf, S_NT_CONFIG_MASK S_TREE, ProfileDestId); b = b && CreateObjectStruct (Buf, &DestOb, WINNTOBJECT); MYASSERT(b);
//
// Copy defaults to new profile, then copy Win9x settings as well
//
if (b) { b = FILTER_RETURN_FAIL != CopyObject (&DefaultOb, &DestOb, NULL, NULL); if (!b) { LOG ((LOG_ERROR, "pCopyHwProfileConfigData: Unable to copy defaults")); } } if (b) { b = FILTER_RETURN_FAIL != CopyObject (&SrcConfigOb, &DestOb, pHwProfileSuppressFilter, NULL); if (!b) { LOG ((LOG_ERROR, "Copy Hardware Profile: Unable to copy Win9x settings")); } }
//
// Cleanup
//
FreeObjectStruct (&DefaultOb); FreeObjectStruct (&SrcConfigOb); FreeObjectStruct (&DestOb);
return b; }
BOOL pCopyHwProfileProperties ( IN DWORD ProfileSrcId, IN DWORD ProfileDestId ) { DATAOBJECT DefaultOb, NameOb, DestOb; BOOL b; TCHAR Buf[MAX_TCHAR_PATH];
ZeroMemory (&DefaultOb, sizeof (DefaultOb)); ZeroMemory (&NameOb, sizeof (NameOb)); ZeroMemory (&DestOb, sizeof (DestOb));
//
// DefaultOb struct points to the default NT hardware profile
// properties
//
b = CreateObjectStruct (S_NT_DEFAULT_HW_ID_KEY S_TREE, &DefaultOb, WINNTOBJECT); MYASSERT(b);
//
// NameOb struct points to the reg key holding FriendlyName<n>
// (i.e. HKLM\System\CCS\Control\IDConfigDB)
//
b = b && CreateObjectStruct (S_BASE_IDCONFIGDB_KEY, &NameOb, WIN95OBJECT); MYASSERT(b);
//
// DestOb struct points to the reg key to receive FriendlyName
// and PreferenceOrder (i.e. HKLM\System\CCS\Control\IDConfigDB\Hardware
// Profiles\<ProfileId>)
//
wsprintf (Buf, S_NT_HW_ID_MASK S_TREE, ProfileDestId); b = b && CreateObjectStruct (Buf, &DestOb, WINNTOBJECT); MYASSERT(b);
//
// Copy default settings to dest object
//
if (b) { b = FILTER_RETURN_FAIL != CopyObject (&DefaultOb, &DestOb, NULL, NULL); if (!b) { LOG ((LOG_ERROR, "Object copy failed")); } DEBUGMSG_IF ((!b, DBG_ERROR, "pCopyHwProfileProperties: Cannot copy, source=%s", DebugEncoder (&DefaultOb))); DEBUGMSG_IF ((!b, DBG_ERROR, "pCopyHwProfileProperties: Cannot copy, dest=%s", DebugEncoder (&DestOb))); }
//
// Copy FriendlyName and PreferenceOrder values to dest object
//
// Obtain FriendlyName<n>
if (b) { wsprintf (Buf, S_FRIENDLYNAME_SPRINTF, ProfileSrcId); SetRegistryValueName (&NameOb, Buf);
b = ReadObject (&NameOb); if (!b) { LOG ((LOG_ERROR, "Copy Hardware Profile Properties: Cannot obtain friendly name")); } }
// Copy data to dest object struct
if (b) { SetRegistryType (&DestOb, REG_SZ); b = ReplaceValue (&DestOb, NameOb.Value.Buffer, NameOb.Value.Size); if (!b) { LOG ((LOG_ERROR, "Copy Hardware Profile Properites: Cannot replace value data")); } }
// Write dest object
if (b) { SetRegistryValueName (&DestOb, S_FRIENDLYNAME); b = WriteObject (&DestOb); if (!b) { LOG ((LOG_ERROR, "Copy Hardware Profile Properties: Cannot write object")); } DEBUGMSG_IF ((!b, DBG_ERROR, "pCopyHwProfileProperties: Cannot write %s", DebugEncoder (&DestOb))); }
// Set preference order in dest object struct
if (b) { SetRegistryType (&DestOb, REG_DWORD); ProfileDestId--; b = ReplaceValue (&DestOb, (LPBYTE) &ProfileDestId, sizeof(ProfileDestId)); if (!b) { LOG ((LOG_ERROR, "Copy Hardware Profile Properties: Cannot set preference order value data")); } DEBUGMSG_IF ((!b, DBG_ERROR, "pCopyHwProfileProperties: Cannot set preference order value data")); }
// Write dest object
if (b) { SetRegistryValueName (&DestOb, S_PREFERENCEORDER); b = WriteObject (&DestOb); if (!b) { LOG ((LOG_ERROR, "Copy Hardware Profile Properties: Cannot write object")); } DEBUGMSG_IF ((!b, DBG_ERROR, "pCopyHwProfileProperties: Cannot write %s", DebugEncoder (&DestOb))); }
//
// Cleanup
//
FreeObjectStruct (&DefaultOb); FreeObjectStruct (&NameOb); FreeObjectStruct (&DestOb);
return b; }
DWORD pGetCurrentConfig ( VOID ) { DATAOBJECT SrcOb; BOOL b; DWORD dwCurrentConfig = 1;
b = CreateObjectStruct (S_CURRENT_CONFIG, &SrcOb, WIN95OBJECT); MYASSERT(b); if (ReadObject (&SrcOb)) { if (IsRegistryTypeSpecified (&SrcOb) && SrcOb.Type == REG_SZ) { //
// Set destination's object to a REG_DWORD equivalent of
// the Win9x REG_SZ setting
//
dwCurrentConfig = _ttoi ((LPCTSTR) SrcOb.Value.Buffer); if(!dwCurrentConfig){ dwCurrentConfig = 1; MYASSERT(FALSE); } DEBUGMSG ((DBG_VERBOSE, "pGetCurrentConfig: %d", dwCurrentConfig)); } else { LOG (( LOG_ERROR, "Get Current Config: Read unexpected data type from registry in object" )); DEBUGMSG (( DBG_ERROR, "pGetCurrentConfig: Read unexpected data type from registry in %s", DebugEncoder (&SrcOb) )); } } else { LOG (( LOG_ERROR, "Get Current Config: Could not read object" )); DEBUGMSG (( DBG_ERROR, "pGetCurrentConfig: Could not read %s", DebugEncoder (&SrcOb) )); }
FreeObjectStruct (&SrcOb);
return dwCurrentConfig; }
BOOL pCopyCurrentConfig ( VOID ) { DATAOBJECT SrcOb, DestOb; BOOL b; DWORD d;
b = CreateObjectStruct (S_CURRENT_CONFIG, &SrcOb, WIN95OBJECT); MYASSERT(b);
b = CreateObjectStruct (S_CURRENT_CONFIG, &DestOb, WINNTOBJECT); MYASSERT(b);
b = ReadObject (&SrcOb); if (b) { if (IsRegistryTypeSpecified (&SrcOb) && SrcOb.Type == REG_SZ) { //
// Set destination's object to a REG_DWORD equivalent of
// the Win9x REG_SZ setting
//
d = _ttoi ((LPCTSTR) SrcOb.Value.Buffer); b = ReplaceValue (&DestOb, (LPBYTE) &d, sizeof(d));
if (b) { SetRegistryType (&DestOb, REG_DWORD); b = WriteObject (&DestOb); if (!b) { LOG (( LOG_ERROR, "Copy Current Config: Could not write object" )); } DEBUGMSG_IF (( !b, DBG_ERROR, "pCopyCurrentConfig: Could not write %s", DebugEncoder (&DestOb) )); } else { LOG ((LOG_ERROR, "Copy Current Config: Unable to replace value")); DEBUGMSG ((DBG_ERROR, "pCopyCurrentConfig: Unable to replace value")); } } else { LOG (( LOG_ERROR, "Copy Current Config: Read unexpected data type from registry in object" )); DEBUGMSG (( DBG_ERROR, "pCopyCurrentConfig: Read unexpected data type from registry in %s", DebugEncoder (&SrcOb) )); } } else { LOG (( LOG_ERROR, "Copy Current Config: Could not read object" )); DEBUGMSG (( DBG_ERROR, "pCopyCurrentConfig: Could not read %s", DebugEncoder (&SrcOb) )); }
FreeObjectStruct (&SrcOb); FreeObjectStruct (&DestOb);
return b; }
VOID pMigrateHardwareProfiles( VOID ) { PHARDWARE_PROFILE hardwareProfile; UINT destHWProfileNumber; UINT itemCount;
BOOL b;
for(destHWProfileNumber = 1, itemCount = GrowListGetSize(&g_HardwareProfileList); destHWProfileNumber <= itemCount; destHWProfileNumber++){ hardwareProfile = (PHARDWARE_PROFILE)GrowListGetItem(&g_HardwareProfileList, destHWProfileNumber - 1);
MYASSERT(hardwareProfile);
//
// Process hardware profile ID entry
//
b = pCopyHwProfileProperties(hardwareProfile->NumberOnWin9x, destHWProfileNumber); if (!b) { LOG ((LOG_ERROR, "Unable to continue processing hardware profile %04u->%04u", hardwareProfile->NumberOnWin9x, destHWProfileNumber)); }
//
// Process hardware profile configuration entries
//
if (b) { b = pCopyHwProfileConfigData(hardwareProfile->NumberOnWin9x, destHWProfileNumber); if (!b) { LOG ((LOG_ERROR, "Unable to complete processing hardware profile %04u->%04u", hardwareProfile->NumberOnWin9x, destHWProfileNumber)); } }
if(1 != destHWProfileNumber){ pDeleteProfilesConfigValues(destHWProfileNumber); } } FreeGrowList(&g_HardwareProfileList); }
|