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.

361 lines
7.8 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. //
  5. // ERROR.CPP
  6. //
  7. // alanbos 28-Jun-98 Created.
  8. //
  9. // Defines the WBEM error cache implementation
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #define NULLBSTR(x) \
  14. SysFreeString (x);\
  15. x = NULL;
  16. #define FREECOAUTH(x) \
  17. if (x)\
  18. {\
  19. WbemFreeAuthIdentity (x);\
  20. x = NULL;\
  21. }
  22. //***************************************************************************
  23. //
  24. // CWbemErrorCache::CWbemErrorCache
  25. //
  26. // DESCRIPTION:
  27. //
  28. // Constructor
  29. //
  30. //***************************************************************************
  31. CWbemErrorCache::CWbemErrorCache ()
  32. {
  33. InitializeCriticalSection (&m_cs);
  34. headPtr = NULL;
  35. }
  36. //***************************************************************************
  37. //
  38. // CWbemErrorCache::~CWbemErrorCache
  39. //
  40. // DESCRIPTION:
  41. //
  42. // Destructor
  43. //
  44. //***************************************************************************
  45. CWbemErrorCache::~CWbemErrorCache ()
  46. {
  47. EnterCriticalSection (&m_cs);
  48. ThreadError *pPtr = headPtr;
  49. while (pPtr)
  50. {
  51. if (pPtr->pErrorObject)
  52. {
  53. pPtr->pErrorObject->Release ();
  54. pPtr->pErrorObject = NULL;
  55. }
  56. if (pPtr->pService)
  57. {
  58. pPtr->pService->Release ();
  59. pPtr->pService = NULL;
  60. }
  61. NULLBSTR (pPtr->strNamespacePath);
  62. NULLBSTR (pPtr->strAuthority);
  63. NULLBSTR (pPtr->strPrincipal);
  64. FREECOAUTH (pPtr->pCoAuthIdentity)
  65. ThreadError *pTmp = pPtr;
  66. pPtr = pPtr->pNext;
  67. delete pTmp;
  68. }
  69. headPtr = NULL;
  70. LeaveCriticalSection (&m_cs);
  71. DeleteCriticalSection (&m_cs);
  72. }
  73. //***************************************************************************
  74. //
  75. // CWbemErrorCache::GetAndResetCurrentThreadError
  76. //
  77. // DESCRIPTION:
  78. //
  79. // Extract the WBEM error object (if any) from the current thread. This
  80. // is a once-only operation as the entry for that thread is cleared by this
  81. // read.
  82. //
  83. //***************************************************************************
  84. CSWbemObject *CWbemErrorCache::GetAndResetCurrentThreadError ()
  85. {
  86. CSWbemObject *pObject = NULL;
  87. DWORD threadId = GetCurrentThreadId ();
  88. EnterCriticalSection (&m_cs);
  89. ThreadError *pPtr = headPtr;
  90. while (pPtr)
  91. {
  92. if (threadId == pPtr->dwThreadId)
  93. {
  94. if (pPtr->pErrorObject)
  95. {
  96. CSWbemServices *pService = NULL;
  97. // Try and create a services object
  98. if (pPtr->pService)
  99. {
  100. pService = new CSWbemServices (pPtr->pService, pPtr->strNamespacePath,
  101. pPtr->pCoAuthIdentity, pPtr->strPrincipal,
  102. pPtr->strAuthority);
  103. if (pService)
  104. pService->AddRef ();
  105. }
  106. if (pPtr->pService)
  107. {
  108. pPtr->pService->Release ();
  109. pPtr->pService = NULL;
  110. }
  111. NULLBSTR (pPtr->strNamespacePath);
  112. NULLBSTR (pPtr->strAuthority);
  113. NULLBSTR (pPtr->strPrincipal);
  114. FREECOAUTH (pPtr->pCoAuthIdentity)
  115. pObject = new CSWbemObject (pService, pPtr->pErrorObject, NULL, true);
  116. pPtr->pErrorObject->Release ();
  117. pPtr->pErrorObject = NULL;
  118. if (pService)
  119. pService->Release ();
  120. // Unhook and delete the ThreadError
  121. if (pPtr == headPtr)
  122. headPtr = pPtr->pNext;
  123. if (pPtr->pNext)
  124. pPtr->pNext->pPrev = pPtr->pPrev;
  125. if (pPtr->pPrev)
  126. pPtr->pPrev->pNext = pPtr->pNext;
  127. delete pPtr;
  128. }
  129. break;
  130. }
  131. pPtr = pPtr->pNext;
  132. }
  133. LeaveCriticalSection (&m_cs);
  134. return pObject;
  135. }
  136. //***************************************************************************
  137. //
  138. // CWbemErrorCache::SetCurrentThreadError
  139. //
  140. // DESCRIPTION:
  141. //
  142. // Set the WBEM error object (if any) for the current thread.
  143. //
  144. //***************************************************************************
  145. void CWbemErrorCache::SetCurrentThreadError (CSWbemServices *pService)
  146. {
  147. IErrorInfo * pInfo = NULL;
  148. if(SUCCEEDED(GetErrorInfo(0, &pInfo)) && pInfo)
  149. {
  150. // Is this a WBEM Error Object?
  151. IWbemClassObject * pObj = NULL;
  152. if(SUCCEEDED(pInfo->QueryInterface(IID_IWbemClassObject, (void **)&pObj)) && pObj)
  153. {
  154. DWORD threadId = GetCurrentThreadId ();
  155. EnterCriticalSection (&m_cs);
  156. ThreadError *pPtr = headPtr;
  157. // Find the current entry (if any)
  158. while (pPtr)
  159. {
  160. if (threadId == pPtr->dwThreadId)
  161. break;
  162. pPtr = pPtr->pNext;
  163. }
  164. // Have a new error object - chain it into the list
  165. if (!pPtr)
  166. {
  167. // No entry for this thread - create one at the head
  168. ThreadError *pTmp = headPtr;
  169. headPtr = new ThreadError;
  170. if (headPtr)
  171. {
  172. headPtr->pPrev = NULL;
  173. headPtr->pNext = pTmp;
  174. if (pTmp)
  175. pTmp->pPrev = headPtr;
  176. headPtr->dwThreadId = threadId;
  177. headPtr->pErrorObject = pObj;
  178. headPtr->pService = NULL;
  179. headPtr->strAuthority = NULL;
  180. headPtr->strPrincipal = NULL;
  181. headPtr->pCoAuthIdentity = NULL;
  182. headPtr->strNamespacePath = NULL;
  183. if (pService)
  184. {
  185. headPtr->pService = pService->GetIWbemServices ();
  186. CSWbemSecurity *pSecurity = pService->GetSecurityInfo ();
  187. if (pSecurity)
  188. {
  189. headPtr->strAuthority = SysAllocString (pSecurity->GetAuthority ());
  190. headPtr->strPrincipal = SysAllocString (pSecurity->GetPrincipal ());
  191. headPtr->pCoAuthIdentity = pSecurity->GetCoAuthIdentity ();
  192. pSecurity->Release ();
  193. }
  194. headPtr->strNamespacePath = SysAllocString(pService->GetPath ());
  195. }
  196. }
  197. }
  198. else
  199. {
  200. // pPtr addresses the current entry for the thread
  201. /***************************************************
  202. * We should not actually do this any more as we
  203. * remove the entry both when it is read and at the
  204. * start of the API call. So at this point there should
  205. * not be any entries left for this thread
  206. ****************************************************/
  207. if (pPtr->pErrorObject)
  208. pPtr->pErrorObject->Release ();
  209. pPtr->pErrorObject = pObj;
  210. if (pPtr->pService)
  211. {
  212. pPtr->pService->Release ();
  213. pPtr->pService = NULL;
  214. }
  215. NULLBSTR (pPtr->strNamespacePath);
  216. NULLBSTR (pPtr->strAuthority);
  217. NULLBSTR (pPtr->strPrincipal);
  218. FREECOAUTH (pPtr->pCoAuthIdentity)
  219. if (pService)
  220. {
  221. pPtr->pService = pService->GetIWbemServices ();
  222. CSWbemSecurity *pSecurity = pService->GetSecurityInfo ();
  223. if (pSecurity)
  224. {
  225. pPtr->strAuthority = SysAllocString (pSecurity->GetAuthority ());
  226. pPtr->strPrincipal = SysAllocString (pSecurity->GetPrincipal ());
  227. pPtr->pCoAuthIdentity = pSecurity->GetCoAuthIdentity ();
  228. pSecurity->Release ();
  229. }
  230. pPtr->strNamespacePath = SysAllocString(pService->GetPath ());
  231. }
  232. }
  233. LeaveCriticalSection (&m_cs);
  234. }
  235. pInfo->Release (); // To balance the GetErrorInfo call
  236. }
  237. }
  238. //***************************************************************************
  239. //
  240. // CWbemErrorCache::ResetCurrentThreadError
  241. //
  242. // DESCRIPTION:
  243. //
  244. // If there is an entry for the current thread then remove it
  245. //
  246. //***************************************************************************
  247. void CWbemErrorCache::ResetCurrentThreadError ()
  248. {
  249. DWORD threadId = GetCurrentThreadId ();
  250. EnterCriticalSection (&m_cs);
  251. ThreadError *pPtr = headPtr;
  252. // Find the current entry (if any)
  253. while (pPtr)
  254. {
  255. if (threadId == pPtr->dwThreadId)
  256. break;
  257. pPtr = pPtr->pNext;
  258. }
  259. if (pPtr)
  260. {
  261. // pPtr addresses the current entry for the thread
  262. if (pPtr->pErrorObject)
  263. {
  264. pPtr->pErrorObject->Release ();
  265. pPtr->pErrorObject = NULL;
  266. }
  267. if (pPtr->pService)
  268. {
  269. pPtr->pService->Release ();
  270. pPtr->pService = NULL;
  271. }
  272. NULLBSTR (pPtr->strNamespacePath);
  273. NULLBSTR (pPtr->strAuthority);
  274. NULLBSTR (pPtr->strPrincipal);
  275. FREECOAUTH (pPtr->pCoAuthIdentity)
  276. // Unhook and delete the ErrorInfo
  277. if (pPtr == headPtr)
  278. headPtr = pPtr->pNext;
  279. if (pPtr->pNext)
  280. pPtr->pNext->pPrev = pPtr->pPrev;
  281. if (pPtr->pPrev)
  282. pPtr->pPrev->pNext = pPtr->pNext;
  283. delete pPtr;
  284. }
  285. LeaveCriticalSection (&m_cs);
  286. }