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.

576 lines
14 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. catch (bad_alloc)
  350. {
  351. hr = E_OUTOFMEMORY;
  352. }
  353. UnloadINetCfg ();
  354. }
  355. // We shouldn't ever leave with an un-released INetCfg.
  356. //
  357. Assert (!m_pNetCfg);
  358. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  359. "CRasBindingConfig::HrLoadINetCfgAndAddOrRemoveBindings");
  360. return hr;
  361. }
  362. VOID
  363. CRasBindingConfig::UnloadINetCfg ()
  364. {
  365. // Must call HrLoadINetCfg before calling this.
  366. //
  367. Assert (m_pNetCfg);
  368. ReleaseIUnknownArray (COUNT_COMPONENTS, (IUnknown**)m_apComponents);
  369. (VOID) HrUninitializeAndReleaseINetCfg (m_fInitCom, m_pNetCfg, TRUE);
  370. m_pNetCfg = NULL;
  371. }
  372. //+---------------------------------------------------------------------------
  373. // Exported functions
  374. //
  375. EXTERN_C
  376. HRESULT
  377. WINAPI
  378. RasAddBindings (
  379. IN OUT UINT* pcIpOut,
  380. IN OUT UINT* pcNbfIn,
  381. IN OUT UINT* pcNbfOut)
  382. {
  383. HRESULT hr;
  384. #if 0
  385. RtlValidateProcessHeaps ();
  386. #endif
  387. // Validate parameters.
  388. //
  389. if (!pcIpOut || !pcNbfIn || !pcNbfOut)
  390. {
  391. hr = E_POINTER;
  392. }
  393. else if (!*pcIpOut && !*pcNbfIn && !*pcNbfOut)
  394. {
  395. hr = E_INVALIDARG;
  396. }
  397. else
  398. {
  399. CRasBindingConfig Config;
  400. hr = Config.HrLoadINetCfgAndAddOrRemoveBindings (
  401. ARA_ADD,
  402. pcIpOut,
  403. NULL,
  404. pcNbfIn,
  405. pcNbfOut);
  406. }
  407. TraceHr (ttidError, FAL, hr, FALSE,
  408. "CRasBindingConfig::RasAddBindings");
  409. return hr;
  410. }
  411. EXTERN_C
  412. HRESULT
  413. WINAPI
  414. RasCountBindings (
  415. OUT UINT* pcIpOut,
  416. OUT UINT* pcNbfIn,
  417. OUT UINT* pcNbfOut)
  418. {
  419. HRESULT hr;
  420. #if 0
  421. RtlValidateProcessHeaps ();
  422. #endif
  423. // Validate parameters.
  424. //
  425. if (!pcIpOut || !pcNbfIn || !pcNbfOut)
  426. {
  427. hr = E_POINTER;
  428. }
  429. else
  430. {
  431. CRasBindingConfig Config;
  432. hr = Config.HrLoadINetCfg (KEY_READ);
  433. if (SUCCEEDED(hr))
  434. {
  435. try
  436. {
  437. hr = Config.HrCountBindings (
  438. pcIpOut,
  439. pcNbfIn,
  440. pcNbfOut);
  441. }
  442. catch (bad_alloc)
  443. {
  444. hr = E_OUTOFMEMORY;
  445. }
  446. Config.UnloadINetCfg ();
  447. }
  448. // We shouldn't ever leave with an un-released INetCfg.
  449. //
  450. Assert (!Config.m_pNetCfg);
  451. }
  452. TraceHr (ttidError, FAL, hr, FALSE,
  453. "CRasBindingConfig::RasCountBindings");
  454. return hr;
  455. }
  456. EXTERN_C
  457. HRESULT
  458. WINAPI
  459. RasRemoveBindings (
  460. IN OUT UINT* pcIpOutBindings,
  461. IN const GUID* pguidIpOutBindings,
  462. IN OUT UINT* pcNbfIn,
  463. IN OUT UINT* pcNbfOut)
  464. {
  465. HRESULT hr;
  466. #if 0
  467. RtlValidateProcessHeaps ();
  468. #endif
  469. // Validate parameters.
  470. //
  471. if (!pcIpOutBindings || !pcNbfIn || !pcNbfOut)
  472. {
  473. hr = E_POINTER;
  474. }
  475. else if (!*pcIpOutBindings && !*pcNbfIn && !*pcNbfOut)
  476. {
  477. hr = E_INVALIDARG;
  478. }
  479. else if (*pcIpOutBindings && !pguidIpOutBindings)
  480. {
  481. hr = E_POINTER;
  482. }
  483. else
  484. {
  485. CRasBindingConfig Config;
  486. hr = Config.HrLoadINetCfgAndAddOrRemoveBindings (
  487. ARA_REMOVE,
  488. pcIpOutBindings,
  489. pguidIpOutBindings,
  490. pcNbfIn,
  491. pcNbfOut);
  492. }
  493. TraceHr (ttidError, FAL, hr, FALSE,
  494. "CRasBindingConfig::RasRemoveBindings");
  495. return hr;
  496. }