|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: C O N F L I C T . C P P
//
// Contents: Code to handle and display software/hardware conflicts
// during upgrade
//
// Notes:
//
// Author: kumarp 04/12/97 17:17:27
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "conflict.h"
#include "infmap.h"
#include "kkreg.h"
#include "kkstl.h"
#include "kkutils.h"
#include "ncreg.h"
#include "netreg.h"
#include "nustrs.h"
#include "nuutils.h"
#include "oemupg.h"
#include "ncsvc.h"
// ----------------------------------------------------------------------
// External string constants
//
extern const WCHAR c_szRegValServiceName[]; extern const WCHAR c_szParameters[];
// ----------------------------------------------------------------------
// String constants
//
const WCHAR sz_DLC[] = L"DLC"; const WCHAR sz_NBF[] = L"NBF"; const WCHAR sz_SNAServerKey[] = L"SOFTWARE\\Microsoft\\Sna Server\\CurrentVersion"; const WCHAR sz_SNAServerVersion[] = L"SNAVersion";
// ----------------------------------------------------------------------
TPtrList* g_pplNetComponents=NULL;
// ----------------------------------------------------------------------
//
// Function: UpgradeConflictsFound
//
// Purpose: Find out if upgrade conflicts have been detected
//
// Arguments: None
//
// Returns: TRUE if found, FALSE otherwise
//
// Author: kumarp 17-December-97
//
// Notes:
//
BOOL UpgradeConflictsFound() { return (g_pplNetComponents && g_pplNetComponents->size()); }
// ----------------------------------------------------------------------
//
// Function: CNetComponent::CNetComponent
//
// Purpose: constructor for class CNetComponent
//
// Arguments:
// pszPreNT5InfId [in] pre NT5 InfID (e.g. IEEPRO)
// pszPreNT5Instance [in] pre NT5 instance name (e.g. IEEPRO2)
// pszDescription [in] description
// eType [in] type (software / hardware)
//
// Author: kumarp 17-December-97
//
// Notes:
//
CNetComponent::CNetComponent(PCWSTR pszPreNT5InfId, PCWSTR pszPreNT5Instance, PCWSTR pszDescription, EComponentType eType) : m_strPreNT5InfId(pszPreNT5InfId), m_strServiceName(pszPreNT5Instance), m_strDescription(pszDescription), m_eType(eType) { }
// ----------------------------------------------------------------------
//
// Function: AddToComponentList
//
// Purpose: Construct and add a CNetComponent to the specified list
//
// Arguments:
// pplComponents [in] pointer to list of
// pszPreNT5InfId [in] pre NT5 InfID (e.g. IEEPRO)
// pszPreNT5Instance [in] pre NT5 instance name (e.g. IEEPRO2)
// pszDescription [in] description
// eType [in] type (software / hardware)
//
// Returns: None
//
// Author: kumarp 17-December-97
//
// Notes:
//
void AddToComponentList(IN TPtrList* pplComponents, IN PCWSTR pszPreNT5InfId, IN PCWSTR pszPreNT5Instance, IN PCWSTR pszDescription, EComponentType eType) { AssertValidReadPtr(pplComponents); AssertValidReadPtr(pszPreNT5InfId); AssertValidReadPtr(pszPreNT5Instance); AssertValidReadPtr(pszDescription);
if (pplComponents) { CNetComponent* pnc; pnc = new CNetComponent(pszPreNT5InfId, pszPreNT5Instance, pszDescription, eType); if (pnc) { pplComponents->push_back(pnc); } } #ifdef ENABLETRACE
tstring strMessage;
GetUnsupportedMessageBool((eType == CT_Hardware), pszPreNT5InfId, pszDescription, &strMessage); TraceTag(ttidNetUpgrade, "%S", strMessage.c_str()); #endif
}
// ----------------------------------------------------------------------
//
// Function: AddToConflictsList
//
// Purpose: Construct and add a CNetComponent to the conflict list
//
// Arguments:
// pszPreNT5InfId [in] pre NT5 InfID (e.g. IEEPRO)
// pszPreNT5Instance [in] pre NT5 instance name (e.g. IEEPRO2)
// pszDescription [in] description
// eType [in] type (software / hardware)
//
// Returns: None
//
// Author: kumarp 17-December-97
//
// Notes:
//
void AddToConflictsList(IN PCWSTR pszPreNT5InfId, IN PCWSTR pszPreNT5Instance, IN PCWSTR pszDescription, EComponentType eType) { if (!g_pplNetComponents) { g_pplNetComponents = new TPtrList; }
AddToComponentList(g_pplNetComponents, pszPreNT5InfId, pszPreNT5Instance, pszDescription, eType); }
// ----------------------------------------------------------------------
//
// Function: HrGetAdapterParamsKeyFromInstance
//
// Purpose: Get handle of Parameters key using adapter instace key
//
// Arguments:
// hkeyAdapterInstance [in] handle of
// phkeyAdapterParams [out] pointer to handle of
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
// Notes:
//
HRESULT HrGetAdapterParamsKeyFromInstance(IN HKEY hkeyAdapterInstance, OUT HKEY* phkeyAdapterParams) { DefineFunctionName("HrGetAdapterParamsKeyFromInstance");
Assert(hkeyAdapterInstance); AssertValidWritePtr(phkeyAdapterParams);
HRESULT hr=S_OK; tstring strServiceName;
hr = HrRegQueryString(hkeyAdapterInstance, c_szRegValServiceName, &strServiceName); if (S_OK == hr) { hr = HrRegOpenServiceSubKey(strServiceName.c_str(), c_szParameters, KEY_READ, phkeyAdapterParams); }
TraceError(__FUNCNAME__, hr);
return hr; }
// ----------------------------------------------------------------------
//
// Function: HrGenerateHardwareConflictList
//
// Purpose: Detect upgrade conflicts for h/w components
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
// Notes:
//
HRESULT HrGenerateHardwareConflictList() { DefineFunctionName("HrGenerateHardwareConflictList");
HKEY hkeyAdapters; HKEY hkeyAdapter; DWORD dwHidden; tstring strAdapterDescription; tstring strPreNT5InfId; tstring strServiceName; tstring strNT5InfId; tstring strAdapterType; BOOL fIsOemAdapter; BOOL fRealNetCard = FALSE;
HRESULT hr=S_OK;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyAdapterHome, KEY_READ, &hkeyAdapters); if (S_OK == hr) { WCHAR szBuf[MAX_PATH]; FILETIME time; DWORD dwSize = celems(szBuf); DWORD dwRegIndex = 0;
while(S_OK == (hr = HrRegEnumKeyEx(hkeyAdapters, dwRegIndex++, szBuf, &dwSize, NULL, NULL, &time))) { dwSize = celems(szBuf); Assert(*szBuf);
hr = HrRegOpenKeyEx(hkeyAdapters, szBuf, KEY_READ, &hkeyAdapter); if (hr == S_OK) { hr = HrRegQueryDword(hkeyAdapter, c_szHidden, &dwHidden);
// for REAL netcards, "Hidden" is absent or if present the value is 0
if (S_OK == hr) { fRealNetCard = (dwHidden == 0); } else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { fRealNetCard = TRUE; hr = S_OK; }
if ((S_OK == hr) && fRealNetCard) {
hr = HrGetPreNT5InfIdAndDesc(hkeyAdapter, &strPreNT5InfId, &strAdapterDescription, & strServiceName); if (S_OK == hr) { HKEY hkeyAdapterParams; hr = HrGetAdapterParamsKeyFromInstance(hkeyAdapter, &hkeyAdapterParams); if (S_OK == hr) { hr = HrMapPreNT5NetCardInfIdToNT5InfId(hkeyAdapterParams, strPreNT5InfId.c_str(), &strNT5InfId, &strAdapterType, &fIsOemAdapter, NULL); if (S_FALSE == hr) { AddToConflictsList(strPreNT5InfId.c_str(), strServiceName.c_str(), strAdapterDescription.c_str(), CT_Hardware); } } RegCloseKey(hkeyAdapterParams); } } RegCloseKey(hkeyAdapter); } } if ((HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr) || (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)) { hr = S_OK; }
RegCloseKey(hkeyAdapters); }
TraceError(__FUNCNAME__, hr);
return hr; }
// ----------------------------------------------------------------------
//
// Function: ShouldIgnoreComponentForInstall
//
// Purpose: Determine if a components should be ignored when
// we are checking to see for obsolesence
//
// Arguments:
// pszComponentName [in] name of component
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: deonb 22-September-2000
//
BOOL ShouldIgnoreComponentForInstall ( IN PCWSTR pszComponentName) { BOOL fRet=FALSE;
if ( // We ignore NETBEUI since it's checked by DOSNET.INF already (NTBUG9: 181798)
(lstrcmpiW(pszComponentName, sz_NBF) == 0) ||
// We ignore DLC since it's checked by HrGenerateNT5ConflictList (NTBUG9: 187135)
(lstrcmpiW(pszComponentName, sz_DLC) == 0) ) { fRet = TRUE; } else { fRet = FALSE; }
return fRet; }
// ----------------------------------------------------------------------
//
// Function: HrGenerateSoftwareConflictListForProvider
//
// Purpose: Detect upgrade conflicts for s/w components of a provider
//
// Arguments:
// pszSoftwareProvider [in] name of software provider (e.g. Microsoft)
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
// Notes:
//
HRESULT HrGenerateSoftwareConflictListForProvider(IN PCWSTR pszSoftwareProvider) { DefineFunctionName("HrGenerateSoftwareConflictList");
HRESULT hr=S_OK; HKEY hkeyProvider; HKEY hkeyProductCurrentVersion;
tstring strProvider; strProvider = c_szRegKeySoftware; AppendToPath(&strProvider, pszSoftwareProvider);
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, strProvider.c_str(), KEY_READ, &hkeyProvider); if (S_OK == hr) { tstring strPreNT5InfId; tstring strNT5InfId; tstring strProductCurrentVersion; tstring strDescription; tstring strServiceName; tstring strSoftwareType; WCHAR szBuf[MAX_PATH]; FILETIME time; DWORD dwSize = celems(szBuf); DWORD dwRegIndex = 0; BOOL fIsOemComponent;
while(S_OK == (hr = HrRegEnumKeyEx(hkeyProvider, dwRegIndex++, szBuf, &dwSize, NULL, NULL, &time))) { dwSize = celems(szBuf); Assert(*szBuf);
if (!ShouldIgnoreComponentForInstall(szBuf)) { strProductCurrentVersion = szBuf; AppendToPath(&strProductCurrentVersion, c_szRegKeyCurrentVersion);
// Look for Component\CurrentVersion
hr = HrRegOpenKeyEx(hkeyProvider, strProductCurrentVersion.c_str(), KEY_READ, &hkeyProductCurrentVersion); if (hr == S_OK) { // Under Component\CurrentVersion, look for "SoftwareType" value
hr = HrRegQueryString(hkeyProductCurrentVersion, c_szRegValSoftwareType, &strSoftwareType); if (!lstrcmpiW(strSoftwareType.c_str(), c_szSoftwareTypeDriver)) { // ignore components of type "driver"
hr = S_OK; } else { hr = HrGetPreNT5InfIdAndDesc(hkeyProductCurrentVersion, &strPreNT5InfId, &strDescription, &strServiceName);
if (S_OK == hr) { hr = HrMapPreNT5NetComponentInfIDToNT5InfID( strPreNT5InfId.c_str(), &strNT5InfId, &fIsOemComponent, NULL, NULL);
if (S_FALSE == hr) { AddToConflictsList(strPreNT5InfId.c_str(), strServiceName.c_str(), strDescription.c_str(), CT_Software); } } RegCloseKey(hkeyProductCurrentVersion); } } } } if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr) { hr = S_OK; }
RegCloseKey(hkeyProvider); }
TraceError(__FUNCNAME__, hr);
return hr; }
// ----------------------------------------------------------------------
//
// Function: HrGenerateSoftwareConflictList
//
// Purpose: Detect upgrade conflicts for s/w components of all providers
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
// Notes:
//
HRESULT HrGenerateSoftwareConflictList() { DefineFunctionName("HrGenerateSoftwareConflictList");
HRESULT hr=S_OK; HKEY hkeySoftware;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeySoftware, KEY_READ, &hkeySoftware); if (S_OK == hr) { WCHAR szBuf[MAX_PATH]; FILETIME time; DWORD dwSize = celems(szBuf); DWORD dwRegIndex = 0;
while(S_OK == (hr = HrRegEnumKeyEx(hkeySoftware, dwRegIndex++, szBuf, &dwSize, NULL, NULL, &time))) { dwSize = celems(szBuf); Assert(*szBuf);
hr = HrGenerateSoftwareConflictListForProvider(szBuf); } if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr) { hr = S_OK; }
RegCloseKey(hkeySoftware); }
TraceError(__FUNCNAME__, hr);
return hr; }
// ----------------------------------------------------------------------
//
// Function: HrGenerateNT5ConflictList
//
// Purpose: Detect upgrade conflicts from Windows 2000
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: deonb 20-September 2000
//
// Notes:
//
HRESULT HrGenerateNT5ConflictList() { HRESULT hr = S_OK; tstring strDescription; BOOL fInstalled;
if ( ShouldRemoveDLC(&strDescription, &fInstalled) ) { // Add to conflict list only if DLC is installed, otherwise user will see
// a warning message even if it is uninstalled.
//
if ( fInstalled ) { if (strDescription.empty()) { // Couldn't find a description from previous O/S. Oh well - just use "DLC".
AddToConflictsList(sz_DLC, sz_DLC, sz_DLC, CT_Software); } else { AddToConflictsList(sz_DLC, sz_DLC, strDescription.c_str(), CT_Software); } } } return hr; }
// ----------------------------------------------------------------------
//
// Function: ShouldRemoveDLC
//
// Purpose: Determine if DLC should be removed during the upgrade irrespective of whether
// it is currently installed or not.
//
// Arguments:
// strDLCDesc [out] pointer to DLC Description string.
// pfInstalled [out] pointer to a boolean indicating if DLC is currently installed.
// Valid for X86 only.
//
// Returns: TRUE if DLC should be removed.
//
// Author: asinha 3/27/2001
//
// Notes:
//
BOOL ShouldRemoveDLC (tstring *strDLCDesc, BOOL *pfInstalled) { HRESULT hr; BOOL fDlcRemove = FALSE;
if ( pfInstalled ) { *pfInstalled = FALSE; }
// Check if DLC is installed (only for x86 - for IA64 we don't care (NTBUG9:186001) )
#ifdef _X86_
CServiceManager sm; CService srv;
if ( pfInstalled ) {
hr = sm.HrOpenService(&srv, sz_DLC);
if (SUCCEEDED(hr)) // DLC Service is installed
{ *pfInstalled = TRUE;
LPQUERY_SERVICE_CONFIG pConfig; HRESULT hr = srv.HrQueryServiceConfig (&pConfig);
if (S_OK == hr) { if ( strDLCDesc ) { *strDLCDesc = pConfig->lpDisplayName; }
MemFree (pConfig); }
srv.Close(); } else { *pfInstalled = FALSE; } }
fDlcRemove = TRUE;
OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
// If SNA Server is installed (on NT5) - this is ok
if (GetVersionEx(&osvi)) // Can't use VerifyVersionInfo - we have to run on NT4.
{ if ( (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0) ) { // If SNA Server is installed - we still allow this
hr = sm.HrOpenService(&srv, L"SnaServr");
if (SUCCEEDED(hr)) // Service is installed
{ srv.Close();
// Only if SNA version is 5.0 or more.
HKEY hkeySnaServer; hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, sz_SNAServerKey, KEY_READ, &hkeySnaServer); if (S_OK == hr) { tstring tstr; hr = HrRegQueryString(hkeySnaServer, sz_SNAServerVersion, &tstr); if (S_OK == hr) { int nSnaVersion = _wtoi(tstr.c_str()); if (nSnaVersion >= 5) { fDlcRemove = FALSE; } } RegCloseKey(hkeySnaServer); } } }
// Never complain about DLC if upgrading from Whistler+
if ( (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) && ( ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ) || (osvi.dwMajorVersion >= 6) ) ) { fDlcRemove = FALSE; } } #endif
return fDlcRemove; }
// ----------------------------------------------------------------------
//
// Function: HrGenerateConflictList
//
// Purpose: Generate upgrade conflict list for s/w and h/w components
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
// Notes:
//
HRESULT HrGenerateConflictList(OUT UINT* pcNumConflicts) { DefineFunctionName("HrGenerateConflictList");
HRESULT hr=S_OK;
(void) HrGenerateHardwareConflictList(); (void) HrGenerateSoftwareConflictList(); (void) HrGenerateNT5ConflictList();
if (g_pplNetComponents && g_pplNetComponents->size()) { *pcNumConflicts = g_pplNetComponents->size(); } else { *pcNumConflicts = 0; }
TraceError(__FUNCNAME__, hr);
return hr; }
// ----------------------------------------------------------------------
//
// Function: UninitConflictList
//
// Purpose: Uninitialize and destroy global lists holding upgrade conflicts
//
// Arguments: None
//
// Returns: None
//
// Author: kumarp 17-December-97
//
// Notes:
//
void UninitConflictList() { if (g_pplNetComponents) { CNetComponent* pnc; TPtrListIter pos;
for (pos = g_pplNetComponents->begin(); pos != g_pplNetComponents->end(); pos++) { pnc = (CNetComponent*) *pos; delete pnc; } g_pplNetComponents->erase(g_pplNetComponents->begin(), g_pplNetComponents->end()); delete g_pplNetComponents; g_pplNetComponents = NULL; } }
// ----------------------------------------------------------------------
//
// Function: HrResolveConflictsFromList
//
// Purpose: Use the specified netmap.inf file to find out if any
// of the components currently detected as unsupported can
// be mapped. If such components are found, then delete them
// from pplComponents if fDeleteResolvedItemsFromList is TRUE
//
// Arguments:
// fDeleteResolvedItemsFromList [in] flag (see above)
// pplComponents [in] pointer to list of unsupported components
// hinfNetMap [in] handle of netmap.inf file
// pdwNumConflictsResolved [out] number of components mapped using the
// specified netmap.inf
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
// Notes:
//
HRESULT HrResolveConflictsFromList(IN BOOL fDeleteResolvedItemsFromList, IN TPtrList* pplComponents, IN HINF hinfNetMap, OUT DWORD* pdwNumConflictsResolved, OUT BOOL* pfHasUpgradeHelpInfo) { DefineFunctionName("HrResolveConflictsFromList");
Assert(hinfNetMap); AssertValidWritePtr(pdwNumConflictsResolved);
HRESULT hr=S_OK;
*pdwNumConflictsResolved = 0;
if (pplComponents && (pplComponents->size() > 0)) { TPtrListIter pos; TPtrListIter tpos; tstring strPreNT5InfId; CNetComponent* pnc; HKEY hkeyAdapterParams; BOOL fIsOemComponent; tstring strNT5InfId;
pos = pplComponents->begin();
while(pos != pplComponents->end()) { pnc = (CNetComponent*) *pos; strNT5InfId = c_szEmpty;
if (pnc->m_eType == CT_Hardware) { hr = HrRegOpenServiceSubKey(pnc->m_strServiceName.c_str(), c_szParameters, KEY_READ, &hkeyAdapterParams); if (S_OK == hr) { fIsOemComponent = FALSE; hr = HrMapPreNT5NetCardInfIdInInf(hinfNetMap, hkeyAdapterParams, pnc->m_strPreNT5InfId.c_str(), &strNT5InfId, NULL, &fIsOemComponent); RegCloseKey(hkeyAdapterParams); } } else { hr = HrMapPreNT5NetComponentInfIDInInf(hinfNetMap, pnc->m_strPreNT5InfId.c_str(), &strNT5InfId, NULL, &fIsOemComponent); if ((S_FALSE == hr) && !strNT5InfId.empty()) { *pfHasUpgradeHelpInfo = TRUE; } } tpos = pos; pos++; // if we found a map, remove the entry
if (S_OK == hr) { (*pdwNumConflictsResolved)++; if (fDeleteResolvedItemsFromList) { delete pnc; pplComponents->erase(tpos); } } } } else { hr = S_FALSE; }
TraceErrorOptional(__FUNCNAME__, hr, (S_FALSE == hr));
return hr; }
// ----------------------------------------------------------------------
//
// Function: HrUpdateConflictList
//
// Purpose: Use the specified netmap.inf file to find out if any
// of the components currently detected as unsupported can
// be mapped. If such components are found, then delete them
// from pplComponents if fDeleteResolvedItemsFromList is TRUE
//
// Arguments:
// fDeleteResolvedItemsFromList [in] flag (see above)
// hinfNetMap [in] handle of netmap.inf file
// pdwNumConflictsResolved [out] number of components mapped using the
// specified netmap.inf
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
// Notes:
//
HRESULT HrUpdateConflictList(IN BOOL fDeleteResolvedItemsFromList, IN HINF hinfNetMap, OUT DWORD* pdwNumConflictsResolved, OUT BOOL* pfHasUpgradeHelpInfo) { DefineFunctionName("HrUpdateConflictList");
HRESULT hr=S_OK;
hr = HrResolveConflictsFromList(fDeleteResolvedItemsFromList, g_pplNetComponents, hinfNetMap, pdwNumConflictsResolved, pfHasUpgradeHelpInfo);
TraceErrorOptional(__FUNCNAME__, hr, (S_FALSE == hr));
return hr; }
HRESULT HrGetConflictsList(OUT TPtrList** ppplNetComponents) { HRESULT hr=S_FALSE;
if (g_pplNetComponents) { hr = S_OK; *ppplNetComponents = g_pplNetComponents; }
return hr; }
|