//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997. // // File: O E M U P G . C P P // // Contents: Down level upgrade code for OEM cards // // Notes: // // Author: kumarp 12 April 97 // //---------------------------------------------------------------------------- #include "pch.h" #pragma hdrstop #include "conflict.h" #include "infmap.h" #include "kkcwinf.h" #include "kkutils.h" #include "nceh.h" #include "ncsetup.h" #include "netupgrd.h" #include "nustrs.h" #include "nuutils.h" #include "oemupg.h" #include "oemupgex.h" #include "resource.h" static const WCHAR c_szOemNMapFileName[] = L"netmap.inf"; TNetMapArray* g_pnmaNetMap=NULL; #if 0 extern BOOL g_fForceNovellDirCopy; #endif //---------------------------------------------------------------------------- // prototypes // void AbortUpgradeOemComponent(IN PCWSTR pszPreNT5InfId, IN PCWSTR pszDescription, IN DWORD dwError, IN DWORD dwErrorMessageId); //---------------------------------------------------------------------------- // ---------------------------------------------------------------------- // // Function: CNetMapInfo::CNetMapInfo // // Purpose: constructor for class CNetMapInfo // // Arguments: None // // Returns: // // Author: kumarp 17-December-97 // // Notes: // CNetMapInfo::CNetMapInfo() { m_hinfNetMap = NULL; m_hOemDll = NULL; m_dwFlags = 0; m_nud.mszServicesNotToBeDeleted = NULL; m_pfnPreUpgradeInitialize = NULL; m_pfnDoPreUpgradeProcessing = NULL; m_fDllInitFailed = FALSE; } // ---------------------------------------------------------------------- // // Function: CNetMapInfo::~CNetMapInfo // // Purpose: destructor for class CNetMapInfo // // Arguments: None // // Returns: None // // Author: kumarp 17-December-97 // // Notes: // CNetMapInfo::~CNetMapInfo() { if (m_hinfNetMap) { ::SetupCloseInfFile(m_hinfNetMap); } if (m_hOemDll) { ::FreeLibrary(m_hOemDll); } } // ---------------------------------------------------------------------- // // Function: CNetMapInfo::HrGetOemInfName // // Purpose: Get name of installation INF of a component // // Arguments: // pszNT5InfId [in] NT5 InfID of a component // pstrOemInf [out] pointer to name of INF for this component // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 26-May-98 // // Notes: // HRESULT CNetMapInfo::HrGetOemInfName(IN PCWSTR pszNT5InfId, OUT tstring* pstrOemInf) { DefineFunctionName("CNetMapInfo::HrGetOemInfName"); AssertValidReadPtr(pszNT5InfId); AssertValidWritePtr(pstrOemInf); HRESULT hr=S_OK; tstring strOemDll; Assert(m_hinfNetMap); hr = HrGetOemUpgradeInfoInInf(m_hinfNetMap, pszNT5InfId, &strOemDll, pstrOemInf); TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrOpenNetUpgInfFile // // Purpose: Open netupg.inf file. // - if env var NETUPGRD_INIT_FILE_DIR is set, open it from that dir // - otherwise open it from the dir where netuprd.dll is located // // Arguments: // phinf [out] handle of netupg.inf file // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrOpenNetUpgInfFile(OUT HINF* phinf) { DefineFunctionName("HrOpenNetUpgInfFile"); AssertValidWritePtr(phinf); static const WCHAR c_szNetUpgInfFile[] = L"netupg.inf"; static const WCHAR c_szNetUpgrdInitDir[] = L"NETUPGRD_INIT_FILE_DIR"; HRESULT hr=S_OK; tstring strNetUpgInfFile; // first try opening from N WCHAR szNetUpgrdInitDir[MAX_PATH+1]; DWORD dwNumCharsReturned; dwNumCharsReturned = GetEnvironmentVariable(c_szNetUpgrdInitDir, szNetUpgrdInitDir, MAX_PATH); if (dwNumCharsReturned) { strNetUpgInfFile = szNetUpgrdInitDir; } else { hr = HrGetNetupgrdDir(&strNetUpgInfFile); } if (S_OK == hr) { AppendToPath(&strNetUpgInfFile, c_szNetUpgInfFile); hr = HrSetupOpenInfFile(strNetUpgInfFile.c_str(), NULL, INF_STYLE_WIN4, NULL, phinf); } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrGetOemDirs // // Purpose: Get list of OEM dirs from netupg.inf file // // Arguments: // pslOemDirs [out] pointer to list of OEM dirs // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrGetOemDirs(OUT TStringList* pslOemDirs) { DefineFunctionName("HrGetOemDirs"); TraceFunctionEntry(ttidNetUpgrade); AssertValidReadPtr(pslOemDirs); HRESULT hr=S_OK; static const WCHAR c_szOemDirsSection[] = L"OemNetUpgradeDirs"; HINF hInf; INFCONTEXT ic; tstring strNetUpgrdDir; tstring strDirFullPath; hr = HrGetNetupgrdDir(&strNetUpgrdDir); if (S_OK == hr) { hr = HrOpenNetUpgInfFile(&hInf); } if (S_OK == hr) { tstring strOemDir; hr = HrSetupFindFirstLine(hInf, c_szOemDirsSection, NULL, &ic); if (S_OK == hr) { do { hr = HrSetupGetLineText(&ic, hInf, NULL, NULL, &strOemDir); if (S_OK == hr) { TraceTag(ttidNetUpgrade, "%s: locating '%S'...", __FUNCNAME__, strOemDir.c_str()); hr = HrDirectoryExists(strOemDir.c_str()); if (S_OK == hr) { strDirFullPath = strOemDir; } else if (S_FALSE == hr) { // this may be a dir. relative to winntupg dir // strDirFullPath = strNetUpgrdDir; AppendToPath(&strDirFullPath, strOemDir.c_str()); hr = HrDirectoryExists(strDirFullPath.c_str()); } if (S_OK == hr) { pslOemDirs->push_back(new tstring(strDirFullPath)); TraceTag(ttidNetUpgrade, "%s: ...found OEM dir: %S", __FUNCNAME__, strDirFullPath.c_str()); } else if (S_FALSE == hr) { TraceTag(ttidNetUpgrade, "%s: ...could not locate '%S'", __FUNCNAME__, strOemDir.c_str()); } if (SUCCEEDED(hr)) { hr = HrSetupFindNextLine(ic, &ic); } } } while (S_OK == hr); if (S_FALSE == hr) { hr = S_OK; } } if (HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND) == hr) { hr = S_OK; } ::SetupCloseInfFile(hInf); } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrOpenOemNMapFile // // Purpose: Open netmap.inf file from the specified dir. // // Arguments: // pszOemDir [in] name of dir. // phinf [out] pointer to handle of netmap.inf file opened // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrOpenOemNMapFile(IN PCWSTR pszOemDir, OUT HINF* phinf) { DefineFunctionName("HrOpenOemNMapFile"); HRESULT hr=S_OK; *phinf = NULL; tstring strOemNMapFile; strOemNMapFile = pszOemDir; AppendToPath(&strOemNMapFile, c_szOemNMapFileName); hr = HrSetupOpenInfFile(strOemNMapFile.c_str(), NULL, INF_STYLE_WIN4, NULL, phinf); TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrAddToNetMapInfo // // Purpose: Add the specified netmap.inf file to the set of netmap.inf files // // Arguments: // pnma [in] array of CNetMapInfo objects // hinf [in] handle of netmap.inf file to add // pszOemDir [in] location of the above file // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrAddToNetMapInfo(IN TNetMapArray* pnma, IN HINF hinf, IN PCWSTR pszOemDir) { DefineFunctionName("HrAddToNetMapInfo"); AssertValidReadPtr(pnma); Assert(hinf); AssertValidReadPtr(pszOemDir); HRESULT hr=E_OUTOFMEMORY; CNetMapInfo* pnmi; pnmi = new CNetMapInfo; if (pnmi) { hr = S_OK; pnmi->m_hinfNetMap = hinf; pnmi->m_strOemDir = pszOemDir; pnma->push_back(pnmi); } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrOpenNetMapAndAddToNetMapInfo // // Purpose: Open and add netmap.inf file in the specified dir. // to the set of netmap.inf files // // Arguments: // pnma [in] array of CNetMapInfo objects // pszOemDir [in] location of netmap.inf file // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrOpenNetMapAndAddToNetMapInfo(IN TNetMapArray* pnma, IN PCWSTR pszOemDir) { DefineFunctionName("HrOpenNetMapAndAddToNetMapInfo"); AssertValidReadPtr(pnma); AssertValidReadPtr(pszOemDir); HRESULT hr = S_OK; HINF hinf; hr = HrOpenOemNMapFile(pszOemDir, &hinf); if (S_OK == hr) { hr = HrAddToNetMapInfo(pnma, hinf, pszOemDir); } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrAddToGlobalNetMapInfo // // Purpose: Add the specified netmap.inf file to the set of netmap.inf files // // Arguments: // hinf [in] handle of netmap.inf file to add // pszOemDir [in] location of the above file // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrAddToGlobalNetMapInfo(IN HINF hinf, IN PCWSTR pszOemDir) { DefineFunctionName("HrAddToGlobalNetMapInfo"); AssertValidReadPtr(g_pnmaNetMap); Assert(hinf); AssertValidReadPtr(pszOemDir); HRESULT hr=E_OUTOFMEMORY; hr = HrAddToNetMapInfo(g_pnmaNetMap, hinf, pszOemDir); TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrInitNetMapInfo // // Purpose: Initialize array of CNetMapInfo objects // // Arguments: None // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrInitNetMapInfo() { DefineFunctionName("HrInitNetMapInfo"); HRESULT hr=E_FAIL; tstring strNetupgrdDir; g_pnmaNetMap = new TNetMapArray; if (!g_pnmaNetMap) { hr = E_OUTOFMEMORY; } else { hr = HrGetNetupgrdDir(&strNetupgrdDir); if (S_OK == hr) { TraceTag(ttidNetUpgrade, "%s: initializing netmap info from '%S'", __FUNCNAME__, strNetupgrdDir.c_str()); hr = HrOpenNetMapAndAddToNetMapInfo(g_pnmaNetMap, strNetupgrdDir.c_str()); } } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: UnInitNetMapInfo // // Purpose: Uninitialize the array of CNetMapInfo objects // // Arguments: None // // Returns: None // // Author: kumarp 17-December-97 // // Notes: // void UnInitNetMapInfo() { DefineFunctionName("UnInitNetMapInfo"); if (g_pnmaNetMap) { CNetMapInfo* pnmi; size_t cNumNetMapEntries = g_pnmaNetMap->size(); for (size_t i = 0; i < cNumNetMapEntries; i++) { pnmi = (CNetMapInfo*) (*g_pnmaNetMap)[i]; delete pnmi; } g_pnmaNetMap->erase(g_pnmaNetMap->begin(), g_pnmaNetMap->end()); delete g_pnmaNetMap; g_pnmaNetMap = NULL; } } // ---------------------------------------------------------------------- // // Function: HrInitAndProcessOemDirs // // Purpose: Initialize and process each OEM dir specified in netupg.inf file // // Arguments: None // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrInitAndProcessOemDirs() { DefineFunctionName("HrInitAndProcessOemDirs"); TraceFunctionEntry(ttidNetUpgrade); HRESULT hr=S_OK; TStringList slOemDirs; hr = HrGetOemDirs(&slOemDirs); if (S_OK == hr) { PCWSTR pszOemDir; HINF hinf; TStringListIter pos; for (pos=slOemDirs.begin(); pos != slOemDirs.end(); pos++) { pszOemDir = (*pos)->c_str(); TraceTag(ttidNetUpgrade, "%s: initializing NetMapInfo for: %S", __FUNCNAME__, pszOemDir); hr = HrProcessAndCopyOemFiles(pszOemDir, FALSE); if (FAILED(hr)) { break; } } } if (S_FALSE == hr) { hr = S_OK; } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrGetNetUpgradeTempDir // // Purpose: Return name of temp. dir to use, creating one if necessary // // Arguments: // pstrTempDir [out] pointer to // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrGetNetUpgradeTempDir(OUT tstring* pstrTempDir) { DefineFunctionName("HrGetNetUpgradeTempDir"); HRESULT hr=E_FAIL; tstring strNetUpgradeTempDir; hr = HrGetWindowsDir(&strNetUpgradeTempDir); if (S_OK == hr) { static const WCHAR c_szNetupgrdSubDir[] = L"\\netsetup\\"; strNetUpgradeTempDir += c_szNetupgrdSubDir; if (!CreateDirectory(strNetUpgradeTempDir.c_str(), NULL)) { hr = HrFromLastWin32Error(); if (HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) == hr) { hr = S_OK; } } if (S_OK == hr) { *pstrTempDir = strNetUpgradeTempDir; } } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrCreateOemTempDir // // Purpose: Create a temp. dir with unique name // // Arguments: // pstrOemTempDir [out] name of dir created // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrCreateOemTempDir(OUT tstring* pstrOemTempDir) { DefineFunctionName("HrCreateOemTempDir"); HRESULT hr=S_OK; static DWORD dwOemDirCount=0; WCHAR szOemDirPath[MAX_PATH]; hr = HrGetNetUpgradeTempDir(pstrOemTempDir); if (S_OK == hr) { DWORD dwRetryCount=0; const DWORD c_dwMaxRetryCount=1000; DWORD err=NO_ERROR; DWORD status; do { swprintf(szOemDirPath, L"%soem%05ld", pstrOemTempDir->c_str(), dwOemDirCount++); TraceTag(ttidNetUpgrade, "%s: trying to create %S", __FUNCNAME__, szOemDirPath); status = CreateDirectory(szOemDirPath, NULL); if (status) { *pstrOemTempDir = szOemDirPath; } else { err = GetLastError(); } } while (!status && (ERROR_ALREADY_EXISTS == err) && (dwRetryCount++ < c_dwMaxRetryCount)); if (!status) { hr = HrFromLastWin32Error(); } } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrLoadAndVerifyOemDll // // Purpose: Load and check for correct exported fns in the specified OEM DLL // // Arguments: // CNetMapInfo [in] // i [in] pointer to // // Returns: S_OK on success, // S_FALSE if DLL init had failed last time when we tried // otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrLoadAndVerifyOemDll(IN OUT CNetMapInfo* pnmi) { DefineFunctionName("HrLoadAndVerifyOemDll"); HRESULT hr=S_OK; Assert(!pnmi->m_hOemDll); Assert(pnmi->m_strOemDllName.size() > 0); Assert(pnmi->m_strOemDir.size() > 0); if (pnmi->m_fDllInitFailed) { hr = S_FALSE; } else if (!pnmi->m_hOemDll) { TraceTag(ttidNetUpgrade, "%s: loading OEM DLL: %S%S", __FUNCNAME__, pnmi->m_strOemDir.c_str(), pnmi->m_strOemDllName.c_str()); tstring strOemDllFullPath; strOemDllFullPath = pnmi->m_strOemDir; AppendToPath(&strOemDllFullPath, pnmi->m_strOemDllName.c_str()); hr = HrLoadLibAndGetProcsV(strOemDllFullPath.c_str(), &pnmi->m_hOemDll, c_szPreUpgradeInitialize, (FARPROC*) &pnmi->m_pfnPreUpgradeInitialize, c_szDoPreUpgradeProcessing, (FARPROC*) &pnmi->m_pfnDoPreUpgradeProcessing, NULL); if (FAILED(hr)) { pnmi->m_hOemDll = NULL; pnmi->m_pfnPreUpgradeInitialize = NULL; pnmi->m_pfnDoPreUpgradeProcessing = NULL; pnmi->m_fDllInitFailed = TRUE; } } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrLoadAndInitOemDll // // Purpose: Load the specified OEM DLL and call its // PreUpgradeInitialize function // // Arguments: // pnmi [in] pointer to CNetMapInfo object // pNetUpgradeInfo [in] pointer to NetUpgradeInfo // // Returns: S_OK on success // S_FALSE if DLL init had failed last time when we tried // otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrLoadAndInitOemDll(IN CNetMapInfo* pnmi, IN NetUpgradeInfo* pNetUpgradeInfo) { DefineFunctionName("HrLoadAndInitOemDll"); HRESULT hr=S_OK; DWORD dwError=ERROR_SUCCESS; VENDORINFO vi; hr = HrLoadAndVerifyOemDll(pnmi); if (S_OK == hr) { if (pnmi->m_pfnPreUpgradeInitialize) { NC_TRY { TraceTag(ttidNetUpgrade, "%s: initializing OEM DLL: %S in %S", __FUNCNAME__, pnmi->m_strOemDllName.c_str(), pnmi->m_strOemDir.c_str()); dwError = pnmi->m_pfnPreUpgradeInitialize(pnmi->m_strOemDir.c_str(), pNetUpgradeInfo, &vi, &pnmi->m_dwFlags, &pnmi->m_nud); #ifdef ENABLETRACE if (pnmi->m_nud.mszServicesNotToBeDeleted) { TraceMultiSz(ttidNetUpgrade, L"OEM services that will not be deleted", pnmi->m_nud.mszServicesNotToBeDeleted); } #endif // ensure that this function gets called only once // pnmi->m_pfnPreUpgradeInitialize = NULL; hr = HRESULT_FROM_WIN32(dwError); if (pnmi->m_dwFlags & NUA_REQUEST_ABORT_UPGRADE) { TraceTag(ttidNetUpgrade, "%s: OEM DLL '%S' requested that upgrade be aborted", __FUNCNAME__, pnmi->m_strOemDllName.c_str()); RequestAbortUpgradeOboOemDll(pnmi->m_strOemDllName.c_str(), &vi); hr = S_FALSE; } else if (pnmi->m_dwFlags & NUA_ABORT_UPGRADE) { TraceTag(ttidNetUpgrade, "%s: OEM DLL '%S' aborted the upgrade", __FUNCNAME__, pnmi->m_strOemDllName.c_str()); AbortUpgradeFn(ERROR_SUCCESS, pnmi->m_strOemDllName.c_str()); hr = S_FALSE; } } NC_CATCH_ALL { TraceTag(ttidError, "%s: OEM DLL '%S' caused an exception", __FUNCNAME__, pnmi->m_strOemDllName.c_str()); hr = HRESULT_FROM_WIN32(ERROR_DLL_INIT_FAILED); } } } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrProcessOemComponent // // Purpose: Load an OEM DLL and call DoPreUpgradeProcessing // function for the specified component // // Arguments: // pnmi [in] pointer to CNetMapInfo object // pNetUpgradeInfo [in] pointer to NetUpgradeInfo // hwndParent [in] handle of parent window // hkeyParams [in] handle of Parameters registry key // pszPreNT5InfId [in] pre-NT5 InfID of a component (e.g. IEEPRO) // pszPreNT5Instance [in] pre-NT5 instance of a component (e.g. IEEPRO2) // pszNT5InfId [in] NT5 InfID of the component // pszDescription [in] description of the component // pszSectionName [in] name of section that the OEM DLL must use // for storing its upgrade parameters // pdwFlags [out] pointer to flags returned by OEM DLL // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrProcessOemComponent(CNetMapInfo* pnmi, IN NetUpgradeInfo* pNetUpgradeInfo, IN HWND hwndParent, IN HKEY hkeyParams, IN PCWSTR pszPreNT5InfId, IN PCWSTR pszPreNT5Instance, IN PCWSTR pszNT5InfId, IN PCWSTR pszDescription, IN PCWSTR pszSectionName, OUT DWORD* pdwFlags) { DefineFunctionName("HrProcessOemComponent"); AssertValidReadPtr(pnmi); AssertValidReadPtr(pNetUpgradeInfo); Assert(hkeyParams); AssertValidReadPtr(pszPreNT5InfId); AssertValidReadPtr(pszPreNT5Instance); AssertValidReadPtr(pszNT5InfId); AssertValidReadPtr(pszDescription); AssertValidReadPtr(pszSectionName); AssertValidWritePtr(pdwFlags); TraceTag(ttidNetUpgrade, "%s: Processing OEM component: %S(%S), instance: %S", __FUNCNAME__, pszNT5InfId, pszPreNT5InfId, pszPreNT5Instance); HRESULT hr=S_OK; VENDORINFO vi; DWORD dwErrorMessageId=0; if (pnmi->m_strOemDllName.empty()) { tstring strOemInf; hr = HrGetOemUpgradeInfoInInf(pnmi->m_hinfNetMap, pszNT5InfId, &pnmi->m_strOemDllName, &strOemInf); if (S_OK == hr) { hr = HrLoadAndInitOemDll(pnmi, pNetUpgradeInfo); if (FAILED(hr)) { dwErrorMessageId = IDS_E_LoadAndInitOemDll; } } else { dwErrorMessageId = IDS_E_GetOemUpgradeDllInfoInInf; } } if (S_OK == hr) { Assert(pnmi->m_pfnDoPreUpgradeProcessing); NC_TRY { TraceTag(ttidNetUpgrade, "%s: calling DoPreUpgradeProcessing in %S for %S", __FUNCNAME__, pnmi->m_strOemDllName.c_str(), pszNT5InfId); Assert(pnmi->m_pfnDoPreUpgradeProcessing); DWORD dwError = pnmi->m_pfnDoPreUpgradeProcessing(hwndParent, hkeyParams, pszPreNT5InfId, pszPreNT5Instance, pszNT5InfId, pszSectionName, &vi, pdwFlags, NULL); TraceTag(ttidNetUpgrade, "%s: DoPreUpgradeProcessing returned: 0x%x", __FUNCNAME__, dwError); hr = HRESULT_FROM_WIN32(dwError); if (S_OK == hr) { if (*pdwFlags & NUA_REQUEST_ABORT_UPGRADE) { RequestAbortUpgradeOboOemDll(pnmi->m_strOemDllName.c_str(), &vi); hr = S_FALSE; } } else { dwErrorMessageId = IDS_E_DoPreUpgradeProcessing; } } NC_CATCH_ALL { TraceTag(ttidError, "%s: OEM DLL '%S' caused an exception", __FUNCNAME__, pnmi->m_strOemDllName.c_str()); hr = HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED); dwErrorMessageId = IDS_E_OemDllCausedAnException; } } else if (S_FALSE == hr) { TraceTag(ttidNetUpgrade, "%s: DoPreUpgradeProcessing was not called" " since DLL init had failed", __FUNCNAME__); } if (FAILED(hr)) { AbortUpgradeOemComponent(pszPreNT5InfId, pszDescription, DwWin32ErrorFromHr(hr), dwErrorMessageId); } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrShowUiAndGetOemFileLocation // // Purpose: Display UI asking the user to specify location of OEM files // // Arguments: // hwndParent [in] handle of parent window // pszComponentName [in] name of Component // pstrOemPath [out] name of netmap.inf file the user selected // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrShowUiAndGetOemFileLocation( IN HWND hwndParent, IN PCWSTR pszComponentName, OUT tstring* pstrOemPath) { DefineFunctionName("HrShowUiAndGetOemFileLocation"); AssertValidWritePtr(pstrOemPath); OPENFILENAME ofn; WCHAR szOemPath[MAX_PATH+1]; PWSTR pszTitle; PCWSTR pszOemQueryFileLocationFormatString = SzLoadString(g_hinst, IDS_OemQueryFileLocation); PCWSTR pszOemFileTypeFilter1 = SzLoadString(g_hinst, IDS_OemNetMapFileFilter1); PCWSTR pszOemFileTypeFilter2 = SzLoadString(g_hinst, IDS_OemNetMapFileFilter2); PWSTR mszFileFilter = NULL; HRESULT hr = S_OK; BOOL f; hr = HrAddSzToMultiSz(pszOemFileTypeFilter1, NULL, STRING_FLAG_ENSURE_AT_END, 0, &mszFileFilter, &f); if (S_OK != hr) { goto cleanup; } hr = HrAddSzToMultiSz(pszOemFileTypeFilter2, mszFileFilter, STRING_FLAG_ENSURE_AT_END, 0, &mszFileFilter, &f); if (S_OK != hr) { goto cleanup; } ZeroMemory (&ofn, sizeof(ofn)); *szOemPath = 0; DwFormatStringWithLocalAlloc ( pszOemQueryFileLocationFormatString, &pszTitle, pszComponentName); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hwndParent; ofn.lpstrFilter = mszFileFilter; ofn.lpstrFile = szOemPath; ofn.nMaxFile = MAX_PATH; ofn.lpstrTitle = pszTitle; ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_NODEREFERENCELINKS; if (GetOpenFileName(&ofn)) { // get rid of the trailing filename. // szOemPath[ofn.nFileOffset] = 0; *pstrOemPath = szOemPath; hr = S_OK; } else { DWORD err; err = CommDlgExtendedError(); if (err) { hr = E_FAIL; TraceTag(ttidError, "%s: FileOpen dialog returned error: %ld (0x%lx)", __FUNCNAME__, err, err); } else { hr = S_FALSE; TraceTag(ttidError, "%s: FileOpen dialog was canceled by user", __FUNCNAME__); } } LocalFree (pszTitle); cleanup: MemFree(mszFileFilter); TraceErrorOptional(__FUNCNAME__, hr, (hr == S_FALSE)); return hr; } // ---------------------------------------------------------------------- // // Function: HrProcessAndCopyOemFiles // // Purpose: Copy OEM files from the specified dir to OEM temp. dir. // // Arguments: // pszOemDir [in] location of OEM files // fInteractive [in] TRUE --> called when a user has interactively // supplied a disk having OEM files, FALSE otherwise // // Returns: S_OK on success, // S_FALSE if the OEM files are valid but not applicable for // currently displayed unsupported components, // otherwise an error code // // Author: kumarp 17-December-97 // // Notes: // HRESULT HrProcessAndCopyOemFiles(IN PCWSTR pszOemDir, IN BOOL fInteractive) { DefineFunctionName("HrProcessAndCopyOemFiles"); HRESULT hr=S_OK; HINF hinf=NULL; tstring strTempOemDir; DWORD dwErrorMessageId; TraceTag(ttidNetUpgrade, "%s: processing OEM files in: %S", __FUNCNAME__, pszOemDir); hr = HrOpenOemNMapFile(pszOemDir, &hinf); if (S_OK == hr) { DWORD dwNumConflictsResolved=0; BOOL fHasUpgradeHelpInfo=FALSE; hr = HrUpdateConflictList(FALSE, hinf, &dwNumConflictsResolved, &fHasUpgradeHelpInfo); #if 0 BOOL fNovell = (g_fForceNovellDirCopy && wcsstr(pszOemDir, L"oem\\novell")); if (SUCCEEDED(hr) && ((dwNumConflictsResolved > 0) || fHasUpgradeHelpInfo || fNovell)) #endif if (SUCCEEDED(hr) && ((dwNumConflictsResolved > 0) || fHasUpgradeHelpInfo)) { #if 0 if (fNovell) { // special case for novell (dir name is %windir%\netsetup\novell) hr = HrGetNetUpgradeTempDir(&strTempOemDir); if (S_OK == hr) { strTempOemDir += L"novell"; if (0 == CreateDirectory(strTempOemDir.c_str(), NULL)) { hr = HrFromLastWin32Error(); if (HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) == hr) { // perhaps a previous failed attempt, maybe. Since // we can just copy on top of this, ignore the 'error'. // hr = S_OK; } if (S_OK == hr) { TraceTag(ttidNetUpgrade, "Created oem\\Novell dir", __FUNCNAME__); } } } } else #endif { // regular case (dir name is %windir%\netsetup\oemNNNNN) hr = HrCreateOemTempDir(&strTempOemDir); } if (S_OK == hr) { hr = HrCopyFiles(pszOemDir, strTempOemDir.c_str()); } if (FAILED(hr)) { dwErrorMessageId = IDS_E_CopyingOemFiles; } } else { if (fInteractive) { MessageBox(NULL, SzLoadString(g_hinst, IDS_E_OemFilesNotValidForComponents), SzLoadString(g_hinst, IDS_NetupgrdCaption), MB_OK|MB_APPLMODAL); } hr = S_FALSE; } ::SetupCloseInfFile(hinf); if (S_OK == hr) { hr = HrOpenOemNMapFile(strTempOemDir.c_str(), &hinf); if (S_OK == hr) { hr = HrUpdateConflictList(TRUE, hinf, &dwNumConflictsResolved, &fHasUpgradeHelpInfo); if (SUCCEEDED(hr) && ((dwNumConflictsResolved > 0) || fHasUpgradeHelpInfo)) { // hinf is stored in the global array, it will be // closed in UninitNetMapInfo function // hr = HrAddToGlobalNetMapInfo(hinf, strTempOemDir.c_str()); } else { ::SetupCloseInfFile(hinf); } } if (FAILED(hr)) { dwErrorMessageId = IDS_E_PresetNetMapInfError; } } } else { TraceTag(ttidNetUpgrade, "%s: could not open netmap.inf in %S", __FUNCNAME__, pszOemDir); dwErrorMessageId = IDS_E_PresetNetMapInfError; } if (FAILED(hr)) { FGetConfirmationAndAbortUpgradeId(dwErrorMessageId); } TraceErrorOptional(__FUNCNAME__, hr, (hr == S_FALSE)); return hr; } // ---------------------------------------------------------------------- // // Function: RequestAbortUpgradeOboOemDll // // Purpose: Display UI on behalf of an OEM DLL and ask user // if upgrade needs to be aborted // // Arguments: // pszDllName [in] name of OEM DLL // // Returns: None // // Author: kumarp 17-December-97 // // Notes: // void RequestAbortUpgradeOboOemDll(IN PCWSTR pszDllName, VENDORINFO* pvi) { tstring strMessage; strMessage = SzLoadString(g_hinst, IDS_E_OemDllRequestsAbortingUpgrade); strMessage += pszDllName; strMessage += L"\n\n"; strMessage += SzLoadString(g_hinst, IDS_InfoAboutOemDllSupplier); strMessage += SzLoadString(g_hinst, IDS_ViCompanyName); strMessage += pvi->szCompanyName; strMessage += L"\n"; if (*pvi->szSupportNumber) { strMessage += SzLoadString(g_hinst, IDS_ViSupportNumber); strMessage += pvi->szSupportNumber; strMessage += L"\n"; } if (*pvi->szSupportUrl) { strMessage += SzLoadString(g_hinst, IDS_ViSupportUrl); strMessage += pvi->szSupportUrl; strMessage += L"\n"; } if (*pvi->szInstructionsToUser) { strMessage += SzLoadString(g_hinst, IDS_ViAdditionalInfo); strMessage += pvi->szInstructionsToUser; strMessage += L"\n"; } FGetConfirmationAndAbortUpgrade(strMessage.c_str()); } // ---------------------------------------------------------------------- // // Function: AbortUpgradeOemComponent // // Purpose: Abort upgrade because of a fatal error when upgrading an // OEM component // // Arguments: // pszPreNT5InfId [in] pre-NT5 InfID of OEM component // pszDescription [in] description of OEM component // dwError [in] error code // dwErrorMessageId [in] ID of error message resource string // // Returns: None // // Author: kumarp 17-December-97 // // Notes: // void AbortUpgradeOemComponent(IN PCWSTR pszPreNT5InfId, IN PCWSTR pszDescription, IN DWORD dwError, IN DWORD dwErrorMessageId) { tstring strMessage; static const WCHAR c_szNewLine[] = L"\n"; WCHAR szErrorCode[16]; swprintf(szErrorCode, L"0x%08x", dwError); strMessage = SzLoadString(g_hinst, IDS_E_OemComponentUpgrade); strMessage = strMessage + c_szNewLine + pszDescription + L"(" + pszPreNT5InfId + L"\n\n" + SzLoadString(g_hinst, dwErrorMessageId) + c_szNewLine + SzLoadString(g_hinst, IDS_E_ErrorCode) + szErrorCode; FGetConfirmationAndAbortUpgrade(strMessage.c_str()); } // ---------------------------------------------------------------------- // // Function: FCanDeleteOemService // // Purpose: Determine if a service can be deleted. // OEM upgrade DLLs can prevent a service from being deleted, // by specifying a list in the mszServicesNotToBeDeleted // member of NetUpgradeData structure. // // Arguments: // pszServiceName [in] name of the service to be spared. // // Returns: TRUE if can delete, FALSE otherwise // // Author: kumarp 04-March-98 // // Notes: // BOOL FCanDeleteOemService(IN PCWSTR pszServiceName) { BOOL fCanDeleteService = TRUE; if (g_pnmaNetMap) { CNetMapInfo* pnmi; size_t cNumNetMapEntries = g_pnmaNetMap->size(); for (size_t i = 0; i < cNumNetMapEntries; i++) { pnmi = (CNetMapInfo*) (*g_pnmaNetMap)[i]; if (FIsSzInMultiSzSafe(pszServiceName, pnmi->m_nud.mszServicesNotToBeDeleted)) { fCanDeleteService = FALSE; break; } } } return fCanDeleteService; }