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.

1041 lines
28 KiB

  1. //=============================================================================
  2. //
  3. // Copyright (c) 1996-1999, Microsoft Corporation, All rights reserved
  4. //
  5. // ESSSINK.CPP
  6. //
  7. // This files implements the class that implements IWbemObjectSink for the ESS.
  8. //
  9. // See esssink.h for documentation.
  10. //
  11. // History:
  12. //
  13. // 11/27/96 a-levn Compiles
  14. //
  15. //=============================================================================
  16. #include "precomp.h"
  17. #include <wincrypt.h>
  18. #include <stdio.h>
  19. #include "ess.h"
  20. #include "esssink.h"
  21. #define IN_ESS_OPERATION \
  22. CInEssSharedLock isl( &m_pObject->m_Lock, FALSE ); \
  23. if ( m_pObject->m_pEss == NULL ) \
  24. return WBEM_E_INVALID_OPERATION; \
  25. if ( m_pObject->m_bShutdown ) \
  26. return WBEM_E_SHUTTING_DOWN;
  27. //*****************************************************************************
  28. // public
  29. //
  30. // See esssink.h for documentation
  31. //
  32. //*****************************************************************************
  33. CEssObjectSink::CEssObjectSink(CLifeControl* pControl, IUnknown* pOuter)
  34. : CUnk(pControl, pOuter), m_XESS(this), m_XNewESS(this), m_XShutdown(this),
  35. m_XHook(this), m_bShutdown(FALSE), m_pEss(NULL), m_pCoreServices(NULL),
  36. m_pIFactory(NULL)
  37. {
  38. ZeroMemory( m_achSecretBytes, SECRET_SIZE );
  39. }
  40. //*****************************************************************************
  41. // public
  42. //
  43. // See esssink.h for documentation
  44. //
  45. //*****************************************************************************
  46. CEssObjectSink::~CEssObjectSink()
  47. {
  48. if( m_pCoreServices )
  49. {
  50. m_pCoreServices->Release();
  51. }
  52. if ( m_pIFactory )
  53. {
  54. m_pIFactory->Release();
  55. }
  56. }
  57. //*****************************************************************************
  58. // public
  59. //
  60. // See esssink.h for documentation
  61. //
  62. //*****************************************************************************
  63. void* CEssObjectSink::GetInterface(REFIID riid)
  64. {
  65. if(riid == IID_IWbemEventSubsystem_m4)
  66. return &m_XESS;
  67. else if(riid == IID_IWbemShutdown)
  68. return &m_XShutdown;
  69. else if(riid == IID__IWmiESS)
  70. return &m_XNewESS;
  71. else if(riid == IID__IWmiCoreWriteHook)
  72. return &m_XHook;
  73. return NULL;
  74. }
  75. HRESULT CEssObjectSink::SetSecret( IWbemContext* pCtx )
  76. {
  77. VARIANT vSecret;
  78. VariantInit( &vSecret );
  79. CClearMe cm( &vSecret );
  80. V_ARRAY(&vSecret) = SafeArrayCreateVector( VT_UI1, 0, SECRET_SIZE );
  81. if ( V_ARRAY(&vSecret) == NULL )
  82. return WBEM_E_OUT_OF_MEMORY;
  83. V_VT(&vSecret) = VT_ARRAY | VT_UI1;
  84. PBYTE pData;
  85. HRESULT hr = SafeArrayAccessData( V_ARRAY(&vSecret), (void**)&pData );
  86. if ( FAILED(hr) )
  87. return WBEM_E_OUT_OF_MEMORY;
  88. CUnaccessMe um( V_ARRAY(&vSecret) );
  89. memcpy( pData, m_achSecretBytes, SECRET_SIZE );
  90. return pCtx->SetValue( L"__SecretEssBytes", 0, &vSecret );
  91. }
  92. HRESULT CEssObjectSink::VerifySecret( IWbemContext* pCtx )
  93. {
  94. VARIANT vSecret;
  95. VariantInit(&vSecret);
  96. HRESULT hr = pCtx->GetValue( L"__SecretEssBytes", 0, &vSecret );
  97. if ( FAILED(hr) )
  98. return hr;
  99. CClearMe cm(&vSecret);
  100. if ( V_VT(&vSecret) != (VT_ARRAY | VT_UI1) )
  101. return WBEM_E_ACCESS_DENIED;
  102. long lUBound;
  103. hr = SafeArrayGetUBound( V_ARRAY(&vSecret), 1, &lUBound );
  104. if ( FAILED(hr) )
  105. return WBEM_E_CRITICAL_ERROR;
  106. if ( lUBound + 1 < SECRET_SIZE )
  107. return WBEM_E_ACCESS_DENIED;
  108. PBYTE pData;
  109. hr = SafeArrayAccessData( V_ARRAY(&vSecret), (void**)&pData );
  110. if ( FAILED(hr) )
  111. return WBEM_E_OUT_OF_MEMORY;
  112. CUnaccessMe um( V_ARRAY(&vSecret) );
  113. if ( memcmp( pData, m_achSecretBytes, SECRET_SIZE ) != 0 )
  114. return WBEM_E_ACCESS_DENIED;
  115. return WBEM_S_NO_ERROR;
  116. }
  117. HRESULT CEssObjectSink::PrepareCurrentEssThreadObject( IWbemContext* pContext )
  118. {
  119. CWbemPtr<IWbemContext> pNewContext = NULL;
  120. VARIANT vValue;
  121. HRESULT hr;
  122. if ( pContext )
  123. {
  124. hr = pContext->Clone( &pNewContext );
  125. if ( SUCCEEDED( hr ) )
  126. {
  127. hr = pNewContext->GetValue( L"__ReentranceTestProp", 0, &vValue );
  128. if ( WBEM_E_NOT_FOUND == hr )
  129. {
  130. V_VT(&vValue) = VT_BOOL;
  131. V_BOOL(&vValue) = VARIANT_FALSE;
  132. hr = pNewContext->SetValue( L"__ReentranceTestProp",
  133. 0,
  134. &vValue );
  135. if ( SUCCEEDED(hr) )
  136. {
  137. hr = SetSecret( pNewContext );
  138. }
  139. }
  140. else if ( FAILED( hr ) )
  141. {
  142. return hr;
  143. }
  144. else
  145. {
  146. hr = VerifySecret( pNewContext );
  147. if ( SUCCEEDED(hr) )
  148. {
  149. V_VT(&vValue) = VT_BOOL;
  150. V_BOOL(&vValue) = VARIANT_TRUE;
  151. hr = pNewContext->SetValue( L"__ReentranceTestProp",
  152. 0,
  153. &vValue );
  154. }
  155. }
  156. }
  157. }
  158. else
  159. {
  160. _DBG_ASSERT( m_pIFactory );
  161. hr = m_pIFactory->CreateInstance( NULL,
  162. IID_IWbemContext,
  163. ( void** )&pNewContext );
  164. if ( SUCCEEDED( hr ) )
  165. {
  166. V_VT(&vValue) = VT_BOOL;
  167. V_BOOL(&vValue) = VARIANT_FALSE;
  168. hr = pNewContext->SetValue( L"__ReentranceTestProp", 0, &vValue );
  169. }
  170. if ( SUCCEEDED(hr) )
  171. {
  172. hr = SetSecret( pNewContext );
  173. }
  174. }
  175. if ( FAILED( hr ) )
  176. {
  177. return hr;
  178. }
  179. SetCurrentEssThreadObject( pNewContext );
  180. if ( NULL == GetCurrentEssThreadObject( ) )
  181. {
  182. return WBEM_E_OUT_OF_MEMORY;
  183. }
  184. return S_OK;
  185. }
  186. //*****************************************************************************
  187. // public
  188. //
  189. // See esssink.h for documentation
  190. //
  191. //*****************************************************************************
  192. STDMETHODIMP CEssObjectSink::XESS::ProcessInternalEvent(long lSendType,
  193. LPCWSTR str1, LPCWSTR str2,
  194. LPCWSTR str3, DWORD dw1, DWORD dw2, DWORD dwObjectCount,
  195. _IWmiObject** apObjects, IWbemContext* pContext)
  196. {
  197. IN_ESS_OPERATION
  198. CEventRepresentation Event;
  199. Event.type = lSendType;
  200. Event.dw1 = dw1;
  201. Event.dw2 = dw2;
  202. Event.wsz1 = (LPWSTR)str1;
  203. Event.wsz2 = (LPWSTR)str2;
  204. Event.wsz3 = (LPWSTR)str3;
  205. Event.nObjects = (int)dwObjectCount;
  206. Event.apObjects = (IWbemClassObject**)apObjects;
  207. // Store the old context value for the future
  208. // ==========================================
  209. CEssThreadObject* pOldThreadObject = GetCurrentEssThreadObject();
  210. // Set it to the current one
  211. // =========================
  212. HRESULT hres = m_pObject->PrepareCurrentEssThreadObject(pContext);
  213. if ( FAILED( hres ) )
  214. {
  215. return hres;
  216. }
  217. //
  218. // we must remove the client's security context from the thread because
  219. // it is really winmgmt raising these events, not the client.
  220. //
  221. IUnknown *pGarb, *pCtx = NULL;
  222. hres = CoSwitchCallContext( NULL, &pCtx );
  223. if ( SUCCEEDED( hres ) )
  224. {
  225. // Do the actual processing
  226. // ========================
  227. hres = m_pObject->m_pEss->ProcessEvent(Event, (long)dw2);
  228. // Restore the context
  229. // ===================
  230. HRESULT hr = CoSwitchCallContext( pCtx, &pGarb );
  231. if ( SUCCEEDED( hres ) )
  232. {
  233. hres = hr;
  234. }
  235. }
  236. CEssThreadObject* pNewThreadObject = GetCurrentEssThreadObject();
  237. delete pNewThreadObject;
  238. if(pOldThreadObject)
  239. {
  240. SetConstructedEssThreadObject(pOldThreadObject);
  241. }
  242. else
  243. {
  244. ClearCurrentEssThreadObject();
  245. }
  246. return hres;
  247. }
  248. STDMETHODIMP CEssObjectSink::XESS::VerifyInternalEvent(long lSendType,
  249. LPCWSTR str1, LPCWSTR str2,
  250. LPCWSTR str3, DWORD dw1, DWORD dw2, DWORD dwObjectCount,
  251. _IWmiObject** apObjects, IWbemContext* pContext)
  252. {
  253. IN_ESS_OPERATION
  254. CEventRepresentation Event;
  255. Event.type = lSendType;
  256. Event.dw1 = dw1;
  257. Event.dw2 = dw2;
  258. Event.wsz1 = (LPWSTR)str1;
  259. Event.wsz2 = (LPWSTR)str2;
  260. Event.wsz3 = (LPWSTR)str3;
  261. Event.nObjects = (int)dwObjectCount;
  262. Event.apObjects = (IWbemClassObject**)apObjects;
  263. // Store the old context value for the future
  264. // ==========================================
  265. CEssThreadObject* pOldThreadObject = GetCurrentEssThreadObject();
  266. // Set it to the current one
  267. // =========================
  268. SetCurrentEssThreadObject(pContext);
  269. if ( GetCurrentEssThreadObject() == NULL )
  270. {
  271. SetConstructedEssThreadObject(pOldThreadObject);
  272. return WBEM_E_OUT_OF_MEMORY;
  273. }
  274. // Do the actual processing
  275. // ========================
  276. HRESULT hres = m_pObject->m_pEss->VerifyInternalEvent(Event);
  277. // Restore the context
  278. // ===================
  279. CEssThreadObject* pNewThreadObject = GetCurrentEssThreadObject();
  280. delete pNewThreadObject;
  281. if(pOldThreadObject)
  282. {
  283. SetConstructedEssThreadObject(pOldThreadObject);
  284. }
  285. else
  286. {
  287. ClearCurrentEssThreadObject();
  288. }
  289. return hres;
  290. }
  291. STDMETHODIMP CEssObjectSink::XESS::RegisterNotificationSink(
  292. LPCWSTR wszNamespace,
  293. LPCWSTR wszQueryLanguage, LPCWSTR wszQuery, long lFlags,
  294. IWbemContext* pContext, IWbemObjectSink* pSink)
  295. {
  296. IN_ESS_OPERATION
  297. // Store the old context value for the future
  298. // ==========================================
  299. CEssThreadObject* pOldThreadObject = GetCurrentEssThreadObject();
  300. // Set it to the current one
  301. // =========================
  302. HRESULT hres = m_pObject->PrepareCurrentEssThreadObject(pContext);
  303. if ( FAILED( hres ) )
  304. {
  305. SetConstructedEssThreadObject( pOldThreadObject );
  306. return hres;
  307. }
  308. // Do the actual processing
  309. // ========================
  310. hres = m_pObject->m_pEss->RegisterNotificationSink(wszNamespace,
  311. wszQueryLanguage, wszQuery, lFlags, pContext, pSink);
  312. // Restore the context
  313. // ===================
  314. CEssThreadObject* pNewThreadObject = GetCurrentEssThreadObject();
  315. delete pNewThreadObject;
  316. if(pOldThreadObject)
  317. {
  318. SetConstructedEssThreadObject(pOldThreadObject);
  319. }
  320. else
  321. {
  322. ClearCurrentEssThreadObject();
  323. }
  324. // Return
  325. // ======
  326. if(FAILED(hres))
  327. {
  328. pSink->SetStatus(0, hres, NULL, NULL);
  329. }
  330. return hres;
  331. }
  332. STDMETHODIMP CEssObjectSink::XESS::RemoveNotificationSink(
  333. IWbemObjectSink* pSink)
  334. {
  335. IN_ESS_OPERATION
  336. // Store the old context value for the future
  337. // ==========================================
  338. CEssThreadObject* pOldThreadObject = GetCurrentEssThreadObject();
  339. // Set it to the current one
  340. // =========================
  341. SetCurrentEssThreadObject(NULL);
  342. if ( GetCurrentEssThreadObject() == NULL )
  343. {
  344. SetConstructedEssThreadObject(pOldThreadObject);
  345. return WBEM_E_OUT_OF_MEMORY;
  346. }
  347. // Do the actual processing
  348. // ========================
  349. HRESULT hres = m_pObject->m_pEss->RemoveNotificationSink(pSink);
  350. // Restore the context
  351. // ===================
  352. CEssThreadObject* pNewThreadObject = GetCurrentEssThreadObject();
  353. delete pNewThreadObject;
  354. if(pOldThreadObject)
  355. {
  356. SetConstructedEssThreadObject(pOldThreadObject);
  357. }
  358. else
  359. {
  360. ClearCurrentEssThreadObject();
  361. }
  362. return hres;
  363. }
  364. STDMETHODIMP CEssObjectSink::XESS::GetNamespaceSink(LPCWSTR wszNamespace,
  365. IWbemObjectSink** ppSink)
  366. {
  367. IN_ESS_OPERATION
  368. CEssNamespaceSink* pSink = _new CEssNamespaceSink(m_pObject->m_pEss,
  369. m_pObject->m_pControl);
  370. if(pSink == NULL)
  371. return WBEM_E_OUT_OF_MEMORY;
  372. HRESULT hres = pSink->Initialize(wszNamespace);
  373. if(FAILED(hres))
  374. {
  375. delete pSink;
  376. return hres;
  377. }
  378. return pSink->QueryInterface(IID_IWbemObjectSink, (void**)ppSink);
  379. }
  380. STDMETHODIMP CEssObjectSink::XNewESS::Initialize( long lFlags,
  381. IWbemContext* pCtx,
  382. _IWmiCoreServices* pServices)
  383. {
  384. //
  385. // This function is not multi-thread safe by design. We do not support
  386. // concurrent operations while in this function. The expectation is that
  387. // the user will call this method and THEN introduce the object into
  388. // an environment where it can be called concurrently.
  389. //
  390. //
  391. // This object will not support being called after a failed initialization.
  392. // The user must deallocate the object and then allocate a new one.
  393. //
  394. HRESULT hres;
  395. hres = CoGetClassObject( CLSID_WbemContext,
  396. CLSCTX_INPROC_SERVER,
  397. NULL,
  398. IID_IClassFactory,
  399. ( void** )&m_pObject->m_pIFactory );
  400. if ( FAILED( hres ) )
  401. {
  402. return hres;
  403. }
  404. if ( m_pObject->m_pEss != NULL )
  405. {
  406. return WBEM_S_FALSE;
  407. }
  408. if ( m_pObject->m_bShutdown )
  409. {
  410. return WBEM_E_INVALID_OPERATION;
  411. }
  412. if ( !m_pObject->m_Lock.Initialize() )
  413. {
  414. return WBEM_E_OUT_OF_MEMORY;
  415. }
  416. //
  417. // set shutdown to true in case we exit prematurely. This will prevent
  418. // any future calls to this function after a failed init.
  419. //
  420. m_pObject->m_bShutdown = TRUE;
  421. //
  422. // Get current machine name --- core is not giving it to us anymore
  423. //
  424. WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH+1];
  425. DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1;
  426. if(!GetComputerNameW(wszComputerName, &dwSize))
  427. {
  428. ERRORTRACE((LOG_ESS, "Cannot retrieve computer name: %d\n",
  429. GetLastError()));
  430. return WBEM_E_CRITICAL_ERROR;
  431. }
  432. //
  433. // Get the decorator from core services
  434. //
  435. CWbemPtr<IWbemDecorator> pDecor;
  436. hres = pServices->GetDecorator(0, &pDecor);
  437. if(FAILED(hres))
  438. {
  439. ERRORTRACE((LOG_ESS, "Cannot retrieve decorator: 0x%X\n", hres));
  440. return WBEM_E_CRITICAL_ERROR;
  441. }
  442. //
  443. // Hook all core write operations
  444. //
  445. m_pObject->m_pCoreServices = pServices;
  446. m_pObject->m_pCoreServices->AddRef();
  447. hres = m_pObject->m_pCoreServices->RegisterWriteHook(
  448. WBEM_FLAG_INST_PUT|WBEM_FLAG_INST_DELETE|WBEM_FLAG_DISABLE_WHEN_OWNER_UPDATE,
  449. &m_pObject->m_XHook);
  450. if(FAILED(hres))
  451. {
  452. ERRORTRACE((LOG_ESS, "Unable to hook core write operations: 0x%X\n",
  453. hres));
  454. return WBEM_E_CRITICAL_ERROR;
  455. }
  456. //
  457. // generate secret value. See hdr for info on how this is used.
  458. //
  459. HCRYPTPROV hCryptProv;
  460. if ( CryptAcquireContext( &hCryptProv,
  461. NULL,
  462. NULL,
  463. PROV_RSA_FULL,
  464. CRYPT_VERIFYCONTEXT ) )
  465. {
  466. BOOL bRes = CryptGenRandom( hCryptProv,
  467. SECRET_SIZE,
  468. m_pObject->m_achSecretBytes );
  469. CryptReleaseContext( hCryptProv, 0 );
  470. if ( !bRes )
  471. return HRESULT_FROM_WIN32( GetLastError() );
  472. }
  473. else
  474. {
  475. return HRESULT_FROM_WIN32( GetLastError() );
  476. }
  477. //
  478. // Initialize for real
  479. //
  480. CEss* pEss = NULL;
  481. try
  482. {
  483. pEss = new CEss();
  484. }
  485. catch(CX_MemoryException)
  486. {
  487. return WBEM_E_OUT_OF_MEMORY;
  488. }
  489. if ( pEss == NULL )
  490. {
  491. return WBEM_E_OUT_OF_MEMORY;
  492. }
  493. //
  494. // create a context object that will be passed around with all work that
  495. // is done on behalf of ess init.
  496. //
  497. CWbemPtr<IWbemContext> pContext;
  498. hres = CoCreateInstance( CLSID_WbemContext,
  499. NULL,
  500. CLSCTX_INPROC_SERVER,
  501. IID_IWbemContext,
  502. (void**)&pContext );
  503. if ( SUCCEEDED(hres) )
  504. {
  505. //
  506. // set the context to be an init context object.
  507. //
  508. VARIANT vInit;
  509. V_VT(&vInit) = VT_BOOL;
  510. V_BOOL(&vInit) = VARIANT_TRUE;
  511. hres = pContext->SetValue( L"__EssInInitialize", 0, &vInit );
  512. }
  513. if ( SUCCEEDED(hres) )
  514. {
  515. //
  516. // attach the init context to the thread
  517. //
  518. hres = m_pObject->PrepareCurrentEssThreadObject(pContext);
  519. }
  520. if ( FAILED(hres) )
  521. {
  522. delete pEss;
  523. ERRORTRACE(( LOG_ESS, "Error creating ess context object during init"
  524. "HR=0x%x\n", hres ));
  525. return hres;
  526. }
  527. hres = pEss->Initialize( wszComputerName, lFlags, pServices, pDecor );
  528. //
  529. // Restore the context
  530. //
  531. CEssThreadObject* pNewThreadObject = GetCurrentEssThreadObject();
  532. delete pNewThreadObject;
  533. ClearCurrentEssThreadObject();
  534. if ( FAILED(hres) )
  535. {
  536. delete pEss;
  537. return hres;
  538. }
  539. m_pObject->m_pEss = pEss;
  540. m_pObject->m_bShutdown = FALSE;
  541. return hres;
  542. }
  543. STDMETHODIMP CEssObjectSink::XNewESS::ExecNotificationQuery(
  544. LPCWSTR wszNamespace, LPCWSTR wszQueryText, long lFlags,
  545. IWbemContext* pContext, IWbemObjectSink* pSink)
  546. {
  547. return m_pObject->m_XESS.RegisterNotificationSink(wszNamespace,
  548. L"WQL", wszQueryText, lFlags, pContext, pSink);
  549. }
  550. STDMETHODIMP CEssObjectSink::XNewESS::CancelAsyncCall(IWbemObjectSink* pSink)
  551. {
  552. return m_pObject->m_XESS.RemoveNotificationSink(pSink);
  553. }
  554. STDMETHODIMP CEssObjectSink::XNewESS::QueryObjectSink(LPCWSTR wszNamespace,
  555. IWbemObjectSink** ppSink)
  556. {
  557. return m_pObject->m_XESS.GetNamespaceSink(wszNamespace, ppSink);
  558. }
  559. STDMETHODIMP CEssObjectSink::XESS::Initialize(LPCWSTR wszServer,
  560. IWbemLocator* pAdminLocator,
  561. IUnknown* pServices)
  562. {
  563. //
  564. // Use the _IWmiESS version.
  565. //
  566. return WBEM_E_NOT_SUPPORTED;
  567. }
  568. STDMETHODIMP CEssObjectSink::XShutdown::Shutdown( LONG uReason,
  569. ULONG uMaxMilliseconds,
  570. IWbemContext* pCtx )
  571. {
  572. // uMaxMilliseconds == 0 means system shutdown
  573. if (0 == uMaxMilliseconds)
  574. return WBEM_S_NO_ERROR;
  575. {
  576. //
  577. // wait for all current operations to complete. Lock will prevent
  578. // any new operations from getting through.
  579. //
  580. CInEssSharedLock isl( &m_pObject->m_Lock, TRUE );
  581. if ( m_pObject->m_bShutdown )
  582. {
  583. return WBEM_S_FALSE;
  584. }
  585. m_pObject->m_bShutdown = TRUE;
  586. }
  587. HRESULT hres;
  588. //
  589. // Unhook all core write operations
  590. //
  591. hres = m_pObject->m_pCoreServices->UnregisterWriteHook(
  592. &m_pObject->m_XHook);
  593. if(FAILED(hres))
  594. {
  595. ERRORTRACE((LOG_ESS, "Unable to unhook core write operations: 0x%X\n",
  596. hres));
  597. }
  598. SetCurrentEssThreadObject(NULL);
  599. if ( GetCurrentEssThreadObject() == NULL )
  600. {
  601. return WBEM_E_OUT_OF_MEMORY;
  602. }
  603. hres = m_pObject->m_pEss->Shutdown((0 == uMaxMilliseconds)?TRUE:FALSE);
  604. CEssThreadObject* pNewThreadObject = GetCurrentEssThreadObject();
  605. delete pNewThreadObject;
  606. ClearCurrentEssThreadObject();
  607. if ( m_pObject->m_pEss != NULL )
  608. {
  609. delete m_pObject->m_pEss;
  610. m_pObject->m_pEss = NULL;
  611. }
  612. return hres;
  613. }
  614. STDMETHODIMP CEssObjectSink::XESS::Shutdown()
  615. {
  616. HRESULT hres;
  617. {
  618. //
  619. // wait for all current operations to complete. Lock will prevent
  620. // any new operations from getting through.
  621. //
  622. CInEssSharedLock isl( &m_pObject->m_Lock, TRUE );
  623. if ( m_pObject->m_bShutdown )
  624. {
  625. return WBEM_S_FALSE;
  626. }
  627. m_pObject->m_bShutdown = TRUE;
  628. }
  629. SetCurrentEssThreadObject(NULL);
  630. if ( GetCurrentEssThreadObject() == NULL )
  631. {
  632. return WBEM_E_OUT_OF_MEMORY;
  633. }
  634. hres = m_pObject->m_pEss->Shutdown(FALSE); // no system shutdown
  635. CEssThreadObject* pNewThreadObject = GetCurrentEssThreadObject();
  636. delete pNewThreadObject;
  637. ClearCurrentEssThreadObject();
  638. return hres;
  639. }
  640. STDMETHODIMP CEssObjectSink::XESS::LastCallForCore(LONG bIsSystemShutdown)
  641. {
  642. IN_ESS_OPERATION
  643. return m_pObject->m_pEss->LastCallForCore(bIsSystemShutdown);
  644. }
  645. //*********************** NAMESPACE SINK **************************************
  646. //******************************************************************************
  647. // public
  648. //
  649. // See esssink.h for documentation
  650. //
  651. //******************************************************************************
  652. CEssNamespaceSink::CEssNamespaceSink(CEss* pEss,
  653. CLifeControl* pControl, IUnknown* pOuter) :
  654. CUnk(pControl, pOuter), m_XSink(this),
  655. m_pEss(pEss)
  656. {
  657. }
  658. HRESULT CEssNamespaceSink::Initialize(LPCWSTR wszNamespace)
  659. {
  660. m_strNamespace = SysAllocString(wszNamespace);
  661. if(m_strNamespace == NULL)
  662. return WBEM_E_OUT_OF_MEMORY;
  663. return WBEM_S_NO_ERROR;
  664. }
  665. //******************************************************************************
  666. // public
  667. //
  668. // See esssink.h for documentation
  669. //
  670. //******************************************************************************
  671. CEssNamespaceSink::~CEssNamespaceSink()
  672. {
  673. SysFreeString(m_strNamespace);
  674. }
  675. //******************************************************************************
  676. // public
  677. //
  678. // See esssink.h for documentation
  679. //
  680. //******************************************************************************
  681. void* CEssNamespaceSink::GetInterface(REFIID riid)
  682. {
  683. if(riid == IID_IWbemObjectSink || riid == IID_IUnknown)
  684. {
  685. return &m_XSink;
  686. }
  687. return NULL;
  688. }
  689. //******************************************************************************
  690. // public
  691. //
  692. // See esssink.h for documentation
  693. //
  694. //******************************************************************************
  695. STDMETHODIMP CEssNamespaceSink::XSink::Indicate(long lObjectCount,
  696. IWbemClassObject** apObjArray)
  697. {
  698. HRESULT hres = WBEM_S_NO_ERROR;
  699. for(int i = 0; i < lObjectCount; i++)
  700. {
  701. IWbemClassObject* pEvent = apObjArray[i];
  702. if ( pEvent == NULL )
  703. return WBEM_E_INVALID_PARAMETER;
  704. CEventRepresentation Event;
  705. hres = Event.CreateFromObject(pEvent, m_pObject->m_strNamespace);
  706. if ( FAILED(hres) )
  707. break;
  708. hres = m_pObject->m_pEss->ProcessQueryObjectSinkEvent( Event );
  709. if ( FAILED(hres) )
  710. break;
  711. }
  712. return hres;
  713. }
  714. STDMETHODIMP CEssObjectSink::XHook::PrePut(long lFlags, long lUserFlags,
  715. IWbemContext* pContext,
  716. IWbemPath* pPath, LPCWSTR wszNamespace,
  717. LPCWSTR wszClass, _IWmiObject* pCopy)
  718. {
  719. HRESULT hres;
  720. IN_ESS_OPERATION
  721. //
  722. // Construct the old CEventRepresentation --- simplest route
  723. //
  724. CEventRepresentation Event;
  725. //
  726. // Determine whether a class or an instance is being put
  727. //
  728. if(pCopy->IsObjectInstance() == S_OK)
  729. Event.type = e_EventTypeInstanceCreation;
  730. else
  731. Event.type = e_EventTypeClassCreation;
  732. Event.dw1 = 0;
  733. Event.dw2 = 0;
  734. Event.wsz1 = (LPWSTR)wszNamespace;
  735. Event.wsz2 = (LPWSTR)wszClass;
  736. Event.wsz3 = NULL;
  737. Event.nObjects = 1;
  738. Event.apObjects = (IWbemClassObject**)&pCopy;
  739. // Store the old context value for the future
  740. // ==========================================
  741. CEssThreadObject* pOldThreadObject = GetCurrentEssThreadObject();
  742. // Set it to the current one
  743. // =========================
  744. SetCurrentEssThreadObject(pContext);
  745. if ( GetCurrentEssThreadObject() == NULL )
  746. {
  747. SetConstructedEssThreadObject(pOldThreadObject);
  748. return WBEM_E_OUT_OF_MEMORY;
  749. }
  750. // Do the actual processing
  751. // ========================
  752. hres = m_pObject->m_pEss->VerifyInternalEvent(Event);
  753. // Restore the context
  754. // ===================
  755. CEssThreadObject* pNewThreadObject = GetCurrentEssThreadObject();
  756. delete pNewThreadObject;
  757. if(pOldThreadObject)
  758. {
  759. SetConstructedEssThreadObject(pOldThreadObject);
  760. }
  761. else
  762. {
  763. ClearCurrentEssThreadObject();
  764. }
  765. return hres;
  766. }
  767. STDMETHODIMP CEssObjectSink::XHook::PostPut(long lFlags, HRESULT hApiResult,
  768. IWbemContext* pContext,
  769. IWbemPath* pPath, LPCWSTR wszNamespace,
  770. LPCWSTR wszClass, _IWmiObject* pNew,
  771. _IWmiObject* pOld)
  772. {
  773. return WBEM_S_NO_ERROR;
  774. }
  775. STDMETHODIMP CEssObjectSink::XHook::PreDelete(long lFlags, long lUserFlags,
  776. IWbemContext* pContext,
  777. IWbemPath* pPath, LPCWSTR wszNamespace,
  778. LPCWSTR wszClass)
  779. {
  780. return WBEM_S_NO_ERROR;
  781. }
  782. STDMETHODIMP CEssObjectSink::XHook::PostDelete(long lFlags,
  783. HRESULT hApiResult,
  784. IWbemContext* pContext,
  785. IWbemPath* pPath, LPCWSTR wszNamespace,
  786. LPCWSTR wszClass, _IWmiObject* pOld)
  787. {
  788. return WBEM_S_NO_ERROR;
  789. }
  790. /****************************************************************************
  791. CEssInternalOperationSink
  792. *****************************************************************************/
  793. STDMETHODIMP CEssInternalOperationSink::Indicate( long cObjs,
  794. IWbemClassObject** ppObjs )
  795. {
  796. HRESULT hr;
  797. //
  798. // if the calling thread already has a thread object, leave it.
  799. //
  800. CEssThreadObject* pOldThreadObject = GetCurrentEssThreadObject();
  801. if ( pOldThreadObject == NULL )
  802. {
  803. //
  804. // set up a new thread object.
  805. //
  806. SetCurrentEssThreadObject(NULL);
  807. if ( GetCurrentEssThreadObject() == NULL )
  808. {
  809. return WBEM_E_OUT_OF_MEMORY;
  810. }
  811. }
  812. hr = m_pSink->Indicate( cObjs, ppObjs );
  813. //
  814. // delete the thread object if necessary
  815. //
  816. if ( pOldThreadObject == NULL )
  817. {
  818. delete GetCurrentEssThreadObject();
  819. ClearCurrentEssThreadObject();
  820. }
  821. return hr;
  822. }
  823. STDMETHODIMP CEssInternalOperationSink::SetStatus( long lFlags,
  824. HRESULT hres,
  825. BSTR bstr,
  826. IWbemClassObject* pObj )
  827. {
  828. //
  829. // simply delegate ( for now )
  830. //
  831. return m_pSink->SetStatus( lFlags, hres, bstr, pObj );
  832. }