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.

801 lines
22 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. /////////////////////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include <aclapi.h>
  8. #include <groupsforuser.h>
  9. #include <sql_1.h>
  10. #include <flexq.h>
  11. static CFlexArray g_apRequests; // Shared between all CWMIEvent instances to provide a master event list
  12. extern CCriticalSection * g_pEventCs;
  13. extern CCriticalSection * g_pListCs;
  14. ////////////////////////////////////////////////////////////////////////////////////////////////
  15. class CFlexQueueEx : public CFlexQueue
  16. {
  17. public:
  18. void ResetQueue()
  19. {
  20. delete [] m_ppData;
  21. m_ppData = NULL;
  22. m_nSize = m_nHeadIndex = m_nTailIndex = 0;
  23. }
  24. };
  25. CFlexQueueEx Q;
  26. ////////////////////////////////////////////////////////////////////////////////////////////////
  27. void WINAPI EventCallbackRoutine(PWNODE_HEADER WnodeHeader, ULONG_PTR Context)
  28. {
  29. PWNODE_HEADER * pEventHeader = NULL;
  30. {
  31. CAutoBlock block (g_pListCs);
  32. // Create a queue
  33. pEventHeader = new PWNODE_HEADER;
  34. if( pEventHeader )
  35. {
  36. *pEventHeader = WnodeHeader;
  37. Q.Enqueue(pEventHeader);
  38. }
  39. }
  40. while( TRUE )
  41. {
  42. //scope the use of the critsec...
  43. {
  44. CAutoBlock block( g_pListCs );
  45. if( Q.GetQueueSize() == 0 )
  46. {
  47. Q.ResetQueue();
  48. break;
  49. }
  50. pEventHeader = (PWNODE_HEADER *) Q.Dequeue();
  51. if (pEventHeader == 0)
  52. break;
  53. }
  54. CWMIEvent * p = (CWMIEvent* ) Context;
  55. p->WMIEventCallback(*pEventHeader);
  56. }
  57. }
  58. /////////////////////////////////////////////////////////////////////
  59. void CWMIEvent::SetEventHandler(IWbemObjectSink __RPC_FAR * pHandler)
  60. {
  61. CAutoBlock Block(g_pEventCs);
  62. if( m_pEventHandler )
  63. {
  64. m_pEventHandler->Release();
  65. }
  66. m_pEventHandler = pHandler;
  67. if( m_pEventHandler )
  68. {
  69. m_pEventHandler->AddRef();
  70. }
  71. }
  72. /////////////////////////////////////////////////////////////////////
  73. void CWMIEvent::SetEventServices(IWbemServices __RPC_FAR * pServices)
  74. {
  75. CAutoBlock Block(g_pEventCs);
  76. if( m_pEventServices )
  77. {
  78. m_pEventServices->Release();
  79. }
  80. m_pEventServices = pServices;
  81. if( m_pEventServices )
  82. {
  83. m_pEventServices->AddRef();
  84. }
  85. }
  86. /////////////////////////////////////////////////////////////////////
  87. void CWMIEvent::SetEventContext(IWbemContext __RPC_FAR * pCtx)
  88. {
  89. CAutoBlock Block(g_pEventCs);
  90. if( m_pEventCtx )
  91. {
  92. m_pEventCtx->Release();
  93. }
  94. m_pEventCtx = pCtx;
  95. if( m_pEventCtx )
  96. {
  97. m_pEventCtx->AddRef();
  98. }
  99. }
  100. ////////////////////////////////////////////////////////////////////////
  101. CWMIEvent::CWMIEvent(int nType)
  102. {
  103. m_nType = nType;
  104. m_lRef = 0;
  105. m_pEventHandler = NULL;
  106. m_pEventServices = NULL;
  107. m_pEventCtx = NULL;
  108. if( m_nType != INTERNAL_EVENT )
  109. {
  110. InterlockedIncrement(&g_cObj);
  111. }
  112. m_fReadyForInternalEvents = FALSE;
  113. }
  114. ////////////////////////////////////////////////////////////////////////
  115. CWMIEvent::~CWMIEvent()
  116. {
  117. SAFE_RELEASE_PTR( m_pEventHandler );
  118. SAFE_RELEASE_PTR( m_pEventServices );
  119. SAFE_RELEASE_PTR( m_pEventCtx );
  120. if( m_nType != INTERNAL_EVENT )
  121. {
  122. InterlockedDecrement(&g_cObj);
  123. }
  124. }
  125. void CWMIEvent::ReleaseAllPointers()
  126. {
  127. IWbemObjectSink * pHandler = NULL;
  128. IWbemServices * pServices = NULL;
  129. IWbemContext * pCtx = NULL;
  130. {
  131. CAutoBlock Block(g_pEventCs);
  132. pHandler = m_pEventHandler;
  133. pServices = m_pEventServices;
  134. pCtx = m_pEventCtx;
  135. m_pEventCtx = NULL;
  136. m_pEventServices = NULL;
  137. m_pEventHandler = NULL;
  138. }
  139. SAFE_RELEASE_PTR( pHandler );
  140. SAFE_RELEASE_PTR( pServices );
  141. SAFE_RELEASE_PTR( pCtx );
  142. }
  143. ////////////////////////////////////////////////////////////////////////
  144. HRESULT CWMIEvent::DeleteAllLeftOverEvents()
  145. {
  146. HRESULT hr = WBEM_E_FAILED;
  147. RevertToSelf();
  148. CWMIStandardShell WMI;
  149. if( SUCCEEDED(WMI.Initialize(NULL,FALSE,&m_HandleMap,TRUE,WMIGUID_NOTIFICATION|WMIGUID_QUERY,m_pEventServices,m_pEventHandler,m_pEventCtx)))
  150. {
  151. CAutoBlock Block(g_pEventCs);
  152. // =====================================================
  153. // Remove all requests with this Id
  154. // =====================================================
  155. for( int i = 0; i < g_apRequests.Size(); i++ )
  156. {
  157. WMIEventRequest* pReq = (WMIEventRequest*) g_apRequests[i];
  158. ULONG_PTR uRc =(ULONG_PTR)this;
  159. //===============================================
  160. // Cancel the Event registration, if it fails...
  161. // so what,we are leaving anyway, so delete all
  162. //===============================================
  163. WMI.CancelWMIEventRegistration(pReq->gGuid,uRc);
  164. delete pReq;
  165. }
  166. g_apRequests.Empty();
  167. hr = S_OK;
  168. }
  169. return hr;
  170. }
  171. ////////////////////////////////////////////////////////////////////////
  172. BOOL CWMIEvent::RegisterForInternalEvents( )
  173. {
  174. BOOL fRc = FALSE;
  175. if( m_fReadyForInternalEvents )
  176. {
  177. if( SUCCEEDED(RegisterForRequestedEvent(BINARY_MOF_ID,RUNTIME_BINARY_MOFS_ADDED,MOF_ADDED)))
  178. {
  179. if( SUCCEEDED(RegisterForRequestedEvent(BINARY_MOF_ID,RUNTIME_BINARY_MOFS_DELETED,MOF_DELETED)))
  180. {
  181. fRc = TRUE;
  182. }
  183. }
  184. }
  185. return fRc;
  186. }
  187. ////////////////////////////////////////////////////////////////////////
  188. HRESULT CWMIEvent::RemoveWMIEvent(DWORD dwId)
  189. {
  190. HRESULT hr = S_OK;
  191. if( m_nType == WMIEVENT )
  192. {
  193. hr = CheckImpersonationLevelAndVerifyInternalEvents(FALSE);
  194. }
  195. else
  196. {
  197. RevertToSelf();
  198. }
  199. if( SUCCEEDED(hr))
  200. {
  201. CWMIStandardShell WMI;
  202. if( SUCCEEDED(WMI.Initialize(NULL,FALSE,&m_HandleMap,TRUE,WMIGUID_NOTIFICATION|WMIGUID_QUERY,m_pEventServices,m_pEventHandler,m_pEventCtx)))
  203. {
  204. CAutoBlock Block(g_pEventCs);
  205. // ================================
  206. // Remove all requests with this Id
  207. // ================================
  208. int nSize = g_apRequests.Size();
  209. int i = 0;
  210. while( i < nSize )
  211. {
  212. WMIEventRequest* pReq = (WMIEventRequest*) g_apRequests[i];
  213. if(pReq->dwId == dwId)
  214. {
  215. // Inform WMI we don't want this anymore as
  216. // long as there are no more these guids in
  217. // the list, there might be more than one
  218. // event consumer registered.
  219. // =========================================
  220. if( NoMoreEventConsumersRegistered( pReq->gGuid ) == 1)
  221. {
  222. ULONG_PTR uRc =(ULONG_PTR)this;
  223. WMI.CancelWMIEventRegistration(pReq->gGuid,uRc);
  224. }
  225. g_apRequests.RemoveAt(i);
  226. delete pReq;
  227. nSize = g_apRequests.Size();
  228. }
  229. else
  230. {
  231. i++;
  232. }
  233. }
  234. }
  235. }
  236. CheckImpersonationLevelAndVerifyInternalEvents(FALSE);
  237. return WBEM_S_NO_ERROR;
  238. }
  239. ////////////////////////////////////////////////////////////////////////
  240. HRESULT CWMIEvent::DeleteBinaryMofResourceEvent()
  241. {
  242. CAutoBlock Block(g_pEventCs);
  243. RevertToSelf();
  244. CWMIStandardShell WMI;
  245. if( SUCCEEDED(WMI.Initialize(NULL,FALSE,&m_HandleMap,TRUE,WMIGUID_NOTIFICATION|WMIGUID_QUERY,m_pEventServices,m_pEventHandler,m_pEventCtx)))
  246. {
  247. // Remove all requests with this Id
  248. // ================================
  249. int nSize = g_apRequests.Size();
  250. int i = 0;
  251. while( i < nSize ){
  252. WMIEventRequest* pReq = (WMIEventRequest*) g_apRequests[i];
  253. if( ( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_ADDED_GUID,pReq->gGuid)) ||
  254. ( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_REMOVED_GUID,pReq->gGuid))){
  255. ULONG_PTR uRc =(ULONG_PTR)this;
  256. WMI.CancelWMIEventRegistration(pReq->gGuid,uRc);
  257. g_apRequests.RemoveAt(i);
  258. delete pReq;
  259. nSize = g_apRequests.Size();
  260. }
  261. else{
  262. i++;
  263. }
  264. }
  265. CheckImpersonationLevelAndVerifyInternalEvents(FALSE);
  266. }
  267. return WBEM_S_NO_ERROR;
  268. }
  269. ////////////////////////////////////////////////////////////////////////
  270. int CWMIEvent::NoMoreEventConsumersRegistered(GUID gGuid)
  271. {
  272. CAutoBlock Block(g_pEventCs);
  273. int nTotalNumberOfRegisteredEventConsumers = 0;
  274. WMIEventRequest * pEvent;
  275. for(int i = 0; i < g_apRequests.Size(); i++)
  276. {
  277. pEvent = (WMIEventRequest *) g_apRequests.GetAt(i);
  278. if( pEvent->gGuid == gGuid)
  279. {
  280. nTotalNumberOfRegisteredEventConsumers++;
  281. }
  282. }
  283. return nTotalNumberOfRegisteredEventConsumers;
  284. }
  285. ////////////////////////////////////////////////////////////////////////
  286. BOOL CWMIEvent::IsGuidInListIfSoGetCorrectContext(GUID gGuid, WMIEventRequest *& pEvent )
  287. {
  288. CAutoBlock Block(g_pEventCs);
  289. for( int i = 0; i < g_apRequests.Size(); i++ )
  290. {
  291. pEvent = (WMIEventRequest *) g_apRequests.GetAt(i);
  292. if( pEvent->gGuid == gGuid){
  293. return TRUE;
  294. }
  295. }
  296. pEvent = NULL;
  297. return FALSE;
  298. }
  299. ////////////////////////////////////////////////////////////////////////
  300. BOOL CWMIEvent::IsGuidInList(WCHAR * wcsGuid, WMIEventRequest *& pEvent)
  301. {
  302. CAutoBlock Block(g_pEventCs);
  303. BOOL fRc = FALSE;
  304. int Size = g_apRequests.Size();
  305. for(int i =0 ; i < Size; i++ ){
  306. pEvent = (WMIEventRequest *) g_apRequests.GetAt(i);
  307. if( (_wcsicmp(pEvent->wcsGuid,wcsGuid)) == 0 ){
  308. fRc = TRUE;
  309. break;
  310. }
  311. }
  312. return fRc;
  313. }
  314. ////////////////////////////////////////////////////////////////////////
  315. HRESULT CWMIEvent::RegisterForRequestedEvent( DWORD dwId, WCHAR * wcsClass, WORD wType)
  316. {
  317. BOOL fRegistered = FALSE;
  318. CWMIStandardShell WMI;
  319. HRESULT hr = WBEM_E_ACCESS_DENIED;
  320. BOOL fInternalEvent = TRUE;
  321. if( wType == STANDARD_EVENT )
  322. {
  323. fInternalEvent = FALSE;
  324. }
  325. if( SUCCEEDED(WMI.Initialize(wcsClass, fInternalEvent, &m_HandleMap,TRUE,WMIGUID_NOTIFICATION|WMIGUID_QUERY,m_pEventServices,m_pEventHandler,m_pEventCtx)))
  326. {
  327. if( m_nType == WMIEVENT ){
  328. hr = CheckImpersonationLevelAndVerifyInternalEvents(FALSE);
  329. }
  330. else
  331. {
  332. RevertToSelf();
  333. hr = S_OK;
  334. }
  335. if( SUCCEEDED(hr) )
  336. {
  337. WCHAR wcsGuid[128];
  338. hr = WMI.SetGuidForEvent( wType,wcsGuid );
  339. if( SUCCEEDED(hr)){
  340. WMIEventRequest * pAlreadyRegisteredEvent;
  341. //===========================================================
  342. // Keep a record of this guy, see if it is already registered
  343. // if it is/isn't we call WDM with different flags
  344. //===========================================================
  345. fRegistered = IsGuidInList( wcsGuid, pAlreadyRegisteredEvent );
  346. //===========================================================
  347. // Register for the requested event
  348. //===========================================================
  349. ULONG_PTR uRc =(ULONG_PTR)this;
  350. CLSID Guid;
  351. hr = WMI.RegisterWMIEvent(wcsGuid,uRc,Guid,fRegistered);
  352. if( SUCCEEDED(hr) && !fRegistered)
  353. {
  354. //=======================================================
  355. // If we succeeded, then add it to our list of events we
  356. // are watching
  357. //=======================================================
  358. WMIEventRequest * pEvent = new WMIEventRequest;
  359. pEvent->gGuid = Guid;
  360. pEvent->dwId = dwId;
  361. pEvent->fHardCoded = wType;
  362. wcscpy( pEvent->wcsGuid,wcsGuid);
  363. pEvent->SetClassName(wcsClass);
  364. pEvent->AddPtrs(m_pEventHandler,m_pEventServices,m_pEventCtx);
  365. g_apRequests.Add(pEvent);
  366. }
  367. }
  368. }
  369. CheckImpersonationLevelAndVerifyInternalEvents(FALSE);
  370. }
  371. return hr;
  372. }
  373. ////////////////////////////////////////////////////////////////////////
  374. CWMIEventProvider::CWMIEventProvider(int nType) : CWMIEvent(nType)
  375. {
  376. m_hResyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  377. ERRORTRACE((THISPROVIDER,"Event Provider constructed\n"));
  378. }
  379. ////////////////////////////////////////////////////////////////////////
  380. CWMIEventProvider::~CWMIEventProvider()
  381. {
  382. ERRORTRACE((THISPROVIDER,"Event Provider denstructed\n"));
  383. }
  384. ////////////////////////////////////////////////////////////////////////
  385. STDMETHODIMP CWMIEventProvider::QueryInterface(REFIID riid, void** ppv)
  386. {
  387. HRESULT hr = E_NOINTERFACE;
  388. *ppv = NULL;
  389. if(riid == IID_IUnknown)
  390. {
  391. *ppv = this;
  392. }
  393. else
  394. if(riid == IID_IWbemEventProvider)
  395. {
  396. *ppv = (IWbemEventProvider*)this;
  397. }
  398. else if(riid == IID_IWbemEventProviderQuerySink)
  399. {
  400. *ppv = (IWbemEventProviderQuerySink*)this;
  401. }
  402. else if (IsEqualIID(riid, IID_IWbemProviderInit))
  403. {
  404. *ppv = (IWbemProviderInit *) this ;
  405. }
  406. else if (IsEqualIID(riid, IID_IWbemEventProviderSecurity))
  407. {
  408. *ppv = (IWbemEventProviderSecurity *) this ;
  409. }
  410. if( *ppv)
  411. {
  412. AddRef();
  413. hr = S_OK;
  414. }
  415. return hr;
  416. }
  417. ////////////////////////////////////////////////////////////////////////
  418. ULONG STDMETHODCALLTYPE CWMIEventProvider::AddRef()
  419. {
  420. return InterlockedIncrement(&m_lRef);
  421. }
  422. ////////////////////////////////////////////////////////////////////////
  423. ULONG STDMETHODCALLTYPE CWMIEventProvider::Release()
  424. {
  425. long lRef = InterlockedDecrement(&m_lRef);
  426. if(lRef == 0){
  427. //**********************************************
  428. // reference count is zero, delete this object.
  429. // and do all of the cleanup for this user,
  430. //**********************************************
  431. delete this ;
  432. }
  433. return lRef;
  434. }
  435. /////////////////////////////////////////////////////////////////////
  436. STDMETHODIMP CWMIEventProvider::Initialize(LPWSTR wszUser, long lFlags,
  437. LPWSTR wszNamespace,
  438. LPWSTR wszLocale,
  439. IWbemServices* pNamespace,
  440. IWbemContext* pCtx,
  441. IWbemProviderInitSink* pSink)
  442. {
  443. IWbemClassObject * pWMIClass = NULL;
  444. HRESULT hres = pNamespace->GetObject(WMI_EVENT_CLASS, 0, NULL, &pWMIClass, NULL);
  445. CAutoBlock Block(g_pEventCs);
  446. // ptr initialization routines
  447. SetEventServices(pNamespace);
  448. SetEventContext(pCtx);
  449. pSink->SetStatus(hres, 0);
  450. SAFE_RELEASE_PTR(pWMIClass);
  451. return hres;
  452. }
  453. ////////////////////////////////////////////////////////////////////////
  454. STDMETHODIMP CWMIEventProvider::ProvideEvents(IWbemObjectSink __RPC_FAR *pSink,long lFlags)
  455. {
  456. CAutoBlock Block(g_pEventCs);
  457. SetEventHandler(pSink);
  458. // ===============================================================================
  459. // Make sure any request added before this was called gets the updated handler
  460. // PROVIDING it isn't the binary mof guid
  461. // ===============================================================================
  462. for(int i = 0; i < g_apRequests.Size(); i++)
  463. {
  464. WMIEventRequest* pReq = (WMIEventRequest*) g_apRequests[i];
  465. if(!pReq->pHandler)
  466. {
  467. if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_ADDED_GUID,pReq->gGuid))
  468. {
  469. }
  470. else
  471. {
  472. if( !pReq->pHandler )
  473. {
  474. pReq->pHandler = pSink;
  475. }
  476. }
  477. }
  478. }
  479. return S_OK;
  480. }
  481. ////////////////////////////////////////////////////////////////////////
  482. STDMETHODIMP CWMIEventProvider::NewQuery( DWORD dwId, WBEM_WSTR wszLanguage, WBEM_WSTR wszQuery)
  483. {
  484. HRESULT hRes = WBEM_S_NO_ERROR;
  485. if (_wcsicmp(wszLanguage, L"WQL") != 0)
  486. {
  487. hRes = WBEM_E_INVALID_QUERY_TYPE;
  488. }
  489. if( hRes == WBEM_S_NO_ERROR )
  490. {
  491. // Parse the query
  492. // Construct the lex source
  493. // ========================
  494. CTextLexSource Source(wszQuery);
  495. // Use the lex source to set up for parser
  496. // =======================================
  497. SQL1_Parser QueryParser(&Source);
  498. SQL_LEVEL_1_RPN_EXPRESSION * pParse;
  499. int ParseRetValue = QueryParser.Parse(&pParse);
  500. if( SQL1_Parser::SUCCESS != ParseRetValue) {
  501. hRes = WBEM_E_INVALID_QUERY;
  502. }
  503. else{
  504. //Set the class
  505. if( pParse ){
  506. hRes = RegisterForRequestedEvent(dwId,pParse->bsClassName,STANDARD_EVENT);
  507. delete pParse;
  508. }
  509. }
  510. }
  511. return hRes;
  512. }
  513. ////////////////////////////////////////////////////////////////////////
  514. STDMETHODIMP CWMIEventProvider::CancelQuery(DWORD dwId)
  515. {
  516. return RemoveWMIEvent(dwId);
  517. }
  518. ////////////////////////////////////////////////////////////////////////
  519. STDMETHODIMP CWMIEventProvider::AccessCheck(WBEM_CWSTR wszLanguage,
  520. WBEM_CWSTR wszQuery,
  521. long lSidLength,
  522. const BYTE* aSid)
  523. {
  524. HRESULT hr = WBEM_E_ACCESS_DENIED;
  525. //=======================================================
  526. // Check platform
  527. //=======================================================
  528. if(!IsNT())
  529. return WBEM_S_FALSE;
  530. //=======================================================
  531. // Check query language
  532. //=======================================================
  533. if (_wcsicmp(wszLanguage, L"WQL") != 0) {
  534. return WBEM_E_INVALID_QUERY_TYPE;
  535. }
  536. //=======================================================
  537. // If the PSid is NULL, then check impersonation level
  538. // as usual - based on the thread
  539. //=======================================================
  540. PSID pSid = (PSID)aSid;
  541. HANDLE hToken = NULL;
  542. if(pSid == NULL){
  543. //=================================================
  544. // if this is the INTERNAL_EVENT class, then we
  545. // do not want the local events set up again.
  546. //=================================================
  547. BOOL VerifyLocalEventsAreSetup = TRUE;
  548. if( m_nType == INTERNAL_EVENT ){
  549. VerifyLocalEventsAreSetup = FALSE;
  550. }
  551. hr = CheckImpersonationLevelAndVerifyInternalEvents(VerifyLocalEventsAreSetup);
  552. }
  553. else{
  554. //=======================================================
  555. // Parse the query
  556. //=======================================================
  557. CTextLexSource Source(wszQuery);
  558. //=======================================================
  559. // Use the lex source to set up for parser
  560. //=======================================================
  561. SQL1_Parser QueryParser(&Source);
  562. SQL_LEVEL_1_RPN_EXPRESSION * pParse;
  563. int ParseRetValue = QueryParser.Parse(&pParse);
  564. if( SQL1_Parser::SUCCESS != ParseRetValue) {
  565. return WBEM_E_INVALID_QUERY;
  566. }
  567. else{
  568. if( pParse ){
  569. CWMIStandardShell WMI;
  570. if( SUCCEEDED(WMI.Initialize(pParse->bsClassName,FALSE,&m_HandleMap,TRUE,WMIGUID_NOTIFICATION|WMIGUID_QUERY,m_pEventServices,m_pEventHandler,m_pEventCtx)))
  571. {
  572. CLSID * pGuid;
  573. pGuid = WMI.GuidPtr();
  574. if(pGuid != NULL)
  575. {
  576. //========================================
  577. // Get the ACL
  578. //========================================
  579. PACL pDacl;
  580. PSECURITY_DESCRIPTOR psd = NULL;
  581. SE_OBJECT_TYPE ObjectType = SE_WMIGUID_OBJECT;
  582. hr = WBEM_E_ACCESS_DENIED;
  583. WCHAR * GuidName = NULL;
  584. hr = UuidToString(pGuid, &GuidName);
  585. if (hr == RPC_S_OK)
  586. {
  587. hr = S_OK;
  588. DWORD dwRc = GetNamedSecurityInfo(GuidName,ObjectType,DACL_SECURITY_INFORMATION,NULL,NULL,&pDacl, NULL, &psd );
  589. if( dwRc != ERROR_SUCCESS )
  590. {
  591. ERRORTRACE((THISPROVIDER, "GetNamedSecurityInfo returned %ld.\n", dwRc ));
  592. hr = WBEM_E_ACCESS_DENIED;
  593. }
  594. }
  595. if( GuidName )
  596. {
  597. RpcStringFree(&GuidName);
  598. }
  599. if(SUCCEEDED(hr))
  600. {
  601. //====================================
  602. // This is our own ACL walker
  603. //====================================
  604. DWORD dwAccessMask;
  605. NTSTATUS st = GetAccessMask((PSID)pSid, pDacl, &dwAccessMask);
  606. if(st)
  607. {
  608. ERRORTRACE((THISPROVIDER, "WDM event provider unable "
  609. "to retrieve access mask for the creator of "
  610. "registration %S: NT status %d.\n"
  611. "Registration disabled\n", wszQuery,st));
  612. return WBEM_E_FAILED;
  613. }
  614. if((dwAccessMask & WMIGUID_QUERY) == 0)
  615. {
  616. hr = WBEM_E_ACCESS_DENIED;
  617. }
  618. else
  619. {
  620. hr = S_OK;
  621. m_nType = PERMANENT_EVENT;
  622. }
  623. }
  624. if( psd != NULL)
  625. {
  626. AccFree( psd );
  627. }
  628. }
  629. delete pParse;
  630. }
  631. }
  632. }
  633. }
  634. return hr;
  635. }
  636. ////////////////////////////////////////////////////////////////////////
  637. void CWMIEvent::WMIEventCallback(PWNODE_HEADER WnodeHeader)
  638. {
  639. LPGUID EventGuid = &WnodeHeader->Guid;
  640. ERRORTRACE((THISPROVIDER,"Received Event\n"));
  641. //=======================================================
  642. // We only support WNODE_FLAG_ALL_DATA and
  643. // WNODE_FLAG_SINGLE_INSTANCE
  644. //
  645. // Parse thru whatever it is and send it off to HMOM
  646. //=======================================================
  647. if( WnodeHeader )
  648. {
  649. HRESULT hr;
  650. WMIEventRequest * pEvent;
  651. //===========================================================
  652. // Make sure it is an event we want
  653. //===========================================================
  654. if( IsGuidInListIfSoGetCorrectContext( *EventGuid,pEvent))
  655. {
  656. CWMIStandardShell WMI;
  657. //=======================================================
  658. // See if a binary mof event is being added or deleted
  659. //=======================================================
  660. WORD wBinaryMofType = 0;
  661. BOOL fInternalEvent = FALSE;
  662. if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_ADDED_GUID,WnodeHeader->Guid))
  663. {
  664. fInternalEvent = TRUE;
  665. wBinaryMofType = MOF_ADDED;
  666. }
  667. else if( IsBinaryMofResourceEvent(WMI_RESOURCE_MOF_REMOVED_GUID,WnodeHeader->Guid))
  668. {
  669. fInternalEvent = TRUE;
  670. wBinaryMofType = MOF_DELETED;
  671. }
  672. if( SUCCEEDED(WMI.Initialize(pEvent->pwcsClass,fInternalEvent,&m_HandleMap,TRUE,WMIGUID_QUERY|WMIGUID_NOTIFICATION,pEvent->pServices,pEvent->pHandler,pEvent->pCtx)))
  673. {
  674. //=======================================================
  675. // If it was, then process it, otherwise go on... :)
  676. //=======================================================
  677. WMI.ProcessEvent(wBinaryMofType,WnodeHeader);
  678. }
  679. }
  680. }
  681. }