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.

572 lines
13 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2000.
  5. //
  6. // File: B I N D C F G . C P P
  7. //
  8. // Contents: Exposes control for creating and removing RAS bindings.
  9. //
  10. // Notes: The exported methods are called by RAS when endpoints
  11. // need to be created or removed for the purpose of making
  12. // calls.
  13. //
  14. // Author: shaunco 16 Oct 1998
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "pch.h"
  18. #pragma hdrstop
  19. #include "ncnetcfg.h"
  20. #include "ncutil.h"
  21. #include "netcfgn.h"
  22. #include <rasapip.h>
  23. extern const WCHAR c_szInfId_MS_NdisWanIp[];
  24. extern const WCHAR c_szInfId_MS_NdisWanNbfIn[];
  25. extern const WCHAR c_szInfId_MS_NdisWanNbfOut[];
  26. extern const WCHAR c_szInfId_MS_NetBEUI[];
  27. extern const WCHAR c_szInfId_MS_TCPIP[];
  28. class CRasBindingConfig
  29. {
  30. public:
  31. INetCfg* m_pNetCfg;
  32. BOOL m_fInitCom;
  33. enum NEEDED_COMPONENTS
  34. {
  35. INDEX_IP = 0,
  36. INDEX_NBF,
  37. INDEX_IPADAPTER,
  38. COUNT_COMPONENTS,
  39. };
  40. INetCfgComponent* m_apComponents [COUNT_COMPONENTS];
  41. public:
  42. #if DBG
  43. CRasBindingConfig ()
  44. {
  45. m_pNetCfg = NULL;
  46. }
  47. ~CRasBindingConfig ()
  48. {
  49. AssertH (!m_pNetCfg);
  50. }
  51. #endif
  52. public:
  53. HRESULT
  54. HrAddOrRemoveBindings (
  55. IN DWORD dwFlags,
  56. IN OUT UINT* pcIpOut,
  57. IN const GUID* pguidIpOutBindings,
  58. IN OUT UINT* pcNbfIn,
  59. IN OUT UINT* pcNbfOut);
  60. HRESULT
  61. HrCountBindings (
  62. OUT UINT* pcIpOut,
  63. OUT UINT* pcNbfIn,
  64. OUT UINT* pcNbfOut);
  65. HRESULT
  66. HrLoadINetCfg (
  67. IN REGSAM samDesired);
  68. HRESULT
  69. HrLoadINetCfgAndAddOrRemoveBindings (
  70. IN DWORD dwFlags,
  71. IN OUT UINT* pcIpOut,
  72. IN const GUID* pguidIpOutBindings,
  73. IN OUT UINT* pcNbfIn,
  74. IN OUT UINT* pcNbfOut);
  75. VOID
  76. UnloadINetCfg ();
  77. INetCfgComponent*
  78. PnccIp ()
  79. {
  80. AssertH (m_pNetCfg);
  81. return m_apComponents [INDEX_IP];
  82. }
  83. INetCfgComponent*
  84. PnccIpAdapter ()
  85. {
  86. AssertH (m_pNetCfg);
  87. return m_apComponents [INDEX_IPADAPTER];
  88. }
  89. INetCfgComponent*
  90. PnccNbf ()
  91. {
  92. AssertH (m_pNetCfg);
  93. return m_apComponents [INDEX_NBF];
  94. }
  95. };
  96. HRESULT
  97. CRasBindingConfig::HrCountBindings (
  98. UINT* pcIpOut,
  99. UINT* pcNbfIn,
  100. UINT* pcNbfOut)
  101. {
  102. Assert (pcIpOut);
  103. Assert (pcNbfIn);
  104. Assert (pcNbfOut);
  105. HRESULT hr = S_OK;
  106. // Initialize output parameters.
  107. //
  108. *pcIpOut = *pcNbfIn = *pcNbfOut = 0;
  109. if (PnccIp() && PnccIpAdapter())
  110. {
  111. INetCfgComponentUpperEdge* pUpperEdge;
  112. hr = HrQueryNotifyObject (
  113. PnccIp(),
  114. IID_INetCfgComponentUpperEdge,
  115. reinterpret_cast<VOID**>(&pUpperEdge));
  116. if (SUCCEEDED(hr))
  117. {
  118. DWORD dwNumInterfaces;
  119. GUID* pguidInterfaceIds;
  120. hr = pUpperEdge->GetInterfaceIdsForAdapter (
  121. PnccIpAdapter(),
  122. &dwNumInterfaces,
  123. &pguidInterfaceIds);
  124. if (SUCCEEDED(hr))
  125. {
  126. *pcIpOut = dwNumInterfaces;
  127. CoTaskMemFree (pguidInterfaceIds);
  128. }
  129. ReleaseObj (pUpperEdge);
  130. }
  131. }
  132. if (PnccNbf())
  133. {
  134. // Iterate adapters in the system.
  135. //
  136. CIterNetCfgComponent nccIter(m_pNetCfg, &GUID_DEVCLASS_NET);
  137. INetCfgComponent* pnccAdapter;
  138. while (S_OK == (hr = nccIter.HrNext (&pnccAdapter)))
  139. {
  140. // Quickly discard non-hidden adapters to avoid unneccesary
  141. // string compares.
  142. //
  143. DWORD dwCharacter;
  144. if ( SUCCEEDED(pnccAdapter->GetCharacteristics (&dwCharacter))
  145. && (dwCharacter & NCF_HIDDEN))
  146. {
  147. PWSTR pszId;
  148. if (SUCCEEDED(pnccAdapter->GetId (&pszId)))
  149. {
  150. if (FEqualComponentId (c_szInfId_MS_NdisWanNbfIn,
  151. pszId))
  152. {
  153. (*pcNbfIn)++;
  154. }
  155. else if (FEqualComponentId (c_szInfId_MS_NdisWanNbfOut,
  156. pszId))
  157. {
  158. (*pcNbfOut)++;
  159. }
  160. CoTaskMemFree (pszId);
  161. }
  162. }
  163. ReleaseObj (pnccAdapter);
  164. }
  165. }
  166. TraceTag (ttidRasCfg,
  167. "Current RAS bindings: "
  168. "%u IP dial-out, %u NBF dial-in, %u NBF dial-out",
  169. *pcIpOut, *pcNbfIn, *pcNbfOut);
  170. // Normalize the HRESULT. (i.e. don't return S_FALSE)
  171. if (SUCCEEDED(hr))
  172. {
  173. hr = S_OK;
  174. }
  175. TraceHr (ttidError, FAL, hr, FALSE,
  176. "CRasBindingConfig::HrCountBindings");
  177. return hr;
  178. }
  179. HRESULT
  180. CRasBindingConfig::HrAddOrRemoveBindings (
  181. IN DWORD dwFlags,
  182. IN OUT UINT* pcIpOut,
  183. IN const GUID* pguidIpOutBindings,
  184. IN OUT UINT* pcNbfIn,
  185. IN OUT UINT* pcNbfOut)
  186. {
  187. HRESULT hr = S_OK;
  188. // Safe off the input parameters.
  189. //
  190. UINT cIpOut = *pcIpOut;
  191. UINT cNbfIn = *pcNbfIn;
  192. UINT cNbfOut = *pcNbfOut;
  193. if (cIpOut && PnccIp() && PnccIpAdapter())
  194. {
  195. INetCfgComponentUpperEdge* pUpperEdge;
  196. hr = HrQueryNotifyObject (
  197. PnccIp(),
  198. IID_INetCfgComponentUpperEdge,
  199. reinterpret_cast<VOID**>(&pUpperEdge));
  200. if (SUCCEEDED(hr))
  201. {
  202. if (dwFlags & ARA_ADD)
  203. {
  204. TraceTag (ttidRasCfg,
  205. "Adding %d TCP/IP interfaces to the ndiswanip adapter",
  206. cIpOut);
  207. hr = pUpperEdge->AddInterfacesToAdapter (
  208. PnccIpAdapter(),
  209. cIpOut);
  210. }
  211. else
  212. {
  213. TraceTag (ttidRasCfg,
  214. "Removing %d TCP/IP interfaces from the ndiswanip adapter",
  215. cIpOut);
  216. hr = pUpperEdge->RemoveInterfacesFromAdapter (
  217. PnccIpAdapter(),
  218. cIpOut,
  219. pguidIpOutBindings);
  220. }
  221. ReleaseObj (pUpperEdge);
  222. }
  223. }
  224. if (PnccNbf() && SUCCEEDED(hr))
  225. {
  226. if (cNbfIn)
  227. {
  228. TraceTag (ttidRasCfg,
  229. "%s %d %S adapters",
  230. (dwFlags & ARA_ADD) ? "Adding" : "Removing",
  231. cNbfIn,
  232. c_szInfId_MS_NdisWanNbfIn);
  233. hr = HrAddOrRemoveAdapter (
  234. m_pNetCfg,
  235. c_szInfId_MS_NdisWanNbfIn,
  236. dwFlags, NULL, cNbfIn, NULL);
  237. }
  238. if (cNbfOut && SUCCEEDED(hr))
  239. {
  240. TraceTag (ttidRasCfg,
  241. "%s %d %S adapters",
  242. (dwFlags & ARA_ADD) ? "Adding" : "Removing",
  243. cNbfOut,
  244. c_szInfId_MS_NdisWanNbfOut);
  245. hr = HrAddOrRemoveAdapter (
  246. m_pNetCfg,
  247. c_szInfId_MS_NdisWanNbfOut,
  248. dwFlags, NULL, cNbfOut, NULL);
  249. }
  250. }
  251. HRESULT hrT = HrCountBindings(pcIpOut, pcNbfIn, pcNbfOut);
  252. if (SUCCEEDED(hr))
  253. {
  254. hr = hrT;
  255. }
  256. TraceHr (ttidError, FAL, hr, FALSE,
  257. "CRasBindingConfig::HrAddOrRemoveBindings");
  258. return hr;
  259. }
  260. HRESULT
  261. CRasBindingConfig::HrLoadINetCfg (
  262. IN REGSAM samDesired)
  263. {
  264. HRESULT hr;
  265. Assert (!m_pNetCfg);
  266. // Get INetCfg and lock it for write.
  267. //
  268. m_fInitCom = TRUE;
  269. hr = HrCreateAndInitializeINetCfg (
  270. &m_fInitCom,
  271. &m_pNetCfg,
  272. (KEY_WRITE == samDesired), // get the write lock if needed
  273. 0, // don't wait for it
  274. L"RAS Binding Configuration",
  275. NULL);
  276. if (SUCCEEDED(hr))
  277. {
  278. ZeroMemory (m_apComponents, sizeof(m_apComponents));
  279. // Find the following components and hold on to their INetCfgComponent
  280. // interface pointers in m_apComponents. UnloadINetCfg will release
  281. // these. HrFindComponents will zero the array so it is safe to
  282. // call UnloadINetCfg if HrFindComponents fails.
  283. //
  284. const GUID* c_apguidComponentClasses [COUNT_COMPONENTS] =
  285. {
  286. &GUID_DEVCLASS_NETTRANS, // Ip
  287. &GUID_DEVCLASS_NETTRANS, // NetBEUI
  288. &GUID_DEVCLASS_NET, // IpAdapter
  289. };
  290. const PCWSTR c_apszComponentIds [COUNT_COMPONENTS] =
  291. {
  292. c_szInfId_MS_TCPIP,
  293. c_szInfId_MS_NetBEUI,
  294. c_szInfId_MS_NdisWanIp,
  295. };
  296. if (SUCCEEDED(hr))
  297. {
  298. hr = HrFindComponents (
  299. m_pNetCfg,
  300. COUNT_COMPONENTS,
  301. c_apguidComponentClasses,
  302. c_apszComponentIds,
  303. m_apComponents);
  304. }
  305. if (FAILED(hr))
  306. {
  307. // If we have a failure while trying to find these components
  308. // we're going to fail this method call, so be sure to cleanup
  309. // m_pNetCfg.
  310. //
  311. UnloadINetCfg ();
  312. Assert (!m_pNetCfg);
  313. }
  314. }
  315. TraceHr (ttidError, FAL, hr, FALSE,
  316. "CRasBindingConfig::HrLoadINetCfg");
  317. return hr;
  318. }
  319. HRESULT
  320. CRasBindingConfig::HrLoadINetCfgAndAddOrRemoveBindings (
  321. IN DWORD dwFlags,
  322. IN OUT UINT* pcIpOut,
  323. IN const GUID* pguidIpOutBindings,
  324. IN OUT UINT* pcNbfIn,
  325. IN OUT UINT* pcNbfOut)
  326. {
  327. Assert (!m_pNetCfg);
  328. HRESULT hr;
  329. hr = HrLoadINetCfg (KEY_WRITE);
  330. if (SUCCEEDED(hr))
  331. {
  332. __try
  333. {
  334. hr = HrAddOrRemoveBindings (
  335. dwFlags,
  336. pcIpOut,
  337. pguidIpOutBindings,
  338. pcNbfIn,
  339. pcNbfOut);
  340. if (SUCCEEDED(hr))
  341. {
  342. (VOID) m_pNetCfg->Apply();
  343. }
  344. else
  345. {
  346. (VOID) m_pNetCfg->Cancel();
  347. }
  348. }
  349. __finally
  350. {
  351. UnloadINetCfg ();
  352. }
  353. }
  354. // We shouldn't ever leave with an un-released INetCfg.
  355. //
  356. Assert (!m_pNetCfg);
  357. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  358. "CRasBindingConfig::HrLoadINetCfgAndAddOrRemoveBindings");
  359. return hr;
  360. }
  361. VOID
  362. CRasBindingConfig::UnloadINetCfg ()
  363. {
  364. // Must call HrLoadINetCfg before calling this.
  365. //
  366. Assert (m_pNetCfg);
  367. ReleaseIUnknownArray (COUNT_COMPONENTS, (IUnknown**)m_apComponents);
  368. (VOID) HrUninitializeAndReleaseINetCfg (m_fInitCom, m_pNetCfg, TRUE);
  369. m_pNetCfg = NULL;
  370. }
  371. //+---------------------------------------------------------------------------
  372. // Exported functions
  373. //
  374. EXTERN_C
  375. HRESULT
  376. WINAPI
  377. RasAddBindings (
  378. IN OUT UINT* pcIpOut,
  379. IN OUT UINT* pcNbfIn,
  380. IN OUT UINT* pcNbfOut)
  381. {
  382. HRESULT hr;
  383. #if 0
  384. RtlValidateProcessHeaps ();
  385. #endif
  386. // Validate parameters.
  387. //
  388. if (!pcIpOut || !pcNbfIn || !pcNbfOut)
  389. {
  390. hr = E_POINTER;
  391. }
  392. else if (!*pcIpOut && !*pcNbfIn && !*pcNbfOut)
  393. {
  394. hr = E_INVALIDARG;
  395. }
  396. else
  397. {
  398. CRasBindingConfig Config;
  399. hr = Config.HrLoadINetCfgAndAddOrRemoveBindings (
  400. ARA_ADD,
  401. pcIpOut,
  402. NULL,
  403. pcNbfIn,
  404. pcNbfOut);
  405. }
  406. TraceHr (ttidError, FAL, hr, FALSE,
  407. "CRasBindingConfig::RasAddBindings");
  408. return hr;
  409. }
  410. EXTERN_C
  411. HRESULT
  412. WINAPI
  413. RasCountBindings (
  414. OUT UINT* pcIpOut,
  415. OUT UINT* pcNbfIn,
  416. OUT UINT* pcNbfOut)
  417. {
  418. HRESULT hr;
  419. #if 0
  420. RtlValidateProcessHeaps ();
  421. #endif
  422. // Validate parameters.
  423. //
  424. if (!pcIpOut || !pcNbfIn || !pcNbfOut)
  425. {
  426. hr = E_POINTER;
  427. }
  428. else
  429. {
  430. CRasBindingConfig Config;
  431. hr = Config.HrLoadINetCfg (KEY_READ);
  432. if (SUCCEEDED(hr))
  433. {
  434. __try
  435. {
  436. hr = Config.HrCountBindings (
  437. pcIpOut,
  438. pcNbfIn,
  439. pcNbfOut);
  440. }
  441. __finally
  442. {
  443. Config.UnloadINetCfg ();
  444. }
  445. }
  446. // We shouldn't ever leave with an un-released INetCfg.
  447. //
  448. Assert (!Config.m_pNetCfg);
  449. }
  450. TraceHr (ttidError, FAL, hr, FALSE,
  451. "CRasBindingConfig::RasCountBindings");
  452. return hr;
  453. }
  454. EXTERN_C
  455. HRESULT
  456. WINAPI
  457. RasRemoveBindings (
  458. IN OUT UINT* pcIpOutBindings,
  459. IN const GUID* pguidIpOutBindings,
  460. IN OUT UINT* pcNbfIn,
  461. IN OUT UINT* pcNbfOut)
  462. {
  463. HRESULT hr;
  464. #if 0
  465. RtlValidateProcessHeaps ();
  466. #endif
  467. // Validate parameters.
  468. //
  469. if (!pcIpOutBindings || !pcNbfIn || !pcNbfOut)
  470. {
  471. hr = E_POINTER;
  472. }
  473. else if (!*pcIpOutBindings && !*pcNbfIn && !*pcNbfOut)
  474. {
  475. hr = E_INVALIDARG;
  476. }
  477. else if (*pcIpOutBindings && !pguidIpOutBindings)
  478. {
  479. hr = E_POINTER;
  480. }
  481. else
  482. {
  483. CRasBindingConfig Config;
  484. hr = Config.HrLoadINetCfgAndAddOrRemoveBindings (
  485. ARA_REMOVE,
  486. pcIpOutBindings,
  487. pguidIpOutBindings,
  488. pcNbfIn,
  489. pcNbfOut);
  490. }
  491. TraceHr (ttidError, FAL, hr, FALSE,
  492. "CRasBindingConfig::RasRemoveBindings");
  493. return hr;
  494. }