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.

5473 lines
148 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: A F I L E I N T . C P P
  7. //
  8. // Contents: Functions that operate on the answer file.
  9. //
  10. // Notes:
  11. //
  12. // Author: kumarp 25-November-97
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "afileint.h"
  18. #include "afilestr.h"
  19. #include "afilexp.h"
  20. #include "errorlog.h"
  21. #include "kkenet.h"
  22. #include "kkreg.h"
  23. #include "kkutils.h"
  24. #include "ncerror.h"
  25. #include "ncnetcfg.h"
  26. #include "netcfgn.h"
  27. #include "netcfgp.h"
  28. #include "nsbase.h"
  29. #include "resource.h"
  30. #include "upgrade.h"
  31. #include "ncreg.h"
  32. #include "ncmisc.h"
  33. #include "oemupgrd.h"
  34. #include "ncsetup.h"
  35. #include "nsexports.h"
  36. #include "nslog.h"
  37. #include "netshell.h"
  38. #include "ncnetcon.h"
  39. #include "lancmn.h"
  40. #include "compid.h"
  41. #include "nceh.h"
  42. // ----------------------------------------------------------------------
  43. // String constants
  44. // ----------------------------------------------------------------------
  45. extern const WCHAR c_szYes[];
  46. extern const WCHAR c_szNo[];
  47. extern const WCHAR c_szDevice[];
  48. extern const WCHAR c_szInfId_MS_GPC[];
  49. extern const WCHAR c_szInfId_MS_MSClient[];
  50. extern const WCHAR c_szInfId_MS_RasCli[];
  51. extern const WCHAR c_szInfId_MS_RasSrv[];
  52. extern const WCHAR c_szInfId_MS_Server[];
  53. extern const WCHAR c_szInfId_MS_TCPIP[];
  54. const WCHAR sz_DLC[] = L"MS_DLC";
  55. const WCHAR sz_DLC_NT40_Inf[] = L"system32\\oemnxpdl.inf";
  56. const WCHAR sz_DLC_Win2k_Inf[] = L"inf\\netdlc.inf";
  57. const WCHAR sz_DLC_Win2k_Pnf[] = L"inf\\netdlc.pnf";
  58. const WCHAR sz_DLC_Sys[] = L"system32\\drivers\\dlc.sys";
  59. const WCHAR sz_DLC_Dll[] = L"system32\\dlcapi.dll";
  60. // ----------------------------------------------------------------------
  61. // Forward declarations
  62. // ----------------------------------------------------------------------
  63. //Misc. helper functions
  64. PCWSTR GetDisplayModeStr(IN EPageDisplayMode pdmDisplay);
  65. EPageDisplayMode MapToDisplayMode(IN PCWSTR pszDisplayMode);
  66. DWORD MapToUpgradeFlag(IN PCWSTR pszUpgradeFromProduct);
  67. HRESULT HrGetProductInfo (LPDWORD pdwUpgradeFrom,
  68. LPDWORD pdwBuildNo);
  69. INTERFACE_TYPE GetBusTypeFromName(IN PCWSTR pszBusType);
  70. void AddAnswerFileError(IN DWORD dwErrorId);
  71. void AddAnswerFileError(IN PCWSTR pszSectionName, IN DWORD dwErrorId);
  72. void AddAnswerFileError(IN PCWSTR pszSectionName,
  73. IN PCWSTR pszKeyName,
  74. IN DWORD dwErrorId);
  75. CNetComponent* FindComponentInList(IN CNetComponentList* pnclComponents,
  76. IN PCWSTR szInfID);
  77. HRESULT HrRemoveNetComponents(IN INetCfg* pnc,
  78. IN TStringList* pslComponents);
  79. HRESULT HrSetLanConnectionName(IN GUID* pguidAdapter,
  80. IN PCWSTR szConnectionName);
  81. VOID RemoveFiles (IN PCWSTR szInfID);
  82. // ----------------------------------------------------------------------
  83. CErrorLog* g_elAnswerFileErrors;
  84. // ======================================================================
  85. // class CNetInstallInfo
  86. // ======================================================================
  87. CNetInstallInfo::CNetInstallInfo()
  88. {
  89. TraceFileFunc(ttidGuiModeSetup);
  90. m_pwifAnswerFile = NULL;
  91. m_pnaiAdaptersPage = NULL;
  92. m_pnpiProtocolsPage = NULL;
  93. m_pnsiServicesPage = NULL;
  94. m_pnciClientsPage = NULL;
  95. m_pnbiBindingsPage = NULL;
  96. m_dwUpgradeFlag = 0;
  97. m_dwBuildNumber = 0;
  98. m_fProcessPageSections = TRUE;
  99. m_fUpgrade = FALSE;
  100. m_fInstallDefaultComponents = FALSE;
  101. ZeroMemory(&m_nui, sizeof(m_nui));
  102. m_hinfAnswerFile = NULL;
  103. }
  104. // ----------------------------------------------------------------------
  105. //
  106. // Function: CNetInstallInfo::CNetInstallInfo
  107. //
  108. // Purpose: constructor for class CNetInstallInfo
  109. //
  110. // Arguments: None
  111. //
  112. // Returns: None
  113. //
  114. // Author: kumarp 25-November-97
  115. //
  116. // Notes:
  117. //
  118. // static
  119. HRESULT
  120. CNetInstallInfo::HrCreateInstance (
  121. IN PCWSTR pszAnswerFileName,
  122. OUT CNetInstallInfo** ppObj)
  123. {
  124. TraceFileFunc(ttidGuiModeSetup);
  125. HRESULT hr;
  126. CNetInstallInfo* pObj;
  127. Assert(ppObj);
  128. *ppObj = NULL;
  129. hr = E_OUTOFMEMORY;
  130. pObj = new CNetInstallInfo ();
  131. if (pObj)
  132. {
  133. g_elAnswerFileErrors = new CErrorLog;
  134. pObj->m_pnaiAdaptersPage = new CNetAdaptersPage(pObj);
  135. pObj->m_pnpiProtocolsPage = new CNetProtocolsPage(pObj);
  136. pObj->m_pnsiServicesPage = new CNetServicesPage(pObj);
  137. pObj->m_pnciClientsPage = new CNetClientsPage(pObj);
  138. pObj->m_pnbiBindingsPage = new CNetBindingsPage(pObj);
  139. if (g_elAnswerFileErrors &&
  140. pObj->m_pnaiAdaptersPage &&
  141. pObj->m_pnpiProtocolsPage &&
  142. pObj->m_pnsiServicesPage &&
  143. pObj->m_pnciClientsPage &&
  144. pObj->m_pnbiBindingsPage)
  145. {
  146. if ( pszAnswerFileName )
  147. {
  148. hr = pObj->HrInitFromAnswerFile (pszAnswerFileName);
  149. }
  150. else
  151. {
  152. hr = pObj->InitRepairMode();
  153. }
  154. if (S_OK == hr)
  155. {
  156. CBindingAction::m_pnii = pObj;
  157. *ppObj = pObj;
  158. }
  159. }
  160. if (S_OK != hr)
  161. {
  162. delete pObj;
  163. }
  164. }
  165. return hr;
  166. }
  167. // ----------------------------------------------------------------------
  168. //
  169. // Function: CNetInstallInfo::~CNetInstallInfo
  170. //
  171. // Purpose: destructor for class CNetInstallInfo
  172. //
  173. // Arguments: None
  174. //
  175. // Returns: None
  176. //
  177. // Author: kumarp 25-November-97
  178. //
  179. // Notes:
  180. //
  181. CNetInstallInfo::~CNetInstallInfo()
  182. {
  183. TraceFileFunc(ttidGuiModeSetup);
  184. if (IsValidHandle(m_hinfAnswerFile))
  185. {
  186. SetupCloseInfFile (m_hinfAnswerFile);
  187. }
  188. delete m_pnaiAdaptersPage;
  189. delete m_pnpiProtocolsPage;
  190. delete m_pnsiServicesPage;
  191. delete m_pnciClientsPage;
  192. delete m_pnbiBindingsPage;
  193. if ( m_pwifAnswerFile )
  194. {
  195. delete m_pwifAnswerFile;
  196. }
  197. delete g_elAnswerFileErrors;
  198. g_elAnswerFileErrors = NULL;
  199. }
  200. HRESULT CNetInstallInfo::InitRepairMode (VOID)
  201. {
  202. m_fProcessPageSections = FALSE;
  203. m_fInstallDefaultComponents = FALSE;
  204. m_fUpgrade = TRUE;
  205. HrGetProductInfo( &m_dwUpgradeFlag, &m_dwBuildNumber );
  206. m_nui.From.ProductType = m_nui.To.ProductType = MapProductFlagToProductType( m_dwUpgradeFlag );
  207. m_nui.From.dwBuildNumber = m_nui.To.dwBuildNumber = m_dwBuildNumber;
  208. m_dwUpgradeFlag |= NSF_PRIMARYINSTALL;
  209. return S_OK;
  210. }
  211. // ----------------------------------------------------------------------
  212. //
  213. // Function: CNetInstallInfo::HrInitFromAnswerFile
  214. //
  215. // Purpose: Initialize internal data by reading answer-file
  216. //
  217. // Arguments:
  218. // pwifAnswerFile [in] pointer to answer-file
  219. //
  220. // Returns: S_OK on success, otherwise an error code
  221. //
  222. // Author: kumarp 25-November-97
  223. //
  224. // Notes:
  225. //
  226. HRESULT CNetInstallInfo::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
  227. {
  228. TraceFileFunc(ttidGuiModeSetup);
  229. DefineFunctionName("CNetInstallInfo::HrInitFromAnswerFile(CWInfFile*)");
  230. TraceFunctionEntry(ttidNetSetup);
  231. AssertValidReadPtr(pwifAnswerFile);
  232. HRESULT hr, hrReturn=S_OK;
  233. tstring strUpgradeFromProduct;
  234. DWORD dwUpgradeFromProduct = 0;
  235. m_pwifAnswerFile = pwifAnswerFile;
  236. //Find upgrade info:
  237. CWInfSection* pwisNetworking;
  238. pwisNetworking = pwifAnswerFile->FindSection(c_szAfSectionNetworking);
  239. if (!pwisNetworking)
  240. {
  241. ShowProgressMessage(L"[%s] section is missing",
  242. c_szAfSectionNetworking);
  243. hrReturn = NETSETUP_E_NO_ANSWERFILE;
  244. goto return_from_function;
  245. }
  246. // ProcessPageSections
  247. m_fProcessPageSections =
  248. pwisNetworking->GetBoolValue(c_szAfProcessPageSections, TRUE);
  249. //UpgradeFromProduct
  250. strUpgradeFromProduct =
  251. pwisNetworking->GetStringValue(c_szAfUpgradeFromProduct, c_szEmpty);
  252. if (strUpgradeFromProduct.empty())
  253. {
  254. // UpgradeFromProduct is missing, implies not an upgrade
  255. m_fUpgrade = FALSE;
  256. m_fInstallDefaultComponents = TRUE;
  257. // pwisNetworking->GetBoolValue(c_szAfInstallDefaultComponents, FALSE);
  258. }
  259. else
  260. {
  261. dwUpgradeFromProduct = MapToUpgradeFlag(strUpgradeFromProduct.c_str());
  262. m_dwUpgradeFlag |= dwUpgradeFromProduct;
  263. if (!dwUpgradeFromProduct)
  264. {
  265. AddAnswerFileError(c_szAfSectionNetworking,
  266. c_szAfUpgradeFromProduct,
  267. IDS_E_AF_InvalidValueForThisKey);
  268. hrReturn = NETSETUP_E_ANS_FILE_ERROR;
  269. goto return_from_function;
  270. }
  271. else
  272. {
  273. m_fUpgrade = TRUE;
  274. }
  275. }
  276. // installing using an answerfile is ALWAYS a primary-install
  277. //
  278. m_dwUpgradeFlag |= NSF_PRIMARYINSTALL;
  279. //BuildNumber
  280. DWORD dwDummy;
  281. dwDummy = 0;
  282. m_dwBuildNumber = pwisNetworking->GetIntValue(c_szAfBuildNumber, dwDummy);
  283. if (m_fUpgrade && !m_dwBuildNumber)
  284. {
  285. AddAnswerFileError(c_szAfSectionNetworking,
  286. c_szAfBuildNumber,
  287. IDS_E_AF_InvalidValueForThisKey);
  288. hrReturn = NETSETUP_E_ANS_FILE_ERROR;
  289. }
  290. m_nui.From.ProductType = MapProductFlagToProductType(dwUpgradeFromProduct);
  291. m_nui.From.dwBuildNumber = m_dwBuildNumber;
  292. m_nui.To = GetCurrentProductInfo();
  293. // the following two keys are currently unsupported
  294. //
  295. pwisNetworking->GetStringListValue(c_szAfNetComponentsToRemove,
  296. m_slNetComponentsToRemove);
  297. if (!m_fProcessPageSections)
  298. {
  299. // we are upgrading from NT5
  300. // no other sections need to be parsed
  301. TraceTag(ttidNetSetup, "%s: %S is FALSE, did not process page sections",
  302. __FUNCNAME__, c_szAfProcessPageSections);
  303. return hrReturn;
  304. }
  305. hr = m_pnaiAdaptersPage->HrInitFromAnswerFile(pwifAnswerFile);
  306. if (FAILED(hr))
  307. {
  308. hrReturn = hr;
  309. }
  310. // HrInitFromAnswerFile returns FALSE if [NetProtocols] is missing
  311. hr = m_pnpiProtocolsPage->HrInitFromAnswerFile(pwifAnswerFile);
  312. if ((S_FALSE == hr) && m_fInstallDefaultComponents)
  313. {
  314. // the section is missing, initialize so that
  315. // default components will be installed
  316. ShowProgressMessage(L"Since InstallDefaultComponents is specified "
  317. L" and the section [%s] is missing, default "
  318. L"components for this section will be installed",
  319. c_szAfSectionNetProtocols);
  320. hr = m_pnpiProtocolsPage->HrInitForDefaultComponents();
  321. }
  322. if (FAILED(hr))
  323. {
  324. hrReturn = hr;
  325. }
  326. // HrInitFromAnswerFile returns FALSE if [NetServices] is missing
  327. hr = m_pnsiServicesPage->HrInitFromAnswerFile(pwifAnswerFile);
  328. if ((S_FALSE == hr) && m_fInstallDefaultComponents)
  329. {
  330. // the section is missing, initialize so that
  331. // default components will be installed
  332. ShowProgressMessage(L"Since InstallDefaultComponents is specified "
  333. L" and the section [%s] is missing, default "
  334. L"components for this section will be installed",
  335. c_szAfSectionNetServices);
  336. hr = m_pnsiServicesPage->HrInitForDefaultComponents();
  337. }
  338. if (FAILED(hr))
  339. {
  340. hrReturn = hr;
  341. }
  342. // HrInitFromAnswerFile returns FALSE if [NetClients] is missing
  343. hr = m_pnciClientsPage->HrInitFromAnswerFile(pwifAnswerFile);
  344. if ((S_FALSE == hr) && m_fInstallDefaultComponents)
  345. {
  346. // the section is missing, initialize so that
  347. // default components will be installed
  348. ShowProgressMessage(L"Since InstallDefaultComponents is specified "
  349. L" and the section [%s] is missing, default "
  350. L"components for this section will be installed",
  351. c_szAfSectionNetClients);
  352. hr = m_pnciClientsPage->HrInitForDefaultComponents();
  353. }
  354. if (FAILED(hr))
  355. {
  356. hrReturn = hr;
  357. }
  358. hr = m_pnbiBindingsPage->HrInitFromAnswerFile(pwifAnswerFile);
  359. if (FAILED(hr))
  360. {
  361. hrReturn = hr;
  362. }
  363. return_from_function:
  364. TraceErrorOptional(__FUNCNAME__, hrReturn,
  365. ((hrReturn == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
  366. (hrReturn == NETSETUP_E_NO_ANSWERFILE)));
  367. // ERROR_FILE_NOT_FOUND and NETSETUP_E_NO_ANSWERFILE are not treated
  368. // as error by the caller of this function since they have a defined
  369. // meaning in the context of initializing from answerfile.
  370. // However, if logged unchanged, they will be treated as errors
  371. // by the loggin code which will cause GUI setup to halt and display
  372. // setuperr.log. To avoid this, change hr to S_OK if hrReturn is
  373. // set to one of the above error codes.
  374. //
  375. hr = hrReturn;
  376. if ((HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ||
  377. (NETSETUP_E_NO_ANSWERFILE == hr))
  378. {
  379. hr = S_OK;
  380. }
  381. NetSetupLogHrStatusV(hr, SzLoadIds(IDS_INIT_FROM_ANSWERFILE), hr);
  382. return hrReturn;
  383. }
  384. // ----------------------------------------------------------------------
  385. //
  386. // Function: CNetInstallInfo::HrInitFromAnswerFile
  387. //
  388. // Purpose: Initialize internal data by reading answer-file
  389. //
  390. // Arguments:
  391. // pwifAnswerFile [in] name of answer-file
  392. //
  393. // Returns: S_OK on success, otherwise an error code
  394. //
  395. // Author: kumarp 25-November-97
  396. //
  397. // Notes:
  398. //
  399. HRESULT CNetInstallInfo::HrInitFromAnswerFile(IN PCWSTR pszAnswerFileName)
  400. {
  401. TraceFileFunc(ttidGuiModeSetup);
  402. DefineFunctionName("CNetInstallInfo::HrInitFromAnswerFile(PCWSTR)");
  403. TraceFunctionEntry(ttidNetSetup);
  404. AssertValidReadPtr(pszAnswerFileName);
  405. HRESULT hr;
  406. hr = E_OUTOFMEMORY;
  407. m_pwifAnswerFile = new CWInfFile();
  408. // initialize answer file class
  409. if ((m_pwifAnswerFile == NULL) ||
  410. (m_pwifAnswerFile->Init() == FALSE))
  411. {
  412. AssertSz(FALSE,"CNetInstallInfo::HrInitFromAnswerFile - Failed to initialize CWInfFile");
  413. return(E_OUTOFMEMORY);
  414. }
  415. if (m_pwifAnswerFile)
  416. {
  417. BOOL fStatus = m_pwifAnswerFile->Open(pszAnswerFileName);
  418. if (fStatus)
  419. {
  420. hr = HrInitFromAnswerFile(m_pwifAnswerFile);
  421. if (S_OK == hr)
  422. {
  423. hr = HrSetupOpenInfFile(
  424. pszAnswerFileName, NULL,
  425. INF_STYLE_OLDNT | INF_STYLE_WIN4,
  426. NULL, &m_hinfAnswerFile);
  427. }
  428. }
  429. else
  430. {
  431. hr = NETSETUP_E_NO_ANSWERFILE;
  432. }
  433. }
  434. TraceErrorOptional(__FUNCNAME__, hr,
  435. (hr == NETSETUP_E_NO_ANSWERFILE));
  436. return hr;
  437. }
  438. // ----------------------------------------------------------------------
  439. //
  440. // Function: CNetInstallInfo::AnswerFileName
  441. //
  442. // Purpose:
  443. //
  444. // Arguments: None
  445. //
  446. // Returns: Name of answer-file or NULL if not yet initialized
  447. //
  448. // Author: kumarp 25-November-97
  449. //
  450. // Notes:
  451. //
  452. PCWSTR CNetInstallInfo::AnswerFileName()
  453. {
  454. TraceFileFunc(ttidGuiModeSetup);
  455. if (!m_pwifAnswerFile)
  456. {
  457. return NULL;
  458. }
  459. else
  460. {
  461. return m_pwifAnswerFile->FileName();
  462. }
  463. }
  464. // ----------------------------------------------------------------------
  465. //
  466. // Function: CNetInstallInfo::HrGetInstanceGuidOfPreNT5NetCardInstance
  467. //
  468. // Purpose: Find and return instance guid of a net-card whose
  469. // pre-nt5 instance is known
  470. //
  471. // Arguments:
  472. // szPreNT5NetCardInstance [in] pre-nt5 instance of a net-card
  473. // pguid [out] pointer to
  474. //
  475. // Returns: S_OK if found, S_FALSE if not
  476. //
  477. // Author: kumarp 25-November-97
  478. //
  479. // Notes:
  480. //
  481. HRESULT
  482. CNetInstallInfo::HrGetInstanceGuidOfPreNT5NetCardInstance (
  483. IN PCWSTR szPreNT5NetCardInstance,
  484. OUT LPGUID pguid)
  485. {
  486. TraceFileFunc(ttidGuiModeSetup);
  487. HRESULT hr = S_FALSE;
  488. CNetAdapter* pna;
  489. pna = m_pnaiAdaptersPage->FindAdapterFromPreUpgradeInstance(
  490. szPreNT5NetCardInstance);
  491. if (pna)
  492. {
  493. pna->GetInstanceGuid(pguid);
  494. hr = S_OK;
  495. }
  496. return hr;
  497. }
  498. // ----------------------------------------------------------------------
  499. //
  500. // Function: CNetInstallInfo::Find
  501. //
  502. // Purpose: Find a component using its name in answerfile
  503. //
  504. // Arguments:
  505. // pszComponentName [in] name in answerfile, e.g. Adapter01 | MS_TCPIP
  506. //
  507. // Returns: pointer to CNetComponent object found, or NULL if not found
  508. //
  509. // Author: kumarp 25-November-97
  510. //
  511. // Notes:
  512. //
  513. CNetComponent* CNetInstallInfo::Find(IN PCWSTR pszComponentName) const
  514. {
  515. TraceFileFunc(ttidGuiModeSetup);
  516. AssertValidReadPtr(pszComponentName);
  517. CNetComponent* pnc;
  518. (pnc = m_pnaiAdaptersPage->Find(pszComponentName)) ||
  519. (pnc = m_pnpiProtocolsPage->Find(pszComponentName)) ||
  520. (pnc = m_pnsiServicesPage->Find(pszComponentName)) ||
  521. (pnc = m_pnciClientsPage->Find(pszComponentName));
  522. return pnc;
  523. }
  524. // ----------------------------------------------------------------------
  525. //
  526. // Function: CNetInstallInfo::FindFromInfID
  527. //
  528. // Purpose: Find a component using its InfID in answerfile
  529. //
  530. // Arguments:
  531. // szInfID [in] InfID of component
  532. //
  533. // Returns: pointer to CNetComponent object found, or NULL if not found
  534. //
  535. // Author: kumarp 25-November-97
  536. //
  537. // Notes:
  538. //
  539. CNetComponent* CNetInstallInfo::FindFromInfID(IN PCWSTR szInfID) const
  540. {
  541. TraceFileFunc(ttidGuiModeSetup);
  542. AssertValidReadPtr(szInfID);
  543. CNetComponent* pnc;
  544. (pnc = m_pnaiAdaptersPage->FindFromInfID(szInfID)) ||
  545. (pnc = m_pnpiProtocolsPage->FindFromInfID(szInfID)) ||
  546. (pnc = m_pnsiServicesPage->FindFromInfID(szInfID)) ||
  547. (pnc = m_pnciClientsPage->FindFromInfID(szInfID));
  548. return pnc;
  549. }
  550. // ----------------------------------------------------------------------
  551. //
  552. // Function: CNetInstallInfo::FindAdapter
  553. //
  554. // Purpose: Find adapter with a given net-card-address in anwerfile
  555. //
  556. // Arguments:
  557. // qwNetCardAddress [in] net card address
  558. //
  559. // Returns: pointer to CNetAdapter object found, or NULL if not found
  560. //
  561. // Author: kumarp 25-November-97
  562. //
  563. // Notes:
  564. //
  565. HRESULT
  566. CNetInstallInfo::FindAdapter (
  567. IN QWORD qwNetCardAddress,
  568. CNetAdapter** ppNetAdapter) const
  569. {
  570. TraceFileFunc(ttidGuiModeSetup);
  571. AssertValidReadPtr(m_pnaiAdaptersPage);
  572. return m_pnaiAdaptersPage->FindAdapter(qwNetCardAddress, ppNetAdapter);
  573. }
  574. // ----------------------------------------------------------------------
  575. //
  576. // Function: CNetInstallInfo::FindAdapter
  577. //
  578. // Purpose: Find adapter with a given net-card-address in anwerfile
  579. //
  580. // Arguments:
  581. // qwNetCardAddress [in] net card address
  582. //
  583. // Returns: pointer to CNetAdapter object found, or NULL if not found
  584. //
  585. // Author: kumarp 25-November-97
  586. //
  587. // Notes:
  588. //
  589. HRESULT
  590. CNetInstallInfo::FindAdapter (
  591. IN DWORD BusNumber,
  592. IN DWORD Address,
  593. CNetAdapter** ppNetAdapter) const
  594. {
  595. TraceFileFunc(ttidGuiModeSetup);
  596. AssertValidReadPtr(m_pnaiAdaptersPage);
  597. return m_pnaiAdaptersPage->FindAdapter(BusNumber, Address, ppNetAdapter);
  598. }
  599. // ----------------------------------------------------------------------
  600. //
  601. // Function: CNetInstallInfo::FindAdapter
  602. //
  603. // Purpose: Find adapter with given InfID in answerfile
  604. //
  605. // Arguments:
  606. // pszInfId [in] InfID of an adapter
  607. //
  608. // Returns: pointer to CNetAdapter object found, or NULL if not found
  609. //
  610. // Author: kumarp 25-November-97
  611. //
  612. // Notes:
  613. //
  614. CNetAdapter* CNetInstallInfo::FindAdapter(IN PCWSTR pszInfId) const
  615. {
  616. TraceFileFunc(ttidGuiModeSetup);
  617. AssertValidReadPtr(m_pnaiAdaptersPage);
  618. return m_pnaiAdaptersPage->FindAdapter(pszInfId);
  619. }
  620. // ----------------------------------------------------------------------
  621. //
  622. // Function: CNetInstallInfo::HrDoUnattended
  623. //
  624. // Purpose: Run answerfile section corresponding to idPage and
  625. // install components specified in that section
  626. //
  627. // Arguments:
  628. // hwndParent [in] handle of parent window
  629. // punk [in] pointer to an interface
  630. // idPage [in] indicates which section to run
  631. // ppdm [out] pointer to
  632. // pfAllowChanges [out] pointer to
  633. //
  634. // Returns: S_OK on success, otherwise an error code
  635. //
  636. // Author: kumarp 25-November-97
  637. //
  638. // Notes:
  639. //
  640. HRESULT
  641. CNetInstallInfo::HrDoUnattended(
  642. IN HWND hwndParent,
  643. IN IUnknown* punk,
  644. IN EUnattendWorkType uawType,
  645. OUT EPageDisplayMode* ppdm,
  646. OUT BOOL* pfAllowChanges)
  647. {
  648. TraceFileFunc(ttidGuiModeSetup);
  649. DefineFunctionName("CNetInstallInfo::HrDoUnattended");
  650. TraceFunctionEntry(ttidNetSetup);
  651. AssertValidWritePtr(ppdm);
  652. AssertValidWritePtr(pfAllowChanges);
  653. // set the defaults in case they are not specified in the answer-file
  654. *ppdm = PDM_ONLY_ON_ERROR;
  655. *pfAllowChanges = FALSE;
  656. HRESULT hr=S_OK;
  657. INetCfg * pnc = reinterpret_cast<INetCfg *>(punk);
  658. switch(uawType)
  659. {
  660. case UAW_NetAdapters:
  661. (void) m_pnaiAdaptersPage->HrDoOemPostUpgradeProcessing(pnc, hwndParent);
  662. (void) m_pnaiAdaptersPage->HrSetConnectionNames();
  663. break;
  664. case UAW_NetProtocols:
  665. m_pnpiProtocolsPage->GetDisplaySettings(ppdm, pfAllowChanges);
  666. if (m_fProcessPageSections)
  667. {
  668. hr = m_pnpiProtocolsPage->HrDoNetworkInstall(hwndParent, pnc);
  669. }
  670. else if (m_fUpgrade)
  671. {
  672. hr = m_pnpiProtocolsPage->HrDoOsUpgrade(pnc);
  673. }
  674. break;
  675. case UAW_NetClients:
  676. m_pnciClientsPage->GetDisplaySettings(ppdm, pfAllowChanges);
  677. if (m_fProcessPageSections)
  678. {
  679. hr = m_pnciClientsPage->HrDoNetworkInstall(hwndParent, pnc);
  680. }
  681. else if (m_fUpgrade)
  682. {
  683. hr = m_pnciClientsPage->HrDoOsUpgrade(pnc);
  684. }
  685. break;
  686. case UAW_NetServices:
  687. m_pnsiServicesPage->GetDisplaySettings(ppdm, pfAllowChanges);
  688. if (m_fProcessPageSections)
  689. {
  690. // we ignore the error code since we want to do other
  691. // things even if HrDoNetworkInstall fails
  692. //
  693. hr = m_pnsiServicesPage->HrDoNetworkInstall(hwndParent, pnc);
  694. // if we installed Router during upgrade, we need to call the
  695. // router upgrade dll to munge the registry at this point
  696. //
  697. if (m_fUpgrade)
  698. {
  699. hr = HrUpgradeRouterIfPresent(pnc, this);
  700. if (FAILED(hr))
  701. {
  702. TraceError(__FUNCNAME__, hr);
  703. TraceTag(ttidError, "%s: router upgrade failed, but the failure was ignored", __FUNCNAME__);
  704. hr = S_OK;
  705. }
  706. hr = HrUpgradeTapiServer(m_hinfAnswerFile);
  707. if (S_OK != hr)
  708. {
  709. TraceTag(ttidError, "%s: TAPI server upgrade failed, but the failure was ignored. error code: 0x%x", __FUNCNAME__, hr);
  710. hr = S_OK;
  711. }
  712. if ( m_pwifAnswerFile )
  713. {
  714. (void) HrRestoreServiceStartValuesToPreUpgradeSetting(m_pwifAnswerFile);
  715. }
  716. // RAID 332622 (jeffspr)
  717. //
  718. (void) HrRemoveEvilIntelWinsockSPs();
  719. // hr = HrRestoreWinsockProviderOrder(m_pwifAnswerFile);
  720. }
  721. }
  722. else if (m_fUpgrade)
  723. {
  724. hr = m_pnsiServicesPage->HrDoOsUpgrade(pnc);
  725. // RAID:NTBUG9:25950 - We need to even do this for NT5 services.
  726. if ( m_pwifAnswerFile )
  727. {
  728. (void) HrRestoreServiceStartValuesToPreUpgradeSetting(m_pwifAnswerFile);
  729. }
  730. }
  731. break;
  732. case UAW_NetBindings:
  733. if (m_fProcessPageSections)
  734. {
  735. m_pnbiBindingsPage->GetDisplaySettings(ppdm, pfAllowChanges);
  736. hr = m_pnbiBindingsPage->HrDoUnattended(pnc);
  737. }
  738. break;
  739. case UAW_RemoveNetComponents:
  740. hr = HrRemoveNetComponents(pnc, &m_slNetComponentsToRemove);
  741. break;
  742. default:
  743. AssertSz(FALSE, "HrDoUnattended: Invalid Page ID passed");
  744. }
  745. // normalize result
  746. //
  747. if (S_FALSE == hr)
  748. {
  749. hr = S_OK;
  750. }
  751. TraceError(__FUNCNAME__, hr);
  752. return hr;
  753. }
  754. // ======================================================================
  755. // class CPageDisplayCommonInfo: public functions
  756. // ======================================================================
  757. // ----------------------------------------------------------------------
  758. //
  759. // Function: CPageDisplayCommonInfo::CPageDisplayCommonInfo
  760. //
  761. // Purpose: constructor for class CPageDisplayCommonInfo
  762. //
  763. // Arguments: None
  764. //
  765. // Returns: None
  766. //
  767. // Author: kumarp 25-November-97
  768. //
  769. // Notes:
  770. //
  771. CPageDisplayCommonInfo::CPageDisplayCommonInfo()
  772. {
  773. TraceFileFunc(ttidGuiModeSetup);
  774. // InitDefaults();
  775. m_pdmDisplay = PDM_ONLY_ON_ERROR;
  776. m_fAllowChanges = TRUE;
  777. }
  778. // ----------------------------------------------------------------------
  779. //
  780. // Function: CPageDisplayCommonInfo::HrInitFromAnswerFile
  781. //
  782. // Purpose: Initialize display related keys from anwerfile
  783. //
  784. // Arguments:
  785. // pwifAnswerFile [in] pointer to CWInfFile object
  786. //
  787. // Returns: S_OK on success, otherwise an error code
  788. //
  789. // Author: kumarp 25-November-97
  790. //
  791. // Notes:
  792. //
  793. HRESULT CPageDisplayCommonInfo::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
  794. {
  795. TraceFileFunc(ttidGuiModeSetup);
  796. DefineFunctionName("CPageDisplayCommonInfo::HrInitFromAnswerFile");
  797. AssertValidReadPtr(pwifAnswerFile);
  798. HRESULT hr=S_OK;
  799. //Defaults for AnswerFile mode
  800. m_pdmDisplay = PDM_ONLY_ON_ERROR;
  801. m_fAllowChanges = TRUE;
  802. //Display
  803. PCWSTR pszDisplayMode;
  804. pszDisplayMode = GetDisplayModeStr(m_pdmDisplay);
  805. pszDisplayMode = pwifAnswerFile->GetStringValue(c_szAfDisplay, pszDisplayMode);
  806. m_pdmDisplay = MapToDisplayMode(pszDisplayMode);
  807. if (m_pdmDisplay == PDM_UNKNOWN)
  808. {
  809. AddAnswerFileError(pwifAnswerFile->CurrentReadSection()->Name(),
  810. c_szAfDisplay,
  811. IDS_E_AF_InvalidValueForThisKey);
  812. hr = NETSETUP_E_ANS_FILE_ERROR;
  813. }
  814. //AllowChanges
  815. m_fAllowChanges = pwifAnswerFile->GetBoolValue(c_szAfAllowChanges,
  816. m_fAllowChanges);
  817. TraceFunctionError(hr);
  818. return hr;
  819. }
  820. // ======================================================================
  821. // class CNetComponentsPageBase
  822. // ======================================================================
  823. // ----------------------------------------------------------------------
  824. //
  825. // Function: CNetComponentsPageBase::CNetComponentsPageBase
  826. //
  827. // Purpose: constructor for class CNetComponentsPageBase
  828. //
  829. // Arguments: None
  830. //
  831. // Returns: None
  832. //
  833. // Author: kumarp 25-November-97
  834. //
  835. // Notes:
  836. //
  837. CNetComponentsPageBase::CNetComponentsPageBase(
  838. IN CNetInstallInfo* pnii,
  839. IN const GUID* lpguidDevClass) : CPageDisplayCommonInfo()
  840. {
  841. TraceFileFunc(ttidGuiModeSetup);
  842. AssertValidReadPtr(pnii);
  843. AssertValidReadPtr(lpguidDevClass);
  844. //InitDefaults();
  845. if (lpguidDevClass == &GUID_DEVCLASS_NET)
  846. {
  847. m_pszClassName = L"Network Cards";
  848. m_eType = NCT_Adapter;
  849. }
  850. else if (lpguidDevClass == &GUID_DEVCLASS_NETTRANS)
  851. {
  852. m_pszClassName = L"Network Protocols";
  853. m_eType = NCT_Protocol;
  854. }
  855. else if (lpguidDevClass == &GUID_DEVCLASS_NETSERVICE)
  856. {
  857. m_pszClassName = L"Network Services";
  858. m_eType = NCT_Service;
  859. }
  860. else if (lpguidDevClass == &GUID_DEVCLASS_NETCLIENT)
  861. {
  862. m_pszClassName = L"Network Clients";
  863. m_eType = NCT_Client;
  864. }
  865. else
  866. {
  867. m_pszClassName = L"unknown";
  868. m_eType = NCT_Unknown;
  869. }
  870. m_pnii = pnii;
  871. m_lpguidDevClass = lpguidDevClass;
  872. }
  873. // ----------------------------------------------------------------------
  874. //
  875. // Function: CNetComponentsPageBase::~CNetComponentsPageBase
  876. //
  877. // Purpose: destructor for class CNetComponentsPageBase
  878. //
  879. // Arguments: None
  880. //
  881. // Returns: None
  882. //
  883. // Author: kumarp 25-November-97
  884. //
  885. // Notes:
  886. //
  887. CNetComponentsPageBase::~CNetComponentsPageBase()
  888. {
  889. TraceFileFunc(ttidGuiModeSetup);
  890. EraseAndDeleteAll(m_pnclComponents);
  891. }
  892. // ----------------------------------------------------------------------
  893. //
  894. // Function: CNetComponentsPageBase::HrInitFromAnswerFile
  895. //
  896. // Purpose: Initialize from the specified section in answerfile
  897. //
  898. // Arguments:
  899. // pwifAnswerFile [in] pointer to CWInfFile object
  900. // pszSectionName [in] section to initialize from
  901. //
  902. // Returns: S_OK on success, otherwise an error code
  903. //
  904. // Author: kumarp 25-November-97
  905. //
  906. // Notes:
  907. //
  908. HRESULT CNetComponentsPageBase::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile,
  909. IN PCWSTR pszSectionName)
  910. {
  911. TraceFileFunc(ttidGuiModeSetup);
  912. DefineFunctionName("CNetComponentsPageBase::HrInitFromAnswerFile");
  913. AssertValidReadPtr(pwifAnswerFile);
  914. AssertValidReadPtr(pszSectionName);
  915. HRESULT hr=S_OK, hrReturn=S_OK;
  916. PCWInfSection pwisComponents=NULL;
  917. pwisComponents = pwifAnswerFile->FindSection(pszSectionName);
  918. if (!pwisComponents)
  919. {
  920. // not an error if the entire section is missing
  921. // AddAnswerFileError(pszSectionName, IDS_E_AF_Missing);
  922. TraceTag(ttidNetSetup, "%s: the section [%S] is missing",
  923. __FUNCNAME__, pszSectionName);
  924. return S_FALSE;
  925. }
  926. PCWInfKey pwikComponent=NULL;
  927. CWInfContext cwicTemp;
  928. tstring strParamsSections;
  929. EraseAndDeleteAll(m_pnclComponents);
  930. do
  931. {
  932. pwikComponent = pwisComponents->NextKey();
  933. ContinueIf(!pwikComponent);
  934. strParamsSections = pwikComponent->GetStringValue(c_szEmpty);
  935. if (strParamsSections.empty())
  936. {
  937. AddAnswerFileError(pszSectionName, pwikComponent->Name(),
  938. IDS_E_AF_InvalidValueForThisKey);
  939. hrReturn = NETSETUP_E_ANS_FILE_ERROR;
  940. continue;
  941. }
  942. CNetComponent *pnc = GetNewComponent(pwikComponent->Name());
  943. ReturnErrorIf(!pnc, E_OUTOFMEMORY);
  944. // pnc->HrInitFromAnswerFile() destroys our context, need to save it
  945. cwicTemp = pwifAnswerFile->CurrentReadContext();
  946. hr = pnc->HrInitFromAnswerFile(pwifAnswerFile, strParamsSections.c_str());
  947. // now, restore the read context
  948. pwifAnswerFile->SetReadContext(cwicTemp);
  949. if (FAILED(hr))
  950. {
  951. ShowProgressMessage(L"component %s has answerfile errors, "
  952. L"it will not be installed/updated",
  953. pwikComponent->Name());
  954. delete pnc;
  955. hrReturn = hr;
  956. continue;
  957. }
  958. m_pnclComponents.insert(m_pnclComponents.end(), pnc);
  959. }
  960. while (pwikComponent);
  961. if (E_OUTOFMEMORY != hrReturn)
  962. {
  963. // we do not want to break upgrade if a single component has answerfile errors
  964. // only in case E_OUTOFMEMORY we want the upgrade to fail
  965. hrReturn = S_OK;
  966. }
  967. TraceErrorOptional(__FUNCNAME__, hrReturn, (S_FALSE == hr));
  968. return hrReturn;
  969. }
  970. // type of PFN_EDC_CALLBACK
  971. VOID
  972. CALLBACK
  973. DefaultComponentCallback (
  974. IN EDC_CALLBACK_MESSAGE Message,
  975. IN ULONG_PTR MessageData,
  976. IN PVOID pvCallerData OPTIONAL)
  977. {
  978. TraceFileFunc(ttidGuiModeSetup);
  979. CNetComponentsPageBase* pCallbackData;
  980. pCallbackData = (CNetComponentsPageBase*)pvCallerData;
  981. Assert (pCallbackData);
  982. if (EDC_INDICATE_COUNT == Message)
  983. {
  984. }
  985. else if (EDC_INDICATE_ENTRY == Message)
  986. {
  987. const EDC_ENTRY* pEntry = (const EDC_ENTRY*)MessageData;
  988. if (*pEntry->pguidDevClass == *pCallbackData->m_lpguidDevClass)
  989. {
  990. CNetComponent* pnc;
  991. pnc = pCallbackData->GetNewComponent(pEntry->pszInfId);
  992. if (pnc)
  993. {
  994. ShowProgressMessage(L"adding default component: %s",
  995. pEntry->pszInfId);
  996. pnc->m_strParamsSections = c_szAfNone;
  997. pCallbackData->m_pnclComponents.push_back(pnc);
  998. }
  999. }
  1000. }
  1001. }
  1002. // ----------------------------------------------------------------------
  1003. //
  1004. // Function: CNetComponentsPageBase::HrInitForComponents
  1005. //
  1006. // Purpose: Initialize data as if the components passed in the specified
  1007. // array were really present in the answerfile.
  1008. //
  1009. // Returns: S_OK on success, otherwise an error code
  1010. //
  1011. // Author: kumarp 25-November-97
  1012. //
  1013. // Notes: This function is used when a top level component section
  1014. // is missing. e.g. if [NetProtocols] section is missing, this
  1015. // function initializes the internal data such that
  1016. // MS_TCPIP (the default protocol) gets installed.
  1017. //
  1018. HRESULT CNetComponentsPageBase::HrInitForDefaultComponents()
  1019. {
  1020. TraceFileFunc(ttidGuiModeSetup);
  1021. EnumDefaultComponents (
  1022. EDC_DEFAULT,
  1023. DefaultComponentCallback,
  1024. this);
  1025. return S_OK;
  1026. }
  1027. // ----------------------------------------------------------------------
  1028. //
  1029. // Function: CNetComponentsPageBase::Find
  1030. //
  1031. // Purpose: Find the component with the specified name
  1032. //
  1033. // Arguments:
  1034. // pszComponentName [in] name of component to find
  1035. //
  1036. // Returns: pointer to CNetComponent object found or NULL if not found
  1037. //
  1038. // Author: kumarp 25-November-97
  1039. //
  1040. // Notes:
  1041. //
  1042. CNetComponent* CNetComponentsPageBase::Find(IN PCWSTR pszComponentName) const
  1043. {
  1044. TraceFileFunc(ttidGuiModeSetup);
  1045. AssertValidReadPtr(pszComponentName);
  1046. CNetComponent *pnc = NULL;
  1047. TPtrListIter pos;
  1048. pos = m_pnclComponents.begin();
  1049. while (pos != m_pnclComponents.end())
  1050. {
  1051. pnc = (CNetComponent*) *pos++;
  1052. if (!lstrcmpiW(pnc->Name().c_str(), pszComponentName))
  1053. {
  1054. return pnc;
  1055. }
  1056. }
  1057. return NULL;
  1058. }
  1059. // ----------------------------------------------------------------------
  1060. //
  1061. // Function: CNetComponentsPageBase::FindFromInfID
  1062. //
  1063. // Purpose: Find the component with the specified InfID
  1064. //
  1065. // Arguments:
  1066. // szInfID [in]
  1067. //
  1068. // Returns: pointer to CNetComponent object or NULL if not found
  1069. //
  1070. // Author: kumarp 25-November-97
  1071. //
  1072. // Notes:
  1073. //
  1074. CNetComponent* CNetComponentsPageBase::FindFromInfID(IN PCWSTR szInfID) const
  1075. {
  1076. TraceFileFunc(ttidGuiModeSetup);
  1077. return FindComponentInList(
  1078. const_cast<CNetComponentList*>(&m_pnclComponents),
  1079. szInfID);
  1080. }
  1081. // ----------------------------------------------------------------------
  1082. //
  1083. // Function: ForceDeleteFile
  1084. //
  1085. // Purpose: Delete file whether it is readonly or not
  1086. //
  1087. // Arguments:
  1088. // lpFileName [in]
  1089. //
  1090. // Returns: TRUE for success, FALSE for failure
  1091. //
  1092. // Notes:
  1093. //
  1094. BOOL
  1095. ForceDeleteFile(IN LPCWSTR lpFileName)
  1096. {
  1097. TraceFileFunc(ttidGuiModeSetup);
  1098. Assert(lpFileName);
  1099. BOOL lRet = DeleteFile(lpFileName);
  1100. if (!lRet && (ERROR_ACCESS_DENIED == GetLastError()))
  1101. {
  1102. // kill the readonly bit, and try again
  1103. //
  1104. DWORD dwAttr = GetFileAttributes(lpFileName);
  1105. SetFileAttributes(lpFileName, (dwAttr & ~FILE_ATTRIBUTE_READONLY));
  1106. lRet = DeleteFile(lpFileName);
  1107. }
  1108. return lRet;
  1109. }
  1110. #if 0
  1111. // ----------------------------------------------------------------------
  1112. //
  1113. // Function: HrCopyNovellInf
  1114. //
  1115. // Purpose: Copies the Novell Client32's INF (iwclient.inf) so that setup will
  1116. // find it in the INF directory when we try to upgrade the client.
  1117. // Currently there is no other way to upgrade non-netclass OEM components
  1118. // on NT5->NT5 upgrades.
  1119. //
  1120. // Returns: S_OK on success, otherwise an error code
  1121. //
  1122. // Notes: Special case code that should be folded into a more generic solution
  1123. // as other users for this are found.
  1124. //
  1125. HRESULT
  1126. HrCopyNovellInf(INetCfgComponent* pINetCfgComponent)
  1127. {
  1128. TraceFileFunc(ttidGuiModeSetup);
  1129. HRESULT hr = S_OK;
  1130. tstring strTemp;
  1131. tstring strNewNovellInfName;
  1132. DefineFunctionName("HrCopyNovellInf");
  1133. TraceFunctionEntry(ttidNetSetup);
  1134. AssertValidReadPtr(pINetCfgComponent);
  1135. // get the windir location
  1136. //
  1137. WCHAR szWindowsDir[MAX_PATH+1];
  1138. TraceTag(ttidNetSetup, "%s: about to get windows dir", __FUNCNAME__);
  1139. if (GetWindowsDirectory(szWindowsDir, MAX_PATH))
  1140. {
  1141. tstring strTemp;
  1142. //
  1143. // old Novell INFs used to copy themselves as part of their install.
  1144. // This is unnecessary, and will confuse setup when it grouts around
  1145. // for INFs. Delete this file.
  1146. //
  1147. strTemp = szWindowsDir;
  1148. strTemp += L"\\inf\\iwclient.inf";
  1149. TraceTag(ttidNetSetup, "%s: deleting old Novell INF file (%S)",
  1150. __FUNCNAME__, strTemp.c_str());
  1151. if (!ForceDeleteFile (strTemp.c_str()))
  1152. {
  1153. TraceTag(ttidNetSetup, "%s: old iwclient.inf not found", __FUNCNAME__);
  1154. }
  1155. else
  1156. {
  1157. TraceTag(ttidNetSetup, "%s: old iwclient.inf found and deleted", __FUNCNAME__);
  1158. }
  1159. strTemp = szWindowsDir;
  1160. strTemp += L"\\inf\\iwclient.Pnf";
  1161. ForceDeleteFile(strTemp.c_str());
  1162. //
  1163. // copy in the new INF file, and remember the destination name.
  1164. //
  1165. if (S_OK == hr)
  1166. {
  1167. static const WCHAR c_szNovellSubDir[] = L"\\netsetup\\novell";
  1168. static const WCHAR c_szNovellInfFile[] = L"\\iwclient.inf";
  1169. tstring strDir = szWindowsDir;
  1170. strDir += c_szNovellSubDir;
  1171. strTemp = szWindowsDir;
  1172. strTemp += c_szNovellSubDir;
  1173. strTemp += c_szNovellInfFile;
  1174. TraceTag(ttidNetSetup, "%s: Copying new Novell INF", __FUNCNAME__, strTemp.c_str());
  1175. hr = HrSetupCopyOemInf(strTemp, strDir, SPOST_PATH, 0, NULL, &strNewNovellInfName);
  1176. if (S_OK == hr)
  1177. {
  1178. TraceTag(ttidNetSetup, "%s: New Novell INF copied", __FUNCNAME__);
  1179. }
  1180. }
  1181. //
  1182. // There may be duplicate INF(s) for nw_nwfs remaining in the INF dir.
  1183. // Find and delete them all, making sure we *don't* delete the one we just copied.
  1184. //
  1185. TStringList lstrNovellInfs;
  1186. HINF hinf;
  1187. INFCONTEXT ic;
  1188. HANDLE hfile;
  1189. WIN32_FIND_DATA FindData;
  1190. WCHAR szTemplate[MAX_PATH+1];
  1191. wcscpy(szTemplate, szWindowsDir);
  1192. wcscat(szTemplate, L"\\inf\\oem*.inf");
  1193. hfile = FindFirstFile(szTemplate, &FindData);
  1194. while (INVALID_HANDLE_VALUE != hfile)
  1195. {
  1196. // if it's the file we just copied, skip it.
  1197. if (0 == lstrcmpiW(FindData.cFileName, strNewNovellInfName.c_str()))
  1198. goto loopcleanup;
  1199. // try it
  1200. hr = HrSetupOpenInfFile(FindData.cFileName, NULL, INF_STYLE_WIN4,
  1201. NULL, &hinf);
  1202. if (S_OK == hr)
  1203. {
  1204. // look in a section titled [Novell]...
  1205. //
  1206. hr = HrSetupFindFirstLine(hinf, L"Novell", NULL, &ic);
  1207. if (S_OK == hr)
  1208. {
  1209. WCHAR szBuf[LINE_LEN]; // LINE_LEN defined in setupapi.h as 256
  1210. do
  1211. {
  1212. // ... for a line that looks like "... = ... , nw_nwfs".
  1213. //
  1214. hr = HrSetupGetStringField(ic, 2, szBuf,
  1215. celems(szBuf), NULL);
  1216. if ((S_OK == hr) && !lstrcmpiW(szBuf, L"nw_nwfs"))
  1217. {
  1218. // another old INF file for Novell Client32!
  1219. TraceTag(ttidNetSetup, "%s: found dup INF for nw_nwfs (%S)",
  1220. __FUNCNAME__, FindData.cFileName);
  1221. // add to list for later deletion
  1222. NC_TRY
  1223. {
  1224. lstrNovellInfs.push_back(new tstring(FindData.cFileName));
  1225. }
  1226. NC_CATCH_ALL
  1227. {
  1228. hr = E_OUTOFMEMORY;
  1229. break;
  1230. }
  1231. // generate the PNF name and add that too.
  1232. //
  1233. if (S_OK == hr)
  1234. {
  1235. WCHAR szPNF[MAX_PATH+1];
  1236. wcscpy(szPNF, FindData.cFileName);
  1237. szPNF[wcslen(szPNF) - 3] = L'p';
  1238. NC_TRY
  1239. {
  1240. lstrNovellInfs.push_back(new tstring(szPNF));
  1241. }
  1242. NC_CATCH_ALL
  1243. {
  1244. hr = E_OUTOFMEMORY;
  1245. break;
  1246. }
  1247. }
  1248. }
  1249. }
  1250. while (S_OK == (hr = HrSetupFindNextLine(ic, &ic)));
  1251. }
  1252. SetupCloseInfFile(hinf);
  1253. if (SUCCEEDED(hr) || (HRESULT_FROM_WIN32(SPAPI_E_LINE_NOT_FOUND) == hr))
  1254. {
  1255. // S_FALSE is returned when HrSetupFindNextLine can find no more lines.
  1256. // line_not_found indicates HrSetupFindFirstLine didn't find a Novell section.
  1257. hr = S_OK;
  1258. }
  1259. }
  1260. if (S_OK != hr)
  1261. {
  1262. break;
  1263. }
  1264. loopcleanup:
  1265. if (!FindNextFile(hfile, &FindData))
  1266. {
  1267. if (ERROR_NO_MORE_FILES != GetLastError())
  1268. {
  1269. hr = HrFromLastWin32Error();
  1270. }
  1271. // either way, end the loop
  1272. break;
  1273. }
  1274. }
  1275. if (INVALID_HANDLE_VALUE != hfile)
  1276. {
  1277. FindClose(hfile);
  1278. }
  1279. //
  1280. // and finally, delete the old INF and PNF.
  1281. //
  1282. if (S_OK == hr)
  1283. {
  1284. TStringListIter iterlstr;
  1285. for (iterlstr = lstrNovellInfs.begin();
  1286. iterlstr != lstrNovellInfs.end();
  1287. iterlstr++)
  1288. {
  1289. tstring strInfName = szWindowsDir;
  1290. strInfName += L"\\inf\\";
  1291. strInfName += (*iterlstr)->c_str();
  1292. TraceTag(ttidNetSetup, "%s: deleting %S", __FUNCNAME__, strInfName.c_str());
  1293. if (!ForceDeleteFile (strInfName.c_str()))
  1294. {
  1295. TraceTag(ttidNetSetup, "%s: strange - we just found this file,",
  1296. " now it is deleted...", __FUNCNAME__);
  1297. }
  1298. else
  1299. {
  1300. TraceTag(ttidNetSetup, "%s: Old Novell INF or PNF deleted (%S)",
  1301. __FUNCNAME__, strInfName.c_str());
  1302. }
  1303. // no errors returned for delete failures...
  1304. }
  1305. }
  1306. EraseAndDeleteAll(&lstrNovellInfs);
  1307. }
  1308. else
  1309. {
  1310. hr = HrFromLastWin32Error();
  1311. }
  1312. return hr;
  1313. }
  1314. #endif
  1315. // ----------------------------------------------------------------------
  1316. //
  1317. // Function: CNetComponentsPageBase::HrDoOsUpgrade
  1318. //
  1319. // Purpose: call Upgrade function of each component in order to
  1320. // upgrade it from earlier build of NT5.
  1321. //
  1322. // Arguments:
  1323. // pnc [in] pointer to INetCfg object
  1324. //
  1325. // Returns: S_OK on success, otherwise an error code
  1326. //
  1327. // Author: kumarp 25-November-97
  1328. //
  1329. HRESULT CNetComponentsPageBase::HrDoOsUpgrade(IN INetCfg* pnc)
  1330. {
  1331. TraceFileFunc(ttidGuiModeSetup);
  1332. HRESULT hr;
  1333. DefineFunctionName("CNetComponentsPageBase::HrDoOsUpgrade");
  1334. TraceFunctionEntry(ttidNetSetup);
  1335. AssertValidReadPtr(m_pnii);
  1336. TraceTag(ttidNetSetup, "%s: upgrading components of class: %S",
  1337. __FUNCNAME__, m_pszClassName);
  1338. INetCfgInternalSetup* pInternalSetup;
  1339. hr = pnc->QueryInterface (
  1340. IID_INetCfgInternalSetup,
  1341. (VOID**)&pInternalSetup);
  1342. if (S_OK == hr)
  1343. {
  1344. INetCfgComponent* pINetCfgComponent;
  1345. CIterNetCfgComponent nccIter(pnc, m_lpguidDevClass);
  1346. while (S_OK == nccIter.HrNext(&pINetCfgComponent))
  1347. {
  1348. PWSTR pszInfId;
  1349. if (FAILED(pINetCfgComponent->GetId(&pszInfId)))
  1350. {
  1351. ReleaseObj(pINetCfgComponent);
  1352. continue;
  1353. }
  1354. TraceTag(ttidNetSetup,
  1355. "%s: Calling INetCfgInstaller::Update for: %S",
  1356. __FUNCNAME__, pszInfId);
  1357. #if 0
  1358. // NOVELL Client32 special casing
  1359. //
  1360. if (!lstrcmpiW(pszInfId, L"nw_nwfs"))
  1361. {
  1362. hr = HrCopyNovellInf(pINetCfgComponent);
  1363. if (FAILED(hr))
  1364. {
  1365. TraceTag(ttidError, "%s: Novell Client32 INF copy failed, upgrade will likely fail : hr = %08lx",
  1366. __FUNCNAME__, hr);
  1367. }
  1368. }
  1369. // end special case
  1370. #endif
  1371. hr = pInternalSetup->UpdateNonEnumeratedComponent (
  1372. pINetCfgComponent,
  1373. m_pnii->UpgradeFlag(),
  1374. m_pnii->BuildNumber());
  1375. if (FAILED(hr))
  1376. {
  1377. TraceTag(ttidError, "%s: error upgrading %S: hr = %08lx",
  1378. __FUNCNAME__, pszInfId, hr);
  1379. }
  1380. NetSetupLogComponentStatus(pszInfId, SzLoadIds (IDS_UPDATING), hr);
  1381. // we dont want to quit upgrade just because 1 component
  1382. // failed OsUpgrade, therefore reset hr to S_OK
  1383. hr = S_OK;
  1384. CoTaskMemFree(pszInfId);
  1385. ReleaseObj(pINetCfgComponent);
  1386. }
  1387. }
  1388. ReleaseObj(pInternalSetup);
  1389. TraceError(__FUNCNAME__, hr);
  1390. return hr;
  1391. }
  1392. // ----------------------------------------------------------------------
  1393. //
  1394. // Function: CNetComponentsPageBase::HrDoNetworkInstall
  1395. //
  1396. // Purpose: call Install function of each component
  1397. // in the answerfile in order to install it.
  1398. //
  1399. // Arguments:
  1400. // hwndParent [in] handle of parent window
  1401. // pnc [in] pointer to INetCfg object
  1402. //
  1403. // Returns: S_OK on success, otherwise an error code
  1404. //
  1405. // Author: kumarp 25-November-97
  1406. //
  1407. // Notes:
  1408. //
  1409. HRESULT
  1410. CNetComponentsPageBase::HrDoNetworkInstall (
  1411. IN HWND hwndParent,
  1412. IN INetCfg* pnc)
  1413. {
  1414. TraceFileFunc(ttidGuiModeSetup);
  1415. DefineFunctionName("CNetComponentsPageBase::HrDoNetworkInstall");
  1416. TraceFunctionEntry(ttidNetSetup);
  1417. AssertValidReadPtr(pnc);
  1418. if (m_pnclComponents.size() > 0)
  1419. {
  1420. ShowProgressMessage(L"Installing components of class: %s",
  1421. m_pszClassName);
  1422. }
  1423. else
  1424. {
  1425. ShowProgressMessage(L"No components to install/update for class: %s",
  1426. m_pszClassName);
  1427. }
  1428. HRESULT hr;
  1429. INetCfgClassSetup* pINetCfgClassSetup;
  1430. hr = pnc->QueryNetCfgClass(m_lpguidDevClass, IID_INetCfgClassSetup,
  1431. reinterpret_cast<void**>(&pINetCfgClassSetup));
  1432. if (S_OK == hr)
  1433. {
  1434. INetCfgComponent* pINetCfgComponent;
  1435. CNetComponentList::iterator pos;
  1436. CNetComponent* pncTemp;
  1437. OBO_TOKEN OboToken;
  1438. ZeroMemory (&OboToken, sizeof(OboToken));
  1439. OboToken.Type = OBO_USER;
  1440. for (pos = m_pnclComponents.begin();
  1441. pos != m_pnclComponents.end();
  1442. pos++)
  1443. {
  1444. pncTemp = (CNetComponent*)*pos;
  1445. Assert(pncTemp);
  1446. PCWSTR pszInfId;
  1447. PCWSTR pszParamsSections;
  1448. pszInfId = pncTemp->InfID().c_str();
  1449. pszParamsSections = pncTemp->ParamsSections().c_str();
  1450. // cant install a component whose InfID is "Unknown"
  1451. // the down-level upgrade DLL, dumps correct InfID
  1452. // for only the supported components,
  1453. // all others are dumped as "Unknown"
  1454. //
  1455. if (!_wcsicmp(pszInfId, c_szAfUnknown))
  1456. {
  1457. continue;
  1458. }
  1459. hr = pnc->FindComponent(pszInfId, &pINetCfgComponent);
  1460. if (FAILED(hr))
  1461. {
  1462. continue;
  1463. }
  1464. else if (S_FALSE == hr)
  1465. {
  1466. // currently the SkipInstall feature is used only by
  1467. // SNA for its peculiar upgrade requirements. This may or may
  1468. // not become a documented feature.
  1469. //
  1470. if (pncTemp->m_fSkipInstall)
  1471. {
  1472. TraceTag(ttidNetSetup,
  1473. "%s: SkipInstall is TRUE for %S --> "
  1474. "skipped its install",
  1475. __FUNCNAME__, pszInfId);
  1476. pINetCfgComponent = NULL;
  1477. hr = S_OK;
  1478. }
  1479. else
  1480. {
  1481. // component is not installed. need to install it first
  1482. //
  1483. ShowProgressMessage(
  1484. L"Installing '%s' and applying "
  1485. L"properties in section [%s] to it... ",
  1486. pszInfId, pszParamsSections);
  1487. TraceTag(ttidNetSetup,
  1488. "%s: UpgradeFlag: 0x%x, BuildNumber: %d",
  1489. __FUNCNAME__,
  1490. m_pnii->UpgradeFlag(),
  1491. m_pnii->BuildNumber());
  1492. Assert (!pINetCfgComponent);
  1493. hr = pINetCfgClassSetup->Install(
  1494. pszInfId,
  1495. &OboToken,
  1496. m_pnii->UpgradeFlag(),
  1497. m_pnii->BuildNumber(),
  1498. m_pnii->AnswerFileName(),
  1499. pszParamsSections,
  1500. &pINetCfgComponent);
  1501. if (SUCCEEDED(hr))
  1502. {
  1503. ShowProgressMessage(L"...successfully installed %s",
  1504. pszInfId);
  1505. GUID guid;
  1506. pINetCfgComponent->GetInstanceGuid(&guid);
  1507. pncTemp->SetInstanceGuid(&guid);
  1508. }
  1509. else
  1510. {
  1511. ShowProgressMessage(L"...error installing: %s, "
  1512. L"errcode: %08lx", pszInfId, hr);
  1513. // Answerfile specified a non-existent INF.
  1514. if (SPAPI_E_NO_DRIVER_SELECTED == hr)
  1515. {
  1516. hr = S_OK;
  1517. continue;
  1518. }
  1519. }
  1520. NetSetupLogComponentStatus(pszInfId,
  1521. SzLoadIds (IDS_INSTALLING), hr);
  1522. }
  1523. }
  1524. else // S_FALSE != hr IOW ( (SUCCEEDED(hr)) && (S_FALSE != hr) )
  1525. {
  1526. Assert (pINetCfgComponent);
  1527. // Component is already installed, just call ReadAnswerFile
  1528. // Need to query for the private component interface which
  1529. // gives us access to the notify object.
  1530. //
  1531. INetCfgComponentPrivate* pComponentPrivate;
  1532. hr = pINetCfgComponent->QueryInterface(
  1533. IID_INetCfgComponentPrivate,
  1534. reinterpret_cast<void**>(&pComponentPrivate));
  1535. if (S_OK == hr)
  1536. {
  1537. INetCfgComponentSetup* pINetCfgComponentSetup;
  1538. // Query the notify object for its setup interface.
  1539. // If it doesn't support it, that's okay, we can continue.
  1540. //
  1541. hr = pComponentPrivate->QueryNotifyObject(
  1542. IID_INetCfgComponentSetup,
  1543. (void**) &pINetCfgComponentSetup);
  1544. if (S_OK == hr)
  1545. {
  1546. ShowProgressMessage(L"Applying properties in section [%s] to component: %s",
  1547. pszParamsSections,
  1548. pszInfId);
  1549. hr = pINetCfgComponentSetup->ReadAnswerFile(
  1550. m_pnii->AnswerFileName(),
  1551. pszParamsSections);
  1552. ReleaseObj(pINetCfgComponentSetup);
  1553. if (SUCCEEDED(hr))
  1554. {
  1555. if (S_OK == hr)
  1556. {
  1557. hr = pComponentPrivate->SetDirty();
  1558. }
  1559. ShowProgressMessage(L"...successfully applied properties to %s",
  1560. pszInfId);
  1561. }
  1562. else
  1563. {
  1564. ShowProgressMessage(L"...error applying properties to: %s, "
  1565. L"errcode: %08lx",
  1566. pszInfId, hr);
  1567. }
  1568. NetSetupLogComponentStatus(pszInfId,
  1569. SzLoadIds (IDS_CONFIGURING), hr);
  1570. }
  1571. else if (E_NOINTERFACE == hr)
  1572. {
  1573. hr = S_OK;
  1574. }
  1575. ReleaseObj (pComponentPrivate);
  1576. }
  1577. }
  1578. if (S_OK == hr)
  1579. {
  1580. // If required, run OEM INF against the Params key
  1581. // of the component that we just installed
  1582. //
  1583. if (pncTemp->m_fIsOemComponent)
  1584. {
  1585. HKEY hkeyParams;
  1586. // currently the SkipInstall feature is used only by
  1587. // SNA for its peculiar upgrade requirements. This may or may
  1588. // not become a documented feature.
  1589. //
  1590. if (pncTemp->m_fSkipInstall)
  1591. {
  1592. hkeyParams = NULL;
  1593. }
  1594. else
  1595. {
  1596. hr = pINetCfgComponent->OpenParamKey(&hkeyParams);
  1597. }
  1598. // if specified, run OEM INF section to patch
  1599. // the component Params key
  1600. //
  1601. if ((S_OK == hr) &&
  1602. !pncTemp->m_strInfToRunAfterInstall.empty())
  1603. {
  1604. TraceTag(ttidNetSetup,
  1605. "%s: running InfToRunAfterInstall for %S, "
  1606. "INF: %S, section: %S",
  1607. __FUNCNAME__, pszInfId,
  1608. pncTemp->m_strInfToRunAfterInstall.c_str(),
  1609. pncTemp->m_strSectionToRunAfterInstall.c_str());
  1610. hr = HrInstallFromInfSectionInFile(
  1611. hwndParent,
  1612. pncTemp->m_strInfToRunAfterInstall.c_str(),
  1613. pncTemp->m_strSectionToRunAfterInstall.c_str(),
  1614. hkeyParams, TRUE);
  1615. if (S_OK != hr)
  1616. {
  1617. TraceTag(ttidNetSetup, "%s: error applying OEM INF for %S, "
  1618. "INF: %S, section: %S",
  1619. __FUNCNAME__, pszInfId,
  1620. pncTemp->m_strInfToRunAfterInstall.c_str(),
  1621. pncTemp->m_strSectionToRunAfterInstall.c_str());
  1622. }
  1623. NetSetupLogComponentStatus(pszInfId,
  1624. SzLoadIds (IDS_APPLY_INFTORUN), hr);
  1625. }
  1626. // If specified, load OEM DLL and call migration function
  1627. //
  1628. if ((S_OK == hr) &&
  1629. !pncTemp->m_strOemDll.empty())
  1630. {
  1631. hr = HrProcessOemComponent(
  1632. hwndParent,
  1633. pncTemp->m_strOemDir.c_str(),
  1634. pncTemp->m_strOemDll.c_str(),
  1635. &m_pnii->m_nui,
  1636. hkeyParams,
  1637. pncTemp->m_strInfID.c_str(),
  1638. pncTemp->m_strInfID.c_str(),
  1639. m_pnii->m_hinfAnswerFile,
  1640. pncTemp->m_strParamsSections.c_str());
  1641. NetSetupLogComponentStatus(pszInfId,
  1642. SzLoadIds (IDS_PROCESSING_OEM), hr);
  1643. }
  1644. RegSafeCloseKey(hkeyParams);
  1645. }
  1646. }
  1647. ReleaseObj(pINetCfgComponent);
  1648. }
  1649. ReleaseObj(pINetCfgClassSetup);
  1650. pnc->Apply();
  1651. }
  1652. TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
  1653. return hr;
  1654. }
  1655. // ----------------------------------------------------------------------
  1656. //
  1657. // Function: CNetComponentsPageBase::HrValidate
  1658. //
  1659. // Purpose: Validate data read from the answerfile
  1660. //
  1661. // Arguments: None
  1662. //
  1663. // Returns: S_OK on success, otherwise an error code
  1664. //
  1665. // Author: kumarp 25-November-97
  1666. //
  1667. // Notes:
  1668. //
  1669. HRESULT CNetComponentsPageBase::HrValidate() const
  1670. {
  1671. TraceFileFunc(ttidGuiModeSetup);
  1672. DefineFunctionName("CNetComponentsPageBase::HrValidate");
  1673. HRESULT hr = E_FAIL;
  1674. TPtrListIter pos;
  1675. CNetComponent* pnc;
  1676. pos = m_pnclComponents.begin();
  1677. while (pos != m_pnclComponents.end())
  1678. {
  1679. pnc = (CNetComponent *) *pos++;
  1680. hr = pnc->HrValidate();
  1681. ReturnHrIfFailed(hr);
  1682. }
  1683. TraceFunctionError(hr);
  1684. return hr;
  1685. }
  1686. // ======================================================================
  1687. // class CNetAdaptersPage
  1688. // ======================================================================
  1689. // ----------------------------------------------------------------------
  1690. //
  1691. // Function: CNetAdaptersPage::CNetAdaptersPage
  1692. //
  1693. // Purpose: constructor for class CNetAdaptersPage
  1694. //
  1695. // Arguments:
  1696. // pnii [in] pointer to CNetInstallInfo object
  1697. //
  1698. // Returns:
  1699. //
  1700. // Author: kumarp 25-November-97
  1701. //
  1702. // Notes:
  1703. //
  1704. CNetAdaptersPage::CNetAdaptersPage(IN CNetInstallInfo* pnii)
  1705. : CNetComponentsPageBase(pnii, &GUID_DEVCLASS_NET)
  1706. {
  1707. TraceFileFunc(ttidGuiModeSetup);
  1708. }
  1709. // ----------------------------------------------------------------------
  1710. //
  1711. // Function: CNetAdaptersPage::HrInitFromAnswerFile
  1712. //
  1713. // Purpose: Initialize from [NetAdapters] section in the answerfile
  1714. //
  1715. // Arguments:
  1716. // pwifAnswerFile [in] pointer to CWInfFile object
  1717. //
  1718. // Returns: S_OK on success, otherwise an error code
  1719. //
  1720. // Author: kumarp 25-November-97
  1721. //
  1722. // Notes:
  1723. //
  1724. HRESULT CNetAdaptersPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
  1725. {
  1726. TraceFileFunc(ttidGuiModeSetup);
  1727. DefineFunctionName("CNetAdaptersPage::HrInitFromAnswerFile");
  1728. AssertValidReadPtr(pwifAnswerFile);
  1729. HRESULT hr;
  1730. hr = CNetComponentsPageBase::HrInitFromAnswerFile(pwifAnswerFile,
  1731. c_szAfSectionNetAdapters);
  1732. TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
  1733. return hr;
  1734. }
  1735. // ----------------------------------------------------------------------
  1736. //
  1737. // Function: CNetAdaptersPage::FindAdapter
  1738. //
  1739. // Purpose: Find adapter with a given net-card-address in anwerfile
  1740. //
  1741. // Arguments:
  1742. // qwNetCardAddress [in] net card address
  1743. //
  1744. // Returns: pointer to CNetAdapter object
  1745. //
  1746. // Author: kumarp 25-November-97
  1747. //
  1748. // Notes:
  1749. //
  1750. HRESULT
  1751. CNetAdaptersPage::FindAdapter(
  1752. IN QWORD qwNetCardAddress,
  1753. OUT CNetAdapter** ppNetAdapter) const
  1754. {
  1755. TraceFileFunc(ttidGuiModeSetup);
  1756. CNetAdapter* pna;
  1757. HRESULT hr;
  1758. TPtrListIter pos;
  1759. Assert(ppNetAdapter);
  1760. hr = NETSETUP_E_NO_EXACT_MATCH;
  1761. pos = m_pnclComponents.begin();
  1762. while (pos != m_pnclComponents.end())
  1763. {
  1764. pna = (CNetAdapter*) *pos++;
  1765. if (pna->NetCardAddr() == qwNetCardAddress)
  1766. {
  1767. *ppNetAdapter = pna;
  1768. hr = S_OK;
  1769. break;
  1770. }
  1771. else if (0 == pna->NetCardAddr())
  1772. {
  1773. hr = NETSETUP_E_AMBIGUOUS_MATCH;
  1774. }
  1775. }
  1776. return hr;
  1777. }
  1778. // ----------------------------------------------------------------------
  1779. //
  1780. // Function: CNetAdaptersPage::FindAdapter
  1781. //
  1782. // Purpose: Find adapter with a given net-card-address in anwerfile
  1783. //
  1784. // Arguments:
  1785. // qwNetCardAddress [in] net card address
  1786. //
  1787. // Returns: pointer to CNetAdapter object
  1788. //
  1789. // Author: kumarp 25-November-97
  1790. //
  1791. // Notes:
  1792. //
  1793. HRESULT
  1794. CNetAdaptersPage::FindAdapter(
  1795. IN DWORD BusNumber,
  1796. IN DWORD Address,
  1797. OUT CNetAdapter** ppNetAdapter) const
  1798. {
  1799. TraceFileFunc(ttidGuiModeSetup);
  1800. CNetAdapter* pna;
  1801. HRESULT hr;
  1802. TPtrListIter pos;
  1803. Assert(ppNetAdapter);
  1804. hr = NETSETUP_E_NO_EXACT_MATCH;
  1805. pos = m_pnclComponents.begin();
  1806. while (pos != m_pnclComponents.end())
  1807. {
  1808. pna = (CNetAdapter*) *pos++;
  1809. // Only check sections that did not specify a MAC address and
  1810. // did specify PCI location info.
  1811. //
  1812. if ((0 == pna->NetCardAddr()) && pna->FPciInfoSpecified())
  1813. {
  1814. if ((pna->PciBusNumber() == BusNumber) &&
  1815. (pna->PciAddress() == Address))
  1816. {
  1817. *ppNetAdapter = pna;
  1818. hr = S_OK;
  1819. break;
  1820. }
  1821. }
  1822. else
  1823. {
  1824. hr = NETSETUP_E_AMBIGUOUS_MATCH;
  1825. }
  1826. }
  1827. return hr;
  1828. }
  1829. // ----------------------------------------------------------------------
  1830. //
  1831. // Function: CNetAdaptersPage::FindAdapter
  1832. //
  1833. // Purpose: Find adapter with the given InfID
  1834. //
  1835. // Arguments:
  1836. // szInfID [in] InfID of the adapter to be located
  1837. //
  1838. // Returns: pointer to CNetAdapter object, or NULL if not found
  1839. //
  1840. // Author: kumarp 25-November-97
  1841. //
  1842. // Notes:
  1843. //
  1844. CNetAdapter* CNetAdaptersPage::FindAdapter(IN PCWSTR szInfID) const
  1845. {
  1846. TraceFileFunc(ttidGuiModeSetup);
  1847. return (CNetAdapter*) FindComponentInList(
  1848. const_cast<CNetComponentList*>(&m_pnclComponents),
  1849. szInfID);
  1850. }
  1851. // ----------------------------------------------------------------------
  1852. //
  1853. // Function: CNetAdaptersPage::FindAdapterFromPreUpgradeInstance
  1854. //
  1855. // Purpose: Find adapter with the given pre-upgrade instance
  1856. //
  1857. // Arguments:
  1858. // szPreUpgradeInstance [in]
  1859. //
  1860. // Returns: pointer to CNetAdapter object
  1861. //
  1862. // Author: kumarp 25-November-97
  1863. //
  1864. // Notes:
  1865. //
  1866. CNetAdapter* CNetAdaptersPage::FindAdapterFromPreUpgradeInstance(IN PCWSTR szPreUpgradeInstance)
  1867. {
  1868. CNetAdapter* pna;
  1869. TPtrListIter pos;
  1870. pos = m_pnclComponents.begin();
  1871. while (pos != m_pnclComponents.end())
  1872. {
  1873. pna = (CNetAdapter*) *pos++;
  1874. if (!lstrcmpiW(pna->PreUpgradeInstance(), szPreUpgradeInstance))
  1875. {
  1876. return pna;
  1877. }
  1878. }
  1879. return NULL;
  1880. }
  1881. // ----------------------------------------------------------------------
  1882. //
  1883. // Function: CNetAdaptersPage::GetNumCompatibleAdapters
  1884. //
  1885. // Purpose: Find the total number of adapters in the answerfile that
  1886. // are compatible with the given list of adapters
  1887. //
  1888. // Arguments:
  1889. // mszInfID [in] list of adapters as a multi-sz
  1890. //
  1891. // Returns: number of such adapters found
  1892. //
  1893. // Author: kumarp 25-November-97
  1894. //
  1895. // Notes:
  1896. //
  1897. DWORD CNetAdaptersPage::GetNumCompatibleAdapters(IN PCWSTR mszInfID) const
  1898. {
  1899. TraceFileFunc(ttidGuiModeSetup);
  1900. DefineFunctionName("CNetAdaptersPage::GetNumCompatibleAdapters");
  1901. if ((NULL == mszInfID) || (0 == *mszInfID))
  1902. {
  1903. return 0;
  1904. }
  1905. CNetAdapter* pna;
  1906. TPtrListIter pos;
  1907. pos = m_pnclComponents.begin();
  1908. DWORD dwNumAdapters=0;
  1909. PCWSTR szInfId;
  1910. while (pos != m_pnclComponents.end())
  1911. {
  1912. pna = (CNetAdapter*) *pos++;
  1913. if ((0 == pna->NetCardAddr()) && !pna->FPciInfoSpecified())
  1914. {
  1915. szInfId = pna->InfID().c_str();
  1916. if (0 == lstrcmpiW(szInfId, c_szAfInfIdWildCard))
  1917. {
  1918. TraceTag(ttidNetSetup, "%s: InfID=%S matches %S",
  1919. __FUNCNAME__, c_szAfInfIdWildCard, mszInfID);
  1920. dwNumAdapters++;
  1921. }
  1922. else if (FIsSzInMultiSzSafe(szInfId, mszInfID))
  1923. {
  1924. dwNumAdapters++;
  1925. }
  1926. }
  1927. }
  1928. return dwNumAdapters;
  1929. }
  1930. // ----------------------------------------------------------------------
  1931. //
  1932. // Function: CNetAdaptersPage::FindCompatibleAdapter
  1933. //
  1934. // Purpose: Find an adapter in the answerfile that
  1935. // is compatible with the given list of adapters
  1936. //
  1937. // Arguments:
  1938. // mszInfIDs [in] list of adapters as a multi-sz
  1939. //
  1940. // Returns: pointer to CNetAdapter object, or NULL if not found
  1941. //
  1942. // Author: kumarp 25-November-97
  1943. //
  1944. // Notes:
  1945. //
  1946. CNetAdapter* CNetAdaptersPage::FindCompatibleAdapter(IN PCWSTR mszInfIDs) const
  1947. {
  1948. TraceFileFunc(ttidGuiModeSetup);
  1949. DefineFunctionName("CNetAdaptersPage::FindCompatibleAdapter");
  1950. CNetAdapter* pna;
  1951. TPtrListIter pos;
  1952. pos = m_pnclComponents.begin();
  1953. PCWSTR szInfId;
  1954. while (pos != m_pnclComponents.end())
  1955. {
  1956. pna = (CNetAdapter*) *pos++;
  1957. // Only compare with those sections that did not specify an ethernet
  1958. // address or PCI location info.
  1959. //
  1960. if ((0 == pna->NetCardAddr()) && !pna->FPciInfoSpecified())
  1961. {
  1962. szInfId = pna->InfID().c_str();
  1963. if (0 == lstrcmpiW(szInfId, c_szAfInfIdWildCard))
  1964. {
  1965. TraceTag(ttidNetSetup, "%s: InfID=%S matched to %S",
  1966. __FUNCNAME__, c_szAfInfIdWildCard, mszInfIDs);
  1967. return pna;
  1968. }
  1969. else if (FIsSzInMultiSzSafe(szInfId, mszInfIDs))
  1970. {
  1971. return pna;
  1972. }
  1973. }
  1974. }
  1975. return NULL;
  1976. }
  1977. // ----------------------------------------------------------------------
  1978. //
  1979. // Function: CNetAdaptersPage::HrResolveNetAdapters
  1980. //
  1981. // Purpose: Enumerate over installed adapters and determine which
  1982. // installed adapter corresponds to which adapter specified in
  1983. // the answerfile.
  1984. //
  1985. // Arguments: None
  1986. //
  1987. // Returns: S_OK on success, otherwise an error code
  1988. //
  1989. // Author: kumarp 25-December-97
  1990. //
  1991. // Notes:
  1992. //
  1993. HRESULT CNetAdaptersPage::HrResolveNetAdapters(IN INetCfg* pnc)
  1994. {
  1995. TraceFileFunc(ttidGuiModeSetup);
  1996. DefineFunctionName("CNetAdaptersPage::HrResolveNetAdapters");
  1997. HRESULT hr=S_OK;
  1998. AssertValidReadPtr(m_pnii);
  1999. AssertValidReadPtr(m_pnii->AnswerFile());
  2000. CWInfSection* pwisNetAdapters;
  2001. pwisNetAdapters =
  2002. m_pnii->AnswerFile()->FindSection(c_szAfSectionNetAdapters);
  2003. if (!pwisNetAdapters)
  2004. {
  2005. TraceTag(ttidNetSetup, "%s: not resolving adapters, since section [%S]"
  2006. " is missing",
  2007. __FUNCNAME__, c_szAfSectionNetAdapters);
  2008. return S_OK;
  2009. }
  2010. INetCfgComponent* pINetCfgComponent;
  2011. GUID guid;
  2012. PWSTR pszInfId;
  2013. PWSTR pmszInfIDs = NULL;
  2014. CNetAdapter* pna;
  2015. WORD cNumAdapters;
  2016. WCHAR szServiceInstance[_MAX_PATH];
  2017. DWORD dwcc; // component characteristics
  2018. ShowProgressMessage(L"Matching installed adapters to the ones "
  2019. L"specified in the answerfile...");
  2020. CIterNetCfgComponent nccIter(pnc, m_lpguidDevClass);
  2021. while ((S_OK == hr) && (S_OK == (hr = nccIter.HrNext(&pINetCfgComponent))))
  2022. {
  2023. hr = pINetCfgComponent->GetId(&pszInfId);
  2024. if (S_OK == hr)
  2025. {
  2026. hr = pINetCfgComponent->GetCharacteristics(&dwcc);
  2027. if (S_OK == hr)
  2028. {
  2029. if (dwcc & NCF_PHYSICAL)
  2030. {
  2031. ShowProgressMessage(L"Trying to resolve adapter '%s'...", pszInfId);
  2032. // the defs of HIDWORD and LODWORD are wrong in byteorder.hxx
  2033. # define LODWORD(a) (DWORD)( (a) & ( (DWORD)~0 ))
  2034. # define HIDWORD(a) (DWORD)( (a) >> (sizeof(DWORD)*8) )
  2035. // since we have more than one adapters of the same type
  2036. // we need to compare their netcard address in order to find a match
  2037. QWORD qwNetCardAddr=0;
  2038. PWSTR pszBindName;
  2039. hr = pINetCfgComponent->GetBindName (&pszBindName);
  2040. if (S_OK == hr)
  2041. {
  2042. wcscpy (szServiceInstance, c_szDevice);
  2043. wcscat (szServiceInstance, pszBindName);
  2044. hr = HrGetNetCardAddr(szServiceInstance,
  2045. &qwNetCardAddr);
  2046. if (S_OK == hr)
  2047. {
  2048. // there is a bug in wvsprintfA (used in trace.cpp)
  2049. // because of which it does not handle %I64x
  2050. // therefore we need to show the QWORD addr as follows
  2051. //
  2052. ShowProgressMessage(
  2053. L"\t... net card address of %s is 0x%x%x",
  2054. szServiceInstance, HIDWORD(qwNetCardAddr),
  2055. LODWORD(qwNetCardAddr));
  2056. hr = FindAdapter(qwNetCardAddr, &pna);
  2057. if (NETSETUP_E_NO_EXACT_MATCH == hr)
  2058. {
  2059. ShowProgressMessage(
  2060. L"\t... there is no card with this "
  2061. L"netcard address in the answerfile");
  2062. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  2063. }
  2064. }
  2065. else
  2066. {
  2067. ShowProgressMessage(
  2068. L"\t... unable to find netcard addr of %s",
  2069. pszInfId);
  2070. }
  2071. CoTaskMemFree (pszBindName);
  2072. }
  2073. hr = HrGetCompatibleIdsOfNetComponent(pINetCfgComponent,
  2074. &pmszInfIDs);
  2075. if (FAILED(hr))
  2076. {
  2077. hr = E_OUTOFMEMORY;
  2078. // make this single InfID into a msz
  2079. //
  2080. UINT cchInfId = wcslen (pszInfId);
  2081. pmszInfIDs = (PWSTR)MemAlloc ((cchInfId + 2) *
  2082. sizeof (WCHAR));
  2083. if (pmszInfIDs)
  2084. {
  2085. hr = S_OK;
  2086. wcscpy (pmszInfIDs, pszInfId);
  2087. pmszInfIDs[cchInfId + 1] = '\0';
  2088. }
  2089. }
  2090. if (S_OK == hr)
  2091. {
  2092. cNumAdapters=0;
  2093. pna = NULL;
  2094. cNumAdapters = GetNumCompatibleAdapters(pmszInfIDs);
  2095. if (cNumAdapters == 1)
  2096. {
  2097. // no need to match the netcard address
  2098. pna = (CNetAdapter*) FindCompatibleAdapter(pmszInfIDs);
  2099. AssertValidReadPtr(pna);
  2100. }
  2101. else
  2102. {
  2103. // no matching adapters found
  2104. ShowProgressMessage(L"... answerfile does not have the "
  2105. L"installed card %s", pszInfId);
  2106. }
  2107. if (!pna)
  2108. {
  2109. hr = NETSETUP_E_NO_EXACT_MATCH;
  2110. }
  2111. MemFree (pmszInfIDs);
  2112. }
  2113. if (S_OK == hr)
  2114. {
  2115. hr = pINetCfgComponent->GetInstanceGuid(&guid);
  2116. if (S_OK == hr)
  2117. {
  2118. pna->SetInstanceGuid(&guid);
  2119. WCHAR szGuid[c_cchGuidWithTerm];
  2120. StringFromGUID2(guid, szGuid, c_cchGuidWithTerm);
  2121. ShowProgressMessage(L"%s == %s (%s)",
  2122. pna->Name().c_str(),
  2123. pszInfId, szGuid);
  2124. }
  2125. }
  2126. }
  2127. else
  2128. {
  2129. TraceTag(ttidNetSetup,
  2130. "%s: skipped non-physical adapter %S",
  2131. __FUNCNAME__, pszInfId);
  2132. }
  2133. }
  2134. CoTaskMemFree(pszInfId);
  2135. }
  2136. ReleaseObj(pINetCfgComponent);
  2137. }
  2138. if (S_FALSE == hr)
  2139. {
  2140. hr = S_OK;
  2141. }
  2142. TraceError(__FUNCNAME__, hr);
  2143. return hr;
  2144. }
  2145. //+---------------------------------------------------------------------------
  2146. //
  2147. // Function: HrFindByInstanceGuid
  2148. //
  2149. // Purpose: Get INetCfgComponent* from the instance GUID
  2150. //
  2151. // Arguments:
  2152. // pnc [in] pointer to INetCfg object
  2153. // pguidDevClass [in] pointer to class GUID
  2154. // pguid [in] pointer to instance GUID
  2155. // ppncc [out] pointer to INetCfgComponent* to return
  2156. //
  2157. // Returns: S_OK on success, S_FALSE if not found,
  2158. // otherwise an error code
  2159. //
  2160. // Author: kumarp 10-September-98
  2161. //
  2162. // Notes:
  2163. //
  2164. HRESULT HrFindByInstanceGuid(IN INetCfg* pnc,
  2165. IN const GUID* pguidDevClass,
  2166. IN LPGUID pguid,
  2167. OUT INetCfgComponent** ppncc)
  2168. {
  2169. TraceFileFunc(ttidGuiModeSetup);
  2170. DefineFunctionName("HrFindByInstanceGuid");
  2171. HRESULT hr=S_FALSE;
  2172. CIterNetCfgComponent nccIter(pnc, pguidDevClass);
  2173. GUID guid;
  2174. INetCfgComponent* pINetCfgComponent;
  2175. int cAdapter=0;
  2176. *ppncc = NULL;
  2177. while (S_OK == (hr = nccIter.HrNext(&pINetCfgComponent)))
  2178. {
  2179. hr = pINetCfgComponent->GetInstanceGuid(&guid);
  2180. if (S_OK == hr)
  2181. {
  2182. #ifdef ENABLETRACE
  2183. WCHAR szGuid[c_cchGuidWithTerm];
  2184. StringFromGUID2(guid, szGuid, c_cchGuidWithTerm);
  2185. TraceTag(ttidNetSetup, "%s: ...%d] %S",
  2186. __FUNCNAME__, ++cAdapter, szGuid);
  2187. #endif
  2188. if (*pguid == guid)
  2189. {
  2190. hr = S_OK;
  2191. *ppncc = pINetCfgComponent;
  2192. break;
  2193. }
  2194. }
  2195. ReleaseObj(pINetCfgComponent);
  2196. }
  2197. TraceError(__FUNCNAME__, hr);
  2198. return hr;
  2199. }
  2200. //+---------------------------------------------------------------------------
  2201. //
  2202. // Function: CNetAdaptersPage::HrDoOemPostUpgradeProcessing
  2203. //
  2204. // Purpose: Call the post-upgrade functions from OEM DLL
  2205. //
  2206. // Arguments:
  2207. // pnc [in] pointer to INetCfg object
  2208. // hwndParent [in] handle of parent window
  2209. //
  2210. // Returns: S_OK on success, otherwise an error code
  2211. //
  2212. // Author: kumarp 10-September-98
  2213. //
  2214. // Notes:
  2215. //
  2216. HRESULT CNetAdaptersPage::HrDoOemPostUpgradeProcessing(IN INetCfg* pnc,
  2217. IN HWND hwndParent)
  2218. {
  2219. TraceFileFunc(ttidGuiModeSetup);
  2220. DefineFunctionName("CNetAdaptersPage::HrDoOemPostUpgradeProcessing");
  2221. TPtrListIter pos;
  2222. CNetComponent* pncTemp;
  2223. HRESULT hr=S_OK;
  2224. PCWSTR szInfID;
  2225. HKEY hkeyParams;
  2226. GUID guid;
  2227. INetCfgComponent* pncc=NULL;
  2228. pos = m_pnclComponents.begin();
  2229. while (pos != m_pnclComponents.end())
  2230. {
  2231. pncTemp = (CNetComponent*) *pos++;
  2232. AssertSz(pncTemp,
  2233. "HrDoOemPostUpgradeProcessing: pncTemp cannot be null!");
  2234. szInfID = pncTemp->InfID().c_str();
  2235. // cant process a component whose InfID is "Unknown"
  2236. //
  2237. if (!_wcsicmp(szInfID, c_szAfUnknown))
  2238. {
  2239. continue;
  2240. }
  2241. // we process only those components that specify OemDll
  2242. //
  2243. if (pncTemp->OemDll().empty())
  2244. {
  2245. continue;
  2246. }
  2247. Assert(!pncTemp->OemDir().empty());
  2248. TraceTag(ttidNetSetup, "%s: processing %S (%S)...",
  2249. __FUNCNAME__, pncTemp->Name().c_str(), szInfID);
  2250. pncTemp->GetInstanceGuid(&guid);
  2251. #ifdef ENABLETRACE
  2252. WCHAR szGuid[c_cchGuidWithTerm];
  2253. StringFromGUID2(guid, szGuid, c_cchGuidWithTerm);
  2254. TraceTag(ttidNetSetup, "%s: ...%S == %S",
  2255. __FUNCNAME__, pncTemp->Name().c_str(), szGuid);
  2256. #endif
  2257. hr = HrFindByInstanceGuid(pnc, m_lpguidDevClass,
  2258. &guid, &pncc);
  2259. if (S_OK == hr)
  2260. {
  2261. hr = pncc->OpenParamKey(&hkeyParams);
  2262. if (S_OK == hr)
  2263. {
  2264. hr = HrProcessOemComponent(
  2265. hwndParent,
  2266. pncTemp->OemDir().c_str(),
  2267. pncTemp->OemDll().c_str(),
  2268. &m_pnii->m_nui,
  2269. hkeyParams,
  2270. szInfID,
  2271. szInfID,
  2272. m_pnii->m_hinfAnswerFile,
  2273. pncTemp->m_strParamsSections.c_str());
  2274. NetSetupLogComponentStatus(szInfID,
  2275. SzLoadIds (IDS_PROCESSING_OEM), hr);
  2276. RegSafeCloseKey(hkeyParams);
  2277. }
  2278. ReleaseObj(pncc);
  2279. }
  2280. #ifdef ENABLETRACE
  2281. else
  2282. {
  2283. TraceTag(ttidNetSetup, "%s: ...could not locate %S",
  2284. __FUNCNAME__, pncTemp->Name().c_str());
  2285. }
  2286. #endif
  2287. }
  2288. TraceError(__FUNCNAME__, hr);
  2289. return hr;
  2290. }
  2291. //+---------------------------------------------------------------------------
  2292. //
  2293. // Function: CNetAdaptersPage::HrSetConnectionNames
  2294. //
  2295. // Purpose: Enumerate over each adapter specified in the answerfile
  2296. // and rename the corresponding connection if
  2297. // ConnectionName is specified for that adapter.
  2298. //
  2299. // Arguments: None
  2300. //
  2301. // Returns: S_OK on success, otherwise an error code
  2302. //
  2303. // Author: kumarp 23-September-98
  2304. //
  2305. // Notes:
  2306. //
  2307. HRESULT CNetAdaptersPage::HrSetConnectionNames()
  2308. {
  2309. TraceFileFunc(ttidGuiModeSetup);
  2310. DefineFunctionName("HrSetConnectionNames");
  2311. HRESULT hr=S_OK;
  2312. TPtrListIter pos;
  2313. CNetAdapter* pncTemp;
  2314. GUID guid;
  2315. PCWSTR szConnectionName;
  2316. PCWSTR szAdapterName;
  2317. pos = m_pnclComponents.begin();
  2318. while (pos != m_pnclComponents.end())
  2319. {
  2320. pncTemp = (CNetAdapter*) *pos++;
  2321. AssertSz(pncTemp,
  2322. "HrSetConnectionNames: pncTemp cannot be null!");
  2323. pncTemp->GetInstanceGuid(&guid);
  2324. if (GUID_NULL != guid)
  2325. {
  2326. szAdapterName = pncTemp->Name().c_str();
  2327. szConnectionName = pncTemp->ConnectionName();
  2328. if (wcslen(szConnectionName) > 0)
  2329. {
  2330. hr = HrSetLanConnectionName(&guid, szConnectionName);
  2331. if (S_OK == hr)
  2332. {
  2333. ShowProgressMessage(L"Name of the connection represented by '%s' set to '%s'", szAdapterName, szConnectionName);
  2334. }
  2335. else
  2336. {
  2337. ShowProgressMessage(L"Could not set name of the connection represented by '%s' to '%s'. Error code: 0x%lx", szAdapterName, szConnectionName, hr);
  2338. }
  2339. }
  2340. }
  2341. #ifdef ENABLETRACE
  2342. else
  2343. {
  2344. TraceTag (ttidNetSetup, "An exact owner could not be found for section %S", pncTemp->m_strParamsSections.c_str());
  2345. }
  2346. #endif
  2347. }
  2348. TraceError(__FUNCNAME__, hr);
  2349. return hr;
  2350. }
  2351. // ----------------------------------------------------------------------
  2352. //
  2353. // Function: CNetAdaptersPage::GetNewComponent
  2354. //
  2355. // Purpose: Create and return a new component suitabe for this class
  2356. //
  2357. // Arguments:
  2358. // pszName [in] name of component to create
  2359. //
  2360. // Returns: pointer to CNetComponent object created
  2361. //
  2362. // Author: kumarp 25-November-97
  2363. //
  2364. // Notes:
  2365. //
  2366. CNetComponent* CNetAdaptersPage::GetNewComponent(IN PCWSTR pszName)
  2367. {
  2368. TraceFileFunc(ttidGuiModeSetup);
  2369. AssertValidReadPtr(pszName);
  2370. return new CNetAdapter(pszName);
  2371. }
  2372. // ======================================================================
  2373. // class CNetProtocolsPage
  2374. // ======================================================================
  2375. // ----------------------------------------------------------------------
  2376. //
  2377. // Function: CNetProtocolsPage::CNetProtocolsPage
  2378. //
  2379. // Purpose: constructor for class CNetProtocolsPage
  2380. //
  2381. // Arguments:
  2382. // pnii [in] pointer to CNetInstallInfo object
  2383. //
  2384. // Returns: None
  2385. //
  2386. // Author: kumarp 25-November-97
  2387. //
  2388. // Notes:
  2389. //
  2390. CNetProtocolsPage::CNetProtocolsPage(IN CNetInstallInfo* pnii)
  2391. : CNetComponentsPageBase(pnii, &GUID_DEVCLASS_NETTRANS)
  2392. {
  2393. TraceFileFunc(ttidGuiModeSetup);
  2394. }
  2395. // ----------------------------------------------------------------------
  2396. //
  2397. // Function: CNetProtocolsPage::HrInitFromAnswerFile
  2398. //
  2399. // Purpose: Initialize from the [NetProtocols] section in the answerfile
  2400. //
  2401. // Arguments:
  2402. // pwifAnswerFile [in] pointer to CWInfFile object
  2403. //
  2404. // Returns: S_OK on success, otherwise an error code
  2405. //
  2406. // Author: kumarp 25-November-97
  2407. //
  2408. // Notes:
  2409. //
  2410. HRESULT CNetProtocolsPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
  2411. {
  2412. TraceFileFunc(ttidGuiModeSetup);
  2413. DefineFunctionName("CNetProtocolsPage::HrInitFromAnswerFile");
  2414. AssertValidReadPtr(pwifAnswerFile);
  2415. HRESULT hr;
  2416. hr = CNetComponentsPageBase::HrInitFromAnswerFile(pwifAnswerFile,
  2417. c_szAfSectionNetProtocols);
  2418. TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
  2419. return hr;
  2420. }
  2421. // ----------------------------------------------------------------------
  2422. //
  2423. // Function: CNetProtocolsPage::GetNewComponent
  2424. //
  2425. // Purpose: Create and return a new component suitabe for this class
  2426. //
  2427. // Arguments:
  2428. // pszName [in] name of
  2429. //
  2430. // Returns: pointer to CNetComponent object
  2431. //
  2432. // Author: kumarp 25-November-97
  2433. //
  2434. // Notes:
  2435. //
  2436. CNetComponent* CNetProtocolsPage::GetNewComponent(IN PCWSTR pszName)
  2437. {
  2438. TraceFileFunc(ttidGuiModeSetup);
  2439. AssertValidReadPtr(pszName);
  2440. return new CNetProtocol(pszName);
  2441. }
  2442. // ======================================================================
  2443. // class CNetServicesPage
  2444. // ======================================================================
  2445. // ----------------------------------------------------------------------
  2446. //
  2447. // Function: CNetServicesPage::CNetServicesPage
  2448. //
  2449. // Purpose: constructor for class CNetServicesPage
  2450. //
  2451. // Arguments:
  2452. // pnii [in] pointer to CNetInstallInfo object
  2453. //
  2454. // Returns: None
  2455. //
  2456. // Author: kumarp 25-November-97
  2457. //
  2458. // Notes:
  2459. //
  2460. CNetServicesPage::CNetServicesPage(IN CNetInstallInfo* pnii)
  2461. : CNetComponentsPageBase(pnii, &GUID_DEVCLASS_NETSERVICE)
  2462. {
  2463. TraceFileFunc(ttidGuiModeSetup);
  2464. }
  2465. // ----------------------------------------------------------------------
  2466. //
  2467. // Function: CNetServicesPage::HrInitFromAnswerFile
  2468. //
  2469. // Purpose: Initialize from the [NetServices] section in the answerfile
  2470. //
  2471. // Arguments:
  2472. // pwifAnswerFile [in] pointer to CWInfFile object
  2473. //
  2474. // Returns: S_OK on success, otherwise an error code
  2475. //
  2476. // Author: kumarp 25-November-97
  2477. //
  2478. // Notes:
  2479. //
  2480. HRESULT CNetServicesPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
  2481. {
  2482. TraceFileFunc(ttidGuiModeSetup);
  2483. DefineFunctionName("CNetServicesPage::HrInitFromAnswerFile");
  2484. AssertValidReadPtr(pwifAnswerFile);
  2485. HRESULT hr;
  2486. hr = CNetComponentsPageBase::HrInitFromAnswerFile(pwifAnswerFile,
  2487. c_szAfSectionNetServices);
  2488. TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
  2489. return hr;
  2490. }
  2491. // ----------------------------------------------------------------------
  2492. //
  2493. // Function: CNetServicesPage::GetNewComponent
  2494. //
  2495. // Purpose: Create and return a new component suitabe for this class
  2496. //
  2497. // Arguments:
  2498. // pszName [in] name of component to be created
  2499. //
  2500. // Returns: pointer to CNetComponent object
  2501. //
  2502. // Author: kumarp 25-November-97
  2503. //
  2504. // Notes:
  2505. //
  2506. CNetComponent* CNetServicesPage::GetNewComponent(IN PCWSTR pszName)
  2507. {
  2508. TraceFileFunc(ttidGuiModeSetup);
  2509. AssertValidReadPtr(pszName);
  2510. return new CNetService(pszName);
  2511. }
  2512. // ======================================================================
  2513. // class CNetClientsPage
  2514. // ======================================================================
  2515. // ----------------------------------------------------------------------
  2516. //
  2517. // Function: CNetClientsPage::CNetClientsPage
  2518. //
  2519. // Purpose: constructor for class CNetClientsPage
  2520. //
  2521. // Arguments:
  2522. // pnii [in] pointer to CNetInstallInfo object
  2523. //
  2524. // Returns: None
  2525. //
  2526. // Author: kumarp 25-November-97
  2527. //
  2528. // Notes:
  2529. //
  2530. CNetClientsPage::CNetClientsPage(IN CNetInstallInfo* pnii)
  2531. : CNetComponentsPageBase(pnii, &GUID_DEVCLASS_NETCLIENT)
  2532. {
  2533. TraceFileFunc(ttidGuiModeSetup);
  2534. }
  2535. // ----------------------------------------------------------------------
  2536. //
  2537. // Function: CNetClientsPage::HrInitFromAnswerFile
  2538. //
  2539. // Purpose: Initialize from the [NetClients] section in the answerfile
  2540. //
  2541. // Arguments:
  2542. // pwifAnswerFile [in] pointer to CWInfFile object
  2543. //
  2544. // Returns: S_OK on success, otherwise an error code
  2545. //
  2546. // Author: kumarp 25-November-97
  2547. //
  2548. // Notes:
  2549. //
  2550. HRESULT CNetClientsPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
  2551. {
  2552. TraceFileFunc(ttidGuiModeSetup);
  2553. DefineFunctionName("CNetClientsPage::HrInitFromAnswerFile");
  2554. AssertValidReadPtr(pwifAnswerFile);
  2555. HRESULT hr;
  2556. hr = CNetComponentsPageBase::HrInitFromAnswerFile(pwifAnswerFile,
  2557. c_szAfSectionNetClients);
  2558. TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
  2559. return hr;
  2560. }
  2561. // ----------------------------------------------------------------------
  2562. //
  2563. // Function: CNetClientsPage::GetNewComponent
  2564. //
  2565. // Purpose: Create and return a new component suitabe for this class
  2566. //
  2567. // Arguments:
  2568. // pszName [in] name of
  2569. //
  2570. // Returns: pointer to CNetComponent object
  2571. //
  2572. // Author: kumarp 25-November-97
  2573. //
  2574. // Notes:
  2575. //
  2576. CNetComponent* CNetClientsPage::GetNewComponent(IN PCWSTR pszName)
  2577. {
  2578. TraceFileFunc(ttidGuiModeSetup);
  2579. AssertValidReadPtr(pszName);
  2580. return new CNetClient(pszName);
  2581. }
  2582. // ======================================================================
  2583. // class CNetBindingsPage
  2584. // ======================================================================
  2585. // ----------------------------------------------------------------------
  2586. //
  2587. // Function: CNetBindingsPage::CNetBindingsPage
  2588. //
  2589. // Purpose: constructor for class CNetBindingsPage
  2590. //
  2591. // Arguments:
  2592. // pnii [in] pointer to CNetInstallInfo object
  2593. //
  2594. // Returns: None
  2595. //
  2596. // Author: kumarp 25-November-97
  2597. //
  2598. // Notes:
  2599. //
  2600. CNetBindingsPage::CNetBindingsPage(IN CNetInstallInfo* pnii)
  2601. {
  2602. TraceFileFunc(ttidGuiModeSetup);
  2603. AssertValidReadPtr(pnii);
  2604. m_pnii = pnii;
  2605. }
  2606. // ----------------------------------------------------------------------
  2607. //
  2608. // Function: CNetBindingsPage::HrInitFromAnswerFile
  2609. //
  2610. // Purpose: Initialize from the [NetBindings] section in the answerfile
  2611. //
  2612. // Arguments:
  2613. // pwifAnswerFile [in] pointer to CWInfFile object
  2614. //
  2615. // Returns: S_OK on success, otherwise an error code
  2616. //
  2617. // Author: kumarp 25-November-97
  2618. //
  2619. // Notes:
  2620. //
  2621. HRESULT CNetBindingsPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
  2622. {
  2623. TraceFileFunc(ttidGuiModeSetup);
  2624. DefineFunctionName("CNetBindingsPage::HrInitFromAnswerFile");
  2625. AssertValidReadPtr(pwifAnswerFile);
  2626. HRESULT hr;
  2627. PCWInfSection pwisBindings;
  2628. pwisBindings = pwifAnswerFile->FindSection(c_szAfSectionNetBindings);
  2629. if (!pwisBindings)
  2630. {
  2631. //it is not an error if the Bindings section is missing
  2632. return S_OK;
  2633. }
  2634. EraseAndDeleteAll(m_plBindingActions);
  2635. hr = E_OUTOFMEMORY;
  2636. CBindingAction* pba = new CBindingAction();
  2637. if (pba)
  2638. {
  2639. hr = S_OK;
  2640. PCWInfKey pwikKey;
  2641. for (pwikKey = pwisBindings->FirstKey();
  2642. pwikKey;
  2643. pwikKey = pwisBindings->NextKey())
  2644. {
  2645. HRESULT hrT = pba->HrInitFromAnswerFile(pwikKey);
  2646. if (S_OK == hrT)
  2647. {
  2648. AddAtEndOfPtrList(m_plBindingActions, pba);
  2649. pba = new CBindingAction();
  2650. if (!pba)
  2651. {
  2652. hr = E_OUTOFMEMORY;
  2653. break;
  2654. }
  2655. }
  2656. }
  2657. delete pba;
  2658. }
  2659. TraceFunctionError(hr);
  2660. return hr;
  2661. }
  2662. // ----------------------------------------------------------------------
  2663. //
  2664. // Function: CNetBindingsPage::HrDoUnattended
  2665. //
  2666. // Purpose: Perform instrunctions specified in the [NetBindings] section
  2667. // in the answerfile
  2668. //
  2669. // Arguments:
  2670. // hwndParent [in] handle of parent window
  2671. // pnc [in] pointer to INetCfg object
  2672. //
  2673. // Returns: S_OK on success, otherwise an error code
  2674. //
  2675. // Author: kumarp 25-November-97
  2676. //
  2677. // Notes:
  2678. //
  2679. HRESULT
  2680. CNetBindingsPage::HrDoUnattended (
  2681. IN INetCfg* pnc)
  2682. {
  2683. TraceFileFunc(ttidGuiModeSetup);
  2684. DefineFunctionName("CNetBindingsPage::HrDoUnattended");
  2685. HRESULT hr;
  2686. if (m_plBindingActions.size() > 0)
  2687. {
  2688. ShowProgressMessage(L"Applying bindings...");
  2689. }
  2690. else
  2691. {
  2692. ShowProgressMessage(L"No binding actions to apply");
  2693. }
  2694. TPtrListIter pos = m_plBindingActions.begin();
  2695. CBindingAction* pba;
  2696. while (pos != m_plBindingActions.end())
  2697. {
  2698. pba = (CBindingAction*) *pos++;
  2699. // ignore the return code so that we can try to perform
  2700. // remaining actions
  2701. hr = pba->HrPerformAction(pnc);
  2702. }
  2703. hr = pnc->Apply();
  2704. TraceFunctionError(hr);
  2705. return hr;
  2706. }
  2707. // ======================================================================
  2708. // class CBindingAction
  2709. // ======================================================================
  2710. CNetInstallInfo* CBindingAction::m_pnii = NULL;
  2711. //+---------------------------------------------------------------------------
  2712. //
  2713. // Function: CBindingAction::CBindingAction
  2714. //
  2715. // Purpose: constructor
  2716. //
  2717. // Arguments: (none)
  2718. //
  2719. //
  2720. // Returns: none
  2721. //
  2722. // Author: kumarp 05-July-97
  2723. //
  2724. // Notes:
  2725. //
  2726. CBindingAction::CBindingAction()
  2727. {
  2728. TraceFileFunc(ttidGuiModeSetup);
  2729. m_eBindingAction = BND_Unknown;
  2730. }
  2731. //+---------------------------------------------------------------------------
  2732. //
  2733. // Function: CBindingAction::~CBindingAction
  2734. //
  2735. // Purpose: destructor
  2736. //
  2737. // Arguments: (none)
  2738. //
  2739. // Returns: none
  2740. //
  2741. // Author: kumarp 05-July-97
  2742. //
  2743. // Notes:
  2744. //
  2745. CBindingAction::~CBindingAction()
  2746. {
  2747. }
  2748. //+---------------------------------------------------------------------------
  2749. //
  2750. // Function: MapBindingActionName
  2751. //
  2752. // Purpose: maps the answerfile token to appropriate binding action
  2753. //
  2754. // Arguments:
  2755. // pszActionName [in] answer-file token, e.g. "Disable"
  2756. //
  2757. // Returns: enum for binding action, or BND_Unknown if incorrect token passed
  2758. //
  2759. // Author: kumarp 05-July-97
  2760. //
  2761. // Notes:
  2762. //
  2763. EBindingAction MapBindingActionName(IN PCWSTR pszActionName)
  2764. {
  2765. TraceFileFunc(ttidGuiModeSetup);
  2766. AssertValidReadPtr(pszActionName);
  2767. if (!_wcsicmp(c_szAfEnable, pszActionName))
  2768. return BND_Enable;
  2769. else if (!_wcsicmp(c_szAfDisable, pszActionName))
  2770. return BND_Disable;
  2771. else if (!_wcsicmp(c_szAfPromote, pszActionName))
  2772. return BND_Promote;
  2773. else if (!_wcsicmp(c_szAfDemote, pszActionName))
  2774. return BND_Demote;
  2775. else
  2776. return BND_Unknown;
  2777. }
  2778. //+---------------------------------------------------------------------------
  2779. //
  2780. // Function: CBindingAction::HrInitFromAnswerFile
  2781. //
  2782. // Purpose: Reads value of a single key passed as argument and initializes
  2783. // internal data
  2784. //
  2785. // Arguments:
  2786. // pwikKey [in] pointer to CWInfKey
  2787. //
  2788. // Returns: S_OK if success or NETSETUP_E_ANS_FILE_ERROR on failure
  2789. //
  2790. // Author: kumarp 05-July-97
  2791. //
  2792. // Notes:
  2793. //
  2794. HRESULT CBindingAction::HrInitFromAnswerFile(IN const CWInfKey* pwikKey)
  2795. {
  2796. TraceFileFunc(ttidGuiModeSetup);
  2797. DefineFunctionName("CBindingAction::HrInitFromAnswerFile");
  2798. AssertValidReadPtr(pwikKey);
  2799. HRESULT hr=E_FAIL;
  2800. tstring strComponent;
  2801. TStringListIter pos;
  2802. m_eBindingAction = MapBindingActionName(pwikKey->Name());
  2803. if (m_eBindingAction == BND_Unknown)
  2804. {
  2805. AddAnswerFileError(c_szAfSectionNetBindings,
  2806. pwikKey->Name(),
  2807. IDS_E_AF_InvalidBindingAction);
  2808. hr = NETSETUP_E_ANS_FILE_ERROR;
  2809. }
  2810. else
  2811. {
  2812. BOOL fStatus;
  2813. TStringList slComponents;
  2814. #if DBG
  2815. m_strBindingPath = pwikKey->GetStringValue(c_szAfUnknown);
  2816. #endif
  2817. fStatus = pwikKey->GetStringListValue(m_slBindingPath);
  2818. DWORD cComponentsInBindingPath = m_slBindingPath.size();
  2819. // we need binding path to have atleast 2 items
  2820. // e.g. Disable=service1,proto1,adapter1
  2821. // we do not process binding actions like
  2822. // Disable=proto1,adapter1 or Disable=adapter1
  2823. //
  2824. if (!fStatus || (cComponentsInBindingPath < 2))
  2825. {
  2826. AddAnswerFileError(c_szAfSectionNetBindings,
  2827. pwikKey->Name(),
  2828. IDS_E_AF_InvalidValueForThisKey);
  2829. hr = NETSETUP_E_ANS_FILE_ERROR;
  2830. #if DBG
  2831. if (cComponentsInBindingPath < 2)
  2832. {
  2833. ShowProgressMessage(L"ignored binding path %s of length %d",
  2834. m_strBindingPath.c_str(),
  2835. cComponentsInBindingPath);
  2836. }
  2837. #endif
  2838. }
  2839. else
  2840. {
  2841. hr = S_OK;
  2842. }
  2843. }
  2844. TraceFunctionError(hr);
  2845. return hr;
  2846. }
  2847. // =================================================================
  2848. // Add to common
  2849. //+---------------------------------------------------------------------------
  2850. //
  2851. // Function: ReleaseINetCfgComponentsAndEraseList
  2852. //
  2853. // Purpose: releases INetCfgComponent pointers in the passed list
  2854. // and then erases the list
  2855. //
  2856. // Arguments:
  2857. // pplComponents [in] list of INetCfgComponent pointers
  2858. //
  2859. // Returns: none
  2860. //
  2861. // Author: kumarp 05-July-97
  2862. //
  2863. // Notes: Does NOT free the passed list
  2864. //
  2865. void ReleaseINetCfgComponentsAndEraseList(TPtrList* pplComponents)
  2866. {
  2867. TraceFileFunc(ttidGuiModeSetup);
  2868. INetCfgComponent* pncc;
  2869. TPtrListIter pos;
  2870. pos = pplComponents->begin();
  2871. while (pos != pplComponents->end())
  2872. {
  2873. pncc = (INetCfgComponent*) *pos++;
  2874. ReleaseObj(pncc);
  2875. }
  2876. EraseAll(pplComponents);
  2877. }
  2878. //+---------------------------------------------------------------------------
  2879. //
  2880. // Function: HrGetBindingPathStr
  2881. //
  2882. // Purpose: Gets a string representation of a given binding-path
  2883. //
  2884. // Arguments:
  2885. // pncbp [in] binding path
  2886. // pstrBindingPath [out] string representation of the binding path
  2887. //
  2888. // Returns: S_OK if success, error code returned by respective COM
  2889. // interfaces otherwise
  2890. //
  2891. // Author: kumarp 05-July-97
  2892. //
  2893. // Notes:
  2894. //
  2895. HRESULT HrGetBindingPathStr(INetCfgBindingPath *pncbp, tstring* pstrBindingPath)
  2896. {
  2897. TraceFileFunc(ttidGuiModeSetup);
  2898. DefineFunctionName("HrGetBindingPathStr");
  2899. AssertValidReadPtr(pncbp);
  2900. AssertValidWritePtr(pstrBindingPath);
  2901. HRESULT hr=S_OK;
  2902. CIterNetCfgBindingInterface ncbiIter(pncbp);
  2903. INetCfgBindingInterface * pncbi;
  2904. INetCfgComponent * pncc = NULL;
  2905. BOOL fFirstInterface=TRUE;
  2906. PWSTR szInfId;
  2907. while (SUCCEEDED(hr) && (S_OK == (hr = ncbiIter.HrNext(&pncbi))))
  2908. {
  2909. if (fFirstInterface)
  2910. {
  2911. fFirstInterface = FALSE;
  2912. hr = pncbi->GetUpperComponent(&pncc);
  2913. if (SUCCEEDED(hr))
  2914. {
  2915. hr = pncc->GetId(&szInfId);
  2916. ReleaseObj(pncc);
  2917. if (SUCCEEDED(hr))
  2918. {
  2919. *pstrBindingPath = szInfId;
  2920. CoTaskMemFree(szInfId);
  2921. }
  2922. }
  2923. }
  2924. if (SUCCEEDED(hr))
  2925. {
  2926. hr = pncbi->GetLowerComponent(&pncc);
  2927. if (SUCCEEDED(hr))
  2928. {
  2929. hr = pncc->GetId(&szInfId);
  2930. if (SUCCEEDED(hr))
  2931. {
  2932. AssertSz(!fFirstInterface, "fFirstInterface should be FALSE");
  2933. if (!pstrBindingPath->empty())
  2934. {
  2935. *pstrBindingPath += L" -> ";
  2936. }
  2937. *pstrBindingPath += szInfId;
  2938. CoTaskMemFree(szInfId);
  2939. }
  2940. ReleaseObj(pncc);
  2941. }
  2942. }
  2943. ReleaseObj(pncbi);
  2944. }
  2945. if (hr == S_FALSE)
  2946. {
  2947. hr = S_OK;
  2948. }
  2949. TraceError(__FUNCNAME__, hr);
  2950. return hr;
  2951. }
  2952. #if DBG
  2953. //+---------------------------------------------------------------------------
  2954. //
  2955. // Function: TraceBindPath
  2956. //
  2957. // Purpose: Traces string representation of a given binding-path using
  2958. // the given trace id
  2959. //
  2960. // Arguments:
  2961. // pncbp [in] binding path
  2962. // ttid [out] trace tag id as defined in tracetag.cpp
  2963. //
  2964. // Returns: none
  2965. //
  2966. // Author: kumarp 05-July-97
  2967. //
  2968. // Notes:
  2969. //
  2970. void TraceBindPath(INetCfgBindingPath *pncbp, TraceTagId ttid)
  2971. {
  2972. TraceFileFunc(ttidGuiModeSetup);
  2973. AssertValidReadPtr(pncbp);
  2974. tstring strBindingPath;
  2975. HRESULT hr;
  2976. hr = HrGetBindingPathStr(pncbp, &strBindingPath);
  2977. if (SUCCEEDED(hr))
  2978. {
  2979. TraceTag(ttid, "Binding path = %S", strBindingPath.c_str());
  2980. }
  2981. else
  2982. {
  2983. TraceTag(ttid, "Error dumping binding path.");
  2984. }
  2985. }
  2986. #endif
  2987. // =================================================================
  2988. //+---------------------------------------------------------------------------
  2989. //
  2990. // Function: HrGetINetCfgComponentOfComponentsInBindingPath
  2991. //
  2992. // Purpose: Finds the INetCfgComponent interface of all components in a
  2993. // binding path.
  2994. //
  2995. // Arguments:
  2996. // pncbp [in] binding path
  2997. // pplComponents [out] list of INetCfgComponent
  2998. //
  2999. // Returns: S_OK if found all, or an error code if not.
  3000. //
  3001. // Author: kumarp 05-July-97
  3002. //
  3003. // Notes:
  3004. // Makes error handling easier since this returns either all components
  3005. // or none.
  3006. // The caller must release the INetCfgComponent interfaces thus obtained.
  3007. //
  3008. HRESULT HrGetINetCfgComponentOfComponentsInBindingPath(IN INetCfgBindingPath* pncbp,
  3009. OUT TPtrList* pplComponents)
  3010. {
  3011. TraceFileFunc(ttidGuiModeSetup);
  3012. DefineFunctionName("HrGetINetCfgComponentOfComponentsInBindingPath");
  3013. AssertValidReadPtr(pncbp);
  3014. AssertValidWritePtr(pplComponents);
  3015. HRESULT hr=S_OK;
  3016. CIterNetCfgBindingInterface ncbiIter(pncbp);
  3017. INetCfgBindingInterface * pncbi;
  3018. INetCfgComponent * pncc = NULL;
  3019. BOOL fFirstInterface = TRUE;
  3020. while (SUCCEEDED(hr) && (S_OK == (hr = ncbiIter.HrNext(&pncbi))))
  3021. {
  3022. if (fFirstInterface)
  3023. {
  3024. fFirstInterface = FALSE;
  3025. hr = pncbi->GetUpperComponent(&pncc);
  3026. if (SUCCEEDED(hr))
  3027. {
  3028. pplComponents->push_back(pncc);
  3029. }
  3030. }
  3031. if (SUCCEEDED(hr))
  3032. {
  3033. hr = pncbi->GetLowerComponent(&pncc);
  3034. if (SUCCEEDED(hr))
  3035. {
  3036. AssertSz(!fFirstInterface, "fFirstInterface shouldn't be TRUE");
  3037. pplComponents->push_back(pncc);
  3038. }
  3039. }
  3040. ReleaseObj(pncbi);
  3041. if (SUCCEEDED(hr))
  3042. {
  3043. DWORD dwcc=0;
  3044. hr = pncc->GetCharacteristics(&dwcc);
  3045. if (S_OK == hr)
  3046. {
  3047. if (dwcc & NCF_DONTEXPOSELOWER)
  3048. {
  3049. // if this component does not want to expose components
  3050. // below it, set hr to end the while loop
  3051. //
  3052. hr = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  3053. #ifdef ENABLETRACE
  3054. PWSTR szInfId;
  3055. BOOL fFree = TRUE;
  3056. if (FAILED(pncc->GetId(&szInfId)))
  3057. {
  3058. szInfId = L"<GetId failed!>";
  3059. fFree = FALSE;
  3060. }
  3061. TraceTag(ttidNetSetup,
  3062. "%s: Component '%S' has NCF_DONTEXPOSELOWER "
  3063. "set. Further components will not be added to "
  3064. "the list of INetCfgComponent in this binding path",
  3065. __FUNCNAME__, szInfId);
  3066. if (fFree)
  3067. {
  3068. CoTaskMemFree(szInfId);
  3069. }
  3070. #endif
  3071. }
  3072. }
  3073. }
  3074. }
  3075. if ((hr == S_FALSE) ||
  3076. (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)))
  3077. {
  3078. hr = S_OK;
  3079. }
  3080. else if (FAILED(hr))
  3081. {
  3082. // need to release all INetCfgComponent found so far
  3083. ReleaseINetCfgComponentsAndEraseList(pplComponents);
  3084. }
  3085. TraceError(__FUNCNAME__, hr);
  3086. return hr;
  3087. }
  3088. //+---------------------------------------------------------------------------
  3089. //
  3090. // Function: HrGetInstanceGuidOfComponents
  3091. //
  3092. // Purpose: Finds the instance guid of all INetCfgComponents in a list
  3093. //
  3094. // Arguments:
  3095. // pplINetCfgComponent [in] list of INetCfgComponent interfaces
  3096. // pplInstanceGuids [out] list of instance guids
  3097. //
  3098. // Returns: S_OK if found all, or an error code if not.
  3099. //
  3100. // Author: kumarp 05-July-97
  3101. //
  3102. // Notes:
  3103. // Makes error handling easier since this returns either all instance guids
  3104. // or none.
  3105. // The caller must free each instance guid and the list elements.
  3106. //
  3107. HRESULT HrGetInstanceGuidOfComponents(IN TPtrList* pplINetCfgComponent,
  3108. OUT TPtrList* pplInstanceGuids)
  3109. {
  3110. TraceFileFunc(ttidGuiModeSetup);
  3111. DefineFunctionName("HrGetInstanceGuidOfComponents");
  3112. HRESULT hr = S_OK;
  3113. TPtrListIter iter;
  3114. INetCfgComponent* pncc;
  3115. GUID guidComponentInstance;
  3116. for (iter = pplINetCfgComponent->begin();
  3117. (iter != pplINetCfgComponent->end()) && (S_OK == hr);
  3118. iter++)
  3119. {
  3120. pncc = (INetCfgComponent*) *iter;
  3121. Assert (pncc);
  3122. hr = pncc->GetInstanceGuid(&guidComponentInstance);
  3123. if (S_OK == hr)
  3124. {
  3125. GUID* pguidTemp = new GUID;
  3126. if (pguidTemp)
  3127. {
  3128. *pguidTemp = guidComponentInstance;
  3129. pplInstanceGuids->push_back(pguidTemp);
  3130. }
  3131. else
  3132. {
  3133. hr = E_OUTOFMEMORY;
  3134. }
  3135. }
  3136. }
  3137. if (S_OK != hr)
  3138. {
  3139. // need to free all instace guids found so far
  3140. EraseAndDeleteAll(pplInstanceGuids);
  3141. }
  3142. TraceError(__FUNCNAME__, hr);
  3143. return hr;
  3144. }
  3145. //+---------------------------------------------------------------------------
  3146. //
  3147. // Function: HrGetInstanceGuidOfComponentsInBindingPath
  3148. //
  3149. // Purpose: Finds the instance guid of all components in a binding path.
  3150. //
  3151. // Arguments:
  3152. // pncbp [in] binding path
  3153. // pplComponentGuids [out] list of instance guids
  3154. //
  3155. // Returns: S_OK if found all, or an error code if not.
  3156. //
  3157. // Author: kumarp 05-July-97
  3158. //
  3159. // Notes:
  3160. // Makes error handling easier since this returns either all components
  3161. // or none.
  3162. // The caller must free each instance guid and the list elements.
  3163. //
  3164. HRESULT HrGetInstanceGuidOfComponentsInBindingPath(IN INetCfgBindingPath* pncbp,
  3165. OUT TPtrList* pplComponentGuids)
  3166. {
  3167. TraceFileFunc(ttidGuiModeSetup);
  3168. DefineFunctionName("HrGetInstanceGuidOfComponentsInBindingPath");
  3169. HRESULT hr=E_FAIL;
  3170. TPtrList plINetCfgComponent;
  3171. hr = HrGetINetCfgComponentOfComponentsInBindingPath(pncbp, &plINetCfgComponent);
  3172. if (SUCCEEDED(hr))
  3173. {
  3174. hr = HrGetInstanceGuidOfComponents(&plINetCfgComponent,
  3175. pplComponentGuids);
  3176. ReleaseINetCfgComponentsAndEraseList(&plINetCfgComponent);
  3177. }
  3178. TraceError(__FUNCNAME__, hr);
  3179. return hr;
  3180. }
  3181. //+---------------------------------------------------------------------------
  3182. //
  3183. // Function: HrGetInstanceGuidOfComponentInAnswerFile
  3184. //
  3185. // Purpose: Finds the instance guid of a component specified in the answerfile
  3186. // or an already installed component
  3187. //
  3188. // Arguments:
  3189. // pszComponentName [in] component id to find.
  3190. // pguid [out] instance guid of the component
  3191. //
  3192. // Returns: S_OK if found, S_FALSE if not, or an error code.
  3193. //
  3194. // Author: kumarp 05-July-97
  3195. //
  3196. // Notes: Caller must free the instance guid
  3197. //
  3198. HRESULT
  3199. HrGetInstanceGuidOfComponentInAnswerFile (
  3200. IN INetCfg* pnc,
  3201. IN PCWSTR pszComponentName,
  3202. OUT LPGUID pguid)
  3203. {
  3204. TraceFileFunc(ttidGuiModeSetup);
  3205. DefineFunctionName("HrGetInstanceGuidOfComponentInAnswerFile");
  3206. TraceFunctionEntry(ttidNetSetup);
  3207. AssertValidReadPtr(pnc);
  3208. AssertValidReadPtr(pszComponentName);
  3209. AssertValidWritePtr(pguid);
  3210. AssertValidReadPtr(g_pnii);
  3211. #if DBG
  3212. tstring strGuid;
  3213. #endif
  3214. HRESULT hr=E_FAIL;
  3215. if (!g_pnii->AnswerFileInitialized())
  3216. {
  3217. hr = E_FAIL;
  3218. goto return_from_function;
  3219. }
  3220. INetCfgComponent* pncc;
  3221. hr = pnc->FindComponent(pszComponentName, &pncc);
  3222. if (hr == S_OK)
  3223. {
  3224. hr = pncc->GetInstanceGuid(pguid);
  3225. ReleaseObj(pncc);
  3226. }
  3227. else if (S_FALSE == hr)
  3228. {
  3229. TraceTag(ttidNetSetup, "%s: '%S' is not installed on system, "
  3230. "let's see if is in the answerfile",
  3231. __FUNCNAME__, pszComponentName);
  3232. // couldnt find as an installed component, try to see if it is
  3233. // in the answer-file-map
  3234. //
  3235. CNetComponent* pnc;
  3236. pnc = g_pnii->Find(pszComponentName);
  3237. if (!pnc)
  3238. {
  3239. hr = S_FALSE;
  3240. }
  3241. else
  3242. {
  3243. pnc->GetInstanceGuid(pguid);
  3244. hr = S_OK;
  3245. }
  3246. }
  3247. #if DBG
  3248. if (S_OK == hr)
  3249. {
  3250. WCHAR szGuid[c_cchGuidWithTerm];
  3251. StringFromGUID2(*pguid, szGuid, c_cchGuidWithTerm);
  3252. strGuid = szGuid;
  3253. }
  3254. else
  3255. {
  3256. strGuid = c_szAfUnknown;
  3257. }
  3258. TraceTag(ttidNetSetup, "%s: %S = %S",
  3259. __FUNCNAME__, pszComponentName, strGuid.c_str());
  3260. #endif
  3261. NetSetupLogComponentStatus(pszComponentName,
  3262. SzLoadIds (IDS_GETTING_INSTANCE_GUID), hr);
  3263. return_from_function:
  3264. TraceFunctionError((S_FALSE == hr) ? S_OK : hr);
  3265. return hr;
  3266. }
  3267. //+---------------------------------------------------------------------------
  3268. //
  3269. // Function: HrGetInstanceGuidOfComponentsInAnswerFile
  3270. //
  3271. // Purpose: Finds the instance guid of a component specified in the answerfile
  3272. // or an already installed component
  3273. //
  3274. // Arguments:
  3275. // pslComponents [in] list of component ids to find.
  3276. // pguid [out] list of instance guids
  3277. //
  3278. // Returns: S_OK if found all, or an error code.
  3279. //
  3280. // Author: kumarp 05-July-97
  3281. //
  3282. // Notes: Caller must free the instance guids and the list items.
  3283. //
  3284. HRESULT HrGetInstanceGuidOfComponentsInAnswerFile(
  3285. IN INetCfg* pnc,
  3286. IN TStringList* pslComponents,
  3287. OUT TPtrList* pplComponentGuids)
  3288. {
  3289. TraceFileFunc(ttidGuiModeSetup);
  3290. DefineFunctionName("HrGetInstanceGuidOfComponentsInAnswerFile");
  3291. AssertValidReadPtr(pnc);
  3292. AssertValidReadPtr(pslComponents);
  3293. AssertValidWritePtr(pplComponentGuids);
  3294. HRESULT hr = S_OK;
  3295. TStringListIter iter;
  3296. tstring* pstr;
  3297. GUID guidComponentInstance;
  3298. for (iter = pslComponents->begin();
  3299. (iter != pslComponents->end()) && (S_OK == hr);
  3300. iter++)
  3301. {
  3302. pstr = *iter;
  3303. hr = HrGetInstanceGuidOfComponentInAnswerFile(
  3304. pnc, pstr->c_str(), &guidComponentInstance);
  3305. if (hr == S_OK)
  3306. {
  3307. GUID* pguidTemp = new GUID;
  3308. if (pguidTemp)
  3309. {
  3310. *pguidTemp = guidComponentInstance;
  3311. pplComponentGuids->push_back(pguidTemp);
  3312. }
  3313. else
  3314. {
  3315. hr = E_OUTOFMEMORY;
  3316. }
  3317. }
  3318. }
  3319. if (S_OK != hr)
  3320. {
  3321. // need to free all instace guids found so far
  3322. EraseAndDeleteAll(pplComponentGuids);
  3323. }
  3324. TraceError(__FUNCNAME__, hr);
  3325. return hr;
  3326. }
  3327. //+---------------------------------------------------------------------------
  3328. //
  3329. // Function: FAreBindingPathsEqual
  3330. //
  3331. // Purpose: Compares two representations of binding paths to find
  3332. // if they represent the same binding path
  3333. //
  3334. // Arguments:
  3335. // pncbp [in] binding path 1
  3336. // pplBindingPathComponentGuids2 [in] list of instance guids representing
  3337. // binding path 2
  3338. //
  3339. // Returns: TRUE if paths are equal, FALSE otherwise
  3340. //
  3341. // Author: kumarp 05-July-97
  3342. //
  3343. // Notes:
  3344. //
  3345. BOOL FAreBindingPathsEqual(INetCfgBindingPath* pncbp,
  3346. TPtrList* pplBindingPathComponentGuids2)
  3347. {
  3348. TraceFileFunc(ttidGuiModeSetup);
  3349. DefineFunctionName("FAreBindingPathsEqual");
  3350. BOOL fEqual = FALSE;
  3351. HRESULT hr=E_FAIL;
  3352. TPtrList plBindingPathComponentGuids1;
  3353. hr = HrGetInstanceGuidOfComponentsInBindingPath(pncbp, &plBindingPathComponentGuids1);
  3354. if (SUCCEEDED(hr))
  3355. {
  3356. // now compare the two lists to see if they are equal
  3357. if (plBindingPathComponentGuids1.size() ==
  3358. pplBindingPathComponentGuids2->size())
  3359. {
  3360. fEqual = TRUE;
  3361. TPtrListIter pos1, pos2;
  3362. GUID guid1, guid2;
  3363. pos1 = plBindingPathComponentGuids1.begin();
  3364. pos2 = pplBindingPathComponentGuids2->begin();
  3365. while (fEqual && (pos1 != plBindingPathComponentGuids1.end()))
  3366. {
  3367. AssertSz(pos2 != pplBindingPathComponentGuids2->end(),
  3368. "reached end of other list ??");
  3369. guid1 = *((LPGUID) *pos1++);
  3370. guid2 = *((LPGUID) *pos2++);
  3371. fEqual = (guid1 == guid2);
  3372. }
  3373. }
  3374. EraseAndDeleteAll(plBindingPathComponentGuids1);
  3375. }
  3376. TraceError(__FUNCNAME__, hr);
  3377. return fEqual;
  3378. }
  3379. //+---------------------------------------------------------------------------
  3380. //
  3381. // Function: HrGetBindingPathFromStringList
  3382. //
  3383. // Purpose: Finds the binding path represented by a list of string tokens.
  3384. // Each token in the list may either be InfID of a networking
  3385. // component or a component specified in the answerfile.
  3386. //
  3387. // Arguments:
  3388. // pnc [in] INetCfg interface
  3389. // pslBindingPath [in] list of component ids to find.
  3390. // ppncbp [out] INetCfgBindingPath
  3391. //
  3392. // Returns: S_OK if found, S_FALSE if not found or an error code.
  3393. //
  3394. // Author: kumarp 05-July-97
  3395. //
  3396. // Notes: Caller must release the binding path
  3397. //
  3398. HRESULT HrGetBindingPathFromStringList(IN INetCfg* pnc,
  3399. IN TStringList* pslBindingPath,
  3400. OUT INetCfgBindingPath** ppncbp)
  3401. {
  3402. TraceFileFunc(ttidGuiModeSetup);
  3403. DefineFunctionName("GetBindingPathFromStringList");
  3404. HRESULT hr=S_FALSE;
  3405. //initialize out param
  3406. *ppncbp = NULL;
  3407. #if DBG
  3408. tstring strBindingPath;
  3409. ConvertStringListToCommaList(*pslBindingPath, strBindingPath);
  3410. TraceTag(ttidNetSetup, "%s: trying to find binding path: %S", __FUNCNAME__,
  3411. strBindingPath.c_str());
  3412. #endif
  3413. TPtrList plComponentGuids;
  3414. TStringListIter pos;
  3415. pos = pslBindingPath->begin();
  3416. tstring strTopComponent;
  3417. strTopComponent = **pos++;
  3418. INetCfgComponent* pnccTop;
  3419. BOOL fFound=FALSE;
  3420. hr = pnc->FindComponent(strTopComponent.c_str(), &pnccTop);
  3421. if (hr == S_OK)
  3422. {
  3423. hr = HrGetInstanceGuidOfComponentsInAnswerFile(pnc,
  3424. pslBindingPath,
  3425. &plComponentGuids);
  3426. if (hr == S_OK)
  3427. {
  3428. CIterNetCfgBindingPath ncbpIter(pnccTop);
  3429. INetCfgBindingPath* pncbp;
  3430. while (!fFound && (S_OK == (hr = ncbpIter.HrNext(&pncbp))))
  3431. {
  3432. #if DBG
  3433. TraceBindPath(pncbp, ttidNetSetup);
  3434. #endif
  3435. if (FAreBindingPathsEqual(pncbp, &plComponentGuids))
  3436. {
  3437. *ppncbp = pncbp;
  3438. fFound = TRUE;
  3439. }
  3440. else
  3441. {
  3442. ReleaseObj(pncbp);
  3443. }
  3444. }
  3445. EraseAndDeleteAll(plComponentGuids);
  3446. if (!fFound && (SUCCEEDED(hr)))
  3447. {
  3448. hr = S_FALSE;
  3449. }
  3450. }
  3451. ReleaseObj(pnccTop);
  3452. }
  3453. #if DBG
  3454. if (hr != S_OK)
  3455. {
  3456. TraceTag(ttidNetSetup, "%s: could not find binding path: %S", __FUNCNAME__,
  3457. strBindingPath.c_str());
  3458. }
  3459. #endif
  3460. TraceError(__FUNCNAME__, (S_FALSE == hr) ? S_OK : hr);
  3461. return hr;
  3462. }
  3463. //+---------------------------------------------------------------------------
  3464. //
  3465. // Function: CBindingAction::HrPerformAction
  3466. //
  3467. // Purpose: Performs the binding action specified in the answerfile
  3468. //
  3469. // Arguments: none
  3470. //
  3471. // Returns: S_OK if success, or an error code.
  3472. //
  3473. // Author: kumarp 05-July-97
  3474. //
  3475. // Notes:
  3476. //
  3477. HRESULT CBindingAction::HrPerformAction(IN INetCfg* pnc)
  3478. {
  3479. TraceFileFunc(ttidGuiModeSetup);
  3480. DefineFunctionName("CBindingAction::HrPerformAction");
  3481. HRESULT hr=S_OK;
  3482. INetCfgBindingPath* pINetCfgBindingPath;
  3483. AssertValidReadPtr(m_pnii);
  3484. #if DBG
  3485. switch (m_eBindingAction)
  3486. {
  3487. case BND_Enable:
  3488. TraceTag(ttidNetSetup, "%s: Enabling: %S",
  3489. __FUNCNAME__, m_strBindingPath.c_str());
  3490. break;
  3491. case BND_Disable:
  3492. TraceTag(ttidNetSetup, "%s: Disabling: %S",
  3493. __FUNCNAME__, m_strBindingPath.c_str());
  3494. break;
  3495. case BND_Promote:
  3496. TraceTag(ttidNetSetup, "%s: Promoting: %S",
  3497. __FUNCNAME__, m_strBindingPath.c_str());
  3498. break;
  3499. case BND_Demote:
  3500. TraceTag(ttidNetSetup, "%s: Demoting: %S",
  3501. __FUNCNAME__, m_strBindingPath.c_str());
  3502. break;
  3503. default:
  3504. TraceTag(ttidNetSetup, "%s: Cannot perform invalid binding action",
  3505. __FUNCNAME__);
  3506. hr = E_FAIL;
  3507. goto return_from_function;
  3508. break;
  3509. }
  3510. #endif
  3511. hr = HrGetBindingPathFromStringList(pnc,
  3512. &m_slBindingPath,
  3513. &pINetCfgBindingPath);
  3514. if (hr == S_OK)
  3515. {
  3516. #if DBG
  3517. TraceTag(ttidNetSetup, "%s: bindpath matches %S",
  3518. __FUNCNAME__, m_strBindingPath.c_str());
  3519. #endif
  3520. switch (m_eBindingAction)
  3521. {
  3522. default:
  3523. hr = S_FALSE;
  3524. TraceTag(ttidNetSetup, "%s: ignored unknown binding action",
  3525. __FUNCNAME__);
  3526. break;
  3527. case BND_Enable:
  3528. hr = pINetCfgBindingPath->Enable(TRUE);
  3529. break;
  3530. case BND_Disable:
  3531. hr = pINetCfgBindingPath->Enable(FALSE);
  3532. break;
  3533. case BND_Promote:
  3534. case BND_Demote:
  3535. AssertValidReadPtr(m_pnii);
  3536. AssertValidReadPtr(pnc);
  3537. INetCfgComponentBindings* pncb;
  3538. INetCfgComponent* pncc;
  3539. tstring strTopComponent;
  3540. strTopComponent = **(m_slBindingPath.begin());
  3541. hr = pnc->FindComponent(strTopComponent.c_str(), &pncc);
  3542. if (hr == S_OK)
  3543. {
  3544. hr = pncc->QueryInterface(IID_INetCfgComponentBindings,
  3545. (void**) &pncb);
  3546. if (SUCCEEDED(hr))
  3547. {
  3548. AssertValidReadPtr(pncb);
  3549. if (m_eBindingAction == BND_Promote)
  3550. {
  3551. hr = pncb->MoveBefore(pINetCfgBindingPath, NULL);
  3552. }
  3553. else
  3554. {
  3555. hr = pncb->MoveAfter(pINetCfgBindingPath, NULL);
  3556. }
  3557. ReleaseObj(pncb);
  3558. }
  3559. ReleaseObj(pncc);
  3560. }
  3561. break;
  3562. }
  3563. #if DBG
  3564. if (S_OK == hr)
  3565. {
  3566. TraceTag(ttidNetSetup, "%s: ...successfully performed binding action",
  3567. __FUNCNAME__);
  3568. }
  3569. #endif
  3570. ReleaseObj(pINetCfgBindingPath);
  3571. }
  3572. #if DBG
  3573. return_from_function:
  3574. #endif
  3575. if (S_FALSE == hr)
  3576. {
  3577. hr = S_OK;
  3578. }
  3579. TraceFunctionError(hr);
  3580. return hr;
  3581. }
  3582. // ======================================================================
  3583. // class CNetComponent
  3584. // ======================================================================
  3585. // ----------------------------------------------------------------------
  3586. //
  3587. // Function: CNetComponent::CNetComponent
  3588. //
  3589. // Purpose: constructor for class CNetComponent
  3590. //
  3591. // Arguments:
  3592. // pszName [in] name of the component
  3593. //
  3594. // Returns: None
  3595. //
  3596. // Author: kumarp 25-November-97
  3597. //
  3598. // Notes:
  3599. //
  3600. CNetComponent::CNetComponent(IN PCWSTR pszName)
  3601. {
  3602. TraceFileFunc(ttidGuiModeSetup);
  3603. AssertValidReadPtr(pszName);
  3604. m_strName = pszName;
  3605. // for all components except adapters, name is same as InfID
  3606. m_strInfID = pszName;
  3607. m_fIsOemComponent = FALSE;
  3608. // currently the SkipInstall feature is used only by
  3609. // SNA for its peculiar upgrade requirements. This may or may
  3610. // not become a documented feature.
  3611. //
  3612. m_fSkipInstall = FALSE;
  3613. m_guidInstance = GUID_NULL;
  3614. }
  3615. // ----------------------------------------------------------------------
  3616. //
  3617. // Function: CNetComponent::GetInstanceGuid
  3618. //
  3619. // Purpose: Get instance guid of this component
  3620. //
  3621. // Arguments:
  3622. // pguid [out] pointer to guid to be returned
  3623. //
  3624. // Returns: None
  3625. //
  3626. // Author: kumarp 25-November-97
  3627. //
  3628. // Notes:
  3629. //
  3630. VOID
  3631. CNetComponent::GetInstanceGuid (
  3632. OUT LPGUID pguid) const
  3633. {
  3634. TraceFileFunc(ttidGuiModeSetup);
  3635. Assert (pguid);
  3636. if (IsInitializedFromAnswerFile() && (m_guidInstance == GUID_NULL))
  3637. {
  3638. // the Instance GUID is not in memory, need to get it from
  3639. // the registry location where it has been saved by an earlier
  3640. // instance of netsetup.dll
  3641. //
  3642. HrLoadInstanceGuid(Name().c_str(), (LPGUID) &m_guidInstance);
  3643. }
  3644. *pguid = m_guidInstance;
  3645. }
  3646. // ----------------------------------------------------------------------
  3647. //
  3648. // Function: CNetComponent::SetInstanceGuid
  3649. //
  3650. // Purpose: Set instance guid of this component
  3651. //
  3652. // Arguments:
  3653. // pguid [in] pointer to the guid to set to
  3654. //
  3655. // Returns: None
  3656. //
  3657. // Author: kumarp 25-November-97
  3658. //
  3659. // Notes:
  3660. //
  3661. VOID
  3662. CNetComponent::SetInstanceGuid (
  3663. IN const GUID* pguid)
  3664. {
  3665. TraceFileFunc(ttidGuiModeSetup);
  3666. m_guidInstance = *pguid;
  3667. if (IsInitializedFromAnswerFile())
  3668. {
  3669. HrSaveInstanceGuid(Name().c_str(), pguid);
  3670. }
  3671. }
  3672. // ----------------------------------------------------------------------
  3673. //
  3674. // Function: CNetComponent::HrInitFromAnswerFile
  3675. //
  3676. // Purpose: Initialize initialize basic information from the section of
  3677. // this component in the answerfile
  3678. //
  3679. // Arguments:
  3680. // pwifAnswerFile [in] pointer to CWInfFile object
  3681. // pszParamsSections [in] parameters section name
  3682. //
  3683. // Returns: S_OK on success, otherwise an error code
  3684. //
  3685. // Author: kumarp 25-November-97
  3686. //
  3687. // Notes:
  3688. //
  3689. HRESULT CNetComponent::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile,
  3690. IN PCWSTR pszParamsSections)
  3691. {
  3692. TraceFileFunc(ttidGuiModeSetup);
  3693. DefineFunctionName("CNetComponent::HrInitFromAnswerFile");
  3694. AssertValidReadPtr(pwifAnswerFile);
  3695. AssertValidReadPtr(pszParamsSections);
  3696. HRESULT hr=S_OK;
  3697. m_strParamsSections = pszParamsSections;
  3698. TStringList slParamsSections;
  3699. ConvertCommaDelimitedListToStringList(m_strParamsSections, slParamsSections);
  3700. tstring strSection;
  3701. CWInfSection *pwisSection;
  3702. tstring strInfID;
  3703. tstring strInfIDReal;
  3704. //if there are multiple sections, InfID could be in any one of them
  3705. //we need to search all.
  3706. TStringListIter pos = slParamsSections.begin();
  3707. while (pos != slParamsSections.end())
  3708. {
  3709. strSection = **pos++;
  3710. pwisSection = pwifAnswerFile->FindSection(strSection.c_str());
  3711. if (!pwisSection)
  3712. {
  3713. TraceTag(ttidNetSetup, "%s: warning: section %S is missing",
  3714. __FUNCNAME__, strSection.c_str());
  3715. continue;
  3716. }
  3717. // it is really an error to specify different InfIDs in different
  3718. // sections. We just take the last one found and overwrite earlier one.
  3719. if (pwisSection->GetStringValue(c_szAfInfid, strInfID))
  3720. {
  3721. //InfId
  3722. m_strInfID = strInfID;
  3723. }
  3724. if (pwisSection->GetStringValue(c_szAfInfidReal, strInfIDReal))
  3725. {
  3726. //InfIdReal
  3727. m_strInfIDReal = strInfIDReal;
  3728. }
  3729. // currently the SkipInstall feature is used only by
  3730. // SNA and MS_NetBIOS for their peculiar upgrade requirements.
  3731. // This may or may not become a documented feature.
  3732. //
  3733. m_fSkipInstall = pwisSection->GetBoolValue(c_szAfSkipInstall, FALSE);
  3734. if (m_strOemSection.empty())
  3735. {
  3736. m_strOemSection =
  3737. pwisSection->GetStringValue(c_szAfOemSection, c_szEmpty);
  3738. m_strOemDir =
  3739. pwisSection->GetStringValue(c_szAfOemDir, c_szEmpty);
  3740. m_strOemDll =
  3741. pwisSection->GetStringValue(c_szAfOemDllToLoad, c_szEmpty);
  3742. if (!m_strOemSection.empty() &&
  3743. !m_strOemDir.empty())
  3744. {
  3745. m_fIsOemComponent = TRUE;
  3746. CWInfSection* pwisOemSection;
  3747. pwisOemSection =
  3748. pwifAnswerFile->FindSection(m_strOemSection.c_str());
  3749. if (pwisOemSection)
  3750. {
  3751. TStringArray saTemp;
  3752. if (pwisOemSection->GetStringArrayValue(c_szInfToRunBeforeInstall,
  3753. saTemp))
  3754. {
  3755. m_strInfToRunBeforeInstall = *saTemp[0];
  3756. m_strSectionToRunBeforeInstall = *saTemp[1];
  3757. TraceTag(ttidNetSetup, "%s: '%S' specified %S: %S, %S",
  3758. __FUNCNAME__, InfID().c_str(),
  3759. c_szInfToRunBeforeInstall,
  3760. m_strInfToRunBeforeInstall.c_str(),
  3761. m_strSectionToRunBeforeInstall.c_str());
  3762. }
  3763. if (pwisOemSection->GetStringArrayValue(c_szInfToRunAfterInstall,
  3764. saTemp))
  3765. {
  3766. m_strInfToRunAfterInstall = *saTemp[0];
  3767. m_strSectionToRunAfterInstall = *saTemp[1];
  3768. if (m_strInfToRunAfterInstall.empty())
  3769. {
  3770. m_strInfToRunAfterInstall = pwifAnswerFile->FileName();
  3771. }
  3772. TraceTag(ttidNetSetup, "%s: '%S' specified %S: %S, %S",
  3773. __FUNCNAME__, InfID().c_str(),
  3774. c_szInfToRunAfterInstall,
  3775. m_strInfToRunAfterInstall.c_str(),
  3776. m_strSectionToRunAfterInstall.c_str());
  3777. }
  3778. EraseAndDeleteAll(&saTemp);
  3779. }
  3780. }
  3781. }
  3782. }
  3783. // cleanup:
  3784. EraseAndDeleteAll(slParamsSections);
  3785. TraceFunctionError(hr);
  3786. return hr;
  3787. }
  3788. // ----------------------------------------------------------------------
  3789. //
  3790. // Function: CNetComponent::HrValidate
  3791. //
  3792. // Purpose: Validate keys specified in the parameters section
  3793. //
  3794. // Arguments: None
  3795. //
  3796. // Returns: S_OK on success, otherwise an error code
  3797. //
  3798. // Author: kumarp 25-November-97
  3799. //
  3800. // Notes:
  3801. //
  3802. HRESULT CNetComponent::HrValidate() const
  3803. {
  3804. TraceFileFunc(ttidGuiModeSetup);
  3805. DefineFunctionName("CNetComponent::HrValidate");
  3806. HRESULT hr=S_OK;
  3807. // BOOL fStatus = !(m_strInfID.empty() || m_strParamsSections.empty());
  3808. // HRESULT hr = fStatus ? S_OK : NETSETUP_E_ANS_FILE_ERROR;
  3809. TraceFunctionError(hr);
  3810. return hr;
  3811. }
  3812. // ======================================================================
  3813. // class CNetAdapter
  3814. // ======================================================================
  3815. // ----------------------------------------------------------------------
  3816. //
  3817. // Function: CNetAdapter::CNetAdapter
  3818. //
  3819. // Purpose: constructor for class CNetAdapter
  3820. //
  3821. // Arguments:
  3822. // pszName [in] name of the adapter
  3823. //
  3824. // Returns: None
  3825. //
  3826. // Author: kumarp 25-November-97
  3827. //
  3828. // Notes:
  3829. //
  3830. CNetAdapter::CNetAdapter(IN PCWSTR pszName)
  3831. : CNetComponent(pszName)
  3832. {
  3833. TraceFileFunc(ttidGuiModeSetup);
  3834. m_fDetect = FALSE;
  3835. m_fPseudoAdapter = FALSE;
  3836. m_itBus = Isa;
  3837. m_wIOAddr = 0;
  3838. m_wIRQ = 0;
  3839. m_wDMA = 0;
  3840. m_dwMem = 0;
  3841. m_qwNetCardAddress = 0;
  3842. m_PciBusNumber = 0xFFFF;
  3843. m_PciDeviceNumber = 0xFFFF;
  3844. m_PciFunctionNumber = 0xFFFF;
  3845. m_fPciLocationInfoSpecified = FALSE;
  3846. }
  3847. // ----------------------------------------------------------------------
  3848. //
  3849. // Function: CNetAdapter::HrInitFromAnswerFile
  3850. //
  3851. // Purpose: Initialize from the parameters section of this adapter
  3852. // in the answerfile
  3853. //
  3854. // Arguments:
  3855. // pwifAnswerFile [in] pointer to CWInfFile object
  3856. // pszParamsSections [in] name of the parameters section
  3857. //
  3858. // Returns: S_OK on success, otherwise an error code
  3859. //
  3860. // Author: kumarp 25-November-97
  3861. //
  3862. // Notes:
  3863. //
  3864. HRESULT CNetAdapter::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile,
  3865. IN PCWSTR pszParamsSections)
  3866. {
  3867. TraceFileFunc(ttidGuiModeSetup);
  3868. DefineFunctionName("CNetAdapter::HrInitFromAnswerFile");
  3869. AssertValidReadPtr(pwifAnswerFile);
  3870. AssertValidReadPtr(pszParamsSections);
  3871. HRESULT hr, hrReturn=S_OK;
  3872. hrReturn = CNetComponent::HrInitFromAnswerFile(pwifAnswerFile,
  3873. pszParamsSections);
  3874. PCWInfSection pwisParams;
  3875. pwisParams = pwifAnswerFile->FindSection(pszParamsSections);
  3876. if (!pwisParams)
  3877. {
  3878. AddAnswerFileError(pszParamsSections, IDS_E_AF_Missing);
  3879. return NETSETUP_E_ANS_FILE_ERROR;
  3880. }
  3881. PCWSTR pszTemp;
  3882. DWORD dwDefault = 0;
  3883. //Detect
  3884. m_fDetect = pwisParams->GetBoolValue(c_szAfDetect, TRUE);
  3885. if (!m_fDetect && m_strInfID.empty())
  3886. {
  3887. AddAnswerFileError(pszParamsSections,
  3888. IDS_E_AF_SpecifyInfIdWhenNotDetecting);
  3889. hrReturn = NETSETUP_E_ANS_FILE_ERROR;
  3890. }
  3891. //PreUpgradeInstance
  3892. m_strPreUpgradeInstance = pwisParams->GetStringValue(c_szAfPreUpgradeInstance,
  3893. c_szEmpty);
  3894. //PseudoAdapter
  3895. m_fPseudoAdapter = pwisParams->GetBoolValue(c_szAfPseudoAdapter, FALSE);
  3896. //if it is a PseudoAdapter, no need to get values of other parameters
  3897. if (m_fPseudoAdapter)
  3898. {
  3899. TraceFunctionError(hrReturn);
  3900. return hrReturn;
  3901. }
  3902. // ConnectionName
  3903. m_strConnectionName = pwisParams->GetStringValue(c_szAfConnectionName,
  3904. c_szEmpty);
  3905. //BusType
  3906. pszTemp = pwisParams->GetStringValue(c_szAfBusType, c_szEmpty);
  3907. m_itBus = GetBusTypeFromName(pszTemp);
  3908. //IOAddr
  3909. m_wIOAddr = pwisParams->GetIntValue(c_szAfIoAddr, dwDefault);
  3910. //IRQ
  3911. m_wIRQ = pwisParams->GetIntValue(c_szAfIrq, dwDefault);
  3912. //DMA
  3913. m_wDMA = pwisParams->GetIntValue(c_szAfDma, dwDefault);
  3914. //MEM
  3915. m_dwMem = pwisParams->GetIntValue(c_szAfMem, dwDefault);
  3916. //NetCardAddr
  3917. pwisParams->GetQwordValue(c_szAfNetCardAddr, &m_qwNetCardAddress);
  3918. // BusNumber
  3919. m_PciBusNumber = pwisParams->GetIntValue (L"PciBusNumber", 0xFFFF);
  3920. if (0xFFFF != m_PciBusNumber)
  3921. {
  3922. // DeviceNumber
  3923. m_PciDeviceNumber = pwisParams->GetIntValue (L"PciDeviceNumber", 0xFFFF);
  3924. if (0xFFFF != m_PciDeviceNumber)
  3925. {
  3926. // FunctionNumber
  3927. m_PciFunctionNumber = pwisParams->GetIntValue (L"PciFunctionNumber",
  3928. 0xFFFF);
  3929. if (0xFFFF != m_PciFunctionNumber)
  3930. {
  3931. m_fPciLocationInfoSpecified = TRUE;
  3932. }
  3933. }
  3934. }
  3935. TraceFunctionError(hrReturn);
  3936. return hrReturn;
  3937. }
  3938. // ----------------------------------------------------------------------
  3939. //
  3940. // Function: CNetAdapter::HrValidate
  3941. //
  3942. // Purpose: Validate netcard parameters
  3943. //
  3944. // Arguments: None
  3945. //
  3946. // Returns: S_OK on success, otherwise an error code
  3947. //
  3948. // Author: kumarp 23-December-97
  3949. //
  3950. // Notes:
  3951. //
  3952. HRESULT CNetAdapter::HrValidate()
  3953. {
  3954. TraceFileFunc(ttidGuiModeSetup);
  3955. DefineFunctionName("CNetAdapter::HrValidate");
  3956. HRESULT hr;
  3957. hr = CNetComponent::HrValidate();
  3958. ReturnHrIfFailed(hr);
  3959. //$ REVIEW kumarp 21-April-97
  3960. // no additinal checking for now
  3961. TraceFunctionError(hr);
  3962. return hr;
  3963. }
  3964. // ======================================================================
  3965. // class CNetProtocol
  3966. // ======================================================================
  3967. // ----------------------------------------------------------------------
  3968. //
  3969. // Function: CNetProtocol::CNetProtocol
  3970. //
  3971. // Purpose: constructor for class CNetProtocol
  3972. //
  3973. // Arguments:
  3974. // pszName [in] name of the protocol
  3975. //
  3976. // Returns: None
  3977. //
  3978. // Author: kumarp 25-November-97
  3979. //
  3980. // Notes:
  3981. //
  3982. CNetProtocol::CNetProtocol(IN PCWSTR pszName)
  3983. : CNetComponent(pszName)
  3984. {
  3985. }
  3986. // ======================================================================
  3987. // class CNetService
  3988. // ======================================================================
  3989. // ----------------------------------------------------------------------
  3990. //
  3991. // Function: CNetService::CNetService
  3992. //
  3993. // Purpose: constructor for class CNetService
  3994. //
  3995. // Arguments:
  3996. // pszName [in] name of the service
  3997. //
  3998. // Returns:
  3999. //
  4000. // Author: kumarp 25-November-97
  4001. //
  4002. // Notes:
  4003. //
  4004. CNetService::CNetService(IN PCWSTR pszName)
  4005. : CNetComponent(pszName)
  4006. {
  4007. TraceFileFunc(ttidGuiModeSetup);
  4008. }
  4009. // ======================================================================
  4010. // class CNetClient
  4011. // ======================================================================
  4012. // ----------------------------------------------------------------------
  4013. //
  4014. // Function: CNetClient::CNetClient
  4015. //
  4016. // Purpose: constructor for class CNetClient
  4017. //
  4018. // Arguments:
  4019. // pszName [in] name of the client
  4020. //
  4021. // Returns:
  4022. //
  4023. // Author: kumarp 25-November-97
  4024. //
  4025. // Notes:
  4026. //
  4027. CNetClient::CNetClient(IN PCWSTR pszName)
  4028. : CNetComponent(pszName)
  4029. {
  4030. TraceFileFunc(ttidGuiModeSetup);
  4031. }
  4032. // ----------------------------------------------------------------------
  4033. // Misc. Helper Functions
  4034. // ----------------------------------------------------------------------
  4035. // ----------------------------------------------------------------------
  4036. //
  4037. // Function: FindComponentInList
  4038. //
  4039. // Purpose: Find component in the given list
  4040. //
  4041. // Arguments:
  4042. // pnclComponents [in] pointer to list of components
  4043. // szInfID [in] component to find
  4044. //
  4045. // Returns: pointer to CNetComponent object, or NULL if not found
  4046. //
  4047. // Author: kumarp 25-November-97
  4048. //
  4049. // Notes:
  4050. //
  4051. CNetComponent* FindComponentInList(
  4052. IN CNetComponentList* pnclComponents,
  4053. IN PCWSTR szInfID)
  4054. {
  4055. TraceFileFunc(ttidGuiModeSetup);
  4056. CNetComponent* pna;
  4057. TPtrListIter pos;
  4058. pos = pnclComponents->begin();
  4059. while (pos != pnclComponents->end())
  4060. {
  4061. pna = (CNetComponent*) *pos++;
  4062. if (0 == lstrcmpiW(pna->InfID().c_str(), szInfID))
  4063. {
  4064. return pna;
  4065. }
  4066. }
  4067. return NULL;
  4068. }
  4069. // ----------------------------------------------------------------------
  4070. //
  4071. // Function: GetDisplayModeStr
  4072. //
  4073. // Purpose: Get string representation of DisplayMode
  4074. //
  4075. // Arguments:
  4076. // pdmDisplay [in] display mode
  4077. //
  4078. // Returns:
  4079. //
  4080. // Author: kumarp 23-December-97
  4081. //
  4082. // Notes:
  4083. //
  4084. PCWSTR GetDisplayModeStr(EPageDisplayMode pdmDisplay)
  4085. {
  4086. TraceFileFunc(ttidGuiModeSetup);
  4087. switch (pdmDisplay)
  4088. {
  4089. case PDM_YES:
  4090. return c_szYes;
  4091. case PDM_NO:
  4092. return c_szNo;
  4093. case PDM_ONLY_ON_ERROR:
  4094. default:
  4095. return c_szAfOnlyOnError;
  4096. }
  4097. }
  4098. // ----------------------------------------------------------------------
  4099. //
  4100. // Function: MapToDisplayMode
  4101. //
  4102. // Purpose: Map display mode string to proper enum value
  4103. //
  4104. // Arguments:
  4105. // pszDisplayMode [in] display mode string
  4106. //
  4107. // Returns: enum corresponding to the string
  4108. //
  4109. // Author: kumarp 25-November-97
  4110. //
  4111. // Notes:
  4112. //
  4113. EPageDisplayMode MapToDisplayMode(IN PCWSTR pszDisplayMode)
  4114. {
  4115. TraceFileFunc(ttidGuiModeSetup);
  4116. AssertValidReadPtr(pszDisplayMode);
  4117. if (!lstrcmpiW(pszDisplayMode, c_szYes))
  4118. return PDM_YES;
  4119. else if (!lstrcmpiW(pszDisplayMode, c_szNo))
  4120. return PDM_NO;
  4121. else if (!lstrcmpiW(pszDisplayMode, c_szAfOnlyOnError))
  4122. return PDM_ONLY_ON_ERROR;
  4123. else
  4124. return PDM_UNKNOWN;
  4125. }
  4126. // ----------------------------------------------------------------------
  4127. //
  4128. // Function: MapToUpgradeFlag
  4129. //
  4130. // Purpose: Map string to proper upgrade flag value
  4131. //
  4132. // Arguments:
  4133. // pszUpgradeFromProduct [in] string describing product
  4134. //
  4135. // Returns: flag corresponding to the string
  4136. //
  4137. // Author: kumarp 25-November-97
  4138. //
  4139. // Notes:
  4140. //
  4141. DWORD MapToUpgradeFlag(IN PCWSTR pszUpgradeFromProduct)
  4142. {
  4143. TraceFileFunc(ttidGuiModeSetup);
  4144. AssertValidReadPtr(pszUpgradeFromProduct);
  4145. if (!lstrcmpiW(pszUpgradeFromProduct, c_szAfNtServer))
  4146. return NSF_WINNT_SVR_UPGRADE;
  4147. else if (!lstrcmpiW(pszUpgradeFromProduct, c_szAfNtSbServer))
  4148. return NSF_WINNT_SBS_UPGRADE;
  4149. else if (!lstrcmpiW(pszUpgradeFromProduct, c_szAfNtWorkstation))
  4150. return NSF_WINNT_WKS_UPGRADE;
  4151. else if (!lstrcmpiW(pszUpgradeFromProduct, c_szAfWin95))
  4152. return NSF_WIN95_UPGRADE;
  4153. else
  4154. return 0;
  4155. }
  4156. HRESULT HrGetProductInfo (LPDWORD pdwUpgradeFrom,
  4157. LPDWORD pdwBuildNo)
  4158. {
  4159. OSVERSIONINFOEX osvi;
  4160. HRESULT hr;
  4161. *pdwUpgradeFrom = 0;
  4162. *pdwBuildNo = 0;
  4163. ZeroMemory( &osvi,
  4164. sizeof(OSVERSIONINFOEX) );
  4165. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  4166. if ( GetVersionEx((LPOSVERSIONINFO)&osvi) )
  4167. {
  4168. *pdwBuildNo = osvi.dwBuildNumber;
  4169. if ( osvi.wSuiteMask & (VER_SUITE_SMALLBUSINESS | VER_SUITE_SMALLBUSINESS_RESTRICTED) )
  4170. {
  4171. *pdwUpgradeFrom = NSF_WINNT_SBS_UPGRADE;
  4172. }
  4173. else if ( osvi.wProductType == VER_NT_WORKSTATION )
  4174. {
  4175. *pdwUpgradeFrom = NSF_WINNT_WKS_UPGRADE;
  4176. }
  4177. else
  4178. {
  4179. *pdwUpgradeFrom = NSF_WINNT_SVR_UPGRADE;
  4180. }
  4181. hr = S_OK;
  4182. }
  4183. else
  4184. {
  4185. hr = HRESULT_FROM_WIN32(GetLastError());
  4186. }
  4187. return hr;
  4188. }
  4189. // ----------------------------------------------------------------------
  4190. //
  4191. // Function: GetBusTypeFromName
  4192. //
  4193. // Purpose: Map bus-type enum from string
  4194. //
  4195. // Arguments:
  4196. // pszBusType [in] name of the bus
  4197. //
  4198. // Returns: enum INTERFACE_TYPE corresponding to the string
  4199. //
  4200. // Author: kumarp 25-November-97
  4201. //
  4202. // Notes:
  4203. //
  4204. INTERFACE_TYPE GetBusTypeFromName(IN PCWSTR pszBusType)
  4205. {
  4206. TraceFileFunc(ttidGuiModeSetup);
  4207. AssertValidReadPtr(pszBusType);
  4208. if (!_wcsicmp(pszBusType, c_szAfBusInternal))
  4209. return Internal;
  4210. else if (!_wcsicmp(pszBusType, c_szAfBusIsa))
  4211. return Isa;
  4212. else if (!_wcsicmp(pszBusType, c_szAfBusEisa))
  4213. return Eisa;
  4214. else if (!_wcsicmp(pszBusType, c_szAfBusMicrochannel))
  4215. return MicroChannel;
  4216. else if (!_wcsicmp(pszBusType, c_szAfBusTurbochannel))
  4217. return TurboChannel;
  4218. else if (!_wcsicmp(pszBusType, c_szAfBusPci))
  4219. return PCIBus;
  4220. else if (!_wcsicmp(pszBusType, c_szAfBusVme))
  4221. return VMEBus;
  4222. else if (!_wcsicmp(pszBusType, c_szAfBusNu))
  4223. return NuBus;
  4224. else if (!_wcsicmp(pszBusType, c_szAfBusPcmcia))
  4225. return PCMCIABus;
  4226. else if (!_wcsicmp(pszBusType, c_szAfBusC))
  4227. return CBus;
  4228. else if (!_wcsicmp(pszBusType, c_szAfBusMpi))
  4229. return MPIBus;
  4230. else if (!_wcsicmp(pszBusType, c_szAfBusMpsa))
  4231. return MPSABus;
  4232. else if (!_wcsicmp(pszBusType, c_szAfBusProcessorinternal))
  4233. return ProcessorInternal;
  4234. else if (!_wcsicmp(pszBusType, c_szAfBusInternalpower))
  4235. return InternalPowerBus;
  4236. else if (!_wcsicmp(pszBusType, c_szAfBusPnpisa))
  4237. return PNPISABus;
  4238. else
  4239. return InterfaceTypeUndefined;
  4240. };
  4241. // ----------------------------------------------------------------------
  4242. //
  4243. // Function: AddAnswerFileError
  4244. //
  4245. // Purpose: Add error with given resource id to the answerfile error-list
  4246. //
  4247. // Arguments:
  4248. // dwErrorId [in] resource id
  4249. //
  4250. // Returns: None
  4251. //
  4252. // Author: kumarp 25-November-97
  4253. //
  4254. // Notes:
  4255. //
  4256. void AddAnswerFileError(IN DWORD dwErrorId)
  4257. {
  4258. TraceFileFunc(ttidGuiModeSetup);
  4259. g_elAnswerFileErrors->Add(dwErrorId);
  4260. }
  4261. // ----------------------------------------------------------------------
  4262. //
  4263. // Function: AddAnswerFileError
  4264. //
  4265. // Purpose: Add error with given section name and error id
  4266. // to the answerfile error-list
  4267. //
  4268. // Arguments:
  4269. // pszSectionName [in] name of section where error occurred
  4270. // dwErrorId [in] error id
  4271. //
  4272. // Returns: None
  4273. //
  4274. // Author: kumarp 25-November-97
  4275. //
  4276. // Notes:
  4277. //
  4278. void AddAnswerFileError(IN PCWSTR pszSectionName, IN DWORD dwErrorId)
  4279. {
  4280. TraceFileFunc(ttidGuiModeSetup);
  4281. AssertValidReadPtr(pszSectionName);
  4282. tstring strMsgPrefix = pszSectionName;
  4283. strMsgPrefix = L"Section [" + strMsgPrefix + L"] : ";
  4284. g_elAnswerFileErrors->Add(strMsgPrefix.c_str(), dwErrorId);
  4285. }
  4286. // ----------------------------------------------------------------------
  4287. //
  4288. // Function: AddAnswerFileError
  4289. //
  4290. // Purpose: Add error with given section name, key name and error id
  4291. // to the answerfile error-list
  4292. //
  4293. // Arguments:
  4294. // pszSectionName [in] name of section where error occurred
  4295. // pszKeyName [in] name of key where error occurred
  4296. // dwErrorId [in] error id
  4297. //
  4298. // Returns: None
  4299. //
  4300. // Author: kumarp 25-November-97
  4301. //
  4302. // Notes:
  4303. //
  4304. void AddAnswerFileError(IN PCWSTR pszSectionName,
  4305. IN PCWSTR pszKeyName,
  4306. IN DWORD dwErrorId)
  4307. {
  4308. TraceFileFunc(ttidGuiModeSetup);
  4309. AssertValidReadPtr(pszSectionName);
  4310. AssertValidReadPtr(pszKeyName);
  4311. tstring strMsgPrefix = pszSectionName;
  4312. strMsgPrefix = L"Section [" + strMsgPrefix + L"]: Key \"" +
  4313. pszKeyName + L"\" : ";
  4314. g_elAnswerFileErrors->Add(strMsgPrefix.c_str(), dwErrorId);
  4315. }
  4316. // ----------------------------------------------------------------------
  4317. //
  4318. // Function: ShowAnswerFileErrorsIfAny
  4319. //
  4320. // Purpose: Display messagebox if there are errors in the answerfile
  4321. //
  4322. // Arguments: None
  4323. //
  4324. // Returns: None
  4325. //
  4326. // Author: kumarp 25-November-97
  4327. //
  4328. // Notes:
  4329. //
  4330. void ShowAnswerFileErrorsIfAny()
  4331. {
  4332. TraceFileFunc(ttidGuiModeSetup);
  4333. static const WCHAR c_szNewLine[] = L"\n";
  4334. TStringList* pslErrors=NULL;
  4335. GetAnswerFileErrorList_Internal(pslErrors);
  4336. if (pslErrors && (pslErrors->size() > 0))
  4337. {
  4338. tstring strErrors;
  4339. strErrors = SzLoadIds(IDS_E_AF_AnsFileHasErrors);
  4340. strErrors += c_szNewLine;
  4341. strErrors += c_szNewLine;
  4342. TStringListIter pos;
  4343. pos = pslErrors->begin();
  4344. while (pos != pslErrors->end())
  4345. {
  4346. strErrors += **pos++;
  4347. strErrors += c_szNewLine;
  4348. }
  4349. MessageBox (NULL, strErrors.c_str(), NULL, MB_OK | MB_TASKMODAL);
  4350. }
  4351. }
  4352. // ----------------------------------------------------------------------
  4353. //
  4354. // Function: GetAnswerFileErrorList
  4355. //
  4356. // Purpose: Return list of errors in the answerfile
  4357. //
  4358. // Arguments:
  4359. // slErrors [out] pointer to list of errors
  4360. //
  4361. // Returns: None
  4362. //
  4363. // Author: kumarp 25-November-97
  4364. //
  4365. // Notes:
  4366. //
  4367. VOID
  4368. GetAnswerFileErrorList_Internal(OUT TStringList*& slErrors)
  4369. {
  4370. TraceFileFunc(ttidGuiModeSetup);
  4371. g_elAnswerFileErrors->GetErrorList(slErrors);
  4372. }
  4373. // ----------------------------------------------------------------------
  4374. //
  4375. // Function: HrRemoveNetComponents
  4376. //
  4377. // Purpose: Remove (DeInstall) specified components
  4378. //
  4379. // Arguments:
  4380. // pnc [in] pointer to INetCfg object
  4381. // pslComponents [in] pointer to list of components to be removed
  4382. //
  4383. // Returns: S_OK on success, otherwise an error code
  4384. //
  4385. // Author: kumarp 25-November-97
  4386. //
  4387. // Notes:
  4388. //
  4389. HRESULT HrRemoveNetComponents(IN INetCfg* pnc,
  4390. IN TStringList* pslComponents)
  4391. {
  4392. TraceFileFunc(ttidGuiModeSetup);
  4393. DefineFunctionName("HrDeInstallNetComponents");
  4394. AssertValidReadPtr(pslComponents);
  4395. HRESULT hr=S_OK;
  4396. TStringListIter pos;
  4397. PCWSTR szComponentId;
  4398. INetCfgComponent* pINetCfgComponent;
  4399. GUID guidClass;
  4400. for (pos = pslComponents->begin(); pos != pslComponents->end(); pos++)
  4401. {
  4402. szComponentId = (*pos)->c_str();
  4403. ShowProgressMessage(L"Trying to remove %s...", szComponentId);
  4404. hr = pnc->FindComponent(szComponentId, &pINetCfgComponent);
  4405. if (S_OK == hr)
  4406. {
  4407. hr = pINetCfgComponent->GetClassGuid(&guidClass);
  4408. if (S_OK == hr)
  4409. {
  4410. hr = HrRemoveComponentOboUser(pnc, guidClass, szComponentId);
  4411. if (S_OK == hr)
  4412. {
  4413. ShowProgressMessage(L"...successfully removed %s",
  4414. szComponentId);
  4415. }
  4416. }
  4417. if (S_OK != hr)
  4418. {
  4419. ShowProgressMessage(L"...error removing %s, error code: 0x%x",
  4420. szComponentId, hr);
  4421. }
  4422. ReleaseObj(pINetCfgComponent);
  4423. }
  4424. else
  4425. {
  4426. ShowProgressMessage(L"...component %s is not installed",
  4427. szComponentId);
  4428. }
  4429. // Remove the files.
  4430. RemoveFiles( szComponentId );
  4431. // we ignore any errors so that we can remove as many components
  4432. // as possible
  4433. //
  4434. hr = S_OK;
  4435. }
  4436. TraceError(__FUNCNAME__, hr);
  4437. return hr;
  4438. }
  4439. // ----------------------------------------------------------------------
  4440. //
  4441. // Function: RemoveFiles
  4442. //
  4443. // Purpose: Remove the files of the specified component.
  4444. //
  4445. // Arguments:
  4446. // szInfID [in] Infid of the component.
  4447. //
  4448. // Returns:
  4449. //
  4450. // Author: asinha 02-April-2001
  4451. //
  4452. // Notes:
  4453. //
  4454. VOID RemoveFiles (IN PCWSTR szInfID)
  4455. {
  4456. tstring strFilename;
  4457. WCHAR szWindowsDir[MAX_PATH+2];
  4458. int len;
  4459. if ( _wcsicmp(szInfID, sz_DLC) == 0 )
  4460. {
  4461. len = GetWindowsDirectoryW(szWindowsDir, MAX_PATH+1);
  4462. if ( szWindowsDir[len-1] != L'\\' )
  4463. {
  4464. szWindowsDir[len] = L'\\';
  4465. szWindowsDir[len+1] = NULL;
  4466. }
  4467. // Don't know if it is an upgrade from NT 4.0 or Win2k, so
  4468. // try to delete the inf file of both the OS's.
  4469. //
  4470. strFilename = szWindowsDir;
  4471. strFilename += sz_DLC_NT40_Inf;
  4472. DeleteFile( strFilename.c_str() );
  4473. strFilename = szWindowsDir;
  4474. strFilename += sz_DLC_Win2k_Inf;
  4475. DeleteFile( strFilename.c_str() );
  4476. strFilename = szWindowsDir;
  4477. strFilename += sz_DLC_Win2k_Pnf;
  4478. DeleteFile( strFilename.c_str() );
  4479. strFilename = szWindowsDir;
  4480. strFilename += sz_DLC_Sys;
  4481. DeleteFile( strFilename.c_str() );
  4482. strFilename = szWindowsDir;
  4483. strFilename += sz_DLC_Dll;
  4484. DeleteFile( strFilename.c_str() );
  4485. }
  4486. return;
  4487. }
  4488. static ProgressMessageCallbackFn g_pfnProgressMsgCallback;
  4489. EXTERN_C
  4490. VOID
  4491. WINAPI
  4492. NetSetupSetProgressCallback (
  4493. ProgressMessageCallbackFn pfn)
  4494. {
  4495. TraceFileFunc(ttidGuiModeSetup);
  4496. g_pfnProgressMsgCallback = pfn;
  4497. }
  4498. VOID
  4499. ShowProgressMessage (
  4500. IN PCWSTR szFormatStr, ...)
  4501. {
  4502. TraceFileFunc(ttidGuiModeSetup);
  4503. va_list arglist;
  4504. va_start (arglist, szFormatStr);
  4505. if (g_pfnProgressMsgCallback)
  4506. {
  4507. g_pfnProgressMsgCallback(szFormatStr, arglist);
  4508. }
  4509. #ifdef ENABLETRACE
  4510. else
  4511. {
  4512. static WCHAR szTempBuf[1024];
  4513. _vstprintf(szTempBuf, szFormatStr, arglist);
  4514. TraceTag(ttidNetSetup, "%S", szTempBuf);
  4515. }
  4516. #endif
  4517. va_end(arglist);
  4518. }
  4519. // ----------------------------------------------------------------------
  4520. //
  4521. // Function: HrMakeCopyOfAnswerFile
  4522. //
  4523. // Purpose: Make a backup copy of the answerfile. Base setup has started
  4524. // deleting it after GUI mode setup, but we want to retain
  4525. // the file for debugging/support purpose.
  4526. //
  4527. // Arguments:
  4528. // szAnswerFileName [in] full path+name of AnswerFile
  4529. //
  4530. // Returns: S_OK on success, otherwise an error code
  4531. //
  4532. // Author: kumarp 12-January-98
  4533. //
  4534. // Notes:
  4535. //
  4536. HRESULT HrMakeCopyOfAnswerFile(IN PCWSTR szAnswerFileName)
  4537. {
  4538. TraceFileFunc(ttidGuiModeSetup);
  4539. DefineFunctionName("HrMakeCopyOfAnswerFile");
  4540. TraceFunctionEntry(ttidNetSetup);
  4541. static const WCHAR c_szAnswerFileCopyName[] = L"af.txt";
  4542. HRESULT hr=S_OK;
  4543. WCHAR szWindowsDir[MAX_PATH+1];
  4544. tstring strAnswerFileCopyName;
  4545. DWORD cNumCharsReturned = GetSystemWindowsDirectory(szWindowsDir, MAX_PATH);
  4546. if (cNumCharsReturned)
  4547. {
  4548. static const WCHAR c_szNetsetupTempSubDir[] = L"\\netsetup\\";
  4549. strAnswerFileCopyName = szWindowsDir;
  4550. strAnswerFileCopyName += c_szNetsetupTempSubDir;
  4551. DWORD err = 0;
  4552. DWORD status;
  4553. status = CreateDirectory(strAnswerFileCopyName.c_str(), NULL);
  4554. if (!status)
  4555. {
  4556. err = GetLastError();
  4557. }
  4558. if (status || (ERROR_ALREADY_EXISTS == err))
  4559. {
  4560. hr = S_OK;
  4561. strAnswerFileCopyName += c_szAnswerFileCopyName;
  4562. status = CopyFile(szAnswerFileName,
  4563. strAnswerFileCopyName.c_str(), FALSE);
  4564. if (status)
  4565. {
  4566. hr = S_OK;
  4567. TraceTag(ttidNetSetup, "%s: AnswerFile %S copied to %S",
  4568. __FUNCNAME__, szAnswerFileName,
  4569. strAnswerFileCopyName.c_str());
  4570. }
  4571. else
  4572. {
  4573. hr = HrFromLastWin32Error();
  4574. }
  4575. }
  4576. else
  4577. {
  4578. hr = HRESULT_FROM_WIN32(err);
  4579. }
  4580. }
  4581. else
  4582. {
  4583. hr = HrFromLastWin32Error();
  4584. }
  4585. TraceError(__FUNCNAME__, hr);
  4586. return hr;
  4587. }
  4588. //+---------------------------------------------------------------------------
  4589. //
  4590. // Function: HrGetConnectionFromAdapterGuid
  4591. //
  4592. // Purpose: Get INetConnection* for a given adapter guid
  4593. //
  4594. // Arguments:
  4595. // pguidAdapter [in] pointer to the instance GUID of an adapter
  4596. // ppconn [out] the corresponding INetConnection*
  4597. //
  4598. // Returns: S_OK on success, otherwise an error code
  4599. // S_FALSE if connection was not found.
  4600. //
  4601. // Author: kumarp 23-September-98
  4602. //
  4603. // Notes:
  4604. //
  4605. HRESULT HrGetConnectionFromAdapterGuid(IN GUID* pguidAdapter,
  4606. OUT INetConnection** ppconn)
  4607. {
  4608. TraceFileFunc(ttidGuiModeSetup);
  4609. DefineFunctionName("HrGetConnectionFromAdapterGuid");
  4610. HRESULT hr=S_OK;
  4611. BOOL fFound = FALSE;
  4612. // Iterate all LAN connections
  4613. //
  4614. INetConnectionManager * pconMan;
  4615. hr = HrCreateInstance(
  4616. CLSID_LanConnectionManager,
  4617. CLSCTX_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  4618. &pconMan);
  4619. TraceHr(ttidError, FAL, hr, FALSE, "HrCreateInstance");
  4620. if (SUCCEEDED(hr))
  4621. {
  4622. CIterNetCon ncIter(pconMan, NCME_DEFAULT);
  4623. INetConnection* pconn = NULL;
  4624. while (!fFound && (S_OK == (ncIter.HrNext(&pconn))))
  4625. {
  4626. if (FPconnEqualGuid(pconn, *pguidAdapter))
  4627. {
  4628. fFound = TRUE;
  4629. *ppconn = pconn;
  4630. }
  4631. else
  4632. {
  4633. ReleaseObj(pconn);
  4634. }
  4635. }
  4636. ReleaseObj(pconMan);
  4637. }
  4638. if (!fFound)
  4639. hr = S_FALSE;
  4640. TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
  4641. return hr;
  4642. }
  4643. //+---------------------------------------------------------------------------
  4644. //
  4645. // Function: HrSetLanConnectionName
  4646. //
  4647. // Purpose: Rename the connection spcified by its adapter guid
  4648. // to the given name
  4649. //
  4650. // Arguments:
  4651. // pguidAdapter [in] pointer to the instance GUID of an adapter
  4652. // szConnectionName [in] name of Connection
  4653. //
  4654. // Returns: S_OK on success, otherwise an error code
  4655. // S_FALSE if connection was not found
  4656. //
  4657. // Author: kumarp 23-September-98
  4658. //
  4659. // Notes:
  4660. //
  4661. HRESULT HrSetLanConnectionName(IN GUID* pguidAdapter,
  4662. IN PCWSTR szConnectionName)
  4663. {
  4664. TraceFileFunc(ttidGuiModeSetup);
  4665. DefineFunctionName("HrSetConnectionName");
  4666. HRESULT hr=S_OK;
  4667. INetConnection* pconn;
  4668. hr = HrGetConnectionFromAdapterGuid(pguidAdapter, &pconn);
  4669. if (S_OK == hr)
  4670. {
  4671. hr = pconn->Rename(szConnectionName);
  4672. ReleaseObj(pconn);
  4673. }
  4674. TraceError(__FUNCNAME__, hr);
  4675. return hr;
  4676. }
  4677. // =======================================================================
  4678. // defunct code
  4679. // =======================================================================