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

1171 lines
35 KiB

  1. /**********************************************************************/
  2. /** RemCfg.cpp : Implementation of CRemCfg **/
  3. /** **/
  4. /** Microsoft Windows/NT **/
  5. /** Copyright(C) Microsoft Corporation, 1997 - 1999 **/
  6. /**********************************************************************/
  7. #include "stdafx.h"
  8. #include <ntsecapi.h>
  9. #include <iptypes.h>
  10. #define _PNP_POWER_
  11. #include <ndispnp.h>
  12. #define _USTRINGP_NO_UNICODE_STRING
  13. #include "ustringp.h"
  14. #include <ntddip.h>
  15. #include <iphlpapi.h>
  16. #include "ndisutil.h"
  17. #include "assert.h"
  18. #include "remras.h"
  19. #include "atlapp.h"
  20. #include "atltmp.h"
  21. #include "RemCfg.h"
  22. #include "netcfgp.h" // private INetCfg stuff
  23. #include "devguid.h"
  24. EXTERN_C const CLSID CLSID_CNetCfg;
  25. #include "update.h"
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CRemCfg
  28. BOOL s_fWriteIPConfig;
  29. BOOL s_fRestartRouter;
  30. RemCfgIPEntryList s_IPEntryList;
  31. extern DWORD g_dwTraceHandle;
  32. CRemCfg::~CRemCfg()
  33. {
  34. TraceSz("CRemCfg destructor");
  35. DeleteCriticalSection(&m_critsec);
  36. }
  37. STDMETHODIMP CRemCfg::NotifyChanges(/* [in] */ BOOL fEnableRouter,
  38. /* [in] */ BYTE uPerformRouterDiscovery)
  39. {
  40. //Do nothing to fix bug 405636 and 345700
  41. //But still keep to method for compatibility with old builds
  42. return S_OK;
  43. }
  44. /*!--------------------------------------------------------------------------
  45. CRemCfg::SetRasEndpoints
  46. -
  47. Author: KennT
  48. ---------------------------------------------------------------------------*/
  49. STDMETHODIMP CRemCfg::SetRasEndpoints(DWORD dwFlags, DWORD dwTotalEndpoints, DWORD dwTotalIncoming, DWORD dwTotalOutgoing)
  50. {
  51. return E_NOTIMPL;
  52. }
  53. /*!--------------------------------------------------------------------------
  54. CRemCfg::GetIpxVirtualNetworkNumber
  55. -
  56. Author: KennT
  57. ---------------------------------------------------------------------------*/
  58. STDMETHODIMP CRemCfg::GetIpxVirtualNetworkNumber(DWORD * pdwVNetworkNumber)
  59. {
  60. //$ TODO : need to add a try/catch block around the whole thing!
  61. INetCfg * pNetCfg = NULL;
  62. IIpxAdapterInfo * pIpxAdapterInfo = NULL;
  63. DWORD dwNetwork;
  64. HRESULT hr = S_OK;
  65. TraceSz("CRemCfg::GetIpxVirtualNetworkNumber entered");
  66. if (pdwVNetworkNumber == NULL)
  67. return E_INVALIDARG;
  68. // Create the INetCfg, we're only reading so we don't
  69. // need to grab the write lock.
  70. hr = HrCreateAndInitializeINetCfg(NULL, /* &fInitCom, */
  71. &pNetCfg,
  72. FALSE /* fGetWriteLock */,
  73. 0 /* cmsTimeout */,
  74. NULL /* swzClientDesc */,
  75. NULL /* ppszwClientDesc */);
  76. if (hr == S_OK)
  77. hr = HrGetIpxPrivateInterface(pNetCfg, &pIpxAdapterInfo);
  78. if (hr == S_OK)
  79. hr = pIpxAdapterInfo->GetVirtualNetworkNumber(&dwNetwork);
  80. if (hr == S_OK)
  81. *pdwVNetworkNumber = dwNetwork;
  82. if (pIpxAdapterInfo)
  83. pIpxAdapterInfo->Release();
  84. if (pNetCfg)
  85. {
  86. HrUninitializeAndReleaseINetCfg(FALSE, /* fInitCom, */
  87. pNetCfg,
  88. FALSE /* fHasLock */);
  89. pNetCfg = NULL;
  90. }
  91. TraceResult("CRemCfg::GetIpxVirtualNetworkNumber", hr);
  92. return hr;
  93. }
  94. /*!--------------------------------------------------------------------------
  95. CRemCfg::SetIpxVirtualNetworkNumber
  96. -
  97. Author: KennT
  98. ---------------------------------------------------------------------------*/
  99. STDMETHODIMP CRemCfg::SetIpxVirtualNetworkNumber(DWORD dwVNetworkNumber)
  100. {
  101. //$ TODO : need to add a try/catch block around the whole thing!
  102. INetCfg * pNetCfg = NULL;
  103. IIpxAdapterInfo * pIpxAdapterInfo = NULL;
  104. HRESULT hr = S_OK;
  105. CString st;
  106. TraceSz("CRemCfg::SetIpxVirtualNetworkNumber entered");
  107. try
  108. {
  109. st.LoadString(IDS_CLIENT_DESC);
  110. }
  111. catch(...)
  112. {
  113. hr = E_OUTOFMEMORY;
  114. };
  115. // Create the INetCfg, we're only reading so we don't
  116. // need to grab the write lock.
  117. if (hr == S_OK)
  118. hr = HrCreateAndInitializeINetCfg(NULL, /* &fInitCom, */
  119. &pNetCfg,
  120. TRUE /* fGetWriteLock */,
  121. 500 /* cmsTimeout */,
  122. (LPCTSTR) st /* swzClientDesc */,
  123. NULL /* ppszwClientDesc */);
  124. if (hr == S_OK)
  125. hr = HrGetIpxPrivateInterface(pNetCfg, &pIpxAdapterInfo);
  126. if (hr == S_OK)
  127. hr = pIpxAdapterInfo->SetVirtualNetworkNumber(dwVNetworkNumber);
  128. if (hr == S_OK)
  129. hr = pNetCfg->Apply();
  130. if (pIpxAdapterInfo)
  131. pIpxAdapterInfo->Release();
  132. if (pNetCfg)
  133. {
  134. HrUninitializeAndReleaseINetCfg(FALSE, /*fInitCom, */
  135. pNetCfg,
  136. TRUE /* fHasLock */);
  137. pNetCfg = NULL;
  138. }
  139. TraceResult("CRemCfg::SetIpxVirtualNetworkNumber", hr);
  140. return hr;
  141. }
  142. /*!--------------------------------------------------------------------------
  143. CRemCfg::GetIpInfo
  144. -
  145. Author: TongLu, KennT
  146. ---------------------------------------------------------------------------*/
  147. STDMETHODIMP CRemCfg::GetIpInfo(const GUID *pGuid, REMOTE_RRAS_IPINFO * * ppInfo)
  148. {
  149. // TODO: Add your implementation code here
  150. INetCfg * pNetCfg = NULL;
  151. ITcpipProperties * pTcpipProperties = NULL;
  152. DWORD dwNetwork;
  153. HRESULT hr = S_OK;
  154. REMOTE_IPINFO *pRemoteIpInfo = NULL;
  155. REMOTE_RRAS_IPINFO * pRemoteRrasIpInfo = NULL;
  156. TraceSz("CRemCfg::GetIpInfo entered");
  157. if ((pGuid == NULL) || (ppInfo == NULL))
  158. return E_INVALIDARG;
  159. // Create the INetCfg, we're only reading so we don't
  160. // need to grab the write lock.
  161. hr = HrCreateAndInitializeINetCfg(NULL, /* &fInitCom, */
  162. &pNetCfg,
  163. FALSE /* fGetWriteLock */,
  164. 0 /* cmsTimeout */,
  165. NULL /* swzClientDesc */,
  166. NULL /* ppszwClientDesc */);
  167. if (hr == S_OK)
  168. {
  169. hr = HrGetIpPrivateInterface(pNetCfg, &pTcpipProperties);
  170. TraceResult("HrGetIpPrivateInterface", hr);
  171. }
  172. if (hr == S_OK)
  173. {
  174. hr = pTcpipProperties->GetIpInfoForAdapter(pGuid, &pRemoteIpInfo);
  175. if (hr != S_OK)
  176. {
  177. OLECHAR szBuffer[256];
  178. CHAR szOutBuffer[256];
  179. StringFromGUID2(*pGuid, szBuffer, 256);
  180. wsprintfA(szOutBuffer, "ITcpipProperties::GetIpInfoForAdapter(%ls)",
  181. szBuffer);
  182. TraceResult(szOutBuffer, hr);
  183. }
  184. }
  185. if (hr == S_OK)
  186. {
  187. // Need to duplicate the functionality (best to keep the
  188. // memory allocations separate).
  189. // Need to allocate the memory for the structure
  190. pRemoteRrasIpInfo = (REMOTE_RRAS_IPINFO *) CoTaskMemAlloc(sizeof(REMOTE_RRAS_IPINFO));
  191. if (!pRemoteRrasIpInfo)
  192. {
  193. hr = E_OUTOFMEMORY;
  194. goto Error;
  195. }
  196. ::ZeroMemory(pRemoteRrasIpInfo, sizeof(*pRemoteRrasIpInfo));
  197. // Set dhcp
  198. pRemoteRrasIpInfo->dwEnableDhcp = pRemoteIpInfo->dwEnableDhcp;
  199. // pRemoteRrasIpInfo->dwEnableDhcp = FALSE;
  200. // Allocate space for each string and copy the data
  201. // pRemoteRrasIpInfo->bstrIpAddrList =
  202. // SysAllocString(_T("1.2.3.4,1.2.3.5"));
  203. // pRemoteRrasIpInfo->bstrSubnetMaskList =
  204. // SysAllocString(_T("255.0.0.0,255.0.0.0"));
  205. // pRemoteRrasIpInfo->bstrOptionList =
  206. // SysAllocString(_T("12.12.13.15,12.12.13.14"));
  207. pRemoteRrasIpInfo->bstrIpAddrList =
  208. SysAllocString(pRemoteIpInfo->pszwIpAddrList);
  209. if (!pRemoteRrasIpInfo->bstrIpAddrList &&
  210. pRemoteIpInfo->pszwIpAddrList)
  211. {
  212. hr = E_OUTOFMEMORY;
  213. goto Error;
  214. }
  215. pRemoteRrasIpInfo->bstrSubnetMaskList =
  216. SysAllocString(pRemoteIpInfo->pszwSubnetMaskList);
  217. if (!pRemoteRrasIpInfo->bstrSubnetMaskList &&
  218. pRemoteIpInfo->pszwSubnetMaskList)
  219. {
  220. hr = E_OUTOFMEMORY;
  221. goto Error;
  222. }
  223. pRemoteRrasIpInfo->bstrOptionList =
  224. SysAllocString(pRemoteIpInfo->pszwOptionList);
  225. if (!pRemoteRrasIpInfo->bstrOptionList &&
  226. pRemoteIpInfo->pszwOptionList)
  227. {
  228. hr = E_OUTOFMEMORY;
  229. goto Error;
  230. }
  231. }
  232. Error:
  233. if (!SUCCEEDED(hr))
  234. {
  235. if (pRemoteRrasIpInfo)
  236. {
  237. SysFreeString(pRemoteRrasIpInfo->bstrIpAddrList);
  238. SysFreeString(pRemoteRrasIpInfo->bstrSubnetMaskList);
  239. SysFreeString(pRemoteRrasIpInfo->bstrOptionList);
  240. CoTaskMemFree(pRemoteRrasIpInfo);
  241. }
  242. }
  243. else
  244. {
  245. *ppInfo = pRemoteRrasIpInfo;
  246. pRemoteRrasIpInfo = NULL;
  247. }
  248. if (pRemoteIpInfo)
  249. {
  250. CoTaskMemFree(pRemoteIpInfo);
  251. pRemoteIpInfo = NULL;
  252. }
  253. if (pTcpipProperties)
  254. pTcpipProperties->Release();
  255. if (pNetCfg)
  256. {
  257. HrUninitializeAndReleaseINetCfg(FALSE,
  258. pNetCfg,
  259. FALSE /* fHasLock */);
  260. pNetCfg = NULL;
  261. }
  262. TraceResult("CRemCfg::GetIpInfo", hr);
  263. return hr;
  264. }
  265. /*!--------------------------------------------------------------------------
  266. CRemCfg::SetIpInfo
  267. -
  268. Author: TongLu, KennT
  269. ---------------------------------------------------------------------------*/
  270. STDMETHODIMP CRemCfg::SetIpInfo(const GUID *pGuid, REMOTE_RRAS_IPINFO * pIpInfo)
  271. {
  272. // TODO: Add your implementation code here
  273. INetCfg * pNetCfg = NULL;
  274. ITcpipProperties * pTcpipProperties = NULL;
  275. DWORD dwNetwork;
  276. HRESULT hr = S_OK;
  277. CString st;
  278. RemCfgIPEntry * pIpEntry = NULL;
  279. RtrCriticalSection cs(&m_critsec);
  280. TraceSz("CRemCfg::SetIpInfo entered");
  281. if ((pGuid == NULL) || (pIpInfo == NULL))
  282. {
  283. TraceResult("CRemCfg::SetIpInfo", E_INVALIDARG);
  284. return E_INVALIDARG;
  285. }
  286. try
  287. {
  288. st.LoadString(IDS_CLIENT_DESC);
  289. pIpEntry = new RemCfgIPEntry;
  290. pIpEntry->m_newIPInfo.pszwIpAddrList = NULL;
  291. pIpEntry->m_newIPInfo.pszwSubnetMaskList = NULL;
  292. pIpEntry->m_newIPInfo.pszwOptionList = NULL;
  293. }
  294. catch(...)
  295. {
  296. hr = E_OUTOFMEMORY;
  297. };
  298. // Create the INetCfg, we're only reading so we don't
  299. // need to grab the write lock.
  300. if (hr == S_OK)
  301. hr = HrCreateAndInitializeINetCfg(NULL,
  302. &pNetCfg,
  303. TRUE /* fGetWriteLock */,
  304. 500 /* cmsTimeout */,
  305. (LPCTSTR) st /* swzClientDesc */,
  306. NULL /* ppszwClientDesc */);
  307. if (hr == S_OK)
  308. hr = HrGetIpPrivateInterface(pNetCfg, &pTcpipProperties);
  309. if (hr == S_OK)
  310. {
  311. pIpEntry->m_IPGuid = *pGuid;
  312. pIpEntry->m_newIPInfo.dwEnableDhcp = pIpInfo->dwEnableDhcp;
  313. pIpEntry->m_newIPInfo.pszwIpAddrList = StrDupW((LPWSTR) pIpInfo->bstrIpAddrList);
  314. pIpEntry->m_newIPInfo.pszwSubnetMaskList = StrDupW((LPWSTR) pIpInfo->bstrSubnetMaskList);
  315. pIpEntry->m_newIPInfo.pszwOptionList = StrDupW((LPWSTR) pIpInfo->bstrOptionList);
  316. hr = pTcpipProperties->SetIpInfoForAdapter(pGuid, &(pIpEntry->m_newIPInfo));
  317. }
  318. if (hr == S_OK)
  319. {
  320. // Add this to the list of OK IP address changes
  321. s_IPEntryList.Add(pIpEntry);
  322. pIpEntry = NULL;
  323. s_fWriteIPConfig = TRUE;
  324. }
  325. // this now gets done in CommitIPInfo
  326. // if (hr == S_OK)
  327. // hr = pNetCfg->Apply();
  328. //Error:
  329. if (pTcpipProperties)
  330. pTcpipProperties->Release();
  331. if (pIpEntry)
  332. {
  333. delete pIpEntry->m_newIPInfo.pszwIpAddrList;
  334. delete pIpEntry->m_newIPInfo.pszwSubnetMaskList;
  335. delete pIpEntry->m_newIPInfo.pszwOptionList;
  336. delete pIpEntry;
  337. }
  338. if (pNetCfg)
  339. {
  340. HrUninitializeAndReleaseINetCfg(FALSE,
  341. pNetCfg,
  342. TRUE /* fHasLock */);
  343. pNetCfg = NULL;
  344. }
  345. TraceResult("CRemCfg::SetIpInfo", hr);
  346. return hr;
  347. }
  348. //+---------------------------------------------------------------------------
  349. //
  350. // Member: HrCleanRouterManagerEntries
  351. //
  352. // Purpose: Remove all Router Manager entries from the registry.
  353. //
  354. // Arguments:
  355. //
  356. // Returns:
  357. //
  358. // Author: MikeG (a-migall) 6 Nov 1998
  359. //
  360. // Notes:
  361. //
  362. HRESULT
  363. HrCleanRouterManagerEntries()
  364. {
  365. // Open a connection to the registry key so we can "clean"
  366. // the registry entries before an install/update to ensure
  367. // that we can start with a "clean" state.
  368. CRegKey rk;
  369. long lRes = rk.Open(HKEY_LOCAL_MACHINE,
  370. _T("System\\CurrentControlSet\\Services\\RemoteAccess\\RouterManagers"));
  371. Assert(rk.m_hKey != NULL);
  372. HRESULT hr = S_OK;
  373. if (lRes == ERROR_FILE_NOT_FOUND) // if key doesn't exist, exit...
  374. return hr;
  375. if (lRes != ERROR_SUCCESS)
  376. {
  377. hr = HRESULT_FROM_WIN32(lRes);
  378. TraceError ("HrCleanRouterManagerEntries", hr);
  379. return hr;
  380. }
  381. // Eliminate the IP transport subkey.
  382. lRes = rk.DeleteSubKey(_T("Ip"));
  383. if (lRes > ERROR_FILE_NOT_FOUND)
  384. {
  385. hr = HRESULT_FROM_WIN32(lRes);
  386. TraceError ("HrCleanRouterManagerEntries", hr);
  387. return hr;
  388. }
  389. // Eliminate the IPX transport subkey.
  390. lRes = rk.DeleteSubKey(_T("Ipx"));
  391. if (lRes > ERROR_FILE_NOT_FOUND)
  392. hr = HRESULT_FROM_WIN32(lRes);
  393. TraceError ("HrCleanRouterManagerEntries", hr);
  394. return hr;
  395. }
  396. //+---------------------------------------------------------------------------
  397. //
  398. // Member: RecurseDeleteKey
  399. //
  400. // Purpose: Delete a named registry key and all of its subkeys.
  401. //
  402. // Arguments:
  403. //
  404. // Returns:
  405. //
  406. // Author: MikeG (a-migall) 6 Nov 1998
  407. //
  408. // Notes: Shamelessly stolen from Kenn's code in ...\tfscore\tregkey.h.
  409. //
  410. long
  411. RecurseDeleteKey(
  412. IN CRegKey &rk,
  413. IN LPCTSTR lpszKey)
  414. {
  415. Assert(!::IsBadReadPtr(&rk, sizeof(CRegKey)));
  416. Assert(rk.m_hKey != NULL);
  417. Assert(!::IsBadStringPtr(lpszKey, ::lstrlen(lpszKey)));
  418. CRegKey key;
  419. long lRes = key.Open(HKEY(rk), lpszKey);
  420. if (lRes != ERROR_SUCCESS)
  421. return lRes;
  422. FILETIME time;
  423. TCHAR szBuffer[256];
  424. DWORD dwSize = 256;
  425. while (::RegEnumKeyEx(HKEY(key),
  426. 0,
  427. szBuffer,
  428. &dwSize,
  429. NULL,
  430. NULL,
  431. NULL,
  432. &time) == ERROR_SUCCESS)
  433. {
  434. lRes = RecurseDeleteKey(key, szBuffer);
  435. if (lRes != ERROR_SUCCESS)
  436. return lRes;
  437. dwSize = 256;
  438. }
  439. key.Close();
  440. return rk.DeleteSubKey(lpszKey);
  441. }
  442. //+---------------------------------------------------------------------------
  443. //
  444. // Member: HrCleanRouterInterfacesEntries
  445. //
  446. // Purpose: Remove all Router Interface entries from the registry.
  447. //
  448. // Arguments:
  449. //
  450. // Returns:
  451. //
  452. // Author: MikeG (a-migall) 6 Nov 1998
  453. //
  454. // Notes:
  455. //
  456. HRESULT
  457. HrCleanRouterInterfacesEntries()
  458. {
  459. // Open a connection to the registry key so we can "clean" the
  460. // registry entries before an install/update to ensure that we
  461. // can start with a "clean" state.
  462. CRegKey rk;
  463. long lRes = rk.Open(HKEY_LOCAL_MACHINE,
  464. _T("System\\CurrentControlSet\\Services\\RemoteAccess\\Interfaces"));
  465. Assert(rk.m_hKey != NULL);
  466. HRESULT hr = S_OK;
  467. if (lRes == ERROR_FILE_NOT_FOUND) // if key doesn't exist, exit...
  468. return hr;
  469. if (lRes != ERROR_SUCCESS)
  470. {
  471. hr = HRESULT_FROM_WIN32(lRes);
  472. TraceError ("HrCleanRouterInterfacesEntries", hr);
  473. return hr;
  474. }
  475. // Determine how many interfaces have been defined.
  476. DWORD dwSubKeyCnt = 0;
  477. lRes = ::RegQueryInfoKey(HKEY(rk), // handle to key to query
  478. NULL, // address of buffer for class string
  479. NULL, // address of size of class string buffer
  480. NULL, // reserved...
  481. &dwSubKeyCnt, // address of buffer for number of subkeys
  482. NULL, // address of buffer for longest subkey name length
  483. NULL, // address of buffer for longest class string length
  484. NULL, // address of buffer for number of value entries
  485. NULL, // address of buffer for longest value name length
  486. NULL, // address of buffer for longest value data length
  487. NULL, // address of buffer for security descriptor length
  488. NULL); // address of buffer for last write time
  489. if (lRes != ERROR_SUCCESS)
  490. {
  491. hr = HRESULT_FROM_WIN32(lRes);
  492. TraceError ("HrCleanRouterInterfacesEntries", hr);
  493. return hr;
  494. }
  495. // Eliminate each of the subkeys.
  496. CString st;
  497. DWORD dwStrSize = 256;
  498. LPTSTR pszKeyName = st.GetBuffer(dwStrSize);
  499. // while (dwSubKeyCnt >= 0)
  500. while (TRUE) // change from above to TRUE, and lRes from the API will cause loop to end
  501. {
  502. // Get the name of the subkey to be deleted.
  503. lRes = ::RegEnumKeyEx(HKEY(rk), // handle to key to enumerate
  504. --dwSubKeyCnt, // index of subkey to enumerate
  505. pszKeyName, // address of buffer for subkey name
  506. &dwStrSize, // address for size of subkey buffer
  507. NULL, // reserved...
  508. NULL, // address of buffer for class string
  509. NULL, // address for size of class buffer
  510. NULL); // address for time key last written to
  511. if (lRes != ERROR_SUCCESS)
  512. {
  513. if ((lRes == ERROR_FILE_NOT_FOUND) ||
  514. (lRes == ERROR_NO_MORE_ITEMS))
  515. {
  516. lRes = 0; // we've run out of keys; so, we can successfuly exit.
  517. }
  518. break;
  519. }
  520. // Delete the key and all of its children.
  521. lRes = RecurseDeleteKey(rk, pszKeyName);
  522. if (lRes > ERROR_FILE_NOT_FOUND)
  523. break;
  524. // Cleanup for next pass.
  525. dwStrSize = 256;
  526. ::ZeroMemory(pszKeyName, (dwStrSize*sizeof(TCHAR)));
  527. }
  528. st.ReleaseBuffer();
  529. hr = HRESULT_FROM_WIN32(lRes);
  530. TraceError ("HrCleanRouterInterfacesEntries", hr);
  531. return hr;
  532. }
  533. STDMETHODIMP CRemCfg::UpgradeRouterConfig()
  534. {
  535. HRESULT hr = S_OK;
  536. INetCfg * pNetCfg = NULL;
  537. TraceSz("CRemCfg::UpgradeRouterConfig entered");
  538. try
  539. {
  540. // This is a two-step process
  541. CSteelhead update;
  542. CString st;
  543. st.LoadString(IDS_CLIENT_DESC);
  544. // First get the INetCfg
  545. hr = HrCreateAndInitializeINetCfg(NULL, /* &fInitCom, */
  546. &pNetCfg,
  547. FALSE /* fGetWriteLock */,
  548. 500 /* cmsTimeout */,
  549. (LPCTSTR) st /* swzClientDesc */,
  550. NULL /* ppszwClientDesc */);
  551. if (hr == S_OK)
  552. {
  553. update.Initialize(pNetCfg);
  554. hr = update.HrFindOtherComponents();
  555. }
  556. if (hr == S_OK)
  557. {
  558. // Delete all previous router configs so we can get back
  559. // to a "clean" install point.
  560. hr = HrCleanRouterManagerEntries();
  561. Assert(SUCCEEDED(hr));
  562. hr = HrCleanRouterInterfacesEntries();
  563. Assert(SUCCEEDED(hr));
  564. // Now create the router config info.
  565. hr = update.HrUpdateRouterConfiguration();
  566. Assert(SUCCEEDED(hr));
  567. update.ReleaseOtherComponents();
  568. RegFlushKey(HKEY_LOCAL_MACHINE);
  569. }
  570. }
  571. catch(...)
  572. {
  573. hr = E_FAIL;
  574. }
  575. if (pNetCfg)
  576. {
  577. HrUninitializeAndReleaseINetCfg(FALSE, /* fInitCom, */
  578. pNetCfg,
  579. FALSE /* fHasLock */);
  580. pNetCfg = NULL;
  581. }
  582. TraceResult("CRemCfg::UpgradeRouterConfig", hr);
  583. return hr;
  584. }
  585. STDMETHODIMP CRemCfg::SetUserConfig(LPCOLESTR pszService,
  586. LPCOLESTR pszNewGroup)
  587. {
  588. DWORD err;
  589. HRESULT hr = S_OK;
  590. try
  591. {
  592. err = SvchostChangeSvchostGroup(pszService, pszNewGroup);
  593. hr = HRESULT_FROM_WIN32(err);
  594. }
  595. catch(...)
  596. {
  597. hr = E_OUTOFMEMORY;
  598. }
  599. TraceResult("CRemCfg::SetUserConfig", hr);
  600. return hr;
  601. }
  602. /*!--------------------------------------------------------------------------
  603. CRemCfg::RestartRouter
  604. Implementation of IRemoteRouterRestart::RestartRouter
  605. Author: KennT
  606. ---------------------------------------------------------------------------*/
  607. STDMETHODIMP CRemCfg::RestartRouter(DWORD dwFlags)
  608. {
  609. HRESULT hr = S_OK;
  610. try
  611. {
  612. // the router will be restarted when remrras.exe shuts down
  613. // ------------------------------------------------------------
  614. s_fRestartRouter = TRUE;
  615. }
  616. catch(...)
  617. {
  618. hr = E_OUTOFMEMORY;
  619. }
  620. return hr;
  621. }
  622. HRESULT CommitIPInfo()
  623. {
  624. // TODO: Add your implementation code here
  625. INetCfg * pNetCfg = NULL;
  626. ITcpipProperties * pTcpipProperties = NULL;
  627. DWORD dwNetwork;
  628. HRESULT hr = S_OK;
  629. CString st;
  630. WCHAR swzGuid[256];
  631. TraceSz("CRemCfg::CommitIpInfo entered");
  632. try
  633. {
  634. st.LoadString(IDS_CLIENT_DESC);
  635. }
  636. catch(...)
  637. {
  638. hr = E_OUTOFMEMORY;
  639. };
  640. // Create the INetCfg, we're only reading so we don't
  641. // need to grab the write lock.
  642. if (hr == S_OK)
  643. hr = HrCreateAndInitializeINetCfg(NULL,
  644. &pNetCfg,
  645. TRUE /* fGetWriteLock */,
  646. 500 /* cmsTimeout */,
  647. (LPCTSTR) st /* swzClientDesc */,
  648. NULL /* ppszwClientDesc */);
  649. if (hr == S_OK)
  650. hr = HrGetIpPrivateInterface(pNetCfg, &pTcpipProperties);
  651. if (hr == S_OK)
  652. {
  653. RemCfgIPEntry * pIpEntry = NULL;
  654. for (int i=0; i<s_IPEntryList.GetSize(); i++)
  655. {
  656. pIpEntry = s_IPEntryList[i];
  657. hr = pTcpipProperties->SetIpInfoForAdapter(
  658. &(pIpEntry->m_IPGuid),
  659. &(pIpEntry->m_newIPInfo));
  660. StringFromGUID2(pIpEntry->m_IPGuid,
  661. swzGuid, 128);
  662. TracePrintf(g_dwTraceHandle,
  663. _T("Setting IP info for %ls returned 0x%08lx"),
  664. swzGuid, hr);
  665. TracePrintf(g_dwTraceHandle,
  666. _T("DHCP Enabled : %d"),
  667. pIpEntry->m_newIPInfo.dwEnableDhcp);
  668. if (pIpEntry->m_newIPInfo.pszwIpAddrList)
  669. TracePrintf(g_dwTraceHandle,
  670. _T(" IP Address : %ls"),
  671. pIpEntry->m_newIPInfo.pszwIpAddrList);
  672. if (pIpEntry->m_newIPInfo.pszwSubnetMaskList)
  673. TracePrintf(g_dwTraceHandle,
  674. _T(" Subnet masks : %ls"),
  675. pIpEntry->m_newIPInfo.pszwSubnetMaskList);
  676. if (pIpEntry->m_newIPInfo.pszwOptionList)
  677. TracePrintf(g_dwTraceHandle,
  678. _T(" Gateway List : %ls"),
  679. pIpEntry->m_newIPInfo.pszwOptionList);
  680. }
  681. }
  682. if (hr == S_OK)
  683. {
  684. hr = pNetCfg->Apply();
  685. TraceResult("CRemCfg::CommitIpInfo calling Apply", hr);
  686. }
  687. if (hr == S_OK)
  688. {
  689. // Release all memory
  690. for (int i=0; i<s_IPEntryList.GetSize(); i++)
  691. {
  692. RemCfgIPEntry * pIpEntry = s_IPEntryList[i];
  693. delete pIpEntry->m_newIPInfo.pszwIpAddrList;
  694. delete pIpEntry->m_newIPInfo.pszwSubnetMaskList;
  695. delete pIpEntry->m_newIPInfo.pszwOptionList;
  696. delete pIpEntry;
  697. }
  698. s_IPEntryList.RemoveAll();
  699. s_fWriteIPConfig = FALSE;
  700. }
  701. //Error:
  702. if (pTcpipProperties)
  703. pTcpipProperties->Release();
  704. if (pNetCfg)
  705. {
  706. HrUninitializeAndReleaseINetCfg(FALSE,
  707. pNetCfg,
  708. TRUE /* fHasLock */);
  709. pNetCfg = NULL;
  710. }
  711. TraceResult("CRemCfg::CommitIpInfo", hr);
  712. return hr;
  713. }
  714. /*!--------------------------------------------------------------------------
  715. HrGetIpxPrivateInterface
  716. -
  717. Author: ScottBri, KennT
  718. ---------------------------------------------------------------------------*/
  719. HRESULT HrGetIpxPrivateInterface(INetCfg* pNetCfg,
  720. IIpxAdapterInfo** ppIpxAdapterInfo)
  721. {
  722. HRESULT hr;
  723. INetCfgClass* pncclass = NULL;
  724. if ((pNetCfg == NULL) || (ppIpxAdapterInfo == NULL))
  725. return E_INVALIDARG;
  726. hr = pNetCfg->QueryNetCfgClass (&GUID_DEVCLASS_NETTRANS, IID_INetCfgClass,
  727. reinterpret_cast<void**>(&pncclass));
  728. if (SUCCEEDED(hr))
  729. {
  730. INetCfgComponent * pnccItem = NULL;
  731. // Find the component.
  732. hr = pncclass->FindComponent(TEXT("MS_NWIPX"), &pnccItem);
  733. //AssertSz (SUCCEEDED(hr), "pncclass->Find failed.");
  734. if (S_OK == hr)
  735. {
  736. INetCfgComponentPrivate* pinccp = NULL;
  737. hr = pnccItem->QueryInterface(IID_INetCfgComponentPrivate,
  738. reinterpret_cast<void**>(&pinccp));
  739. if (SUCCEEDED(hr))
  740. {
  741. hr = pinccp->QueryNotifyObject(IID_IIpxAdapterInfo,
  742. reinterpret_cast<void**>(ppIpxAdapterInfo));
  743. pinccp->Release();
  744. }
  745. }
  746. if (pnccItem)
  747. pnccItem->Release();
  748. }
  749. if (pncclass)
  750. pncclass->Release();
  751. // S_OK indicates success (interface returned)
  752. // S_FALSE indicates Ipx not installed
  753. // other values are errors
  754. TraceResult("HrGetIpxPrivateInterface", hr);
  755. return hr;
  756. }
  757. /*!--------------------------------------------------------------------------
  758. HrGetIpPrivateInterface
  759. -
  760. Author: TongLu, KennT
  761. ---------------------------------------------------------------------------*/
  762. HRESULT HrGetIpPrivateInterface(INetCfg* pNetCfg,
  763. ITcpipProperties **ppTcpProperties)
  764. {
  765. HRESULT hr;
  766. INetCfgClass* pncclass = NULL;
  767. if ((pNetCfg == NULL) || (ppTcpProperties == NULL))
  768. return E_INVALIDARG;
  769. hr = pNetCfg->QueryNetCfgClass (&GUID_DEVCLASS_NETTRANS, IID_INetCfgClass,
  770. reinterpret_cast<void**>(&pncclass));
  771. if (SUCCEEDED(hr))
  772. {
  773. INetCfgComponent * pnccItem = NULL;
  774. // Find the component.
  775. hr = pncclass->FindComponent(TEXT("MS_TCPIP"), &pnccItem);
  776. //AssertSz (SUCCEEDED(hr), "pncclass->Find failed.");
  777. if (S_OK == hr)
  778. {
  779. INetCfgComponentPrivate* pinccp = NULL;
  780. hr = pnccItem->QueryInterface(IID_INetCfgComponentPrivate,
  781. reinterpret_cast<void**>(&pinccp));
  782. if (SUCCEEDED(hr))
  783. {
  784. hr = pinccp->QueryNotifyObject(IID_ITcpipProperties,
  785. reinterpret_cast<void**>(ppTcpProperties));
  786. pinccp->Release();
  787. }
  788. }
  789. if (pnccItem)
  790. pnccItem->Release();
  791. }
  792. if (pncclass)
  793. pncclass->Release();
  794. // S_OK indicates success (interface returned)
  795. // S_FALSE indicates Ipx not installed
  796. // other values are errors
  797. TraceResult("HrGetIpPrivateInterface", hr);
  798. return hr;
  799. }
  800. //+---------------------------------------------------------------------------
  801. //
  802. // Function: HrCreateAndInitializeINetCfg
  803. //
  804. // Purpose: Cocreate and initialize the root INetCfg object. This will
  805. // optionally initialize COM for the caller too.
  806. //
  807. // Arguments:
  808. // pfInitCom [in,out] TRUE to call CoInitialize before creating.
  809. // returns TRUE if COM was successfully
  810. // initialized FALSE if not. If NULL, means
  811. // don't initialize COM.
  812. // ppnc [out] The returned INetCfg object.
  813. // fGetWriteLock [in] TRUE if a writable INetCfg is needed
  814. // cmsTimeout [in] See INetCfg::LockForWrite
  815. // szwClientDesc [in] See INetCfg::LockForWrite
  816. // ppszwClientDesc [out] See INetCfg::LockForWrite
  817. //
  818. // Returns: S_OK or an error code.
  819. //
  820. // Author: shaunco 7 May 1997
  821. //
  822. // Notes:
  823. //
  824. HRESULT
  825. HrCreateAndInitializeINetCfg (
  826. BOOL* pfInitCom,
  827. INetCfg** ppnc,
  828. BOOL fGetWriteLock,
  829. DWORD cmsTimeout,
  830. LPCWSTR szwClientDesc,
  831. LPWSTR * ppszwClientDesc)
  832. {
  833. // ASSERT (ppnc);
  834. // Initialize the output parameter.
  835. *ppnc = NULL;
  836. if (ppszwClientDesc)
  837. *ppszwClientDesc = NULL;
  838. // Initialize COM if the caller requested.
  839. HRESULT hr = S_OK;
  840. if (pfInitCom && *pfInitCom)
  841. {
  842. hr = CoInitializeEx( NULL,
  843. COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED );
  844. if (RPC_E_CHANGED_MODE == hr)
  845. {
  846. hr = S_OK;
  847. if (pfInitCom)
  848. {
  849. *pfInitCom = FALSE;
  850. }
  851. }
  852. }
  853. if (SUCCEEDED(hr))
  854. {
  855. // Create the object implementing INetCfg.
  856. //
  857. INetCfg* pnc;
  858. hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER,
  859. IID_INetCfg, reinterpret_cast<void**>(&pnc));
  860. TraceResult("HrCreateAndInitializeINetCfg - CoCreateInstance(CLSID_CNetCfg)", hr);
  861. if (SUCCEEDED(hr))
  862. {
  863. INetCfgLock * pnclock = NULL;
  864. if (fGetWriteLock)
  865. {
  866. // Get the locking interface
  867. hr = pnc->QueryInterface(IID_INetCfgLock,
  868. reinterpret_cast<LPVOID *>(&pnclock));
  869. TraceResult("HrCreateAndInitializeINetCfg - QueryInterface(IID_INetCfgLock", hr);
  870. if (SUCCEEDED(hr))
  871. {
  872. // Attempt to lock the INetCfg for read/write
  873. hr = pnclock->AcquireWriteLock(cmsTimeout, szwClientDesc,
  874. ppszwClientDesc);
  875. TraceResult("HrCreateAndInitializeINetCfg - INetCfgLock::LockForWrite", hr);
  876. if (S_FALSE == hr)
  877. {
  878. // Couldn't acquire the lock
  879. hr = NETCFG_E_NO_WRITE_LOCK;
  880. }
  881. }
  882. }
  883. if (SUCCEEDED(hr))
  884. {
  885. // Initialize the INetCfg object.
  886. //
  887. hr = pnc->Initialize (NULL);
  888. TraceResult("HrCreateAndInitializeINetCfg - Initialize", hr);
  889. if (SUCCEEDED(hr))
  890. {
  891. *ppnc = pnc;
  892. if (pnc)
  893. pnc->AddRef();
  894. }
  895. else
  896. {
  897. if (pnclock)
  898. {
  899. pnclock->ReleaseWriteLock();
  900. }
  901. }
  902. // Transfer reference to caller.
  903. }
  904. ReleaseObj(pnclock);
  905. pnclock = NULL;
  906. ReleaseObj(pnc);
  907. pnc = NULL;
  908. }
  909. // If we failed anything above, and we've initialized COM,
  910. // be sure an uninitialize it.
  911. //
  912. if (FAILED(hr) && pfInitCom && *pfInitCom)
  913. {
  914. CoUninitialize ();
  915. }
  916. }
  917. TraceResult("HrCreateAndInitializeINetCfg", hr);
  918. return hr;
  919. }
  920. //+---------------------------------------------------------------------------
  921. //
  922. // Function: HrUninitializeAndReleaseINetCfg
  923. //
  924. // Purpose: Unintialize and release an INetCfg object. This will
  925. // optionally uninitialize COM for the caller too.
  926. //
  927. // Arguments:
  928. // fUninitCom [in] TRUE to uninitialize COM after the INetCfg is
  929. // uninitialized and released.
  930. // pnc [in] The INetCfg object.
  931. // fHasLock [in] TRUE if the INetCfg was locked for write and
  932. // must be unlocked.
  933. //
  934. // Returns: S_OK or an error code.
  935. //
  936. // Author: shaunco 7 May 1997
  937. //
  938. // Notes: The return value is the value returned from
  939. // INetCfg::Uninitialize. Even if this fails, the INetCfg
  940. // is still released. Therefore, the return value is for
  941. // informational purposes only. You can't touch the INetCfg
  942. // object after this call returns.
  943. //
  944. HRESULT
  945. HrUninitializeAndReleaseINetCfg (
  946. BOOL fUninitCom,
  947. INetCfg* pnc,
  948. BOOL fHasLock)
  949. {
  950. // Assert (pnc);
  951. HRESULT hr = S_OK;
  952. if (fHasLock)
  953. {
  954. hr = HrUninitializeAndUnlockINetCfg(pnc);
  955. }
  956. else
  957. {
  958. hr = pnc->Uninitialize ();
  959. }
  960. ReleaseObj (pnc);
  961. pnc = NULL;
  962. if (fUninitCom)
  963. {
  964. CoUninitialize ();
  965. }
  966. TraceResult("HrUninitializeAndReleaseINetCfg", hr);
  967. return hr;
  968. }
  969. //+---------------------------------------------------------------------------
  970. //
  971. // Function: HrUninitializeAndUnlockINetCfg
  972. //
  973. // Purpose: Uninitializes and unlocks the INetCfg object
  974. //
  975. // Arguments:
  976. // pnc [in] INetCfg to uninitialize and unlock
  977. //
  978. // Returns: S_OK if success, OLE or Win32 error otherwise
  979. //
  980. // Author: danielwe 13 Nov 1997
  981. //
  982. // Notes:
  983. //
  984. HRESULT
  985. HrUninitializeAndUnlockINetCfg (
  986. INetCfg* pnc)
  987. {
  988. HRESULT hr = S_OK;
  989. hr = pnc->Uninitialize();
  990. if (SUCCEEDED(hr))
  991. {
  992. INetCfgLock * pnclock;
  993. // Get the locking interface
  994. hr = pnc->QueryInterface(IID_INetCfgLock,
  995. reinterpret_cast<LPVOID *>(&pnclock));
  996. if (SUCCEEDED(hr))
  997. {
  998. // Attempt to lock the INetCfg for read/write
  999. hr = pnclock->ReleaseWriteLock();
  1000. ReleaseObj(pnclock);
  1001. pnclock = NULL;
  1002. }
  1003. }
  1004. TraceResult("HrUninitializeAndUnlockINetCfg", hr);
  1005. return hr;
  1006. }