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.

604 lines
16 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-2000 Microsoft Corporation
  4. //
  5. // LOCATOR.CPP
  6. //
  7. // alanbos 15-Aug-96 Created.
  8. //
  9. // Defines the implementation of ISWbemLocator
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include "objsink.h"
  14. #define WBEMS_DEFAULT_SERVER L"."
  15. extern CRITICAL_SECTION g_csErrorCache;
  16. wchar_t *CSWbemLocator::s_pDefaultNamespace = NULL;
  17. //***************************************************************************
  18. //
  19. // CSWbemLocator::CSWbemLocator
  20. //
  21. // DESCRIPTION:
  22. //
  23. // Constructor.
  24. //
  25. //***************************************************************************
  26. CSWbemLocator::CSWbemLocator(CSWbemPrivilegeSet *pPrivilegeSet) :
  27. m_pUnsecuredApartment (NULL),
  28. m_pIServiceProvider (NULL),
  29. m_cRef (0)
  30. {
  31. // Initialize the underlying locators
  32. HRESULT result = CoCreateInstance(CLSID_WbemLocator, 0,
  33. CLSCTX_INPROC_SERVER, IID_IWbemLocator,
  34. (LPVOID *) &m_pIWbemLocator);
  35. EnsureGlobalsInitialized () ;
  36. m_Dispatch.SetObj((ISWbemLocator *)this, IID_ISWbemLocator,
  37. CLSID_SWbemLocator, L"SWbemLocator");
  38. m_SecurityInfo = new CWbemLocatorSecurity (pPrivilegeSet);
  39. if (m_SecurityInfo)
  40. {
  41. // Set the impersonation level by default in the locator - note
  42. // that this must be done after EnsureGlobalsInitialized is called
  43. m_SecurityInfo->put_ImpersonationLevel (CSWbemSecurity::GetDefaultImpersonationLevel ());
  44. }
  45. InterlockedIncrement(&g_cObj);
  46. }
  47. CSWbemLocator::CSWbemLocator(CSWbemLocator & csWbemLocator) :
  48. m_pUnsecuredApartment (NULL),
  49. m_pIServiceProvider (NULL),
  50. m_cRef (0)
  51. {
  52. _RD(static char *me = "CSWbemLocator::CSWbemLocator()";)
  53. // This is a smart COM pointers so no explicit AddRef required
  54. m_pIWbemLocator = csWbemLocator.m_pIWbemLocator;
  55. m_Dispatch.SetObj((ISWbemLocator *)this,IID_ISWbemLocator,
  56. CLSID_SWbemLocator, L"SWbemLocator");
  57. m_SecurityInfo = new CWbemLocatorSecurity (csWbemLocator.m_SecurityInfo);
  58. InterlockedIncrement(&g_cObj);
  59. }
  60. //***************************************************************************
  61. //
  62. // CSWbemLocator::~CSWbemLocator
  63. //
  64. // DESCRIPTION:
  65. //
  66. // Destructor.
  67. //
  68. //***************************************************************************
  69. CSWbemLocator::~CSWbemLocator(void)
  70. {
  71. InterlockedDecrement(&g_cObj);
  72. RELEASEANDNULL(m_SecurityInfo)
  73. RELEASEANDNULL(m_pUnsecuredApartment)
  74. }
  75. //***************************************************************************
  76. // HRESULT CSWbemLocator::QueryInterface
  77. // long CSWbemLocator::AddRef
  78. // long CSWbemLocator::Release
  79. //
  80. // DESCRIPTION:
  81. //
  82. // Standard Com IUNKNOWN functions.
  83. //
  84. //***************************************************************************
  85. STDMETHODIMP CSWbemLocator::QueryInterface (
  86. IN REFIID riid,
  87. OUT LPVOID *ppv
  88. )
  89. {
  90. *ppv=NULL;
  91. if (IID_IUnknown==riid)
  92. *ppv = reinterpret_cast<IUnknown*>(this);
  93. else if (IID_ISWbemLocator==riid)
  94. *ppv = (ISWbemLocator *)this;
  95. else if (IID_IDispatch==riid)
  96. *ppv = (IDispatch *)((ISWbemLocator *)this);
  97. else if (IID_IObjectSafety==riid)
  98. *ppv = (IObjectSafety *)this;
  99. else if (IID_IDispatchEx==riid)
  100. *ppv = (IDispatchEx *)this;
  101. else if (IID_ISupportErrorInfo==riid)
  102. *ppv = (ISupportErrorInfo *)this;
  103. else if (IID_IProvideClassInfo==riid)
  104. *ppv = (IProvideClassInfo *)this;
  105. if (NULL!=*ppv)
  106. {
  107. ((LPUNKNOWN)*ppv)->AddRef();
  108. return NOERROR;
  109. }
  110. return ResultFromScode(E_NOINTERFACE);
  111. }
  112. STDMETHODIMP_(ULONG) CSWbemLocator::AddRef(void)
  113. {
  114. InterlockedIncrement(&m_cRef);
  115. return m_cRef;
  116. }
  117. STDMETHODIMP_(ULONG) CSWbemLocator::Release(void)
  118. {
  119. InterlockedDecrement(&m_cRef);
  120. if (0L!=m_cRef)
  121. return m_cRef;
  122. delete this;
  123. return 0;
  124. }
  125. // IDispatch methods should be inline
  126. STDMETHODIMP CSWbemLocator::GetTypeInfoCount(UINT* pctinfo)
  127. {
  128. _RD(static char *me = "CSWbemLocator::GetTypeInfoCount()";)
  129. _RPrint(me, "Called", 0, "");
  130. return m_Dispatch.GetTypeInfoCount(pctinfo);}
  131. STDMETHODIMP CSWbemLocator::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
  132. {
  133. _RD(static char *me = "CSWbemLocator::GetTypeInfo()";)
  134. _RPrint(me, "Called", 0, "");
  135. return m_Dispatch.GetTypeInfo(itinfo, lcid, pptinfo);}
  136. STDMETHODIMP CSWbemLocator::GetIDsOfNames(REFIID riid, OLECHAR** rgszNames,
  137. UINT cNames, LCID lcid, DISPID* rgdispid)
  138. {
  139. _RD(static char *me = "CSWbemLocator::GetIdsOfNames()";)
  140. _RPrint(me, "Called", 0, "");
  141. return m_Dispatch.GetIDsOfNames(riid, rgszNames, cNames,
  142. lcid,
  143. rgdispid);}
  144. STDMETHODIMP CSWbemLocator::Invoke(DISPID dispidMember, REFIID riid, LCID lcid,
  145. WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
  146. EXCEPINFO* pexcepinfo, UINT* puArgErr)
  147. {
  148. _RD(static char *me = "CSWbemLocator::Invoke()";)
  149. _RPrint(me, "Called", 0, "");
  150. return m_Dispatch.Invoke(dispidMember, riid, lcid, wFlags,
  151. pdispparams, pvarResult, pexcepinfo, puArgErr);}
  152. // IDispatchEx methods should be inline
  153. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetDispID(
  154. /* [in] */ BSTR bstrName,
  155. /* [in] */ DWORD grfdex,
  156. /* [out] */ DISPID __RPC_FAR *pid)
  157. {
  158. _RD(static char *me = "CSWbemLocator::GetDispID()";)
  159. _RPrint(me, "Called", 0, "");
  160. return m_Dispatch.GetDispID(bstrName, grfdex, pid);
  161. }
  162. /* [local] */ HRESULT STDMETHODCALLTYPE CSWbemLocator::InvokeEx(
  163. /* [in] */ DISPID id,
  164. /* [in] */ LCID lcid,
  165. /* [in] */ WORD wFlags,
  166. /* [in] */ DISPPARAMS __RPC_FAR *pdp,
  167. /* [out] */ VARIANT __RPC_FAR *pvarRes,
  168. /* [out] */ EXCEPINFO __RPC_FAR *pei,
  169. /* [unique][in] */ IServiceProvider __RPC_FAR *pspCaller)
  170. {
  171. HRESULT hr;
  172. _RD(static char *me = "CSWbemLocator::InvokeEx()";)
  173. _RPrint(me, "Called", (long)id, "id");
  174. _RPrint(me, "Called", (long)wFlags, "wFlags");
  175. /*
  176. * Store away the service provider so that it can be accessed
  177. * by calls that remote to CIMOM
  178. */
  179. m_pIServiceProvider = pspCaller;
  180. hr = m_Dispatch.InvokeEx(id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
  181. m_pIServiceProvider = NULL;
  182. return hr;
  183. }
  184. HRESULT STDMETHODCALLTYPE CSWbemLocator::DeleteMemberByName(
  185. /* [in] */ BSTR bstr,
  186. /* [in] */ DWORD grfdex)
  187. {
  188. _RD(static char *me = "CSWbemLocator::DeleteMemberByName()";)
  189. _RPrint(me, "Called", 0, "");
  190. return m_Dispatch.DeleteMemberByName(bstr, grfdex);
  191. }
  192. HRESULT STDMETHODCALLTYPE CSWbemLocator::DeleteMemberByDispID(
  193. /* [in] */ DISPID id)
  194. {
  195. _RD(static char *me = "CSWbemLocator::DeletememberByDispId()";)
  196. _RPrint(me, "Called", 0, "");
  197. return m_Dispatch.DeleteMemberByDispID(id);
  198. }
  199. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetMemberProperties(
  200. /* [in] */ DISPID id,
  201. /* [in] */ DWORD grfdexFetch,
  202. /* [out] */ DWORD __RPC_FAR *pgrfdex)
  203. {
  204. _RD(static char *me = "CSWbemLocator::GetMemberProperties()";)
  205. _RPrint(me, "Called", 0, "");
  206. return m_Dispatch.GetMemberProperties(id, grfdexFetch, pgrfdex);
  207. }
  208. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetMemberName(
  209. /* [in] */ DISPID id,
  210. /* [out] */ BSTR __RPC_FAR *pbstrName)
  211. {
  212. _RD(static char *me = "CSWbemLocator::GetMemberName()";)
  213. _RPrint(me, "Called", 0, "");
  214. return m_Dispatch.GetMemberName(id, pbstrName);
  215. }
  216. /*
  217. * I don't think this needs implementing
  218. */
  219. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetNextDispID(
  220. /* [in] */ DWORD grfdex,
  221. /* [in] */ DISPID id,
  222. /* [out] */ DISPID __RPC_FAR *pid)
  223. {
  224. _RD(static char *me = "CSWbemLocator::GetNextDispID()";)
  225. HRESULT rc = S_FALSE;
  226. _RPrint(me, "Called", 0, "");
  227. if ((grfdex & fdexEnumAll) && pid) {
  228. if (DISPID_STARTENUM == id) {
  229. *pid = 1;
  230. rc = S_OK;
  231. } else if (1 == id) {
  232. *pid = 2;
  233. }
  234. }
  235. return rc;
  236. }
  237. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetNameSpaceParent(
  238. /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunk)
  239. {
  240. _RD(static char *me = "CSWbemLocator::GetNamespaceParent()";)
  241. _RPrint(me, "Called", 0, "");
  242. return m_Dispatch.GetNameSpaceParent(ppunk);
  243. }
  244. //***************************************************************************
  245. // HRESULT CSWbemLocator::InterfaceSupportsErrorInfo
  246. //
  247. // DESCRIPTION:
  248. //
  249. // Standard Com ISupportErrorInfo functions.
  250. //
  251. //***************************************************************************
  252. STDMETHODIMP CSWbemLocator::InterfaceSupportsErrorInfo (IN REFIID riid)
  253. {
  254. return (IID_ISWbemLocator == riid) ? S_OK : S_FALSE;
  255. }
  256. //***************************************************************************
  257. //
  258. // SCODE CSWbemLocator::ConnectServer
  259. //
  260. // DESCRIPTION:
  261. //
  262. // Initiate connection to namespace
  263. //
  264. // PARAMETERS:
  265. //
  266. // bsServer The Server to which to connect
  267. // bsNamespace The namespace to connect to (default is reg lookup)
  268. // bsUser The user ("" implies default to logged-on user)
  269. // bsPassword The password ("" implies default to logged-on user's
  270. // password if bsUser == "")
  271. // bsLocale Requested locale
  272. // bsAuthority Authority
  273. // lSecurityFlags Currently 0 by default
  274. // pContext If non-null, extra context info for the connection
  275. // ppNamespace On successful return addresses the IWbemSServices
  276. // connection to the namespace.
  277. //
  278. // RETURN VALUES:
  279. //
  280. // WBEM_S_NO_ERROR success
  281. // WBEM_E_INVALID_PARAMETER bad input parameters
  282. // WBEM_E_FAILED otherwise
  283. //
  284. // Other WBEM error codes may be returned by ConnectServer etc., in which
  285. // case these are passed on to the caller.
  286. //
  287. //***************************************************************************
  288. HRESULT CSWbemLocator::ConnectServer (
  289. BSTR bsServer,
  290. BSTR bsNamespace,
  291. BSTR bsUser,
  292. BSTR bsPassword,
  293. BSTR bsLocale,
  294. BSTR bsAuthority,
  295. long lSecurityFlags,
  296. /*ISWbemValueBag*/ IDispatch *pContext,
  297. ISWbemServices **ppNamespace
  298. )
  299. {
  300. _RD(static char *me = "CSWbemLocator::ConnectServer";)
  301. HRESULT hr = WBEM_E_FAILED;
  302. ResetLastErrors ();
  303. if (NULL == ppNamespace)
  304. hr = WBEM_E_INVALID_PARAMETER;
  305. else if (m_pIWbemLocator && m_SecurityInfo)
  306. {
  307. bool useDefaultUser = (NULL == bsUser) || (0 == wcslen(bsUser));
  308. bool useDefaultAuthority = (NULL != bsAuthority) && (0 == wcslen (bsAuthority));
  309. // Build the namespace path
  310. BSTR bsNamespacePath = BuildPath (bsServer, bsNamespace);
  311. // Get the context
  312. IWbemContext *pIContext = CSWbemNamedValueSet::GetIWbemContext (pContext, m_pIServiceProvider);
  313. // Connect to the requested namespace
  314. IWbemServices *pIWbemService = NULL;
  315. bool needToResetSecurity = false;
  316. HANDLE hThreadToken = NULL;
  317. if (m_SecurityInfo->SetSecurity (bsUser, needToResetSecurity, hThreadToken))
  318. hr = m_pIWbemLocator->ConnectServer (
  319. bsNamespacePath,
  320. (useDefaultUser) ? NULL : bsUser,
  321. (useDefaultUser) ? NULL : bsPassword,
  322. ((NULL != bsLocale) && (0 < wcslen (bsLocale))) ? bsLocale : NULL,
  323. lSecurityFlags,
  324. (useDefaultAuthority) ? NULL : bsAuthority,
  325. pIContext,
  326. &pIWbemService);
  327. if (needToResetSecurity)
  328. m_SecurityInfo->ResetSecurity (hThreadToken);
  329. if (WBEM_S_NO_ERROR == hr)
  330. {
  331. // Create a new CSWbemServices using the IWbemServices interface
  332. // just returned. This will AddRef pIWbemService.
  333. CSWbemServices *pService =
  334. new CSWbemServices (
  335. pIWbemService,
  336. bsNamespacePath,
  337. ((NULL != bsAuthority) && (0 < wcslen (bsAuthority))) ? bsAuthority : NULL,
  338. (useDefaultUser) ? NULL : bsUser,
  339. (useDefaultUser) ? NULL : bsPassword,
  340. m_SecurityInfo,
  341. ((NULL != bsLocale) && (0 < wcslen (bsLocale))) ? bsLocale : NULL
  342. );
  343. if (!pService)
  344. hr = WBEM_E_OUT_OF_MEMORY;
  345. else if (FAILED(hr = pService->QueryInterface (IID_ISWbemServices,
  346. (PPVOID) ppNamespace)))
  347. delete pService;
  348. pIWbemService->Release ();
  349. }
  350. if (NULL != pIContext)
  351. pIContext->Release ();
  352. SysFreeString (bsNamespacePath);
  353. }
  354. if (FAILED(hr))
  355. m_Dispatch.RaiseException (hr);
  356. return hr;
  357. }
  358. //***************************************************************************
  359. //
  360. // SCODE CSWbemLocator::BuildPath
  361. //
  362. // DESCRIPTION:
  363. //
  364. // Build a namespace path from a server and namespace
  365. //
  366. // PARAMETERS:
  367. //
  368. // bsServer The Server to which to connect
  369. // bsNamespace The namespace to connect to (default is reg lookup)
  370. //
  371. // RETURN VALUES:
  372. //
  373. // The fully-formed namespace path
  374. //
  375. //***************************************************************************
  376. BSTR CSWbemLocator::BuildPath (BSTR bsServer, BSTR bsNamespace)
  377. {
  378. BSTR namespacePath = NULL;
  379. bool ok = false;
  380. CComBSTR bsPath;
  381. if ((NULL == bsServer) || (0 == wcslen(bsServer)))
  382. bsServer = WBEMS_DEFAULT_SERVER;
  383. // Use the default namespace if none supplied
  384. if ((NULL == bsNamespace) || (0 == wcslen(bsNamespace)))
  385. {
  386. const wchar_t *defaultNamespace = GetDefaultNamespace ();
  387. if (defaultNamespace)
  388. {
  389. CWbemPathCracker pathCracker;
  390. pathCracker.SetServer (bsServer);
  391. pathCracker.SetNamespacePath (defaultNamespace);
  392. ok = pathCracker.GetPathText (bsPath, false, true);
  393. }
  394. }
  395. else
  396. {
  397. CWbemPathCracker pathCracker;
  398. pathCracker.SetServer (bsServer);
  399. pathCracker.SetNamespacePath (bsNamespace);
  400. ok = pathCracker.GetPathText (bsPath, false, true);
  401. }
  402. if (ok)
  403. namespacePath = bsPath.Detach ();
  404. return namespacePath;
  405. }
  406. //***************************************************************************
  407. //
  408. // SCODE CSWbemLocator::GetDefaultNamespace
  409. //
  410. // DESCRIPTION:
  411. //
  412. // Get the default namespace path
  413. //
  414. // PARAMETERS:
  415. //
  416. // None
  417. //
  418. // RETURN VALUES:
  419. //
  420. // The default Namespace.
  421. //
  422. //***************************************************************************
  423. const wchar_t *CSWbemLocator::GetDefaultNamespace ()
  424. {
  425. if (!s_pDefaultNamespace)
  426. {
  427. // Get the value from the registry key
  428. HKEY hKey;
  429. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  430. WBEMS_RK_SCRIPTING, 0, KEY_QUERY_VALUE, &hKey))
  431. {
  432. DWORD dataLen = 0;
  433. // Find out how much space to allocate first
  434. if (ERROR_SUCCESS == RegQueryValueEx (hKey, WBEMS_RV_DEFNS,
  435. NULL, NULL, NULL, &dataLen))
  436. {
  437. TCHAR *defNamespace = new TCHAR [dataLen];
  438. if (defNamespace)
  439. {
  440. if (ERROR_SUCCESS == RegQueryValueEx (hKey, WBEMS_RV_DEFNS,
  441. NULL, NULL, (LPBYTE) defNamespace, &dataLen))
  442. {
  443. #ifndef UNICODE
  444. // Convert the multibyte value to its wide character equivalent
  445. int wDataLen = MultiByteToWideChar(CP_ACP, 0, defNamespace, -1, NULL, 0);
  446. s_pDefaultNamespace = new wchar_t [wDataLen];
  447. if (s_pDefaultNamespace)
  448. MultiByteToWideChar(CP_ACP, 0, defNamespace, -1, s_pDefaultNamespace, wDataLen);
  449. #else
  450. s_pDefaultNamespace = new wchar_t [wcslen (defNamespace) + 1];
  451. if (s_pDefaultNamespace)
  452. wcscpy (s_pDefaultNamespace, defNamespace);
  453. #endif
  454. }
  455. delete [] defNamespace;
  456. }
  457. }
  458. RegCloseKey (hKey);
  459. }
  460. // If we failed to read the registry OK, just use the default
  461. if (!s_pDefaultNamespace)
  462. {
  463. #ifndef UNICODE
  464. int wDataLen = MultiByteToWideChar(CP_ACP, 0, WBEMS_DEFNS, -1, NULL, 0);
  465. s_pDefaultNamespace = new wchar_t [wDataLen];
  466. if (s_pDefaultNamespace)
  467. MultiByteToWideChar(CP_ACP, 0, WBEMS_DEFNS, -1, s_pDefaultNamespace, wDataLen);
  468. #else
  469. s_pDefaultNamespace = new wchar_t [wcslen (WBEMS_DEFNS) + 1];
  470. if (s_pDefaultNamespace)
  471. wcscpy (s_pDefaultNamespace, WBEMS_DEFNS);
  472. #endif
  473. }
  474. }
  475. return s_pDefaultNamespace;
  476. }
  477. //***************************************************************************
  478. //
  479. // SCODE CSWbemLocator::get_Security_
  480. //
  481. // DESCRIPTION:
  482. //
  483. // Return the security configurator
  484. //
  485. // WBEM_S_NO_ERROR success
  486. // WBEM_E_INVALID_PARAMETER bad input parameters
  487. // WBEM_E_FAILED otherwise
  488. //
  489. //***************************************************************************
  490. HRESULT CSWbemLocator::get_Security_ (
  491. ISWbemSecurity **ppSecurity
  492. )
  493. {
  494. HRESULT hr = WBEM_E_FAILED;
  495. ResetLastErrors ();
  496. if (NULL == ppSecurity)
  497. hr = WBEM_E_INVALID_PARAMETER;
  498. {
  499. *ppSecurity = NULL;
  500. if (m_SecurityInfo)
  501. {
  502. if (SUCCEEDED (m_SecurityInfo->QueryInterface (IID_ISWbemSecurity,
  503. (PPVOID) ppSecurity)))
  504. hr = WBEM_S_NO_ERROR;
  505. }
  506. }
  507. if (FAILED(hr))
  508. m_Dispatch.RaiseException (hr);
  509. return hr;
  510. }