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.

382 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: B I N D O B J . C P P
  7. //
  8. // Contents: Implementation of base class for RAS binding objects.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 11 Jun 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "bindobj.h"
  18. #include "ncmisc.h"
  19. #include "ncsvc.h"
  20. extern const WCHAR c_szBiNdisAtm[];
  21. extern const WCHAR c_szBiNdisCoWan[];
  22. extern const WCHAR c_szBiNdisWan[];
  23. extern const WCHAR c_szBiNdisWanAsync[];
  24. extern const WCHAR c_szInfId_MS_AppleTalk[];
  25. extern const WCHAR c_szInfId_MS_NWIPX[];
  26. extern const WCHAR c_szInfId_MS_NdisWan[];
  27. extern const WCHAR c_szInfId_MS_NetBEUI[];
  28. extern const WCHAR c_szInfId_MS_NetMon[];
  29. extern const WCHAR c_szInfId_MS_RasCli[];
  30. extern const WCHAR c_szInfId_MS_RasSrv[];
  31. extern const WCHAR c_szInfId_MS_TCPIP[];
  32. //----------------------------------------------------------------------------
  33. // Data used for finding the other components we have to deal with.
  34. //
  35. const GUID* CRasBindObject::c_apguidComponentClasses [c_cOtherComponents] =
  36. {
  37. &GUID_DEVCLASS_NETSERVICE, // RasCli
  38. &GUID_DEVCLASS_NETSERVICE, // RasSrv
  39. &GUID_DEVCLASS_NETTRANS, // Ip
  40. &GUID_DEVCLASS_NETTRANS, // Ipx
  41. &GUID_DEVCLASS_NETTRANS, // Nbf
  42. &GUID_DEVCLASS_NETTRANS, // Atalk
  43. &GUID_DEVCLASS_NETTRANS, // NetMon
  44. &GUID_DEVCLASS_NETTRANS, // NdisWan
  45. &GUID_DEVCLASS_NET, // IpAdapter
  46. };
  47. const PCWSTR CRasBindObject::c_apszComponentIds [c_cOtherComponents] =
  48. {
  49. c_szInfId_MS_RasCli,
  50. c_szInfId_MS_RasSrv,
  51. c_szInfId_MS_TCPIP,
  52. c_szInfId_MS_NWIPX,
  53. c_szInfId_MS_NetBEUI,
  54. c_szInfId_MS_AppleTalk,
  55. c_szInfId_MS_NetMon,
  56. c_szInfId_MS_NdisWan,
  57. c_szInfId_MS_NdisWanIp,
  58. };
  59. CRasBindObject::CRasBindObject ()
  60. {
  61. m_ulOtherComponents = 0;
  62. m_pnc = NULL;
  63. }
  64. HRESULT
  65. CRasBindObject::HrCountInstalledMiniports (
  66. UINT* pcIpOut,
  67. UINT* pcNbfIn,
  68. UINT* pcNbfOut)
  69. {
  70. Assert (pcIpOut);
  71. Assert (pcNbfIn);
  72. Assert (pcNbfOut);
  73. // Initialize output parameters.
  74. //
  75. *pcIpOut = *pcNbfIn = *pcNbfOut = 0;
  76. if (PnccIp() && PnccIpAdapter())
  77. {
  78. INetCfgComponentUpperEdge* pUpperEdge;
  79. HRESULT hr = HrQueryNotifyObject (
  80. PnccIp(),
  81. IID_INetCfgComponentUpperEdge,
  82. reinterpret_cast<VOID**>(&pUpperEdge));
  83. if (SUCCEEDED(hr))
  84. {
  85. DWORD dwNumInterfaces;
  86. GUID* pguidInterfaceIds;
  87. hr = pUpperEdge->GetInterfaceIdsForAdapter (
  88. PnccIpAdapter(),
  89. &dwNumInterfaces,
  90. &pguidInterfaceIds);
  91. if (SUCCEEDED(hr))
  92. {
  93. *pcIpOut = dwNumInterfaces;
  94. CoTaskMemFree (pguidInterfaceIds);
  95. }
  96. ReleaseObj (pUpperEdge);
  97. }
  98. }
  99. // Iterate adapters in the system.
  100. //
  101. HRESULT hr = S_OK;
  102. CIterNetCfgComponent nccIter(m_pnc, &GUID_DEVCLASS_NET);
  103. INetCfgComponent* pnccAdapter;
  104. while(S_OK == (hr = nccIter.HrNext (&pnccAdapter)))
  105. {
  106. // Quickly discard non-hidden adapters to avoid unneccesary string
  107. // compares.
  108. //
  109. DWORD dwCharacter;
  110. if ( SUCCEEDED(pnccAdapter->GetCharacteristics (&dwCharacter))
  111. && (dwCharacter & NCF_HIDDEN))
  112. {
  113. PWSTR pszId;
  114. if (SUCCEEDED(pnccAdapter->GetId (&pszId)))
  115. {
  116. if (FEqualComponentId (c_szInfId_MS_NdisWanNbfIn, pszId))
  117. {
  118. (*pcNbfIn)++;
  119. }
  120. else if (FEqualComponentId (c_szInfId_MS_NdisWanNbfOut, pszId))
  121. {
  122. (*pcNbfOut)++;
  123. }
  124. CoTaskMemFree (pszId);
  125. }
  126. }
  127. ReleaseObj (pnccAdapter);
  128. }
  129. TraceTag (ttidRasCfg,
  130. "Current ndiswan miniports: "
  131. "%u IP dial-out, %u NBF dial-in, %u NBF dial-out",
  132. *pcIpOut, *pcNbfIn, *pcNbfOut);
  133. // Normalize the HRESULT. (i.e. don't return S_FALSE)
  134. if (SUCCEEDED(hr))
  135. {
  136. hr = S_OK;
  137. }
  138. TraceError ("CRasBindObject::HrCountInstalledMiniports", hr);
  139. return hr;
  140. }
  141. //+---------------------------------------------------------------------------
  142. //
  143. // Member: CRasBindObject::HrFindOtherComponents
  144. //
  145. // Purpose: Find the components listed in our OTHER_COMPONENTS enum.
  146. //
  147. // Arguments:
  148. // (none)
  149. //
  150. // Returns: S_OK or an error code.
  151. //
  152. // Author: shaunco 28 Jul 1997
  153. //
  154. // Notes: We ref-count this action. If called again (before
  155. // ReleaseOtherComponents) we increment a refcount.
  156. //
  157. //
  158. HRESULT
  159. CRasBindObject::HrFindOtherComponents ()
  160. {
  161. AssertSz (c_cOtherComponents == celems(c_apguidComponentClasses),
  162. "Uhh...you broke something.");
  163. AssertSz (c_cOtherComponents == celems(c_apszComponentIds),
  164. "Uhh...you broke something.");
  165. AssertSz (c_cOtherComponents == celems(m_apnccOther),
  166. "Uhh...you broke something.");
  167. HRESULT hr = S_OK;
  168. if (!m_ulOtherComponents)
  169. {
  170. hr = HrFindComponents (
  171. m_pnc, c_cOtherComponents,
  172. c_apguidComponentClasses,
  173. c_apszComponentIds,
  174. m_apnccOther);
  175. }
  176. if (SUCCEEDED(hr))
  177. {
  178. m_ulOtherComponents++;
  179. }
  180. TraceError ("CRasBindObject::HrFindOtherComponents", hr);
  181. return hr;
  182. }
  183. //+---------------------------------------------------------------------------
  184. //
  185. // Member: CRasBindObject::ReleaseOtherComponents
  186. //
  187. // Purpose: Releases the components found by a previous call to
  188. // HrFindOtherComponents. (But only if the refcount is zero.)
  189. //
  190. // Arguments:
  191. // (none)
  192. //
  193. // Returns: Nothing.
  194. //
  195. // Author: shaunco 28 Jul 1997
  196. //
  197. // Notes:
  198. //
  199. NOTHROW
  200. void
  201. CRasBindObject::ReleaseOtherComponents ()
  202. {
  203. AssertSz (m_ulOtherComponents,
  204. "You have not called HrFindOtherComponents yet or you have "
  205. "called ReleaseOtherComponents too many times.");
  206. if (0 == --m_ulOtherComponents)
  207. {
  208. ReleaseIUnknownArray (c_cOtherComponents, (IUnknown**)m_apnccOther);
  209. }
  210. }
  211. //+---------------------------------------------------------------------------
  212. //
  213. // Member: CRasBindObject::FIsRasBindingInterface
  214. //
  215. // Purpose: Return TRUE if an INetCfgBindingInterface represents
  216. // a RAS binding interface. If it is, return the corresponding
  217. // RAS_BINDING_ID.
  218. //
  219. // Arguments:
  220. // pncbi [in] INetCfgBindingInterface to check.
  221. // pRasBindId [out] Returned RAS_BINDING_ID if the method returns
  222. // TRUE.
  223. //
  224. // Returns: TRUE if the INetCfgBindingInterface represents a RAS binding
  225. // interface. FALSE if not.
  226. //
  227. // Author: shaunco 28 Jul 1997
  228. //
  229. // Notes:
  230. //
  231. BOOL
  232. CRasBindObject::FIsRasBindingInterface (
  233. INetCfgBindingInterface* pncbi,
  234. RAS_BINDING_ID* pRasBindId)
  235. {
  236. Assert (pRasBindId);
  237. // Initialize the output parameter.
  238. *pRasBindId = RBID_INVALID;
  239. PWSTR pszName;
  240. if (SUCCEEDED(pncbi->GetName (&pszName)))
  241. {
  242. if (0 == lstrcmpW (c_szBiNdisAtm, pszName))
  243. {
  244. *pRasBindId = RBID_NDISATM;
  245. }
  246. else if (0 == lstrcmpW (c_szBiNdisCoWan, pszName))
  247. {
  248. *pRasBindId = RBID_NDISCOWAN;
  249. }
  250. else if (0 == lstrcmpW (c_szBiNdisWan, pszName))
  251. {
  252. *pRasBindId = RBID_NDISWAN;
  253. }
  254. else if (0 == lstrcmpW (c_szBiNdisWanAsync, pszName))
  255. {
  256. *pRasBindId = RBID_NDISWANASYNC;
  257. }
  258. CoTaskMemFree (pszName);
  259. }
  260. return (RBID_INVALID != *pRasBindId);
  261. }
  262. HRESULT
  263. CRasBindObject::HrAddOrRemoveIpOut (
  264. INT nInstances)
  265. {
  266. if ((nInstances > 0) && PnccIp() && PnccIpAdapter())
  267. {
  268. INetCfgComponentUpperEdge* pUpperEdge;
  269. HRESULT hr = HrQueryNotifyObject (
  270. PnccIp(),
  271. IID_INetCfgComponentUpperEdge,
  272. reinterpret_cast<VOID**>(&pUpperEdge));
  273. if (SUCCEEDED(hr))
  274. {
  275. TraceTag (ttidRasCfg,
  276. "Adding %d TCP/IP interfaces to the ndiswanip adapter",
  277. nInstances);
  278. hr = pUpperEdge->AddInterfacesToAdapter (
  279. PnccIpAdapter(),
  280. nInstances);
  281. ReleaseObj (pUpperEdge);
  282. }
  283. }
  284. return S_OK;
  285. }
  286. HRESULT
  287. CRasBindObject::HrProcessEndpointChange ()
  288. {
  289. Assert (m_pnc);
  290. HRESULT hr = HrFindOtherComponents ();
  291. if (SUCCEEDED(hr))
  292. {
  293. // These will be the number of miniports we add(+) or remove(-) for
  294. // the in and out directions. ('d' is hungarian for 'difference'.)
  295. //
  296. INT dIpOut, dNbfIn, dNbfOut;
  297. dIpOut = dNbfIn = dNbfOut = 0;
  298. UINT cCurIpOut, cCurNbfIn, cCurNbfOut;
  299. hr = HrCountInstalledMiniports (&cCurIpOut, &cCurNbfIn, &cCurNbfOut);
  300. if (SUCCEEDED(hr))
  301. {
  302. PRODUCT_FLAVOR pf;
  303. (VOID) GetProductFlavor (NULL, &pf);
  304. // This is the number of miniports we want to end up with
  305. // without normalizing the number within the max range.
  306. //
  307. INT cDesiredIpOut = 2;
  308. INT cDesiredNbfIn = 0;
  309. INT cDesiredNbfOut = 1;
  310. if (PF_SERVER == pf)
  311. {
  312. cDesiredNbfIn = 2;
  313. }
  314. dIpOut = ((PnccIp()) ? cDesiredIpOut : 0) - cCurIpOut;
  315. dNbfIn = ((PnccNbf()) ? cDesiredNbfIn : 0) - cCurNbfIn;
  316. dNbfOut = ((PnccNbf()) ? cDesiredNbfOut : 0) - cCurNbfOut;
  317. }
  318. if (SUCCEEDED(hr) && dIpOut)
  319. {
  320. hr = HrAddOrRemoveIpOut (dIpOut);
  321. }
  322. if (SUCCEEDED(hr) && dNbfIn)
  323. {
  324. hr = HrAddOrRemoveNbfIn (dNbfIn);
  325. }
  326. if (SUCCEEDED(hr) && dNbfOut)
  327. {
  328. hr = HrAddOrRemoveNbfOut (dNbfOut);
  329. }
  330. // Normalize the HRESULT. (i.e. don't return S_FALSE)
  331. if (SUCCEEDED(hr))
  332. {
  333. hr = S_OK;
  334. }
  335. ReleaseOtherComponents ();
  336. }
  337. TraceError ("CRasBindObject::HrProcessEndpointChange", hr);
  338. return hr;
  339. }