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.

940 lines
30 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: U P G R A D E . C P P
  7. //
  8. // Contents: functions related only to network upgrade
  9. // (i.e. not used when installing fresh)
  10. //
  11. // Notes:
  12. //
  13. // Author: kumarp
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. #include "nsbase.h"
  19. #include "afileint.h"
  20. #include "afilestr.h"
  21. #include "afilexp.h"
  22. #include "kkreg.h"
  23. #include "kkutils.h"
  24. #include "ncatl.h"
  25. #include "nceh.h"
  26. #include "ncnetcfg.h"
  27. #include "ncreg.h"
  28. #include "ncsetup.h"
  29. #include "ncsvc.h"
  30. #include "resource.h"
  31. #include "upgrade.h"
  32. #include "nslog.h"
  33. #include "winsock2.h" // For WSCEnumProtocols
  34. #include "ws2spi.h"
  35. #include "sporder.h" // For WSCWriteProviderOrder
  36. // ----------------------------------------------------------------------
  37. // String constants
  38. // ----------------------------------------------------------------------
  39. extern const WCHAR c_szSvcRasAuto[];
  40. extern const WCHAR c_szSvcRouter[];
  41. extern const WCHAR c_szSvcRemoteAccess[];
  42. extern const WCHAR c_szSvcRipForIp[];
  43. extern const WCHAR c_szSvcRipForIpx[];
  44. extern const WCHAR c_szSvcDhcpRelayAgent[];
  45. extern const WCHAR c_szInfId_MS_RasSrv[];
  46. // ----------------------------------------------------------------------
  47. // forward declarations
  48. // ----------------------------------------------------------------------
  49. // returns S_OK on success.
  50. typedef HRESULT (*HrOemComponentUpgradeFnPrototype) (IN DWORD dwUpgradeFlag,
  51. IN DWORD dwUpgradeFromBuildNumber,
  52. IN PCWSTR pszAnswerFileName,
  53. IN PCWSTR pszAnswerFileSectionName);
  54. BOOL InitWorkForWizIntro();
  55. // ----------------------------------------------------------------------
  56. static const WCHAR c_szCleanSection[] = L"Clean";
  57. static const WCHAR c_szCleanServicesSection[]= L"Clean.Services";
  58. const WCHAR c_szRouterUpgradeDll[] = L"rtrupg.dll";
  59. const CHAR c_szRouterUpgradeFn[] = "RouterUpgrade";
  60. // ----------------------------------------------------------------------
  61. #define RGAS_SERVICES_HOME L"SYSTEM\\CurrentControlSet\\Services"
  62. // ----------------------------------------------------------------------
  63. //+---------------------------------------------------------------------------
  64. //
  65. // Function: HrRunAnswerFileCleanSection
  66. //
  67. // Purpose: Runs the [Clean] section of the answer file to remove old
  68. // registry entries and services.
  69. //
  70. // Arguments:
  71. // (none)
  72. //
  73. // Returns: S_OK if succeeded, SetupAPI error otherwise
  74. //
  75. // Author: danielwe 12 Jun 1997
  76. //
  77. // Notes:
  78. //
  79. HRESULT HrRunAnswerFileCleanSection(IN PCWSTR pszAnswerFileName)
  80. {
  81. TraceFileFunc(ttidGuiModeSetup);
  82. DefineFunctionName("HrRunAnswerFileCleanSection");
  83. TraceFunctionEntry(ttidNetSetup);
  84. AssertValidReadPtr(pszAnswerFileName);
  85. TraceTag(ttidNetSetup, "%s: Cleaning services and registry keys based "
  86. "on params in the answer file %S.", __FUNCNAME__, pszAnswerFileName);
  87. HRESULT hr;
  88. HINF hinf;
  89. hr = HrSetupOpenInfFile(pszAnswerFileName, NULL,
  90. INF_STYLE_OLDNT | INF_STYLE_WIN4,
  91. NULL, &hinf);
  92. if (S_OK == hr)
  93. {
  94. BOOL frt;
  95. // It may say "Install" but this really deletes a bunch of
  96. // registry "leftovers" from previous installs
  97. frt = SetupInstallFromInfSection(NULL, hinf, c_szCleanSection,
  98. SPINST_ALL, NULL, NULL, NULL,
  99. NULL, NULL, NULL, NULL);
  100. if (frt)
  101. {
  102. frt = SetupInstallServicesFromInfSection(hinf,
  103. c_szCleanServicesSection,
  104. 0);
  105. if (!frt)
  106. {
  107. hr = HrFromLastWin32Error();
  108. TraceErrorOptional("SetupInstallServicesFromInfSection", hr,
  109. (hr == HRESULT_FROM_SETUPAPI(ERROR_SECTION_NOT_FOUND)));
  110. }
  111. }
  112. else
  113. {
  114. hr = HrFromLastWin32Error();
  115. TraceErrorOptional("SetupInstallServicesFromInfSection", hr,
  116. (hr == HRESULT_FROM_SETUPAPI(ERROR_SECTION_NOT_FOUND)));
  117. }
  118. SetupCloseInfFile(hinf);
  119. }
  120. if (HRESULT_FROM_SETUPAPI(ERROR_SECTION_NOT_FOUND) == hr)
  121. {
  122. hr = S_OK;
  123. }
  124. TraceError("HrRunAnswerFileCleanSection", hr);
  125. return hr;
  126. }
  127. // ----------------------------------------------------------------------
  128. //
  129. // Function: HrSaveInstanceGuid
  130. //
  131. // Purpose: Save instance guid of the specified component to the registry
  132. //
  133. // Arguments:
  134. // pszComponentName [in] name of
  135. // pguidInstance [in] pointer to
  136. //
  137. // Returns: S_OK on success, otherwise an error code
  138. //
  139. // Author: kumarp 23-December-97
  140. //
  141. // Notes:
  142. //
  143. HRESULT HrSaveInstanceGuid(
  144. IN PCWSTR pszComponentName,
  145. IN const GUID* pguidInstance)
  146. {
  147. TraceFileFunc(ttidGuiModeSetup);
  148. DefineFunctionName("HrSaveInstanceGuid");
  149. AssertValidReadPtr(pszComponentName);
  150. AssertValidReadPtr(pguidInstance);
  151. HRESULT hr;
  152. HKEY hkeyMap;
  153. hr = HrRegCreateKeyEx (
  154. HKEY_LOCAL_MACHINE,
  155. c_szRegKeyAnswerFileMap,
  156. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  157. &hkeyMap, NULL);
  158. if (S_OK == hr)
  159. {
  160. hr = HrRegSetGuidAsSz (hkeyMap, pszComponentName, *pguidInstance);
  161. RegCloseKey (hkeyMap);
  162. }
  163. TraceFunctionError(hr);
  164. return hr;
  165. }
  166. // ----------------------------------------------------------------------
  167. //
  168. // Function: HrLoadInstanceGuid
  169. //
  170. // Purpose: Load instance guid of the specified component from registry
  171. //
  172. // Arguments:
  173. // pszComponentName [in] name of
  174. // pguidInstance [out] pointer to
  175. //
  176. // Returns: S_OK on success, otherwise an error code
  177. //
  178. // Author: kumarp 23-December-97
  179. //
  180. // Notes:
  181. //
  182. HRESULT HrLoadInstanceGuid(
  183. IN PCWSTR pszComponentName,
  184. OUT LPGUID pguidInstance)
  185. {
  186. TraceFileFunc(ttidGuiModeSetup);
  187. DefineFunctionName("HrLoadInstanceGuid");
  188. Assert (pszComponentName);
  189. Assert (pguidInstance);
  190. HRESULT hr;
  191. HKEY hkeyMap;
  192. ZeroMemory(pguidInstance, sizeof(GUID));
  193. hr = HrRegOpenKeyEx (
  194. HKEY_LOCAL_MACHINE,
  195. c_szRegKeyAnswerFileMap,
  196. KEY_READ,
  197. &hkeyMap);
  198. if (S_OK == hr)
  199. {
  200. WCHAR szGuid[c_cchGuidWithTerm];
  201. DWORD cbGuid = sizeof(szGuid);
  202. hr = HrRegQuerySzBuffer (
  203. hkeyMap,
  204. pszComponentName,
  205. szGuid,
  206. &cbGuid);
  207. if (S_OK == hr)
  208. {
  209. hr = IIDFromString (szGuid, pguidInstance);
  210. }
  211. RegCloseKey (hkeyMap);
  212. }
  213. TraceFunctionError(hr);
  214. return hr;
  215. }
  216. static const PCWSTR c_aszServicesToIgnore[] =
  217. {
  218. L"afd",
  219. L"asyncmac",
  220. L"atmarp",
  221. L"dhcp",
  222. L"nbf", // see bug 143346
  223. L"ndistapi",
  224. L"ndiswan",
  225. L"nwlnkipx",
  226. L"nwlnknb",
  227. L"nwlnkspx",
  228. L"rpcss",
  229. L"wanarp",
  230. };
  231. // ----------------------------------------------------------------------
  232. //
  233. // Function: HrRestoreServiceStartValuesToPreUpgradeSetting
  234. //
  235. // Purpose: Restore start value of each network service to
  236. // what was before upgrade
  237. //
  238. // Arguments:
  239. // pwifAnswerFile [in] pointer to CWInfFile object
  240. //
  241. // Returns: S_OK on success, otherwise an error code
  242. //
  243. // Author: kumarp 23-December-97
  244. //
  245. // Notes:
  246. //
  247. HRESULT HrRestoreServiceStartValuesToPreUpgradeSetting(IN CWInfFile* pwifAnswerFile)
  248. {
  249. TraceFileFunc(ttidGuiModeSetup);
  250. DefineFunctionName("HrRestoreServiceStartValuesToPreUpgradeSetting");
  251. CWInfSection* pwisServiceStartTypes;
  252. pwisServiceStartTypes = pwifAnswerFile->FindSection(c_szAfServiceStartTypes);
  253. if (!pwisServiceStartTypes)
  254. {
  255. return S_OK;
  256. }
  257. HRESULT hr;
  258. CServiceManager scm;
  259. hr = scm.HrOpen();
  260. if (SUCCEEDED(hr))
  261. {
  262. DWORD dwPreUpgRouterStartType=0;
  263. DWORD dwPreUpgRemoteAccessStartType=0;
  264. DWORD dwRRASStartType=0;
  265. DWORD dwPreUpgRipForIpStartType=0;
  266. DWORD dwPreUpgRipForIpxStartType=0;
  267. DWORD dwPreUpgDhcpRelayAgentStartType=0;
  268. // In Windows2000, Router and RemoteAccess have merged.
  269. // If they have differing service start types before upgrade
  270. // we use the lower of the two start-type values to set
  271. // the start-type of "Routing and remote access" service.
  272. //
  273. // for more info see bug# 260253
  274. //
  275. if (pwisServiceStartTypes->GetIntValue(c_szSvcRouter,
  276. &dwPreUpgRouterStartType) &&
  277. pwisServiceStartTypes->GetIntValue(c_szSvcRemoteAccess,
  278. &dwPreUpgRemoteAccessStartType))
  279. {
  280. dwRRASStartType = min(dwPreUpgRemoteAccessStartType,
  281. dwPreUpgRouterStartType);
  282. TraceTag(ttidNetSetup, "%s: pre-upg start-types:: Router: %d, RemoteAccess: %d",
  283. __FUNCNAME__, dwPreUpgRouterStartType,
  284. dwPreUpgRemoteAccessStartType);
  285. }
  286. // 306202: if IPRIP/IPXRIP/DHCPrelayagent were in use on NT4, set RRAS to Auto
  287. //
  288. if (pwisServiceStartTypes->GetIntValue(c_szSvcRipForIp, &dwPreUpgRipForIpStartType) &&
  289. (SERVICE_AUTO_START == dwPreUpgRipForIpStartType))
  290. {
  291. TraceTag(ttidNetSetup, "%s: pre-upg start-types:: IPRIP: %d, RemoteAccess: %d",
  292. __FUNCNAME__, dwPreUpgRipForIpStartType,
  293. dwPreUpgRemoteAccessStartType);
  294. dwRRASStartType = SERVICE_AUTO_START;
  295. }
  296. if (pwisServiceStartTypes->GetIntValue(c_szSvcRipForIpx, &dwPreUpgRipForIpxStartType) &&
  297. (SERVICE_AUTO_START == dwPreUpgRipForIpxStartType))
  298. {
  299. TraceTag(ttidNetSetup, "%s: pre-upg start-types:: RipForIpx: %d, RemoteAccess: %d",
  300. __FUNCNAME__, dwPreUpgRipForIpxStartType,
  301. dwPreUpgRemoteAccessStartType);
  302. dwRRASStartType = SERVICE_AUTO_START;
  303. }
  304. if (pwisServiceStartTypes->GetIntValue(c_szSvcDhcpRelayAgent, &dwPreUpgDhcpRelayAgentStartType) &&
  305. (SERVICE_AUTO_START == dwPreUpgDhcpRelayAgentStartType))
  306. {
  307. TraceTag(ttidNetSetup, "%s: pre-upg start-types:: DHCPRelayAgent: %d, RemoteAccess: %d",
  308. __FUNCNAME__, dwPreUpgDhcpRelayAgentStartType,
  309. dwPreUpgRemoteAccessStartType);
  310. dwRRASStartType = SERVICE_AUTO_START;
  311. }
  312. // end 306202
  313. for (CWInfKey* pwik = pwisServiceStartTypes->FirstKey();
  314. pwik;
  315. pwik = pwisServiceStartTypes->NextKey())
  316. {
  317. PCWSTR pszServiceName;
  318. DWORD dwPreUpgradeStartValue;
  319. pszServiceName = pwik->Name();
  320. AssertValidReadPtr(pszServiceName);
  321. dwPreUpgradeStartValue = pwik->GetIntValue(-1);
  322. if (dwPreUpgradeStartValue > SERVICE_DISABLED)
  323. {
  324. NetSetupLogStatusV(
  325. LogSevError,
  326. SzLoadIds (IDS_INVALID_PREUPGRADE_START),
  327. pszServiceName);
  328. continue;
  329. }
  330. // We do not want to restore the pre-upgrade start type if:
  331. // - it is one of c_aszServicesToIgnore AND
  332. //
  333. if (FIsInStringArray(c_aszServicesToIgnore,
  334. celems(c_aszServicesToIgnore),
  335. pszServiceName))
  336. {
  337. NetSetupLogStatusV(
  338. LogSevInformation,
  339. SzLoadIds (IDS_IGNORED_SERVICE_PREUPGRADE), pszServiceName);
  340. continue;
  341. }
  342. // special case for RRAS, see the comment before the while loop
  343. if ((dwRRASStartType != 0) &&
  344. !lstrcmpiW(pszServiceName, c_szSvcRemoteAccess))
  345. {
  346. dwPreUpgradeStartValue = dwRRASStartType;
  347. }
  348. // 305065: if RasAuto was not disabled on NT4, make it demand-start on NT5
  349. else if ((SERVICE_DISABLED != dwPreUpgradeStartValue) &&
  350. !lstrcmpiW(pszServiceName, c_szSvcRasAuto))
  351. {
  352. dwPreUpgradeStartValue = SERVICE_DEMAND_START;
  353. NetSetupLogStatusV(
  354. LogSevInformation,
  355. SzLoadIds (IDS_FORCING_DEMAND_START),
  356. pszServiceName);
  357. }
  358. CService service;
  359. hr = scm.HrOpenService(&service, pszServiceName);
  360. if (S_OK == hr)
  361. {
  362. DWORD dwStartValue;
  363. hr = service.HrQueryStartType(&dwStartValue);
  364. if ((S_OK == hr) && (dwStartValue != dwPreUpgradeStartValue))
  365. {
  366. hr = service.HrSetStartType(dwPreUpgradeStartValue);
  367. NetSetupLogHrStatusV(hr,
  368. SzLoadIds (IDS_RESTORING_START_TYPE),
  369. pszServiceName, dwStartValue, dwPreUpgradeStartValue, hr);
  370. }
  371. }
  372. }
  373. // ignore any errors
  374. hr = S_OK;
  375. }
  376. TraceError(__FUNCNAME__, hr);
  377. return hr;
  378. }
  379. // GUIDs provided for the sole use of this function, which removes incompatible
  380. // Intel Winsock providers
  381. //
  382. const GUID GUID_INTEL_RSVP =
  383. { 0x0f1e5156L, 0xf07a, 0x11cf, 0x98, 0x0e, 0x00, 0xaa, 0x00, 0x58, 0x0a, 0x07 };
  384. const GUID GUID_INTEL_GQOS1 =
  385. { 0xbca8a790L, 0xc186, 0x11d0, 0xb8, 0x69, 0x00, 0xa0, 0xc9, 0x08, 0x1e, 0x34 };
  386. const GUID GUID_INTEL_GQOS2 =
  387. { 0xf80d1d20L, 0x8b7a, 0x11d0, 0xb8, 0x53, 0x00, 0xa0, 0xc9, 0x08, 0x1e, 0x34 };
  388. //+---------------------------------------------------------------------------
  389. //
  390. // Function: HrRemoveEvilIntelRSVPWinsockSPs
  391. //
  392. // Purpose: Remove the Intel RSVP Winsock SP's so they don't conflict
  393. // with the Windows 2000 RSVP provider. This is a complete hack
  394. // to cure RAID 332622, but it's all we can do this late in the
  395. // ship cycle. There's not a good general-case fix for this
  396. // problem.
  397. //
  398. // Arguments:
  399. // (none)
  400. //
  401. // Returns:
  402. //
  403. // Author: jeffspr 22 Aug 1999
  404. //
  405. // Notes:
  406. //
  407. HRESULT HrRemoveEvilIntelWinsockSPs()
  408. {
  409. TraceFileFunc(ttidGuiModeSetup);
  410. HRESULT hr = S_OK;
  411. // Now read the new IDs and order them in memory
  412. //
  413. INT nErr = NO_ERROR;
  414. ULONG ulRes;
  415. DWORD cbInfo = 0;
  416. WSAPROTOCOL_INFO* pwpi = NULL;
  417. WSAPROTOCOL_INFO* pwpiInfo = NULL;
  418. // First get the size needed
  419. //
  420. ulRes = WSCEnumProtocols(NULL, NULL, &cbInfo, &nErr);
  421. if ((SOCKET_ERROR == ulRes) && (WSAENOBUFS == nErr))
  422. {
  423. pwpi = reinterpret_cast<WSAPROTOCOL_INFO*>(new BYTE[cbInfo]);
  424. if (pwpi)
  425. {
  426. // Find out all the protocols on the system
  427. //
  428. ulRes = WSCEnumProtocols(NULL, pwpi, &cbInfo, &nErr);
  429. if (SOCKET_ERROR != ulRes)
  430. {
  431. ULONG cProt = 0;
  432. for (pwpiInfo = pwpi, cProt = ulRes;
  433. cProt;
  434. cProt--, pwpiInfo++)
  435. {
  436. BOOL fDeleteMe = FALSE;
  437. if (IsEqualGUID(GUID_INTEL_RSVP, pwpiInfo->ProviderId))
  438. {
  439. fDeleteMe = TRUE;
  440. }
  441. else if (IsEqualGUID(GUID_INTEL_GQOS1, pwpiInfo->ProviderId))
  442. {
  443. fDeleteMe = TRUE;
  444. }
  445. else if (IsEqualGUID(GUID_INTEL_GQOS2, pwpiInfo->ProviderId))
  446. {
  447. fDeleteMe = TRUE;
  448. }
  449. if (fDeleteMe)
  450. {
  451. int iErrNo = 0;
  452. int iReturn = WSCDeinstallProvider(
  453. &pwpiInfo->ProviderId, &iErrNo);
  454. TraceTag(ttidNetSetup,
  455. "SP Removal guid: %08x %04x %04x %02x%02x %02x%02x%02x%02x%02x%02x",
  456. pwpiInfo->ProviderId.Data1,
  457. pwpiInfo->ProviderId.Data2,
  458. pwpiInfo->ProviderId.Data3,
  459. pwpiInfo->ProviderId.Data4[0],
  460. pwpiInfo->ProviderId.Data4[1],
  461. pwpiInfo->ProviderId.Data4[2],
  462. pwpiInfo->ProviderId.Data4[3],
  463. pwpiInfo->ProviderId.Data4[4],
  464. pwpiInfo->ProviderId.Data4[5],
  465. pwpiInfo->ProviderId.Data4[6],
  466. pwpiInfo->ProviderId.Data4[7],
  467. pwpiInfo->ProviderId.Data4[8]);
  468. TraceTag(ttidNetSetup,
  469. "Removing incompatible RSVP WS provider: %S (%d, %04x), ret=%d, ierr=%d",
  470. pwpiInfo->szProtocol, pwpiInfo->dwCatalogEntryId,
  471. pwpiInfo->dwCatalogEntryId,
  472. iReturn, iErrNo);
  473. }
  474. }
  475. }
  476. else
  477. {
  478. TraceTag(ttidNetSetup, "Socket error in secondary WSCEnumProtocols");
  479. }
  480. delete pwpi;
  481. }
  482. }
  483. else
  484. {
  485. TraceTag(ttidNetSetup, "Socket error in initial WSCEnumProtocols");
  486. }
  487. TraceHr(ttidNetSetup, FAL, hr, FALSE, "HrRemoveEvilIntelWinsockSPs");
  488. // Yes, we track hr for debugging purposes, but we don't ever want to
  489. // fail based on a failed removal of incompatible Winsock providers
  490. //
  491. return S_OK;
  492. }
  493. BOOL FIsValidCatalogId(WSAPROTOCOL_INFO *pwpi, ULONG cProt, DWORD dwCatId)
  494. {
  495. TraceFileFunc(ttidGuiModeSetup);
  496. for (; cProt; cProt--, pwpi++)
  497. {
  498. if (dwCatId == pwpi->dwCatalogEntryId)
  499. return TRUE;
  500. }
  501. return FALSE;
  502. }
  503. HRESULT HrRestoreWinsockProviderOrder(IN CWInfFile* pwifAnswerFile)
  504. {
  505. TraceFileFunc(ttidGuiModeSetup);
  506. HRESULT hr = S_OK;
  507. vector<DWORD> vecIds;
  508. CWInfSection * pwisWinsock;
  509. DefineFunctionName("HrRestoreWinsockProviderOrder");
  510. // First get the old IDs into a vector of DWORDs
  511. //
  512. pwisWinsock = pwifAnswerFile->FindSection(c_szAfSectionWinsock);
  513. if (pwisWinsock)
  514. {
  515. tstring strOrder;
  516. PWSTR pszOrder;
  517. PWSTR pszId;
  518. pwisWinsock->GetStringValue(c_szAfKeyWinsockOrder, strOrder);
  519. if (!strOrder.empty())
  520. {
  521. pszOrder = SzDupSz(strOrder.c_str());
  522. pszId = wcstok(pszOrder, L".");
  523. while (pszId)
  524. {
  525. DWORD dwId = wcstoul(pszId, NULL, 10);
  526. vecIds.push_back(dwId);
  527. pszId = wcstok(NULL, L".");
  528. }
  529. delete pszOrder;
  530. // Now read the new IDs and order them in memory
  531. //
  532. INT nErr;
  533. ULONG ulRes;
  534. DWORD cbInfo = 0;
  535. WSAPROTOCOL_INFO* pwpi = NULL;
  536. WSAPROTOCOL_INFO* pwpiInfo = NULL;
  537. // First get the size needed
  538. //
  539. ulRes = WSCEnumProtocols(NULL, NULL, &cbInfo, &nErr);
  540. if ((SOCKET_ERROR == ulRes) && (WSAENOBUFS == nErr))
  541. {
  542. pwpi = reinterpret_cast<WSAPROTOCOL_INFO*>(new BYTE[cbInfo]);
  543. if (pwpi)
  544. {
  545. // Find out all the protocols on the system
  546. //
  547. ulRes = WSCEnumProtocols(NULL, pwpi, &cbInfo, &nErr);
  548. if (SOCKET_ERROR != ulRes)
  549. {
  550. ULONG cProt;
  551. vector<DWORD>::iterator iterLocation;
  552. iterLocation = vecIds.begin();
  553. for (pwpiInfo = pwpi, cProt = ulRes;
  554. cProt;
  555. cProt--, pwpiInfo++)
  556. {
  557. if (vecIds.end() == find(vecIds.begin(),
  558. vecIds.end(),
  559. pwpiInfo->dwCatalogEntryId))
  560. {
  561. // Not already in the list.. Add it after the last
  562. // entry we added (or the front if this is the first
  563. // addition)
  564. iterLocation = vecIds.insert(iterLocation,
  565. pwpiInfo->dwCatalogEntryId);
  566. }
  567. }
  568. DWORD * pdwIds = NULL;
  569. DWORD * pdwCurId;
  570. DWORD cdwIds = vecIds.size();
  571. pdwIds = new DWORD[ulRes];
  572. if (pdwIds)
  573. {
  574. #if DBG
  575. DWORD cValid = 0;
  576. #endif
  577. for (pdwCurId = pdwIds, iterLocation = vecIds.begin();
  578. iterLocation != vecIds.end();
  579. iterLocation++, pdwCurId++)
  580. {
  581. // Make sure we only re-order valid catalog
  582. // IDs
  583. if (FIsValidCatalogId(pwpi, ulRes, *iterLocation))
  584. {
  585. #if DBG
  586. cValid++;
  587. #endif
  588. *pdwCurId = *iterLocation;
  589. }
  590. }
  591. AssertSz(ulRes == cValid, "Number of providers is"
  592. " different!");
  593. // Restore the winsock provider order
  594. //
  595. nErr = WSCWriteProviderOrder(pdwIds, cdwIds);
  596. delete pdwIds;
  597. }
  598. }
  599. delete pwpi;
  600. }
  601. }
  602. }
  603. }
  604. TraceError(__FUNCNAME__, hr);
  605. return hr;
  606. }
  607. // ----------------------------------------------------------------------
  608. //
  609. // Function: HrUpgradeOemComponent
  610. //
  611. // Purpose: Upgrade a component. This started as a generalized function
  612. // but currently it is being used only by HrUpgradeRouterIfPresent
  613. //
  614. // Arguments:
  615. // pszComponentToUpgrade [in] component to upgrade
  616. // pszDllName [in] name of DLL to load
  617. // psznEntryPoint [in] entry point to call
  618. // dwUpgradeFlag [in] upgrade flag
  619. // dwUpgradeFromBuildNumber [in] upgrade to build number
  620. // pszAnswerFileName [in] name of answerfile
  621. // pszAnswerFileSectionName [in] name of answerfile section name to use
  622. //
  623. // Returns: S_OK on success, otherwise an error code
  624. //
  625. // Author: kumarp 23-December-97
  626. //
  627. // Notes:
  628. //
  629. HRESULT
  630. HrUpgradeOemComponent (
  631. IN PCWSTR pszComponentToUpgrade,
  632. IN PCWSTR pszDllName,
  633. IN PCSTR psznEntryPoint,
  634. IN DWORD dwUpgradeFlag,
  635. IN DWORD dwUpgradeFromBuildNumber,
  636. IN PCWSTR pszAnswerFileName,
  637. IN PCWSTR pszAnswerFileSectionName)
  638. {
  639. TraceFileFunc(ttidGuiModeSetup);
  640. DefineFunctionName("HrUpgradeOemComponent");
  641. HRESULT hr=E_FAIL;
  642. HrOemComponentUpgradeFnPrototype pfn;
  643. HMODULE hLib;
  644. TraceTag(ttidNetSetup,
  645. "%s: calling function '%s' in '%S' to upgrade component: %S...",
  646. __FUNCNAME__, psznEntryPoint, pszDllName, pszComponentToUpgrade);
  647. hr = HrLoadLibAndGetProc(pszDllName, psznEntryPoint, &hLib, (FARPROC*) &pfn);
  648. if (S_OK == hr)
  649. {
  650. NC_TRY
  651. {
  652. hr = pfn(dwUpgradeFlag, dwUpgradeFromBuildNumber,
  653. pszAnswerFileName, pszAnswerFileSectionName);
  654. }
  655. NC_CATCH_ALL
  656. {
  657. hr = E_UNEXPECTED;
  658. }
  659. FreeLibrary(hLib);
  660. }
  661. TraceError(__FUNCNAME__, hr);
  662. return hr;
  663. }
  664. // ----------------------------------------------------------------------
  665. //
  666. // Function: HrUpgradeRouterIfPresent
  667. //
  668. // Purpose: Upgrade the Router service if present
  669. //
  670. // Arguments:
  671. // pnii [in] pointer to CNetInstallInfo object
  672. //
  673. // Returns: S_OK on success, otherwise an error code
  674. //
  675. // Author: kumarp 23-December-97
  676. //
  677. // Notes:
  678. //
  679. HRESULT HrUpgradeRouterIfPresent(
  680. IN INetCfg* pNetCfg,
  681. IN CNetInstallInfo* pnii)
  682. {
  683. TraceFileFunc(ttidGuiModeSetup);
  684. DefineFunctionName("HrUpgradeRouterIfPresent");
  685. HRESULT hr=S_FALSE;
  686. INFCONTEXT ic;
  687. PCWSTR pszRouterParamsSection=NULL;
  688. CNetComponent* pnc = pnii->FindFromInfID(L"ms_rasrtr");
  689. if (pnc)
  690. {
  691. // Ensure RemoteAccess is installed. In the case of upgrade from
  692. // NT4 with Steelhead, we wouldn't have written a section to
  693. // the answerfile for RemoteAccess and consequently it would not
  694. // have been installed yet. We need to install it before we turn
  695. // the router upgrade DLL loose. In the case when RemoteAccess
  696. // is already installed, this is a no-op.
  697. //
  698. hr = HrInstallComponentOboUser (pNetCfg, NULL,
  699. GUID_DEVCLASS_NETSERVICE,
  700. c_szInfId_MS_RasSrv,
  701. NULL);
  702. if (SUCCEEDED(hr))
  703. {
  704. // we call rtrupg.dll if atleast one of the following keys
  705. // is present in the params.MS_RasRtr section
  706. // - PreUpgradeRouter
  707. // - Sap.Parameters
  708. // - IpRip.Parameters
  709. //
  710. pszRouterParamsSection = pnc->ParamsSections().c_str();
  711. hr = HrSetupFindFirstLine(pnii->m_hinfAnswerFile, pszRouterParamsSection,
  712. c_szAfPreUpgradeRouter, &ic);
  713. if (S_OK != hr)
  714. {
  715. hr = HrSetupFindFirstLine(pnii->m_hinfAnswerFile, pszRouterParamsSection,
  716. c_szAfNwSapAgentParams, &ic);
  717. }
  718. if (S_OK != hr)
  719. {
  720. hr = HrSetupFindFirstLine(pnii->m_hinfAnswerFile, pszRouterParamsSection,
  721. c_szAfIpRipParameters, &ic);
  722. }
  723. if (S_OK != hr)
  724. {
  725. hr = HrSetupFindFirstLine(pnii->m_hinfAnswerFile, pszRouterParamsSection,
  726. c_szAfDhcpRelayAgentParameters, &ic);
  727. }
  728. if (S_OK == hr)
  729. {
  730. hr = HrUpgradeOemComponent(L"ms_rasrtr",
  731. c_szRouterUpgradeDll,
  732. c_szRouterUpgradeFn,
  733. pnii->UpgradeFlag(),
  734. pnii->BuildNumber(),
  735. pnii->AnswerFileName(),
  736. pszRouterParamsSection);
  737. }
  738. }
  739. }
  740. if (!pnc ||
  741. (SPAPI_E_LINE_NOT_FOUND == hr))
  742. {
  743. TraceTag(ttidNetSetup, "%s: PreUpgradeRouter/Sap.Parameters/IpRip.Parameters key is not in answerfile, %S will not be called", __FUNCNAME__,
  744. c_szRouterUpgradeDll);
  745. }
  746. TraceErrorOptional(__FUNCNAME__, hr, ((hr == S_FALSE) ||
  747. (SPAPI_E_LINE_NOT_FOUND == hr)));
  748. return hr;
  749. }
  750. //+---------------------------------------------------------------------------
  751. //
  752. // Function: HrUpgradeTapiServer
  753. //
  754. // Purpose: Handle upgrade requirements of TAPI server
  755. //
  756. // Arguments:
  757. // hinfAnswerFile [in] handle of AnswerFile
  758. //
  759. // Returns: S_OK on success, otherwise an error code
  760. //
  761. // Author: kumarp 28-January-99
  762. //
  763. // Notes:
  764. //
  765. HRESULT HrUpgradeTapiServer(IN HINF hinfAnswerFile)
  766. {
  767. TraceFileFunc(ttidGuiModeSetup);
  768. Assert(hinfAnswerFile);
  769. DefineFunctionName("HrUpgradeTapiServer");
  770. TraceFunctionEntry(ttidNetSetup);
  771. HRESULT hr=S_OK;
  772. BOOL fRunInSeparateInstance=FALSE;
  773. hr = HrSetupGetFirstStringAsBool(hinfAnswerFile,
  774. c_szAfMiscUpgradeData,
  775. c_szAfTapiSrvRunInSeparateInstance,
  776. &fRunInSeparateInstance);
  777. if ((S_OK == hr) && fRunInSeparateInstance)
  778. {
  779. static const WCHAR c_szTapisrv[] = L"Tapisrv";
  780. static const CHAR c_szSvchostChangeSvchostGroup[] =
  781. "SvchostChangeSvchostGroup";
  782. static const WCHAR c_szNetcfgxDll[] = L"netcfgx.dll";
  783. TraceTag(ttidNetSetup, "%s: TapiSrvRunInSeparateInstance is TRUE...",
  784. __FUNCNAME__);
  785. typedef HRESULT (STDAPICALLTYPE *SvchostChangeSvchostGroupFn) (PCWSTR pszService, PCWSTR pszNewGroup);
  786. SvchostChangeSvchostGroupFn pfnSvchostChangeSvchostGroup;
  787. HMODULE hNetcfgx;
  788. hr = HrLoadLibAndGetProc(c_szNetcfgxDll, c_szSvchostChangeSvchostGroup,
  789. &hNetcfgx,
  790. (FARPROC*) &pfnSvchostChangeSvchostGroup);
  791. if (S_OK == hr)
  792. {
  793. hr = pfnSvchostChangeSvchostGroup(c_szTapisrv, c_szTapisrv);
  794. FreeLibrary(hNetcfgx);
  795. }
  796. }
  797. if ((SPAPI_E_LINE_NOT_FOUND == hr) ||
  798. (SPAPI_E_SECTION_NOT_FOUND == hr))
  799. {
  800. TraceTag(ttidNetSetup, "%s: %S not found in section [%S]",
  801. __FUNCNAME__, c_szAfTapiSrvRunInSeparateInstance,
  802. c_szAfMiscUpgradeData);
  803. hr = S_OK;
  804. }
  805. TraceError(__FUNCNAME__, hr);
  806. return hr;
  807. }