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.

448 lines
9.4 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. CorrectedEngine.cpp
  5. Abstract:
  6. This module encapsulates the routines that are needed only for
  7. corrected error retrieval.
  8. Author:
  9. Abdullah Ustuner (AUstuner) 28-August-2002
  10. --*/
  11. #include "mca.h"
  12. extern IWbemServices *gPIWbemServices;
  13. extern IWbemLocator *gPIWbemLocator;
  14. //
  15. // Event which signals the corrected error retrieval.
  16. //
  17. HANDLE gErrorProcessedEvent;
  18. //
  19. // TimeOut period in minutes for corrected error retrieval.
  20. //
  21. INT gTimeOut;
  22. BOOL
  23. MCACreateProcessedEvent(
  24. VOID
  25. )
  26. /*++
  27. Routine Description:
  28. This function creates the "processed event", which is used to keep track of
  29. whether a corrected error record has been retrieved from WMI or not. When a
  30. corrected error is retrieved from WMI then, this event is signaled which
  31. causes the application to finish.
  32. Arguments:
  33. none
  34. Return Value:
  35. TRUE - Successful.
  36. FALSE - Unsuccessful.
  37. --*/
  38. {
  39. //
  40. // Create the processsed event.
  41. //
  42. gErrorProcessedEvent = CreateEvent(NULL,
  43. TRUE,
  44. FALSE,
  45. L"ErrorProcessedEvent"
  46. );
  47. return (gErrorProcessedEvent != NULL);
  48. }
  49. VOID
  50. MCAErrorReceived(
  51. IN IWbemClassObject *ErrorObject
  52. )
  53. /*++
  54. Routine Description:
  55. This function is called by an instance of the MCAObjectSink class when a corrected
  56. error is retrieved from WMI. The error record data is extracted from the object and
  57. the contents of this record is displayed on the screen.
  58. Arguments:
  59. ErrorObject - Error object retrieved from WMI.
  60. Return Value:
  61. none
  62. --*/
  63. {
  64. PUCHAR pErrorRecordBuffer = NULL;
  65. //
  66. // Extract the actual MCA error record from the retrieved object.
  67. //
  68. if (!MCAExtractErrorRecord(ErrorObject, &pErrorRecordBuffer)) {
  69. wprintf(L"ERROR: Failed to get corrected error record data!\n");
  70. goto CleanUp;
  71. }
  72. //
  73. // Display the corrected error record on the screen.
  74. //
  75. MCAPrintErrorRecord(pErrorRecordBuffer);
  76. CleanUp:
  77. if (pErrorRecordBuffer) {
  78. free(pErrorRecordBuffer);
  79. }
  80. }
  81. BOOL
  82. MCAGetCorrectedError(
  83. VOID
  84. )
  85. /*++
  86. Routine Description:
  87. This function registers to WMI for corrected error notification and waits until
  88. TimeOut limit is reached or an error is retrieved. If an error is successfully
  89. retrieved then, the contents of the error record are displayed on the screen.
  90. Arguments:
  91. none
  92. Return Value:
  93. TRUE - Successful.
  94. FALSE - Unsuccessful.
  95. --*/
  96. {
  97. BOOL isSuccess = TRUE;
  98. HRESULT hResult = WBEM_S_NO_ERROR;
  99. DWORD returnValue = 0;
  100. //
  101. // Create the Sink instances, which will be responsible for handling
  102. // the event callbacks from WMI.
  103. //
  104. MCAObjectSink *pCMCSink = new MCAObjectSink();
  105. MCAObjectSink *pCPESink = new MCAObjectSink();
  106. //
  107. // Check if instance creation was successful.
  108. //
  109. if (pCMCSink == NULL || pCPESink == NULL) {
  110. isSuccess = FALSE;
  111. wprintf(L"ERROR: Memory allocation failed for object sinks!");
  112. goto CleanUp;
  113. }
  114. //
  115. // Complete the required initialization tasks.
  116. //
  117. if (!MCAInitialize()) {
  118. isSuccess = FALSE;
  119. wprintf(L"ERROR: Initialization failed!\n");
  120. goto CleanUp;
  121. }
  122. //
  123. // Create processed event, which will be used to signal event retrieval from WMI.
  124. //
  125. if(!MCACreateProcessedEvent()){
  126. isSuccess = FALSE;
  127. wprintf(L"ERROR: Processed event creation failed!\n");
  128. goto CleanUp;
  129. }
  130. //
  131. // Register to WMI for CMC event notification.
  132. //
  133. if (!MCARegisterCMCConsumer(pCMCSink)) {
  134. isSuccess = FALSE;
  135. goto CleanUp;
  136. }
  137. //
  138. // Register to WMI for CPE event notification.
  139. //
  140. if (!MCARegisterCPEConsumer(pCPESink)) {
  141. isSuccess = FALSE;
  142. goto CleanUp;
  143. }
  144. wprintf(L"INFO: Waiting for notification from WMI...\n");
  145. //
  146. // Wait for error retrieval until TimeOut limit is reached.
  147. //
  148. returnValue = WaitForSingleObjectEx(gErrorProcessedEvent,
  149. gTimeOut*60*1000,
  150. FALSE
  151. );
  152. if (returnValue == WAIT_TIMEOUT) {
  153. wprintf(L"INFO: No error notification is received during the timeout period.\n");
  154. }
  155. CleanUp:
  156. if (gPIWbemServices) {
  157. //
  158. // Cancel any currently pending asynchronous call based on the MCAObjectSink pointers.
  159. //
  160. hResult = gPIWbemServices->CancelAsyncCall(pCMCSink);
  161. if (hResult != WBEM_S_NO_ERROR){
  162. wprintf(L"IWbemServices::CancelAsyncCall failed on CMCSink: %d\n", hResult);
  163. }
  164. hResult = gPIWbemServices->CancelAsyncCall(pCPESink);
  165. if(hResult != WBEM_S_NO_ERROR){
  166. wprintf(L"IWbemServices::CancelAsyncCall failed on CPESink: %d\n", hResult);
  167. }
  168. gPIWbemServices->Release();
  169. }
  170. //
  171. // Release the sink object associated with CMC notification.
  172. //
  173. if (pCMCSink != NULL) {
  174. pCMCSink->Release();
  175. }
  176. //
  177. // Release the sink object associated with CPE notification.
  178. //
  179. if (pCPESink != NULL) {
  180. pCPESink->Release();
  181. }
  182. if (gPIWbemLocator) {
  183. gPIWbemLocator->Release();
  184. }
  185. return isSuccess;
  186. }
  187. BOOL
  188. MCARegisterCMCConsumer(
  189. MCAObjectSink *pCMCSink
  190. )
  191. /*++
  192. Routine Description:
  193. This function registers the provided object sink as a temporary consumer
  194. to WMI for CMC event notification.
  195. Arguments:
  196. pCMCSink - Object sink that will be registered to WMI for CMC error notification.
  197. Return Value:
  198. TRUE - Successful.
  199. FALSE - Unsuccessful.
  200. --*/
  201. {
  202. HRESULT hResult = 0;
  203. BOOL isSuccess = TRUE;
  204. LPWSTR pQueryLanguage = L"WQL";
  205. LPWSTR pQueryStatement = L"select * from MSMCAInfo_RawCMCEvent";
  206. BSTR bQueryLanguage = SysAllocString(pQueryLanguage);
  207. BSTR bQueryStatement = SysAllocString(pQueryStatement);
  208. if (bQueryLanguage == NULL || bQueryStatement == NULL) {
  209. isSuccess = FALSE;
  210. wprintf(L"ERROR: Memory allocation for string failed!\n");
  211. goto CleanUp;
  212. }
  213. //
  214. // Register the object sink as a temporary consumer to WMI for CMC error notification.
  215. //
  216. hResult = gPIWbemServices->ExecNotificationQueryAsync(bQueryLanguage,
  217. bQueryStatement,
  218. WBEM_FLAG_SEND_STATUS,
  219. NULL,
  220. pCMCSink
  221. );
  222. if (FAILED(hResult)) {
  223. isSuccess = FALSE;
  224. wprintf(L"ERROR: Temporary consumer registration for CMC failed!\n");
  225. wprintf(L"Result: 0x%x\n", hResult);
  226. goto CleanUp;
  227. }
  228. wprintf(L"INFO: Registered for CMC error notification successfully.\n");
  229. CleanUp:
  230. if (bQueryLanguage != NULL) {
  231. SysFreeString(bQueryLanguage);
  232. }
  233. if (bQueryStatement != NULL) {
  234. SysFreeString(bQueryStatement);
  235. }
  236. return isSuccess;
  237. }
  238. BOOL
  239. MCARegisterCPEConsumer(
  240. MCAObjectSink *pCPESink
  241. )
  242. /*++
  243. Routine Description:
  244. This function registers the provided object sink as a temporary consumer
  245. to WMI for CPE event notification.
  246. Arguments:
  247. pCPESink - Object sink that will be registered to WMI for CPE error notification.
  248. Return Value:
  249. TRUE - Successful.
  250. FALSE - Unsuccessful.
  251. --*/
  252. {
  253. HRESULT hResult = 0;
  254. BOOL isSuccess = TRUE;
  255. LPWSTR pQueryLanguage = L"WQL";
  256. LPWSTR pQueryStatement = L"select * from MSMCAInfo_RawCorrectedPlatformEvent";
  257. BSTR bQueryLanguage = SysAllocString(pQueryLanguage);
  258. BSTR bQueryStatement = SysAllocString(pQueryStatement);
  259. if (bQueryLanguage == NULL || bQueryStatement == NULL) {
  260. isSuccess = FALSE;
  261. wprintf(L"ERROR: Memory allocation for string failed!\n");
  262. goto CleanUp;
  263. }
  264. //
  265. // Register the object sink as a temporary consumer to WMI for CPE error notification.
  266. //
  267. hResult = gPIWbemServices->ExecNotificationQueryAsync(bQueryLanguage,
  268. bQueryStatement,
  269. WBEM_FLAG_SEND_STATUS,
  270. NULL,
  271. pCPESink
  272. );
  273. if (FAILED(hResult)) {
  274. isSuccess = FALSE;
  275. wprintf(L"ERROR: Temporary consumer registration for CPE failed!\n");
  276. wprintf(L"ERROR: Result: 0x%x\n", hResult);
  277. goto CleanUp;
  278. }
  279. wprintf(L"INFO: Registered for CPE error notification successfully.\n");
  280. CleanUp:
  281. if (bQueryLanguage != NULL) {
  282. SysFreeString(bQueryLanguage);
  283. }
  284. if (bQueryStatement != NULL) {
  285. SysFreeString(bQueryStatement);
  286. }
  287. return isSuccess;
  288. }