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.

609 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. LONG cRef = InterlockedDecrement(&m_cRef);
  120. if (0 != cRef)
  121. {
  122. _ASSERT(cRef > 0);
  123. return cRef;
  124. }
  125. delete this;
  126. return 0;
  127. }
  128. // IDispatch methods should be inline
  129. STDMETHODIMP CSWbemLocator::GetTypeInfoCount(UINT* pctinfo)
  130. {
  131. _RD(static char *me = "CSWbemLocator::GetTypeInfoCount()";)
  132. _RPrint(me, "Called", 0, "");
  133. return m_Dispatch.GetTypeInfoCount(pctinfo);}
  134. STDMETHODIMP CSWbemLocator::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
  135. {
  136. _RD(static char *me = "CSWbemLocator::GetTypeInfo()";)
  137. _RPrint(me, "Called", 0, "");
  138. return m_Dispatch.GetTypeInfo(itinfo, lcid, pptinfo);}
  139. STDMETHODIMP CSWbemLocator::GetIDsOfNames(REFIID riid, OLECHAR** rgszNames,
  140. UINT cNames, LCID lcid, DISPID* rgdispid)
  141. {
  142. _RD(static char *me = "CSWbemLocator::GetIdsOfNames()";)
  143. _RPrint(me, "Called", 0, "");
  144. return m_Dispatch.GetIDsOfNames(riid, rgszNames, cNames,
  145. lcid,
  146. rgdispid);}
  147. STDMETHODIMP CSWbemLocator::Invoke(DISPID dispidMember, REFIID riid, LCID lcid,
  148. WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
  149. EXCEPINFO* pexcepinfo, UINT* puArgErr)
  150. {
  151. _RD(static char *me = "CSWbemLocator::Invoke()";)
  152. _RPrint(me, "Called", 0, "");
  153. return m_Dispatch.Invoke(dispidMember, riid, lcid, wFlags,
  154. pdispparams, pvarResult, pexcepinfo, puArgErr);}
  155. // IDispatchEx methods should be inline
  156. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetDispID(
  157. /* [in] */ BSTR bstrName,
  158. /* [in] */ DWORD grfdex,
  159. /* [out] */ DISPID __RPC_FAR *pid)
  160. {
  161. _RD(static char *me = "CSWbemLocator::GetDispID()";)
  162. _RPrint(me, "Called", 0, "");
  163. return m_Dispatch.GetDispID(bstrName, grfdex, pid);
  164. }
  165. /* [local] */ HRESULT STDMETHODCALLTYPE CSWbemLocator::InvokeEx(
  166. /* [in] */ DISPID id,
  167. /* [in] */ LCID lcid,
  168. /* [in] */ WORD wFlags,
  169. /* [in] */ DISPPARAMS __RPC_FAR *pdp,
  170. /* [out] */ VARIANT __RPC_FAR *pvarRes,
  171. /* [out] */ EXCEPINFO __RPC_FAR *pei,
  172. /* [unique][in] */ IServiceProvider __RPC_FAR *pspCaller)
  173. {
  174. HRESULT hr;
  175. _RD(static char *me = "CSWbemLocator::InvokeEx()";)
  176. _RPrint(me, "Called", (long)id, "id");
  177. _RPrint(me, "Called", (long)wFlags, "wFlags");
  178. /*
  179. * Store away the service provider so that it can be accessed
  180. * by calls that remote to CIMOM
  181. */
  182. m_pIServiceProvider = pspCaller;
  183. hr = m_Dispatch.InvokeEx(id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
  184. m_pIServiceProvider = NULL;
  185. return hr;
  186. }
  187. HRESULT STDMETHODCALLTYPE CSWbemLocator::DeleteMemberByName(
  188. /* [in] */ BSTR bstr,
  189. /* [in] */ DWORD grfdex)
  190. {
  191. _RD(static char *me = "CSWbemLocator::DeleteMemberByName()";)
  192. _RPrint(me, "Called", 0, "");
  193. return m_Dispatch.DeleteMemberByName(bstr, grfdex);
  194. }
  195. HRESULT STDMETHODCALLTYPE CSWbemLocator::DeleteMemberByDispID(
  196. /* [in] */ DISPID id)
  197. {
  198. _RD(static char *me = "CSWbemLocator::DeletememberByDispId()";)
  199. _RPrint(me, "Called", 0, "");
  200. return m_Dispatch.DeleteMemberByDispID(id);
  201. }
  202. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetMemberProperties(
  203. /* [in] */ DISPID id,
  204. /* [in] */ DWORD grfdexFetch,
  205. /* [out] */ DWORD __RPC_FAR *pgrfdex)
  206. {
  207. _RD(static char *me = "CSWbemLocator::GetMemberProperties()";)
  208. _RPrint(me, "Called", 0, "");
  209. return m_Dispatch.GetMemberProperties(id, grfdexFetch, pgrfdex);
  210. }
  211. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetMemberName(
  212. /* [in] */ DISPID id,
  213. /* [out] */ BSTR __RPC_FAR *pbstrName)
  214. {
  215. _RD(static char *me = "CSWbemLocator::GetMemberName()";)
  216. _RPrint(me, "Called", 0, "");
  217. return m_Dispatch.GetMemberName(id, pbstrName);
  218. }
  219. /*
  220. * I don't think this needs implementing
  221. */
  222. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetNextDispID(
  223. /* [in] */ DWORD grfdex,
  224. /* [in] */ DISPID id,
  225. /* [out] */ DISPID __RPC_FAR *pid)
  226. {
  227. _RD(static char *me = "CSWbemLocator::GetNextDispID()";)
  228. HRESULT rc = S_FALSE;
  229. _RPrint(me, "Called", 0, "");
  230. if ((grfdex & fdexEnumAll) && pid) {
  231. if (DISPID_STARTENUM == id) {
  232. *pid = 1;
  233. rc = S_OK;
  234. } else if (1 == id) {
  235. *pid = 2;
  236. }
  237. }
  238. return rc;
  239. }
  240. HRESULT STDMETHODCALLTYPE CSWbemLocator::GetNameSpaceParent(
  241. /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunk)
  242. {
  243. _RD(static char *me = "CSWbemLocator::GetNamespaceParent()";)
  244. _RPrint(me, "Called", 0, "");
  245. return m_Dispatch.GetNameSpaceParent(ppunk);
  246. }
  247. //***************************************************************************
  248. // HRESULT CSWbemLocator::InterfaceSupportsErrorInfo
  249. //
  250. // DESCRIPTION:
  251. //
  252. // Standard Com ISupportErrorInfo functions.
  253. //
  254. //***************************************************************************
  255. STDMETHODIMP CSWbemLocator::InterfaceSupportsErrorInfo (IN REFIID riid)
  256. {
  257. return (IID_ISWbemLocator == riid) ? S_OK : S_FALSE;
  258. }
  259. //***************************************************************************
  260. //
  261. // SCODE CSWbemLocator::ConnectServer
  262. //
  263. // DESCRIPTION:
  264. //
  265. // Initiate connection to namespace
  266. //
  267. // PARAMETERS:
  268. //
  269. // bsServer The Server to which to connect
  270. // bsNamespace The namespace to connect to (default is reg lookup)
  271. // bsUser The user ("" implies default to logged-on user)
  272. // bsPassword The password ("" implies default to logged-on user's
  273. // password if bsUser == "")
  274. // bsLocale Requested locale
  275. // bsAuthority Authority
  276. // lSecurityFlags Currently 0 by default
  277. // pContext If non-null, extra context info for the connection
  278. // ppNamespace On successful return addresses the IWbemSServices
  279. // connection to the namespace.
  280. //
  281. // RETURN VALUES:
  282. //
  283. // WBEM_S_NO_ERROR success
  284. // WBEM_E_INVALID_PARAMETER bad input parameters
  285. // WBEM_E_FAILED otherwise
  286. //
  287. // Other WBEM error codes may be returned by ConnectServer etc., in which
  288. // case these are passed on to the caller.
  289. //
  290. //***************************************************************************
  291. HRESULT CSWbemLocator::ConnectServer (
  292. BSTR bsServer,
  293. BSTR bsNamespace,
  294. BSTR bsUser,
  295. BSTR bsPassword,
  296. BSTR bsLocale,
  297. BSTR bsAuthority,
  298. long lSecurityFlags,
  299. /*ISWbemValueBag*/ IDispatch *pContext,
  300. ISWbemServices **ppNamespace
  301. )
  302. {
  303. _RD(static char *me = "CSWbemLocator::ConnectServer";)
  304. HRESULT hr = WBEM_E_FAILED;
  305. ResetLastErrors ();
  306. if (NULL == ppNamespace)
  307. hr = WBEM_E_INVALID_PARAMETER;
  308. else if (m_pIWbemLocator && m_SecurityInfo)
  309. {
  310. bool useDefaultUser = (NULL == bsUser) || (0 == wcslen(bsUser));
  311. bool useDefaultAuthority = (NULL != bsAuthority) && (0 == wcslen (bsAuthority));
  312. // Build the namespace path
  313. BSTR bsNamespacePath = BuildPath (bsServer, bsNamespace);
  314. // Get the context
  315. IWbemContext *pIContext = CSWbemNamedValueSet::GetIWbemContext (pContext, m_pIServiceProvider);
  316. // Connect to the requested namespace
  317. IWbemServices *pIWbemService = NULL;
  318. bool needToResetSecurity = false;
  319. HANDLE hThreadToken = NULL;
  320. if (m_SecurityInfo->SetSecurity (bsUser, needToResetSecurity, hThreadToken))
  321. hr = m_pIWbemLocator->ConnectServer (
  322. bsNamespacePath,
  323. (useDefaultUser) ? NULL : bsUser,
  324. (useDefaultUser) ? NULL : bsPassword,
  325. ((NULL != bsLocale) && (0 < wcslen (bsLocale))) ? bsLocale : NULL,
  326. lSecurityFlags,
  327. (useDefaultAuthority) ? NULL : bsAuthority,
  328. pIContext,
  329. &pIWbemService);
  330. if (needToResetSecurity)
  331. m_SecurityInfo->ResetSecurity (hThreadToken);
  332. if (WBEM_S_NO_ERROR == hr)
  333. {
  334. // Create a new CSWbemServices using the IWbemServices interface
  335. // just returned. This will AddRef pIWbemService.
  336. CSWbemServices *pService =
  337. new CSWbemServices (
  338. pIWbemService,
  339. bsNamespacePath,
  340. ((NULL != bsAuthority) && (0 < wcslen (bsAuthority))) ? bsAuthority : NULL,
  341. (useDefaultUser) ? NULL : bsUser,
  342. (useDefaultUser) ? NULL : bsPassword,
  343. m_SecurityInfo,
  344. ((NULL != bsLocale) && (0 < wcslen (bsLocale))) ? bsLocale : NULL
  345. );
  346. if (!pService)
  347. hr = WBEM_E_OUT_OF_MEMORY;
  348. else if (FAILED(hr = pService->QueryInterface (IID_ISWbemServices,
  349. (PPVOID) ppNamespace)))
  350. delete pService;
  351. pIWbemService->Release ();
  352. }
  353. if (NULL != pIContext)
  354. pIContext->Release ();
  355. SysFreeString (bsNamespacePath);
  356. }
  357. if (FAILED(hr))
  358. m_Dispatch.RaiseException (hr);
  359. return hr;
  360. }
  361. //***************************************************************************
  362. //
  363. // SCODE CSWbemLocator::BuildPath
  364. //
  365. // DESCRIPTION:
  366. //
  367. // Build a namespace path from a server and namespace
  368. //
  369. // PARAMETERS:
  370. //
  371. // bsServer The Server to which to connect
  372. // bsNamespace The namespace to connect to (default is reg lookup)
  373. //
  374. // RETURN VALUES:
  375. //
  376. // The fully-formed namespace path
  377. //
  378. //***************************************************************************
  379. BSTR CSWbemLocator::BuildPath (BSTR bsServer, BSTR bsNamespace)
  380. {
  381. BSTR namespacePath = NULL;
  382. bool ok = false;
  383. CComBSTR bsPath;
  384. if ((NULL == bsServer) || (0 == wcslen(bsServer)))
  385. bsServer = WBEMS_DEFAULT_SERVER;
  386. // Use the default namespace if none supplied
  387. if ((NULL == bsNamespace) || (0 == wcslen(bsNamespace)))
  388. {
  389. const wchar_t *defaultNamespace = GetDefaultNamespace ();
  390. if (defaultNamespace)
  391. {
  392. CWbemPathCracker pathCracker;
  393. pathCracker.SetServer (bsServer);
  394. pathCracker.SetNamespacePath (defaultNamespace);
  395. ok = pathCracker.GetPathText (bsPath, false, true);
  396. }
  397. }
  398. else
  399. {
  400. CWbemPathCracker pathCracker;
  401. pathCracker.SetServer (bsServer);
  402. pathCracker.SetNamespacePath (bsNamespace);
  403. ok = pathCracker.GetPathText (bsPath, false, true);
  404. }
  405. if (ok)
  406. namespacePath = bsPath.Detach ();
  407. return namespacePath;
  408. }
  409. //***************************************************************************
  410. //
  411. // SCODE CSWbemLocator::GetDefaultNamespace
  412. //
  413. // DESCRIPTION:
  414. //
  415. // Get the default namespace path
  416. //
  417. // PARAMETERS:
  418. //
  419. // None
  420. //
  421. // RETURN VALUES:
  422. //
  423. // The default Namespace.
  424. //
  425. //***************************************************************************
  426. const wchar_t *CSWbemLocator::GetDefaultNamespace ()
  427. {
  428. if (!s_pDefaultNamespace)
  429. {
  430. // Get the value from the registry key
  431. HKEY hKey;
  432. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  433. WBEMS_RK_SCRIPTING, 0, KEY_QUERY_VALUE, &hKey))
  434. {
  435. DWORD dataLen = 0;
  436. // Find out how much space to allocate first
  437. if (ERROR_SUCCESS == RegQueryValueEx (hKey, WBEMS_RV_DEFNS,
  438. NULL, NULL, NULL, &dataLen))
  439. {
  440. TCHAR *defNamespace = new TCHAR [dataLen];
  441. if (defNamespace)
  442. {
  443. if (ERROR_SUCCESS == RegQueryValueEx (hKey, WBEMS_RV_DEFNS,
  444. NULL, NULL, (LPBYTE) defNamespace, &dataLen))
  445. {
  446. #ifndef UNICODE
  447. // Convert the multibyte value to its wide character equivalent
  448. int wDataLen = MultiByteToWideChar(CP_ACP, 0, defNamespace, -1, NULL, 0);
  449. s_pDefaultNamespace = new wchar_t [wDataLen];
  450. if (s_pDefaultNamespace)
  451. MultiByteToWideChar(CP_ACP, 0, defNamespace, -1, s_pDefaultNamespace, wDataLen);
  452. #else
  453. s_pDefaultNamespace = new wchar_t [wcslen (defNamespace) + 1];
  454. if (s_pDefaultNamespace)
  455. wcscpy (s_pDefaultNamespace, defNamespace);
  456. #endif
  457. }
  458. delete [] defNamespace;
  459. }
  460. }
  461. RegCloseKey (hKey);
  462. }
  463. // If we failed to read the registry OK, just use the default
  464. if (!s_pDefaultNamespace)
  465. {
  466. #ifndef UNICODE
  467. int wDataLen = MultiByteToWideChar(CP_ACP, 0, WBEMS_DEFNS, -1, NULL, 0);
  468. s_pDefaultNamespace = new wchar_t [wDataLen];
  469. if (s_pDefaultNamespace)
  470. MultiByteToWideChar(CP_ACP, 0, WBEMS_DEFNS, -1, s_pDefaultNamespace, wDataLen);
  471. #else
  472. s_pDefaultNamespace = new wchar_t [wcslen (WBEMS_DEFNS) + 1];
  473. if (s_pDefaultNamespace)
  474. wcscpy (s_pDefaultNamespace, WBEMS_DEFNS);
  475. #endif
  476. }
  477. }
  478. return s_pDefaultNamespace;
  479. }
  480. //***************************************************************************
  481. //
  482. // SCODE CSWbemLocator::get_Security_
  483. //
  484. // DESCRIPTION:
  485. //
  486. // Return the security configurator
  487. //
  488. // WBEM_S_NO_ERROR success
  489. // WBEM_E_INVALID_PARAMETER bad input parameters
  490. // WBEM_E_FAILED otherwise
  491. //
  492. //***************************************************************************
  493. HRESULT CSWbemLocator::get_Security_ (
  494. ISWbemSecurity **ppSecurity
  495. )
  496. {
  497. HRESULT hr = WBEM_E_FAILED;
  498. ResetLastErrors ();
  499. if (NULL == ppSecurity)
  500. hr = WBEM_E_INVALID_PARAMETER;
  501. else // Bug ID 566345
  502. {
  503. *ppSecurity = NULL;
  504. if (m_SecurityInfo)
  505. {
  506. if (SUCCEEDED (m_SecurityInfo->QueryInterface (IID_ISWbemSecurity,
  507. (PPVOID) ppSecurity)))
  508. hr = WBEM_S_NO_ERROR;
  509. }
  510. }
  511. if (FAILED(hr))
  512. m_Dispatch.RaiseException (hr);
  513. return hr;
  514. }