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.

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