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.

651 lines
14 KiB

  1. #include "precomp.h"
  2. #include <objbase.h>
  3. #include <wbemcli.h>
  4. #include <wbemint.h>
  5. #include <wmiutils.h>
  6. #include "Globals.h"
  7. #include "ProvRegDeCoupled.h"
  8. #include <wmiutils.h>
  9. #include "CGlobals.h"
  10. #include "provcache.h"
  11. #include "aggregator.h"
  12. #include "ProvWsvS.h"
  13. #include "ProvWsv.h"
  14. #include "ProvInSk.h"
  15. #include "ProvobSk.h"
  16. #include <genlex.h>
  17. #include <flexarry.h>
  18. #include <wqllex.h>
  19. struct SWQLColRef;
  20. #include <wqlscan.h>
  21. #include <autoptr.h>
  22. /******************************************************************************
  23. *
  24. * Name:
  25. *
  26. *
  27. * Description:
  28. *
  29. *
  30. *****************************************************************************/
  31. DCProxy :: DCProxy ( ) : m_ReferenceCount ( 0 ) ,
  32. event_only_(false),
  33. m_Sink(NULL),
  34. NULL_IWbemServices( WBEM_E_NOT_AVAILABLE )
  35. {
  36. InterlockedIncrement (&DecoupledProviderSubSystem_Globals::s_ObjectsInProgress);
  37. }
  38. /******************************************************************************
  39. *
  40. * Name:
  41. *
  42. *
  43. * Description:
  44. *
  45. *
  46. *****************************************************************************/
  47. DCProxy :: ~DCProxy ()
  48. {
  49. if (m_aggregator_)
  50. m_aggregator_->deActivate();
  51. InterlockedDecrement (&DecoupledProviderSubSystem_Globals::s_ObjectsInProgress);
  52. }
  53. /******************************************************************************
  54. *
  55. * Name:
  56. *
  57. *
  58. * Description:
  59. *
  60. *
  61. *****************************************************************************/
  62. STDMETHODIMP_(ULONG) DCProxy :: AddRef ( void )
  63. {
  64. return InterlockedIncrement (&m_ReferenceCount) ;
  65. }
  66. /******************************************************************************
  67. *
  68. * Name:
  69. *
  70. *
  71. * Description:
  72. *
  73. *
  74. *****************************************************************************/
  75. STDMETHODIMP_(ULONG) DCProxy :: Release ( void )
  76. {
  77. LONG t_Reference = InterlockedDecrement (&m_ReferenceCount);
  78. if ( 0 == t_Reference )
  79. {
  80. delete this ;
  81. return 0 ;
  82. }
  83. else
  84. {
  85. return t_Reference ;
  86. }
  87. }
  88. /******************************************************************************
  89. *
  90. * Name:
  91. *
  92. *
  93. * Description:
  94. *
  95. *
  96. *****************************************************************************/
  97. STDMETHODIMP
  98. DCProxy :: QueryInterface ( REFIID iid , LPVOID FAR *iplpv )
  99. {
  100. if (iplpv == 0)
  101. return E_POINTER;
  102. if (iid == IID_IUnknown)
  103. {
  104. *iplpv = static_cast<NULL_IWbemServices*>(this) ;
  105. }
  106. else if (iid == IID_IWbemServices)
  107. {
  108. *iplpv = static_cast<IWbemServices *>(this) ;
  109. }
  110. else if (iid == IID_IWbemPropertyProvider)
  111. {
  112. *iplpv = static_cast<IWbemPropertyProvider *>(this);
  113. }
  114. else if ( iid == IID_IWbemProviderInit )
  115. {
  116. *iplpv = static_cast<IWbemProviderInit *>(this) ;
  117. }
  118. else if ( iid == IID_IWbemEventProvider )
  119. {
  120. *iplpv = static_cast<IWbemEventProvider *>(this) ;
  121. }
  122. else if ( iid == IID_IWbemEventProviderSecurity )
  123. {
  124. *iplpv = static_cast<IWbemEventProviderSecurity *>(this) ;
  125. }
  126. else if ( iid == IID_IWbemProviderIdentity )
  127. {
  128. *iplpv = static_cast<IWbemProviderIdentity *>(this) ;
  129. }
  130. else if ( iid == IID_IWbemEventProviderQuerySink)
  131. {
  132. *iplpv = static_cast<IWbemEventProviderQuerySink *>(this) ;
  133. }
  134. else
  135. {
  136. *iplpv = 0;
  137. return E_NOINTERFACE;
  138. }
  139. DCProxy::AddRef () ;
  140. return S_OK;
  141. }
  142. /******************************************************************************
  143. *
  144. * Name:
  145. *
  146. *
  147. * Description:
  148. *
  149. *
  150. *****************************************************************************/
  151. HRESULT DCProxy :: Initialize (
  152. LPWSTR a_User,
  153. LONG a_Flags,
  154. LPWSTR a_Namespace,
  155. LPWSTR a_Locale,
  156. IWbemServices *a_CoreService, // For anybody
  157. IWbemContext *a_Context,
  158. IWbemProviderInitSink *a_Sink // For init signals
  159. )
  160. {
  161. // The connection to the agregator is deffered
  162. if( !a_Sink)
  163. return WBEM_E_INVALID_PARAMETER;
  164. if(!a_CoreService )
  165. return a_Sink->SetStatus ( WBEM_E_INVALID_PARAMETER , 0 ) ;
  166. m_CoreService = a_CoreService;
  167. m_Context = a_Context;
  168. m_Flags = a_Flags;
  169. try{
  170. m_User = a_User;
  171. m_Locale = a_Locale;
  172. m_Namespace = a_Namespace;
  173. // Register the Registrar
  174. if (DC_registrar::instance())
  175. DC_registrar::instance()->Save();
  176. }
  177. catch( _com_error& err)
  178. {
  179. return a_Sink->SetStatus ( WBEM_E_OUT_OF_MEMORY , 0 ) ;
  180. }
  181. // Instance provider - we don't know the provider name
  182. // The real initialization is deffered
  183. if(!event_only_)
  184. return a_Sink->SetStatus ( S_OK , 0 ) ;
  185. // Event provider - safely to initialize
  186. HRESULT hr = _initialize();
  187. return a_Sink->SetStatus ( hr , 0 ) ;
  188. }
  189. /******************************************************************************
  190. *
  191. * Name:
  192. *
  193. *
  194. * Description:
  195. *
  196. *
  197. *****************************************************************************/
  198. HRESULT
  199. DCProxy::GetObjectAsync (const BSTR a_ObjectPath,
  200. long a_Flags,
  201. IWbemContext *a_Context,
  202. IWbemObjectSink *a_Sink)
  203. {
  204. HRESULT t_Result = initialize_from_instance (a_ObjectPath);
  205. if (FAILED (t_Result))
  206. return WBEM_E_FAILED;
  207. return m_aggregator_->GetObjectAsync( a_ObjectPath, a_Flags, a_Context, a_Sink );
  208. }
  209. HRESULT DCProxy :: PutInstanceAsync (
  210. IWbemClassObject *a_Instance,
  211. long a_Flags ,
  212. IWbemContext *a_Context ,
  213. IWbemObjectSink *a_Sink
  214. )
  215. {
  216. HRESULT t_Result = initialize( a_Instance );
  217. if ( FAILED (t_Result ) )
  218. return t_Result;
  219. return m_aggregator_->PutInstanceAsync( a_Instance, a_Flags, a_Context, a_Sink );
  220. }
  221. /******************************************************************************
  222. *
  223. * Name:
  224. *
  225. *
  226. * Description:
  227. *
  228. *
  229. *****************************************************************************/
  230. HRESULT
  231. DCProxy :: DeleteInstanceAsync (
  232. const BSTR a_ObjectPath,
  233. long a_Flags,
  234. IWbemContext *a_Context,
  235. IWbemObjectSink *a_Sink
  236. )
  237. {
  238. HRESULT t_Result = initialize_from_instance (a_ObjectPath);
  239. if (FAILED (t_Result))
  240. return WBEM_E_FAILED;
  241. return m_aggregator_->DeleteInstanceAsync(a_ObjectPath, a_Flags, a_Context, a_Sink );
  242. }
  243. /******************************************************************************
  244. *
  245. * Name:
  246. *
  247. *
  248. * Description:
  249. *
  250. *
  251. *****************************************************************************/
  252. HRESULT
  253. DCProxy::CreateInstanceEnumAsync (const BSTR a_Class ,
  254. long a_Flags ,
  255. IWbemContext *a_Context ,
  256. IWbemObjectSink *a_Sink)
  257. {
  258. HRESULT t_Result = initialize (a_Class);
  259. if (FAILED (t_Result))
  260. return t_Result;
  261. return m_aggregator_->CreateInstanceEnumAsync (a_Class,
  262. a_Flags,
  263. a_Context,
  264. a_Sink);
  265. }
  266. /******************************************************************************
  267. *
  268. * Name:
  269. *
  270. *
  271. * Description:
  272. *
  273. *
  274. *****************************************************************************/
  275. HRESULT
  276. DCProxy::ExecMethodAsync (const BSTR a_ObjectPath,
  277. const BSTR a_MethodName,
  278. long a_Flags,
  279. IWbemContext *a_Context,
  280. IWbemClassObject *a_InParams,
  281. IWbemObjectSink *a_Sink)
  282. {
  283. HRESULT t_Result = initialize (a_ObjectPath);
  284. if (FAILED (t_Result))
  285. return t_Result;
  286. return m_aggregator_->ExecMethodAsync (a_ObjectPath,
  287. a_MethodName,
  288. a_Flags ,
  289. a_Context,
  290. a_InParams,
  291. a_Sink);
  292. }
  293. /******************************************************************************
  294. *
  295. * Name:
  296. *
  297. *
  298. * Description:
  299. *
  300. *
  301. *****************************************************************************/
  302. HRESULT
  303. DCProxy::ProvideEvents (IWbemObjectSink *a_Sink ,
  304. long a_Flags)
  305. {
  306. if (m_aggregator_)
  307. return m_aggregator_->ProvideEvents (a_Sink, a_Flags);
  308. else
  309. return WBEM_E_FAILED;
  310. }
  311. bool
  312. DCProxy::initialized ()
  313. {
  314. return m_aggregator_;
  315. };
  316. HRESULT
  317. DCProxy::_initialize ()
  318. {
  319. DC_DBkey key( m_User, m_Locale, m_Namespace, m_ProviderName);
  320. auto_ref<DCProxyAggr> tmp = DC_registrar::instance()->GetAggregator( key );
  321. if( tmp )
  322. {
  323. if ( tmp->initialized() )
  324. {
  325. m_aggregator_ = tmp;
  326. m_aggregator_->activate();
  327. return S_OK;
  328. }
  329. CServerObject_ProviderInitSink *t_ProviderInitSink = new CServerObject_ProviderInitSink ;
  330. if (t_ProviderInitSink)
  331. {
  332. t_ProviderInitSink->AddRef();
  333. HRESULT hr = tmp ->Initialize(
  334. (wchar_t *)m_User,
  335. m_Flags,
  336. (wchar_t *)m_Namespace,
  337. (wchar_t *)m_Locale,
  338. (wchar_t *)m_ProviderName,
  339. m_CoreService.GetInterfacePtr(),
  340. m_Context.GetInterfacePtr(),
  341. t_ProviderInitSink
  342. );
  343. t_ProviderInitSink->Release();
  344. if( SUCCEEDED ( hr) )
  345. {
  346. m_aggregator_ = tmp;
  347. m_aggregator_->activate();
  348. };
  349. return hr;
  350. }
  351. else
  352. return WBEM_E_OUT_OF_MEMORY ;
  353. }
  354. else
  355. return WBEM_E_OUT_OF_MEMORY ;
  356. };
  357. HRESULT
  358. DCProxy ::initialize (IWbemClassObject * pObj)
  359. {
  360. if (initialized()) return S_OK;
  361. _variant_t v;
  362. HRESULT hr = pObj->Get(L"__CLASS", 0, &v, 0, 0);
  363. // check the HRESULT to see if the action succeeded
  364. if (SUCCEEDED (hr))
  365. {
  366. return initialize ( _bstr_t (v));
  367. }
  368. return WBEM_E_FAILED;
  369. };
  370. HRESULT
  371. DCProxy::initialize (const BSTR _name)
  372. {
  373. if (initialized ())
  374. return S_OK;
  375. LockGuard<CriticalSection> t_guard( DC_registrar::instance()->GetLock());
  376. if (t_guard.locked()==false)
  377. return WBEM_E_OUT_OF_MEMORY;
  378. // Double checked looking variant
  379. if (initialized ())
  380. return S_OK;
  381. IWbemClassObject * t_ObjectPath = NULL ;
  382. IWbemClassObject *Identity ;
  383. HRESULT t_Result = m_CoreService->GetObject (_name ,
  384. 0 ,
  385. m_Context ,
  386. & Identity ,
  387. NULL) ;
  388. if (FAILED (t_Result))
  389. return t_Result;
  390. IWbemQualifierSet *t_QualifierObject = NULL ;
  391. t_Result = Identity->GetQualifierSet (&t_QualifierObject);
  392. if (SUCCEEDED (t_Result))
  393. {
  394. _variant_t prov_name;
  395. t_Result = t_QualifierObject->Get (L"provider", 0, & prov_name, NULL);
  396. if (SUCCEEDED (t_Result))
  397. {
  398. m_ProviderName = (_bstr_t)prov_name;
  399. };
  400. t_QualifierObject->Release();
  401. }
  402. return _initialize();
  403. }
  404. HRESULT
  405. DCProxy::initialize_from_instance (const BSTR _path)
  406. {
  407. if (initialized ())
  408. return S_OK;
  409. wchar_t * pszClassName = NULL;
  410. IWbemPathPtr pPath;
  411. HRESULT t_Result = pPath.CreateInstance (CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER);
  412. if (SUCCEEDED (t_Result))
  413. {
  414. t_Result = pPath->SetText (WBEMPATH_CREATE_ACCEPT_ALL , _path) ;
  415. if (SUCCEEDED (t_Result))
  416. {
  417. ULONG uBuf = 0;
  418. t_Result = pPath->GetClassName(&uBuf, 0);
  419. if (SUCCEEDED (t_Result))
  420. {
  421. pszClassName = new wchar_t[uBuf+1];
  422. if (pszClassName == 0)
  423. return WBEM_E_OUT_OF_MEMORY;
  424. wmilib::auto_buffer<wchar_t> deleteArray(pszClassName);
  425. t_Result = pPath->GetClassName(&uBuf, pszClassName);
  426. if (FAILED(t_Result))
  427. {
  428. return WBEM_E_FAILED;
  429. }
  430. t_Result = initialize (pszClassName);
  431. }
  432. }
  433. }
  434. return t_Result; // The return code is used internally
  435. }
  436. HRESULT DCProxy ::AccessCheck (
  437. WBEM_CWSTR a_QueryLanguage ,
  438. WBEM_CWSTR a_Query ,
  439. long a_SidLength ,
  440. const BYTE *a_Sid
  441. )
  442. {
  443. if( m_aggregator_ )
  444. return m_aggregator_ ->AccessCheck ( a_QueryLanguage, a_Query, a_SidLength, a_Sid);
  445. else
  446. return WBEM_E_FAILED;
  447. }
  448. HRESULT
  449. DCProxy::SetRegistrationObject(
  450. long lFlags,
  451. IWbemClassObject* pProvReg
  452. )
  453. {
  454. HRESULT t_Result = WBEM_E_FAILED;
  455. _variant_t v;
  456. t_Result = pProvReg->Get(L"NAME", 0, &v, 0, 0);
  457. // check the HRESULT to see if the action succeeded
  458. if ( SUCCEEDED( t_Result) )
  459. {
  460. m_ProviderName = (_bstr_t)v;
  461. event_only_ = true;
  462. return WBEM_S_NO_ERROR;
  463. }
  464. else
  465. {
  466. return WBEM_E_FAILED;
  467. }
  468. };
  469. HRESULT
  470. DCProxy::NewQuery(
  471. unsigned long dwId,
  472. WBEM_WSTR wszQueryLanguage,
  473. WBEM_WSTR wszQuery
  474. )
  475. {
  476. if( !initialized() )
  477. return WBEM_E_FAILED;
  478. return m_aggregator_->NewQuery( dwId, wszQueryLanguage, wszQuery );
  479. }
  480. HRESULT
  481. DCProxy::CancelQuery( unsigned long dwId )
  482. {
  483. if( !initialized() )
  484. return WBEM_E_FAILED;
  485. return m_aggregator_->CancelQuery( dwId );
  486. };
  487. HRESULT
  488. DCProxy::ExecQueryAsync(
  489. const BSTR strQueryLanguage,
  490. const BSTR strQuery,
  491. long lFlags,
  492. IWbemContext *pCtx,
  493. IWbemObjectSink *pResponseHandler
  494. )
  495. {
  496. // Try to parse it
  497. // ===============
  498. CTextLexSource src(strQuery);
  499. CWQLScanner Parser(&src);
  500. int nRes = Parser.Parse();
  501. if(nRes != CWQLScanner::SUCCESS)
  502. {
  503. return WBEM_E_INVALID_QUERY;
  504. }
  505. // Successfully parsed. Go to the first tables involved
  506. // ======================================================
  507. CWStringArray awsTables;
  508. Parser.GetReferencedTables(awsTables);
  509. if (awsTables.Size()>0)
  510. {
  511. HRESULT t_Result = initialize( awsTables[0] );
  512. if (SUCCEEDED(t_Result))
  513. {
  514. return m_aggregator_->ExecQueryAsync(
  515. strQueryLanguage,
  516. strQuery,
  517. lFlags,
  518. pCtx,
  519. pResponseHandler );
  520. }
  521. else
  522. return t_Result;
  523. }
  524. else
  525. {
  526. return WBEM_E_FAILED;
  527. }
  528. };
  529. STDMETHODIMP
  530. DCProxy::GetProperty( long lFlags, const BSTR strLocale, const BSTR strClassMapping,
  531. const BSTR strInstMapping, const BSTR strPropMapping, VARIANT *pvValue )
  532. {
  533. return WBEM_S_FALSE;
  534. };
  535. STDMETHODIMP
  536. DCProxy::PutProperty( long lFlags, const BSTR strLocale, const BSTR strClassMapping,
  537. const BSTR strInstMapping, const BSTR strPropMapping, const VARIANT *pvValue )
  538. {
  539. return WBEM_S_FALSE;
  540. }