Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1407 lines
38 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: O E M U P G . C P P
  7. //
  8. // Contents: Down level upgrade code for OEM cards
  9. //
  10. // Notes:
  11. //
  12. // Author: kumarp 12 April 97
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "conflict.h"
  18. #include "infmap.h"
  19. #include "kkcwinf.h"
  20. #include "kkutils.h"
  21. #include "nceh.h"
  22. #include "ncsetup.h"
  23. #include "netupgrd.h"
  24. #include "nustrs.h"
  25. #include "nuutils.h"
  26. #include "oemupg.h"
  27. #include "oemupgex.h"
  28. #include "resource.h"
  29. static const WCHAR c_szOemNMapFileName[] = L"netmap.inf";
  30. TNetMapArray* g_pnmaNetMap=NULL;
  31. #if 0
  32. extern BOOL g_fForceNovellDirCopy;
  33. #endif
  34. //----------------------------------------------------------------------------
  35. // prototypes
  36. //
  37. void AbortUpgradeOemComponent(IN PCWSTR pszPreNT5InfId,
  38. IN PCWSTR pszDescription,
  39. IN DWORD dwError,
  40. IN DWORD dwErrorMessageId);
  41. //----------------------------------------------------------------------------
  42. // ----------------------------------------------------------------------
  43. //
  44. // Function: CNetMapInfo::CNetMapInfo
  45. //
  46. // Purpose: constructor for class CNetMapInfo
  47. //
  48. // Arguments: None
  49. //
  50. // Returns:
  51. //
  52. // Author: kumarp 17-December-97
  53. //
  54. // Notes:
  55. //
  56. CNetMapInfo::CNetMapInfo()
  57. {
  58. m_hinfNetMap = NULL;
  59. m_hOemDll = NULL;
  60. m_dwFlags = 0;
  61. m_nud.mszServicesNotToBeDeleted = NULL;
  62. m_pfnPreUpgradeInitialize = NULL;
  63. m_pfnDoPreUpgradeProcessing = NULL;
  64. m_fDllInitFailed = FALSE;
  65. }
  66. // ----------------------------------------------------------------------
  67. //
  68. // Function: CNetMapInfo::~CNetMapInfo
  69. //
  70. // Purpose: destructor for class CNetMapInfo
  71. //
  72. // Arguments: None
  73. //
  74. // Returns: None
  75. //
  76. // Author: kumarp 17-December-97
  77. //
  78. // Notes:
  79. //
  80. CNetMapInfo::~CNetMapInfo()
  81. {
  82. if (m_hinfNetMap)
  83. {
  84. ::SetupCloseInfFile(m_hinfNetMap);
  85. }
  86. if (m_hOemDll)
  87. {
  88. ::FreeLibrary(m_hOemDll);
  89. }
  90. }
  91. // ----------------------------------------------------------------------
  92. //
  93. // Function: CNetMapInfo::HrGetOemInfName
  94. //
  95. // Purpose: Get name of installation INF of a component
  96. //
  97. // Arguments:
  98. // pszNT5InfId [in] NT5 InfID of a component
  99. // pstrOemInf [out] pointer to name of INF for this component
  100. //
  101. // Returns: S_OK on success, otherwise an error code
  102. //
  103. // Author: kumarp 26-May-98
  104. //
  105. // Notes:
  106. //
  107. HRESULT CNetMapInfo::HrGetOemInfName(IN PCWSTR pszNT5InfId,
  108. OUT tstring* pstrOemInf)
  109. {
  110. DefineFunctionName("CNetMapInfo::HrGetOemInfName");
  111. AssertValidReadPtr(pszNT5InfId);
  112. AssertValidWritePtr(pstrOemInf);
  113. HRESULT hr=S_OK;
  114. tstring strOemDll;
  115. Assert(m_hinfNetMap);
  116. hr = HrGetOemUpgradeInfoInInf(m_hinfNetMap, pszNT5InfId,
  117. &strOemDll, pstrOemInf);
  118. TraceError(__FUNCNAME__, hr);
  119. return hr;
  120. }
  121. // ----------------------------------------------------------------------
  122. //
  123. // Function: HrOpenNetUpgInfFile
  124. //
  125. // Purpose: Open netupg.inf file.
  126. // - if env var NETUPGRD_INIT_FILE_DIR is set, open it from that dir
  127. // - otherwise open it from the dir where netuprd.dll is located
  128. //
  129. // Arguments:
  130. // phinf [out] handle of netupg.inf file
  131. //
  132. // Returns: S_OK on success, otherwise an error code
  133. //
  134. // Author: kumarp 17-December-97
  135. //
  136. // Notes:
  137. //
  138. HRESULT HrOpenNetUpgInfFile(OUT HINF* phinf)
  139. {
  140. DefineFunctionName("HrOpenNetUpgInfFile");
  141. AssertValidWritePtr(phinf);
  142. static const WCHAR c_szNetUpgInfFile[] = L"netupg.inf";
  143. static const WCHAR c_szNetUpgrdInitDir[] = L"NETUPGRD_INIT_FILE_DIR";
  144. HRESULT hr=S_OK;
  145. tstring strNetUpgInfFile;
  146. // first try opening from N
  147. WCHAR szNetUpgrdInitDir[MAX_PATH+1];
  148. DWORD dwNumCharsReturned;
  149. dwNumCharsReturned =
  150. GetEnvironmentVariable(c_szNetUpgrdInitDir, szNetUpgrdInitDir, MAX_PATH);
  151. if (dwNumCharsReturned)
  152. {
  153. strNetUpgInfFile = szNetUpgrdInitDir;
  154. }
  155. else
  156. {
  157. hr = HrGetNetupgrdDir(&strNetUpgInfFile);
  158. }
  159. if (S_OK == hr)
  160. {
  161. AppendToPath(&strNetUpgInfFile, c_szNetUpgInfFile);
  162. hr = HrSetupOpenInfFile(strNetUpgInfFile.c_str(), NULL,
  163. INF_STYLE_WIN4, NULL, phinf);
  164. }
  165. TraceError(__FUNCNAME__, hr);
  166. return hr;
  167. }
  168. // ----------------------------------------------------------------------
  169. //
  170. // Function: HrGetOemDirs
  171. //
  172. // Purpose: Get list of OEM dirs from netupg.inf file
  173. //
  174. // Arguments:
  175. // pslOemDirs [out] pointer to list of OEM dirs
  176. //
  177. // Returns: S_OK on success, otherwise an error code
  178. //
  179. // Author: kumarp 17-December-97
  180. //
  181. // Notes:
  182. //
  183. HRESULT HrGetOemDirs(OUT TStringList* pslOemDirs)
  184. {
  185. DefineFunctionName("HrGetOemDirs");
  186. TraceFunctionEntry(ttidNetUpgrade);
  187. AssertValidReadPtr(pslOemDirs);
  188. HRESULT hr=S_OK;
  189. static const WCHAR c_szOemDirsSection[] = L"OemNetUpgradeDirs";
  190. HINF hInf;
  191. INFCONTEXT ic;
  192. tstring strNetUpgrdDir;
  193. tstring strDirFullPath;
  194. hr = HrGetNetupgrdDir(&strNetUpgrdDir);
  195. if (S_OK == hr)
  196. {
  197. hr = HrOpenNetUpgInfFile(&hInf);
  198. }
  199. if (S_OK == hr)
  200. {
  201. tstring strOemDir;
  202. hr = HrSetupFindFirstLine(hInf, c_szOemDirsSection, NULL, &ic);
  203. if (S_OK == hr)
  204. {
  205. do
  206. {
  207. hr = HrSetupGetLineText(&ic, hInf, NULL, NULL, &strOemDir);
  208. if (S_OK == hr)
  209. {
  210. TraceTag(ttidNetUpgrade, "%s: locating '%S'...",
  211. __FUNCNAME__, strOemDir.c_str());
  212. hr = HrDirectoryExists(strOemDir.c_str());
  213. if (S_OK == hr)
  214. {
  215. strDirFullPath = strOemDir;
  216. }
  217. else if (S_FALSE == hr)
  218. {
  219. // this may be a dir. relative to winntupg dir
  220. //
  221. strDirFullPath = strNetUpgrdDir;
  222. AppendToPath(&strDirFullPath, strOemDir.c_str());
  223. hr = HrDirectoryExists(strDirFullPath.c_str());
  224. }
  225. if (S_OK == hr)
  226. {
  227. pslOemDirs->push_back(new tstring(strDirFullPath));
  228. TraceTag(ttidNetUpgrade, "%s: ...found OEM dir: %S",
  229. __FUNCNAME__, strDirFullPath.c_str());
  230. }
  231. else if (S_FALSE == hr)
  232. {
  233. TraceTag(ttidNetUpgrade,
  234. "%s: ...could not locate '%S'",
  235. __FUNCNAME__, strOemDir.c_str());
  236. }
  237. if (SUCCEEDED(hr))
  238. {
  239. hr = HrSetupFindNextLine(ic, &ic);
  240. }
  241. }
  242. }
  243. while (S_OK == hr);
  244. if (S_FALSE == hr)
  245. {
  246. hr = S_OK;
  247. }
  248. }
  249. if (HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND) == hr)
  250. {
  251. hr = S_OK;
  252. }
  253. ::SetupCloseInfFile(hInf);
  254. }
  255. TraceError(__FUNCNAME__, hr);
  256. return hr;
  257. }
  258. // ----------------------------------------------------------------------
  259. //
  260. // Function: HrOpenOemNMapFile
  261. //
  262. // Purpose: Open netmap.inf file from the specified dir.
  263. //
  264. // Arguments:
  265. // pszOemDir [in] name of dir.
  266. // phinf [out] pointer to handle of netmap.inf file opened
  267. //
  268. // Returns: S_OK on success, otherwise an error code
  269. //
  270. // Author: kumarp 17-December-97
  271. //
  272. // Notes:
  273. //
  274. HRESULT HrOpenOemNMapFile(IN PCWSTR pszOemDir, OUT HINF* phinf)
  275. {
  276. DefineFunctionName("HrOpenOemNMapFile");
  277. HRESULT hr=S_OK;
  278. *phinf = NULL;
  279. tstring strOemNMapFile;
  280. strOemNMapFile = pszOemDir;
  281. AppendToPath(&strOemNMapFile, c_szOemNMapFileName);
  282. hr = HrSetupOpenInfFile(strOemNMapFile.c_str(), NULL,
  283. INF_STYLE_WIN4, NULL, phinf);
  284. TraceError(__FUNCNAME__, hr);
  285. return hr;
  286. }
  287. // ----------------------------------------------------------------------
  288. //
  289. // Function: HrAddToNetMapInfo
  290. //
  291. // Purpose: Add the specified netmap.inf file to the set of netmap.inf files
  292. //
  293. // Arguments:
  294. // pnma [in] array of CNetMapInfo objects
  295. // hinf [in] handle of netmap.inf file to add
  296. // pszOemDir [in] location of the above file
  297. //
  298. // Returns: S_OK on success, otherwise an error code
  299. //
  300. // Author: kumarp 17-December-97
  301. //
  302. // Notes:
  303. //
  304. HRESULT HrAddToNetMapInfo(IN TNetMapArray* pnma,
  305. IN HINF hinf,
  306. IN PCWSTR pszOemDir)
  307. {
  308. DefineFunctionName("HrAddToNetMapInfo");
  309. AssertValidReadPtr(pnma);
  310. Assert(hinf);
  311. AssertValidReadPtr(pszOemDir);
  312. HRESULT hr=E_OUTOFMEMORY;
  313. CNetMapInfo* pnmi;
  314. pnmi = new CNetMapInfo;
  315. if (pnmi)
  316. {
  317. hr = S_OK;
  318. pnmi->m_hinfNetMap = hinf;
  319. pnmi->m_strOemDir = pszOemDir;
  320. pnma->push_back(pnmi);
  321. }
  322. TraceError(__FUNCNAME__, hr);
  323. return hr;
  324. }
  325. // ----------------------------------------------------------------------
  326. //
  327. // Function: HrOpenNetMapAndAddToNetMapInfo
  328. //
  329. // Purpose: Open and add netmap.inf file in the specified dir.
  330. // to the set of netmap.inf files
  331. //
  332. // Arguments:
  333. // pnma [in] array of CNetMapInfo objects
  334. // pszOemDir [in] location of netmap.inf file
  335. //
  336. // Returns: S_OK on success, otherwise an error code
  337. //
  338. // Author: kumarp 17-December-97
  339. //
  340. // Notes:
  341. //
  342. HRESULT HrOpenNetMapAndAddToNetMapInfo(IN TNetMapArray* pnma,
  343. IN PCWSTR pszOemDir)
  344. {
  345. DefineFunctionName("HrOpenNetMapAndAddToNetMapInfo");
  346. AssertValidReadPtr(pnma);
  347. AssertValidReadPtr(pszOemDir);
  348. HRESULT hr = S_OK;
  349. HINF hinf;
  350. hr = HrOpenOemNMapFile(pszOemDir, &hinf);
  351. if (S_OK == hr)
  352. {
  353. hr = HrAddToNetMapInfo(pnma, hinf, pszOemDir);
  354. }
  355. TraceError(__FUNCNAME__, hr);
  356. return hr;
  357. }
  358. // ----------------------------------------------------------------------
  359. //
  360. // Function: HrAddToGlobalNetMapInfo
  361. //
  362. // Purpose: Add the specified netmap.inf file to the set of netmap.inf files
  363. //
  364. // Arguments:
  365. // hinf [in] handle of netmap.inf file to add
  366. // pszOemDir [in] location of the above file
  367. //
  368. // Returns: S_OK on success, otherwise an error code
  369. //
  370. // Author: kumarp 17-December-97
  371. //
  372. // Notes:
  373. //
  374. HRESULT HrAddToGlobalNetMapInfo(IN HINF hinf,
  375. IN PCWSTR pszOemDir)
  376. {
  377. DefineFunctionName("HrAddToGlobalNetMapInfo");
  378. AssertValidReadPtr(g_pnmaNetMap);
  379. Assert(hinf);
  380. AssertValidReadPtr(pszOemDir);
  381. HRESULT hr=E_OUTOFMEMORY;
  382. hr = HrAddToNetMapInfo(g_pnmaNetMap, hinf, pszOemDir);
  383. TraceError(__FUNCNAME__, hr);
  384. return hr;
  385. }
  386. // ----------------------------------------------------------------------
  387. //
  388. // Function: HrInitNetMapInfo
  389. //
  390. // Purpose: Initialize array of CNetMapInfo objects
  391. //
  392. // Arguments: None
  393. //
  394. // Returns: S_OK on success, otherwise an error code
  395. //
  396. // Author: kumarp 17-December-97
  397. //
  398. // Notes:
  399. //
  400. HRESULT HrInitNetMapInfo()
  401. {
  402. DefineFunctionName("HrInitNetMapInfo");
  403. HRESULT hr=E_FAIL;
  404. tstring strNetupgrdDir;
  405. g_pnmaNetMap = new TNetMapArray;
  406. if (!g_pnmaNetMap)
  407. {
  408. hr = E_OUTOFMEMORY;
  409. }
  410. else
  411. {
  412. hr = HrGetNetupgrdDir(&strNetupgrdDir);
  413. if (S_OK == hr)
  414. {
  415. TraceTag(ttidNetUpgrade, "%s: initializing netmap info from '%S'",
  416. __FUNCNAME__, strNetupgrdDir.c_str());
  417. hr = HrOpenNetMapAndAddToNetMapInfo(g_pnmaNetMap,
  418. strNetupgrdDir.c_str());
  419. }
  420. }
  421. TraceError(__FUNCNAME__, hr);
  422. return hr;
  423. }
  424. // ----------------------------------------------------------------------
  425. //
  426. // Function: UnInitNetMapInfo
  427. //
  428. // Purpose: Uninitialize the array of CNetMapInfo objects
  429. //
  430. // Arguments: None
  431. //
  432. // Returns: None
  433. //
  434. // Author: kumarp 17-December-97
  435. //
  436. // Notes:
  437. //
  438. void UnInitNetMapInfo()
  439. {
  440. DefineFunctionName("UnInitNetMapInfo");
  441. if (g_pnmaNetMap)
  442. {
  443. CNetMapInfo* pnmi;
  444. size_t cNumNetMapEntries = g_pnmaNetMap->size();
  445. for (size_t i = 0; i < cNumNetMapEntries; i++)
  446. {
  447. pnmi = (CNetMapInfo*) (*g_pnmaNetMap)[i];
  448. delete pnmi;
  449. }
  450. g_pnmaNetMap->erase(g_pnmaNetMap->begin(), g_pnmaNetMap->end());
  451. delete g_pnmaNetMap;
  452. g_pnmaNetMap = NULL;
  453. }
  454. }
  455. // ----------------------------------------------------------------------
  456. //
  457. // Function: HrInitAndProcessOemDirs
  458. //
  459. // Purpose: Initialize and process each OEM dir specified in netupg.inf file
  460. //
  461. // Arguments: None
  462. //
  463. // Returns: S_OK on success, otherwise an error code
  464. //
  465. // Author: kumarp 17-December-97
  466. //
  467. // Notes:
  468. //
  469. HRESULT HrInitAndProcessOemDirs()
  470. {
  471. DefineFunctionName("HrInitAndProcessOemDirs");
  472. TraceFunctionEntry(ttidNetUpgrade);
  473. HRESULT hr=S_OK;
  474. TStringList slOemDirs;
  475. hr = HrGetOemDirs(&slOemDirs);
  476. if (S_OK == hr)
  477. {
  478. PCWSTR pszOemDir;
  479. HINF hinf;
  480. TStringListIter pos;
  481. for (pos=slOemDirs.begin(); pos != slOemDirs.end(); pos++)
  482. {
  483. pszOemDir = (*pos)->c_str();
  484. TraceTag(ttidNetUpgrade, "%s: initializing NetMapInfo for: %S",
  485. __FUNCNAME__, pszOemDir);
  486. hr = HrProcessAndCopyOemFiles(pszOemDir, FALSE);
  487. if (FAILED(hr))
  488. {
  489. break;
  490. }
  491. }
  492. }
  493. if (S_FALSE == hr)
  494. {
  495. hr = S_OK;
  496. }
  497. TraceError(__FUNCNAME__, hr);
  498. return hr;
  499. }
  500. // ----------------------------------------------------------------------
  501. //
  502. // Function: HrGetNetUpgradeTempDir
  503. //
  504. // Purpose: Return name of temp. dir to use, creating one if necessary
  505. //
  506. // Arguments:
  507. // pstrTempDir [out] pointer to
  508. //
  509. // Returns: S_OK on success, otherwise an error code
  510. //
  511. // Author: kumarp 17-December-97
  512. //
  513. // Notes:
  514. //
  515. HRESULT HrGetNetUpgradeTempDir(OUT tstring* pstrTempDir)
  516. {
  517. DefineFunctionName("HrGetNetUpgradeTempDir");
  518. HRESULT hr=E_FAIL;
  519. tstring strNetUpgradeTempDir;
  520. hr = HrGetWindowsDir(&strNetUpgradeTempDir);
  521. if (S_OK == hr)
  522. {
  523. static const WCHAR c_szNetupgrdSubDir[] = L"\\netsetup\\";
  524. strNetUpgradeTempDir += c_szNetupgrdSubDir;
  525. if (!CreateDirectory(strNetUpgradeTempDir.c_str(), NULL))
  526. {
  527. hr = HrFromLastWin32Error();
  528. if (HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) == hr)
  529. {
  530. hr = S_OK;
  531. }
  532. }
  533. if (S_OK == hr)
  534. {
  535. *pstrTempDir = strNetUpgradeTempDir;
  536. }
  537. }
  538. TraceError(__FUNCNAME__, hr);
  539. return hr;
  540. }
  541. // ----------------------------------------------------------------------
  542. //
  543. // Function: HrCreateOemTempDir
  544. //
  545. // Purpose: Create a temp. dir with unique name
  546. //
  547. // Arguments:
  548. // pstrOemTempDir [out] name of dir created
  549. //
  550. // Returns: S_OK on success, otherwise an error code
  551. //
  552. // Author: kumarp 17-December-97
  553. //
  554. // Notes:
  555. //
  556. HRESULT HrCreateOemTempDir(OUT tstring* pstrOemTempDir)
  557. {
  558. DefineFunctionName("HrCreateOemTempDir");
  559. HRESULT hr=S_OK;
  560. static DWORD dwOemDirCount=0;
  561. WCHAR szOemDirPath[MAX_PATH];
  562. hr = HrGetNetUpgradeTempDir(pstrOemTempDir);
  563. if (S_OK == hr)
  564. {
  565. DWORD dwRetryCount=0;
  566. const DWORD c_dwMaxRetryCount=1000;
  567. DWORD err=NO_ERROR;
  568. DWORD status;
  569. do
  570. {
  571. swprintf(szOemDirPath, L"%soem%05ld",
  572. pstrOemTempDir->c_str(), dwOemDirCount++);
  573. TraceTag(ttidNetUpgrade, "%s: trying to create %S",
  574. __FUNCNAME__, szOemDirPath);
  575. status = CreateDirectory(szOemDirPath, NULL);
  576. if (status)
  577. {
  578. *pstrOemTempDir = szOemDirPath;
  579. }
  580. else
  581. {
  582. err = GetLastError();
  583. }
  584. }
  585. while (!status && (ERROR_ALREADY_EXISTS == err) &&
  586. (dwRetryCount++ < c_dwMaxRetryCount));
  587. if (!status)
  588. {
  589. hr = HrFromLastWin32Error();
  590. }
  591. }
  592. TraceError(__FUNCNAME__, hr);
  593. return hr;
  594. }
  595. // ----------------------------------------------------------------------
  596. //
  597. // Function: HrLoadAndVerifyOemDll
  598. //
  599. // Purpose: Load and check for correct exported fns in the specified OEM DLL
  600. //
  601. // Arguments:
  602. // CNetMapInfo [in]
  603. // i [in] pointer to
  604. //
  605. // Returns: S_OK on success,
  606. // S_FALSE if DLL init had failed last time when we tried
  607. // otherwise an error code
  608. //
  609. // Author: kumarp 17-December-97
  610. //
  611. // Notes:
  612. //
  613. HRESULT HrLoadAndVerifyOemDll(IN OUT CNetMapInfo* pnmi)
  614. {
  615. DefineFunctionName("HrLoadAndVerifyOemDll");
  616. HRESULT hr=S_OK;
  617. Assert(!pnmi->m_hOemDll);
  618. Assert(pnmi->m_strOemDllName.size() > 0);
  619. Assert(pnmi->m_strOemDir.size() > 0);
  620. if (pnmi->m_fDllInitFailed)
  621. {
  622. hr = S_FALSE;
  623. }
  624. else if (!pnmi->m_hOemDll)
  625. {
  626. TraceTag(ttidNetUpgrade, "%s: loading OEM DLL: %S%S",
  627. __FUNCNAME__, pnmi->m_strOemDir.c_str(),
  628. pnmi->m_strOemDllName.c_str());
  629. tstring strOemDllFullPath;
  630. strOemDllFullPath = pnmi->m_strOemDir;
  631. AppendToPath(&strOemDllFullPath, pnmi->m_strOemDllName.c_str());
  632. hr = HrLoadLibAndGetProcsV(strOemDllFullPath.c_str(),
  633. &pnmi->m_hOemDll,
  634. c_szPreUpgradeInitialize,
  635. (FARPROC*) &pnmi->m_pfnPreUpgradeInitialize,
  636. c_szDoPreUpgradeProcessing,
  637. (FARPROC*) &pnmi->m_pfnDoPreUpgradeProcessing,
  638. NULL);
  639. if (FAILED(hr))
  640. {
  641. pnmi->m_hOemDll = NULL;
  642. pnmi->m_pfnPreUpgradeInitialize = NULL;
  643. pnmi->m_pfnDoPreUpgradeProcessing = NULL;
  644. pnmi->m_fDllInitFailed = TRUE;
  645. }
  646. }
  647. TraceError(__FUNCNAME__, hr);
  648. return hr;
  649. }
  650. // ----------------------------------------------------------------------
  651. //
  652. // Function: HrLoadAndInitOemDll
  653. //
  654. // Purpose: Load the specified OEM DLL and call its
  655. // PreUpgradeInitialize function
  656. //
  657. // Arguments:
  658. // pnmi [in] pointer to CNetMapInfo object
  659. // pNetUpgradeInfo [in] pointer to NetUpgradeInfo
  660. //
  661. // Returns: S_OK on success
  662. // S_FALSE if DLL init had failed last time when we tried
  663. // otherwise an error code
  664. //
  665. // Author: kumarp 17-December-97
  666. //
  667. // Notes:
  668. //
  669. HRESULT HrLoadAndInitOemDll(IN CNetMapInfo* pnmi,
  670. IN NetUpgradeInfo* pNetUpgradeInfo)
  671. {
  672. DefineFunctionName("HrLoadAndInitOemDll");
  673. HRESULT hr=S_OK;
  674. DWORD dwError=ERROR_SUCCESS;
  675. VENDORINFO vi;
  676. hr = HrLoadAndVerifyOemDll(pnmi);
  677. if (S_OK == hr)
  678. {
  679. if (pnmi->m_pfnPreUpgradeInitialize)
  680. {
  681. NC_TRY
  682. {
  683. TraceTag(ttidNetUpgrade, "%s: initializing OEM DLL: %S in %S",
  684. __FUNCNAME__,
  685. pnmi->m_strOemDllName.c_str(),
  686. pnmi->m_strOemDir.c_str());
  687. dwError = pnmi->m_pfnPreUpgradeInitialize(pnmi->m_strOemDir.c_str(),
  688. pNetUpgradeInfo,
  689. &vi,
  690. &pnmi->m_dwFlags,
  691. &pnmi->m_nud);
  692. #ifdef ENABLETRACE
  693. if (pnmi->m_nud.mszServicesNotToBeDeleted)
  694. {
  695. TraceMultiSz(ttidNetUpgrade,
  696. L"OEM services that will not be deleted",
  697. pnmi->m_nud.mszServicesNotToBeDeleted);
  698. }
  699. #endif
  700. // ensure that this function gets called only once
  701. //
  702. pnmi->m_pfnPreUpgradeInitialize = NULL;
  703. hr = HRESULT_FROM_WIN32(dwError);
  704. if (pnmi->m_dwFlags & NUA_REQUEST_ABORT_UPGRADE)
  705. {
  706. TraceTag(ttidNetUpgrade,
  707. "%s: OEM DLL '%S' requested that upgrade be aborted",
  708. __FUNCNAME__, pnmi->m_strOemDllName.c_str());
  709. RequestAbortUpgradeOboOemDll(pnmi->m_strOemDllName.c_str(),
  710. &vi);
  711. hr = S_FALSE;
  712. }
  713. else if (pnmi->m_dwFlags & NUA_ABORT_UPGRADE)
  714. {
  715. TraceTag(ttidNetUpgrade,
  716. "%s: OEM DLL '%S' aborted the upgrade",
  717. __FUNCNAME__, pnmi->m_strOemDllName.c_str());
  718. AbortUpgradeFn(ERROR_SUCCESS, pnmi->m_strOemDllName.c_str());
  719. hr = S_FALSE;
  720. }
  721. }
  722. NC_CATCH_ALL
  723. {
  724. TraceTag(ttidError, "%s: OEM DLL '%S' caused an exception",
  725. __FUNCNAME__, pnmi->m_strOemDllName.c_str());
  726. hr = HRESULT_FROM_WIN32(ERROR_DLL_INIT_FAILED);
  727. }
  728. }
  729. }
  730. TraceError(__FUNCNAME__, hr);
  731. return hr;
  732. }
  733. // ----------------------------------------------------------------------
  734. //
  735. // Function: HrProcessOemComponent
  736. //
  737. // Purpose: Load an OEM DLL and call DoPreUpgradeProcessing
  738. // function for the specified component
  739. //
  740. // Arguments:
  741. // pnmi [in] pointer to CNetMapInfo object
  742. // pNetUpgradeInfo [in] pointer to NetUpgradeInfo
  743. // hwndParent [in] handle of parent window
  744. // hkeyParams [in] handle of Parameters registry key
  745. // pszPreNT5InfId [in] pre-NT5 InfID of a component (e.g. IEEPRO)
  746. // pszPreNT5Instance [in] pre-NT5 instance of a component (e.g. IEEPRO2)
  747. // pszNT5InfId [in] NT5 InfID of the component
  748. // pszDescription [in] description of the component
  749. // pszSectionName [in] name of section that the OEM DLL must use
  750. // for storing its upgrade parameters
  751. // pdwFlags [out] pointer to flags returned by OEM DLL
  752. //
  753. // Returns: S_OK on success, otherwise an error code
  754. //
  755. // Author: kumarp 17-December-97
  756. //
  757. // Notes:
  758. //
  759. HRESULT HrProcessOemComponent(CNetMapInfo* pnmi,
  760. IN NetUpgradeInfo* pNetUpgradeInfo,
  761. IN HWND hwndParent,
  762. IN HKEY hkeyParams,
  763. IN PCWSTR pszPreNT5InfId,
  764. IN PCWSTR pszPreNT5Instance,
  765. IN PCWSTR pszNT5InfId,
  766. IN PCWSTR pszDescription,
  767. IN PCWSTR pszSectionName,
  768. OUT DWORD* pdwFlags)
  769. {
  770. DefineFunctionName("HrProcessOemComponent");
  771. AssertValidReadPtr(pnmi);
  772. AssertValidReadPtr(pNetUpgradeInfo);
  773. Assert(hkeyParams);
  774. AssertValidReadPtr(pszPreNT5InfId);
  775. AssertValidReadPtr(pszPreNT5Instance);
  776. AssertValidReadPtr(pszNT5InfId);
  777. AssertValidReadPtr(pszDescription);
  778. AssertValidReadPtr(pszSectionName);
  779. AssertValidWritePtr(pdwFlags);
  780. TraceTag(ttidNetUpgrade,
  781. "%s: Processing OEM component: %S(%S), instance: %S",
  782. __FUNCNAME__, pszNT5InfId, pszPreNT5InfId, pszPreNT5Instance);
  783. HRESULT hr=S_OK;
  784. VENDORINFO vi;
  785. DWORD dwErrorMessageId=0;
  786. if (pnmi->m_strOemDllName.empty())
  787. {
  788. tstring strOemInf;
  789. hr = HrGetOemUpgradeInfoInInf(pnmi->m_hinfNetMap,
  790. pszNT5InfId,
  791. &pnmi->m_strOemDllName,
  792. &strOemInf);
  793. if (S_OK == hr)
  794. {
  795. hr = HrLoadAndInitOemDll(pnmi, pNetUpgradeInfo);
  796. if (FAILED(hr))
  797. {
  798. dwErrorMessageId = IDS_E_LoadAndInitOemDll;
  799. }
  800. }
  801. else
  802. {
  803. dwErrorMessageId = IDS_E_GetOemUpgradeDllInfoInInf;
  804. }
  805. }
  806. if (S_OK == hr)
  807. {
  808. Assert(pnmi->m_pfnDoPreUpgradeProcessing);
  809. NC_TRY
  810. {
  811. TraceTag(ttidNetUpgrade,
  812. "%s: calling DoPreUpgradeProcessing in %S for %S",
  813. __FUNCNAME__, pnmi->m_strOemDllName.c_str(), pszNT5InfId);
  814. Assert(pnmi->m_pfnDoPreUpgradeProcessing);
  815. DWORD dwError =
  816. pnmi->m_pfnDoPreUpgradeProcessing(hwndParent, hkeyParams,
  817. pszPreNT5InfId, pszPreNT5Instance,
  818. pszNT5InfId,
  819. pszSectionName,
  820. &vi,
  821. pdwFlags, NULL);
  822. TraceTag(ttidNetUpgrade, "%s: DoPreUpgradeProcessing returned: 0x%x",
  823. __FUNCNAME__, dwError);
  824. hr = HRESULT_FROM_WIN32(dwError);
  825. if (S_OK == hr)
  826. {
  827. if (*pdwFlags & NUA_REQUEST_ABORT_UPGRADE)
  828. {
  829. RequestAbortUpgradeOboOemDll(pnmi->m_strOemDllName.c_str(),
  830. &vi);
  831. hr = S_FALSE;
  832. }
  833. }
  834. else
  835. {
  836. dwErrorMessageId = IDS_E_DoPreUpgradeProcessing;
  837. }
  838. }
  839. NC_CATCH_ALL
  840. {
  841. TraceTag(ttidError, "%s: OEM DLL '%S' caused an exception",
  842. __FUNCNAME__, pnmi->m_strOemDllName.c_str());
  843. hr = HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED);
  844. dwErrorMessageId = IDS_E_OemDllCausedAnException;
  845. }
  846. }
  847. else if (S_FALSE == hr)
  848. {
  849. TraceTag(ttidNetUpgrade, "%s: DoPreUpgradeProcessing was not called"
  850. " since DLL init had failed", __FUNCNAME__);
  851. }
  852. if (FAILED(hr))
  853. {
  854. AbortUpgradeOemComponent(pszPreNT5InfId, pszDescription,
  855. DwWin32ErrorFromHr(hr), dwErrorMessageId);
  856. }
  857. TraceError(__FUNCNAME__, hr);
  858. return hr;
  859. }
  860. // ----------------------------------------------------------------------
  861. //
  862. // Function: HrShowUiAndGetOemFileLocation
  863. //
  864. // Purpose: Display UI asking the user to specify location of OEM files
  865. //
  866. // Arguments:
  867. // hwndParent [in] handle of parent window
  868. // pszComponentName [in] name of Component
  869. // pstrOemPath [out] name of netmap.inf file the user selected
  870. //
  871. // Returns: S_OK on success, otherwise an error code
  872. //
  873. // Author: kumarp 17-December-97
  874. //
  875. // Notes:
  876. //
  877. HRESULT
  878. HrShowUiAndGetOemFileLocation(
  879. IN HWND hwndParent,
  880. IN PCWSTR pszComponentName,
  881. OUT tstring* pstrOemPath)
  882. {
  883. DefineFunctionName("HrShowUiAndGetOemFileLocation");
  884. AssertValidWritePtr(pstrOemPath);
  885. OPENFILENAME ofn;
  886. WCHAR szOemPath[MAX_PATH+1];
  887. PWSTR pszTitle;
  888. PCWSTR pszOemQueryFileLocationFormatString =
  889. SzLoadString(g_hinst, IDS_OemQueryFileLocation);
  890. PCWSTR pszOemFileTypeFilter1 =
  891. SzLoadString(g_hinst, IDS_OemNetMapFileFilter1);
  892. PCWSTR pszOemFileTypeFilter2 =
  893. SzLoadString(g_hinst, IDS_OemNetMapFileFilter2);
  894. PWSTR mszFileFilter = NULL;
  895. HRESULT hr = S_OK;
  896. BOOL f;
  897. hr = HrAddSzToMultiSz(pszOemFileTypeFilter1, NULL,
  898. STRING_FLAG_ENSURE_AT_END,
  899. 0, &mszFileFilter, &f);
  900. if (S_OK != hr)
  901. {
  902. goto cleanup;
  903. }
  904. hr = HrAddSzToMultiSz(pszOemFileTypeFilter2, mszFileFilter,
  905. STRING_FLAG_ENSURE_AT_END,
  906. 0, &mszFileFilter, &f);
  907. if (S_OK != hr)
  908. {
  909. goto cleanup;
  910. }
  911. ZeroMemory (&ofn, sizeof(ofn));
  912. *szOemPath = 0;
  913. DwFormatStringWithLocalAlloc (
  914. pszOemQueryFileLocationFormatString,
  915. &pszTitle,
  916. pszComponentName);
  917. ofn.lStructSize = sizeof(OPENFILENAME);
  918. ofn.hwndOwner = hwndParent;
  919. ofn.lpstrFilter = mszFileFilter;
  920. ofn.lpstrFile = szOemPath;
  921. ofn.nMaxFile = MAX_PATH;
  922. ofn.lpstrTitle = pszTitle;
  923. ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST |
  924. OFN_HIDEREADONLY | OFN_NOCHANGEDIR |
  925. OFN_NODEREFERENCELINKS;
  926. if (GetOpenFileName(&ofn))
  927. {
  928. // get rid of the trailing filename.
  929. //
  930. szOemPath[ofn.nFileOffset] = 0;
  931. *pstrOemPath = szOemPath;
  932. hr = S_OK;
  933. }
  934. else
  935. {
  936. DWORD err;
  937. err = CommDlgExtendedError();
  938. if (err)
  939. {
  940. hr = E_FAIL;
  941. TraceTag(ttidError, "%s: FileOpen dialog returned error: %ld (0x%lx)",
  942. __FUNCNAME__, err, err);
  943. }
  944. else
  945. {
  946. hr = S_FALSE;
  947. TraceTag(ttidError, "%s: FileOpen dialog was canceled by user",
  948. __FUNCNAME__);
  949. }
  950. }
  951. LocalFree (pszTitle);
  952. cleanup:
  953. MemFree(mszFileFilter);
  954. TraceErrorOptional(__FUNCNAME__, hr, (hr == S_FALSE));
  955. return hr;
  956. }
  957. // ----------------------------------------------------------------------
  958. //
  959. // Function: HrProcessAndCopyOemFiles
  960. //
  961. // Purpose: Copy OEM files from the specified dir to OEM temp. dir.
  962. //
  963. // Arguments:
  964. // pszOemDir [in] location of OEM files
  965. // fInteractive [in] TRUE --> called when a user has interactively
  966. // supplied a disk having OEM files, FALSE otherwise
  967. //
  968. // Returns: S_OK on success,
  969. // S_FALSE if the OEM files are valid but not applicable for
  970. // currently displayed unsupported components,
  971. // otherwise an error code
  972. //
  973. // Author: kumarp 17-December-97
  974. //
  975. // Notes:
  976. //
  977. HRESULT HrProcessAndCopyOemFiles(IN PCWSTR pszOemDir,
  978. IN BOOL fInteractive)
  979. {
  980. DefineFunctionName("HrProcessAndCopyOemFiles");
  981. HRESULT hr=S_OK;
  982. HINF hinf=NULL;
  983. tstring strTempOemDir;
  984. DWORD dwErrorMessageId;
  985. TraceTag(ttidNetUpgrade, "%s: processing OEM files in: %S",
  986. __FUNCNAME__, pszOemDir);
  987. hr = HrOpenOemNMapFile(pszOemDir, &hinf);
  988. if (S_OK == hr)
  989. {
  990. DWORD dwNumConflictsResolved=0;
  991. BOOL fHasUpgradeHelpInfo=FALSE;
  992. hr = HrUpdateConflictList(FALSE, hinf, &dwNumConflictsResolved,
  993. &fHasUpgradeHelpInfo);
  994. #if 0
  995. BOOL fNovell = (g_fForceNovellDirCopy && wcsstr(pszOemDir, L"oem\\novell"));
  996. if (SUCCEEDED(hr) && ((dwNumConflictsResolved > 0) ||
  997. fHasUpgradeHelpInfo ||
  998. fNovell))
  999. #endif
  1000. if (SUCCEEDED(hr) && ((dwNumConflictsResolved > 0) ||
  1001. fHasUpgradeHelpInfo))
  1002. {
  1003. #if 0
  1004. if (fNovell)
  1005. {
  1006. // special case for novell (dir name is %windir%\netsetup\novell)
  1007. hr = HrGetNetUpgradeTempDir(&strTempOemDir);
  1008. if (S_OK == hr)
  1009. {
  1010. strTempOemDir += L"novell";
  1011. if (0 == CreateDirectory(strTempOemDir.c_str(), NULL))
  1012. {
  1013. hr = HrFromLastWin32Error();
  1014. if (HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) == hr)
  1015. {
  1016. // perhaps a previous failed attempt, maybe. Since
  1017. // we can just copy on top of this, ignore the 'error'.
  1018. //
  1019. hr = S_OK;
  1020. }
  1021. if (S_OK == hr)
  1022. {
  1023. TraceTag(ttidNetUpgrade, "Created oem\\Novell dir",
  1024. __FUNCNAME__);
  1025. }
  1026. }
  1027. }
  1028. }
  1029. else
  1030. #endif
  1031. {
  1032. // regular case (dir name is %windir%\netsetup\oemNNNNN)
  1033. hr = HrCreateOemTempDir(&strTempOemDir);
  1034. }
  1035. if (S_OK == hr)
  1036. {
  1037. hr = HrCopyFiles(pszOemDir, strTempOemDir.c_str());
  1038. }
  1039. if (FAILED(hr))
  1040. {
  1041. dwErrorMessageId = IDS_E_CopyingOemFiles;
  1042. }
  1043. }
  1044. else
  1045. {
  1046. if (fInteractive)
  1047. {
  1048. MessageBox(NULL,
  1049. SzLoadString(g_hinst, IDS_E_OemFilesNotValidForComponents),
  1050. SzLoadString(g_hinst, IDS_NetupgrdCaption),
  1051. MB_OK|MB_APPLMODAL);
  1052. }
  1053. hr = S_FALSE;
  1054. }
  1055. ::SetupCloseInfFile(hinf);
  1056. if (S_OK == hr)
  1057. {
  1058. hr = HrOpenOemNMapFile(strTempOemDir.c_str(), &hinf);
  1059. if (S_OK == hr)
  1060. {
  1061. hr = HrUpdateConflictList(TRUE, hinf, &dwNumConflictsResolved,
  1062. &fHasUpgradeHelpInfo);
  1063. if (SUCCEEDED(hr) && ((dwNumConflictsResolved > 0) ||
  1064. fHasUpgradeHelpInfo))
  1065. {
  1066. // hinf is stored in the global array, it will be
  1067. // closed in UninitNetMapInfo function
  1068. //
  1069. hr = HrAddToGlobalNetMapInfo(hinf, strTempOemDir.c_str());
  1070. }
  1071. else
  1072. {
  1073. ::SetupCloseInfFile(hinf);
  1074. }
  1075. }
  1076. if (FAILED(hr))
  1077. {
  1078. dwErrorMessageId = IDS_E_PresetNetMapInfError;
  1079. }
  1080. }
  1081. }
  1082. else
  1083. {
  1084. TraceTag(ttidNetUpgrade, "%s: could not open netmap.inf in %S",
  1085. __FUNCNAME__, pszOemDir);
  1086. dwErrorMessageId = IDS_E_PresetNetMapInfError;
  1087. }
  1088. if (FAILED(hr))
  1089. {
  1090. FGetConfirmationAndAbortUpgradeId(dwErrorMessageId);
  1091. }
  1092. TraceErrorOptional(__FUNCNAME__, hr, (hr == S_FALSE));
  1093. return hr;
  1094. }
  1095. // ----------------------------------------------------------------------
  1096. //
  1097. // Function: RequestAbortUpgradeOboOemDll
  1098. //
  1099. // Purpose: Display UI on behalf of an OEM DLL and ask user
  1100. // if upgrade needs to be aborted
  1101. //
  1102. // Arguments:
  1103. // pszDllName [in] name of OEM DLL
  1104. //
  1105. // Returns: None
  1106. //
  1107. // Author: kumarp 17-December-97
  1108. //
  1109. // Notes:
  1110. //
  1111. void RequestAbortUpgradeOboOemDll(IN PCWSTR pszDllName, VENDORINFO* pvi)
  1112. {
  1113. tstring strMessage;
  1114. strMessage = SzLoadString(g_hinst, IDS_E_OemDllRequestsAbortingUpgrade);
  1115. strMessage += pszDllName;
  1116. strMessage += L"\n\n";
  1117. strMessage += SzLoadString(g_hinst, IDS_InfoAboutOemDllSupplier);
  1118. strMessage += SzLoadString(g_hinst, IDS_ViCompanyName);
  1119. strMessage += pvi->szCompanyName;
  1120. strMessage += L"\n";
  1121. if (*pvi->szSupportNumber)
  1122. {
  1123. strMessage += SzLoadString(g_hinst, IDS_ViSupportNumber);
  1124. strMessage += pvi->szSupportNumber;
  1125. strMessage += L"\n";
  1126. }
  1127. if (*pvi->szSupportUrl)
  1128. {
  1129. strMessage += SzLoadString(g_hinst, IDS_ViSupportUrl);
  1130. strMessage += pvi->szSupportUrl;
  1131. strMessage += L"\n";
  1132. }
  1133. if (*pvi->szInstructionsToUser)
  1134. {
  1135. strMessage += SzLoadString(g_hinst, IDS_ViAdditionalInfo);
  1136. strMessage += pvi->szInstructionsToUser;
  1137. strMessage += L"\n";
  1138. }
  1139. FGetConfirmationAndAbortUpgrade(strMessage.c_str());
  1140. }
  1141. // ----------------------------------------------------------------------
  1142. //
  1143. // Function: AbortUpgradeOemComponent
  1144. //
  1145. // Purpose: Abort upgrade because of a fatal error when upgrading an
  1146. // OEM component
  1147. //
  1148. // Arguments:
  1149. // pszPreNT5InfId [in] pre-NT5 InfID of OEM component
  1150. // pszDescription [in] description of OEM component
  1151. // dwError [in] error code
  1152. // dwErrorMessageId [in] ID of error message resource string
  1153. //
  1154. // Returns: None
  1155. //
  1156. // Author: kumarp 17-December-97
  1157. //
  1158. // Notes:
  1159. //
  1160. void AbortUpgradeOemComponent(IN PCWSTR pszPreNT5InfId,
  1161. IN PCWSTR pszDescription,
  1162. IN DWORD dwError,
  1163. IN DWORD dwErrorMessageId)
  1164. {
  1165. tstring strMessage;
  1166. static const WCHAR c_szNewLine[] = L"\n";
  1167. WCHAR szErrorCode[16];
  1168. swprintf(szErrorCode, L"0x%08x", dwError);
  1169. strMessage = SzLoadString(g_hinst, IDS_E_OemComponentUpgrade);
  1170. strMessage = strMessage + c_szNewLine + pszDescription + L"(" +
  1171. pszPreNT5InfId + L"\n\n" +
  1172. SzLoadString(g_hinst, dwErrorMessageId) +
  1173. c_szNewLine + SzLoadString(g_hinst, IDS_E_ErrorCode) + szErrorCode;
  1174. FGetConfirmationAndAbortUpgrade(strMessage.c_str());
  1175. }
  1176. // ----------------------------------------------------------------------
  1177. //
  1178. // Function: FCanDeleteOemService
  1179. //
  1180. // Purpose: Determine if a service can be deleted.
  1181. // OEM upgrade DLLs can prevent a service from being deleted,
  1182. // by specifying a list in the mszServicesNotToBeDeleted
  1183. // member of NetUpgradeData structure.
  1184. //
  1185. // Arguments:
  1186. // pszServiceName [in] name of the service to be spared.
  1187. //
  1188. // Returns: TRUE if can delete, FALSE otherwise
  1189. //
  1190. // Author: kumarp 04-March-98
  1191. //
  1192. // Notes:
  1193. //
  1194. BOOL FCanDeleteOemService(IN PCWSTR pszServiceName)
  1195. {
  1196. BOOL fCanDeleteService = TRUE;
  1197. if (g_pnmaNetMap)
  1198. {
  1199. CNetMapInfo* pnmi;
  1200. size_t cNumNetMapEntries = g_pnmaNetMap->size();
  1201. for (size_t i = 0; i < cNumNetMapEntries; i++)
  1202. {
  1203. pnmi = (CNetMapInfo*) (*g_pnmaNetMap)[i];
  1204. if (FIsSzInMultiSzSafe(pszServiceName,
  1205. pnmi->m_nud.mszServicesNotToBeDeleted))
  1206. {
  1207. fCanDeleteService = FALSE;
  1208. break;
  1209. }
  1210. }
  1211. }
  1212. return fCanDeleteService;
  1213. }