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.

1005 lines
28 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT5.0
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: O E M U P G R D . H
  7. //
  8. // Contents: Functions for OEM upgrade
  9. //
  10. // Notes:
  11. //
  12. // Author: kumarp 13-November-97
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include <setupapi.h>
  18. #include "nsbase.h"
  19. #include "afileint.h"
  20. #include "afilestr.h"
  21. #include "kkutils.h"
  22. #include "ncatl.h"
  23. #include "nceh.h"
  24. #include "ncsetup.h"
  25. #include "netcfgn.h"
  26. #include "oemupgrd.h"
  27. #include "nslog.h"
  28. #include "resource.h"
  29. static const PCWSTR c_aszComponentSections[] =
  30. {
  31. c_szAfSectionNetAdapters,
  32. c_szAfSectionNetProtocols,
  33. c_szAfSectionNetClients,
  34. c_szAfSectionNetServices
  35. };
  36. // ----------------------------------------------------------------------
  37. //
  38. // Function: COemInfo::COemInfo
  39. //
  40. // Purpose: constructor for class COemInfo
  41. //
  42. // Arguments: None
  43. //
  44. // Returns: None
  45. //
  46. // Author: kumarp 24-December-97
  47. //
  48. // Notes:
  49. //
  50. COemInfo::COemInfo()
  51. {
  52. TraceFileFunc(ttidGuiModeSetup);
  53. m_hOemDll = 0;
  54. m_dwError = ERROR_SUCCESS;
  55. m_pfnPostUpgradeInitialize = 0;
  56. m_pfnDoPostUpgradeProcessing = 0;
  57. }
  58. // ----------------------------------------------------------------------
  59. //
  60. // Function: COemInfo::~COemInfo
  61. //
  62. // Purpose: destructor for class COemInfo
  63. //
  64. // Arguments: None
  65. //
  66. // Returns: None
  67. //
  68. // Author: kumarp 24-December-97
  69. //
  70. // Notes:
  71. //
  72. COemInfo::~COemInfo()
  73. {
  74. TraceFileFunc(ttidGuiModeSetup);
  75. DefineFunctionName("COemInfo::~COemInfo");
  76. if (m_hOemDll)
  77. {
  78. TraceTag(ttidNetSetup, "%s: unloading OEM DLL: %S\\%S",
  79. __FUNCNAME__, m_strOemDir.c_str(), m_strOemDll.c_str());
  80. ::FreeLibrary(m_hOemDll);
  81. }
  82. }
  83. // ----------------------------------------------------------------------
  84. //
  85. // Function: HrLoadAndVerifyOemDll
  86. //
  87. // Purpose: Load OEM upgrade DLL and verify that it has
  88. // correct exported functions
  89. //
  90. // Arguments:
  91. // poi [in/out] pointer to COemInfo object
  92. //
  93. // Returns: S_OK on success, otherwise an error code
  94. //
  95. // Author: kumarp 19-February-98
  96. //
  97. // Notes:
  98. //
  99. HRESULT HrLoadAndVerifyOemDll(IN OUT COemInfo* poi)
  100. {
  101. TraceFileFunc(ttidGuiModeSetup);
  102. AssertValidWritePtr(poi);
  103. DefineFunctionName("HrLoadAndVerifyOemDll");
  104. HRESULT hr=S_OK;
  105. if (!poi->m_hOemDll)
  106. {
  107. tstring strOemDllFullPath;
  108. strOemDllFullPath = poi->m_strOemDir;
  109. AppendToPath(&strOemDllFullPath, poi->m_strOemDll.c_str());
  110. TraceTag(ttidNetSetup, "%s: loading OEM DLL: %S",
  111. __FUNCNAME__, strOemDllFullPath.c_str());
  112. hr = HrLoadLibAndGetProcsV(strOemDllFullPath.c_str(),
  113. &poi->m_hOemDll,
  114. c_szPostUpgradeInitialize,
  115. (FARPROC*) &poi->m_pfnPostUpgradeInitialize,
  116. c_szDoPostUpgradeProcessing,
  117. (FARPROC*) &poi->m_pfnDoPostUpgradeProcessing,
  118. NULL);
  119. if (S_OK != hr)
  120. {
  121. FreeLibrary(poi->m_hOemDll);
  122. poi->m_hOemDll = NULL;
  123. poi->m_pfnPostUpgradeInitialize = NULL;
  124. poi->m_pfnDoPostUpgradeProcessing = NULL;
  125. poi->m_dwError = ERROR_DLL_INIT_FAILED;
  126. }
  127. NetSetupLogComponentStatus(poi->m_strOemDll.c_str(),
  128. SzLoadIds (IDS_LOADING), hr);
  129. }
  130. TraceError(__FUNCNAME__, hr);
  131. return hr;
  132. }
  133. // ----------------------------------------------------------------------
  134. //
  135. // Function: HrLoadAndInitOemDll
  136. //
  137. // Purpose: Load OEM DLL, verify that it exports correct functions
  138. // and call DoPostUpgradeInitialize
  139. //
  140. // Arguments:
  141. // poi [in] pointer to COemInfo object
  142. // pNetUpgradeInfo [in] pointer to NetUpgradeInfo
  143. //
  144. // Returns: S_OK on success, otherwise an error code
  145. //
  146. // Author: kumarp 04-March-98
  147. //
  148. // Notes:
  149. //
  150. HRESULT HrLoadAndInitOemDll(IN COemInfo* poi,
  151. IN NetUpgradeInfo* pNetUpgradeInfo)
  152. {
  153. TraceFileFunc(ttidGuiModeSetup);
  154. DefineFunctionName("HrLoadAndInitOemDll");
  155. HRESULT hr=S_OK;
  156. DWORD dwError=ERROR_SUCCESS;
  157. hr = HrLoadAndVerifyOemDll(poi);
  158. VENDORINFO vi;
  159. if (S_OK == hr)
  160. {
  161. if ((ERROR_SUCCESS == poi->m_dwError) &&
  162. poi->m_pfnPostUpgradeInitialize)
  163. {
  164. NC_TRY
  165. {
  166. TraceTag(ttidNetSetup, "%s: initializing OEM DLL: %S\\%S",
  167. __FUNCNAME__, poi->m_strOemDir.c_str(),
  168. poi->m_strOemDll.c_str());
  169. dwError = poi->m_pfnPostUpgradeInitialize(poi->m_strOemDir.c_str(),
  170. pNetUpgradeInfo,
  171. &vi, NULL);
  172. // ensure that this function gets called only once
  173. //
  174. poi->m_pfnPostUpgradeInitialize = NULL;
  175. if (ERROR_SUCCESS == dwError)
  176. {
  177. hr = S_OK;
  178. }
  179. }
  180. NC_CATCH_ALL
  181. {
  182. dwError = ERROR_DLL_INIT_FAILED;
  183. NetSetupLogHrStatusV(S_FALSE,
  184. SzLoadIds (IDS_POSTUPGRADEINIT_EXCEPTION),
  185. poi->m_strOemDll.c_str());
  186. }
  187. poi->m_dwError = dwError;
  188. NetSetupLogComponentStatus(poi->m_strOemDll.c_str(),
  189. SzLoadIds (IDS_POSTUPGRADE_INIT), dwError);
  190. }
  191. else
  192. {
  193. hr = S_FALSE;
  194. }
  195. }
  196. TraceError(__FUNCNAME__, hr);
  197. return hr;
  198. }
  199. typedef list<COemInfo*> TOemInfoList;
  200. typedef TOemInfoList::iterator TOemInfoListIter;
  201. static TOemInfoList* g_plOemInfo;
  202. // ----------------------------------------------------------------------
  203. //
  204. // Function: HrGetOemInfo
  205. //
  206. // Purpose: Locate (create if not found) and return COemInfo
  207. // for the given dir & dll
  208. //
  209. // Arguments:
  210. // pszOemDir [in] full path to OEM temp dir
  211. // pszOemDll [in] full path to OEM DLL
  212. // ppoi [out] pointer to pointer to COemInfo object
  213. //
  214. // Returns: S_OK on success, otherwise an error code
  215. //
  216. // Author: kumarp 04-March-98
  217. //
  218. // Notes:
  219. //
  220. HRESULT HrGetOemInfo(IN PCWSTR pszOemDir,
  221. IN PCWSTR pszOemDll,
  222. OUT COemInfo** ppoi)
  223. {
  224. TraceFileFunc(ttidGuiModeSetup);
  225. DefineFunctionName("HrGetOemInfo");
  226. HRESULT hr=E_OUTOFMEMORY;
  227. *ppoi = NULL;
  228. if (!g_plOemInfo)
  229. {
  230. g_plOemInfo = new TOemInfoList;
  231. }
  232. if (g_plOemInfo)
  233. {
  234. TOemInfoListIter pos;
  235. COemInfo* poi;
  236. for (pos=g_plOemInfo->begin(); pos != g_plOemInfo->end(); pos++)
  237. {
  238. poi = (COemInfo*) *pos;
  239. if (!lstrcmpiW(pszOemDir, poi->m_strOemDir.c_str()) &&
  240. !lstrcmpiW(pszOemDll, poi->m_strOemDll.c_str()))
  241. {
  242. *ppoi = poi;
  243. hr = S_OK;
  244. break;
  245. }
  246. }
  247. if (!*ppoi)
  248. {
  249. hr = E_OUTOFMEMORY;
  250. *ppoi = new COemInfo;
  251. if (*ppoi)
  252. {
  253. (*ppoi)->m_strOemDir = pszOemDir;
  254. (*ppoi)->m_strOemDll = pszOemDll;
  255. g_plOemInfo->push_back(*ppoi);
  256. hr = S_OK;
  257. }
  258. }
  259. }
  260. TraceError(__FUNCNAME__, hr);
  261. return hr;
  262. }
  263. // ----------------------------------------------------------------------
  264. //
  265. // Function: CleanupOemInfo
  266. //
  267. // Purpose: Cleanup OEM data
  268. //
  269. // Arguments: None
  270. //
  271. // Returns: None
  272. //
  273. // Author: kumarp 04-March-98
  274. //
  275. // Notes:
  276. //
  277. void CleanupOemInfo()
  278. {
  279. TraceFileFunc(ttidGuiModeSetup);
  280. if (g_plOemInfo)
  281. {
  282. FreeCollectionAndItem(*g_plOemInfo);
  283. g_plOemInfo = 0;
  284. }
  285. }
  286. // ----------------------------------------------------------------------
  287. //
  288. // Function: HrProcessOemComponent
  289. //
  290. // Purpose: Process upgrade an OEM component in the following steps
  291. // - if OEM upgrade DLL is not loaded, load it and
  292. // verify that it exports the required functions
  293. // - call DoPostUpgradeInitialize only once
  294. // - call DoPostUpgradeProcessing
  295. //
  296. // Arguments:
  297. // hwndParent [in] handle of parent window
  298. // pszOemDir [in] OEM working temp dir
  299. // pszOemDll [in] full path to OEM DLL
  300. // pNetUpgradeInfo [in] pointer to NetUpgradeInfo
  301. // hkeyParams [in] handle of Parameters regkey
  302. // pszPreNT5Instance [in] pre-NT5 instance e.g. IEEPRO3
  303. // pszNT5InfId [in] NT5 InfID/PnpID
  304. // hinfAnswerFile [in] handle of AnswerFile
  305. // pszSectionName [in] name of OEM Section
  306. //
  307. // Returns: S_OK on success, otherwise an error code
  308. //
  309. // Author: kumarp 04-March-98
  310. //
  311. // Notes:
  312. //
  313. HRESULT HrProcessOemComponent(IN HWND hwndParent,
  314. IN PCWSTR pszOemDir,
  315. IN PCWSTR pszOemDll,
  316. IN NetUpgradeInfo* pNetUpgradeInfo,
  317. IN HKEY hkeyParams,
  318. IN PCWSTR pszPreNT5Instance,
  319. IN PCWSTR pszNT5InfId,
  320. IN HINF hinfAnswerFile,
  321. IN PCWSTR pszSectionName)
  322. {
  323. TraceFileFunc(ttidGuiModeSetup);
  324. DefineFunctionName("HrProcessOemComponent");
  325. VENDORINFO vi;
  326. TraceTag(ttidNetSetup,
  327. "%s: Processing OEM component: %S, instance: %S",
  328. __FUNCNAME__, pszNT5InfId, pszPreNT5Instance);
  329. HRESULT hr=S_OK;
  330. COemInfo* poi;
  331. hr = HrGetOemInfo(pszOemDir, pszOemDll, &poi);
  332. DWORD dwError;
  333. DWORD dwErrorMessageId=0;
  334. if (S_OK == hr)
  335. {
  336. hr = HrLoadAndInitOemDll(poi, pNetUpgradeInfo);
  337. }
  338. if ((S_OK == hr) && (ERROR_SUCCESS == poi->m_dwError))
  339. {
  340. Assert(poi->m_pfnDoPostUpgradeProcessing);
  341. NC_TRY
  342. {
  343. TraceTag(ttidNetSetup,
  344. "%s: calling DoPostUpgradeProcessing in %S\\%S for %S",
  345. __FUNCNAME__, poi->m_strOemDll.c_str(),
  346. poi->m_strOemDir.c_str(), pszNT5InfId);
  347. dwError =
  348. poi->m_pfnDoPostUpgradeProcessing(hwndParent, hkeyParams,
  349. pszPreNT5Instance,
  350. pszNT5InfId, hinfAnswerFile,
  351. pszSectionName, &vi, NULL);
  352. NetSetupLogComponentStatus(pszNT5InfId,
  353. SzLoadIds (IDS_POSTUPGRADE_PROCESSING), dwError);
  354. }
  355. NC_CATCH_ALL
  356. {
  357. dwError = ERROR_OPERATION_ABORTED;
  358. NetSetupLogHrStatusV(S_FALSE,
  359. SzLoadIds (IDS_POSTUPGRADEPROC_EXCEPTION), pszOemDll,
  360. pszNT5InfId);
  361. }
  362. if (dwError == ERROR_SUCCESS)
  363. {
  364. hr = S_OK;
  365. }
  366. else
  367. {
  368. hr = HRESULT_FROM_WIN32(dwError);
  369. }
  370. poi->m_dwError = dwError;
  371. NetSetupLogComponentStatus(pszOemDll,
  372. SzLoadIds (IDS_POSTUPGRADE_PROCESSING),
  373. hr);
  374. }
  375. else
  376. {
  377. hr = HRESULT_FROM_WIN32(poi->m_dwError);
  378. }
  379. TraceError(__FUNCNAME__, hr);
  380. return hr;
  381. }
  382. // ----------------------------------------------------------------------
  383. //
  384. // Function: MapProductFlagToProductType
  385. //
  386. // Purpose: Map Product flag (NSF_*) to PRODUCTTYPE
  387. //
  388. // Arguments:
  389. // dwUpgradeFromProductFlag [in] product flag
  390. //
  391. // Returns: PRODUCTTYPE
  392. //
  393. // Author: kumarp 04-March-98
  394. //
  395. // Notes:
  396. //
  397. PRODUCTTYPE MapProductFlagToProductType(IN DWORD dwUpgradeFromProductFlag)
  398. {
  399. TraceFileFunc(ttidGuiModeSetup);
  400. PRODUCTTYPE pt;
  401. switch (dwUpgradeFromProductFlag)
  402. {
  403. case NSF_WINNT_SVR_UPGRADE:
  404. case NSF_WINNT_SBS_UPGRADE:
  405. pt = NT_SERVER;
  406. break;
  407. case NSF_WINNT_WKS_UPGRADE:
  408. pt = NT_WORKSTATION;
  409. break;
  410. default:
  411. pt = UNKNOWN;
  412. break;
  413. }
  414. return pt;
  415. }
  416. // ----------------------------------------------------------------------
  417. //
  418. // Function: GetCurrentProductBuildNumber
  419. //
  420. // Purpose: Get build number of NT on which we are running
  421. //
  422. // Arguments: None
  423. //
  424. // Returns: build number
  425. //
  426. // Author: kumarp 04-March-98
  427. //
  428. // Notes:
  429. //
  430. DWORD GetCurrentProductBuildNumber()
  431. {
  432. TraceFileFunc(ttidGuiModeSetup);
  433. OSVERSIONINFO osv;
  434. osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  435. GetVersionEx(&osv);
  436. return osv.dwBuildNumber;
  437. }
  438. // ----------------------------------------------------------------------
  439. //
  440. // Function: MapProductFlavorToProductType
  441. //
  442. // Purpose: Map from PRODUCT_FLAVOR to PRODUCTTYPE
  443. //
  444. // Arguments:
  445. // pf [in] product flavor
  446. //
  447. // Returns: product type
  448. //
  449. // Author: kumarp 04-March-98
  450. //
  451. // Notes:
  452. //
  453. PRODUCTTYPE MapProductFlavorToProductType(IN PRODUCT_FLAVOR pf)
  454. {
  455. TraceFileFunc(ttidGuiModeSetup);
  456. PRODUCTTYPE pt;
  457. switch (pf)
  458. {
  459. case PF_WORKSTATION:
  460. pt = NT_WORKSTATION;
  461. break;
  462. case PF_SERVER:
  463. pt = NT_SERVER;
  464. break;
  465. }
  466. return pt;
  467. }
  468. // ----------------------------------------------------------------------
  469. //
  470. // Function: GetCurrentProductInfo
  471. //
  472. // Purpose: Get info. on the product on which we are running
  473. //
  474. // Arguments: None
  475. //
  476. // Returns: pointer to
  477. //
  478. // Author: kumarp 04-March-98
  479. //
  480. // Notes:
  481. //
  482. ProductInfo GetCurrentProductInfo()
  483. {
  484. TraceFileFunc(ttidGuiModeSetup);
  485. ProductInfo pi;
  486. pi.dwBuildNumber = GetCurrentProductBuildNumber();
  487. PRODUCT_FLAVOR pf;
  488. GetProductFlavor(NULL, &pf);
  489. pi.ProductType = MapProductFlavorToProductType(pf);
  490. return pi;
  491. }
  492. // ----------------------------------------------------------------------
  493. //
  494. // Function: HrSetupGetFieldCount
  495. //
  496. // Purpose: Wrapper for SetupGetFieldCount
  497. //
  498. // Arguments:
  499. // pic [in] pointer to INFCONTEXT
  500. // pcNumFields [out] pointer to number of fields
  501. //
  502. // Returns: S_OK on success, otherwise an error code
  503. //
  504. // Author: kumarp 04-March-98
  505. //
  506. // Notes:
  507. //
  508. HRESULT HrSetupGetFieldCount(IN INFCONTEXT* pic,
  509. OUT UINT* pcNumFields)
  510. {
  511. TraceFileFunc(ttidGuiModeSetup);
  512. HRESULT hr=S_OK;
  513. if (!(*pcNumFields = SetupGetFieldCount(pic)))
  514. {
  515. hr = HrFromLastWin32Error();
  516. }
  517. return hr;
  518. }
  519. // ----------------------------------------------------------------------
  520. //
  521. // Function: HrAfGetInfToRunValue
  522. //
  523. // Purpose: Helper fn. to parse and locate the INF/section to run
  524. // Before/After installing an OEM component
  525. //
  526. // Arguments:
  527. // hinfAnswerFile [in] handle of AnswerFile
  528. // szAnswerFileName [in] name of AnswerFile
  529. // szParamsSection [in] name of Params section
  530. // itrType [in] type of InfToRun key (Before/After)
  531. // pstrInfToRun [out] pointer to the name of INF to run
  532. // pstrSectionToRun [out] pointer to the name of section to run
  533. //
  534. // Returns: S_OK on success, otherwise an error code
  535. //
  536. // Author: kumarp 04-March-98
  537. //
  538. // Notes:
  539. //
  540. HRESULT HrAfGetInfToRunValue(IN HINF hinfAnswerFile,
  541. IN PCWSTR szAnswerFileName,
  542. IN PCWSTR szParamsSection,
  543. IN EInfToRunValueType itrType,
  544. OUT tstring* pstrInfToRun,
  545. OUT tstring* pstrSectionToRun,
  546. OUT tstring* pstrInfToRunType)
  547. {
  548. TraceFileFunc(ttidGuiModeSetup);
  549. DefineFunctionName("HrAfGetInfToRunValue");
  550. HRESULT hr=S_OK;
  551. INFCONTEXT ic, ic2;
  552. PCWSTR szInfToRunKey;
  553. if (itrType == I2R_BeforeInstall)
  554. {
  555. szInfToRunKey = c_szInfToRunBeforeInstall;
  556. }
  557. else
  558. {
  559. szInfToRunKey = c_szInfToRunAfterInstall;
  560. }
  561. *pstrInfToRunType = szInfToRunKey;
  562. hr = HrSetupFindFirstLine(hinfAnswerFile, szParamsSection,
  563. c_szAfOemSection, &ic);
  564. if (S_OK == hr)
  565. {
  566. tstring strOemSection;
  567. hr = HrSetupGetStringField(ic, 1, &strOemSection);
  568. if (S_OK == hr)
  569. {
  570. hr = HrSetupFindFirstLine(hinfAnswerFile, strOemSection.c_str(),
  571. szInfToRunKey, &ic2);
  572. if (S_OK == hr)
  573. {
  574. UINT cNumFields=0;
  575. hr = HrSetupGetFieldCount(&ic2, &cNumFields);
  576. if (S_OK == hr)
  577. {
  578. if (2 == cNumFields)
  579. {
  580. hr = HrSetupGetStringField(ic2, 1, pstrInfToRun);
  581. if (S_OK == hr)
  582. {
  583. if (pstrInfToRun->empty())
  584. {
  585. if (itrType == I2R_AfterInstall)
  586. {
  587. *pstrInfToRun = szAnswerFileName;
  588. }
  589. else
  590. {
  591. hr = SPAPI_E_LINE_NOT_FOUND;
  592. }
  593. }
  594. if (S_OK == hr)
  595. {
  596. hr = HrSetupGetStringField(ic2, 2,
  597. pstrSectionToRun);
  598. }
  599. }
  600. }
  601. else
  602. {
  603. hr = SPAPI_E_LINE_NOT_FOUND;
  604. }
  605. }
  606. }
  607. else
  608. {
  609. hr = S_FALSE;
  610. }
  611. }
  612. }
  613. TraceErrorOptional(__FUNCNAME__, hr,
  614. ((SPAPI_E_LINE_NOT_FOUND == hr) || (S_FALSE == hr)));
  615. return hr;
  616. }
  617. // ----------------------------------------------------------------------
  618. //
  619. // Function: HrProcessInfToRunForComponent
  620. //
  621. // Purpose: Run INF/section indicated by InfToRunBefore/AfterInstall
  622. // key of a given OEM component
  623. //
  624. // Arguments:
  625. // hinfAnswerFile [in] handle of AnswerFile
  626. // szAnswerFileName [in] name of AnswerFile
  627. // szParamsSection [in] parameters section of a component
  628. // itrType [in] type of InfToRun key (Before/After)
  629. // hwndParent [in] handle of parent window
  630. // hkeyParams [in] handle of Parameters regkey
  631. // fQuietInstall [in] TRUE if we do not want any UI to popup
  632. //
  633. // Returns: S_OK on success, otherwise an error code
  634. //
  635. // Author: kumarp 04-March-98
  636. //
  637. // Notes:
  638. //
  639. HRESULT HrProcessInfToRunForComponent(IN HINF hinfAnswerFile,
  640. IN PCWSTR szAnswerFileName,
  641. IN PCWSTR szParamsSection,
  642. IN EInfToRunValueType itrType,
  643. IN HWND hwndParent,
  644. IN HKEY hkeyParams,
  645. IN BOOL fQuietInstall)
  646. {
  647. TraceFileFunc(ttidGuiModeSetup);
  648. DefineFunctionName("HrProcessInfToRunForComponent");
  649. HRESULT hr=S_OK;
  650. tstring strInfToRun;
  651. tstring strSectionToRun;
  652. tstring strInfToRunType;
  653. hr = HrAfGetInfToRunValue(hinfAnswerFile, szAnswerFileName,
  654. szParamsSection, itrType,
  655. &strInfToRun, &strSectionToRun, &strInfToRunType);
  656. if (S_OK == hr)
  657. {
  658. hr = HrInstallFromInfSectionInFile(hwndParent,
  659. strInfToRun.c_str(),
  660. strSectionToRun.c_str(),
  661. hkeyParams,
  662. fQuietInstall);
  663. NetSetupLogHrStatusV(hr, SzLoadIds (IDS_STATUS_OF_APPLYING),
  664. szParamsSection,
  665. strInfToRunType.c_str(),
  666. strSectionToRun.c_str(),
  667. strInfToRun.c_str());
  668. }
  669. else if (SPAPI_E_LINE_NOT_FOUND == hr)
  670. {
  671. hr = S_FALSE;
  672. }
  673. TraceErrorOptional(__FUNCNAME__, hr, (S_FALSE == hr));
  674. return hr;
  675. }
  676. // ----------------------------------------------------------------------
  677. //
  678. // Function: HrProcessInfToRunBeforeInstall
  679. //
  680. // Purpose: Process the answerfile and run any INFs/sections
  681. // indicated by InfToRunBeforeInstall keys
  682. //
  683. // Arguments:
  684. // hwndParent [in] handle of parent window
  685. // szAnswerFileName [in] name of AnswerFile
  686. //
  687. // Returns: S_OK on success, otherwise an error code
  688. //
  689. // Author: kumarp 04-March-98
  690. //
  691. // Notes:
  692. //
  693. HRESULT HrProcessInfToRunBeforeInstall(IN HWND hwndParent,
  694. IN PCWSTR szAnswerFileName)
  695. {
  696. TraceFileFunc(ttidGuiModeSetup);
  697. AssertValidReadPtr(szAnswerFileName);
  698. DefineFunctionName("HrRunInfToRunBeforeInstall");
  699. HRESULT hr;
  700. HINF hinf;
  701. hr = HrSetupOpenInfFile(szAnswerFileName, NULL,
  702. INF_STYLE_OLDNT | INF_STYLE_WIN4,
  703. NULL, &hinf);
  704. if (S_OK == hr)
  705. {
  706. PCWSTR szSection;
  707. INFCONTEXT ic;
  708. tstring strParamsSection;
  709. for (int iSection=0; iSection < celems(c_aszComponentSections); iSection++)
  710. {
  711. szSection = c_aszComponentSections[iSection];
  712. TraceTag(ttidNetSetup, "%s: Processing section [%S]",
  713. __FUNCNAME__, szSection);
  714. hr = HrSetupFindFirstLine(hinf, szSection, NULL, &ic);
  715. if (S_OK == hr)
  716. {
  717. do
  718. {
  719. hr = HrSetupGetStringField(ic, 1, &strParamsSection);
  720. if (S_OK == hr)
  721. {
  722. hr = HrProcessInfToRunForComponent(hinf, szAnswerFileName,
  723. strParamsSection.c_str(),
  724. I2R_BeforeInstall,
  725. hwndParent,
  726. NULL, // HKR
  727. TRUE); // fQuietInstall
  728. if (SUCCEEDED(hr))
  729. {
  730. hr = HrSetupFindNextLine(ic, &ic);
  731. }
  732. }
  733. } while (S_OK == hr);
  734. }
  735. else if ((SPAPI_E_SECTION_NOT_FOUND == hr) ||
  736. (SPAPI_E_LINE_NOT_FOUND == hr))
  737. {
  738. hr = S_OK;
  739. }
  740. }
  741. SetupCloseInfFile(hinf);
  742. }
  743. if (S_FALSE == hr)
  744. {
  745. hr = S_OK;
  746. }
  747. TraceError(__FUNCNAME__, hr);
  748. return hr;
  749. }
  750. // ----------------------------------------------------------------------
  751. //
  752. // Function: HrNetSetupCopyOemInfs
  753. //
  754. // Purpose: Copies all OEM INF files using SetupCopyOemInf
  755. //
  756. // Arguments:
  757. // szAnswerFileName [in] name of AnswerFile
  758. //
  759. // Returns: S_OK on success, otherwise an error code
  760. //
  761. // Author: kumarp 12-May-98
  762. //
  763. // Notes:
  764. //
  765. HRESULT HrNetSetupCopyOemInfs(IN PCWSTR szAnswerFileName)
  766. {
  767. TraceFileFunc(ttidGuiModeSetup);
  768. DefineFunctionName("HrNetSetupCopyOemInfs");
  769. TraceTag(ttidNetSetup, "----> entering %s", __FUNCNAME__);
  770. AssertValidReadPtr(szAnswerFileName);
  771. HRESULT hr=S_OK;
  772. HINF hinf=NULL;
  773. INFCONTEXT ic;
  774. tstring strParamsSection;
  775. tstring strOemDir;
  776. tstring strOemInf;
  777. WCHAR szInfNameAfterCopy[MAX_PATH+1];
  778. hr = HrSetupOpenInfFile(szAnswerFileName, NULL,
  779. INF_STYLE_OLDNT | INF_STYLE_WIN4,
  780. NULL, &hinf);
  781. if (S_OK == hr)
  782. {
  783. PCWSTR szSection;
  784. for (int iSection=0; iSection < celems(c_aszComponentSections); iSection++)
  785. {
  786. szSection = c_aszComponentSections[iSection];
  787. TraceTag(ttidNetSetup, "%s: Processing section [%S]",
  788. __FUNCNAME__, szSection);
  789. hr = HrSetupFindFirstLine(hinf, szSection, NULL, &ic);
  790. if (S_OK == hr)
  791. {
  792. do
  793. {
  794. hr = HrSetupGetStringField(ic, 1, &strParamsSection);
  795. if (S_OK == hr)
  796. {
  797. hr = HrSetupGetFirstString(hinf, strParamsSection.c_str(),
  798. c_szAfOemInf, &strOemInf);
  799. if (S_OK == hr)
  800. {
  801. hr = HrSetupGetFirstString(hinf,
  802. strParamsSection.c_str(),
  803. c_szAfOemDir,
  804. &strOemDir);
  805. if (S_OK == hr)
  806. {
  807. AppendToPath(&strOemDir, strOemInf.c_str());
  808. TraceTag(ttidNetSetup,
  809. "%s: calling SetupCopyOemInf for %S",
  810. __FUNCNAME__, strOemDir.c_str());
  811. if (SetupCopyOEMInf(strOemDir.c_str(),
  812. NULL, SPOST_PATH,
  813. 0, szInfNameAfterCopy,
  814. MAX_PATH, NULL, NULL))
  815. {
  816. ShowProgressMessage(
  817. L"...%s was copied as %s",
  818. strOemDir.c_str(),
  819. szInfNameAfterCopy);
  820. NetSetupLogHrStatusV(S_OK,
  821. SzLoadIds (IDS_OEMINF_COPY),
  822. strOemDir.c_str(),
  823. szInfNameAfterCopy);
  824. }
  825. else
  826. {
  827. hr = HrFromLastWin32Error();
  828. ShowProgressMessage(
  829. L"...SetupCopyOemInf failed for %s: error code: 0x%08x",
  830. strOemDir.c_str(), hr);
  831. NetSetupLogComponentStatus(strOemDir.c_str(),
  832. SzLoadIds (IDS_CALLING_COPY_OEM_INF), hr);
  833. }
  834. }
  835. else if (SPAPI_E_LINE_NOT_FOUND == hr)
  836. {
  837. TraceTag(ttidNetSetup,
  838. "%s: Found %S but not %S!!",
  839. __FUNCNAME__, c_szAfOemInf, c_szAfOemDir);
  840. hr = S_OK;
  841. }
  842. }
  843. else
  844. {
  845. if (SPAPI_E_LINE_NOT_FOUND == hr)
  846. {
  847. hr = S_OK;
  848. }
  849. }
  850. }
  851. // ignore all earlier errors, see if we can do the
  852. // next item right
  853. //
  854. hr = HrSetupFindNextLine(ic, &ic);
  855. } while (S_OK == hr);
  856. }
  857. else if ((SPAPI_E_SECTION_NOT_FOUND == hr) ||
  858. (SPAPI_E_LINE_NOT_FOUND == hr))
  859. {
  860. hr = S_OK;
  861. }
  862. }
  863. SetupCloseInfFile(hinf);
  864. }
  865. if (S_FALSE == hr)
  866. {
  867. hr = S_OK;
  868. }
  869. TraceError(__FUNCNAME__, hr);
  870. return hr;
  871. }