Leaked source code of windows server 2003
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.

4056 lines
122 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: I C S U P G R D . CPP
  7. //
  8. // Contents: Functions that is related to
  9. // o upgrade of ICS from Win98 SE, WinMe and Win2K to Whistler
  10. // o unattended clean install of Homenet on Whistler or later
  11. //
  12. // Date: 20-Sept-2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include <winsock2.h>
  18. #include <netcon.h>
  19. #include <netconp.h>
  20. #include <shfolder.h>
  21. #include <hnetcfg.h>
  22. #include <atlbase.h>
  23. extern CComModule _Module; // required by atlcom.h
  24. #include <atlcom.h>
  25. #include "ncatl.h"
  26. #include "ncui.h"
  27. #include "ncstring.h"
  28. #include "ncnetcfg.h"
  29. #include "kkutils.h"
  30. #include "kkcwinf.h"
  31. #include "nslog.h"
  32. #include "afilexp.h"
  33. #include "ncras.h"
  34. #include "ncreg.h"
  35. extern "C"
  36. {
  37. // Fix IA64 conflict with Shell Macro
  38. #undef IS_ALIGNED
  39. #include <ipnat.h>
  40. }
  41. #include "IcsUpgrd.h"
  42. #include "resource.h" // need to use string resource ids
  43. /*++
  44. Routine Description:
  45. This function drives the FIcsUpgrade call by
  46. passing a init'ed and opened CWInfFile object.
  47. Arguments:
  48. None
  49. Returns: TRUE if succeeded
  50. Notes:
  51. --*/
  52. BOOL FDoIcsUpgradeIfNecessary()
  53. {
  54. BOOL fRet = FALSE;
  55. HRESULT hr;
  56. tstring strAnswerFileName;
  57. hr = HrGetAnswerFileName(&strAnswerFileName);
  58. if (S_OK == hr)
  59. {
  60. CWInfFile wifIcsAnswerFile;
  61. // initialize answer file
  62. if (wifIcsAnswerFile.Init())
  63. {
  64. if (wifIcsAnswerFile.Open(strAnswerFileName.c_str()))
  65. {
  66. TraceTag(ttidNetSetup, "calling FIcsUpgrade now...");
  67. fRet = FIcsUpgrade(&wifIcsAnswerFile);
  68. wifIcsAnswerFile.Close();
  69. }
  70. else
  71. {
  72. TraceTag(ttidNetSetup, "wifIcsAnswerFile.Open failed");
  73. }
  74. }
  75. else
  76. {
  77. TraceTag(ttidNetSetup, "wifIcsAnswerFile.Init failed");
  78. }
  79. }
  80. else
  81. {
  82. TraceTag(ttidNetSetup, "HrGetAnswerFileName failed");
  83. }
  84. return fRet;
  85. }
  86. /*++
  87. Routine Description:
  88. Perform the upgrade of
  89. o ICS from Win98 SE, WinMe and Win2K
  90. o Unattended Homenet clean install
  91. Arguments:
  92. [in] pwifAnswerFile The answer-file contains upgrade info from Win9x or
  93. Windows XP unattended clean install.
  94. Returns: TRUE if succeeded
  95. Notes:
  96. --*/
  97. BOOL FIcsUpgrade(CWInfFile* pwifAnswerFile)
  98. {
  99. HRESULT hr = S_OK;
  100. ICS_UPGRADE_SETTINGS iusSettings;
  101. BOOL fUpgradeIcsToRrasNat = FALSE;
  102. BOOL fCoUninitialize = FALSE;
  103. DefineFunctionName("FIcsUpgrade");
  104. TraceFunctionEntry(ttidNetSetup);
  105. hr = CoInitialize(NULL);
  106. if (SUCCEEDED(hr))
  107. {
  108. fCoUninitialize = TRUE;
  109. }
  110. else
  111. {
  112. if (RPC_E_CHANGED_MODE == hr)
  113. {
  114. hr = S_OK;
  115. }
  116. else
  117. {
  118. TraceTag(ttidError,
  119. "%s: CoInitialize failed: 0x%lx",
  120. __FUNCNAME__, hr);
  121. NetSetupLogStatusV(
  122. LogSevError,
  123. SzLoadIds (IDS_TXT_CANT_UPGRADE_ICS));
  124. return FALSE;
  125. }
  126. }
  127. do
  128. {
  129. SetIcsDefaultSettings(&iusSettings);
  130. // check if we are upgrading from Windows 2000
  131. if (FNeedIcsUpgradeFromWin2K())
  132. {
  133. hr = BuildIcsUpgradeSettingsFromWin2K(&iusSettings);
  134. if (FAILED(hr))
  135. {
  136. TraceTag(ttidError,
  137. "%s: BuildIcsUpgradeSettingsFromWin2K failed: 0x%lx",
  138. __FUNCNAME__, hr);
  139. NetSetupLogStatusV(
  140. LogSevInformation,
  141. SzLoadIds (IDS_TXT_CANT_UPGRADE_ICS));
  142. break;
  143. }
  144. // ICS installed on Win2K if we are here
  145. if (FOsIsUnsupported())
  146. {
  147. TraceTag(ttidNetSetup,
  148. "%s: We're running an Unsupported SKU, won't upgrade ICS from Win2K.",
  149. __FUNCNAME__);
  150. fUpgradeIcsToRrasNat = TRUE;
  151. break;
  152. }
  153. // OS version is less than Advanced Server if we are here
  154. }
  155. else
  156. {
  157. // we need to check if we are doing ICS upgrade from Win9x or
  158. // doing unattended Homenet install on Windows XP or later
  159. if (NULL == pwifAnswerFile)
  160. {
  161. TraceTag(ttidNetSetup,
  162. "%s: Not an ICS Upgrade from Win2K and no answer-file.",
  163. __FUNCNAME__);
  164. break;
  165. }
  166. // Try to load "Homenet" section data from Answer-File
  167. hr = LoadIcsSettingsFromAnswerFile(pwifAnswerFile, &iusSettings);
  168. if (S_FALSE == hr)
  169. {
  170. // no Homenet section
  171. hr = S_OK;
  172. break;
  173. }
  174. if (FAILED(hr))
  175. {
  176. TraceTag(ttidNetSetup,
  177. "%s: LoadIcsSettingsFromAnswerFile failed: 0x%lx",
  178. __FUNCNAME__, hr);
  179. // this may not be an error because of bug# 253074 in Win9x
  180. // OEM ICS upgrade
  181. // I'm not going to log this to setup log
  182. if (iusSettings.fEnableICS && iusSettings.fWin9xUpgrade)
  183. {
  184. hr = S_OK; // ICS enabled but no internal/external adapters.
  185. }
  186. break;
  187. }
  188. // Assert: Answer file has valid [Homenet] section.
  189. // make sure OS SKU is less than Advanced Server
  190. if (FOsIsUnsupported())
  191. {
  192. TraceTag(ttidNetSetup,
  193. "%s: We're running an Unsupported SKU, won't do any homenet unattended setup.",
  194. __FUNCNAME__);
  195. NetSetupLogStatusV(
  196. LogSevInformation,
  197. SzLoadIds (IDS_TXT_CANT_UPGRADE_ICS_ADS_DTC));
  198. break;
  199. }
  200. }
  201. // upgrade ics settings to XP or do unattended Homenet if we
  202. // can reach here
  203. hr = UpgradeIcsSettings(&iusSettings);
  204. if (S_OK != hr)
  205. {
  206. TraceTag(ttidError,
  207. "%s: UpgradeIcsSettings failed : 0x%lx",
  208. __FUNCNAME__, hr);
  209. NetSetupLogStatusV(
  210. LogSevInformation,
  211. SzLoadIds (IDS_TXT_CANT_UPGRADE_ICS));
  212. }
  213. } while (FALSE);
  214. if (fUpgradeIcsToRrasNat)
  215. {
  216. // If we are here, ICS installed on Win2K and this is an upgrade of OS
  217. // to ADS/DTC SKUs. We won't upgrade ICS on ADS/DTC SKUs
  218. TraceTag(ttidNetSetup,
  219. "%s: We are not upgrading ICS on ADS/DTC SKUs",
  220. __FUNCNAME__);
  221. // During the "Report System Compatiblilty" stage (winnt32.exe) of this
  222. // OS upgrade process, user has already been notified that we're not
  223. // upgrading ICS on ADS/DTC SKUs.
  224. // we will still log a message to setupact.log file.
  225. NetSetupLogStatusV(
  226. LogSevInformation,
  227. SzLoadIds (IDS_TXT_CANT_UPGRADE_ICS_ADS_DTC));
  228. // we need to delete and backup the old ICS registry settings
  229. hr = BackupAndDelIcsRegistryValuesOnWin2k();
  230. if (FAILED(hr))
  231. {
  232. TraceTag(ttidNetSetup,
  233. "%s: BackupAndDelIcsRegistryValuesOnWin2k failed: 0x%lx",
  234. __FUNCNAME__, hr);
  235. }
  236. }
  237. // Free iusSettings contents if needed
  238. FreeIcsUpgradeSettings(&iusSettings);
  239. if (fCoUninitialize)
  240. {
  241. CoUninitialize();
  242. }
  243. return (S_OK == hr? TRUE : FALSE);
  244. }
  245. //--------- ICS Upgrade helpers begin----------------------------
  246. /*++
  247. Routine Description:
  248. Gets the current shared ICS connection On Win2K
  249. Arguments:
  250. [out] pConnection The shared connection information
  251. Returns: S_OK if succeeded
  252. Notes: Returns the interface connected to the internet
  253. --*/
  254. HRESULT GetSharedConnectionOnWin2k(LPRASSHARECONN pConnection)
  255. {
  256. HKEY hKey = NULL;
  257. HRESULT hr = S_OK;
  258. DefineFunctionName("GetSharedConnectionOnWin2k");
  259. TraceFunctionEntry(ttidNetSetup);
  260. Assert(pConnection);
  261. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_wszRegKeySharedAccessParams, KEY_ALL_ACCESS, &hKey);
  262. if (FAILED(hr))
  263. {
  264. TraceTag(ttidError,
  265. "%s: HrRegOpenKeyEx failed: 0x%lx",
  266. __FUNCNAME__, hr);
  267. return hr;
  268. }
  269. Assert(hKey);
  270. DWORD dwType = REG_BINARY;
  271. PBYTE pByte = NULL;
  272. DWORD dwValueSize = 0;
  273. hr = HrRegQueryValueWithAlloc(hKey, c_wszRegValSharedConnection, &dwType, &pByte, &dwValueSize);
  274. if (FAILED(hr))
  275. {
  276. TraceTag(ttidError,
  277. "%s: HrRegQueryValueWithAlloc %S failed: 0x%lx",
  278. __FUNCNAME__, c_wszRegValSharedConnection, hr);
  279. goto Exit;
  280. }
  281. if (dwValueSize > sizeof(RASSHARECONN))
  282. {
  283. TraceTag(ttidError,
  284. "%s: RASSHARECONN size too big: 0x%lx bytes",
  285. __FUNCNAME__, dwValueSize);
  286. hr = E_FAIL;
  287. goto Exit;
  288. }
  289. // transfer value
  290. memcpy(pConnection, pByte, dwValueSize);
  291. Exit:
  292. // Close the key, if opened
  293. RegSafeCloseKey(hKey);
  294. // Clean up the registry buffer
  295. if (pByte)
  296. {
  297. MemFree(pByte);
  298. }
  299. return hr;
  300. }
  301. /*++
  302. Routine Description:
  303. Gets the current private LAN connection on Win2K
  304. Arguments:
  305. [out] pGuid The private LAN information
  306. Returns: S_OK if succeeded
  307. Notes: Returns the interface connected to the private LAN
  308. On Win2K, there is only 1 private LAN connection
  309. --*/
  310. HRESULT GetSharedPrivateLanOnWin2K(GUID *pGuid)
  311. {
  312. HKEY hKey = NULL;
  313. HRESULT hr = S_OK;
  314. DefineFunctionName("GetSharedPrivateLanOnWin2K");
  315. TraceFunctionEntry(ttidNetSetup);
  316. Assert(pGuid);
  317. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_wszRegKeySharedAccessParams, KEY_ALL_ACCESS, &hKey);
  318. if (FAILED(hr))
  319. {
  320. TraceTag(ttidError,
  321. "%s: HrRegOpenKeyEx failed: 0x%lx",
  322. __FUNCNAME__, hr);
  323. return hr;
  324. }
  325. Assert(hKey);
  326. DWORD dwType = REG_SZ;
  327. PBYTE pByte = NULL;
  328. DWORD dwValueSize = 0;
  329. hr = HrRegQueryValueWithAlloc(hKey, c_wszRegValSharedPrivateLan, &dwType, &pByte, &dwValueSize);
  330. if (FAILED(hr))
  331. {
  332. TraceTag(ttidError,
  333. "%s: HrRegQueryValueWithAlloc %S failed: 0x%lx",
  334. __FUNCNAME__, c_wszRegValSharedPrivateLan, hr);
  335. goto Exit;
  336. }
  337. // SharedPrivateLan is of type REG_SZ, pByte should have included
  338. // the terminating null character.
  339. hr = CLSIDFromString(reinterpret_cast<PWCHAR>(pByte), pGuid);
  340. Exit:
  341. // Close the key, if opened
  342. RegSafeCloseKey(hKey);
  343. // Clean up the registry buffer
  344. if (pByte)
  345. {
  346. MemFree(pByte);
  347. }
  348. return hr;
  349. }
  350. /*++
  351. Routine Description:
  352. Delete and backup SharedConnection and SharedPrivateLan registry values
  353. Arguments: none
  354. Returns: S_OK if succeeded
  355. Notes:
  356. --*/
  357. HRESULT BackupAndDelIcsRegistryValuesOnWin2k()
  358. {
  359. HKEY hKey = NULL;
  360. HRESULT hr = S_OK;
  361. DefineFunctionName("BackupAndDelIcsRegistryValuesOnWin2k");
  362. TraceFunctionEntry(ttidNetSetup);
  363. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_wszRegKeySharedAccessParams, KEY_ALL_ACCESS, &hKey);
  364. if (FAILED(hr))
  365. {
  366. TraceTag(ttidError,
  367. "%s: HrRegOpenKeyEx failed: 0x%lx",
  368. __FUNCNAME__, hr);
  369. return hr;
  370. }
  371. Assert(hKey);
  372. DWORD dwType = REG_BINARY;
  373. PBYTE pByte = NULL;
  374. DWORD dwValueSize = 0;
  375. // backup SharedConnection
  376. hr = HrRegQueryValueWithAlloc(hKey, c_wszRegValSharedConnection, &dwType, &pByte, &dwValueSize);
  377. if (FAILED(hr))
  378. {
  379. TraceTag(ttidError,
  380. "%s: HrRegQueryValueWithAlloc %S failed: 0x%lx",
  381. __FUNCNAME__, c_wszRegValSharedConnection, hr);
  382. goto Exit;
  383. }
  384. hr = HrRegSetValueEx(hKey, c_wszRegValBackupSharedConnection, dwType, pByte, dwValueSize);
  385. if (FAILED(hr))
  386. {
  387. TraceTag(ttidError,
  388. "%s: HrRegSetValueEx %S failed: 0x%lx",
  389. __FUNCNAME__, c_wszRegValBackupSharedConnection, hr);
  390. goto Exit;
  391. }
  392. if (pByte)
  393. {
  394. MemFree(pByte);
  395. }
  396. // Reset values
  397. pByte = NULL;
  398. dwValueSize = 0;
  399. dwType = REG_SZ;
  400. // backup SharedPrivateLan
  401. hr = HrRegQueryValueWithAlloc(hKey, c_wszRegValSharedPrivateLan, &dwType, &pByte, &dwValueSize);
  402. if (FAILED(hr))
  403. {
  404. TraceTag(ttidError,
  405. "%s: HrRegQueryValueWithAlloc %S failed: 0x%lx",
  406. __FUNCNAME__, c_wszRegValSharedPrivateLan, hr);
  407. goto Exit;
  408. }
  409. hr = HrRegSetValueEx(hKey, c_wszRegValBackupSharedPrivateLan, dwType, pByte, dwValueSize);
  410. if (FAILED(hr))
  411. {
  412. TraceTag(ttidError,
  413. "%s: HrRegSetValueEx %S failed: 0x%lx",
  414. __FUNCNAME__, c_wszRegValBackupSharedPrivateLan, hr);
  415. goto Exit;
  416. }
  417. Exit:
  418. // Delete SharedConnection and ShardPrivateLan named values, ignore any errors
  419. HrRegDeleteValue(hKey, c_wszRegValSharedConnection);
  420. HrRegDeleteValue(hKey, c_wszRegValSharedPrivateLan);
  421. RegSafeCloseKey(hKey);
  422. if (pByte)
  423. {
  424. MemFree(pByte);
  425. }
  426. return hr;
  427. }
  428. /*++
  429. Routine Description:
  430. Gets the RAS phonebook directory
  431. Arguments:
  432. [out] pszPathBuf The phone book path
  433. Returns: S_OK if succeeded
  434. Notes:
  435. --*/
  436. HRESULT GetPhonebookDirectory(WCHAR* pwszPathBuf)
  437. // Loads caller's 'pszPathBuf' (should have length MAX_PATH + 1) with the
  438. // path to the directory containing phonebook files for the given mode,
  439. // e.g. c:\nt\system32\ras\" for mode PBM_Router. Note the
  440. // trailing backslash.
  441. //
  442. // Returns true if successful, false otherwise. Caller is guaranteed that
  443. // an 8.3 filename will fit on the end of the directory without exceeding
  444. // MAX_PATH.
  445. //
  446. {
  447. DefineFunctionName("GetPhonebookDirectory");
  448. TraceFunctionEntry(ttidNetSetup);
  449. HANDLE hToken = NULL;
  450. PFNSHGETFOLDERPATHW pfnSHGetFolderPathW;
  451. HINSTANCE Hinstance;
  452. //
  453. // Load ShFolder.dll, which contains the 'SHGetFolderPath' entrypoint
  454. // that we will use to get the Application data for all users path
  455. if (!(Hinstance = LoadLibraryW(c_wszShFolder)) ||
  456. !(pfnSHGetFolderPathW = (PFNSHGETFOLDERPATHW)
  457. GetProcAddress(Hinstance, c_szSHGetFolderPathW)))
  458. {
  459. if (Hinstance)
  460. {
  461. FreeLibrary(Hinstance);
  462. }
  463. return E_FAIL;
  464. }
  465. if ((OpenThreadToken(
  466. GetCurrentThread(),
  467. TOKEN_QUERY | TOKEN_IMPERSONATE,
  468. TRUE,
  469. &hToken)
  470. || OpenProcessToken(
  471. GetCurrentProcess(),
  472. TOKEN_QUERY | TOKEN_IMPERSONATE,
  473. &hToken)))
  474. {
  475. HRESULT hr;
  476. INT csidl = CSIDL_COMMON_APPDATA;
  477. hr = pfnSHGetFolderPathW(NULL, csidl, hToken, 0, pwszPathBuf);
  478. if (SUCCEEDED(hr))
  479. {
  480. if(lstrlen(pwszPathBuf) <=
  481. (MAX_PATH -
  482. (lstrlen(c_wszPhoneBookPath))))
  483. {
  484. lstrcat(pwszPathBuf, c_wszPhoneBookPath);
  485. CloseHandle(hToken);
  486. FreeLibrary(Hinstance);
  487. return S_OK;
  488. }
  489. }
  490. else
  491. {
  492. TraceTag(ttidError, "%s: SHGetFolderPath failed: 0x%lx",
  493. __FUNCNAME__, hr);
  494. }
  495. CloseHandle(hToken);
  496. }
  497. FreeLibrary(Hinstance);
  498. return E_FAIL;
  499. }
  500. /*++
  501. Routine Description:
  502. CSharedAccessServer::CSharedAccessServer() Constructor
  503. Arguments: none
  504. Return Value: none
  505. Notes:
  506. --*/
  507. CSharedAccessServer::CSharedAccessServer()
  508. {
  509. m_wPort = 0;
  510. m_wInternalPort = 0;
  511. m_bBuiltIn = FALSE;
  512. m_bSelected = FALSE;
  513. m_dwSectionNum = 0;
  514. };
  515. /*++
  516. Routine Description:
  517. Returns the current list of Shared Access Servers
  518. Arguments:
  519. [in,out] lstSharedAccessServers List of SharedAccessServers
  520. Returns: S_OK if succeeded
  521. Notes: Reads the sharedaccess.ini phonebook file for server mappings.
  522. --*/
  523. HRESULT GetServerMappings(list<CSharedAccessServer> &lstSharedAccessServers)
  524. {
  525. WCHAR wszPathBuf[MAX_PATH + 1];
  526. HRESULT hr = GetPhonebookDirectory(wszPathBuf);
  527. if FAILED(hr)
  528. return hr;
  529. tstring strIniFile; // full pathname to sharedaccess.ini
  530. strIniFile = wszPathBuf;
  531. strIniFile += c_wszFileSharedAccess;
  532. const DWORD dwBufSize = 32768; // limit the section buffer size to the same value as Win9x max. buffer size
  533. PWCHAR wszLargeReturnedString = new WCHAR[dwBufSize];
  534. if (NULL == wszLargeReturnedString)
  535. {
  536. return E_OUTOFMEMORY;
  537. }
  538. DWORD dwResult;
  539. dwResult = GetPrivateProfileSection(c_wszContentsServer, wszLargeReturnedString, dwBufSize-1, strIniFile.c_str());
  540. if (dwResult)
  541. {
  542. PWCHAR wszEnd = wszLargeReturnedString + dwResult;
  543. for (PWCHAR wszServer = wszLargeReturnedString; (*wszServer) && (wszServer < wszEnd); wszServer += wcslen(wszServer) + 1)
  544. {
  545. WCHAR wszReturnedString[MAX_PATH];
  546. PWCHAR wszSectionNum = NULL;
  547. PWCHAR wszEnabled;
  548. // prefix bug# 295834
  549. wszSectionNum = new WCHAR[wcslen(wszServer)+1];
  550. if (NULL == wszSectionNum)
  551. {
  552. delete [] wszLargeReturnedString;
  553. return E_OUTOFMEMORY;
  554. }
  555. wcscpy(wszSectionNum, wszServer);
  556. PWCHAR wszAssign = wcschr(wszSectionNum, L'=');
  557. if (wszAssign)
  558. {
  559. *wszAssign = NULL;
  560. wszEnabled = wszAssign + 1;
  561. }
  562. else
  563. {
  564. wszEnabled = FALSE;
  565. }
  566. tstring strSectionName;
  567. strSectionName = c_wszServerPrefix; // prefix bug# 295835
  568. strSectionName += wszSectionNum; // prefix bug# 295836
  569. CSharedAccessServer SharedAccessServer;
  570. SharedAccessServer.m_dwSectionNum = _wtoi(wszSectionNum);
  571. SharedAccessServer.m_bSelected = _wtoi(wszEnabled);
  572. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszInternalName, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  573. if (dwResult)
  574. {
  575. SharedAccessServer.m_szInternalName = wszReturnedString;
  576. }
  577. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszTitle, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  578. if (dwResult)
  579. {
  580. SharedAccessServer.m_szTitle = wszReturnedString;
  581. }
  582. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszInternalPort, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  583. if (dwResult)
  584. {
  585. SharedAccessServer.m_wInternalPort = static_cast<USHORT>(_wtoi(wszReturnedString));
  586. }
  587. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszPort, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  588. if (dwResult)
  589. {
  590. SharedAccessServer.m_wPort = static_cast<USHORT>(_wtoi(wszReturnedString));
  591. }
  592. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszReservedAddress, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  593. if (dwResult)
  594. {
  595. SharedAccessServer.m_szReservedAddress = wszReturnedString;
  596. }
  597. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszProtocol, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  598. if (dwResult)
  599. {
  600. SharedAccessServer.m_szProtocol = wszReturnedString;
  601. }
  602. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszBuiltIn, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  603. if (dwResult)
  604. {
  605. SharedAccessServer.m_bBuiltIn = static_cast<USHORT>(_wtoi(wszReturnedString));
  606. }
  607. lstSharedAccessServers.insert(lstSharedAccessServers.end(), SharedAccessServer);
  608. delete [] wszSectionNum;
  609. wszSectionNum = NULL;
  610. }
  611. }
  612. delete [] wszLargeReturnedString;
  613. return S_OK;
  614. }
  615. /*++
  616. Routine Description:
  617. Returns the current list of Shared Access Applications
  618. Arguments:
  619. [in,out] lstSharedAccessApplications List of SharedAccessApplications
  620. Returns: S_OK if succeeded
  621. Notes: Reads the sharedaccess.ini phonebook file for application mappings.
  622. --*/
  623. HRESULT GetApplicationMappings(list<CSharedAccessApplication> &lstSharedAccessApplications)
  624. {
  625. WCHAR wszPathBuf[MAX_PATH + 1];
  626. HRESULT hr = GetPhonebookDirectory(wszPathBuf);
  627. if FAILED(hr)
  628. return hr;
  629. tstring strIniFile; // full pathname to sharedaccess.ini
  630. strIniFile = wszPathBuf;
  631. strIniFile += c_wszFileSharedAccess;
  632. const DWORD dwBufSize = 32768; // limit the section buffer size to the same value as Win9x max. buffer size
  633. PWCHAR wszLargeReturnedString = new WCHAR[dwBufSize];
  634. if (NULL == wszLargeReturnedString)
  635. {
  636. return E_OUTOFMEMORY;
  637. }
  638. DWORD dwResult;
  639. dwResult = GetPrivateProfileSection(c_wszContentsApplication, wszLargeReturnedString, dwBufSize-1, strIniFile.c_str());
  640. if (dwResult)
  641. {
  642. PWCHAR wszEnd = wszLargeReturnedString + dwResult;
  643. for (PWCHAR wszApplication = wszLargeReturnedString; (*wszApplication) && (wszApplication < wszEnd); wszApplication += wcslen(wszApplication) + 1)
  644. {
  645. WCHAR wszReturnedString[MAX_PATH];
  646. PWCHAR wszSectionNum = NULL;
  647. PWCHAR wszEnabled;
  648. // prefix bug# 295838
  649. wszSectionNum = new WCHAR[wcslen(wszApplication)+1];
  650. if (NULL == wszSectionNum)
  651. {
  652. delete [] wszLargeReturnedString;
  653. return E_OUTOFMEMORY;
  654. }
  655. wcscpy(wszSectionNum, wszApplication);
  656. PWCHAR wszAssign = wcschr(wszSectionNum, L'=');
  657. if (wszAssign)
  658. {
  659. *wszAssign = NULL;
  660. wszEnabled = wszAssign + 1;
  661. }
  662. else
  663. {
  664. wszEnabled = FALSE;
  665. }
  666. tstring strSectionName;
  667. strSectionName = c_wszApplicationPrefix; // prefix bug# 295839
  668. strSectionName += wszSectionNum; // prefix bug# 295840
  669. CSharedAccessApplication SharedAccessApplication;
  670. SharedAccessApplication.m_dwSectionNum = _wtoi(wszSectionNum);
  671. SharedAccessApplication.m_bSelected = _wtoi(wszEnabled);
  672. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszTitle, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  673. if (dwResult)
  674. {
  675. SharedAccessApplication.m_szTitle = wszReturnedString;
  676. }
  677. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszProtocol, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  678. if (dwResult)
  679. {
  680. SharedAccessApplication.m_szProtocol = wszReturnedString;
  681. }
  682. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszPort, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  683. if (dwResult)
  684. {
  685. SharedAccessApplication.m_wPort = static_cast<USHORT>(_wtoi(wszReturnedString));
  686. }
  687. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszTcpResponseList, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  688. if (dwResult)
  689. {
  690. SharedAccessApplication.m_szTcpResponseList = wszReturnedString;
  691. }
  692. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszUdpResponseList, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  693. if (dwResult)
  694. {
  695. SharedAccessApplication.m_szUdpResponseList = wszReturnedString;
  696. }
  697. dwResult = GetPrivateProfileString(strSectionName.c_str(), c_wszBuiltIn, L"", wszReturnedString, MAX_PATH, strIniFile.c_str());
  698. if (dwResult)
  699. {
  700. SharedAccessApplication.m_bBuiltIn = static_cast<USHORT>(_wtoi(wszReturnedString));
  701. }
  702. lstSharedAccessApplications.insert(lstSharedAccessApplications.end(), SharedAccessApplication);
  703. delete [] wszSectionNum;
  704. wszSectionNum = NULL;
  705. }
  706. }
  707. delete [] wszLargeReturnedString;
  708. return S_OK;
  709. }
  710. /*++
  711. Routine Description:
  712. Add ResponseList string into vector of HNET_RESPONSE_RANGE
  713. Arguments:
  714. [in] rssaAppProt - ref. to the CSharedAccessApplication obj.
  715. [in] ucProtocol - NAT_PROTOCOL_TCP or NAT_PROTOCOL_UDP
  716. [out] rvecResponseRange - add new HNET_RESPONSE_RANGE(s) to this vector
  717. Returns: S_OK if succeeded
  718. Notes: In case of failure, contents of rvecResponseRange will be erased.
  719. Design by contract: ucProtocol could only be NAT_PROTOCOL_TCP or
  720. NAT_PROTOCOL_UDP
  721. --*/
  722. HRESULT AddResponseStringToVector(
  723. CSharedAccessApplication& rsaaAppProt,
  724. UCHAR ucProtocol,
  725. vector<HNET_RESPONSE_RANGE>& rvecResponseRange // vector of response range
  726. )
  727. {
  728. WCHAR* Endp;
  729. USHORT EndPort; // the End port # in the range of response port #
  730. USHORT StartPort; // the starting port # in the range of response port #
  731. const WCHAR* pwszValue = NULL; // the tcp or udp ResponseString to be converted.
  732. // (e.g "1300-1310,1450" or "1245")
  733. HNET_RESPONSE_RANGE hnrrResponseRange; // the response range
  734. HRESULT hr = S_OK;
  735. // select the ResponseList to be added
  736. if (NAT_PROTOCOL_TCP == ucProtocol)
  737. {
  738. pwszValue = rsaaAppProt.m_szTcpResponseList.c_str();
  739. }
  740. else if (NAT_PROTOCOL_UDP == ucProtocol)
  741. {
  742. pwszValue = rsaaAppProt.m_szUdpResponseList.c_str();
  743. }
  744. if (NULL == pwszValue)
  745. {
  746. // no operation
  747. goto Exit;
  748. }
  749. while (*pwszValue)
  750. {
  751. // Read either a single port or a range of ports.
  752. if (!(StartPort = (USHORT)wcstoul(pwszValue, &Endp, 10)))
  753. {
  754. hr = E_FAIL;
  755. goto Exit;
  756. }
  757. else if (!*Endp || *Endp == L',')
  758. {
  759. EndPort = StartPort;
  760. pwszValue = (!*Endp ? Endp : Endp + 1);
  761. }
  762. else if (*Endp != L'-')
  763. {
  764. hr = E_FAIL;
  765. goto Exit;
  766. }
  767. else if (!(EndPort = (USHORT)wcstoul(++Endp, (WCHAR**)&pwszValue, 10)))
  768. {
  769. hr = E_FAIL;
  770. goto Exit;
  771. }
  772. else if (EndPort < StartPort)
  773. {
  774. hr = E_FAIL;
  775. goto Exit;
  776. }
  777. else if (*pwszValue && *pwszValue++ != L',')
  778. {
  779. hr = E_FAIL;
  780. goto Exit;
  781. }
  782. // transfer values
  783. hnrrResponseRange.ucIPProtocol = ucProtocol;
  784. hnrrResponseRange.usStartPort = HTONS(StartPort);
  785. hnrrResponseRange.usEndPort = HTONS(EndPort);
  786. rvecResponseRange.push_back(hnrrResponseRange);
  787. }
  788. Exit:
  789. if (FAILED(hr))
  790. {
  791. rvecResponseRange.erase(rvecResponseRange.begin(), rvecResponseRange.end());
  792. }
  793. return hr;
  794. }
  795. /*++
  796. Routine Description:
  797. Converts ResponseList string into array of HNET_RESPONSE_RANGE
  798. Arguments:
  799. [in] rssaAppProt - ref. to the CSharedAccessApplication obj.
  800. [out] puscResponse - number of HNET_RESPONSE_RANGE converted
  801. [out] pphnrrResponseRange - array of HNET_RESPONSE_RANGE converted
  802. Returns: S_OK if succeeded
  803. Notes: User is responsible to free pphnrrResponseRange by
  804. "delete [] (BYTE*)(*pphnrrResponseRange)" if *puscResponse > 0
  805. --*/
  806. HRESULT PutResponseStringIntoArray(
  807. CSharedAccessApplication& rsaaAppProt, // Application Protocol
  808. USHORT* puscResponse,
  809. HNET_RESPONSE_RANGE** pphnrrResponseRange
  810. )
  811. {
  812. HRESULT hr;
  813. DWORD dwIdx = 0;
  814. Assert(pphnrrResponseRange != NULL);
  815. Assert(puscResponse != NULL);
  816. *pphnrrResponseRange = NULL;
  817. *puscResponse = 0;
  818. vector<HNET_RESPONSE_RANGE> vecResponseRange; // vector of response range
  819. if (! rsaaAppProt.m_szTcpResponseList.empty())
  820. {
  821. //TcpResponseList is not empty
  822. hr = AddResponseStringToVector(rsaaAppProt, NAT_PROTOCOL_TCP, vecResponseRange);
  823. if (FAILED(hr))
  824. {
  825. return hr;
  826. }
  827. }
  828. if (! rsaaAppProt.m_szUdpResponseList.empty())
  829. {
  830. // UdpResponseList is not empty
  831. hr = AddResponseStringToVector(rsaaAppProt, NAT_PROTOCOL_UDP, vecResponseRange);
  832. if (FAILED(hr))
  833. {
  834. return hr;
  835. }
  836. }
  837. HNET_RESPONSE_RANGE* phnrrResponseRange = NULL;
  838. USHORT uscResponseRange = (USHORT) vecResponseRange.size();
  839. if (1 > uscResponseRange)
  840. {
  841. // we should have at least 1 ReponseRange
  842. hr = E_FAIL;
  843. goto Exit;
  844. }
  845. phnrrResponseRange = (HNET_RESPONSE_RANGE*)
  846. new BYTE[sizeof(HNET_RESPONSE_RANGE) * uscResponseRange];
  847. if (phnrrResponseRange == NULL)
  848. {
  849. hr = E_OUTOFMEMORY;
  850. goto Exit;
  851. }
  852. for (vector<HNET_RESPONSE_RANGE>::iterator iter = vecResponseRange.begin();
  853. iter != vecResponseRange.end();
  854. ++iter, ++dwIdx)
  855. {
  856. phnrrResponseRange[dwIdx] = *iter;
  857. }
  858. // transfer values
  859. *pphnrrResponseRange = phnrrResponseRange;
  860. *puscResponse = uscResponseRange;
  861. Exit:
  862. vecResponseRange.erase(vecResponseRange.begin(), vecResponseRange.end());
  863. return hr;
  864. }
  865. /*++
  866. Routine Description:
  867. Check if we need to upgrade ICS from Win2K
  868. Returns: TRUE or FALSE
  869. Notes:
  870. 1. Check if registry value names (SharedConnection and
  871. SharedPrivateLan) exist.
  872. 2. Check if sharedaccess.ini file exists
  873. After upgrade, the registry names should be deleted because
  874. ICS will use settings from WMI repository.
  875. We don't Check if the IPNATHLP service exists, because it is
  876. removed in ADS and DTC SKUs
  877. --*/
  878. BOOL FNeedIcsUpgradeFromWin2K()
  879. {
  880. // 1. Check if registry key values exist
  881. HKEY hKey = NULL;
  882. HRESULT hr = S_OK;
  883. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_wszRegKeySharedAccessParams, KEY_ALL_ACCESS, &hKey);
  884. if (FAILED(hr))
  885. {
  886. return FALSE;
  887. }
  888. Assert(hKey);
  889. DWORD dwType = REG_BINARY;
  890. PBYTE pByte = NULL;
  891. DWORD dwValueSize = 0;
  892. hr = HrRegQueryValueWithAlloc(hKey, c_wszRegValSharedConnection, &dwType, &pByte, &dwValueSize);
  893. if (FAILED(hr))
  894. {
  895. RegSafeCloseKey(hKey);
  896. return FALSE;
  897. }
  898. if (pByte)
  899. {
  900. MemFree(pByte);
  901. }
  902. // Reset values
  903. pByte = NULL;
  904. dwValueSize = 0;
  905. dwType = REG_SZ;
  906. hr = HrRegQueryValueWithAlloc(hKey, c_wszRegValSharedPrivateLan, &dwType, &pByte, &dwValueSize);
  907. if (FAILED(hr))
  908. {
  909. RegSafeCloseKey(hKey);
  910. return FALSE;
  911. }
  912. if (pByte)
  913. {
  914. MemFree(pByte);
  915. }
  916. // 2. Check if sharedaccess.ini file exists
  917. WCHAR wszPathBuf[MAX_PATH + 1];
  918. hr = GetPhonebookDirectory(wszPathBuf);
  919. if FAILED(hr)
  920. return FALSE;
  921. tstring strShareAccessFile;
  922. strShareAccessFile = wszPathBuf;
  923. strShareAccessFile += c_wszFileSharedAccess;
  924. HANDLE hOpenFile =
  925. CreateFileW(strShareAccessFile.c_str(), // open file
  926. GENERIC_READ, // open for reading
  927. FILE_SHARE_READ, // share for reading
  928. NULL, // no security
  929. OPEN_EXISTING, // existing file only
  930. FILE_ATTRIBUTE_NORMAL, // normal file
  931. NULL); // no attr. template
  932. if (INVALID_HANDLE_VALUE == hOpenFile)
  933. {
  934. return FALSE;
  935. }
  936. CloseHandle(hOpenFile);
  937. return TRUE;
  938. }
  939. /*++
  940. Routine Description:
  941. Upgrade ICS Settings
  942. Arguments:
  943. [in] pIcsUpgradeSettings - the ICS UPGRADE SETTINGS
  944. Returns: standard HRESULT
  945. Notes:
  946. --*/
  947. HRESULT UpgradeIcsSettings(ICS_UPGRADE_SETTINGS * pIcsUpgrdSettings)
  948. {
  949. HRESULT hr;
  950. DefineFunctionName("UpgradeIcsSettings");
  951. TraceFunctionEntry(ttidNetSetup);
  952. CIcsUpgrade IcsUpgradeObj;
  953. hr = IcsUpgradeObj.Init(pIcsUpgrdSettings);
  954. if (S_OK != hr)
  955. {
  956. TraceTag(ttidError,
  957. "%s: IcsUpgradeObj.Init failed: 0x%lx",
  958. __FUNCNAME__, hr);
  959. return hr;
  960. }
  961. return IcsUpgradeObj.StartUpgrade();
  962. }
  963. /*++
  964. Routine Description:
  965. Build the ICS_UPGRADE_SETTINGS struct from Win2K ICS settings
  966. Arguments:
  967. [in] pIcsUpgrdSettings - pointer to the ICS_UPGRADE_SETTINGS
  968. Return Value: standard HRESULT
  969. Notes:
  970. --*/
  971. HRESULT BuildIcsUpgradeSettingsFromWin2K(ICS_UPGRADE_SETTINGS* pIcsUpgrdSettings)
  972. {
  973. HRESULT hr;
  974. DefineFunctionName("BuildIcsUpgradeSettingsFromWin2K");
  975. TraceFunctionEntry(ttidNetSetup);
  976. Assert(pIcsUpgrdSettings != NULL);
  977. GUID guid;
  978. hr = GetSharedPrivateLanOnWin2K(&guid);
  979. if (FAILED(hr))
  980. {
  981. TraceTag(ttidError, "%s: GetSharedPrivateLanOnWin2K failed: 0x%lx",
  982. __FUNCNAME__, hr);
  983. return hr;
  984. }
  985. hr = GetSharedConnectionOnWin2k(&(pIcsUpgrdSettings->rscExternal));
  986. if (FAILED(hr))
  987. {
  988. TraceTag(ttidError, "%s: GetSharedConnectionOnWin2k failed: 0x%lx",
  989. __FUNCNAME__, hr);
  990. return hr;
  991. }
  992. hr = GetServerMappings(pIcsUpgrdSettings->listSvrPortmappings);
  993. if (FAILED(hr))
  994. {
  995. TraceTag(ttidError, "%s: Ignore error from GetServerMappings : 0x%lx",
  996. __FUNCNAME__, hr);
  997. }
  998. hr = GetApplicationMappings(pIcsUpgrdSettings->listAppPortmappings);
  999. if (FAILED(hr))
  1000. {
  1001. TraceTag(ttidError, "%s: Ignore error from GetApplicationMappings : 0x%lx",
  1002. __FUNCNAME__, hr);
  1003. }
  1004. // transfer values
  1005. pIcsUpgrdSettings->guidInternal = guid;
  1006. pIcsUpgrdSettings->fInternalAdapterFound = TRUE;
  1007. pIcsUpgrdSettings->fDialOnDemand = TRUE;
  1008. pIcsUpgrdSettings->fEnableICS = TRUE;
  1009. pIcsUpgrdSettings->fShowTrayIcon = TRUE;
  1010. pIcsUpgrdSettings->fWin2KUpgrade = TRUE;
  1011. return S_OK;
  1012. }
  1013. /*++
  1014. Routine Description:
  1015. Free resources inside the ICS_UPGRADE_SETTINGS
  1016. Arguments:
  1017. [in] pIcsUpgrdSettings - pointer to the ICS_UPGRADE_SETTINGS
  1018. Return Value: none
  1019. Note.
  1020. --*/
  1021. void FreeIcsUpgradeSettings(ICS_UPGRADE_SETTINGS* pIcsUpgrdSettings)
  1022. {
  1023. Assert(pIcsUpgrdSettings != NULL);
  1024. list<GUID>& rlistPersonalFirewall = pIcsUpgrdSettings->listPersonalFirewall;
  1025. list<GUID>& rlistBridge = pIcsUpgrdSettings->listBridge;
  1026. list<CSharedAccessServer>& rlistSvrPortmappings = pIcsUpgrdSettings->listSvrPortmappings;
  1027. list<CSharedAccessApplication>& rlistAppPortmappings = pIcsUpgrdSettings->listAppPortmappings;
  1028. rlistPersonalFirewall.erase(rlistPersonalFirewall.begin(), rlistPersonalFirewall.end());
  1029. rlistBridge.erase(rlistBridge.begin(), rlistBridge.end());
  1030. rlistSvrPortmappings.erase(rlistSvrPortmappings.begin(), rlistSvrPortmappings.end());
  1031. rlistAppPortmappings.erase(rlistAppPortmappings.begin(), rlistAppPortmappings.end());
  1032. }
  1033. /*++
  1034. Routine Description:
  1035. convert a list of adapter strings into a list of its corresponding GUID
  1036. Arguments:
  1037. [in] rslAdapters - reference to the list of adapter strings
  1038. [in out] rlistGuid - a list of the converted GUIDs
  1039. Return Value:
  1040. S_OK - if either all of the adapter strings converted to its corresponding
  1041. GUIDs or the input is an empty list of adapter strings.
  1042. S_FALSE - if it can convert at least one of the adaper strings.
  1043. E_FAIL - if none of the adapter strings could be converted to its
  1044. corresponding GUIDs
  1045. --*/
  1046. HRESULT ConvertAdapterStringListToGuidList(IN TStringList& rslAdapters,
  1047. IN OUT list<GUID>& rlistGuid)
  1048. {
  1049. HRESULT hr = S_OK;
  1050. GUID guidTemp = {0};
  1051. tstring* pstrTemp = NULL;
  1052. TStringList::iterator iter;
  1053. if (rslAdapters.empty())
  1054. return hr;
  1055. // init the [in out] parameter first
  1056. rlistGuid.erase(rlistGuid.begin(), rlistGuid.end());
  1057. for (iter = rslAdapters.begin(); iter != rslAdapters.end(); ++iter)
  1058. {
  1059. pstrTemp = *iter;
  1060. Assert(pstrTemp);
  1061. if (!FGetInstanceGuidOfComponentFromAnswerFileMap(pstrTemp->c_str(), &guidTemp))
  1062. {
  1063. TraceTag(ttidError,
  1064. "FGetInstanceGuidOfComponentFromAnswerFileMap failed to match GUID for adapter %S",
  1065. pstrTemp->c_str());
  1066. NetSetupLogStatusV(
  1067. LogSevInformation,
  1068. SzLoadIds (IDS_TXT_E_ADAPTER_TO_GUID),
  1069. pstrTemp->c_str());
  1070. }
  1071. else
  1072. {
  1073. rlistGuid.push_back(guidTemp);
  1074. }
  1075. }
  1076. if (rlistGuid.empty())
  1077. {
  1078. hr = E_FAIL;
  1079. }
  1080. if (rlistGuid.size() < rslAdapters.size())
  1081. {
  1082. hr = S_FALSE;
  1083. }
  1084. return hr;
  1085. }
  1086. /*++
  1087. Routine Description:
  1088. remove duplicates in a TStringList
  1089. Arguments:
  1090. [in, out] sl - the string list contains duplicates to be removed
  1091. Return Value: none
  1092. --*/
  1093. void RemoveDupsInTStringList(IN OUT TStringList& sl)
  1094. {
  1095. for (list<tstring*>::iterator i = sl.begin(); i != sl.end(); ++i)
  1096. {
  1097. list<tstring*>::iterator tmpI = i;
  1098. for (list<tstring*>::iterator j = ++tmpI; j != sl.end(); ++j)
  1099. {
  1100. list<tstring*>::iterator tmpJ = j;
  1101. list<tstring*>::iterator k = --tmpJ;
  1102. if (!_wcsicmp((*i)->c_str(), (*j)->c_str()))
  1103. {
  1104. TraceTag(ttidNetSetup,
  1105. "RemoveDupsInTStringList: found duplicated string %S",
  1106. (*i)->c_str());
  1107. delete *j; // free the resource
  1108. sl.erase(j); // erase the list item
  1109. j = k; // adjust the iterator to the previous one
  1110. }
  1111. }
  1112. }
  1113. }
  1114. /*++
  1115. Routine Description:
  1116. remove items in slDest if the item is also in slSrc
  1117. Arguments:
  1118. [in] slSrc - the source string list contains items to be matched
  1119. [in, out] slDest - the string list where equal items are removed
  1120. Return Value: none
  1121. Note : Both slSrc and slDest MUST not contain duplicated items.
  1122. --*/
  1123. void RemoveEqualItems(IN const TStringList& slSrc, IN OUT TStringList& slDest)
  1124. {
  1125. list<tstring*>::iterator _F = slSrc.begin(), _L = slSrc.end(), pos;
  1126. if (slDest.empty())
  1127. return;
  1128. while (_F != _L)
  1129. {
  1130. if (FIsInStringList(slDest, (*_F)->c_str(), &pos))
  1131. {
  1132. TraceTag(ttidNetSetup,
  1133. "RemoveEqualItems: '%S' appeared in both slSrc and slDest lists, remove it from slDest.",
  1134. (*_F)->c_str());
  1135. // found a matched item.
  1136. delete *pos;
  1137. slDest.erase(pos);
  1138. if (slDest.empty())
  1139. return;
  1140. }
  1141. ++_F;
  1142. }
  1143. }
  1144. /*++
  1145. Routine Description:
  1146. remove item in slDest if the item is the same as pstrSrc
  1147. Arguments:
  1148. [in] strSrc - the source string to be matched
  1149. [in, out] slDest - the string list where equal item is removed
  1150. Return Value: none
  1151. Note : Both slDest MUST not contain duplicated items.
  1152. --*/
  1153. void RemoveEqualItems(IN const tstring& strSrc, IN OUT TStringList& slDest)
  1154. {
  1155. list<tstring*>::iterator pos;
  1156. if (FIsInStringList(slDest, strSrc.c_str(), &pos))
  1157. {
  1158. TraceTag(ttidNetSetup,
  1159. "RemoveEqualItems: remove '%S' from slDest.",
  1160. strSrc.c_str());
  1161. // found a matched item.
  1162. delete *pos;
  1163. slDest.erase(pos);
  1164. if (slDest.empty())
  1165. return;
  1166. }
  1167. }
  1168. /*++
  1169. Routine Description:
  1170. Load Homenet settings from the answer file and put the
  1171. settings into the ICS_UPGRADE_SETTINGS structure
  1172. Arguments:
  1173. [in] pwifAnswerFile the access point of the answer file
  1174. [in/out] pSettings it contains the settings when the
  1175. routine returns S_OK
  1176. Returns: S_OK if there are Homenet settings in the answer file
  1177. S_FALSE: no Homenet settings present in the answer file
  1178. otherwise the failure code
  1179. Notes:
  1180. Bug# 253047, the Answer-File for a Win9x ICS upgrade will
  1181. look like the following (if Clean install WinMe, selecting custom
  1182. installation, and select ICS as an optional component.):
  1183. [Homenet]
  1184. IsW9xUpgrade='1'
  1185. EnableICS="1"
  1186. ShowTrayIcon="1"
  1187. Bug# 304474, in this case, Answer-File for a Win9x ICS upgrade will look
  1188. like (There is no value for ExternalAdapter or
  1189. ExternalConnectionName key.):
  1190. [Homenet]
  1191. IsW9xUpgrade='1'
  1192. InternalAdapter="Adapter2"
  1193. DialOnDemand="0"
  1194. EnableICS="1"
  1195. ShowTrayIcon="1"
  1196. More notes regarding validation of Answer File:
  1197. 1. if adapter found in both the PersonalFirewall list and Bridge list,
  1198. remove that adaper from the PersonalFirewall list.
  1199. 2. if ICS public LAN found in Bridge list, it will be removed from the
  1200. Bridge list.
  1201. 3. if ICS private found in Firewall list, remove that adapter from the
  1202. PersonalFirewall list.
  1203. --*/
  1204. HRESULT LoadIcsSettingsFromAnswerFile(
  1205. CWInfFile* pwifAnswerFile,
  1206. PICS_UPGRADE_SETTINGS pSettings
  1207. )
  1208. {
  1209. HRESULT hr = S_OK;
  1210. BOOL fRet;
  1211. PCWInfSection pwifSection = NULL;
  1212. //BOOL fInternalAdapterFound = FALSE;
  1213. DefineFunctionName("LoadIcsSettingsFromAnswerFile");
  1214. TraceFunctionEntry(ttidNetSetup);
  1215. Assert(pwifAnswerFile);
  1216. Assert(pSettings);
  1217. pwifSection = pwifAnswerFile->FindSection(c_wszHomenetSection);
  1218. if (NULL == pwifSection)
  1219. return S_FALSE;
  1220. tstring strTemp;
  1221. TStringList slICF, slBridge; // hold comma-delimited string into a list
  1222. GUID guidTemp = {0};
  1223. BOOL fTemp = FALSE;
  1224. do
  1225. {
  1226. // ICS Upgrade from Win9x or Unattended Homenet clean install
  1227. // determine if this answer file is for Win9x upgrade or
  1228. // Homenet unattended clean install
  1229. pSettings->fWin9xUpgrade = pwifSection->GetBoolValue(c_wszIsW9xUpgrade, FALSE);
  1230. pSettings->fXpUnattended = !pSettings->fWin9xUpgrade;
  1231. // default value for EnableICS is FALSE
  1232. pSettings->fEnableICS = pwifSection->GetBoolValue(c_wszICSEnabled, FALSE);
  1233. // default value for InternalIsBridge is FALSE
  1234. pSettings->fInternalIsBridge = pwifSection->GetBoolValue(c_wszInternalIsBridge, FALSE);
  1235. TraceTag(ttidNetSetup,
  1236. "IsW9xUpgrade: %S, EnableICS: %S, InternalIsBridge: %S",
  1237. pSettings->fWin9xUpgrade ? L"Yes" : L"No",
  1238. pSettings->fEnableICS ? L"Yes" : L"No",
  1239. pSettings->fInternalIsBridge ? L"Yes" : L"No");
  1240. //
  1241. // get a list of interface GUID for the Internet Connection Firewall
  1242. // (ICF) and a list of interface GUID that forms the bridge. We'll also
  1243. // do validation before converting adapter names to interface GUID
  1244. //
  1245. fRet = pwifSection->GetStringListValue(c_wszPersonalFirewall, slICF);
  1246. if (fRet)
  1247. {
  1248. // remove duplicates within slICF
  1249. RemoveDupsInTStringList(slICF);
  1250. }
  1251. fRet = pwifSection->GetStringListValue(c_wszBridge, slBridge);
  1252. if (fRet)
  1253. {
  1254. // remove duplicates within slBridge
  1255. RemoveDupsInTStringList(slBridge);
  1256. }
  1257. if (!slICF.empty() && !slBridge.empty())
  1258. {
  1259. // remove items in slICF if the item is also in slBridge
  1260. RemoveEqualItems(slBridge, slICF);
  1261. }
  1262. // if ICS is enabled, get the share connection.
  1263. // If the share connection is a LAN connection, make sure it is
  1264. // not a member of the bridge.
  1265. if (pSettings->fEnableICS)
  1266. {
  1267. fRet = pwifSection->GetStringValue(c_wszExternalAdapter, strTemp);
  1268. if (fRet)
  1269. {
  1270. if (!FGetInstanceGuidOfComponentFromAnswerFileMap(strTemp.c_str(), &guidTemp))
  1271. {
  1272. TraceTag(ttidError,
  1273. "FGetInstanceGuidOfComponentFromAnswerFileMap failed to match GUID for adapter %S",
  1274. strTemp.c_str());
  1275. NetSetupLogStatusV(
  1276. LogSevInformation,
  1277. SzLoadIds (IDS_TXT_E_ADAPTER_TO_GUID),
  1278. strTemp.c_str());
  1279. hr = E_FAIL;
  1280. break;
  1281. }
  1282. pSettings->rscExternal.fIsLanConnection = TRUE;
  1283. pSettings->rscExternal.guid = guidTemp;
  1284. // Another validation:
  1285. // ICS public LAN adapter couldn't be a member of a bridge
  1286. if (! slBridge.empty())
  1287. {
  1288. RemoveEqualItems(strTemp, slBridge);
  1289. }
  1290. }
  1291. else
  1292. {
  1293. // Can't find "ExternalAdapter" key in answer-file.
  1294. // We'll try the "ExternalConnectionName" key.
  1295. TraceTag(ttidNetSetup,
  1296. "pwifSection->GetStringValue failed to get %S, we will try to get %S",
  1297. c_wszExternalAdapter, c_wszExternalConnectionName);
  1298. fRet = pwifSection->GetStringValue(c_wszExternalConnectionName, strTemp);
  1299. if (! fRet)
  1300. {
  1301. if (pSettings->fWin9xUpgrade)
  1302. {
  1303. TraceTag(ttidNetSetup,
  1304. "pwifSection->GetStringValue failed to get %S too.",
  1305. c_wszExternalConnectionName);
  1306. TraceTag(ttidNetSetup,
  1307. "We will try to look for a WAN connectoid as the ExternalConnectionName.");
  1308. // Bug# 304474
  1309. // Cook up a fake WAN connectoid name, the code in
  1310. // GetINetConnectionByName will later try to resolve it
  1311. // to a WAN connectoid if there is *only 1* WAN
  1312. // connectoid left on the system. WAN connectoid has
  1313. // media types of either NCM_PHONE, NCM_ISDN or
  1314. // NCM_TUNNEL.
  1315. lstrcpynW(pSettings->rscExternal.name.szEntryName,
  1316. L"X1-2Bogus-3WAN-4Conn-5Name",
  1317. celems(pSettings->rscExternal.name.szEntryName));
  1318. }
  1319. else
  1320. {
  1321. TraceTag(ttidError,
  1322. "pwifSection->GetStringValue failed to get %S too.",
  1323. c_wszExternalConnectionName);
  1324. hr = E_FAIL;
  1325. break;
  1326. }
  1327. }
  1328. else
  1329. {
  1330. lstrcpynW(pSettings->rscExternal.name.szEntryName,
  1331. strTemp.c_str(),
  1332. celems(pSettings->rscExternal.name.szEntryName));
  1333. }
  1334. pSettings->rscExternal.fIsLanConnection = FALSE;
  1335. }
  1336. }
  1337. // convert bridge adapter names to interface GUID
  1338. if (!slBridge.empty())
  1339. {
  1340. hr = ConvertAdapterStringListToGuidList(slBridge, pSettings->listBridge);
  1341. if (FAILED(hr))
  1342. {
  1343. TraceTag(
  1344. ttidError,
  1345. "Error in converting Personal Firewall string list to GUID list");
  1346. break;
  1347. }
  1348. if (S_FALSE == hr)
  1349. {
  1350. hr = S_OK; // convert any S_FALSE to S_OK
  1351. }
  1352. }
  1353. // we will convert the slICF list later because we need to check if
  1354. // ICS private adapter is also in slICF, if yes, we need to remove it
  1355. // from the slICF list.
  1356. //
  1357. // get the internal adapter GUID
  1358. //
  1359. fRet = pwifSection->GetStringValue(c_wszInternalAdapter, strTemp);
  1360. if (fRet && !pSettings->fInternalIsBridge && !pSettings->fEnableICS)
  1361. {
  1362. // invalid parameters from answer file (AF)
  1363. TraceTag(ttidError,
  1364. "Invalid AF settings: InternalAdapter=%S, InternalIsBridge='0', EnableICS='0'.",
  1365. strTemp.c_str());
  1366. NetSetupLogStatusV(
  1367. LogSevInformation,
  1368. SzLoadIds (IDS_TXT_HOMENET_INVALID_AF_SETTINGS));
  1369. hr = E_FAIL;
  1370. break;
  1371. }
  1372. if (fRet && pSettings->fInternalIsBridge)
  1373. {
  1374. TraceTag(ttidError,
  1375. "Invalid AF settings: InternalAdapter=%S, InternalIsBridge='1'.",
  1376. strTemp.c_str());
  1377. NetSetupLogStatusV(
  1378. LogSevInformation,
  1379. SzLoadIds (IDS_TXT_HOMENET_INVALID_AF_SETTINGS));
  1380. hr = E_FAIL;
  1381. break;
  1382. }
  1383. if (fRet)
  1384. {
  1385. // get the internal adapter GUID if InternalIsBridge is '0'
  1386. Assert(!pSettings->fInternalIsBridge);
  1387. if (!FGetInstanceGuidOfComponentFromAnswerFileMap(strTemp.c_str(), &guidTemp))
  1388. {
  1389. TraceTag(ttidError,
  1390. "FGetInstanceGuidOfComponentFromAnswerFileMap failed to match GUID for adapter %S",
  1391. strTemp.c_str());
  1392. NetSetupLogStatusV(
  1393. LogSevInformation,
  1394. SzLoadIds (IDS_TXT_E_ADAPTER_TO_GUID),
  1395. strTemp.c_str());
  1396. hr = E_FAIL;
  1397. break;
  1398. }
  1399. else
  1400. {
  1401. pSettings->fInternalAdapterFound = TRUE;
  1402. pSettings->guidInternal = guidTemp;
  1403. // another validation:
  1404. // remove ICS private from the firewall list (slICF)
  1405. // if necessary.
  1406. if (!slICF.empty())
  1407. {
  1408. RemoveEqualItems(strTemp, slICF);
  1409. }
  1410. }
  1411. }
  1412. // check for other answer file errors
  1413. if (pSettings->fWin9xUpgrade && !pSettings->fEnableICS)
  1414. {
  1415. TraceTag(
  1416. ttidError,
  1417. "Invalid AF settings: IsW9xUpgrade='1', EnableICS='0'");
  1418. hr = E_FAIL;
  1419. break;
  1420. }
  1421. // special case for Win9x ICS upgrade.
  1422. if ( pSettings->fWin9xUpgrade)
  1423. {
  1424. // Bug# 315265
  1425. if ( pSettings->fInternalIsBridge &&
  1426. 1 == (pSettings->listBridge).size() )
  1427. {
  1428. // for Win9x ICS upgrade, one of the 2 internal adapters is
  1429. // broken, we will continue to do the upgrade without creating
  1430. // the internal bridge.
  1431. // adjust answer file parameters
  1432. pSettings->fWin9xUpgradeAtLeastOneInternalAdapterBroken = TRUE;
  1433. pSettings->fInternalAdapterFound = TRUE;
  1434. pSettings->guidInternal = *((pSettings->listBridge).begin());
  1435. // note: On Win9x ICS upgrade, there will be no firewall list,
  1436. // so, we don't try to remove this ICS private from the
  1437. // firewall list (slICF).
  1438. pSettings->fInternalIsBridge = FALSE;
  1439. pSettings->listBridge.erase(pSettings->listBridge.begin(),
  1440. pSettings->listBridge.end());
  1441. TraceTag(
  1442. ttidNetSetup,
  1443. "On Win9x ICS upgrade, one internal adapter couldn't be upgraded.");
  1444. }
  1445. }
  1446. if ( (pSettings->fInternalIsBridge && (pSettings->listBridge).size() < 2) ||
  1447. (1 == (pSettings->listBridge).size()) )
  1448. {
  1449. TraceTag(
  1450. ttidError,
  1451. "Invalid setting: fInternalIsBridge: %S, size of listBridge: %d",
  1452. pSettings->fInternalIsBridge ? L"TRUE" : L"FALSE",
  1453. (pSettings->listBridge).size());
  1454. NetSetupLogStatusV(
  1455. LogSevInformation,
  1456. SzLoadIds (IDS_TXT_HOMENET_INVALID_AF_SETTINGS));
  1457. hr = E_FAIL;
  1458. break;
  1459. }
  1460. if ( pSettings->fEnableICS &&
  1461. !pSettings->fInternalIsBridge &&
  1462. !pSettings->fInternalAdapterFound)
  1463. {
  1464. // Bug# 304474 falls under this case
  1465. TraceTag(
  1466. ttidError,
  1467. "Invalid AF settings: no InternalAdapter, InternalIsBridge='0', EnableICS='1'.");
  1468. NetSetupLogStatusV(
  1469. LogSevInformation,
  1470. SzLoadIds (IDS_TXT_HOMENET_INVALID_AF_SETTINGS));
  1471. hr = E_FAIL;
  1472. break;
  1473. }
  1474. // convert firewall adapter names to interface GUID
  1475. if (!slICF.empty())
  1476. {
  1477. hr = ConvertAdapterStringListToGuidList(slICF, pSettings->listPersonalFirewall);
  1478. if (FAILED(hr))
  1479. {
  1480. TraceTag(
  1481. ttidError,
  1482. "Error in converting Personal Firewall string list to GUID list");
  1483. break;
  1484. }
  1485. if (S_FALSE == hr)
  1486. {
  1487. hr = S_OK; // convert any S_FALSE to S_OK
  1488. }
  1489. }
  1490. // default value for DialOnDemand is FALSE
  1491. pSettings->fDialOnDemand = pwifSection->GetBoolValue(c_wszDialOnDemand, FALSE);
  1492. // default value for ShowTrayIcon is TRUE
  1493. pSettings->fShowTrayIcon = pwifSection->GetBoolValue(c_wszShowTrayIcon, TRUE);
  1494. } while(FALSE);
  1495. // free resource if necessary
  1496. EraseAndDeleteAll(&slICF);
  1497. EraseAndDeleteAll(&slBridge);
  1498. return hr;
  1499. }
  1500. /*++
  1501. Routine Description:
  1502. Set some default values into ICS_UPGRADE_SETTINGS
  1503. Arguments:
  1504. [in] pIcsUpgrdSettings - pointer to the ICS_UPGRADE_SETTINGS
  1505. Return Value: none
  1506. Note.
  1507. --*/
  1508. void SetIcsDefaultSettings(ICS_UPGRADE_SETTINGS * pSettings)
  1509. {
  1510. //initialize the settings here
  1511. pSettings->fDialOnDemand = FALSE;
  1512. pSettings->fEnableICS = FALSE;
  1513. pSettings->fShowTrayIcon = TRUE;
  1514. pSettings->fWin9xUpgrade = FALSE;
  1515. pSettings->fWin9xUpgradeAtLeastOneInternalAdapterBroken = FALSE;
  1516. pSettings->fWin2KUpgrade = FALSE;
  1517. pSettings->fXpUnattended = FALSE;
  1518. pSettings->fInternalIsBridge = FALSE;
  1519. pSettings->fInternalAdapterFound = FALSE;
  1520. }
  1521. BOOL FOsIsUnsupported()
  1522. /*++
  1523. Routine Description:
  1524. Check current OS version.
  1525. billi: I am modifying the version check to synchronize it with the home
  1526. networking version check. We want to prevent upgrages on specific
  1527. sku's and server suites higher than Advanced Server.
  1528. Arguments:
  1529. None
  1530. Return Value: returns TRUE if current OS version is Adv. Server or higher
  1531. Note.
  1532. --*/
  1533. {
  1534. OSVERSIONINFOEXW verInfo = {0};
  1535. ULONGLONG ConditionMask = 0;
  1536. verInfo.dwOSVersionInfoSize = sizeof(verInfo);
  1537. verInfo.wSuiteMask = VER_SUITE_DATACENTER |
  1538. // VER_SUITE_BACKOFFICE |
  1539. VER_SUITE_SMALLBUSINESS_RESTRICTED |
  1540. VER_SUITE_SMALLBUSINESS |
  1541. VER_SUITE_BLADE;
  1542. VER_SET_CONDITION(ConditionMask, VER_SUITENAME, VER_OR);
  1543. return VerifyVersionInfo(&verInfo, VER_SUITENAME, ConditionMask);
  1544. }
  1545. //--------- ICS Upgrade helpers end -----------------------------
  1546. //--------- HNet helpers begin ----------------------------------
  1547. // extract from %sdxroot%\net\rras\ras\ui\common\nouiutil\noui.c
  1548. DWORD
  1549. IpPszToHostAddr(
  1550. IN LPCTSTR cp )
  1551. // Converts an IP address represented as a string to
  1552. // host byte order.
  1553. //
  1554. {
  1555. DWORD val, base, n;
  1556. TCHAR c;
  1557. DWORD parts[4], *pp = parts;
  1558. again:
  1559. // Collect number up to ``.''.
  1560. // Values are specified as for C:
  1561. // 0x=hex, 0=octal, other=decimal.
  1562. //
  1563. val = 0; base = 10;
  1564. if (*cp == TEXT('0'))
  1565. base = 8, cp++;
  1566. if (*cp == TEXT('x') || *cp == TEXT('X'))
  1567. base = 16, cp++;
  1568. while (c = *cp)
  1569. {
  1570. if ((c >= TEXT('0')) && (c <= TEXT('9')))
  1571. {
  1572. val = (val * base) + (c - TEXT('0'));
  1573. cp++;
  1574. continue;
  1575. }
  1576. if ((base == 16) &&
  1577. ( ((c >= TEXT('0')) && (c <= TEXT('9'))) ||
  1578. ((c >= TEXT('A')) && (c <= TEXT('F'))) ||
  1579. ((c >= TEXT('a')) && (c <= TEXT('f'))) ))
  1580. {
  1581. val = (val << 4) + (c + 10 - (
  1582. ((c >= TEXT('a')) && (c <= TEXT('f')))
  1583. ? TEXT('a')
  1584. : TEXT('A') ) );
  1585. cp++;
  1586. continue;
  1587. }
  1588. break;
  1589. }
  1590. if (*cp == TEXT('.'))
  1591. {
  1592. // Internet format:
  1593. // a.b.c.d
  1594. // a.b.c (with c treated as 16-bits)
  1595. // a.b (with b treated as 24 bits)
  1596. //
  1597. if (pp >= parts + 3)
  1598. return (DWORD) -1;
  1599. *pp++ = val, cp++;
  1600. goto again;
  1601. }
  1602. // Check for trailing characters.
  1603. //
  1604. if (*cp && (*cp != TEXT(' ')))
  1605. return 0xffffffff;
  1606. *pp++ = val;
  1607. // Concoct the address according to
  1608. // the number of parts specified.
  1609. //
  1610. n = (DWORD) (pp - parts);
  1611. switch (n)
  1612. {
  1613. case 1: // a -- 32 bits
  1614. val = parts[0];
  1615. break;
  1616. case 2: // a.b -- 8.24 bits
  1617. val = (parts[0] << 24) | (parts[1] & 0xffffff);
  1618. break;
  1619. case 3: // a.b.c -- 8.8.16 bits
  1620. val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
  1621. (parts[2] & 0xffff);
  1622. break;
  1623. case 4: // a.b.c.d -- 8.8.8.8 bits
  1624. val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
  1625. ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
  1626. break;
  1627. default:
  1628. return 0xffffffff;
  1629. }
  1630. return val;
  1631. }
  1632. /*++
  1633. Routine Description:
  1634. Sets the standard COM security settings on the proxy for an
  1635. object.
  1636. Arguments:
  1637. pUnk - the object to set the proxy blanket on
  1638. Return Value:
  1639. Note. Even if the CoSetProxyBlanket calls fail, pUnk remains
  1640. in a usable state. Failure is expected in certain contexts, such
  1641. as when, for example, we're being called w/in the netman process --
  1642. in this case, we have direct pointers to the netman objects, instead
  1643. of going through a proxy.
  1644. --*/
  1645. VOID SetProxyBlanket(IUnknown *pUnk)
  1646. {
  1647. HRESULT hr;
  1648. Assert(pUnk);
  1649. hr = CoSetProxyBlanket(
  1650. pUnk,
  1651. RPC_C_AUTHN_WINNT, // use NT default security
  1652. RPC_C_AUTHZ_NONE, // use NT default authentication
  1653. NULL, // must be null if default
  1654. RPC_C_AUTHN_LEVEL_CALL, // call
  1655. RPC_C_IMP_LEVEL_IMPERSONATE,
  1656. NULL, // use process token
  1657. EOAC_NONE
  1658. );
  1659. if (SUCCEEDED(hr))
  1660. {
  1661. IUnknown * pUnkSet = NULL;
  1662. hr = pUnk->QueryInterface(&pUnkSet);
  1663. if (SUCCEEDED(hr))
  1664. {
  1665. hr = CoSetProxyBlanket(
  1666. pUnkSet,
  1667. RPC_C_AUTHN_WINNT, // use NT default security
  1668. RPC_C_AUTHZ_NONE, // use NT default authentication
  1669. NULL, // must be null if default
  1670. RPC_C_AUTHN_LEVEL_CALL, // call
  1671. RPC_C_IMP_LEVEL_IMPERSONATE,
  1672. NULL, // use process token
  1673. EOAC_NONE
  1674. );
  1675. pUnkSet->Release();
  1676. }
  1677. }
  1678. }
  1679. /////////////////////////////////////////////////////////////////////////////
  1680. // CIcsUpgrade public methods
  1681. /////////////////////////////////////////////////////////////////////////////
  1682. /*++
  1683. Routine Description:
  1684. Init ourself with the pIcsUpgradeSettings, we also cache the
  1685. IEnumNetConnection object in our m_spEnum.
  1686. Arguments:
  1687. [in] pIcsUpgradeSettings - the ICS UPGRADE SETTINGS
  1688. Return Value:
  1689. standard HRESULT
  1690. --*/
  1691. HRESULT CIcsUpgrade::Init(ICS_UPGRADE_SETTINGS * pIcsUpgradeSettings)
  1692. {
  1693. HRESULT hr;
  1694. if (!pIcsUpgradeSettings)
  1695. {
  1696. return E_INVALIDARG;
  1697. }
  1698. if (pIcsUpgradeSettings->fWin9xUpgrade)
  1699. {
  1700. // validate parameters for Win9x ICS upgrade
  1701. if (!pIcsUpgradeSettings->fEnableICS)
  1702. {
  1703. return E_INVALIDARG;
  1704. }
  1705. if (pIcsUpgradeSettings->fInternalIsBridge)
  1706. {
  1707. // internal is a bridge
  1708. if ( (pIcsUpgradeSettings->listBridge).size() < 2 )
  1709. {
  1710. return E_INVALIDARG;
  1711. }
  1712. }
  1713. else
  1714. {
  1715. if (!pIcsUpgradeSettings->fInternalAdapterFound)
  1716. {
  1717. return E_INVALIDARG;
  1718. }
  1719. }
  1720. }
  1721. else if (pIcsUpgradeSettings->fWin2KUpgrade)
  1722. {
  1723. // validate parameters for Win2K ICS upgrade
  1724. if (pIcsUpgradeSettings->fInternalIsBridge ||
  1725. !pIcsUpgradeSettings->fEnableICS ||
  1726. !pIcsUpgradeSettings->fInternalAdapterFound)
  1727. {
  1728. return E_INVALIDARG;
  1729. }
  1730. }
  1731. if (!m_fInited)
  1732. {
  1733. // Get the net connection manager
  1734. INetConnectionManager *pConnMan;
  1735. hr = CoCreateInstance(CLSID_ConnectionManager, NULL,
  1736. CLSCTX_ALL,
  1737. IID_INetConnectionManager,
  1738. (LPVOID *)&pConnMan);
  1739. if (S_OK == hr)
  1740. {
  1741. // Get the enumeration of connections
  1742. SetProxyBlanket(pConnMan);
  1743. hr = pConnMan->EnumConnections(NCME_DEFAULT, &m_spEnum);
  1744. pConnMan->Release();
  1745. }
  1746. else
  1747. {
  1748. return E_FAIL;
  1749. }
  1750. if (S_OK == hr)
  1751. {
  1752. SetProxyBlanket(m_spEnum);
  1753. m_fInited = TRUE;
  1754. }
  1755. else
  1756. {
  1757. return E_FAIL;
  1758. }
  1759. }
  1760. m_pIcsUpgradeSettings = pIcsUpgradeSettings;
  1761. return S_OK;
  1762. }
  1763. /*++
  1764. Routine Description:
  1765. Enable ICS on external adapter and internal adapters.
  1766. Enable personal firewall on the external adapter.
  1767. Migrating the server and application port mappings.
  1768. Arguments:
  1769. None
  1770. Return Value:
  1771. standard HRESULT
  1772. --*/
  1773. HRESULT CIcsUpgrade::StartUpgrade()
  1774. {
  1775. HRESULT hr;
  1776. DefineFunctionName("CIcsUpgrade::StartUpGrade");
  1777. TraceFunctionEntry(ttidNetSetup);
  1778. if (m_fInited)
  1779. {
  1780. if (m_pIcsUpgradeSettings->fWin2KUpgrade)
  1781. {
  1782. // we need to delete Win2K registry named value
  1783. hr = BackupAndDelIcsRegistryValuesOnWin2k();
  1784. if (FAILED(hr))
  1785. {
  1786. TraceTag(ttidError,
  1787. "%s: Ignore BackupAndDelIcsRegistryValuesOnWin2k failed: 0x%lx",
  1788. __FUNCNAME__, hr);
  1789. }
  1790. hr = SetupApplicationProtocol();
  1791. if (FAILED(hr))
  1792. {
  1793. TraceTag(ttidError, "%s: SetupApplicationProtocol failed: 0x%lx",
  1794. __FUNCNAME__, hr);
  1795. return hr;
  1796. }
  1797. hr = SetupServerPortMapping();
  1798. if (FAILED(hr))
  1799. {
  1800. TraceTag(ttidError, "%s: SetupServerPortMapping failed: 0x%lx",
  1801. __FUNCNAME__, hr);
  1802. return hr;
  1803. }
  1804. }
  1805. hr = SetupHomenetConnections();
  1806. if (FAILED(hr))
  1807. {
  1808. TraceTag(ttidError, "%s: SetupHomenetConnections failed: 0x%lx",
  1809. __FUNCNAME__, hr);
  1810. return hr;
  1811. }
  1812. hr = SetupIcsMiscItems();
  1813. if (FAILED(hr))
  1814. {
  1815. TraceTag(ttidError,
  1816. "%s: Ignore SetupIcsMiscItems failed: 0x%lx",
  1817. __FUNCNAME__, hr);
  1818. }
  1819. }
  1820. return S_OK;
  1821. }
  1822. /////////////////////////////////////////////////////////////////////////////
  1823. // CIcsUpgrade private methods
  1824. /////////////////////////////////////////////////////////////////////////////
  1825. /*++
  1826. Routine Description:
  1827. Free all cached resources,
  1828. CComPtr smart pointer will be released when this object is out of scope or
  1829. being deleted.
  1830. Arguments:
  1831. None
  1832. Return Value:
  1833. None
  1834. --*/
  1835. void CIcsUpgrade::FinalRelease()
  1836. {
  1837. if (m_pExternalNetConn)
  1838. {
  1839. m_pExternalNetConn->Release();
  1840. m_pExternalNetConn = NULL;
  1841. }
  1842. if (m_hIcsUpgradeEvent)
  1843. {
  1844. CloseHandle(m_hIcsUpgradeEvent);
  1845. m_hIcsUpgradeEvent = NULL;
  1846. }
  1847. }
  1848. /*++
  1849. Routine Description:
  1850. Setup Homenet connections based on parameters from m_pIcsUpgradeSettings.
  1851. Arguments:
  1852. None
  1853. Return Value:
  1854. standard HRESULT
  1855. --*/
  1856. HRESULT CIcsUpgrade::SetupHomenetConnections()
  1857. {
  1858. DefineFunctionName("CIcsUpgrade::SetupHomenetConnections");
  1859. TraceFunctionEntry(ttidNetSetup);
  1860. HRESULT hr = S_OK;
  1861. INetConnection** prgINetConn = NULL; // array of INetConnection*
  1862. DWORD cINetConn = 0; // number of INetConnection* in the array
  1863. INetConnection* pExternalNetConn = NULL;
  1864. INetConnection* pInternalNetConn = NULL;
  1865. // Create a named event to notify other components that we're
  1866. // in GUI Mode ICS Upgrade. Reason: sharedaccess service
  1867. // fails to start during the GUI Mode Setup.
  1868. hr = CreateIcsUpgradeNamedEvent();
  1869. if (FAILED(hr))
  1870. {
  1871. TraceTag(ttidError,
  1872. "%s: CreateIcsUpgradeNamedEvent failed: 0x%lx",
  1873. __FUNCNAME__, hr);
  1874. return hr;
  1875. }
  1876. // create a bridge if we have more than 1 adapter guid
  1877. if ( (m_pIcsUpgradeSettings->listBridge).size() > 1 )
  1878. {
  1879. do
  1880. {
  1881. hr = GetINetConnectionArray(m_pIcsUpgradeSettings->listBridge,
  1882. &prgINetConn, &cINetConn);
  1883. TraceTag(ttidNetSetup,
  1884. "after GetINetConnectionArray for bridge.");
  1885. if (FAILED(hr))
  1886. {
  1887. TraceTag(ttidError, "%s: GetINetConnectionArray failed: 0x%lx line: %d",
  1888. __FUNCNAME__, hr, __LINE__);
  1889. NetSetupLogStatusV(
  1890. LogSevInformation,
  1891. SzLoadIds (IDS_TXT_CANT_CREATE_BRIDGE));
  1892. break;
  1893. }
  1894. TraceTag(ttidNetSetup, "calling HNetCreateBridge.");
  1895. hr = HNetCreateBridge(prgINetConn, NULL);
  1896. if (FAILED(hr))
  1897. {
  1898. TraceTag(ttidError, "%s: HNetCreateBridge failed: 0x%lx",
  1899. __FUNCNAME__, hr);
  1900. NetSetupLogStatusV(
  1901. LogSevInformation,
  1902. SzLoadIds (IDS_TXT_CANT_CREATE_BRIDGE));
  1903. break;
  1904. }
  1905. } while (FALSE);
  1906. // free resource if necessary
  1907. for (DWORD i = 0; i < cINetConn ; ++i)
  1908. {
  1909. if (prgINetConn[i])
  1910. prgINetConn[i]->Release();
  1911. }
  1912. if (prgINetConn)
  1913. {
  1914. delete [] (BYTE*)prgINetConn;
  1915. }
  1916. prgINetConn = NULL;
  1917. cINetConn = 0;
  1918. }
  1919. // create ICS
  1920. if (m_pIcsUpgradeSettings->fEnableICS)
  1921. {
  1922. do
  1923. {
  1924. if (m_pExternalNetConn == NULL)
  1925. { // no cached copy
  1926. hr = GetExternalINetConnection(&pExternalNetConn);
  1927. if (FAILED(hr))
  1928. {
  1929. TraceTag(ttidError, "%s: GetExternalINetConnection failed: 0x%lx",
  1930. __FUNCNAME__, hr);
  1931. NetSetupLogStatusV(
  1932. LogSevInformation,
  1933. SzLoadIds (IDS_TXT_CANT_CREATE_ICS));
  1934. break;
  1935. }
  1936. }
  1937. else
  1938. {
  1939. pExternalNetConn = m_pExternalNetConn; // use the cached copy
  1940. }
  1941. if (m_pIcsUpgradeSettings->fInternalIsBridge)
  1942. {
  1943. hr = GetBridgeINetConn(&pInternalNetConn);
  1944. if (FAILED(hr))
  1945. {
  1946. TraceTag(ttidError, "%s: GetBridgeINetConn failed: 0x%lx",
  1947. __FUNCNAME__, hr);
  1948. NetSetupLogStatusV(
  1949. LogSevInformation,
  1950. SzLoadIds (IDS_TXT_CANT_CREATE_ICS));
  1951. break;
  1952. }
  1953. }
  1954. else
  1955. {
  1956. hr = GetINetConnectionByGuid(
  1957. &m_pIcsUpgradeSettings->guidInternal,
  1958. &pInternalNetConn);
  1959. if (FAILED(hr))
  1960. {
  1961. TraceTag(ttidError, "%s: GetINetConnectionByGuid failed: 0x%lx line: %d",
  1962. __FUNCNAME__, hr, __LINE__);
  1963. NetSetupLogStatusV(
  1964. LogSevInformation,
  1965. SzLoadIds (IDS_TXT_CANT_CREATE_ICS));
  1966. break;
  1967. }
  1968. }
  1969. TraceTag(ttidNetSetup, "calling HrCreateICS.");
  1970. hr = HrCreateICS(pExternalNetConn, pInternalNetConn);
  1971. if (FAILED(hr))
  1972. {
  1973. TraceTag(ttidError, "%s: HNetCreateBridge failed: 0x%lx",
  1974. __FUNCNAME__, hr);
  1975. NetSetupLogStatusV(
  1976. LogSevInformation,
  1977. SzLoadIds (IDS_TXT_CANT_CREATE_ICS));
  1978. break;
  1979. }
  1980. m_fICSCreated = TRUE;
  1981. } while (FALSE);
  1982. // cleanup if necessary
  1983. if (pInternalNetConn)
  1984. {
  1985. pInternalNetConn->Release();
  1986. }
  1987. if (FAILED(hr))
  1988. {
  1989. if (pExternalNetConn && !m_pExternalNetConn)
  1990. {
  1991. pExternalNetConn->Release();
  1992. }
  1993. }
  1994. else
  1995. {
  1996. // cache External INetConnections if necessary
  1997. if (!m_pExternalNetConn)
  1998. {
  1999. m_pExternalNetConn = pExternalNetConn;
  2000. }
  2001. }
  2002. }
  2003. // enable firewall on each connection specified from answer file
  2004. // note: ICS private couldn't be firewalled, bridge couldn't be firewalled.
  2005. if ( (m_pIcsUpgradeSettings->listPersonalFirewall).size() > 0 )
  2006. {
  2007. do
  2008. {
  2009. hr = GetINetConnectionArray(
  2010. m_pIcsUpgradeSettings->listPersonalFirewall,
  2011. &prgINetConn, &cINetConn);
  2012. if (FAILED(hr))
  2013. {
  2014. TraceTag(ttidError, "%s: GetINetConnectionArray failed: 0x%lx line: %d",
  2015. __FUNCNAME__, hr, __LINE__);
  2016. NetSetupLogStatusV(
  2017. LogSevInformation,
  2018. SzLoadIds (IDS_TXT_CANT_FIREWALL));
  2019. break;
  2020. }
  2021. TraceTag(ttidNetSetup, "calling HrEnablePersonalFirewall.");
  2022. hr = HrEnablePersonalFirewall(prgINetConn);
  2023. if (FAILED(hr))
  2024. {
  2025. TraceTag(ttidError, "%s: HrEnablePersonalFirewall failed: 0x%lx",
  2026. __FUNCNAME__, hr);
  2027. NetSetupLogStatusV(
  2028. LogSevInformation,
  2029. SzLoadIds (IDS_TXT_CANT_FIREWALL));
  2030. break;
  2031. }
  2032. } while(FALSE);
  2033. // free resource if necessary
  2034. for (DWORD i = 0; i < cINetConn ; ++i)
  2035. {
  2036. if (prgINetConn[i])
  2037. prgINetConn[i]->Release();
  2038. }
  2039. if (prgINetConn)
  2040. {
  2041. delete [] (BYTE*)prgINetConn;
  2042. }
  2043. prgINetConn = NULL;
  2044. cINetConn = 0;
  2045. }
  2046. return hr;
  2047. }
  2048. /*++
  2049. Routine Description:
  2050. Get an array of INetConnection interface pointers
  2051. corresponds to a list of GUID in rlistGuid.
  2052. Arguments:
  2053. [in] rlistGuid - a list of interface Guid.
  2054. [in, out] pprgInternalNetConn - an array of INetConnection*
  2055. [in, out] pcInternalNetConn - number of INetConnection* in the array
  2056. Return Value:
  2057. standard HRESULT
  2058. Note :
  2059. -User needs to release the returned INetConnection interface pointers in
  2060. the array.
  2061. -User needs to free the memory allocated for the array by using
  2062. "delete [] (BYTE*)prgInternalNetConn".
  2063. -The array is NULL terminated (similar to "char** argv" argument in
  2064. main())
  2065. --*/
  2066. HRESULT CIcsUpgrade::GetINetConnectionArray(
  2067. IN list<GUID>& rlistGuid,
  2068. IN OUT INetConnection*** pprgINetConn,
  2069. IN OUT DWORD* pcINetConn)
  2070. {
  2071. DefineFunctionName("CIcsUpgrade::GetINetConnectionArray");
  2072. TraceFunctionEntry(ttidNetSetup);
  2073. HRESULT hr;
  2074. Assert(pprgINetConn);
  2075. Assert(pcINetConn);
  2076. *pprgINetConn = NULL;
  2077. *pcINetConn = 0;
  2078. DWORD cConnections = rlistGuid.size();
  2079. if (cConnections < 1)
  2080. {
  2081. return E_FAIL;
  2082. }
  2083. // Note that we allocated an extra entry since this is a null-terminated
  2084. // array
  2085. DWORD dwSize = (cConnections + 1) * sizeof(INetConnection*);
  2086. INetConnection** prgINetConn = (INetConnection**) new BYTE[dwSize];
  2087. if (prgINetConn)
  2088. {
  2089. ZeroMemory((PVOID) prgINetConn, dwSize);
  2090. DWORD i = 0;
  2091. for (list<GUID>::iterator iter = rlistGuid.begin();
  2092. iter != rlistGuid.end(); ++iter, ++i)
  2093. {
  2094. hr = GetINetConnectionByGuid( &(*iter), &prgINetConn[i]);
  2095. if (FAILED(hr))
  2096. {
  2097. for (DWORD j = 0; j < i; ++j)
  2098. {
  2099. if (prgINetConn[j])
  2100. {
  2101. prgINetConn[j]->Release();
  2102. }
  2103. }
  2104. delete [] (BYTE*)prgINetConn;
  2105. return hr;
  2106. }
  2107. }
  2108. }
  2109. else
  2110. {
  2111. hr = E_OUTOFMEMORY;
  2112. }
  2113. if (SUCCEEDED(hr))
  2114. {
  2115. *pcINetConn = cConnections;
  2116. *pprgINetConn = prgINetConn;
  2117. }
  2118. return hr;
  2119. }
  2120. /*++
  2121. Routine Description:
  2122. Retrieves the INetConnection that corresponds to the LPRASSHARECONN
  2123. in m_pIcsUpgradeSettings->pExternal.
  2124. Arguments:
  2125. [out] ppNetConn - receives the interface
  2126. Return Value:
  2127. standard HRESULT
  2128. --*/
  2129. HRESULT CIcsUpgrade::GetExternalINetConnection(INetConnection** ppNetConn)
  2130. {
  2131. LPRASSHARECONN pRasShareConn = &(m_pIcsUpgradeSettings->rscExternal);
  2132. if (pRasShareConn->fIsLanConnection)
  2133. {
  2134. return GetINetConnectionByGuid(&(pRasShareConn->guid), ppNetConn);
  2135. }
  2136. else
  2137. {
  2138. return GetINetConnectionByName((pRasShareConn->name).szEntryName,
  2139. ppNetConn);
  2140. }
  2141. }
  2142. /*++
  2143. Routine Description:
  2144. Retrieves the INetConnection that corresponds to the given GUID.
  2145. We will enumerate the INetConnection using our cached m_spEnum.
  2146. Arguments:
  2147. [in] pGuid - the guid of the connection
  2148. [out] ppNetCon - receives the interface
  2149. Return Value:
  2150. standard HRESULT
  2151. --*/
  2152. HRESULT
  2153. CIcsUpgrade::GetINetConnectionByGuid(
  2154. GUID* pGuid,
  2155. INetConnection** ppNetCon)
  2156. {
  2157. HRESULT hr;
  2158. INetConnection* pConn;
  2159. Assert(NULL != pGuid);
  2160. Assert(NULL != ppNetCon);
  2161. *ppNetCon = NULL;
  2162. // Search for the connection with the correct guid
  2163. ULONG ulCount;
  2164. BOOLEAN fFound = FALSE;
  2165. #if DBG
  2166. WCHAR szGuid[c_cchGuidWithTerm];
  2167. if (SUCCEEDED(StringFromGUID2(*pGuid, szGuid, c_cchGuidWithTerm)))
  2168. {
  2169. TraceTag(ttidNetSetup, "GetINetConnectionByGuid: pGuid is: %S", szGuid);
  2170. }
  2171. #endif
  2172. // reset our cache m_spEnum
  2173. m_spEnum->Reset();
  2174. do
  2175. {
  2176. NETCON_PROPERTIES* pProps;
  2177. hr = m_spEnum->Next(1, &pConn, &ulCount);
  2178. if (SUCCEEDED(hr) && 1 == ulCount)
  2179. {
  2180. SetProxyBlanket(pConn);
  2181. hr = pConn->GetProperties(&pProps);
  2182. if (S_OK == hr)
  2183. {
  2184. if (IsEqualGUID(pProps->guidId, *pGuid))
  2185. {
  2186. fFound = TRUE;
  2187. *ppNetCon = pConn;
  2188. (*ppNetCon)->AddRef();
  2189. }
  2190. NcFreeNetconProperties(pProps);
  2191. }
  2192. pConn->Release();
  2193. }
  2194. } while (FALSE == fFound && SUCCEEDED(hr) && 1 == ulCount);
  2195. // Normalize hr
  2196. hr = (fFound ? S_OK : E_FAIL);
  2197. return hr;
  2198. }
  2199. /*++
  2200. Routine Description:
  2201. Retrieves the INetConnection that corresponds to the given Name
  2202. of the Connection Icon in Network Connection Folder.
  2203. We will enumerate the INetConnection using our cached m_spEnum.
  2204. Arguments:
  2205. [in] pwszConnName - the connection name to search
  2206. [out] ppNetCon - receives the interface
  2207. Return Value:
  2208. standard HRESULT
  2209. Note: Bug# 304474: If we couldn't find the INetConnection corresponding
  2210. to the given name from the pwszConnName parameter and there is
  2211. exactly one WAN MediaType connection left, we'll return the
  2212. INetconnection for that WAN connection. WAN media types are either
  2213. NCM_PHONE, NCM_ISDN or NCM_TUNNEL.
  2214. --*/
  2215. HRESULT CIcsUpgrade::GetINetConnectionByName(
  2216. WCHAR* pwszConnName,
  2217. INetConnection** ppNetCon)
  2218. {
  2219. HRESULT hr;
  2220. INetConnection* pConn;
  2221. Assert(NULL != pwszConnName);
  2222. Assert(NULL != ppNetCon);
  2223. *ppNetCon = NULL;
  2224. TraceTag(ttidNetSetup, "GetINetConnectionByName: pwszConnName: %S", pwszConnName);
  2225. // Search for the connection with the correct connection name
  2226. ULONG ulCount;
  2227. BOOLEAN fFound = FALSE;
  2228. INetConnection* pWANConn = NULL;
  2229. ULONG ulcWANConn = 0;
  2230. // reset our cache m_spEnum
  2231. m_spEnum->Reset();
  2232. do
  2233. {
  2234. NETCON_PROPERTIES* pProps;
  2235. hr = m_spEnum->Next(1, &pConn, &ulCount);
  2236. if (SUCCEEDED(hr) && 1 == ulCount)
  2237. {
  2238. SetProxyBlanket(pConn);
  2239. hr = pConn->GetProperties(&pProps);
  2240. if (S_OK == hr)
  2241. {
  2242. TraceTag(ttidNetSetup, "GetINetConnectionByName: Connection Name: %S", pProps->pszwName);
  2243. if ( (NCM_PHONE == pProps->MediaType) ||
  2244. (NCM_ISDN == pProps->MediaType) ||
  2245. (NCM_TUNNEL == pProps->MediaType)
  2246. )
  2247. {
  2248. TraceTag(
  2249. ttidNetSetup,
  2250. "GetINetConnectionByName: Connection Name: %S is WAN, MediaType is %d",
  2251. pProps->pszwName, pProps->MediaType);
  2252. ulcWANConn++;
  2253. if (1 == ulcWANConn)
  2254. {
  2255. // save the 1st WAN connection found
  2256. TraceTag(ttidNetSetup, "GetINetConnectionByName: Connection Name: %S is 1st WAN found", pProps->pszwName);
  2257. pWANConn = pConn;
  2258. pWANConn->AddRef();
  2259. }
  2260. }
  2261. if (wcscmp(pProps->pszwName, pwszConnName) == 0)
  2262. {
  2263. fFound = TRUE;
  2264. *ppNetCon = pConn;
  2265. (*ppNetCon)->AddRef();
  2266. }
  2267. NcFreeNetconProperties(pProps);
  2268. }
  2269. pConn->Release();
  2270. }
  2271. }
  2272. while (FALSE == fFound && SUCCEEDED(hr) && 1 == ulCount);
  2273. if (fFound)
  2274. {
  2275. if (pWANConn)
  2276. {
  2277. // No matter how many WAN connections we have,
  2278. // release the saved WAN connection.
  2279. pWANConn->Release();
  2280. }
  2281. }
  2282. else
  2283. {
  2284. TraceTag(ttidNetSetup, "GetINetConnectionByName: Can't find pwszConnName: %S", pwszConnName);
  2285. // no connection has the name specified by the pwszConnName [in] parameter
  2286. if (1 == ulcWANConn && pWANConn)
  2287. {
  2288. // There is exactly ONE WAN connection left on the sysetm.
  2289. // Transfer this as the INetConnection output.
  2290. TraceTag(ttidNetSetup, "GetINetConnectionByName: will use the only one WAN connectoid left");
  2291. *ppNetCon = pWANConn;
  2292. fFound = TRUE;
  2293. }
  2294. else if (ulcWANConn > 1 && pWANConn)
  2295. {
  2296. // not found and there are more than 1 WAN connections
  2297. TraceTag(ttidNetSetup, "GetINetConnectionByName: more than one WAN connectoid found");
  2298. pWANConn->Release();
  2299. }
  2300. }
  2301. // Normalize hr
  2302. hr = (fFound ? S_OK : E_FAIL);
  2303. return hr;
  2304. }
  2305. /*++
  2306. Routine Description:
  2307. Setup the global Application Protocol
  2308. Arguments:
  2309. None
  2310. Return Value:
  2311. standard HRESULT
  2312. --*/
  2313. HRESULT CIcsUpgrade::SetupApplicationProtocol()
  2314. {
  2315. DefineFunctionName("CIcsUpgrade::SetupApplicationProtocol");
  2316. TraceFunctionEntry(ttidNetSetup);
  2317. HRESULT hr;
  2318. list<CSharedAccessApplication>& rListAppProt =
  2319. m_pIcsUpgradeSettings->listAppPortmappings;
  2320. if ( rListAppProt.size() == 0)
  2321. {
  2322. // no Application Protocol to set
  2323. return S_OK;
  2324. }
  2325. // 1. Get the INetProtocolSettings interface to control system-wide
  2326. // ICS and firewall settings (i.e port mappings and applications).
  2327. // Create Homenet Configuration Manager COM Instance
  2328. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  2329. hr = CoCreateInstance(CLSID_HNetCfgMgr, NULL,
  2330. CLSCTX_ALL,
  2331. IID_IHNetCfgMgr,
  2332. (LPVOID *)&spIHNetCfgMgr);
  2333. if (FAILED(hr))
  2334. {
  2335. TraceTag(ttidError, "%s: CoCreateInstance CLSID_HNetCfgMgr failed: 0x%lx",
  2336. __FUNCNAME__, hr);
  2337. return hr;
  2338. }
  2339. // Get the IHNetProtocolSettings
  2340. CComPtr<IHNetProtocolSettings> spHNetProtocolSettings;
  2341. hr = spIHNetCfgMgr->QueryInterface(IID_IHNetProtocolSettings,
  2342. (LPVOID *)&spHNetProtocolSettings);
  2343. if (FAILED(hr))
  2344. {
  2345. TraceTag(ttidError, "%s: QueryInterface IID_IHNetProtocolSettings failed: 0x%lx",
  2346. __FUNCNAME__, hr);
  2347. return hr;
  2348. }
  2349. // 2. For each enabled CSharedAccessApplication
  2350. // if (there is no existing matching ApplicationProtocol
  2351. // invoke INetProtocolSettings::CreateApplicationProtocol
  2352. // else
  2353. // update the existing ApplicaitonProtocol
  2354. for (list<CSharedAccessApplication>::iterator iter = rListAppProt.begin();
  2355. iter != rListAppProt.end();
  2356. ++iter)
  2357. {
  2358. HNET_RESPONSE_RANGE* pHNetResponseArray = NULL;
  2359. USHORT uscResponseRange = 0; // number of HNET_RESPONSE_RANGE returned
  2360. if ((*iter).m_bSelected)
  2361. {
  2362. // migrate the enabled one only
  2363. UCHAR ucProtocol;
  2364. if (lstrcmpiW( ((*iter).m_szProtocol).c_str(), c_wszTCP) == 0)
  2365. {
  2366. ucProtocol = NAT_PROTOCOL_TCP;
  2367. }
  2368. else if (lstrcmpiW( ((*iter).m_szProtocol).c_str(), c_wszUDP) == 0)
  2369. {
  2370. ucProtocol = NAT_PROTOCOL_UDP;
  2371. }
  2372. else
  2373. {
  2374. // ignore others
  2375. continue;
  2376. }
  2377. USHORT usPort = HTONS((*iter).m_wPort);
  2378. WCHAR* pwszTitle = (WCHAR*)((*iter).m_szTitle).c_str();
  2379. hr = PutResponseStringIntoArray(*iter, &uscResponseRange,
  2380. &pHNetResponseArray);
  2381. if (FAILED(hr))
  2382. {
  2383. TraceTag(ttidError,
  2384. "%s: Ignore error in PutResponseStringIntoArray : 0x%lx",
  2385. __FUNCNAME__, hr);
  2386. }
  2387. if (S_OK == hr)
  2388. {
  2389. Assert(pHNetResponseArray != NULL);
  2390. CComPtr<IHNetApplicationProtocol> spHNetAppProt;
  2391. hr = FindMatchingApplicationProtocol(
  2392. spHNetProtocolSettings, ucProtocol, usPort,
  2393. &spHNetAppProt);
  2394. if (S_OK == hr)
  2395. {
  2396. TraceTag(ttidNetSetup,
  2397. "%s: Update existing ApplicationProtocol for %S",
  2398. __FUNCNAME__, pwszTitle);
  2399. // there is existing ApplicatonProtocol
  2400. hr = spHNetAppProt->SetName(pwszTitle);
  2401. if (S_OK != hr)
  2402. {
  2403. TraceTag(ttidError, "%s: spHNetAppProt->SetName failed: 0x%lx",
  2404. __FUNCNAME__, hr);
  2405. }
  2406. hr = spHNetAppProt->SetResponseRanges(uscResponseRange,
  2407. pHNetResponseArray);
  2408. if (S_OK != hr)
  2409. {
  2410. TraceTag(ttidError, "%s: spHNetAppProt->SetResponseRanges failed: 0x%lx",
  2411. __FUNCNAME__, hr);
  2412. }
  2413. hr = spHNetAppProt->SetEnabled(TRUE);
  2414. if (S_OK != hr)
  2415. {
  2416. TraceTag(ttidError, "%s: spHNetAppProt->SetEnabled failed: 0x%lx",
  2417. __FUNCNAME__, hr);
  2418. }
  2419. }
  2420. else
  2421. {
  2422. // no existing ApplicationProtocol, create a new one
  2423. hr = spHNetProtocolSettings->CreateApplicationProtocol(
  2424. pwszTitle,
  2425. ucProtocol,
  2426. usPort,
  2427. uscResponseRange,
  2428. pHNetResponseArray,
  2429. &spHNetAppProt);
  2430. if (S_OK != hr)
  2431. {
  2432. TraceTag(ttidError,
  2433. "%s: CreateApplicationProtocol failed: 0x%lx",
  2434. __FUNCNAME__, hr);
  2435. }
  2436. else
  2437. {
  2438. hr = spHNetAppProt->SetEnabled(TRUE);
  2439. if (S_OK != hr)
  2440. {
  2441. TraceTag(ttidError,
  2442. "%s: spHNetAppProt->SetEnabled failed: 0x%lx",
  2443. __FUNCNAME__, hr);
  2444. }
  2445. }
  2446. }
  2447. delete [] (BYTE*) pHNetResponseArray;
  2448. pHNetResponseArray = NULL;
  2449. uscResponseRange = 0;
  2450. }
  2451. }
  2452. } //end for
  2453. return S_OK;
  2454. }
  2455. /*++
  2456. Routine Description:
  2457. Setup the Server Port Mapping Protocol on the external connection.
  2458. Arguments:
  2459. None
  2460. Return Value:
  2461. standard HRESULT
  2462. --*/
  2463. HRESULT CIcsUpgrade::SetupServerPortMapping()
  2464. {
  2465. HRESULT hr;
  2466. list<CSharedAccessServer>& rListSvrPortMappings =
  2467. m_pIcsUpgradeSettings->listSvrPortmappings;
  2468. DefineFunctionName("CIcsUpgrade::SetupServerPortMapping");
  2469. TraceFunctionEntry(ttidNetSetup);
  2470. if ( rListSvrPortMappings.size() == 0 )
  2471. {
  2472. // no Server Port Mappings to set
  2473. return S_OK;
  2474. }
  2475. // 1. Get the INetProtocolSettings interface to control system-wide
  2476. // ICS and firewall settings (i.e port mappings and applications).
  2477. // Create Homenet Configuration Manager COM Instance
  2478. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  2479. hr = CoCreateInstance(CLSID_HNetCfgMgr, NULL,
  2480. CLSCTX_ALL,
  2481. IID_IHNetCfgMgr,
  2482. (LPVOID *)&spIHNetCfgMgr);
  2483. if (FAILED(hr))
  2484. {
  2485. TraceTag(ttidError, "%s: CoCreateInstance CLSID_HNetCfgMgr failed: 0x%lx",
  2486. __FUNCNAME__, hr);
  2487. return hr;
  2488. }
  2489. // Get the IHNetProtocolSettings
  2490. CComPtr<IHNetProtocolSettings> spHNetProtocolSettings;
  2491. hr = spIHNetCfgMgr->QueryInterface(IID_IHNetProtocolSettings,
  2492. (LPVOID *)&spHNetProtocolSettings);
  2493. if (FAILED(hr))
  2494. {
  2495. TraceTag(ttidError, "%s: QueryInterface IID_IHNetProtocolSettings failed: 0x%lx",
  2496. __FUNCNAME__, hr);
  2497. return hr;
  2498. }
  2499. // 2. For each enabled CSharedAccessServer x
  2500. // if (there is no PortMapping Protocol corresponding to the
  2501. // x.m_szProtocol and x.m_wInternalPort)
  2502. // call INetProtocolSettings::CreatePortMappingProtocol
  2503. // to get an IHNetPortMappingProtocol interface ptr;
  2504. // else
  2505. // get an existing IHNetPortMappingProtocol interface ptr
  2506. //
  2507. // Get IHNetPortMappingBinding interface ptr by calling
  2508. // IHNetConnection::GetBindingForPortMappingProtocol by passing the
  2509. // IHNetPortMappingProtocol iface ptr on the public IHNetConnection;
  2510. // call IHNetPortMappingBinding::SetTargetComputerName;
  2511. for (list<CSharedAccessServer>::iterator iter =
  2512. rListSvrPortMappings.begin();
  2513. iter != rListSvrPortMappings.end();
  2514. ++iter)
  2515. {
  2516. // migrate the enabled one only
  2517. if ((*iter).m_bSelected)
  2518. {
  2519. UCHAR ucProtocol;
  2520. if (lstrcmpiW( ((*iter).m_szProtocol).c_str(), c_wszTCP) == 0)
  2521. {
  2522. ucProtocol = NAT_PROTOCOL_TCP;
  2523. }
  2524. else if (lstrcmpiW( ((*iter).m_szProtocol).c_str(), c_wszUDP) == 0)
  2525. {
  2526. ucProtocol = NAT_PROTOCOL_UDP;
  2527. }
  2528. else
  2529. {
  2530. // ignore others
  2531. continue;
  2532. }
  2533. USHORT usPort = HTONS((*iter).m_wInternalPort);
  2534. WCHAR* pwszTitle = (WCHAR*) ((*iter).m_szTitle).c_str();
  2535. // get the IHNetPortMappingProtocol iface ptr
  2536. CComPtr<IHNetPortMappingProtocol> spHNetPortMappingProt;
  2537. hr = FindMatchingPortMappingProtocol(
  2538. spHNetProtocolSettings, ucProtocol, usPort,
  2539. &spHNetPortMappingProt);
  2540. if (S_OK == hr)
  2541. {
  2542. TraceTag(ttidNetSetup,
  2543. "%s: Update existing PortMappingProtocol for %S",
  2544. __FUNCNAME__, pwszTitle);
  2545. // change the name of the title
  2546. hr= spHNetPortMappingProt->SetName(pwszTitle);
  2547. if (FAILED(hr))
  2548. {
  2549. TraceTag(ttidError,
  2550. "%s: spHNetPortMappingProt->SetName failed: 0x%lx",
  2551. __FUNCNAME__, hr);
  2552. hr = S_OK; // we still want to invoke
  2553. // IHNetPortMappingBinding::SetEnabled() below.
  2554. }
  2555. }
  2556. else
  2557. {
  2558. TraceTag(ttidNetSetup,
  2559. "%s: CreatePortMappingProtocol for %S",
  2560. __FUNCNAME__, pwszTitle);
  2561. // no existing PortMappingProtocol, create a new one
  2562. hr = spHNetProtocolSettings->CreatePortMappingProtocol(
  2563. pwszTitle, // Title
  2564. ucProtocol, // Protocol
  2565. usPort, // InternalPort
  2566. &spHNetPortMappingProt); // returned iface ptr
  2567. if (FAILED(hr))
  2568. {
  2569. TraceTag(ttidError, "%s: CreatePortMappingProtocol failed: 0x%lx",
  2570. __FUNCNAME__, hr);
  2571. }
  2572. }
  2573. if (S_OK == hr)
  2574. {
  2575. CComPtr<IHNetConnection> spExternalHNetConn;
  2576. if (m_pExternalNetConn == NULL)
  2577. {
  2578. hr = GetExternalINetConnection(&m_pExternalNetConn);
  2579. if (FAILED(hr))
  2580. {
  2581. TraceTag(ttidError, "%s: GetExternalINetConnection failed: 0x%lx",
  2582. __FUNCNAME__, hr);
  2583. return hr; // fatal return
  2584. }
  2585. }
  2586. // get the external/public IHNetConnection iface ptr
  2587. hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection(
  2588. m_pExternalNetConn,
  2589. &spExternalHNetConn);
  2590. if (FAILED(hr))
  2591. {
  2592. TraceTag(ttidError, "%s: GetIHNetConnectionForINetConnection failed: 0x%lx",
  2593. __FUNCNAME__, hr);
  2594. }
  2595. if (S_OK == hr)
  2596. {
  2597. // Get IHNetPortMappingBinding interface ptr
  2598. CComPtr<IHNetPortMappingBinding> spHNetPortMappingBinding;
  2599. hr = spExternalHNetConn->GetBindingForPortMappingProtocol(
  2600. spHNetPortMappingProt,
  2601. &spHNetPortMappingBinding);
  2602. if (FAILED(hr))
  2603. {
  2604. TraceTag(ttidError,
  2605. "%s: GetBindingForPortMappingProtocol failed: 0x%lx",
  2606. __FUNCNAME__, hr);
  2607. return hr;
  2608. }
  2609. if (S_OK == hr)
  2610. {
  2611. ULONG ulAddress = INADDR_NONE;
  2612. WCHAR* pwszInternalName = (OLECHAR *)((*iter).m_szInternalName).c_str();
  2613. if ( ((*iter).m_szInternalName).length() > 7)
  2614. {
  2615. // 1.2.3.4 -- minimum of 7 characters
  2616. ulAddress = IpPszToHostAddr(pwszInternalName);
  2617. }
  2618. if (INADDR_NONE == ulAddress)
  2619. {
  2620. hr = spHNetPortMappingBinding->SetTargetComputerName(
  2621. pwszInternalName);
  2622. if (FAILED(hr))
  2623. {
  2624. TraceTag(ttidError,
  2625. "%s: SetTargetComputerName failed: 0x%lx",
  2626. __FUNCNAME__, hr);
  2627. }
  2628. }
  2629. else
  2630. {
  2631. hr = spHNetPortMappingBinding->SetTargetComputerAddress(
  2632. HTONL(ulAddress));
  2633. if (FAILED(hr))
  2634. {
  2635. TraceTag(ttidError,
  2636. "%s: SetTargetComputerAddress failed: 0x%lx",
  2637. __FUNCNAME__, hr);
  2638. }
  2639. }
  2640. if (S_OK == hr)
  2641. {
  2642. hr = spHNetPortMappingBinding->SetEnabled(TRUE);
  2643. if (FAILED(hr))
  2644. {
  2645. TraceTag(ttidError,
  2646. "%s: SetEnabled failed: 0x%lx",
  2647. __FUNCNAME__, hr);
  2648. }
  2649. }
  2650. }
  2651. }
  2652. }
  2653. } // end if ((*iter).m_bSelected)
  2654. } //end for
  2655. return S_OK;
  2656. }
  2657. /*++
  2658. Routine Description:
  2659. retrive a matching IHNetPortMappingProtocol object which matches the
  2660. given protocol (ucProtocol) and port number (usPort)
  2661. Arguments:
  2662. [in] pHNetProtocolSettings - IHNetProtocolSettings iface ptr
  2663. [in] ucProtocol - NAT_PROTOCOL_TCP or NAT_PROTOCOL_UDP
  2664. [in] usPort - port number used by this server PortMapping Protocol
  2665. [out] ppHNetPortMappingProtocol - return the matching
  2666. IHNetPortMappingProtocol
  2667. Return Value:
  2668. standard HRESULT
  2669. --*/
  2670. HRESULT CIcsUpgrade::FindMatchingPortMappingProtocol(
  2671. IHNetProtocolSettings* pHNetProtocolSettings,
  2672. UCHAR ucProtocol,
  2673. USHORT usPort,
  2674. IHNetPortMappingProtocol** ppHNetPortMappingProtocol)
  2675. {
  2676. HRESULT hr;
  2677. Assert(pHNetProtocolSettings != NULL);
  2678. Assert(ppHNetPortMappingProtocol != NULL);
  2679. DefineFunctionName("CIcsUpgrade::FindMatchingPortMappingProtocol");
  2680. TraceFunctionEntry(ttidNetSetup);
  2681. *ppHNetPortMappingProtocol = NULL;
  2682. CComPtr<IEnumHNetPortMappingProtocols> spServerEnum;
  2683. hr = pHNetProtocolSettings->EnumPortMappingProtocols(
  2684. &spServerEnum);
  2685. if (FAILED(hr))
  2686. {
  2687. return hr;
  2688. }
  2689. IHNetPortMappingProtocol* pServer;
  2690. ULONG ulCount;
  2691. do
  2692. {
  2693. UCHAR ucFoundProtocol;
  2694. USHORT usFoundPort;
  2695. hr = spServerEnum->Next(
  2696. 1,
  2697. &pServer,
  2698. &ulCount
  2699. );
  2700. if (SUCCEEDED(hr) && 1 == ulCount)
  2701. {
  2702. hr = pServer->GetIPProtocol(&ucFoundProtocol);
  2703. if (FAILED(hr))
  2704. {
  2705. pServer->Release();
  2706. return hr;
  2707. }
  2708. hr = pServer->GetPort(&usFoundPort);
  2709. if (FAILED(hr))
  2710. {
  2711. pServer->Release();
  2712. return hr;
  2713. }
  2714. if (ucFoundProtocol == ucProtocol &&
  2715. usFoundPort == usPort)
  2716. {
  2717. // found mathcing one, transfer value
  2718. *ppHNetPortMappingProtocol = pServer;
  2719. return S_OK;
  2720. }
  2721. pServer->Release();
  2722. }
  2723. } while (SUCCEEDED(hr) && 1 == ulCount);
  2724. return E_FAIL; // not found
  2725. }
  2726. /*++
  2727. Routine Description:
  2728. retrive a matching IHNetApplicationProtocol object which matches the
  2729. given protocol (ucProtocol) and port number (usPort)
  2730. Arguments:
  2731. [in] pHNetProtocolSettings - IHNetProtocolSettings iface ptr
  2732. [in] ucProtocol - NAT_PROTOCOL_TCP or NAT_PROTOCOL_UDP
  2733. [in] usPort - port number used by this server PortMapping Protocol
  2734. [out] ppHNetApplicationProtocol - return the matching
  2735. IHNetApplicationProtocol
  2736. Return Value:
  2737. standard HRESULT
  2738. --*/
  2739. HRESULT CIcsUpgrade::FindMatchingApplicationProtocol(
  2740. IHNetProtocolSettings* pHNetProtocolSettings,
  2741. UCHAR ucProtocol,
  2742. USHORT usPort,
  2743. IHNetApplicationProtocol** ppHNetApplicationProtocol)
  2744. {
  2745. HRESULT hr;
  2746. Assert(pHNetProtocolSettings != NULL);
  2747. Assert(ppHNetApplicationProtocol != NULL);
  2748. DefineFunctionName("CIcsUpgrade::FindMatchingApplicationProtocol");
  2749. TraceFunctionEntry(ttidNetSetup);
  2750. *ppHNetApplicationProtocol = NULL;
  2751. CComPtr<IEnumHNetApplicationProtocols> spAppEnum;
  2752. hr = pHNetProtocolSettings->EnumApplicationProtocols(
  2753. FALSE,
  2754. &spAppEnum);
  2755. if (FAILED(hr))
  2756. {
  2757. return hr;
  2758. }
  2759. IHNetApplicationProtocol* pApp;
  2760. ULONG ulCount;
  2761. do
  2762. {
  2763. UCHAR ucFoundProtocol;
  2764. USHORT usFoundPort;
  2765. hr = spAppEnum->Next(
  2766. 1,
  2767. &pApp,
  2768. &ulCount
  2769. );
  2770. if (SUCCEEDED(hr) && 1 == ulCount)
  2771. {
  2772. hr = pApp->GetOutgoingIPProtocol(&ucFoundProtocol);
  2773. if (FAILED(hr))
  2774. {
  2775. pApp->Release();
  2776. return hr;
  2777. }
  2778. hr = pApp->GetOutgoingPort(&usFoundPort);
  2779. if (FAILED(hr))
  2780. {
  2781. pApp->Release();
  2782. return hr;
  2783. }
  2784. if (ucFoundProtocol == ucProtocol &&
  2785. usFoundPort == usPort)
  2786. {
  2787. // found mathcing one, transfer value
  2788. *ppHNetApplicationProtocol = pApp;
  2789. return S_OK;
  2790. }
  2791. pApp->Release();
  2792. }
  2793. } while (SUCCEEDED(hr) && 1 == ulCount);
  2794. return E_FAIL; // not found
  2795. }
  2796. /*++
  2797. Routine Description:
  2798. Setup ICS misc. settings from m_pIcsUpgradeSettings
  2799. Arguments:
  2800. Return Value:
  2801. standard HRESULT
  2802. --*/
  2803. HRESULT CIcsUpgrade::SetupIcsMiscItems()
  2804. {
  2805. HRESULT hr = S_OK;
  2806. if (NULL == m_pIcsUpgradeSettings)
  2807. {
  2808. return E_UNEXPECTED;
  2809. }
  2810. DefineFunctionName("CIcsUpgrade::SetupIcsMiscItems");
  2811. TraceFunctionEntry(ttidNetSetup);
  2812. if (!m_fICSCreated)
  2813. {
  2814. // no need to continue if ICS has not been created
  2815. return hr;
  2816. }
  2817. // If Win9x/Win2K ICS upgrade, firewall the ICS public connection
  2818. if (m_pIcsUpgradeSettings->fWin9xUpgrade ||
  2819. m_pIcsUpgradeSettings->fWin2KUpgrade)
  2820. {
  2821. INetConnection* rgINetConn[2] = {0, 0};
  2822. if (m_pExternalNetConn)
  2823. {
  2824. rgINetConn[0] = m_pExternalNetConn;
  2825. hr = HrEnablePersonalFirewall(rgINetConn);
  2826. if (FAILED(hr))
  2827. {
  2828. TraceTag(ttidError, "%s: HrEnablePersonalFirewall failed: 0x%lx line: %d",
  2829. __FUNCNAME__, hr, __LINE__);
  2830. NetSetupLogStatusV(
  2831. LogSevInformation,
  2832. SzLoadIds (IDS_TXT_CANT_FIREWALL));
  2833. hr = S_OK; // continue with the rest.
  2834. }
  2835. }
  2836. }
  2837. // Bug# 315265, 315242
  2838. // post-processing to fix up IP Configuration on private connection
  2839. // (1) if there is at least one internal adapter couldn't be upgraded from
  2840. // Win9x ICS upgrade, we have to make sure the survival internal adapter
  2841. // has static IP address 192.168.0.1, subnet mask 255.255.255.0
  2842. // (2) if we create a bridge for Win9x ICS upgrade, we need to set static
  2843. // IP address 192.168.0.1, subnet mask 255.255.255.0 for TcpIp bound to
  2844. // the bridge.
  2845. // Note: (1) and (2) are exclusive.
  2846. //
  2847. // For WinXP Unattended clean install,
  2848. // (3) if an internal ICS adapter is found, set static IP address
  2849. // 192.168.0.1, subnet mask 255.255.255.0 for the TCPIP bound to the
  2850. // internal adapter.
  2851. // (4) if ICS is enabled and the bridge is the ICS private connection.
  2852. // Set static IP address 192.168.0.1, subnet mask 255.255.255.0 for
  2853. // TcpIp bound to the bridge.
  2854. // Note: (3) and (4) are exclusive.
  2855. if ( m_pIcsUpgradeSettings->fInternalAdapterFound &&
  2856. (m_pIcsUpgradeSettings->fWin9xUpgradeAtLeastOneInternalAdapterBroken ||
  2857. m_pIcsUpgradeSettings->fXpUnattended) )
  2858. {
  2859. hr = SetPrivateIpConfiguration(m_pIcsUpgradeSettings->guidInternal);
  2860. if (FAILED(hr))
  2861. {
  2862. // logging, but we'll continue to do the rest of the ICS upgrade though.
  2863. TraceTag(ttidError,
  2864. "%s: SetPrivateIpConfiguration on private adapter failed: 0x%lx",
  2865. __FUNCNAME__, hr);
  2866. NetSetupLogStatusV(
  2867. LogSevInformation,
  2868. SzLoadIds (IDS_TXT_CANT_UPGRADE_ICS));
  2869. }
  2870. }
  2871. else if ( ((m_pIcsUpgradeSettings->listBridge).size() >= 2) &&
  2872. !m_pIcsUpgradeSettings->fInternalAdapterFound)
  2873. {
  2874. // A bridge was created as ICS private.
  2875. // We need to setup its static IP Configuration since
  2876. // these settings are not configured when it was created a while ago.
  2877. GUID guidBridge;
  2878. hr = GetBridgeGuid(guidBridge);
  2879. if (SUCCEEDED(hr))
  2880. {
  2881. hr = SetPrivateIpConfiguration(guidBridge);
  2882. if (FAILED(hr))
  2883. {
  2884. // logging, but we'll continue to do the rest of the ICS upgrade though.
  2885. TraceTag(ttidError,
  2886. "%s: SetPrivateIpConfiguration for bridge failed: 0x%lx",
  2887. __FUNCNAME__, hr);
  2888. NetSetupLogStatusV(
  2889. LogSevInformation,
  2890. SzLoadIds (IDS_TXT_CANT_UPGRADE_ICS));
  2891. }
  2892. }
  2893. else
  2894. {
  2895. // logging, but we'll continue to do the rest of the ICS upgrade though.
  2896. TraceTag(ttidError,
  2897. "%s: GetBridgeGuid failed: 0x%lx",
  2898. __FUNCNAME__, hr);
  2899. NetSetupLogStatusV(
  2900. LogSevInformation,
  2901. SzLoadIds (IDS_TXT_CANT_UPGRADE_ICS));
  2902. }
  2903. }
  2904. LPRASSHARECONN pRasShareConn = &(m_pIcsUpgradeSettings->rscExternal);
  2905. // set the fShowTrayIcon to the external INetConnection
  2906. // note: this property has already migrated for Win2K upgrade
  2907. if ( (m_pExternalNetConn) &&
  2908. (m_pIcsUpgradeSettings->fWin9xUpgrade ||
  2909. m_pIcsUpgradeSettings->fXpUnattended) )
  2910. {
  2911. if (pRasShareConn->fIsLanConnection)
  2912. {
  2913. INetLanConnection* pLanConn = NULL;
  2914. hr = HrQIAndSetProxyBlanket(m_pExternalNetConn, &pLanConn);
  2915. if (SUCCEEDED(hr) && pLanConn)
  2916. {
  2917. LANCON_INFO linfo = {0};
  2918. linfo.fShowIcon = m_pIcsUpgradeSettings->fShowTrayIcon;
  2919. // Set new value of show icon property
  2920. hr = pLanConn->SetInfo(LCIF_ICON, &linfo);
  2921. if (FAILED(hr))
  2922. {
  2923. TraceTag(ttidError, "%s: pLanConn->SetInfo failed: 0x%lx",
  2924. __FUNCNAME__, hr);
  2925. }
  2926. pLanConn->Release();
  2927. }
  2928. else
  2929. {
  2930. TraceTag(
  2931. ttidError,
  2932. "%s: HrQIAndSetProxyBlanket for INetLanConnection failed: 0x%lx",
  2933. __FUNCNAME__, hr);
  2934. }
  2935. }
  2936. else
  2937. {
  2938. // this is a WAN connection
  2939. RASCON_INFO rci;
  2940. LPRASENTRY pRasEntry = NULL;
  2941. DWORD dwRasEntrySize;
  2942. hr = HrRciGetRasConnectionInfo(m_pExternalNetConn, &rci);
  2943. if (SUCCEEDED(hr))
  2944. {
  2945. hr = HrRasGetEntryProperties(rci.pszwPbkFile, rci.pszwEntryName,
  2946. &pRasEntry, &dwRasEntrySize);
  2947. if (SUCCEEDED(hr) && pRasEntry)
  2948. {
  2949. DWORD dwRet;
  2950. if (m_pIcsUpgradeSettings->fShowTrayIcon)
  2951. pRasEntry->dwfOptions |= RASEO_ModemLights;
  2952. else
  2953. pRasEntry->dwfOptions &= (~RASEO_ModemLights);
  2954. dwRet = RasSetEntryProperties(rci.pszwPbkFile, rci.pszwEntryName,
  2955. pRasEntry, dwRasEntrySize, 0, 0);
  2956. if (0 != dwRet)
  2957. {
  2958. TraceTag(
  2959. ttidError,
  2960. "%s: RasSetEntryProperties failed: 0x%lx",
  2961. __FUNCNAME__, GetLastError());
  2962. hr = HRESULT_FROM_WIN32(GetLastError());
  2963. }
  2964. MemFree(pRasEntry);
  2965. }
  2966. else
  2967. {
  2968. TraceTag(
  2969. ttidError,
  2970. "%s: HrRasGetEntryProperties failed: 0x%lx",
  2971. __FUNCNAME__, hr);
  2972. }
  2973. RciFree (&rci);
  2974. }
  2975. else
  2976. {
  2977. TraceTag(
  2978. ttidError,
  2979. "%s: HrRciGetRasConnectionInfo failed: 0x%lx",
  2980. __FUNCNAME__, hr);
  2981. }
  2982. }
  2983. }
  2984. // Set the dial on demand setting.
  2985. // We don't need to do it for 2 cases:
  2986. // 1. Win2K ICS upgrade because the registry settings is already migrated.
  2987. // 2. the ICS public is a LAN connection.
  2988. if (pRasShareConn->fIsLanConnection || m_pIcsUpgradeSettings->fWin2KUpgrade)
  2989. {
  2990. // no need to set dial on-demand for external lan connection
  2991. return hr;
  2992. }
  2993. // Get the IHNetIcsSettings interface to control system-wide
  2994. // ICS settings
  2995. // Create Homenet Configuration Manager COM Instance
  2996. CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
  2997. hr = CoCreateInstance(CLSID_HNetCfgMgr, NULL,
  2998. CLSCTX_ALL,
  2999. IID_IHNetCfgMgr,
  3000. (LPVOID *)&spIHNetCfgMgr);
  3001. if (FAILED(hr))
  3002. {
  3003. TraceTag(ttidError, "%s: CoCreateInstance CLSID_HNetCfgMgr failed: 0x%lx",
  3004. __FUNCNAME__, hr);
  3005. return hr;
  3006. }
  3007. // Get the IHNetIcsSettings
  3008. CComPtr<IHNetIcsSettings> spHNetIcsSettings;
  3009. hr = spIHNetCfgMgr->QueryInterface(IID_IHNetIcsSettings,
  3010. (LPVOID *)&spHNetIcsSettings);
  3011. if (FAILED(hr))
  3012. {
  3013. TraceTag(ttidError,
  3014. "%s: QueryInterface IID_IHNetIcsSettings failed: 0x%lx",
  3015. __FUNCNAME__, hr);
  3016. return hr;
  3017. }
  3018. hr = spHNetIcsSettings->SetAutodialSettings(!!(m_pIcsUpgradeSettings->fDialOnDemand));
  3019. if (FAILED(hr))
  3020. {
  3021. TraceTag(ttidError,
  3022. "%s: Ignore SetAutodialSettings failed: 0x%lx",
  3023. __FUNCNAME__, hr);
  3024. hr = S_OK;
  3025. }
  3026. return hr;
  3027. }
  3028. /*++
  3029. Routine Description:
  3030. The interface given by rAdapterGuid will be configured to
  3031. use ICS static IP 192.168.0.1, subnet mask 255.255.255.0
  3032. Arguments:
  3033. [in] rInterfaceGuid -- the Guid of the TcpIp interface
  3034. Return Value:
  3035. standard HRESULT
  3036. --*/
  3037. HRESULT CIcsUpgrade::SetPrivateIpConfiguration(IN GUID& rInterfaceGuid)
  3038. {
  3039. HRESULT hr = S_OK;
  3040. HKEY hkeyTcpipInterface = NULL;
  3041. DefineFunctionName("CIcsUpgrade::SetPrivateIpConfiguration");
  3042. TraceFunctionEntry(ttidNetSetup);
  3043. hr = OpenTcpipInterfaceKey(rInterfaceGuid, &hkeyTcpipInterface);
  3044. if (FAILED(hr))
  3045. {
  3046. TraceTag(ttidError,
  3047. "%s: OpenTcpipInterfaceKey failed: 0x%lx",
  3048. __FUNCNAME__, hr);
  3049. return hr;
  3050. }
  3051. Assert(hkeyTcpipInterface);
  3052. // IPAddress
  3053. hr = HrRegSetMultiSz(hkeyTcpipInterface,
  3054. c_wszIPAddress,
  3055. c_mszScopeAddress);
  3056. if(FAILED(hr))
  3057. {
  3058. TraceTag(ttidError,
  3059. "%s: failed to set %S to the registry. hr = 0x%lx.",
  3060. __FUNCNAME__, c_wszIPAddress,
  3061. hr);
  3062. goto Error;
  3063. }
  3064. // SubnetMask
  3065. hr = HrRegSetMultiSz(hkeyTcpipInterface,
  3066. c_wszSubnetMask,
  3067. c_mszScopeMask);
  3068. if(FAILED(hr))
  3069. {
  3070. TraceTag(ttidError,
  3071. "%s: failed to set %S to the registry. hr = 0x%lx.",
  3072. __FUNCNAME__, c_wszIPAddress,
  3073. hr);
  3074. goto Error;
  3075. }
  3076. // EnableDHCP
  3077. hr = HrRegSetDword(hkeyTcpipInterface,
  3078. c_wszEnableDHCP,
  3079. 0);
  3080. if(FAILED(hr))
  3081. {
  3082. TraceTag(ttidError,
  3083. "%s: failed to set %S to the registry. hr = 0x%lx.",
  3084. __FUNCNAME__, c_wszEnableDHCP,
  3085. hr);
  3086. goto Error;
  3087. }
  3088. Error:
  3089. RegSafeCloseKey(hkeyTcpipInterface);
  3090. return hr;
  3091. }
  3092. /*++
  3093. Routine Description:
  3094. Get the interface guid of a bridge.
  3095. Arguments:
  3096. [out] rInterfaceGuid -- receive the Guid from the bridge interface
  3097. Return Value:
  3098. standard HRESULT
  3099. --*/
  3100. HRESULT CIcsUpgrade::GetBridgeGuid(OUT GUID& rInterfaceGuid)
  3101. {
  3102. HRESULT hr = S_OK;
  3103. BOOLEAN fFound = FALSE;
  3104. INetConnection* pConn = NULL;
  3105. ULONG ulCount = 0;
  3106. DefineFunctionName("CIcsUpgrade::GetBridgeGuid");
  3107. TraceFunctionEntry(ttidNetSetup);
  3108. // we don't use the cached m_spEnum because it may be in a stale
  3109. // state (a bridge has just been created).
  3110. CComPtr<IEnumNetConnection> spEnum;
  3111. // Get the net connection manager
  3112. INetConnectionManager* pConnMan = NULL;
  3113. hr = CoCreateInstance(CLSID_ConnectionManager, NULL,
  3114. CLSCTX_ALL,
  3115. IID_INetConnectionManager,
  3116. (LPVOID *)&pConnMan);
  3117. if (SUCCEEDED(hr))
  3118. {
  3119. // Get the enumeration of connections
  3120. SetProxyBlanket(pConnMan);
  3121. hr = pConnMan->EnumConnections(NCME_DEFAULT, &spEnum);
  3122. pConnMan->Release(); // don't need this anymore
  3123. if (SUCCEEDED(hr))
  3124. {
  3125. SetProxyBlanket(spEnum);
  3126. }
  3127. else
  3128. {
  3129. TraceTag(ttidError,
  3130. "%s: EnumConnections failed: 0x%lx.",
  3131. __FUNCNAME__, hr);
  3132. return hr;
  3133. }
  3134. }
  3135. else
  3136. {
  3137. TraceTag(ttidError,
  3138. "%s: CoCreateInstance failed: 0x%lx.",
  3139. __FUNCNAME__, hr);
  3140. return hr;
  3141. }
  3142. hr = spEnum->Reset();
  3143. if (FAILED(hr))
  3144. {
  3145. TraceTag(ttidError,
  3146. "%s: Reset failed: 0x%lx.",
  3147. __FUNCNAME__, hr);
  3148. return hr;
  3149. }
  3150. do
  3151. {
  3152. NETCON_PROPERTIES* pProps;
  3153. hr = spEnum->Next(1, &pConn, &ulCount);
  3154. if (SUCCEEDED(hr) && 1 == ulCount)
  3155. {
  3156. SetProxyBlanket(pConn);
  3157. hr = pConn->GetProperties(&pProps);
  3158. if (SUCCEEDED(hr))
  3159. {
  3160. if (NCM_BRIDGE == pProps->MediaType)
  3161. {
  3162. // transfer value
  3163. rInterfaceGuid = pProps->guidId;
  3164. fFound = TRUE;
  3165. }
  3166. NcFreeNetconProperties(pProps);
  3167. }
  3168. pConn->Release();
  3169. }
  3170. } while (FALSE == fFound && SUCCEEDED(hr) && 1 == ulCount);
  3171. // Normalize hr
  3172. hr = (fFound ? S_OK : E_FAIL);
  3173. return hr;
  3174. }
  3175. /*++
  3176. Routine Description:
  3177. Get the INetConnection of a bridge.
  3178. Arguments:
  3179. [out] ppINetConn -- receive the INetConnection from the bridge interface
  3180. Return Value:
  3181. standard HRESULT
  3182. --*/
  3183. HRESULT CIcsUpgrade::GetBridgeINetConn(OUT INetConnection** ppINetConn)
  3184. {
  3185. HRESULT hr = S_OK;
  3186. BOOLEAN fFound = FALSE;
  3187. INetConnection* pConn = NULL;
  3188. ULONG ulCount = 0;
  3189. DefineFunctionName("CIcsUpgrade::GetBridgeINetConn");
  3190. TraceFunctionEntry(ttidNetSetup);
  3191. Assert(ppINetConn);
  3192. *ppINetConn = NULL;
  3193. // we don't use the cached m_spEnum because it may be in a stale
  3194. // state (a bridge has just been created).
  3195. CComPtr<IEnumNetConnection> spEnum;
  3196. // Get the net connection manager
  3197. INetConnectionManager* pConnMan = NULL;
  3198. hr = CoCreateInstance(CLSID_ConnectionManager, NULL,
  3199. CLSCTX_ALL,
  3200. IID_INetConnectionManager,
  3201. (LPVOID *)&pConnMan);
  3202. if (SUCCEEDED(hr))
  3203. {
  3204. // Get the enumeration of connections
  3205. SetProxyBlanket(pConnMan);
  3206. hr = pConnMan->EnumConnections(NCME_DEFAULT, &spEnum);
  3207. pConnMan->Release(); // don't need this anymore
  3208. if (SUCCEEDED(hr))
  3209. {
  3210. SetProxyBlanket(spEnum);
  3211. }
  3212. else
  3213. {
  3214. TraceTag(ttidError,
  3215. "%s: EnumConnections failed: 0x%lx.",
  3216. __FUNCNAME__, hr);
  3217. return hr;
  3218. }
  3219. }
  3220. else
  3221. {
  3222. TraceTag(ttidError,
  3223. "%s: CoCreateInstance failed: 0x%lx.",
  3224. __FUNCNAME__, hr);
  3225. return hr;
  3226. }
  3227. hr = spEnum->Reset();
  3228. if (FAILED(hr))
  3229. {
  3230. TraceTag(ttidError,
  3231. "%s: Reset failed: 0x%lx.",
  3232. __FUNCNAME__, hr);
  3233. return hr;
  3234. }
  3235. do
  3236. {
  3237. NETCON_PROPERTIES* pProps;
  3238. hr = spEnum->Next(1, &pConn, &ulCount);
  3239. if (SUCCEEDED(hr) && 1 == ulCount)
  3240. {
  3241. SetProxyBlanket(pConn);
  3242. hr = pConn->GetProperties(&pProps);
  3243. if (SUCCEEDED(hr))
  3244. {
  3245. if (NCM_BRIDGE == pProps->MediaType)
  3246. {
  3247. // transfer value
  3248. *ppINetConn = pConn;
  3249. fFound = TRUE;
  3250. }
  3251. NcFreeNetconProperties(pProps);
  3252. }
  3253. if (!fFound)
  3254. {
  3255. pConn->Release();
  3256. }
  3257. }
  3258. } while (FALSE == fFound && SUCCEEDED(hr) && 1 == ulCount);
  3259. // Normalize hr
  3260. hr = (fFound ? S_OK : E_FAIL);
  3261. return hr;
  3262. }
  3263. /*++
  3264. Routine Description:
  3265. Open the Ip Configuration registry Key of an interface
  3266. Arguments:
  3267. [in] rGuid -- the Guid of the TcpIp interface
  3268. [out] phKey -- receives the opened key
  3269. Return Value:
  3270. standard HRESULT
  3271. --*/
  3272. HRESULT CIcsUpgrade::OpenTcpipInterfaceKey(
  3273. IN GUID& rGuid,
  3274. OUT PHKEY phKey)
  3275. {
  3276. HRESULT hr;
  3277. LPWSTR wszSubKeyName;
  3278. ULONG ulSubKeyNameLength;
  3279. LPWSTR wszGuid;
  3280. Assert(phKey);
  3281. hr = StringFromCLSID(rGuid, &wszGuid);
  3282. if (SUCCEEDED(hr))
  3283. {
  3284. ulSubKeyNameLength =
  3285. wcslen(c_wszTcpipParametersKey) + 1 +
  3286. wcslen(c_wszInterfaces) + 1 +
  3287. wcslen(wszGuid) + 2;
  3288. wszSubKeyName = new WCHAR[ulSubKeyNameLength];
  3289. if (NULL != wszSubKeyName)
  3290. {
  3291. swprintf(
  3292. wszSubKeyName,
  3293. L"%ls\\%ls\\%ls",
  3294. c_wszTcpipParametersKey,
  3295. c_wszInterfaces,
  3296. wszGuid
  3297. );
  3298. }
  3299. else
  3300. {
  3301. hr = E_OUTOFMEMORY;
  3302. }
  3303. CoTaskMemFree(wszGuid);
  3304. }
  3305. if (SUCCEEDED(hr))
  3306. {
  3307. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, wszSubKeyName, KEY_ALL_ACCESS, phKey);
  3308. delete [] wszSubKeyName;
  3309. }
  3310. return hr;
  3311. }
  3312. /*++
  3313. Routine Description:
  3314. Create a named event to notify other components that we're
  3315. in GUI Mode Setup of Win2K ICS Upgrade
  3316. Arguments:
  3317. Return Value:
  3318. standard HRESULT
  3319. --*/
  3320. HRESULT CIcsUpgrade::CreateIcsUpgradeNamedEvent()
  3321. {
  3322. DefineFunctionName("CIcsUpgrade::CreateIcsUpgradeNamedEvent");
  3323. TraceFunctionEntry(ttidNetSetup);
  3324. // create an auto-reset, nonsingaled, named event
  3325. m_hIcsUpgradeEvent = CreateEvent(NULL, FALSE, FALSE, c_wszIcsUpgradeEventName);
  3326. if (NULL == m_hIcsUpgradeEvent)
  3327. {
  3328. TraceTag(ttidError,
  3329. "%s: CreateEvent failed: 0x%lx",
  3330. __FUNCNAME__, GetLastError());
  3331. NetSetupLogStatusV(
  3332. LogSevError,
  3333. SzLoadIds (IDS_TXT_CANT_UPGRADE_ICS));
  3334. return HRESULT_FROM_WIN32(GetLastError());
  3335. }
  3336. return S_OK;
  3337. }
  3338. //--------- HNet helpers end ------------------------------------