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.

576 lines
16 KiB

  1. // INSTPROV.CPP: implementation of the CBaseInstanceProvider class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "HMAgent.h"
  5. #include "instprov.h"
  6. //////////////////////////////////////////////////////////////////////
  7. // global data
  8. extern CSystem* g_pSystem;
  9. extern HANDLE g_hConfigLock;
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CBaseInstanceProvider::CBaseInstanceProvider()
  14. {
  15. OutputDebugString(L"CBaseInstanceProvider::CBaseInstanceProvider()\n");
  16. m_cRef = 0L;
  17. m_pIWbemServices = NULL;
  18. }
  19. CBaseInstanceProvider::~CBaseInstanceProvider()
  20. {
  21. OutputDebugString(L"CBaseInstanceProvider::~CBaseInstanceProvider()\n");
  22. if (m_pIWbemServices)
  23. {
  24. m_pIWbemServices->Release();
  25. }
  26. m_pIWbemServices = NULL;
  27. }
  28. //////////////////////////////////////////////////////////////////////
  29. // IUnknown Implementation
  30. //////////////////////////////////////////////////////////////////////
  31. STDMETHODIMP CBaseInstanceProvider::QueryInterface(REFIID riid, LPVOID* ppv)
  32. {
  33. MY_ASSERT(ppv);
  34. *ppv = NULL;
  35. if(riid== IID_IWbemServices)
  36. {
  37. *ppv=(IWbemServices*)this;
  38. }
  39. else if(IID_IUnknown==riid || riid== IID_IWbemProviderInit)
  40. {
  41. *ppv=(IWbemProviderInit*)this;
  42. }
  43. else
  44. {
  45. return E_NOINTERFACE;
  46. }
  47. AddRef();
  48. return S_OK;
  49. }
  50. STDMETHODIMP_(ULONG) CBaseInstanceProvider::AddRef(void)
  51. {
  52. return InterlockedIncrement((long*)&m_cRef);
  53. }
  54. STDMETHODIMP_(ULONG) CBaseInstanceProvider::Release(void)
  55. {
  56. LONG lCount = InterlockedDecrement((long*)&m_cRef);
  57. if (0 != lCount)
  58. {
  59. return lCount;
  60. }
  61. delete this;
  62. return 0L;
  63. }
  64. //////////////////////////////////////////////////////////////////////
  65. // IWbemProviderInit Implementation
  66. //////////////////////////////////////////////////////////////////////
  67. HRESULT CBaseInstanceProvider::Initialize(LPWSTR pszUser,
  68. LONG lFlags,
  69. LPWSTR pszNamespace,
  70. LPWSTR pszLocale,
  71. IWbemServices __RPC_FAR *pNamespace,
  72. IWbemContext __RPC_FAR *pCtx,
  73. IWbemProviderInitSink __RPC_FAR *pInitSink)
  74. {
  75. OutputDebugString(L"CBaseInstanceProvider::Initialize()\n");
  76. if (NULL == pNamespace)
  77. {
  78. return WBEM_E_INVALID_PARAMETER;
  79. }
  80. m_pIWbemServices = pNamespace;
  81. m_pIWbemServices->AddRef();
  82. pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
  83. return WBEM_S_NO_ERROR;
  84. }
  85. //////////////////////////////////////////////////////////////////////
  86. // IWbemService Implementation
  87. //////////////////////////////////////////////////////////////////////
  88. HRESULT CBaseInstanceProvider::CreateInstanceEnumAsync(const BSTR Class, long lFlags,
  89. IWbemContext __RPC_FAR *pCtx, IWbemObjectSink __RPC_FAR *pResponseHandler)
  90. {
  91. HRESULT hRes;
  92. DWORD dwErr = 0;
  93. TCHAR szClass[HM_MAX_PATH];
  94. if (pResponseHandler == NULL)
  95. {
  96. return WBEM_E_INVALID_PARAMETER;
  97. }
  98. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync BLOCK - g_hConfigLock BLOCK WAIT", 4);
  99. dwErr = WaitForSingleObject(g_hConfigLock, HM_ASYNC_TIMEOUT);
  100. if(dwErr != WAIT_OBJECT_0)
  101. {
  102. if(dwErr = WAIT_TIMEOUT)
  103. {
  104. TRACE_MUTEX(L"TIMEOUT MUTEX");
  105. return WBEM_S_TIMEDOUT;
  106. }
  107. else
  108. {
  109. TRACE_MUTEX(L"WaitForSingleObject on Mutex failed");
  110. return WBEM_E_FAILED;
  111. }
  112. }
  113. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync BLOCK - g_hConfigLock BLOCK GOT IT", 4);
  114. if (!g_pSystem)
  115. {
  116. ReleaseMutex(g_hConfigLock);
  117. return S_FALSE;
  118. }
  119. // Class is a MicrosoftHM_xxx
  120. MY_ASSERT(wcslen(Class) > HM_PREFIX_LEN);
  121. wcsncpy(szClass, Class, HM_MAX_PATH-1);
  122. szClass[HM_MAX_PATH-1] = '\0';
  123. _wcsupr(szClass);
  124. if (!wcscmp(szClass+HM_PREFIX_LEN, L"SYSTEMSTATUS"))
  125. {
  126. hRes = g_pSystem->SendHMSystemStatusInstances(pResponseHandler);
  127. }
  128. else if (!wcscmp(szClass+HM_PREFIX_LEN, L"DATAGROUPSTATUS"))
  129. {
  130. hRes = g_pSystem->SendHMDataGroupStatusInstances(pResponseHandler);
  131. }
  132. else if (!wcscmp(szClass+HM_PREFIX_LEN, L"DATACOLLECTORSTATUS"))
  133. {
  134. hRes = g_pSystem->SendHMDataCollectorStatusInstances(pResponseHandler);
  135. }
  136. else if (!wcscmp(szClass+HM_PREFIX_LEN, L"DATACOLLECTORPERINSTANCESTATUS"))
  137. {
  138. hRes = g_pSystem->SendHMDataCollectorPerInstanceStatusInstances(pResponseHandler);
  139. }
  140. else if (!wcscmp(szClass+HM_PREFIX_LEN, L"DATACOLLECTORSTATISTICS"))
  141. {
  142. hRes = g_pSystem->SendHMDataCollectorStatisticsInstances(pResponseHandler);
  143. }
  144. else if (!wcscmp(szClass+HM_PREFIX_LEN, L"THRESHOLDSTATUS"))
  145. {
  146. hRes = g_pSystem->SendHMThresholdStatusInstances(pResponseHandler);
  147. }
  148. else if (!wcscmp(szClass+HM_PREFIX_LEN, L"ACTIONSTATUS"))
  149. {
  150. hRes = g_pSystem->SendHMActionStatusInstances(pResponseHandler);
  151. }
  152. else
  153. {
  154. // class not supported by this provider
  155. hRes = pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
  156. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  157. ReleaseMutex(g_hConfigLock);
  158. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASED", 4);
  159. return WBEM_E_NOT_SUPPORTED;
  160. }
  161. if (FAILED(hRes))
  162. {
  163. OutputDebugString(L"CBaseInstanceProvider SendSMEvents failed!");
  164. pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
  165. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  166. ReleaseMutex(g_hConfigLock);
  167. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASED", 4);
  168. return hRes;
  169. }
  170. // Now let caller know it's done.
  171. pResponseHandler->SetStatus(0L, WBEM_S_NO_ERROR, NULL, NULL);
  172. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  173. ReleaseMutex(g_hConfigLock);
  174. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::CreateInstanceEnumAsync g_hConfigLock BLOCK - RELEASED", 4);
  175. return WBEM_S_NO_ERROR;
  176. }
  177. HRESULT CBaseInstanceProvider::GetObjectAsync(const BSTR ObjectPath, long lFlags, IWbemContext __RPC_FAR *pCtx,
  178. IWbemObjectSink __RPC_FAR *pResponseHandler)
  179. {
  180. TCHAR szPath[HM_MAX_PATH];
  181. LPTSTR pszGUID;
  182. LPTSTR pszEnd;
  183. HRESULT hRes;
  184. DWORD dwErr = 0;
  185. if (pResponseHandler==NULL || (HM_MAX_PATH-1) < wcslen(ObjectPath))
  186. {
  187. return WBEM_E_INVALID_PARAMETER;
  188. }
  189. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync BLOCK - g_hConfigLock BLOCK WAIT", 4);
  190. dwErr = WaitForSingleObject(g_hConfigLock, HM_ASYNC_TIMEOUT);
  191. if(dwErr != WAIT_OBJECT_0)
  192. {
  193. if(dwErr = WAIT_TIMEOUT)
  194. {
  195. TRACE_MUTEX(L"TIMEOUT MUTEX");
  196. return WBEM_S_TIMEDOUT;
  197. }
  198. else
  199. {
  200. MY_OUTPUT(L"WaitForSingleObject on Mutex failed",4);
  201. return WBEM_E_FAILED;
  202. }
  203. }
  204. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync BLOCK - g_hConfigLock BLOCK GOT IT", 4);
  205. OutputDebugString(L"CBaseInstanceProvider::GetObjectAsync()\n");
  206. if (!g_pSystem)
  207. {
  208. ReleaseMutex(g_hConfigLock);
  209. return S_FALSE;
  210. }
  211. //
  212. // Going to look something like this ->
  213. // MicrosoftHM_DataGroupStatus.GUID="{269EA380-07CA-11d3-8FEB-006097919914}"
  214. //
  215. wcsncpy(szPath, ObjectPath, HM_MAX_PATH-1);
  216. szPath[HM_MAX_PATH-1] = '\0';
  217. _wcsupr(szPath);
  218. pszEnd = wcschr(szPath, '.');
  219. if (pszEnd)
  220. {
  221. *pszEnd = '\0';
  222. pszEnd++;
  223. pszEnd = wcschr(pszEnd, '"');
  224. if (pszEnd)
  225. {
  226. pszEnd++;
  227. pszGUID = pszEnd;
  228. pszEnd = wcschr(pszEnd, '"');
  229. if (pszEnd)
  230. {
  231. *pszEnd = '\0';
  232. }
  233. else
  234. {
  235. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  236. ReleaseMutex(g_hConfigLock);
  237. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  238. return WBEM_E_INVALID_PARAMETER;
  239. }
  240. }
  241. else
  242. {
  243. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  244. ReleaseMutex(g_hConfigLock);
  245. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  246. return WBEM_E_INVALID_PARAMETER;
  247. }
  248. }
  249. else
  250. {
  251. pszEnd = wcschr(szPath, '=');
  252. if (pszEnd)
  253. {
  254. *pszEnd = '\0';
  255. pszEnd++;
  256. if (*pszEnd == '@')
  257. {
  258. pszGUID = pszEnd;
  259. }
  260. else
  261. {
  262. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  263. ReleaseMutex(g_hConfigLock);
  264. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  265. return WBEM_E_INVALID_PARAMETER;
  266. }
  267. }
  268. else
  269. {
  270. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  271. ReleaseMutex(g_hConfigLock);
  272. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  273. return WBEM_E_INVALID_PARAMETER;
  274. }
  275. }
  276. try
  277. {
  278. //
  279. // Now find out which instance type we need to return.
  280. //
  281. if (!wcscmp(szPath+HM_PREFIX_LEN, L"SYSTEMSTATUS"))
  282. {
  283. hRes = g_pSystem->SendHMSystemStatusInstance(pResponseHandler, pszGUID);
  284. }
  285. else if (!wcscmp(szPath+HM_PREFIX_LEN, L"DATAGROUPSTATUS"))
  286. {
  287. hRes = g_pSystem->SendHMDataGroupStatusInstance(pResponseHandler, pszGUID);
  288. }
  289. else if (!wcscmp(szPath+HM_PREFIX_LEN, L"DATACOLLECTORSTATUS"))
  290. {
  291. hRes = g_pSystem->SendHMDataCollectorStatusInstance(pResponseHandler, pszGUID);
  292. }
  293. else if (!wcscmp(szPath+HM_PREFIX_LEN, L"DATACOLLECTORPERINSTANCESTATUS"))
  294. {
  295. hRes = g_pSystem->SendHMDataCollectorPerInstanceStatusInstance(pResponseHandler, pszGUID);
  296. }
  297. else if (!wcscmp(szPath+HM_PREFIX_LEN, L"DATACOLLECTORSTATISTICS"))
  298. {
  299. hRes = g_pSystem->SendHMDataCollectorStatisticsInstance(pResponseHandler, pszGUID);
  300. }
  301. else if (!wcscmp(szPath+HM_PREFIX_LEN, L"THRESHOLDSTATUS"))
  302. {
  303. hRes = g_pSystem->SendHMThresholdStatusInstance(pResponseHandler, pszGUID);
  304. }
  305. else if (!wcscmp(szPath+HM_PREFIX_LEN, L"ACTIONSTATUS"))
  306. {
  307. hRes = g_pSystem->SendHMActionStatusInstance(pResponseHandler, pszGUID);
  308. }
  309. else
  310. {
  311. MY_ASSERT(FALSE);
  312. hRes = pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
  313. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  314. ReleaseMutex(g_hConfigLock);
  315. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  316. return WBEM_E_NOT_SUPPORTED;
  317. }
  318. }
  319. catch (...)
  320. {
  321. hRes = S_FALSE;
  322. MY_ASSERT(FALSE);
  323. }
  324. if (FAILED(hRes))
  325. {
  326. MY_HRESASSERT(hRes);
  327. OutputDebugString(L"CBaseInstanceProvider SendSMEvents failed!");
  328. pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
  329. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  330. ReleaseMutex(g_hConfigLock);
  331. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  332. return hRes;
  333. }
  334. // Now let caller know it's done.
  335. pResponseHandler->SetStatus(0L, WBEM_S_NO_ERROR, NULL, NULL);
  336. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  337. ReleaseMutex(g_hConfigLock);
  338. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  339. return WBEM_S_NO_ERROR;
  340. }
  341. HRESULT CBaseInstanceProvider::ExecQueryAsync(const BSTR QueryLanguage, const BSTR Query, long lFlags,
  342. IWbemContext __RPC_FAR *pCtx, IWbemObjectSink __RPC_FAR *pResponseHandler)
  343. {
  344. TCHAR szQuery[HM_MAX_PATH];
  345. LPTSTR pszClass;
  346. LPTSTR pszGUID;
  347. LPTSTR pszEnd;
  348. HRESULT hRes;
  349. BOOL bCapable;
  350. DWORD dwErr = 0;
  351. if((pResponseHandler == NULL) || (wcslen(Query) > HM_MAX_PATH-1))
  352. {
  353. return WBEM_E_INVALID_PARAMETER;
  354. }
  355. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync BLOCK - g_hConfigLock BLOCK WAIT", 4);
  356. dwErr = WaitForSingleObject(g_hConfigLock, HM_ASYNC_TIMEOUT);
  357. if(dwErr != WAIT_OBJECT_0)
  358. {
  359. if(dwErr = WAIT_TIMEOUT)
  360. {
  361. TRACE_MUTEX(L"TIMEOUT MUTEX");
  362. return WBEM_S_TIMEDOUT;
  363. }
  364. else
  365. {
  366. TRACE_MUTEX(L"WaitForSingleObject on Mutex failed");
  367. return WBEM_E_FAILED;
  368. }
  369. }
  370. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync BLOCK - g_hConfigLock BLOCK GOT IT", 4);
  371. OutputDebugString(L"CBaseInstanceProvider::GetObjectAsync()\n");
  372. if (!g_pSystem)
  373. {
  374. ReleaseMutex(g_hConfigLock);
  375. return S_FALSE;
  376. }
  377. //
  378. // Going to look something like this ->
  379. // select * from MicrosoftHM_DataCollectorstatus where GUID="{X}"
  380. //
  381. wcsncpy(szQuery, Query, HM_MAX_PATH-1);
  382. szQuery[HM_MAX_PATH-1] = '\0';
  383. bCapable = FALSE;
  384. _wcsupr(szQuery);
  385. pszEnd = wcsstr(szQuery, L"FROM");
  386. if (pszEnd)
  387. {
  388. // Get the name of the Class we are being asked to supply instances of
  389. pszEnd += 4;
  390. while (*pszEnd==' ' || *pszEnd=='\t')
  391. {
  392. pszEnd++;
  393. }
  394. pszClass = pszEnd;
  395. while (*pszEnd!=' ' && *pszEnd!='\t' && *pszEnd!='\0' && *pszEnd!='=')
  396. {
  397. pszEnd++;
  398. }
  399. *pszEnd = '\0';
  400. pszEnd++;
  401. //
  402. // Make sure it is something we can handle
  403. //
  404. if (!wcsstr(pszEnd, L"AND") && !wcsstr(pszEnd, L"OR") && (wcsstr(pszEnd, L" GUID") || wcsstr(pszEnd, L"\tGUID")))
  405. {
  406. pszEnd = wcschr(pszEnd, '"');
  407. if (pszEnd)
  408. {
  409. pszEnd++;
  410. pszGUID = pszEnd;
  411. pszEnd = wcschr(pszEnd, '"');
  412. if (pszEnd)
  413. {
  414. *pszEnd = '\0';
  415. bCapable = TRUE;
  416. }
  417. }
  418. }
  419. }
  420. else
  421. {
  422. pszClass = szQuery;
  423. }
  424. if (bCapable)
  425. {
  426. try
  427. {
  428. //
  429. // Now find out which instance type we need to return.
  430. //
  431. if (!wcscmp(pszClass+HM_PREFIX_LEN, L"SYSTEMSTATUS"))
  432. {
  433. hRes = g_pSystem->SendHMSystemStatusInstance(pResponseHandler, pszGUID);
  434. }
  435. else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"DATAGROUPSTATUS"))
  436. {
  437. hRes = g_pSystem->SendHMDataGroupStatusInstance(pResponseHandler, pszGUID);
  438. }
  439. else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"DATACOLLECTORSTATUS"))
  440. {
  441. hRes = g_pSystem->SendHMDataCollectorStatusInstance(pResponseHandler, pszGUID);
  442. }
  443. else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"DATACOLLECTORPERINSTANCESTATUS"))
  444. {
  445. hRes = g_pSystem->SendHMDataCollectorPerInstanceStatusInstance(pResponseHandler, pszGUID);
  446. }
  447. else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"DATACOLLECTORSTATISTICS"))
  448. {
  449. hRes = g_pSystem->SendHMDataCollectorStatisticsInstance(pResponseHandler, pszGUID);
  450. }
  451. else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"THRESHOLDSTATUS"))
  452. {
  453. hRes = g_pSystem->SendHMThresholdStatusInstance(pResponseHandler, pszGUID);
  454. }
  455. else if (!wcscmp(pszClass+HM_PREFIX_LEN, L"ACTIONSTATUS"))
  456. {
  457. hRes = g_pSystem->SendHMActionStatusInstance(pResponseHandler, pszGUID);
  458. }
  459. else
  460. {
  461. MY_ASSERT(FALSE);
  462. hRes = pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
  463. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  464. ReleaseMutex(g_hConfigLock);
  465. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  466. return WBEM_E_NOT_SUPPORTED;
  467. }
  468. }
  469. catch (...)
  470. {
  471. hRes = S_FALSE;
  472. MY_ASSERT(FALSE);
  473. }
  474. if (FAILED(hRes))
  475. {
  476. // MY_HRESASSERT(hRes);
  477. hRes = pResponseHandler->SetStatus(0L, WBEM_E_FAILED, NULL, NULL);
  478. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  479. ReleaseMutex(g_hConfigLock);
  480. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  481. return hRes;
  482. }
  483. // Now let caller know it's done.
  484. hRes = pResponseHandler->SetStatus(0L, WBEM_S_NO_ERROR, NULL, NULL);
  485. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  486. ReleaseMutex(g_hConfigLock);
  487. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  488. return WBEM_S_NO_ERROR;
  489. }
  490. else
  491. {
  492. // Now let caller know it's done.
  493. //XXX pResponseHandler->SetStatus(0L, WBEM_S_NO_ERROR, NULL, NULL);
  494. // To implement ExecQueryAsync, and have WMI handle query if the query is too
  495. // complicated. The proper way to handle it today is to call
  496. pResponseHandler->SetStatus(WBEM_STATUS_REQUIREMENTS, WBEM_REQUIREMENTS_START_POSTFILTER, 0, NULL);
  497. // And then proceed to enumerate all your instances.
  498. // NOTE!!! Don't need to release the Mutex because it is done inside the call.
  499. hRes = CBaseInstanceProvider::CreateInstanceEnumAsync(pszClass, lFlags, pCtx, pResponseHandler);
  500. // NOTE!!! Don't need to release the Mutex because it is done inside the call.
  501. // OR DO WE. Once for each Wait called.
  502. //XXX
  503. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  504. ReleaseMutex(g_hConfigLock);
  505. MY_OUTPUT(L"BLOCK - BLOCK CBaseInstanceProvider::GetObjectAsync g_hConfigLock BLOCK - RELEASED", 4);
  506. return hRes;
  507. }
  508. }