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.

2209 lines
64 KiB

  1. //***************************************************************************
  2. //
  3. // (c) 1997-2001 by Microsoft Corporation
  4. //
  5. // SINKS.CPP
  6. //
  7. // raymcc 3-Mar-99 Updated for separately threaded proxies
  8. //
  9. //***************************************************************************
  10. #include "precomp.h"
  11. #include <stdio.h>
  12. #include <wbemcore.h>
  13. #include <evtlog.h>
  14. #include <oahelp.inl>
  15. #include <genutils.h>
  16. #include <stdarg.h>
  17. #include <autoptr.h>
  18. #define LOWER_AUTH_LEVEL_NOTSET 0xFFFFFFFF
  19. static HRESULT ZapWriteOnlyProps(IWbemClassObject *pObj);
  20. extern LONG g_nSinkCount;
  21. extern LONG g_nStdSinkCount;
  22. extern LONG g_nSynchronousSinkCount;
  23. extern LONG g_nProviderSinkCount;
  24. int _Trace(char *pFile, const char *fmt, ...);
  25. //
  26. //
  27. //
  28. //////////////////////////////////////////////
  29. void EmptyObjectList(CFlexArray &aTarget)
  30. {
  31. for (int i = 0; i < aTarget.Size(); i++)
  32. {
  33. IWbemClassObject *pObj = (IWbemClassObject *) aTarget[i];
  34. if (pObj) pObj->Release();
  35. }
  36. aTarget.Empty();
  37. };
  38. //
  39. //
  40. //
  41. /////////////////////////////////////////////////////
  42. void Sink_Return(IWbemObjectSink* pSink,HRESULT & hRes, IWbemClassObject * & pObjParam)
  43. {
  44. pSink->SetStatus(0,hRes,NULL,pObjParam);
  45. }
  46. //***************************************************************************
  47. //
  48. //***************************************************************************
  49. CBasicObjectSink::CBasicObjectSink()
  50. {
  51. InterlockedIncrement(&g_nSinkCount);
  52. }
  53. CBasicObjectSink::~CBasicObjectSink()
  54. {
  55. InterlockedDecrement(&g_nSinkCount);
  56. }
  57. //***************************************************************************
  58. //
  59. //***************************************************************************
  60. STDMETHODIMP CBasicObjectSink::QueryInterface(REFIID riid, LPVOID* ppvObj)
  61. {
  62. if(riid == CLSID_WbemLocator)
  63. {
  64. // internal test
  65. *ppvObj = NULL;
  66. return S_OK;
  67. }
  68. if(riid == IID_IUnknown || riid == IID_IWbemObjectSink)
  69. {
  70. *ppvObj = (IWbemObjectSink*)this;
  71. AddRef();
  72. return S_OK;
  73. }
  74. else return E_NOINTERFACE;
  75. }
  76. //***************************************************************************
  77. //
  78. //***************************************************************************
  79. ULONG STDMETHODCALLTYPE CObjectSink::AddRef()
  80. {
  81. return InterlockedIncrement(&m_lRef);
  82. }
  83. //***************************************************************************
  84. //
  85. //***************************************************************************
  86. ULONG STDMETHODCALLTYPE CObjectSink::Release()
  87. {
  88. long lRef = InterlockedDecrement(&m_lRef);
  89. if(lRef == 0)
  90. delete this;
  91. return lRef;
  92. }
  93. //***************************************************************************
  94. //
  95. //***************************************************************************
  96. CSynchronousSink * CSynchronousSink::Create(IWbemObjectSink* pProxy)
  97. {
  98. try
  99. {
  100. return new CSynchronousSink(pProxy);
  101. }
  102. catch(CX_Exception &)
  103. {
  104. return 0;
  105. }
  106. }
  107. CSynchronousSink::CSynchronousSink(IWbemObjectSink* pProxy) :
  108. m_hEvent(NULL),
  109. m_str(NULL), m_pErrorObj(NULL), m_hres(WBEM_E_CRITICAL_ERROR)
  110. {
  111. m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  112. if (NULL == m_hEvent) throw CX_MemoryException();
  113. if(pProxy)
  114. {
  115. m_pCurrentProxy = pProxy;
  116. pProxy->AddRef();
  117. }
  118. else
  119. m_pCurrentProxy = NULL;
  120. InterlockedIncrement(&g_nSynchronousSinkCount);
  121. };
  122. //***************************************************************************
  123. //
  124. //***************************************************************************
  125. CSynchronousSink::~CSynchronousSink()
  126. {
  127. if(m_pCurrentProxy)
  128. m_pCurrentProxy->Release();
  129. CloseHandle(m_hEvent);
  130. SysFreeString(m_str);
  131. if(m_pErrorObj)
  132. m_pErrorObj->Release();
  133. InterlockedDecrement(&g_nSynchronousSinkCount);
  134. }
  135. //***************************************************************************
  136. //
  137. //***************************************************************************
  138. STDMETHODIMP CSynchronousSink::Indicate(long lNumObjects,
  139. IWbemClassObject** apObj)
  140. {
  141. CInCritSec ics(&m_cs);
  142. HRESULT hRes = WBEM_S_NO_ERROR;
  143. for(long i = 0; i < lNumObjects && SUCCEEDED(hRes); i++)
  144. {
  145. if (m_apObjects.Add(apObj[i]) < 0)
  146. hRes = WBEM_E_OUT_OF_MEMORY;
  147. }
  148. return hRes;
  149. }
  150. //***************************************************************************
  151. //
  152. //***************************************************************************
  153. STDMETHODIMP CSynchronousSink::SetStatus(long lFlags, long lParam,
  154. BSTR strParam, IWbemClassObject* pObjParam)
  155. {
  156. if(lFlags == WBEM_STATUS_PROGRESS)
  157. {
  158. if(m_pCurrentProxy)
  159. return m_pCurrentProxy->SetStatus(lFlags, lParam, strParam, pObjParam);
  160. else
  161. return S_OK;
  162. }
  163. if(lFlags != 0) return WBEM_S_NO_ERROR;
  164. CInCritSec ics(&m_cs); // SEC:REVIEWED 2002-03-22 : Assumes entry
  165. m_hres = lParam;
  166. m_str = SysAllocString(strParam);
  167. if (m_pErrorObj)
  168. m_pErrorObj->Release();
  169. m_pErrorObj = pObjParam;
  170. if(m_pErrorObj)
  171. m_pErrorObj->AddRef();
  172. SetEvent(m_hEvent);
  173. return WBEM_S_NO_ERROR;
  174. }
  175. //***************************************************************************
  176. //
  177. //***************************************************************************
  178. void CSynchronousSink::Block()
  179. {
  180. if(m_hres != WBEM_E_CRITICAL_ERROR)
  181. return;
  182. CCoreQueue::QueueWaitForSingleObject(m_hEvent, INFINITE);
  183. }
  184. //***************************************************************************
  185. //
  186. //***************************************************************************
  187. void CSynchronousSink::GetStatus(HRESULT* phres, BSTR* pstrParam,
  188. IWbemClassObject** ppErrorObj)
  189. {
  190. CInCritSec ics(&m_cs); // SEC:REVIEWED 2002-03-22 : Assumes entry
  191. if(phres)
  192. *phres = m_hres;
  193. if(pstrParam)
  194. *pstrParam = SysAllocString(m_str);
  195. if(ppErrorObj)
  196. {
  197. *ppErrorObj = m_pErrorObj;
  198. if(m_pErrorObj)
  199. m_pErrorObj->AddRef();
  200. }
  201. }
  202. //***************************************************************************
  203. //
  204. //***************************************************************************
  205. CForwardingSink::CForwardingSink(CBasicObjectSink* pDest, long lRef)
  206. : CObjectSink(lRef),
  207. m_pDestIndicate(pDest->GetIndicateSink()),
  208. m_pDestStatus(pDest->GetStatusSink()),
  209. m_pDest(pDest)
  210. {
  211. m_pDestIndicate->AddRef();
  212. m_pDestStatus->AddRef();
  213. m_pDest->AddRef();
  214. }
  215. //***************************************************************************
  216. //
  217. //***************************************************************************
  218. CForwardingSink::~CForwardingSink()
  219. {
  220. if(m_pDestIndicate)
  221. m_pDestIndicate->Release();
  222. if(m_pDestStatus)
  223. m_pDestStatus->Release();
  224. if(m_pDest)
  225. m_pDest->Release();
  226. }
  227. //***************************************************************************
  228. //
  229. //***************************************************************************
  230. STDMETHODIMP CForwardingSink::Indicate(long lObjectCount,
  231. IWbemClassObject** pObjArray)
  232. {
  233. return m_pDestIndicate->Indicate(lObjectCount, pObjArray);
  234. }
  235. //***************************************************************************
  236. //
  237. //***************************************************************************
  238. STDMETHODIMP CForwardingSink::SetStatus(long lFlags, long lParam,
  239. BSTR strParam, IWbemClassObject* pObjParam)
  240. {
  241. return m_pDestStatus->SetStatus(lFlags, lParam, strParam, pObjParam);
  242. }
  243. //***************************************************************************
  244. //
  245. //***************************************************************************
  246. CCombiningSink::CCombiningSink(CBasicObjectSink* pDest, HRESULT hresToIgnore)
  247. : CForwardingSink(pDest, 0), m_hresToIgnore(hresToIgnore),
  248. m_hres(WBEM_S_NO_ERROR), m_pErrorObj(NULL), m_strParam(NULL)
  249. {
  250. }
  251. //***************************************************************************
  252. //
  253. //***************************************************************************
  254. CCombiningSink::~CCombiningSink()
  255. {
  256. // Time to call SetStatus on the destination
  257. // =========================================
  258. m_pDestStatus->SetStatus(0, m_hres,
  259. (SUCCEEDED(m_hres)?m_strParam:NULL),
  260. (SUCCEEDED(m_hres)?NULL:m_pErrorObj)
  261. );
  262. if(m_pErrorObj)
  263. m_pErrorObj->Release();
  264. SysFreeString(m_strParam);
  265. }
  266. //***************************************************************************
  267. //
  268. //***************************************************************************
  269. STDMETHODIMP CCombiningSink::SetStatus(long lFlags, long lParam, BSTR strParam,
  270. IWbemClassObject* pObjParam)
  271. {
  272. if(lFlags != 0)
  273. return m_pDestStatus->SetStatus(lFlags, lParam, strParam, pObjParam);
  274. // An error occurred. For now, only store one
  275. // ==========================================
  276. if(strParam)
  277. {
  278. SysFreeString(m_strParam);
  279. m_strParam = SysAllocString(strParam);
  280. }
  281. CInCritSec ics(&m_cs); // SEC:REVIEWED 2002-03-22 : Assumes entry
  282. if(SUCCEEDED(m_hres) || (m_pErrorObj == NULL && pObjParam != NULL))
  283. {
  284. // This error needs to be recorded
  285. // ===============================
  286. if(FAILED(lParam))
  287. {
  288. // Record the error code, unless it is to be ignored
  289. // =================================================
  290. if(lParam != m_hresToIgnore)
  291. {
  292. m_hres = lParam;
  293. }
  294. // Record the error object anyway
  295. // ==============================
  296. if(m_pErrorObj)
  297. m_pErrorObj->Release();
  298. m_pErrorObj = pObjParam;
  299. if(m_pErrorObj)
  300. m_pErrorObj->AddRef();
  301. }
  302. else
  303. {
  304. if(lParam != m_hresToIgnore)
  305. {
  306. m_hres = lParam;
  307. }
  308. }
  309. }
  310. return WBEM_S_NO_ERROR;
  311. }
  312. //***************************************************************************
  313. //
  314. //***************************************************************************
  315. /*
  316. CAnySuccessSink::~CAnySuccessSink()
  317. {
  318. // If no real success occurred, report a failure
  319. // =============================================
  320. if(!m_bSuccess && SUCCEEDED(m_hres))
  321. {
  322. // We must report a failure since there were no successes, but there
  323. // were no real failures either, so we must create an error code.
  324. // =================================================================
  325. if(m_hresIgnored == 0)
  326. m_hres = m_hresNotError1;
  327. else
  328. m_hres = m_hresIgnored;
  329. }
  330. }
  331. */
  332. //***************************************************************************
  333. //
  334. //***************************************************************************
  335. /*
  336. STDMETHODIMP CAnySuccessSink::SetStatus(long lFlags, long lParam, BSTR strParam,
  337. IWbemClassObject* pObjParam)
  338. {
  339. if(lFlags == 0)
  340. {
  341. if(SUCCEEDED(lParam))
  342. m_bSuccess = TRUE;
  343. else if(lParam == m_hresNotError1 && m_hresIgnored == 0)
  344. {
  345. m_hresIgnored = m_hresNotError1;
  346. lParam = WBEM_S_NO_ERROR;
  347. }
  348. else if(lParam == m_hresNotError2)
  349. {
  350. m_hresIgnored = m_hresNotError2;
  351. lParam = WBEM_S_NO_ERROR;
  352. }
  353. }
  354. return CCombiningSink::SetStatus(lFlags, lParam, strParam, pObjParam);
  355. }
  356. */
  357. //***************************************************************************
  358. //
  359. //***************************************************************************
  360. STDMETHODIMP COperationErrorSink::SetStatus(long lFlags, long lParam,
  361. BSTR strParam, IWbemClassObject* pObjParam)
  362. {
  363. if(lFlags == 0 && FAILED(lParam))
  364. {
  365. HRESULT hres = WBEM_S_NO_ERROR;
  366. IWbemClassObject* pErrorObj = NULL;
  367. bool bErr = false;
  368. try
  369. {
  370. CErrorObject Error(pObjParam);
  371. Error.SetOperation(m_wsOperation);
  372. Error.SetParamInformation(m_wsParameter);
  373. Error.SetProviderName(m_wsProviderName);
  374. pErrorObj = Error.GetObject();
  375. }
  376. // If an exception occurs, send the error to the client and
  377. // return an error from the call.
  378. catch ( CX_Exception & )
  379. {
  380. lParam = WBEM_E_OUT_OF_MEMORY;
  381. bErr = true;
  382. }
  383. hres = m_pDestStatus->SetStatus(lFlags, lParam, strParam, pErrorObj);
  384. if ( NULL != pErrorObj )
  385. {
  386. pErrorObj->Release();
  387. }
  388. if ( bErr )
  389. {
  390. hres = lParam;
  391. }
  392. return hres;
  393. }
  394. else if(m_bFinal &&
  395. lFlags != WBEM_STATUS_COMPLETE && lFlags != WBEM_STATUS_PROGRESS)
  396. {
  397. DEBUGTRACE((LOG_WBEMCORE, "Ignoring internal SetStatus call to the "
  398. "client: 0x%X 0x%X %S\n", lFlags, lParam, strParam));
  399. return WBEM_S_FALSE;
  400. }
  401. else if(lFlags == 0 && strParam &&
  402. !m_wsOperation.EqualNoCase(L"PutInstance"))
  403. {
  404. ERRORTRACE((LOG_WBEMCORE, "Provider used strParam in SetStatus "
  405. "outside of PutInstance! Actual operation was <%S>, string was <%S>. Ignoring\n", (const wchar_t*)m_wsOperation, strParam));
  406. return m_pDestStatus->SetStatus(lFlags, lParam, NULL, pObjParam);
  407. }
  408. else
  409. {
  410. return m_pDestStatus->SetStatus(lFlags, lParam, strParam, pObjParam);
  411. }
  412. }
  413. //***************************************************************************
  414. //
  415. //***************************************************************************
  416. void COperationErrorSink::SetProviderName(LPCWSTR wszName)
  417. {
  418. m_wsProviderName = wszName;
  419. }
  420. //***************************************************************************
  421. //
  422. //***************************************************************************
  423. void COperationErrorSink::SetParameterInfo(LPCWSTR wszParam)
  424. {
  425. m_wsParameter = wszParam;
  426. }
  427. //***************************************************************************
  428. //
  429. //***************************************************************************
  430. CDecoratingSink::CDecoratingSink(CBasicObjectSink* pDest,
  431. CWbemNamespace* pNamespace)
  432. : CForwardingSink(pDest, 0), m_pNamespace(pNamespace)
  433. {
  434. m_pNamespace->AddRef();
  435. }
  436. //***************************************************************************
  437. //
  438. //***************************************************************************
  439. CDecoratingSink::~CDecoratingSink()
  440. {
  441. m_pNamespace->Release();
  442. }
  443. //***************************************************************************
  444. //
  445. //***************************************************************************
  446. STDMETHODIMP CDecoratingSink::Indicate(long lNumObjects,
  447. IWbemClassObject** apObjects)
  448. {
  449. // Clone the indicated objects before decorating
  450. HRESULT hres;
  451. if (0 > lNumObjects) return WBEM_E_INVALID_PARAMETER;
  452. if (0 == lNumObjects)
  453. return m_pDestIndicate->Indicate(lNumObjects, apObjects);
  454. // We will optimize for indicates of a single object (which will probably
  455. // be the most likely type of indicate. In which case we won't allocate any
  456. // memory for the cloned object array, and rather will just use a stack variable.
  457. if ( 1 == lNumObjects )
  458. {
  459. IWbemClassObject* pClonedObject = NULL;
  460. hres = ((CWbemObject *)apObjects[0])->CloneAndDecorate(0,ConfigMgr::GetMachineName(),m_pNamespace->GetName(),&pClonedObject);
  461. if (SUCCEEDED(hres))
  462. {
  463. hres = m_pDestIndicate->Indicate(lNumObjects, &pClonedObject);
  464. pClonedObject->Release();
  465. }
  466. /*
  467. hres = apObjects[0]->Clone(&pClonedObject);
  468. if (FAILED(hres)) return hres;
  469. hres = m_pNamespace->DecorateObject(pClonedObject);
  470. if (SUCCEEDED(hres))
  471. hres = m_pDestIndicate->Indicate(lNumObjects, &pClonedObject);
  472. pClonedObject->Release();
  473. return hres;
  474. */
  475. return hres;
  476. }
  477. // Allocate an array and zero it out
  478. wmilib::auto_buffer<IWbemClassObject*> apClonedObjects(new IWbemClassObject*[lNumObjects]);
  479. if ( NULL == apClonedObjects.get() ) return WBEM_E_OUT_OF_MEMORY;
  480. ZeroMemory( apClonedObjects.get(), lNumObjects * sizeof(IWbemClassObject*) );
  481. // Clone the objects into the array (error out if this fails)
  482. hres = S_OK;
  483. for ( long lCtr = 0; SUCCEEDED( hres ) && lCtr < lNumObjects; lCtr++ )
  484. {
  485. if (apObjects[lCtr])
  486. {
  487. hres = ((CWbemObject *)apObjects[lCtr])->CloneAndDecorate(0,ConfigMgr::GetMachineName(),m_pNamespace->GetName(),&apClonedObjects[lCtr]);
  488. //Clone( &apClonedObjects[lCtr] );
  489. }
  490. else
  491. {
  492. apClonedObjects[lCtr] = NULL;
  493. }
  494. }
  495. // Now decorate the cloned objects and indicate them
  496. if ( SUCCEEDED( hres ) )
  497. {
  498. /*
  499. for(int i = 0; i < lNumObjects && SUCCEEDED(hres); i++)
  500. {
  501. hres = m_pNamespace->DecorateObject(apClonedObjects[i]);
  502. }
  503. if (SUCCEEDED(hres))
  504. */
  505. hres = m_pDestIndicate->Indicate(lNumObjects, (IWbemClassObject**)apClonedObjects.get());
  506. }
  507. for ( lCtr = 0; lCtr < lNumObjects; lCtr++ )
  508. {
  509. if ( apClonedObjects[lCtr] ) apClonedObjects[lCtr]->Release();
  510. }
  511. return hres;
  512. }
  513. //***************************************************************************
  514. //
  515. //***************************************************************************
  516. CSingleMergingSink::~CSingleMergingSink()
  517. {
  518. if(SUCCEEDED(m_hres))
  519. {
  520. if(m_pResult == NULL)
  521. {
  522. // Nobody succeeded, but nobody failed either. Not found
  523. // =====================================================
  524. m_hres = WBEM_E_NOT_FOUND;
  525. }
  526. else if(m_pResult->InheritsFrom(m_wsTargetClass) == S_OK)
  527. {
  528. m_pDestIndicate->Indicate(1, &m_pResult);
  529. }
  530. else
  531. {
  532. // Found somewhere, but not in this class
  533. // ======================================
  534. m_hres = WBEM_E_NOT_FOUND;
  535. }
  536. }
  537. if(m_pResult)
  538. m_pResult->Release();
  539. }
  540. //***************************************************************************
  541. //
  542. //***************************************************************************
  543. STDMETHODIMP CSingleMergingSink::Indicate(long lNumObjects,
  544. IWbemClassObject** apObjects)
  545. {
  546. CInCritSec ics(&m_cs); // SEC:REVIEWED 2002-03-22 : Assumes entry
  547. if(lNumObjects != 1)
  548. {
  549. ERRORTRACE((LOG_WBEMCORE, "Provider gave %d objects for GetObject!\n",
  550. lNumObjects));
  551. return WBEM_S_NO_ERROR;
  552. }
  553. if(m_pResult == NULL)
  554. {
  555. apObjects[0]->Clone(&m_pResult);
  556. return WBEM_S_NO_ERROR;
  557. }
  558. CVar vName;
  559. ((CWbemInstance*)m_pResult)->GetClassName(&vName);
  560. if(apObjects[0]->InheritsFrom(vName.GetLPWSTR()) == S_OK)
  561. {
  562. IWbemClassObject* pClone;
  563. apObjects[0]->Clone(&pClone);
  564. HRESULT hres = CWbemInstance::AsymmetricMerge((CWbemInstance*)m_pResult,
  565. (CWbemInstance*)pClone);
  566. if(FAILED(hres))
  567. {
  568. ERRORTRACE((LOG_WBEMCORE, "Failed to merge instances!!\n"));
  569. pClone->Release();
  570. }
  571. else
  572. {
  573. m_pResult->Release();
  574. m_pResult = pClone; // already AddRefed
  575. }
  576. }
  577. else
  578. {
  579. HRESULT hres = CWbemInstance::AsymmetricMerge(
  580. (CWbemInstance*)apObjects[0], (CWbemInstance*)m_pResult);
  581. if(FAILED(hres))
  582. {
  583. ERRORTRACE((LOG_WBEMCORE, "Failed to merge instances!!\n"));
  584. }
  585. }
  586. return WBEM_S_NO_ERROR;
  587. }
  588. //***************************************************************************
  589. //
  590. //***************************************************************************
  591. CLocaleMergingSink::CLocaleMergingSink(CBasicObjectSink *pDest, LPCWSTR wszLocale, LPCWSTR pNamespace)
  592. : CCombiningSink(pDest, WBEM_S_NO_ERROR),
  593. m_wsLocale(wszLocale),
  594. m_pPrimaryNs(NULL),
  595. m_pPrimarySession(NULL),
  596. m_pPrimaryDriver(NULL),
  597. m_pDefaultNs(NULL),
  598. m_pDefaultSession(NULL),
  599. m_pDefaultDriver(NULL)
  600. {
  601. GetDbPtr(pNamespace);
  602. }
  603. CLocaleMergingSink::~CLocaleMergingSink()
  604. {
  605. releaseNS();
  606. }
  607. //***************************************************************************
  608. //
  609. //***************************************************************************
  610. HRESULT CLocaleMergingSink::LocalizeQualifiers(bool bInstance, bool bParentLocalized,
  611. IWbemQualifierSet *pBase, IWbemQualifierSet *pLocalized, bool &bChg)
  612. {
  613. HRESULT hrInner;
  614. HRESULT hr = WBEM_S_NO_ERROR;
  615. pLocalized->BeginEnumeration(0);
  616. BSTR strName = NULL;
  617. VARIANT vVal;
  618. VariantInit(&vVal);
  619. long lFlavor;
  620. while(pLocalized->Next(0, &strName, &vVal, &lFlavor) == S_OK)
  621. {
  622. // Ignore if this is an instance.
  623. if (bInstance && !(lFlavor & WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE))
  624. {
  625. VariantClear(&vVal);
  626. SysFreeString(strName);
  627. continue;
  628. }
  629. if (!wbem_wcsicmp(strName, L"amendment") ||
  630. !wbem_wcsicmp(strName, L"key") ||
  631. !wbem_wcsicmp(strName, L"singleton") ||
  632. !wbem_wcsicmp(strName, L"dynamic") ||
  633. !wbem_wcsicmp(strName, L"indexed") ||
  634. !wbem_wcsicmp(strName, L"cimtype") ||
  635. !wbem_wcsicmp(strName, L"static") ||
  636. !wbem_wcsicmp(strName, L"implemented") ||
  637. !wbem_wcsicmp(strName, L"abstract"))
  638. {
  639. VariantClear(&vVal);
  640. SysFreeString(strName);
  641. continue;
  642. }
  643. // If this is not a propagated qualifier,
  644. // ignore it. (Bug #45799)
  645. // =====================================
  646. if (bParentLocalized &&
  647. !(lFlavor & WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS))
  648. {
  649. VariantClear(&vVal);
  650. SysFreeString(strName);
  651. continue;
  652. }
  653. // Now, we need to test for this in the other
  654. // class.
  655. // The only localized qualifiers that do not override the
  656. // default are where only parent qualifiers exist, but the
  657. // child has overriden its own parent.
  658. // =======================================================
  659. VARIANT vBasicVal;
  660. VariantInit(&vBasicVal);
  661. long lBasicFlavor;
  662. hrInner = pBase->Get(strName, 0, &vBasicVal, &lBasicFlavor);
  663. if (hrInner != WBEM_E_NOT_FOUND)
  664. {
  665. if (bParentLocalized && // If there is no localized copy of this class
  666. (lBasicFlavor & WBEM_FLAVOR_OVERRIDABLE) && // .. and this is an overridable qualifier
  667. (lBasicFlavor & WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS) && // and this is propogated
  668. (lBasicFlavor & WBEM_FLAVOR_ORIGIN_LOCAL)) // .. and this was actualy overridden
  669. {
  670. VariantClear(&vVal); // .. DON'T DO IT.
  671. VariantClear(&vBasicVal);
  672. SysFreeString(strName);
  673. continue;
  674. }
  675. if (bParentLocalized &&
  676. !(lBasicFlavor & WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS))
  677. {
  678. VariantClear(&vVal);
  679. VariantClear(&vBasicVal);
  680. SysFreeString(strName);
  681. continue;
  682. }
  683. }
  684. pBase->Put(strName, &vVal, (lFlavor&~WBEM_FLAVOR_ORIGIN_PROPAGATED) | WBEM_FLAVOR_AMENDED);
  685. bChg = true;
  686. VariantClear(&vVal);
  687. VariantClear(&vBasicVal);
  688. SysFreeString(strName);
  689. }
  690. return hr;
  691. }
  692. //***************************************************************************
  693. //
  694. //***************************************************************************
  695. HRESULT CLocaleMergingSink::LocalizeProperties(bool bInstance, bool bParentLocalized, IWbemClassObject *pOriginal,
  696. IWbemClassObject *pLocalized, bool &bChg)
  697. {
  698. HRESULT hr = WBEM_S_NO_ERROR;
  699. pLocalized->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
  700. BSTR strPropName = NULL;
  701. LONG lLong;
  702. CIMTYPE ct;
  703. VARIANT vNewVal;
  704. VariantInit(&vNewVal);
  705. while(pLocalized->Next(0, &strPropName, &vNewVal, &ct, &lLong) == S_OK)
  706. {
  707. CSysFreeMe sfm(strPropName);
  708. CClearMe ccm(&vNewVal);
  709. IWbemQualifierSet *pLocalizedQs = NULL, *pThisQs = NULL;
  710. if (FAILED(pLocalized->GetPropertyQualifierSet(strPropName,&pLocalizedQs)))
  711. {
  712. continue;
  713. }
  714. CReleaseMe rm1(pLocalizedQs);
  715. if (FAILED(pOriginal->GetPropertyQualifierSet(strPropName, &pThisQs)))
  716. {
  717. continue;
  718. }
  719. CReleaseMe rm2(pThisQs);
  720. hr = LocalizeQualifiers(bInstance, bParentLocalized, pThisQs, pLocalizedQs, bChg);
  721. if (FAILED(hr))
  722. {
  723. continue;
  724. }
  725. }
  726. pLocalized->EndEnumeration();
  727. return hr;
  728. }
  729. //***************************************************************************
  730. //
  731. //***************************************************************************
  732. // This function sets up the pointer to the localized namespace.
  733. void CLocaleMergingSink::GetDbPtr(const wchar_t * name_space)
  734. {
  735. if (m_pThisNamespace.EqualNoCase(name_space))
  736. return;
  737. releaseNS();
  738. m_pThisNamespace = name_space;
  739. if (wcslen(name_space) == 0) // SEC:REVIEWED 2002-03-22 : Precondition ensures NULL
  740. return;
  741. // SEC:REVIEWED 2002-03-22 : Needs EH because of WString ops below
  742. WString sNsName;
  743. sNsName = m_pThisNamespace;
  744. sNsName += L"\\";
  745. sNsName += m_wsLocale;
  746. IWmiDbSession *pTempSession = NULL;
  747. HRESULT hRes = CRepository::GetDefaultSession(&pTempSession);
  748. if (FAILED(hRes))
  749. return;
  750. hRes = CRepository::OpenScope(pTempSession, sNsName, 0, &m_pPrimaryDriver, &m_pPrimarySession, 0, &m_pPrimaryNs);
  751. if (wbem_wcsicmp(m_wsLocale, L"ms_409"))
  752. {
  753. sNsName = m_pThisNamespace;
  754. sNsName += L"\\ms_409";
  755. hRes = CRepository::OpenScope(pTempSession, sNsName, 0, &m_pDefaultDriver, &m_pDefaultSession, 0, &m_pDefaultNs);
  756. }
  757. pTempSession->Release();
  758. }
  759. void CLocaleMergingSink::releaseNS(void)
  760. {
  761. ReleaseIfNotNULL(m_pPrimarySession);
  762. ReleaseIfNotNULL(m_pDefaultSession);
  763. ReleaseIfNotNULL(m_pPrimaryNs);
  764. ReleaseIfNotNULL(m_pPrimaryDriver);
  765. ReleaseIfNotNULL(m_pDefaultNs);
  766. ReleaseIfNotNULL(m_pDefaultDriver);
  767. m_pPrimarySession = 0;
  768. m_pDefaultSession = 0;
  769. m_pPrimaryNs = 0;
  770. m_pPrimaryDriver = 0;
  771. m_pDefaultNs = 0;
  772. m_pDefaultDriver = 0;
  773. };
  774. bool CLocaleMergingSink::hasLocale(const wchar_t * name_space)
  775. {
  776. GetDbPtr(name_space) ;
  777. return (m_pPrimaryNs || m_pDefaultNs);
  778. };
  779. //***************************************************************************
  780. //
  781. //***************************************************************************
  782. // Do the work.
  783. STDMETHODIMP CLocaleMergingSink::Indicate(long lNumObjects,
  784. IWbemClassObject** apObjects)
  785. {
  786. CInCritSec ics(&m_cs); // SEC:REVIEWED 2002-03-22 : Assumes entry
  787. IWbemQualifierSet *pLocalizedQs = NULL, *pThisQs = NULL;
  788. bool bParentLocalized = false;
  789. bool bInstance = false;
  790. HRESULT hr = WBEM_S_NO_ERROR;
  791. HRESULT hRes;
  792. for (int i = 0; i < lNumObjects; i++)
  793. {
  794. // SEC:REVIEWED 2002-03-22 : Needs EH because of WString, CVar, etc. below
  795. CWbemObject *pResult = (CWbemObject *)apObjects[i];
  796. CVar vServer;
  797. if (FAILED(pResult->GetProperty(L"__SERVER", &vServer)) || vServer.IsNull())
  798. continue;
  799. if (wbem_wcsicmp(LPWSTR(vServer), ConfigMgr::GetMachineName())!=0)
  800. continue;
  801. VARIANT name_space;
  802. VariantInit(&name_space);
  803. CClearMe cm(&name_space);
  804. HRESULT hres = pResult->Get(L"__NAMESPACE", 0, &name_space, NULL, NULL);
  805. if (FAILED(hres) || hasLocale (V_BSTR(&name_space)) == false)
  806. continue;
  807. if (pResult->IsInstance())
  808. bInstance = true;
  809. CVar vName, vDeriv;
  810. if (FAILED(pResult->GetClassName(&vName)))
  811. continue;
  812. WString wKey; // SEC:REVIEWED 2002-03-22 : Can throw
  813. int nRes = 0;
  814. bool bChg = false;
  815. // Does this instance exist in the localized namespace?
  816. // Does this class exist in the localized namespace?
  817. // If not, loop through all the parents until we
  818. // run out or we have a hit.
  819. // =================================================
  820. CWbemObject *pClassDef = NULL;
  821. if (wcslen(vName.GetLPWSTR()) > 0) // SEC:REVIEWED 2002-03-22 : Ok, vName can't get here unless a NULL terminator was found
  822. {
  823. WString sName = vName.GetLPWSTR();
  824. hRes = WBEM_E_NOT_FOUND;
  825. if (m_pPrimaryNs)
  826. hRes = CRepository::GetObject(m_pPrimarySession, m_pPrimaryNs, sName, 0, (IWbemClassObject **) &pClassDef);
  827. if (FAILED(hRes) && m_pDefaultNs)
  828. hRes = CRepository::GetObject(m_pDefaultSession, m_pDefaultNs, sName, 0, (IWbemClassObject **) &pClassDef);
  829. if (hRes == WBEM_E_NOT_FOUND)
  830. {
  831. bParentLocalized = TRUE;
  832. pResult->GetDerivation(&vDeriv);
  833. CVarVector *pvTemp = vDeriv.GetVarVector();
  834. for (int j = 0; j < pvTemp->Size(); j++)
  835. {
  836. CVar vParentName = pvTemp->GetAt(j);
  837. WString sParentName = vParentName.GetLPWSTR();
  838. hRes = WBEM_E_NOT_FOUND;
  839. if (m_pPrimaryNs)
  840. hRes = CRepository::GetObject(m_pPrimarySession, m_pPrimaryNs, sParentName, 0, (IWbemClassObject **) &pClassDef);
  841. if (FAILED(hRes) && m_pDefaultNs)
  842. hRes = CRepository::GetObject(m_pDefaultSession, m_pDefaultNs, sParentName, 0, (IWbemClassObject **) &pClassDef);
  843. if (SUCCEEDED(hRes)) break;
  844. }
  845. }
  846. }
  847. if (pClassDef == NULL)
  848. {
  849. nRes = WBEM_S_NO_ERROR;
  850. continue;
  851. }
  852. CReleaseMe rm11((IWbemClassObject*)pClassDef);
  853. // At this point, we have the localized copy, and are
  854. // ready to combine qualifiers. Start with class qualifiers.
  855. // ============================================================
  856. if (FAILED(pClassDef->GetQualifierSet(&pLocalizedQs)))
  857. continue;
  858. if (FAILED(pResult->GetQualifierSet(&pThisQs)))
  859. {
  860. pLocalizedQs->Release();
  861. continue;
  862. }
  863. hr = LocalizeQualifiers(bInstance, bParentLocalized, pThisQs, pLocalizedQs, bChg);
  864. pLocalizedQs->EndEnumeration();
  865. pLocalizedQs->Release();
  866. pThisQs->Release();
  867. if (FAILED(hr))
  868. break;
  869. hr = LocalizeProperties(bInstance, bParentLocalized, pResult, pClassDef, bChg);
  870. // Methods.
  871. // Putting a method cancels enumeration, so we have to enumerate first.
  872. IWbemClassObject *pLIn = NULL, *pLOut = NULL;
  873. IWbemClassObject *pOIn = NULL, *pOOut = NULL;
  874. BSTR bstrMethodName = NULL ;
  875. int iPos = 0;
  876. pClassDef->BeginMethodEnumeration(0);
  877. while ( pClassDef->NextMethod(0, &bstrMethodName, 0, 0) == S_OK )
  878. {
  879. pLIn = NULL;
  880. pOIn = NULL;
  881. pLOut = NULL;
  882. pOOut = NULL;
  883. pClassDef->GetMethod(bstrMethodName, 0, &pLIn, &pLOut);
  884. hr = pResult->GetMethod(bstrMethodName, 0, &pOIn, &pOOut);
  885. CSysFreeMe fm(bstrMethodName);
  886. CReleaseMe rm0(pLIn);
  887. CReleaseMe rm1(pOIn);
  888. CReleaseMe rm2(pLOut);
  889. CReleaseMe rm3(pOOut);
  890. // METHOD IN PARAMETERS
  891. if (pLIn)
  892. if (pOIn)
  893. hr = LocalizeProperties(bInstance, bParentLocalized, pOIn, pLIn, bChg);
  894. if (pLOut)
  895. if (pOOut)
  896. hr = LocalizeProperties(bInstance, bParentLocalized, pOOut, pLOut, bChg);
  897. // METHOD QUALIFIERS
  898. hr = pResult->GetMethodQualifierSet(bstrMethodName, &pThisQs);
  899. if (FAILED(hr))
  900. {
  901. continue;
  902. }
  903. hr = pClassDef->GetMethodQualifierSet(bstrMethodName, &pLocalizedQs);
  904. if (FAILED(hr))
  905. {
  906. pThisQs->Release();
  907. continue;
  908. }
  909. hr = LocalizeQualifiers(bInstance, bParentLocalized, pThisQs, pLocalizedQs, bChg);
  910. pResult->PutMethod(bstrMethodName, 0, pOIn, pOOut);
  911. pThisQs->Release();
  912. pLocalizedQs->Release();
  913. }
  914. pClassDef->EndMethodEnumeration();
  915. if (bChg)
  916. pResult->SetLocalized(true);
  917. }
  918. #ifdef DBG
  919. for(int i = 0; i < lNumObjects; i++)
  920. {
  921. CWbemObject *pResult = (CWbemObject *)apObjects[i];
  922. if (FAILED(pResult->ValidateObject(WMIOBJECT_VALIDATEOBJECT_FLAG_FORCE)))
  923. DebugBreak();
  924. }
  925. #endif
  926. m_pDestIndicate->Indicate(lNumObjects, apObjects);
  927. return WBEM_S_NO_ERROR;
  928. }
  929. //***************************************************************************
  930. //
  931. //***************************************************************************
  932. /*
  933. STDMETHODIMP CCountedSink::Indicate(long lNumObjects,
  934. IWbemClassObject** apObjects)
  935. {
  936. if(lNumObjects != 1)
  937. return WBEM_E_UNEXPECTED;
  938. DWORD dwNewSent = (DWORD)InterlockedIncrement((LONG*)&m_dwSent);
  939. if(dwNewSent > m_dwMax)
  940. return WBEM_E_UNEXPECTED;
  941. m_pDestIndicate->Indicate(1, apObjects);
  942. if(dwNewSent == m_dwMax)
  943. {
  944. m_pDestStatus->SetStatus(0, WBEM_S_NO_ERROR, NULL, NULL);
  945. return WBEM_S_FALSE;
  946. }
  947. else return WBEM_S_NO_ERROR;
  948. }
  949. */
  950. //***************************************************************************
  951. //
  952. //***************************************************************************
  953. /*
  954. STDMETHODIMP CCountedSink::SetStatus(long lFlags, long lParam,
  955. BSTR strParam, IWbemClassObject* pObjParam)
  956. {
  957. // If SetStatus is 0, indicating that the enum is finished, but we
  958. // didn't send back the requested number of objects, we should
  959. // SetStatus to WBEM_S_FALSE.
  960. if ( WBEM_S_NO_ERROR == lParam )
  961. {
  962. if ( m_dwSent != m_dwMax )
  963. {
  964. lParam = WBEM_S_FALSE;
  965. }
  966. }
  967. return m_pDestStatus->SetStatus( lFlags, lParam, strParam, pObjParam );
  968. }
  969. */
  970. //***************************************************************************
  971. //
  972. //***************************************************************************
  973. STDMETHODIMP CFilteringSink::Indicate(long lObjectCount,
  974. IWbemClassObject** apObjects)
  975. {
  976. try
  977. {
  978. // Allocate new array
  979. wmilib::auto_buffer<IWbemClassObject*> apNewArray(new IWbemClassObject*[lObjectCount]);
  980. if (NULL == apNewArray.get()) return WBEM_E_OUT_OF_MEMORY;
  981. long lNewIndex = 0;
  982. for(int i = 0; i < lObjectCount; i++)
  983. {
  984. if(Test((CWbemObject*)apObjects[i])) // throw
  985. {
  986. apNewArray[lNewIndex++] = apObjects[i];
  987. }
  988. }
  989. HRESULT hres = WBEM_S_NO_ERROR;
  990. if(lNewIndex > 0)
  991. {
  992. hres = m_pDestIndicate->Indicate(lNewIndex, apNewArray.get());
  993. }
  994. return hres;
  995. }
  996. catch (CX_MemoryException &) // becasue Test uses CStack that throws
  997. {
  998. return WBEM_E_OUT_OF_MEMORY;
  999. }
  1000. }
  1001. //***************************************************************************
  1002. //
  1003. //***************************************************************************
  1004. STDMETHODIMP CErrorChangingSink::SetStatus(long lFlags, long lParam,
  1005. BSTR strParam, IWbemClassObject* pObjParam)
  1006. {
  1007. if(lFlags == 0 && lParam == m_hresFrom)
  1008. return m_pDestStatus->SetStatus(0, m_hresTo, NULL, NULL);
  1009. else
  1010. return m_pDestStatus->SetStatus(lFlags, lParam, strParam, pObjParam);
  1011. }
  1012. //***************************************************************************
  1013. //
  1014. //***************************************************************************
  1015. CNoDuplicatesSink::CNoDuplicatesSink(CBasicObjectSink* pDest)
  1016. : CFilteringSink(pDest), m_strDupClass(NULL)
  1017. {
  1018. }
  1019. //***************************************************************************
  1020. //
  1021. //***************************************************************************
  1022. CNoDuplicatesSink::~CNoDuplicatesSink()
  1023. {
  1024. SysFreeString(m_strDupClass);
  1025. }
  1026. //***************************************************************************
  1027. //
  1028. //***************************************************************************
  1029. BOOL CNoDuplicatesSink::Test(CWbemObject* pObj)
  1030. {
  1031. CInCritSec ics(&m_cs); // SEC:REVIEWED 2002-03-22 : Assumes entry
  1032. // Get the path
  1033. // ============
  1034. CVar vPath;
  1035. if(FAILED(pObj->GetPath(&vPath)) || vPath.IsNull()) return FALSE;
  1036. if(m_mapPaths.find(vPath.GetLPWSTR()) == m_mapPaths.end())
  1037. {
  1038. m_mapPaths[vPath.GetLPWSTR()] = true;
  1039. return TRUE;
  1040. }
  1041. else
  1042. {
  1043. // Duplicate!
  1044. // ==========
  1045. ERRORTRACE((LOG_WBEMCORE, "Duplicate objects returned with path %S\n",
  1046. vPath.GetLPWSTR()));
  1047. ConfigMgr::GetEventLog()->Report(EVENTLOG_ERROR_TYPE,
  1048. WBEM_MC_DUPLICATE_OBJECTS, vPath.GetLPWSTR());
  1049. if(m_strDupClass == NULL)
  1050. {
  1051. m_strDupClass = SysAllocString(vPath.GetLPWSTR());
  1052. }
  1053. return FALSE;
  1054. }
  1055. }
  1056. //***************************************************************************
  1057. //
  1058. //***************************************************************************
  1059. STDMETHODIMP CNoDuplicatesSink::SetStatus(long lFlags, long lParam,
  1060. BSTR strParam, IWbemClassObject* pObjParam)
  1061. {
  1062. if(lFlags == WBEM_STATUS_COMPLETE && lParam == WBEM_S_NO_ERROR &&
  1063. m_strDupClass != NULL)
  1064. {
  1065. // Success is being reported, but we have seen duplications
  1066. // ========================================================
  1067. return CFilteringSink::SetStatus(lFlags, WBEM_S_DUPLICATE_OBJECTS,
  1068. m_strDupClass, pObjParam);
  1069. }
  1070. else
  1071. {
  1072. return CFilteringSink::SetStatus(lFlags, lParam, strParam, pObjParam);
  1073. }
  1074. }
  1075. //***************************************************************************
  1076. //
  1077. //***************************************************************************
  1078. STDMETHODIMP CHandleClassProvErrorsSink::SetStatus(long lFlags, long lParam,
  1079. BSTR strParam, IWbemClassObject* pObjParam)
  1080. {
  1081. if(lFlags == WBEM_STATUS_COMPLETE && FAILED(lParam) &&
  1082. lParam != WBEM_E_NOT_FOUND)
  1083. {
  1084. // Log an error into the event log
  1085. // ===============================
  1086. ERRORTRACE((LOG_WBEMCORE,
  1087. "Class provider '%S' installed in namespace '%S' failed to enumerate classes, "
  1088. "returning error code 0x%lx. Operations will continue as if the class provider "
  1089. "had no classes. This provider-specific error condition needs to be corrected "
  1090. "before this class provider can contribute to this namespace.\n",
  1091. (LPWSTR)m_wsProvider, (LPWSTR) m_wsNamespace, lParam));
  1092. lParam = WBEM_E_NOT_FOUND;
  1093. }
  1094. return CForwardingSink::SetStatus(lFlags, lParam, strParam, pObjParam);
  1095. }
  1096. //***************************************************************************
  1097. //
  1098. //***************************************************************************
  1099. STDMETHODIMP CSuccessSuppressionSink::SetStatus(long lFlags, long lParam,
  1100. BSTR strParam, IWbemClassObject* pObjParam)
  1101. {
  1102. if(lFlags != WBEM_STATUS_COMPLETE ||
  1103. (FAILED(lParam) && lParam != m_hresNotError1 &&
  1104. lParam != m_hresNotError2))
  1105. {
  1106. return CForwardingSink::SetStatus(lFlags, lParam, strParam, pObjParam);
  1107. }
  1108. else
  1109. {
  1110. return WBEM_S_NO_ERROR;
  1111. }
  1112. }
  1113. //***************************************************************************
  1114. //
  1115. //***************************************************************************
  1116. CDynPropsSink::CDynPropsSink(CBasicObjectSink* pDest, CWbemNamespace * pNs, long lRef) : CForwardingSink(pDest, lRef)
  1117. {
  1118. m_pNs = pNs;
  1119. if(m_pNs)
  1120. m_pNs->AddRef();
  1121. }
  1122. //***************************************************************************
  1123. //
  1124. //***************************************************************************
  1125. CDynPropsSink::~CDynPropsSink()
  1126. {
  1127. // Send all the cached entries
  1128. DWORD dwCacheSize = m_UnsentCache.GetSize();
  1129. for(DWORD dwCnt = 0; dwCnt < dwCacheSize; dwCnt++)
  1130. {
  1131. IWbemClassObject* pObj = m_UnsentCache[dwCnt];
  1132. if(m_pNs)
  1133. m_pNs->GetOrPutDynProps((CWbemObject *)pObj, CWbemNamespace::GET);
  1134. m_pDestIndicate->Indicate(1, &pObj);
  1135. }
  1136. if(m_pNs)
  1137. m_pNs->Release();
  1138. }
  1139. //***************************************************************************
  1140. //
  1141. //***************************************************************************
  1142. STDMETHODIMP CDynPropsSink::Indicate(long lObjectCount,
  1143. IWbemClassObject** pObjArray)
  1144. {
  1145. // If there are no dyn props then immediately do the indicate
  1146. wmilib::auto_buffer<IWbemClassObject*> apNewArray( new IWbemClassObject*[lObjectCount]);
  1147. if (NULL == apNewArray.get()) return WBEM_E_OUT_OF_MEMORY;
  1148. CVar vDynTest;
  1149. HRESULT hRes = S_OK;
  1150. long lIndex = 0 ;
  1151. for(long lCnt = 0; lCnt < lObjectCount; lCnt++)
  1152. {
  1153. CWbemObject *pWbemObj = (CWbemObject *)pObjArray[lCnt];
  1154. HRESULT hres = pWbemObj->GetQualifier(L"DYNPROPS", &vDynTest);
  1155. if (hres == S_OK && vDynTest.GetBool() == VARIANT_TRUE)
  1156. {
  1157. if (m_UnsentCache.Add(pWbemObj) < 0)
  1158. hRes = WBEM_E_OUT_OF_MEMORY;
  1159. }
  1160. else
  1161. {
  1162. apNewArray[lIndex++] = pObjArray[lCnt] ;
  1163. }
  1164. }
  1165. if ( 0 == lIndex ) return hRes;
  1166. IServerSecurity * pSec = NULL;
  1167. hRes = CoGetCallContext(IID_IServerSecurity,(void **)&pSec);
  1168. CReleaseMe rmSec(pSec);
  1169. if (RPC_E_CALL_COMPLETE == hRes ) hRes = S_OK; // no call context
  1170. if (FAILED(hRes)) return hRes;
  1171. BOOL bImper = (pSec)?pSec->IsImpersonating():FALSE;
  1172. if (pSec && bImper && FAILED(hRes = pSec->RevertToSelf())) return hRes;
  1173. hRes = m_pDestIndicate->Indicate(lIndex, apNewArray.get());
  1174. if (bImper && pSec)
  1175. {
  1176. HRESULT hrInner = pSec->ImpersonateClient();
  1177. if (FAILED(hrInner)) return hrInner;
  1178. }
  1179. return hRes;
  1180. }
  1181. //***************************************************************************
  1182. //
  1183. //***************************************************************************
  1184. STDMETHODIMP CMethodSink::Indicate(long lObjectCount,
  1185. IWbemClassObject** pObjArray)
  1186. {
  1187. if(lObjectCount == 1 && m_pRes == NULL)
  1188. {
  1189. pObjArray[0]->Clone(&m_pRes);
  1190. }
  1191. return S_OK;
  1192. }
  1193. STDMETHODIMP CMethodSink::SetStatus(long lFlags, long lParam,
  1194. BSTR strParam, IWbemClassObject* pObjParam)
  1195. {
  1196. if(lParam == S_OK && m_pRes)
  1197. {
  1198. m_pDestIndicate->Indicate(1, &m_pRes);
  1199. }
  1200. if(m_pRes)
  1201. m_pRes->Release();
  1202. return CForwardingSink::SetStatus(lFlags, lParam, strParam, pObjParam);
  1203. }
  1204. //***************************************************************************
  1205. //
  1206. // ZapWriteOnlyProps
  1207. //
  1208. // Removes write-only properties from an object.
  1209. // Precondition: Object has been tested for presence of "HasWriteOnlyProps"
  1210. // on the object itself.
  1211. //
  1212. //***************************************************************************
  1213. static HRESULT ZapWriteOnlyProps(IWbemClassObject *pObj)
  1214. {
  1215. VARIANT v;
  1216. VariantInit(&v);
  1217. V_VT(&v) = VT_NULL;
  1218. SAFEARRAY *pNames = 0;
  1219. pObj->GetNames(L"WriteOnly", WBEM_FLAG_ONLY_IF_TRUE, 0, &pNames);
  1220. LONG lUpper;
  1221. SafeArrayGetUBound(pNames, 1, &lUpper);
  1222. for (long i = 0; i <= lUpper; i++)
  1223. {
  1224. BSTR strName = 0;
  1225. SafeArrayGetElement(pNames, &i, &strName);
  1226. pObj->Put(strName, 0, &v, 0);
  1227. }
  1228. SafeArrayDestroy(pNames);
  1229. return WBEM_S_NO_ERROR;
  1230. }
  1231. //***************************************************************************
  1232. //
  1233. //***************************************************************************
  1234. //
  1235. CStdSink::CStdSink(IWbemObjectSink *pRealDest)
  1236. {
  1237. m_pDest = pRealDest;
  1238. m_hRes = 0;
  1239. m_bCancelForwarded = FALSE;
  1240. m_lRefCount = 0L;
  1241. if ( NULL != m_pDest )
  1242. m_pDest->AddRef();
  1243. InterlockedIncrement(&g_nStdSinkCount);
  1244. }
  1245. //***************************************************************************
  1246. //
  1247. //***************************************************************************
  1248. //
  1249. CStdSink::~CStdSink()
  1250. {
  1251. if ( NULL != m_pDest )
  1252. m_pDest->Release();
  1253. InterlockedDecrement(&g_nStdSinkCount);
  1254. }
  1255. //***************************************************************************
  1256. //
  1257. //***************************************************************************
  1258. //
  1259. HRESULT CStdSink::Cancel()
  1260. {
  1261. HRESULT hResTmp;
  1262. m_hRes = WBEM_E_CALL_CANCELLED;
  1263. if (m_bCancelForwarded)
  1264. return m_hRes;
  1265. try
  1266. {
  1267. hResTmp = m_pDest->SetStatus(0, m_hRes, 0, 0);
  1268. }
  1269. catch (...) // untrusted code ?
  1270. {
  1271. ExceptionCounter c;
  1272. m_hRes = WBEM_E_CRITICAL_ERROR;
  1273. }
  1274. m_bCancelForwarded = TRUE;
  1275. return m_hRes;
  1276. }
  1277. //***************************************************************************
  1278. //
  1279. //***************************************************************************
  1280. //
  1281. ULONG STDMETHODCALLTYPE CStdSink::AddRef()
  1282. {
  1283. return InterlockedIncrement( &m_lRefCount );
  1284. }
  1285. //***************************************************************************
  1286. //
  1287. //***************************************************************************
  1288. //
  1289. ULONG STDMETHODCALLTYPE CStdSink::Release()
  1290. {
  1291. LONG lRes = InterlockedDecrement( &m_lRefCount );
  1292. if (lRes == 0)
  1293. delete this;
  1294. return lRes;
  1295. }
  1296. //***************************************************************************
  1297. //
  1298. //***************************************************************************
  1299. //
  1300. HRESULT STDMETHODCALLTYPE CStdSink::QueryInterface(REFIID riid, LPVOID* ppvObj)
  1301. {
  1302. return m_pDest->QueryInterface(riid, ppvObj);
  1303. }
  1304. //***************************************************************************
  1305. //
  1306. //***************************************************************************
  1307. //
  1308. HRESULT STDMETHODCALLTYPE CStdSink::Indicate(
  1309. long lObjectCount,
  1310. IWbemClassObject** pObjArray
  1311. )
  1312. {
  1313. HRESULT hRes;
  1314. if (m_hRes == WBEM_E_CALL_CANCELLED)
  1315. {
  1316. return Cancel();
  1317. }
  1318. try
  1319. {
  1320. hRes = m_pDest->Indicate(lObjectCount, pObjArray);
  1321. }
  1322. catch (...) // untrusted code ?
  1323. {
  1324. ExceptionCounter c;
  1325. hRes = Cancel();
  1326. }
  1327. return hRes;
  1328. }
  1329. //***************************************************************************
  1330. //
  1331. //***************************************************************************
  1332. //
  1333. HRESULT STDMETHODCALLTYPE CStdSink::SetStatus(
  1334. long lFlags,
  1335. long lParam,
  1336. BSTR strParam,
  1337. IWbemClassObject* pObjParam
  1338. )
  1339. {
  1340. HRESULT hRes;
  1341. if (m_hRes == WBEM_E_CALL_CANCELLED)
  1342. {
  1343. return Cancel();
  1344. }
  1345. try
  1346. {
  1347. hRes = m_pDest->SetStatus(lFlags, lParam, strParam, pObjParam);
  1348. }
  1349. catch (...) // untrusted code ?
  1350. {
  1351. ExceptionCounter c;
  1352. hRes = Cancel();
  1353. }
  1354. return hRes;
  1355. }
  1356. //***************************************************************************
  1357. //
  1358. //***************************************************************************
  1359. //
  1360. CFlexArray g_aProviderSinks;
  1361. CStaticCritSec g_csProvSinkCs;
  1362. //***************************************************************************
  1363. //
  1364. //***************************************************************************
  1365. //
  1366. HRESULT WINAPI CProviderSink::Dump(FILE *f)
  1367. {
  1368. CInCritSec ics(&g_csProvSinkCs); // SEC:REVIEWED 2002-03-22 : Assumes entry
  1369. fprintf(f, "---Begin Provider Sink Info---\n"); // SEC:REVIEWED 2002-03-22 : Ok, debug code
  1370. for (int i = 0; i < g_aProviderSinks.Size(); i++)
  1371. {
  1372. CProviderSink *pSink = (CProviderSink *) g_aProviderSinks[i];
  1373. if (pSink)
  1374. {
  1375. fprintf(f, "Provider Sink 0x%p\n", pSink); // SEC:REVIEWED 2002-03-22 : Ok, debug code
  1376. fprintf(f, " Total Indicates = %d\n", pSink->m_lIndicateCount); // SEC:REVIEWED 2002-03-22 : Ok, debug code
  1377. // Check that this is non-NULL
  1378. if ( NULL != pSink->m_pszDebugInfo )
  1379. {
  1380. fprintf(f, " Debug Info = %S\n", pSink->m_pszDebugInfo); // SEC:REVIEWED 2002-03-22 : Ok, debug code
  1381. }
  1382. else
  1383. {
  1384. fprintf(f, " Debug Info = NULL\n"); // SEC:REVIEWED 2002-03-22 : Ok, debug code
  1385. }
  1386. fprintf(f, " SetStatus called? %d\n", pSink->m_bDone); // SEC:REVIEWED 2002-03-22 : Ok, debug code
  1387. fprintf(f, " hRes = 0x%X\n", pSink->m_hRes); // SEC:REVIEWED 2002-03-22 : Ok, debug code
  1388. fprintf(f, " m_pNextSink = 0x%p\n", pSink->m_pNextSink); // SEC:REVIEWED 2002-03-22 : Ok, debug code
  1389. }
  1390. }
  1391. fprintf(f, "---End Provider Sink Info---\n"); // SEC:REVIEWED 2002-03-22 : Ok, debug code
  1392. return 0;
  1393. }
  1394. //***************************************************************************
  1395. //
  1396. //***************************************************************************
  1397. //
  1398. CProviderSink::CProviderSink(
  1399. LONG lStartingRefCount,
  1400. LPWSTR pszDebugInf
  1401. ):m_pNextSink(0)
  1402. {
  1403. m_lRefCount = lStartingRefCount;
  1404. InterlockedIncrement(&g_nSinkCount);
  1405. InterlockedIncrement(&g_nProviderSinkCount);
  1406. m_hRes = 0;
  1407. m_bDone = FALSE;
  1408. m_lIndicateCount = 0;
  1409. m_pszDebugInfo = 0;
  1410. if (pszDebugInf)
  1411. {
  1412. DUP_STRING_NEW(m_pszDebugInfo, pszDebugInf);
  1413. }
  1414. CInCritSec ics(&g_csProvSinkCs);
  1415. g_aProviderSinks.Add(this); // just for debug
  1416. }
  1417. //***************************************************************************
  1418. //
  1419. //***************************************************************************
  1420. //
  1421. CProviderSink::~CProviderSink()
  1422. {
  1423. {
  1424. CInCritSec ics(&g_csProvSinkCs); // SEC:REVIEWED 2002-03-22 : Assumes entry
  1425. for (int i = 0; i < g_aProviderSinks.Size(); i++)
  1426. {
  1427. if (this == (CProviderSink *) g_aProviderSinks[i])
  1428. {
  1429. g_aProviderSinks.RemoveAt(i);
  1430. break;
  1431. }
  1432. }
  1433. }
  1434. // Cleanup AFTER we remove from the array so the Diagnostic Thread won't
  1435. // crash.
  1436. ReleaseIfNotNULL(m_pNextSink);
  1437. InterlockedDecrement(&g_nSinkCount);
  1438. InterlockedDecrement(&g_nProviderSinkCount);
  1439. delete [] m_pszDebugInfo;
  1440. }
  1441. //***************************************************************************
  1442. //
  1443. //***************************************************************************
  1444. //
  1445. ULONG CProviderSink::AddRef()
  1446. {
  1447. LONG lRes = InterlockedIncrement(&m_lRefCount);
  1448. return (ULONG) lRes;
  1449. }
  1450. //***************************************************************************
  1451. //
  1452. //***************************************************************************
  1453. //
  1454. ULONG CProviderSink::LocalAddRef()
  1455. {
  1456. LONG lRes = InterlockedIncrement(&m_lRefCount);
  1457. return lRes;
  1458. }
  1459. //***************************************************************************
  1460. //
  1461. //***************************************************************************
  1462. //
  1463. ULONG CProviderSink::LocalRelease()
  1464. {
  1465. LONG lRes = InterlockedDecrement(&m_lRefCount);
  1466. if (lRes == 0)
  1467. delete this;
  1468. return lRes;
  1469. }
  1470. //***************************************************************************
  1471. //
  1472. //***************************************************************************
  1473. //
  1474. ULONG CProviderSink::Release()
  1475. {
  1476. LONG lRes = InterlockedDecrement(&m_lRefCount);
  1477. if (lRes == 0)
  1478. delete this;
  1479. return (ULONG) lRes;
  1480. }
  1481. //***************************************************************************
  1482. //
  1483. //***************************************************************************
  1484. //
  1485. HRESULT CProviderSink::QueryInterface(REFIID riid, LPVOID* ppvObj)
  1486. {
  1487. if (riid == IID_IUnknown || riid == IID_IWbemObjectSink)
  1488. {
  1489. *ppvObj = (IWbemObjectSink*)this;
  1490. AddRef();
  1491. return S_OK;
  1492. }
  1493. else return E_NOINTERFACE;
  1494. }
  1495. //***************************************************************************
  1496. //
  1497. //***************************************************************************
  1498. //
  1499. HRESULT CProviderSink::Indicate(
  1500. long lObjectCount,
  1501. IWbemClassObject** pObjArray
  1502. )
  1503. {
  1504. if (m_hRes)
  1505. return m_hRes;
  1506. IWbemObjectSink* pNextSink = NULL;
  1507. {
  1508. CInCritSec ics(&m_cs); // SEC:REVIEWED 2002-03-22 : Assumes entry
  1509. pNextSink = m_pNextSink;
  1510. if ( NULL != pNextSink )
  1511. {
  1512. pNextSink->AddRef();
  1513. }
  1514. }
  1515. // AutoRelease
  1516. CReleaseMe rm( pNextSink );
  1517. HRESULT hRes;
  1518. if ( NULL != pNextSink )
  1519. {
  1520. m_lIndicateCount += lObjectCount;
  1521. hRes = pNextSink->Indicate(lObjectCount, pObjArray);
  1522. }
  1523. else
  1524. {
  1525. hRes = WBEM_E_CRITICAL_ERROR;
  1526. }
  1527. return hRes;
  1528. }
  1529. //***************************************************************************
  1530. //
  1531. //***************************************************************************
  1532. //
  1533. void CProviderSink::Cancel()
  1534. {
  1535. if (m_bDone)
  1536. return;
  1537. IWbemObjectSink* pNextSink = NULL;
  1538. {
  1539. CInCritSec ics(&m_cs);
  1540. m_hRes = WBEM_E_CALL_CANCELLED;
  1541. pNextSink = m_pNextSink;
  1542. if ( NULL != m_pNextSink )
  1543. {
  1544. // We will release it outside the critical section
  1545. m_pNextSink = NULL;
  1546. }
  1547. }
  1548. // Auto Release
  1549. CReleaseMe rm( pNextSink );
  1550. if ( pNextSink )
  1551. {
  1552. pNextSink->SetStatus(0, WBEM_E_CALL_CANCELLED, 0, 0);
  1553. }
  1554. }
  1555. //***************************************************************************
  1556. //
  1557. //***************************************************************************
  1558. //
  1559. HRESULT CProviderSink::SetStatus(
  1560. long lFlags,
  1561. long lParam,
  1562. BSTR strParam,
  1563. IWbemClassObject* pObjParam
  1564. )
  1565. {
  1566. if (m_hRes)
  1567. return m_hRes;
  1568. IWbemObjectSink* pNextSink = NULL;
  1569. {
  1570. CInCritSec ics(&m_cs);
  1571. pNextSink = m_pNextSink;
  1572. if ( NULL != m_pNextSink )
  1573. {
  1574. // We will always release it outside the critical section
  1575. // If this is the completion status, then we should go ahead and set
  1576. // the member variable to NULL. We're done with the sink.
  1577. if ( lFlags == WBEM_STATUS_COMPLETE )
  1578. {
  1579. m_pNextSink = NULL;
  1580. }
  1581. else
  1582. {
  1583. pNextSink->AddRef();
  1584. }
  1585. }
  1586. }
  1587. // Auto Release
  1588. CReleaseMe rm( pNextSink );
  1589. HRESULT hRes = WBEM_S_NO_ERROR;
  1590. if ( NULL != pNextSink )
  1591. {
  1592. pNextSink->SetStatus(lFlags, lParam, strParam, pObjParam);
  1593. m_bDone = TRUE;
  1594. }
  1595. return hRes;
  1596. }
  1597. //***************************************************************************
  1598. //
  1599. //***************************************************************************
  1600. //
  1601. long g_lNumStatusSinks = 0L;
  1602. CStatusSink::CStatusSink( void )
  1603. : m_hRes( WBEM_S_NO_ERROR ),
  1604. m_lRefCount( 1 )
  1605. {
  1606. InterlockedIncrement( &g_lNumStatusSinks );
  1607. }
  1608. //***************************************************************************
  1609. //
  1610. //***************************************************************************
  1611. //
  1612. CStatusSink::~CStatusSink()
  1613. {
  1614. InterlockedDecrement( &g_lNumStatusSinks );
  1615. }
  1616. //***************************************************************************
  1617. //
  1618. //***************************************************************************
  1619. //
  1620. ULONG STDMETHODCALLTYPE CStatusSink::AddRef()
  1621. {
  1622. return InterlockedIncrement( &m_lRefCount );
  1623. }
  1624. //***************************************************************************
  1625. //
  1626. //***************************************************************************
  1627. //
  1628. ULONG STDMETHODCALLTYPE CStatusSink::Release()
  1629. {
  1630. LONG lRes = InterlockedDecrement( &m_lRefCount );
  1631. if (lRes == 0)
  1632. delete this;
  1633. return lRes;
  1634. }
  1635. //***************************************************************************
  1636. //
  1637. //***************************************************************************
  1638. //
  1639. HRESULT STDMETHODCALLTYPE CStatusSink::QueryInterface(REFIID riid, LPVOID* ppvObj)
  1640. {
  1641. if( riid == IID_IUnknown || riid == IID_IWbemObjectSink )
  1642. {
  1643. *ppvObj = (IWbemObjectSink*)this;
  1644. AddRef();
  1645. return S_OK;
  1646. }
  1647. return E_NOINTERFACE;
  1648. }
  1649. //***************************************************************************
  1650. //
  1651. //***************************************************************************
  1652. //
  1653. HRESULT STDMETHODCALLTYPE CStatusSink::Indicate(
  1654. long lObjectCount,
  1655. IWbemClassObject** pObjArray
  1656. )
  1657. {
  1658. // Why are we even here??!?!?!?
  1659. _DBG_ASSERT( 0 );
  1660. return WBEM_E_FAILED;
  1661. }
  1662. //***************************************************************************
  1663. //
  1664. //***************************************************************************
  1665. //
  1666. HRESULT STDMETHODCALLTYPE CStatusSink::SetStatus(
  1667. long lFlags,
  1668. long lParam,
  1669. BSTR strParam,
  1670. IWbemClassObject* pObjParam
  1671. )
  1672. {
  1673. if ( lFlags == WBEM_STATUS_COMPLETE )
  1674. {
  1675. if ( SUCCEEDED( m_hRes ) && FAILED( lParam ) )
  1676. {
  1677. m_hRes = lParam;
  1678. }
  1679. }
  1680. return WBEM_S_NO_ERROR;
  1681. }
  1682. //***************************************************************************
  1683. //
  1684. //***************************************************************************
  1685. COperationError::COperationError(CBasicObjectSink* pDest,
  1686. LPCWSTR wszOperation,
  1687. LPCWSTR wszParam,
  1688. BOOL bFinal)
  1689. {
  1690. m_fOk = false;
  1691. m_pSink = NULL;
  1692. try
  1693. {
  1694. m_pSink = new COperationErrorSink(pDest, wszOperation, wszParam, bFinal);
  1695. if (NULL == m_pSink)
  1696. {
  1697. if (pDest) pDest->Return(WBEM_E_OUT_OF_MEMORY);
  1698. return;
  1699. }
  1700. m_fOk = true;
  1701. }
  1702. catch(CX_Exception &)
  1703. {
  1704. if (pDest) pDest->Return(WBEM_E_OUT_OF_MEMORY);
  1705. }
  1706. }
  1707. //***************************************************************************
  1708. //
  1709. //***************************************************************************
  1710. COperationError::~COperationError()
  1711. {
  1712. if (m_pSink) m_pSink->Release();
  1713. }
  1714. //***************************************************************************
  1715. //
  1716. //***************************************************************************
  1717. HRESULT COperationError::ErrorOccurred(
  1718. HRESULT hRes,
  1719. IWbemClassObject* pErrorObj
  1720. )
  1721. {
  1722. if (m_pSink) m_pSink->SetStatus(0, hRes, NULL, pErrorObj);
  1723. return hRes;
  1724. }
  1725. //***************************************************************************
  1726. //
  1727. //***************************************************************************
  1728. HRESULT COperationError::ProviderReturned(
  1729. LPCWSTR wszProviderName,
  1730. HRESULT hRes,
  1731. IWbemClassObject* pErrorObj
  1732. )
  1733. {
  1734. m_pSink->SetProviderName(wszProviderName);
  1735. m_pSink->SetStatus(0, hRes, NULL, pErrorObj);
  1736. return hRes;
  1737. }
  1738. //***************************************************************************
  1739. //
  1740. //***************************************************************************
  1741. void COperationError::SetParameterInfo(LPCWSTR wszParam)
  1742. {
  1743. m_pSink->SetParameterInfo(wszParam);
  1744. }
  1745. //***************************************************************************
  1746. //
  1747. //***************************************************************************
  1748. void COperationError::SetProviderName(LPCWSTR wszName)
  1749. {
  1750. m_pSink->SetProviderName(wszName);
  1751. }
  1752. //***************************************************************************
  1753. //
  1754. //***************************************************************************
  1755. CFinalizingSink::CFinalizingSink(
  1756. CWbemNamespace* pNamespace,
  1757. CBasicObjectSink* pDest
  1758. )
  1759. : CForwardingSink(pDest, 0), m_pNamespace(pNamespace)
  1760. {
  1761. m_pNamespace->AddRef();
  1762. }
  1763. //***************************************************************************
  1764. //
  1765. //***************************************************************************
  1766. CFinalizingSink::~CFinalizingSink()
  1767. {
  1768. m_pNamespace->Release();
  1769. }
  1770. //***************************************************************************
  1771. //
  1772. //***************************************************************************
  1773. STDMETHODIMP CFinalizingSink::Indicate(
  1774. long lNumObjects,
  1775. IWbemClassObject** apObj
  1776. )
  1777. {
  1778. HRESULT hRes;
  1779. for (long i = 0; i < lNumObjects; i++)
  1780. {
  1781. CWbemObject *pObj = (CWbemObject *) apObj[i];
  1782. if (pObj == 0)
  1783. {
  1784. ERRORTRACE((LOG_WBEMCORE, "CFinalizingSink::Indicate() -- Null pointer Indicate\n"));
  1785. continue;
  1786. }
  1787. // If object is an instance, we have to deal with dynamic
  1788. // properties.
  1789. // ======================================================
  1790. if (pObj->IsInstance())
  1791. {
  1792. hRes = m_pNamespace->GetOrPutDynProps((CWbemObject*)apObj[i],CWbemNamespace::GET);
  1793. if (FAILED(hRes))
  1794. {
  1795. ERRORTRACE((LOG_WBEMCORE, "CFinalizingSink::Indicate() -- Failed to post-process an instance "
  1796. "using a property provider. Error code %X\n", hRes));
  1797. }
  1798. }
  1799. }
  1800. return m_pDest->Indicate(lNumObjects, apObj);
  1801. }