|
|
//+---------------------------------------------------------------------------
//
// 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; }
|