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.

720 lines
20 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Windows 2000 Active Directory Service domain trust verification WMI provider
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 2000
  7. //
  8. // File: TrustPrv.cpp
  9. //
  10. // Contents: Trust Monitor provider WMI interface class implementation
  11. //
  12. // Classes: CTrustPrv
  13. //
  14. // History: 22-Mar-00 EricB created
  15. //
  16. //-----------------------------------------------------------------------------
  17. #include "stdafx.h"
  18. #include "dbg.cpp"
  19. PCWSTR CLASSNAME_STRING_PROVIDER = L"Microsoft_TrustProvider";
  20. PCWSTR CLASSNAME_STRING_TRUST = L"Microsoft_DomainTrustStatus";
  21. PCWSTR CLASSNAME_STRING_LOCAL = L"Microsoft_LocalDomainInfo";
  22. PCWSTR CSTR_PROP_TRUST_LIST_LIFETIME = L"TrustListLifetime"; // uint32
  23. PCWSTR CSTR_PROP_TRUST_STATUS_LIFETIME = L"TrustStatusLifetime"; // uint32
  24. PCWSTR CSTR_PROP_TRUST_CHECK_LEVEL = L"TrustCheckLevel"; // uint32
  25. PCWSTR CSTR_PROP_RETURN_ALL_TRUSTS = L"ReturnAll"; // boolean
  26. //WCHAR * const PROVIDER_CLASS_CHANGE_QUERY = L"select * from __InstanceOperationEvent where TargetInstance.__Relpath = \"Microsoft_TrustProvider=@\"";
  27. WCHAR * const PROVIDER_CLASS_CHANGE_QUERY = L"select * from __InstanceOperationEvent where TargetInstance isa \"Microsoft_TrustProvider\"";
  28. WCHAR * const PROVIDER_CLASS_INSTANCE = L"Microsoft_TrustProvider=@";
  29. //+----------------------------------------------------------------------------
  30. //
  31. // class CTrustPrv
  32. //
  33. //-----------------------------------------------------------------------------
  34. CTrustPrv::CTrustPrv(void) :
  35. m_hMutex(NULL),
  36. m_TrustCheckLevel(DEFAULT_TRUST_CHECK_LEVEL),
  37. m_fReturnAllTrusts(TRUE),
  38. m_fRegisteredForChanges(FALSE)
  39. {
  40. TRACE(L"CTrustPrv::CTrustPrv(0x%08x)\n", this);
  41. m_liTrustEnumMaxAge.QuadPart = TRUSTMON_DEFAULT_ENUM_AGE;
  42. m_liVerifyMaxAge.QuadPart = TRUSTMON_DEFAULT_VERIFY_AGE;
  43. }
  44. CTrustPrv::~CTrustPrv(void)
  45. {
  46. TRACE(L"CTrustPrv::~CTrustPrv\n");
  47. if (m_hMutex)
  48. {
  49. CloseHandle(m_hMutex);
  50. }
  51. if (m_fRegisteredForChanges)
  52. {
  53. m_sipNamespace->CancelAsyncCall(this);
  54. }
  55. }
  56. //+----------------------------------------------------------------------------
  57. //
  58. // Method: CTrustPrv::IWbemProviderInit::Initialize
  59. //
  60. // Synopsis: Initialize the provider object.
  61. //
  62. // Returns: WMI error codes
  63. //
  64. //-----------------------------------------------------------------------------
  65. STDMETHODIMP
  66. CTrustPrv::Initialize(
  67. IN LPWSTR pszUser,
  68. IN LONG lFlags,
  69. IN LPWSTR pszNamespace,
  70. IN LPWSTR pszLocale,
  71. IN IWbemServices *pNamespace,
  72. IN IWbemContext *pCtx,
  73. IN IWbemProviderInitSink *pInitSink)
  74. {
  75. WBEM_VALIDATE_INTF_PTR(pNamespace);
  76. WBEM_VALIDATE_INTF_PTR(pCtx);
  77. WBEM_VALIDATE_INTF_PTR(pInitSink);
  78. TRACE(L"\nCTrustPrv::Initialize\n");
  79. HRESULT hr = WBEM_S_NO_ERROR;
  80. do
  81. {
  82. m_hMutex = CreateMutex(NULL, FALSE, NULL);
  83. BREAK_ON_NULL_(m_hMutex, hr, WBEM_E_OUT_OF_MEMORY);
  84. m_sipNamespace = pNamespace;
  85. CComPtr<IWbemClassObject> sipProviderInstance;
  86. IWbemClassObject * pLocalClassDef = NULL;
  87. //
  88. // Get pointers to the class definition objects. If a failure, re-compile
  89. // the MOF file and try once more.
  90. //
  91. for (int i = 0; i <= 1; i++)
  92. {
  93. CComBSTR sbstrObjectName = CLASSNAME_STRING_TRUST;
  94. hr = m_sipNamespace->GetObject(sbstrObjectName,
  95. WBEM_FLAG_RETURN_WBEM_COMPLETE,
  96. pCtx,
  97. &m_sipClassDefTrustStatus,
  98. NULL);
  99. if (FAILED(hr))
  100. {
  101. TRACE(L"GetObject(%s) failed with error 0x%08x\n", sbstrObjectName, hr);
  102. DoMofComp(NULL, NULL, NULL, 0);
  103. continue;
  104. }
  105. sbstrObjectName = CLASSNAME_STRING_LOCAL;
  106. hr = m_sipNamespace->GetObject(sbstrObjectName,
  107. WBEM_FLAG_RETURN_WBEM_COMPLETE,
  108. pCtx,
  109. &pLocalClassDef,
  110. NULL);
  111. if (FAILED(hr))
  112. {
  113. TRACE(L"GetObject(%s) failed with error 0x%08x\n", sbstrObjectName, hr);
  114. DoMofComp(NULL, NULL, NULL, 0);
  115. continue;
  116. }
  117. sbstrObjectName = CLASSNAME_STRING_PROVIDER;
  118. hr = m_sipNamespace->GetObject(sbstrObjectName,
  119. WBEM_FLAG_RETURN_WBEM_COMPLETE,
  120. pCtx,
  121. &m_sipClassDefTrustProvider,
  122. NULL);
  123. if (FAILED(hr))
  124. {
  125. TRACE(L"GetObject(%s) failed with error 0x%08x\n", sbstrObjectName, hr);
  126. DoMofComp(NULL, NULL, NULL, 0);
  127. continue;
  128. }
  129. //
  130. // Get the instance of the provider class to read its properties.
  131. //
  132. sbstrObjectName = PROVIDER_CLASS_INSTANCE;
  133. hr = m_sipNamespace->GetObject(sbstrObjectName,
  134. WBEM_FLAG_RETURN_WBEM_COMPLETE,
  135. pCtx,
  136. &sipProviderInstance,
  137. NULL);
  138. if (FAILED(hr))
  139. {
  140. TRACE(L"GetObject(%s) failed with error 0x%08x\n", sbstrObjectName, hr);
  141. DoMofComp(NULL, NULL, NULL, 0);
  142. }
  143. else
  144. {
  145. i = 2; // success, don't loop again.
  146. }
  147. }
  148. BREAK_ON_FAIL;
  149. //
  150. // Set this provider instance's runtime properties.
  151. //
  152. hr = SetProviderProps(sipProviderInstance);
  153. BREAK_ON_FAIL;
  154. //
  155. // Initialize the domain object.
  156. //
  157. hr = m_DomainInfo.Init(pLocalClassDef);
  158. BREAK_ON_FAIL;
  159. //
  160. // Register to recieve change notifications for the provider class
  161. // properties.
  162. //
  163. CComBSTR bstrLang(L"WQL");
  164. CComBSTR bstrClassQuery(PROVIDER_CLASS_CHANGE_QUERY);
  165. hr = m_sipNamespace->ExecNotificationQueryAsync(bstrLang,
  166. bstrClassQuery,
  167. 0,
  168. NULL,
  169. this);
  170. BREAK_ON_FAIL;
  171. m_fRegisteredForChanges = TRUE;
  172. //
  173. // Let CIMOM know we are initialized.
  174. // Return value and SetStatus param should be consistent, so ignore
  175. // the return value from SetStatus itself (in retail builds).
  176. //
  177. HRESULT hr2;
  178. hr2 = pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
  179. ASSERT(!FAILED(hr2));
  180. } while (false);
  181. if (FAILED(hr))
  182. {
  183. TRACE(L"hr = 0x%08x\n", hr);
  184. pInitSink->SetStatus(WBEM_E_FAILED, 0);
  185. }
  186. return hr;
  187. }
  188. //+----------------------------------------------------------------------------
  189. //
  190. // Method: CTrustPrv::IWbemObjectSink::Indicate
  191. //
  192. // Synopsis: Recieves provider object instance change notifications from WMI.
  193. //
  194. //-----------------------------------------------------------------------------
  195. STDMETHODIMP
  196. CTrustPrv::Indicate(LONG lObjectCount,
  197. IWbemClassObject ** rgpObjArray)
  198. {
  199. TRACE(L"\nCTrustPrv::Indicate++++++++++++++++\n");
  200. if (1 > lObjectCount)
  201. {
  202. TRACE(L"\tno objects supplied!\n");
  203. return WBEM_S_NO_ERROR;
  204. }
  205. VARIANT var;
  206. HRESULT hr = (*rgpObjArray)->Get(L"TargetInstance", 0, &var, NULL, NULL);
  207. if (FAILED(hr) || VT_UNKNOWN != var.vt || !var.punkVal)
  208. {
  209. TRACE(L"Error, could not get the target instance, hr = 0x%08x\n", hr);
  210. return hr;
  211. }
  212. hr = SetProviderProps((IWbemClassObject *)var.punkVal);
  213. VariantClear(&var);
  214. return hr;
  215. }
  216. //+----------------------------------------------------------------------------
  217. //
  218. // Method: CTrustPrv::SetProviderProps
  219. //
  220. // Synopsis: Set the provider runtime instance values from the instance of
  221. // the Microsoft_TrustProvider class.
  222. //
  223. //-----------------------------------------------------------------------------
  224. HRESULT
  225. CTrustPrv::SetProviderProps(IWbemClassObject * pClass)
  226. {
  227. WBEM_VALIDATE_INTF_PTR(pClass);
  228. TRACE(L"\nCTrustPrv::SetProviderProps\n");
  229. HRESULT hr = WBEM_S_NO_ERROR;
  230. do
  231. {
  232. VARIANT var;
  233. hr = pClass->Get(CSTR_PROP_TRUST_LIST_LIFETIME, 0, &var, NULL, NULL);
  234. BREAK_ON_FAIL;
  235. SetTrustListLifetime(var.lVal);
  236. VariantClear(&var);
  237. hr = pClass->Get(CSTR_PROP_TRUST_STATUS_LIFETIME, 0, &var, NULL, NULL);
  238. BREAK_ON_FAIL;
  239. SetTrustStatusLifetime(var.lVal);
  240. VariantClear(&var);
  241. hr = pClass->Get(CSTR_PROP_TRUST_CHECK_LEVEL, 0, &var, NULL, NULL);
  242. BREAK_ON_FAIL;
  243. SetTrustCheckLevel(var.lVal);
  244. VariantClear(&var);
  245. hr = pClass->Get(CSTR_PROP_RETURN_ALL_TRUSTS, 0, &var, NULL, NULL);
  246. BREAK_ON_FAIL;
  247. SetReturnAll(var.boolVal);
  248. VariantClear(&var);
  249. } while (false);
  250. return hr;
  251. }
  252. //+----------------------------------------------------------------------------
  253. //
  254. // Function: GetClass
  255. //
  256. // Synopsis: Determines if the first element of the passed in path is one
  257. // of the valid class names.
  258. //
  259. // Returns: TrustMonClass enum value.
  260. //
  261. //-----------------------------------------------------------------------------
  262. TrustMonClass
  263. GetClass(BSTR strClass)
  264. {
  265. if (_wcsnicmp(strClass, CLASSNAME_STRING_PROVIDER, wcslen(CLASSNAME_STRING_PROVIDER)) == 0)
  266. {
  267. TRACE(L"GetClass returning %s\n", CLASSNAME_STRING_PROVIDER);
  268. return CLASS_PROVIDER;
  269. }
  270. else
  271. {
  272. if (_wcsnicmp(strClass, CLASSNAME_STRING_TRUST, wcslen(CLASSNAME_STRING_TRUST)) == 0)
  273. {
  274. TRACE(L"GetClass returning %s\n", CLASSNAME_STRING_TRUST);
  275. return CLASS_TRUST;
  276. }
  277. else
  278. {
  279. if (_wcsnicmp(strClass, CLASSNAME_STRING_LOCAL, wcslen(CLASSNAME_STRING_LOCAL)) == 0)
  280. {
  281. TRACE(L"GetClass returning %s\n", CLASSNAME_STRING_LOCAL);
  282. return CLASS_LOCAL;
  283. }
  284. else
  285. {
  286. TRACE(L"GetClass returning NO_CLASS\n");
  287. return NO_CLASS;
  288. }
  289. }
  290. }
  291. }
  292. //+----------------------------------------------------------------------------
  293. //
  294. // Method: CTrustPrv::IWbemServices::GetObjectAsync
  295. //
  296. // Synopsis: Return the instance named by strObjectPath.
  297. //
  298. // Returns: WMI error codes
  299. //
  300. //-----------------------------------------------------------------------------
  301. STDMETHODIMP
  302. CTrustPrv::GetObjectAsync(
  303. IN const BSTR strObjectPath,
  304. IN long lFlags,
  305. IN IWbemContext * pCtx,
  306. IN IWbemObjectSink * pResponseHandler)
  307. {
  308. HRESULT hr = WBEM_S_NO_ERROR;
  309. CTrustInfo * pTrust;
  310. BOOL fReverted = FALSE;
  311. TRACE(L"\nCTrustsPrv::GetObjectAsync:\n"
  312. L"\tObject param = %s, flags = 0x%08x\n", strObjectPath, lFlags);
  313. do
  314. {
  315. WBEM_VALIDATE_IN_STRING_PTR(strObjectPath);
  316. WBEM_VALIDATE_INTF_PTR(pCtx);
  317. WBEM_VALIDATE_INTF_PTR(pResponseHandler);
  318. //
  319. // Determine which class is being requested.
  320. // A valid class object path has the form: class_name.key_name="key_value"
  321. //
  322. TrustMonClass Class = GetClass(strObjectPath);
  323. if (NO_CLASS == Class)
  324. {
  325. hr = WBEM_E_INVALID_OBJECT_PATH;
  326. BREAK_ON_FAIL(hr);
  327. }
  328. // Isolate the class name from the key name
  329. //
  330. PWSTR pwzInstance;
  331. PWSTR pwzKeyName = wcschr(strObjectPath, L'.');
  332. if (pwzKeyName)
  333. {
  334. // A request without a key name is only valid for a class that
  335. // is defined to have zero or only one dynamic instance (singleton).
  336. //
  337. // Isolate the key name from the class name
  338. //
  339. *pwzKeyName = L'\0'; // overwrite the period with a null
  340. pwzKeyName++; // point to the first char of the key name
  341. }
  342. switch (Class)
  343. {
  344. case CLASS_PROVIDER:
  345. //
  346. // The provider class has no dynamic instances, return a copy of the
  347. // static instance.
  348. //
  349. fReverted = TRUE; // never impersonated
  350. hr = CreateAndSendProv(pResponseHandler);
  351. BREAK_ON_FAIL(hr);
  352. break;
  353. case CLASS_TRUST:
  354. //
  355. // There can be zero or more trusts. Thus the key name and value must
  356. // be specified.
  357. //
  358. CoImpersonateClient();
  359. if (!pwzKeyName)
  360. {
  361. hr = WBEM_E_INVALID_OBJECT_PATH;
  362. BREAK_ON_FAIL(hr);
  363. }
  364. pwzInstance = wcschr(pwzKeyName, L'=');
  365. if (!pwzInstance || L'\"' != pwzInstance[1])
  366. {
  367. // No equal sign found or the following char not a quote.
  368. //
  369. hr = WBEM_E_INVALID_OBJECT_PATH;
  370. BREAK_ON_FAIL(hr);
  371. }
  372. *pwzInstance = L'\0'; // isolate the key name.
  373. if (_wcsicmp(pwzKeyName, CSTR_PROP_TRUSTED_DOMAIN) != 0)
  374. {
  375. // Key name not correct.
  376. //
  377. hr = WBEM_E_INVALID_OBJECT_PATH;
  378. BREAK_ON_FAIL(hr);
  379. }
  380. pwzInstance++; // point to the first quote
  381. if (L'\0' == pwzInstance[1] || L'\"' == pwzInstance[1])
  382. {
  383. // No char following the quote or the next char a second quote
  384. //
  385. hr = WBEM_E_INVALID_OBJECT_PATH;
  386. BREAK_ON_FAIL(hr);
  387. }
  388. pwzInstance++; // point to the first char of the instance value;
  389. PWSTR pwzInstEnd;
  390. pwzInstEnd = wcschr(pwzInstance, L'\"');
  391. if (!pwzInstEnd)
  392. {
  393. // No terminating quote.
  394. //
  395. hr = WBEM_E_INVALID_OBJECT_PATH;
  396. BREAK_ON_FAIL(hr);
  397. }
  398. *pwzInstEnd = L'\0'; // replace ending quote with a null
  399. if (m_DomainInfo.IsTrustListStale(m_liTrustEnumMaxAge))
  400. {
  401. hr = m_DomainInfo.EnumerateTrusts();
  402. }
  403. BREAK_ON_FAIL(hr);
  404. pTrust = m_DomainInfo.FindTrust(pwzInstance);
  405. BREAK_ON_NULL_(pTrust, hr, WBEM_E_INVALID_OBJECT_PATH);
  406. //
  407. // Verify the trust.
  408. //
  409. if (pTrust->IsVerificationStale(m_liVerifyMaxAge))
  410. {
  411. pTrust->Verify(GetTrustCheckLevel());
  412. }
  413. CoRevertToSelf();
  414. fReverted = TRUE;
  415. //
  416. // Create a new instance of the object
  417. //
  418. hr = CreateAndSendTrustInst(*pTrust,
  419. m_sipClassDefTrustStatus,
  420. pResponseHandler);
  421. BREAK_ON_FAIL(hr);
  422. break;
  423. case CLASS_LOCAL:
  424. //
  425. // The local domain info class has only one instance, return that.
  426. //
  427. fReverted = TRUE; // never impersonated
  428. hr = m_DomainInfo.CreateAndSendInst(pResponseHandler);
  429. BREAK_ON_FAIL(hr);
  430. break;
  431. default:
  432. hr = WBEM_E_INVALID_OBJECT_PATH;
  433. BREAK_ON_FAIL(hr);
  434. }
  435. } while(FALSE);
  436. if (!fReverted)
  437. {
  438. CoRevertToSelf();
  439. }
  440. return pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  441. }
  442. //+----------------------------------------------------------------------------
  443. //
  444. // Method: CTrustPrv::IWbemServices::CreateInstanceEnumAsync
  445. //
  446. // Synopsis: Start an asyncronous enumeration of the instances of the class.
  447. //
  448. // Returns: WMI error codes
  449. //
  450. //-----------------------------------------------------------------------------
  451. STDMETHODIMP
  452. CTrustPrv::CreateInstanceEnumAsync(
  453. IN const BSTR strClass,
  454. IN long lFlags,
  455. IN IWbemContext *pCtx,
  456. IN IWbemObjectSink *pResponseHandler)
  457. {
  458. TRACE(L"\nCTrustsPrv::CreateInstanceEnumAsync:\n"
  459. L"\tClass param = %s, flags = 0x%08x\n", strClass, lFlags);
  460. HRESULT hr = WBEM_S_NO_ERROR;
  461. do
  462. {
  463. WBEM_VALIDATE_IN_STRING_PTR(strClass);
  464. WBEM_VALIDATE_INTF_PTR(pCtx);
  465. WBEM_VALIDATE_INTF_PTR(pResponseHandler);
  466. //
  467. // Determine which class is being requested.
  468. // A valid class object path has the form: class_name.key_name="key_value"
  469. //
  470. TrustMonClass Class = GetClass(strClass);
  471. if (NO_CLASS == Class)
  472. {
  473. hr = WBEM_E_INVALID_OBJECT_PATH;
  474. BREAK_ON_FAIL(hr);
  475. }
  476. CAsyncCallWorker * pWorker;
  477. switch (Class)
  478. {
  479. case CLASS_PROVIDER:
  480. //
  481. // The provider class has no dynamic instances, return a copy of the
  482. // static instance.
  483. //
  484. hr = CreateAndSendProv(pResponseHandler);
  485. BREAK_ON_FAIL(hr);
  486. hr = pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  487. BREAK_ON_FAIL(hr);
  488. break;
  489. case CLASS_TRUST:
  490. //
  491. // Spawn the worker thread to enum and return the trust instances.
  492. // Note that the class definition pointer is not add-ref'd here
  493. // because it is add-ref'd separately in the CAsyncCallWorker ctor.
  494. //
  495. pWorker = new CAsyncCallWorker(this,
  496. lFlags,
  497. m_sipClassDefTrustStatus,
  498. pResponseHandler);
  499. BREAK_ON_NULL_(pWorker, hr, WBEM_E_OUT_OF_MEMORY);
  500. uintptr_t hThread;
  501. hThread = _beginthread(CAsyncCallWorker::CreateInstEnum, 0, (PVOID)pWorker);
  502. BREAK_ON_NULL_(hThread != -1, hr, WBEM_E_OUT_OF_MEMORY);
  503. break;
  504. case CLASS_LOCAL:
  505. //
  506. // The local domain info class has only one instance, return that.
  507. //
  508. hr = m_DomainInfo.CreateAndSendInst(pResponseHandler);
  509. BREAK_ON_FAIL(hr);
  510. hr = pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  511. BREAK_ON_FAIL(hr);
  512. break;
  513. default:
  514. hr = WBEM_E_INVALID_OBJECT_PATH;
  515. BREAK_ON_FAIL(hr);
  516. }
  517. } while(FALSE);
  518. if (FAILED(hr))
  519. {
  520. return pResponseHandler->SetStatus(WBEM_STATUS_COMPLETE, hr, NULL, NULL);
  521. }
  522. return hr;
  523. }
  524. //+----------------------------------------------------------------------------
  525. //
  526. // Method: CTrustPrv::CreateAndSendProv
  527. //
  528. // Synopsis: Return the provider parameters.
  529. //
  530. //-----------------------------------------------------------------------------
  531. HRESULT
  532. CTrustPrv::CreateAndSendProv(IWbemObjectSink * pResponseHandler)
  533. {
  534. TRACE(L"CTrustsPrv::CreateAndSendProv:\n");
  535. HRESULT hr = WBEM_S_NO_ERROR;
  536. do
  537. {
  538. CComPtr<IWbemClassObject> ipNewInst;
  539. VARIANT var;
  540. VariantInit(&var);
  541. //
  542. // Create a new instance of the WMI class object
  543. //
  544. hr = m_sipClassDefTrustProvider->SpawnInstance(0, &ipNewInst);
  545. BREAK_ON_FAIL;
  546. // Set the TrustListLifetime property value
  547. var.lVal = (long)GetTrustListLifetime();
  548. var.vt = VT_I4;
  549. hr = ipNewInst->Put(CSTR_PROP_TRUST_LIST_LIFETIME, 0, &var, 0);
  550. TRACE(L"\tTrustListLifetime %d\n", var.bstrVal);
  551. BREAK_ON_FAIL;
  552. // Set the TrustStatusLifetime property value
  553. var.lVal = (long)GetTrustStatusLifetime();
  554. hr = ipNewInst->Put(CSTR_PROP_TRUST_STATUS_LIFETIME, 0, &var, 0);
  555. TRACE(L"\tTrustStatusLifetime %d\n", var.bstrVal);
  556. BREAK_ON_FAIL;
  557. // Set the TrustCheckLevel property value
  558. var.lVal = (long)GetTrustCheckLevel();
  559. hr = ipNewInst->Put(CSTR_PROP_TRUST_CHECK_LEVEL, 0, &var, 0);
  560. TRACE(L"\tTrustCheckLevel %d\n", var.bstrVal);
  561. BREAK_ON_FAIL;
  562. // Set the ReturnAll property value
  563. var.boolVal = (GetReturnAll()) ? VARIANT_TRUE : VARIANT_FALSE;
  564. var.vt = VT_BOOL;
  565. hr = ipNewInst->Put(CSTR_PROP_RETURN_ALL_TRUSTS, 0, &var, 0);
  566. TRACE(L"\tReturnAll %d\n", var.bstrVal);
  567. BREAK_ON_FAIL;
  568. //
  569. // Send the object to the caller
  570. //
  571. // [In] param, no need to addref.
  572. IWbemClassObject * pNewInstance = ipNewInst;
  573. hr = pResponseHandler->Indicate(1, &pNewInstance);
  574. BREAK_ON_FAIL;
  575. } while(FALSE);
  576. return hr;
  577. }