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.

374 lines
8.1 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. CALLRES.CPP
  5. Abstract:
  6. Call Result Class
  7. History:
  8. --*/
  9. #include "precomp.h"
  10. #include "wbemcore.h"
  11. #pragma warning(disable:4355)
  12. CCallResult::CCallResult(IWbemClassObject* pResObj, HRESULT hres,
  13. IWbemClassObject* pErrorObj)
  14. : m_lRef(1), m_pResObj(pResObj), m_hres(hres), m_pErrorObj(pErrorObj),
  15. m_pResNamespace(NULL), m_strResult(NULL), m_ppResObjDest(NULL),
  16. m_bReady(TRUE), m_XSink(this)
  17. {
  18. m_hReady = CreateEvent(NULL, TRUE, TRUE, NULL);
  19. if (NULL == m_hReady) throw CX_MemoryException();
  20. if(pResObj)
  21. pResObj->AddRef();
  22. if(pErrorObj)
  23. pErrorObj->AddRef();
  24. gClientCounter.AddClientPtr(&m_Entry);
  25. }
  26. CCallResult::CCallResult(IWbemClassObject** ppResObjDest)
  27. : m_lRef(1), m_pResObj(NULL), m_hres(WBEM_E_CRITICAL_ERROR),
  28. m_pErrorObj(NULL), m_pResNamespace(NULL), m_strResult(NULL),
  29. m_ppResObjDest(ppResObjDest), m_bReady(FALSE), m_XSink(this)
  30. {
  31. m_hReady = CreateEvent(NULL, TRUE, FALSE, NULL);
  32. if (NULL == m_hReady) throw CX_MemoryException();
  33. gClientCounter.AddClientPtr(&m_Entry);
  34. }
  35. CCallResult::~CCallResult()
  36. {
  37. if(m_pResObj)
  38. m_pResObj->Release();
  39. if(m_pErrorObj)
  40. m_pErrorObj->Release();
  41. if(m_pResNamespace)
  42. m_pResNamespace->Release();
  43. SysFreeString(m_strResult);
  44. CloseHandle(m_hReady);
  45. gClientCounter.RemoveClientPtr(&m_Entry);
  46. }
  47. HRESULT CCallResult::SetStatus(HRESULT hres, BSTR strParam,
  48. IWbemClassObject* pErrorObj)
  49. {
  50. CInCritSec ics(&m_cs);
  51. // Check that SetStatus has not been called yet
  52. // ============================================
  53. if(m_bReady)
  54. {
  55. return WBEM_E_UNEXPECTED;
  56. }
  57. // Store data
  58. // ==========
  59. m_hres = hres;
  60. m_strResult = SysAllocString(strParam);
  61. m_pErrorObj = pErrorObj;
  62. if(pErrorObj)
  63. pErrorObj->AddRef();
  64. // Signal both events --- we are ready for everything
  65. // ==================================================
  66. m_bReady = TRUE;
  67. SetEvent(m_hReady);
  68. return WBEM_S_NO_ERROR;
  69. }
  70. HRESULT CCallResult::SetResultObject(IWbemClassObject* pResObj)
  71. {
  72. CInCritSec ics(&m_cs);
  73. // Check that neither SetStatus nor Indicate has been called yet
  74. // =============================================================
  75. if(m_bReady)
  76. {
  77. return WBEM_E_UNEXPECTED;
  78. }
  79. // Store data
  80. // ==========
  81. m_pResObj = pResObj;
  82. if(pResObj)
  83. pResObj->AddRef();
  84. if(m_ppResObjDest)
  85. {
  86. *m_ppResObjDest = pResObj;
  87. if(pResObj)
  88. pResObj->AddRef();
  89. }
  90. return WBEM_S_NO_ERROR;
  91. }
  92. void CCallResult::SetResultString(LPWSTR wszRes)
  93. {
  94. SysFreeString(m_strResult);
  95. m_strResult = SysAllocString(wszRes);
  96. }
  97. void CCallResult::SetResultServices(IWbemServices* pRes)
  98. {
  99. if(m_pResNamespace)
  100. m_pResNamespace->Release();
  101. m_pResNamespace = pRes;
  102. if(pRes)
  103. pRes->AddRef();
  104. }
  105. void CCallResult::SetErrorInfo()
  106. {
  107. if(m_pErrorObj)
  108. {
  109. IErrorInfo* pInfo = NULL;
  110. m_pErrorObj->QueryInterface(IID_IErrorInfo, (void**)&pInfo);
  111. ::SetErrorInfo(0, pInfo);
  112. pInfo->Release();
  113. }
  114. }
  115. STDMETHODIMP CCallResult::QueryInterface(REFIID riid, void** ppv)
  116. {
  117. if (NULL == ppv) return E_POINTER;
  118. if(riid == IID_IUnknown || riid == IID_IWbemCallResult)
  119. {
  120. AddRef();
  121. *ppv = (void*)this;
  122. return S_OK;
  123. }
  124. else
  125. {
  126. *ppv = NULL;
  127. return E_NOINTERFACE;
  128. }
  129. }
  130. STDMETHODIMP CCallResult::GetResultObject(long lTimeout,
  131. IWbemClassObject** ppObj)
  132. {
  133. // SEC:REVIEWED 2002-03-22 : Needs EH in case <ppObj> is invalid
  134. if(!m_Security.AccessCheck())
  135. return WBEM_E_ACCESS_DENIED;
  136. *ppObj = NULL;
  137. if(lTimeout < 0 && lTimeout != -1)
  138. return WBEM_E_INVALID_PARAMETER;
  139. DWORD dwRes = CCoreQueue::QueueWaitForSingleObject(m_hReady, lTimeout);
  140. if(dwRes == WAIT_TIMEOUT)
  141. return WBEM_S_TIMEDOUT;
  142. if(dwRes == WAIT_FAILED)
  143. return WBEM_E_FAILED;
  144. // Event is signaled --- expect object
  145. // ===================================
  146. if(m_pResObj)
  147. {
  148. *ppObj = m_pResObj;
  149. m_pResObj->AddRef();
  150. return WBEM_S_NO_ERROR;
  151. }
  152. else
  153. {
  154. *ppObj = NULL;
  155. if(FAILED(m_hres))
  156. SetErrorInfo();
  157. return m_hres;
  158. }
  159. }
  160. STDMETHODIMP CCallResult::GetResultString(long lTimeout, BSTR* pstr)
  161. {
  162. // SEC:REVIEWED 2002-03-22 : Needs EH in case <pstr> is invalid
  163. if(!m_Security.AccessCheck())
  164. return WBEM_E_ACCESS_DENIED;
  165. *pstr = NULL;
  166. if(lTimeout < 0 && lTimeout != -1)
  167. return WBEM_E_INVALID_PARAMETER;
  168. DWORD dwRes = CCoreQueue::QueueWaitForSingleObject(m_hReady, lTimeout);
  169. if(dwRes == WAIT_TIMEOUT)
  170. return WBEM_S_TIMEDOUT;
  171. if(dwRes == WAIT_FAILED)
  172. return WBEM_E_FAILED;
  173. // Event is signaled --- expect string
  174. // ===================================
  175. if(m_strResult)
  176. {
  177. *pstr = SysAllocString(m_strResult);
  178. return WBEM_S_NO_ERROR;
  179. }
  180. else
  181. {
  182. *pstr = NULL;
  183. if(SUCCEEDED(m_hres))
  184. return WBEM_E_INVALID_OPERATION;
  185. else
  186. {
  187. SetErrorInfo();
  188. return m_hres;
  189. }
  190. }
  191. }
  192. STDMETHODIMP CCallResult::GetCallStatus(long lTimeout, long* plStatus)
  193. {
  194. // SEC:REVIEWED 2002-03-22 : Needs EH in case <plStatus> is invalid
  195. if(!m_Security.AccessCheck())
  196. return WBEM_E_ACCESS_DENIED;
  197. //*plStatus = WBEM_E_CRITICAL_ERROR;
  198. if(lTimeout < 0 && lTimeout != -1)
  199. return WBEM_E_INVALID_PARAMETER;
  200. DWORD dwRes = CCoreQueue::QueueWaitForSingleObject(m_hReady, lTimeout);
  201. if(dwRes == WAIT_TIMEOUT)
  202. return WBEM_S_TIMEDOUT;
  203. if(dwRes == WAIT_FAILED)
  204. return WBEM_E_FAILED;
  205. // Event is signaled --- expect status
  206. // ===================================
  207. try
  208. {
  209. *plStatus = m_hres;
  210. }
  211. catch (...)
  212. {
  213. ExceptionCounter c;
  214. return WBEM_E_INVALID_PARAMETER;
  215. }
  216. if(FAILED(m_hres))
  217. {
  218. SetErrorInfo();
  219. }
  220. return WBEM_S_NO_ERROR;
  221. }
  222. STDMETHODIMP CCallResult::GetResultServices(long lTimeout,
  223. IWbemServices** ppServices)
  224. {
  225. // SEC:REVIEWED 2002-03-22 : Needs EH in case <ppServices> is not valid
  226. if(!m_Security.AccessCheck())
  227. return WBEM_E_ACCESS_DENIED;
  228. *ppServices = NULL;
  229. if(lTimeout < 0 && lTimeout != -1)
  230. return WBEM_E_INVALID_PARAMETER;
  231. DWORD dwRes = CCoreQueue::QueueWaitForSingleObject(m_hReady, lTimeout);
  232. if(dwRes == WAIT_TIMEOUT)
  233. return WBEM_S_TIMEDOUT;
  234. if(dwRes == WAIT_FAILED)
  235. return WBEM_E_FAILED;
  236. if(m_pResNamespace)
  237. {
  238. *ppServices = m_pResNamespace;
  239. m_pResNamespace->AddRef();
  240. return WBEM_S_NO_ERROR;
  241. }
  242. else
  243. {
  244. *ppServices = NULL;
  245. if(SUCCEEDED(m_hres))
  246. return WBEM_E_INVALID_OPERATION;
  247. else
  248. {
  249. SetErrorInfo();
  250. return m_hres;
  251. }
  252. }
  253. }
  254. STDMETHODIMP CCallResult::GetResult(
  255. long lTimeout,
  256. long lFlags,
  257. /* [in] */ REFIID riid,
  258. /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvResult
  259. )
  260. {
  261. return WBEM_E_NOT_SUPPORTED;
  262. }
  263. STDMETHODIMP CCallResult::CResultSink::
  264. Indicate(long lNumObjects, IWbemClassObject** aObjects)
  265. {
  266. if(lNumObjects > 1)
  267. {
  268. return WBEM_E_UNEXPECTED;
  269. }
  270. if(lNumObjects == 0)
  271. {
  272. return WBEM_S_NO_ERROR;
  273. }
  274. return m_pOwner->SetResultObject(aObjects[0]);
  275. }
  276. STDMETHODIMP CCallResult::CResultSink::
  277. SetStatus(long lFlags, HRESULT hres, BSTR strParam, IWbemClassObject* pErrorObj)
  278. {
  279. if(lFlags != 0)
  280. {
  281. return WBEM_S_NO_ERROR;
  282. }
  283. return m_pOwner->SetStatus(hres, strParam, pErrorObj);
  284. }