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.

352 lines
9.6 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999.
  5. //
  6. // File: I C L A S S . C P P
  7. //
  8. // Contents: Implements the INetCfgClass and INetCfgClassSetup COM
  9. // interfaces on the NetCfgClass sub-level COM object.
  10. //
  11. // Notes:
  12. //
  13. // Author: shaunco 15 Jan 1999
  14. //
  15. //----------------------------------------------------------------------------
  16. #include <pch.h>
  17. #pragma hdrstop
  18. #include "iclass.h"
  19. #include "icomp.h"
  20. #include "ienum.h"
  21. #include "install.h"
  22. #include "netcfg.h"
  23. #include "obotoken.h"
  24. // static
  25. HRESULT
  26. CImplINetCfgClass::HrCreateInstance (
  27. IN CImplINetCfg* pINetCfg,
  28. IN NETCLASS Class,
  29. OUT INetCfgClass** ppIClass)
  30. {
  31. HRESULT hr = E_OUTOFMEMORY;
  32. CImplINetCfgClass* pObj;
  33. pObj = new CComObject <CImplINetCfgClass>;
  34. if (pObj)
  35. {
  36. // Initialize our members.
  37. //
  38. pObj->m_Class = Class;
  39. // Do the standard CComCreator::CreateInstance stuff.
  40. //
  41. pObj->SetVoid (NULL);
  42. pObj->InternalFinalConstructAddRef ();
  43. hr = pObj->FinalConstruct ();
  44. pObj->InternalFinalConstructRelease ();
  45. if (S_OK == hr)
  46. {
  47. hr = pObj->GetUnknown()->QueryInterface (IID_INetCfgClass,
  48. (VOID**)ppIClass);
  49. // The last thing we do is addref any interfaces we hold.
  50. // We only do this if we are returning success.
  51. //
  52. if (S_OK == hr)
  53. {
  54. pObj->HoldINetCfg (pINetCfg);
  55. }
  56. }
  57. if (S_OK != hr)
  58. {
  59. delete pObj;
  60. }
  61. }
  62. TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgClass::HrCreateInstance");
  63. return hr;
  64. }
  65. //+---------------------------------------------------------------------------
  66. // INetCfgClass -
  67. //
  68. STDMETHODIMP
  69. CImplINetCfgClass::FindComponent (
  70. IN PCWSTR pszInfId,
  71. OUT INetCfgComponent** ppComp OPTIONAL)
  72. {
  73. HRESULT hr;
  74. // Validate parameters.
  75. //
  76. if (FBadInPtr(pszInfId) || FBadOutPtrOptional(ppComp))
  77. {
  78. hr = E_POINTER;
  79. }
  80. else if (wcslen (pszInfId) >= MAX_DEVICE_ID_LEN)
  81. {
  82. //impose the same limit on infid as imposed by pnp on pnpid.
  83. hr = E_INVALIDARG;
  84. }
  85. else
  86. {
  87. if (ppComp)
  88. {
  89. *ppComp = NULL;
  90. }
  91. hr = HrLockAndTestForValidInterface (IF_DEFAULT);
  92. if (S_OK == hr)
  93. {
  94. CComponent* pComponent;
  95. pComponent = m_pINetCfg->m_pNetConfig->Core.Components.
  96. PFindComponentByInfId (pszInfId, NULL);
  97. // Don't return interfaces to components that have had
  98. // problem loading.
  99. //
  100. if (pComponent &&
  101. pComponent->Ext.FLoadedOkayIfLoadedAtAll() &&
  102. (m_Class == pComponent->Class()))
  103. {
  104. hr = S_OK;
  105. if (ppComp)
  106. {
  107. hr = pComponent->HrGetINetCfgComponentInterface (
  108. m_pINetCfg, ppComp);
  109. }
  110. }
  111. else
  112. {
  113. hr = S_FALSE;
  114. }
  115. Unlock();
  116. }
  117. }
  118. TraceHr (ttidError, FAL, hr, (S_FALSE == hr),
  119. "CImplINetCfgClass::FindComponent");
  120. return hr;
  121. }
  122. STDMETHODIMP
  123. CImplINetCfgClass::EnumComponents (
  124. OUT IEnumNetCfgComponent** ppIEnum)
  125. {
  126. HRESULT hr;
  127. // Validate parameters.
  128. //
  129. if (FBadOutPtr(ppIEnum))
  130. {
  131. hr = E_POINTER;
  132. }
  133. else
  134. {
  135. *ppIEnum = NULL;
  136. hr = HrLockAndTestForValidInterface (IF_DEFAULT);
  137. if (S_OK == hr)
  138. {
  139. hr = CImplIEnumNetCfgComponent::HrCreateInstance (
  140. m_pINetCfg,
  141. m_Class,
  142. ppIEnum);
  143. Unlock();
  144. }
  145. }
  146. TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgClass::EnumComponents");
  147. return hr;
  148. }
  149. //+---------------------------------------------------------------------------
  150. // INetCfgClassSetup -
  151. //
  152. STDMETHODIMP
  153. CImplINetCfgClass::SelectAndInstall (
  154. IN HWND hwndParent,
  155. IN OBO_TOKEN* pOboToken OPTIONAL,
  156. OUT INetCfgComponent** ppIComp OPTIONAL)
  157. {
  158. HRESULT hr = m_pINetCfg->SelectWithFilterAndInstall(
  159. hwndParent,
  160. MAP_NETCLASS_TO_GUID[m_Class],
  161. pOboToken,
  162. NULL,
  163. ppIComp);
  164. TraceHr (ttidError, FAL, hr,
  165. (HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr) ||
  166. (NETCFG_S_REBOOT == hr),
  167. "CImplINetCfgClass::SelectAndInstall");
  168. return hr;
  169. }
  170. STDMETHODIMP
  171. CImplINetCfgClass::Install (
  172. IN PCWSTR pszwInfId,
  173. IN OBO_TOKEN* pOboToken OPTIONAL,
  174. IN DWORD dwSetupFlags OPTIONAL,
  175. IN DWORD dwUpgradeFromBuildNo OPTIONAL,
  176. IN PCWSTR pszAnswerFile OPTIONAL,
  177. IN PCWSTR pszAnswerSection OPTIONAL,
  178. OUT INetCfgComponent** ppIComp OPTIONAL)
  179. {
  180. HRESULT hr;
  181. // Validate parameters.
  182. //
  183. if (FBadInPtr (pszwInfId) ||
  184. !FOboTokenValidForClass(pOboToken, m_Class) ||
  185. FBadInPtrOptional (pszAnswerFile) ||
  186. FBadInPtrOptional (pszAnswerSection) ||
  187. FBadOutPtrOptional(ppIComp))
  188. {
  189. hr = E_POINTER;
  190. }
  191. // Must specifiy a non-empty INF id, and must either not specifiy,
  192. // or completely specifiy the answerfile and the section.
  193. //
  194. else if (!(*pszwInfId) ||
  195. ((!!pszAnswerFile) ^ (!!pszAnswerSection)))
  196. {
  197. hr = E_INVALIDARG;
  198. }
  199. else if (wcslen (pszwInfId) >= MAX_DEVICE_ID_LEN)
  200. {
  201. //impose the same limit on infid as imposed by pnp on pnpid.
  202. hr = E_INVALIDARG;
  203. }
  204. else if (S_OK == (hr = HrProbeOboToken(pOboToken)))
  205. {
  206. if (ppIComp)
  207. {
  208. *ppIComp = NULL;
  209. }
  210. hr = HrLockAndTestForValidInterface (
  211. IF_NEED_WRITE_LOCK | IF_REFUSE_REENTRANCY |
  212. IF_ALLOW_INSTALL_OR_REMOVE);
  213. if (S_OK == hr)
  214. {
  215. Assert (m_pINetCfg->m_pNetConfig->ModifyCtx.m_fPrepared);
  216. NETWORK_INSTALL_PARAMS nip;
  217. COMPONENT_INSTALL_PARAMS Params;
  218. CComponent* pComponent;
  219. // Pack the network install parameters and call the common
  220. // function.
  221. //
  222. //$REVIEW: Just make this method take NETWORK_INSTALL_PARAMS?.
  223. //
  224. nip.dwSetupFlags = dwSetupFlags;
  225. nip.dwUpgradeFromBuildNo = dwUpgradeFromBuildNo;
  226. nip.pszAnswerFile = pszAnswerFile;
  227. nip.pszAnswerSection = pszAnswerSection;
  228. // Setup the component install parameters.
  229. //
  230. ZeroMemory (&Params, sizeof(Params));
  231. Params.Class = m_Class;
  232. Params.pszInfId = pszwInfId;
  233. Params.pOboToken = pOboToken;
  234. Params.pnip = &nip;
  235. hr = m_pINetCfg->m_pNetConfig->ModifyCtx.
  236. HrInstallNewOrReferenceExistingComponent (
  237. Params,
  238. &pComponent);
  239. // The above may return NETCFG_S_REBOOT so use SUCCEEDED instead
  240. // of checking for S_OK only.
  241. //
  242. if (SUCCEEDED(hr) && ppIComp)
  243. {
  244. pComponent->HrGetINetCfgComponentInterface (
  245. m_pINetCfg,
  246. ppIComp);
  247. }
  248. Unlock();
  249. }
  250. }
  251. TraceHr (ttidError, FAL, hr, (NETCFG_S_REBOOT == hr),
  252. "CImplINetCfgClass::Install");
  253. return hr;
  254. }
  255. STDMETHODIMP
  256. CImplINetCfgClass::DeInstall (
  257. IN INetCfgComponent* pIComp,
  258. IN OBO_TOKEN* pOboToken OPTIONAL,
  259. OUT PWSTR* ppmszwRefs OPTIONAL)
  260. {
  261. HRESULT hr;
  262. // Validate parameters.
  263. //
  264. if (FBadInPtr (pIComp) ||
  265. !FOboTokenValidForClass(pOboToken, m_Class) ||
  266. FBadOutPtrOptional(ppmszwRefs))
  267. {
  268. hr = E_POINTER;
  269. }
  270. else if (S_OK == (hr = HrProbeOboToken(pOboToken)))
  271. {
  272. if (ppmszwRefs)
  273. {
  274. *ppmszwRefs = NULL;
  275. }
  276. hr = HrLockAndTestForValidInterface (
  277. IF_NEED_WRITE_LOCK | IF_REFUSE_REENTRANCY |
  278. IF_ALLOW_INSTALL_OR_REMOVE);
  279. if (S_OK == hr)
  280. {
  281. Assert (m_pINetCfg->m_pNetConfig->ModifyCtx.m_fPrepared);
  282. CImplINetCfgComponent* pICompToRemove;
  283. pICompToRemove = (CImplINetCfgComponent*)pIComp;
  284. hr = pICompToRemove->HrIsValidInterface (IF_NEED_COMPONENT_DATA);
  285. if (S_OK == hr)
  286. {
  287. // We don't allow removals of physical adapters via INetCfg.
  288. //
  289. if (!FIsPhysicalAdapter (m_Class,
  290. pICompToRemove->m_pComponent->m_dwCharacter))
  291. {
  292. hr = m_pINetCfg->m_pNetConfig->ModifyCtx.
  293. HrRemoveComponentIfNotReferenced (
  294. pICompToRemove->m_pComponent,
  295. pOboToken,
  296. ppmszwRefs);
  297. }
  298. else
  299. {
  300. hr = SPAPI_E_INVALID_CLASS;
  301. }
  302. }
  303. Unlock();
  304. }
  305. }
  306. TraceHr (ttidError, FAL, hr,
  307. (NETCFG_S_REBOOT == hr) || (NETCFG_S_STILL_REFERENCED == hr),
  308. "CImplINetCfgClass::DeInstall");
  309. return hr;
  310. }