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.

570 lines
15 KiB

  1. //depot/private/homenet/net/homenet/Config/CfgMgr/HNBridge.cpp#13 - edit change 5915 (text)
  2. //+---------------------------------------------------------------------------
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 1997 - 2000
  6. //
  7. // File: H N B R I D G E . C P P
  8. //
  9. // Contents: CHNBridge implementation
  10. //
  11. // Notes:
  12. //
  13. // Author: jonburs 23 June 2000
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. //
  19. // IHNetBridge Methods
  20. //
  21. STDMETHODIMP
  22. CHNBridge::EnumMembers(
  23. IEnumHNetBridgedConnections **ppEnum
  24. )
  25. {
  26. HRESULT hr;
  27. CComObject<CEnumHNetBridgedConnections> *pEnum;
  28. INetCfgComponent *pBridgeProtocol = NULL;
  29. INetCfg *pnetcfg;
  30. IHNetBridgedConnection **rgBridgedAdapters = NULL;
  31. ULONG ulCountAdapters = 0L;
  32. if( NULL != ppEnum )
  33. {
  34. *ppEnum = NULL;
  35. hr = CoCreateInstance(
  36. CLSID_CNetCfg,
  37. NULL,
  38. CLSCTX_SERVER,
  39. IID_PPV_ARG(INetCfg, &pnetcfg));
  40. if( S_OK == hr )
  41. {
  42. hr = pnetcfg->Initialize( NULL );
  43. if( S_OK == hr )
  44. {
  45. hr = pnetcfg->FindComponent( c_wszSBridgeSID, &pBridgeProtocol );
  46. if( S_OK == hr )
  47. {
  48. INetCfgComponentBindings *pnetcfgProtocolBindings;
  49. // Get the ComponentBindings interface for the protocol component
  50. hr = pBridgeProtocol->QueryInterface(
  51. IID_PPV_ARG(INetCfgComponentBindings, &pnetcfgProtocolBindings)
  52. );
  53. if( S_OK == hr )
  54. {
  55. const GUID guidDevClass = GUID_DEVCLASS_NET;
  56. IEnumNetCfgComponent *penumncfgcomp;
  57. INetCfgComponent *pnetcfgcomp;
  58. //
  59. // Get the list of NET (adapter) devices
  60. //
  61. hr = pnetcfg->EnumComponents( &guidDevClass, &penumncfgcomp );
  62. if( S_OK == hr )
  63. {
  64. ULONG ul;
  65. //
  66. // Examine each adapter to see if it's bound to the bridge protocol
  67. //
  68. while( (S_OK == hr) && (S_OK == penumncfgcomp->Next(1, &pnetcfgcomp, &ul)) )
  69. {
  70. _ASSERT( 1L == ul );
  71. hr = pnetcfgProtocolBindings->IsBoundTo(pnetcfgcomp);
  72. if( S_OK == hr )
  73. {
  74. IHNetBridgedConnection *pBridgedConnection;
  75. //
  76. // The bridge protocol is bound to this adapter. Turn the NetCfg component
  77. // interface into an IHNetBridgedConnection.
  78. //
  79. hr = GetIHNetConnectionForNetCfgComponent(
  80. m_piwsHomenet,
  81. pnetcfgcomp,
  82. TRUE,
  83. IID_PPV_ARG(IHNetBridgedConnection, &pBridgedConnection)
  84. );
  85. if( S_OK == hr )
  86. {
  87. IHNetBridgedConnection **ppNewArray;
  88. //
  89. // Add the new IHNetBridgedConnection to our array
  90. //
  91. ppNewArray = reinterpret_cast<IHNetBridgedConnection**>(CoTaskMemRealloc( rgBridgedAdapters, (ulCountAdapters + 1) * sizeof(IHNetBridgedConnection*) ));
  92. if( NULL == ppNewArray )
  93. {
  94. hr = E_OUTOFMEMORY;
  95. // rgBridgedAdapters will be cleaned up below
  96. }
  97. else
  98. {
  99. // Use the newly grown array
  100. rgBridgedAdapters = ppNewArray;
  101. rgBridgedAdapters[ulCountAdapters] = pBridgedConnection;
  102. ulCountAdapters++;
  103. pBridgedConnection->AddRef();
  104. }
  105. pBridgedConnection->Release();
  106. }
  107. }
  108. else if( S_FALSE == hr )
  109. {
  110. // The bridge protocol is not bound to this adapter. Reset hr to success.
  111. hr = S_OK;
  112. }
  113. pnetcfgcomp->Release();
  114. }
  115. penumncfgcomp->Release();
  116. }
  117. pnetcfgProtocolBindings->Release();
  118. }
  119. pBridgeProtocol->Release();
  120. }
  121. pnetcfg->Uninitialize();
  122. }
  123. pnetcfg->Release();
  124. }
  125. //
  126. // Turn the array of bridge members into an enumeration
  127. //
  128. if( S_OK == hr )
  129. {
  130. hr = CComObject<CEnumHNetBridgedConnections>::CreateInstance(&pEnum);
  131. if( SUCCEEDED(hr) )
  132. {
  133. pEnum->AddRef();
  134. hr = pEnum->Initialize(rgBridgedAdapters, ulCountAdapters);
  135. if( SUCCEEDED(hr) )
  136. {
  137. hr = pEnum-> QueryInterface(
  138. IID_PPV_ARG(IEnumHNetBridgedConnections, ppEnum)
  139. );
  140. }
  141. pEnum->Release();
  142. }
  143. }
  144. //
  145. // The enumeration made a copy of the array and AddRef()ed the members.
  146. // Ditch it now.
  147. //
  148. if( rgBridgedAdapters )
  149. {
  150. ULONG i;
  151. _ASSERT( ulCountAdapters );
  152. for( i = 0; i < ulCountAdapters; i++ )
  153. {
  154. _ASSERT( rgBridgedAdapters[i] );
  155. rgBridgedAdapters[i]->Release();
  156. }
  157. CoTaskMemFree( rgBridgedAdapters );
  158. }
  159. }
  160. else
  161. {
  162. hr = E_POINTER;
  163. }
  164. return hr;
  165. }
  166. STDMETHODIMP
  167. CHNBridge::AddMember(
  168. IHNetConnection *pConn,
  169. IHNetBridgedConnection **ppBridgedConn,
  170. INetCfg *pnetcfgExisting
  171. )
  172. {
  173. HRESULT hr = S_OK;
  174. if (NULL == ppBridgedConn)
  175. {
  176. hr = E_POINTER;
  177. }
  178. else
  179. {
  180. *ppBridgedConn = NULL;
  181. if (NULL == pConn)
  182. {
  183. hr = E_INVALIDARG;
  184. }
  185. }
  186. if (ProhibitedByPolicy(NCPERM_AllowNetBridge_NLA))
  187. {
  188. hr = HN_E_POLICY;
  189. }
  190. //
  191. // Make sure that it's permissible to add this connection
  192. // to a bridge
  193. //
  194. if (S_OK == hr)
  195. {
  196. HNET_CONN_PROPERTIES *pProps;
  197. hr = pConn->GetProperties(&pProps);
  198. if (S_OK == hr)
  199. {
  200. if (!pProps->fCanBeBridged)
  201. {
  202. hr = E_UNEXPECTED;
  203. }
  204. CoTaskMemFree(pProps);
  205. }
  206. }
  207. //
  208. // Bind the adapter to the bridge
  209. //
  210. if (S_OK == hr)
  211. {
  212. GUID *pguidAdapter;
  213. hr = pConn->GetGuid (&pguidAdapter);
  214. if (S_OK == hr)
  215. {
  216. hr = BindNewAdapter (pguidAdapter, pnetcfgExisting);
  217. CoTaskMemFree(pguidAdapter);
  218. }
  219. }
  220. if (SUCCEEDED(hr))
  221. {
  222. if( NULL != pnetcfgExisting )
  223. {
  224. // Need to apply the changes for the next call to succeed
  225. hr = pnetcfgExisting->Apply();
  226. }
  227. if( SUCCEEDED(hr) )
  228. {
  229. // We should now be able to turn the provided connection into
  230. // an IHNetBridgedConnection
  231. hr = pConn->GetControlInterface( IID_PPV_ARG(IHNetBridgedConnection, ppBridgedConn) );
  232. // There is no good way to recover if this last operation failed
  233. _ASSERT( SUCCEEDED(hr) );
  234. //
  235. // Inform netman that something changed. Error doesn't matter.
  236. //
  237. UpdateNetman();
  238. }
  239. }
  240. return hr;
  241. }
  242. STDMETHODIMP
  243. CHNBridge::Destroy(
  244. INetCfg *pnetcfgExisting
  245. )
  246. {
  247. HRESULT hr = S_OK;
  248. IEnumHNetBridgedConnections *pEnum;
  249. IHNetBridgedConnection *pConn;
  250. GUID *pGuid = NULL;
  251. if (ProhibitedByPolicy(NCPERM_AllowNetBridge_NLA))
  252. {
  253. hr = HN_E_POLICY;
  254. }
  255. // Remember our connection GUID before we destroy it
  256. hr = GetGuid( &pGuid );
  257. if (SUCCEEDED(hr))
  258. {
  259. //
  260. // Get the enumeration of our members
  261. //
  262. hr = EnumMembers(&pEnum);
  263. if (S_OK == hr)
  264. {
  265. ULONG ulCount;
  266. //
  267. // Remove each member from the bridge
  268. //
  269. do
  270. {
  271. hr = pEnum->Next(
  272. 1,
  273. &pConn,
  274. &ulCount
  275. );
  276. if (SUCCEEDED(hr) && 1 == ulCount)
  277. {
  278. hr = pConn->RemoveFromBridge( pnetcfgExisting );
  279. pConn->Release();
  280. }
  281. }
  282. while (SUCCEEDED(hr) && 1 == ulCount);
  283. pEnum->Release();
  284. }
  285. }
  286. else
  287. {
  288. _ASSERT( NULL == pGuid );
  289. }
  290. if (SUCCEEDED(hr))
  291. {
  292. //
  293. // Remove the miniport
  294. //
  295. hr = RemoveMiniport( pnetcfgExisting );
  296. }
  297. if (SUCCEEDED(hr))
  298. {
  299. //
  300. // Delete the WMI objects
  301. //
  302. hr = m_piwsHomenet->DeleteInstance(
  303. m_bstrProperties,
  304. 0,
  305. NULL,
  306. NULL
  307. );
  308. if (WBEM_S_NO_ERROR == hr)
  309. {
  310. hr = m_piwsHomenet->DeleteInstance(
  311. m_bstrConnection,
  312. 0,
  313. NULL,
  314. NULL
  315. );
  316. }
  317. }
  318. if (WBEM_S_NO_ERROR == hr)
  319. {
  320. //
  321. // Inform netman that something changed. Error doesn't matter.
  322. //
  323. UpdateNetman();
  324. // Refresh the UI to remove this connection
  325. _ASSERT( NULL != pGuid );
  326. SignalDeletedConnection( pGuid );
  327. }
  328. if( NULL != pGuid )
  329. {
  330. CoTaskMemFree( pGuid );
  331. }
  332. return hr;
  333. }
  334. HRESULT
  335. CHNBridge::RemoveMiniport(
  336. IN OPTIONAL INetCfg *pnetcfgExisting
  337. )
  338. {
  339. HRESULT hr = S_OK;
  340. INetCfg *pnetcfg = NULL;
  341. INetCfgLock *pncfglock = NULL;
  342. GUID *pguid;
  343. if( NULL == pnetcfgExisting )
  344. {
  345. hr = InitializeNetCfgForWrite( &pnetcfg, &pncfglock );
  346. // Bail out if we failed to get a netcfg context
  347. if( FAILED(hr) )
  348. {
  349. return hr;
  350. }
  351. }
  352. else
  353. {
  354. // Use the NetCfg context we were given
  355. pnetcfg = pnetcfgExisting;
  356. }
  357. // We must have a NetCfg context at this point
  358. _ASSERT( pnetcfg != NULL );
  359. hr = GetGuid( &pguid );
  360. if ( SUCCEEDED(hr) )
  361. {
  362. INetCfgComponent *pnetcfgcomp;
  363. //
  364. // Locate ourselves by GUID
  365. //
  366. hr = FindAdapterByGUID(pnetcfg, pguid, &pnetcfgcomp);
  367. if ( SUCCEEDED(hr) )
  368. {
  369. const GUID guidDevClass = GUID_DEVCLASS_NET;
  370. INetCfgClassSetup *pncfgsetup = NULL;
  371. //
  372. // Recover the NetCfgClassSetup interface
  373. //
  374. hr = pnetcfg->QueryNetCfgClass(
  375. &guidDevClass,
  376. IID_PPV_ARG(INetCfgClassSetup, &pncfgsetup)
  377. );
  378. if ( SUCCEEDED(hr) )
  379. {
  380. //
  381. // Blow away this instance of the bridge
  382. //
  383. hr = pncfgsetup->DeInstall(
  384. pnetcfgcomp,
  385. NULL,
  386. NULL
  387. );
  388. pncfgsetup->Release();
  389. }
  390. // Done with the bridge component
  391. pnetcfgcomp->Release();
  392. }
  393. CoTaskMemFree(pguid);
  394. }
  395. // If we created our own NetCfg context, shut it down now
  396. if( NULL == pnetcfgExisting )
  397. {
  398. // Apply everything if we succeeded, back out otherwise
  399. if ( SUCCEEDED(hr) )
  400. {
  401. hr = pnetcfg->Apply();
  402. }
  403. else
  404. {
  405. // Don't want to lose the original error code
  406. pnetcfg->Cancel();
  407. }
  408. UninitializeNetCfgForWrite( pnetcfg, pncfglock );
  409. }
  410. return hr;
  411. }
  412. HRESULT
  413. CHNBridge::BindNewAdapter(
  414. IN GUID *pguid,
  415. IN OPTIONAL INetCfg *pnetcfgExisting
  416. )
  417. {
  418. HRESULT hr = S_OK;
  419. INetCfg *pnetcfg = NULL;
  420. INetCfgLock *pncfglock = NULL;
  421. INetCfgComponent *pnetcfgcomp;
  422. if( NULL == pnetcfgExisting )
  423. {
  424. hr = InitializeNetCfgForWrite( &pnetcfg, &pncfglock );
  425. // Bail out if we failed to get a netcfg context
  426. if( FAILED(hr) )
  427. {
  428. return hr;
  429. }
  430. }
  431. else
  432. {
  433. // Use the NetCfg context we were given
  434. pnetcfg = pnetcfgExisting;
  435. }
  436. // We must have a NetCfg context at this point
  437. _ASSERT( pnetcfg != NULL );
  438. hr = FindAdapterByGUID(
  439. pnetcfg,
  440. pguid,
  441. &pnetcfgcomp
  442. );
  443. if ( SUCCEEDED(hr) )
  444. {
  445. hr = BindOnlyToBridge( pnetcfgcomp );
  446. pnetcfgcomp->Release();
  447. }
  448. // If we created our own NetCfg context, shut it down now
  449. if( NULL == pnetcfgExisting )
  450. {
  451. // Apply everything if we succeeded, back out otherwise
  452. if ( SUCCEEDED(hr) )
  453. {
  454. hr = pnetcfg->Apply();
  455. // Redraw this connection
  456. SignalModifiedConnection( pguid );
  457. }
  458. else
  459. {
  460. // Don't want to lose the original error code
  461. pnetcfg->Cancel();
  462. }
  463. UninitializeNetCfgForWrite( pnetcfg, pncfglock );
  464. }
  465. return hr;
  466. }