898 lines
23 KiB
C
898 lines
23 KiB
C
|
/*++
|
|||
|
|
|||
|
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);
|
|||
|
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);
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
<EFBFBD> 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.
|
|||
|
<EFBFBD> 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.
|
|||
|
<EFBFBD> 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.
|
|||
|
<EFBFBD> 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);
|
|||
|
}
|