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.

811 lines
25 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. Common.cpp
  5. Abstract:
  6. This module encapsulates the common routines that are used
  7. during both fatal and corrected error retrieval.
  8. Author:
  9. Abdullah Ustuner (AUstuner) 26-August-2002
  10. --*/
  11. #include "mca.h"
  12. IWbemServices *gPIWbemServices = NULL;
  13. IWbemLocator *gPIWbemLocator = NULL;
  14. BOOL
  15. MCAExtractErrorRecord(
  16. IN IWbemClassObject *PObject,
  17. OUT PUCHAR *PRecordBuffer
  18. )
  19. /*++
  20. Routine Description:
  21. This function retrieves embedded objects from the error record
  22. (obtained from WMI) that contain both the record data and other
  23. information about the record (such as length). The data is saved
  24. into the output buffer provided.
  25. Arguments:
  26. PObject - Event object retrieved from WMI.
  27. PRecordBuffer - Pointer to a buffer to save the MCA error record.
  28. Return Value:
  29. TRUE - Successful.
  30. FALSE - Unsuccessful.
  31. --*/
  32. {
  33. IWbemClassObject *pRecordsObject = NULL;
  34. VARIANT recordsPropertyVariant;
  35. VARIANT countPropertyVariant;
  36. VARIANT recordLengthVariant;
  37. VARIANT recordDataVariant;
  38. HRESULT hResult = WBEM_S_NO_ERROR;
  39. IUnknown *punk = NULL;
  40. LONG mcaRecordByte = 0, index = 0;
  41. UCHAR recordDataByte;
  42. BOOL isSuccess = TRUE;
  43. //
  44. // Retrieve the "Records" property value of the event object.
  45. //
  46. hResult = PObject->Get(L"Records",
  47. 0,
  48. &recordsPropertyVariant,
  49. NULL,
  50. NULL
  51. );
  52. if (FAILED(hResult)) {
  53. isSuccess = FALSE;
  54. wprintf(L"ERROR: \"Records\" property value couldn't be retrieved!\n");
  55. goto CleanUp;
  56. }
  57. //
  58. // Retrieve the "Count" property value of the event object.
  59. //
  60. hResult = PObject->Get(L"Count",
  61. 0,
  62. &countPropertyVariant,
  63. NULL,
  64. NULL
  65. );
  66. if (FAILED(hResult)) {
  67. isSuccess = FALSE;
  68. wprintf(L"ERROR: \"Count\" property value couldn't be retrieved!\n");
  69. goto CleanUp;
  70. }
  71. //
  72. // Check the "Count" property to ensure that it is not zero.
  73. //
  74. if (countPropertyVariant.lVal < 1) {
  75. isSuccess = FALSE;
  76. wprintf(L"ERROR: \"Count\" is less than 1!\n");
  77. goto CleanUp;
  78. }
  79. //
  80. // The Records Property Variant.parray should contain a
  81. // pointer to an array of pointers. However, MCA should only
  82. // place one pointer in this array. Use the Safearray APIs to
  83. // get that pointer.
  84. //
  85. hResult = SafeArrayGetElement(recordsPropertyVariant.parray,
  86. &index,
  87. &punk
  88. );
  89. if(FAILED(hResult)){
  90. isSuccess = FALSE;
  91. wprintf(L"ERROR: Couldn't retrieve array pointer!\n");
  92. goto CleanUp;
  93. }
  94. //
  95. // Punk should contain an object of type IWbemClassObject. This should
  96. // be the MCA record object that will contain "Length" and "Data" elements.
  97. //
  98. hResult = (punk->QueryInterface(IID_IWbemClassObject,
  99. (PVOID*)&pRecordsObject)
  100. );
  101. if (FAILED(hResult)) {
  102. isSuccess = FALSE;
  103. wprintf(L"ERROR: Interface pointer couldn't be retrieved!\n");
  104. goto CleanUp;
  105. }
  106. //
  107. // Obtain the length of the error record.
  108. //
  109. hResult = pRecordsObject->Get(L"Length",
  110. 0,
  111. &recordLengthVariant,
  112. NULL,
  113. NULL
  114. );
  115. if (FAILED(hResult)) {
  116. isSuccess = FALSE;
  117. wprintf(L"\"Length\" property value couldn't be retrieved!\n");
  118. goto CleanUp;
  119. }
  120. //
  121. // Obtain the actual data from the records object. This should contain a parray
  122. // that points to the actual MCA data we are looking for.
  123. //
  124. hResult = pRecordsObject->Get(L"Data",
  125. 0,
  126. &recordDataVariant,
  127. NULL,
  128. NULL
  129. );
  130. if (FAILED(hResult)) {
  131. isSuccess = FALSE;
  132. wprintf(L"\"Data\" property value couldn't be retrieved!\n");
  133. goto CleanUp;
  134. }
  135. //
  136. // Check if the "Data" field in the record contains any data.
  137. //
  138. if (recordDataVariant.parray == NULL) {
  139. isSuccess = FALSE;
  140. wprintf(L"ERROR: Error record contains to data!\n");
  141. goto CleanUp;
  142. }
  143. PUCHAR PTempBuffer = NULL;
  144. //
  145. // Allocate memory for the error record buffer. The size of the memory should be
  146. // equal to the size of the MCA error record data field.
  147. //
  148. if ((*PRecordBuffer) == NULL) {
  149. *PRecordBuffer = (PUCHAR)(calloc(recordLengthVariant.lVal, sizeof(UINT8)));
  150. if((*PRecordBuffer) == NULL) {
  151. isSuccess = FALSE;
  152. wprintf(L"ERROR: Memory allocation for record buffer failed!\n");
  153. goto CleanUp;
  154. }
  155. } else{
  156. PTempBuffer = (PUCHAR)(realloc(*PRecordBuffer, (recordLengthVariant.lVal * sizeof(UINT8))));
  157. //
  158. // If reallocation of memory for the buffer failed, then display error message and return.
  159. //
  160. if (PTempBuffer == NULL) {
  161. isSuccess = FALSE;
  162. wprintf(L"ERROR: Memory reallocation for record buffer failed!\n");
  163. goto CleanUp;
  164. } else {
  165. *PRecordBuffer = PTempBuffer;
  166. ZeroMemory(*PRecordBuffer, recordLengthVariant.lVal * sizeof(**PRecordBuffer));
  167. }
  168. }
  169. //
  170. // Get the MCA error record data byte by byte and save it into the allocated buffer.
  171. //
  172. for (mcaRecordByte = 0; mcaRecordByte < recordLengthVariant.lVal; mcaRecordByte++){
  173. recordDataByte = 0;
  174. hResult = SafeArrayGetElement(recordDataVariant.parray,
  175. &mcaRecordByte,
  176. &recordDataByte
  177. );
  178. if (FAILED(hResult)) {
  179. isSuccess = FALSE;
  180. wprintf(L"ERROR: Error record data couldn't be read!\n");
  181. goto CleanUp;
  182. }
  183. // Copy error record data byte into buffer.
  184. *((*PRecordBuffer) + (mcaRecordByte * sizeof(UINT8))) = recordDataByte;
  185. }
  186. CleanUp:
  187. VariantClear(&recordDataVariant);
  188. VariantClear(&recordLengthVariant);
  189. VariantClear(&recordsPropertyVariant);
  190. VariantClear(&countPropertyVariant);
  191. return isSuccess;
  192. }
  193. BOOL
  194. MCAInitialize(
  195. VOID
  196. )
  197. /*++
  198. Routine Description:
  199. This function accomplishes the required initialization tasks required by
  200. both fatal and corrected error retrieval.
  201. Arguments:
  202. none
  203. Return Value:
  204. TRUE - Successful.
  205. FALSE - Unsuccessful.
  206. --*/
  207. {
  208. BOOL isSuccess = TRUE;
  209. //
  210. // Initialize COM Library
  211. //
  212. if (!MCAInitializeCOMLibrary()) {
  213. return FALSE;
  214. }
  215. //
  216. // Set Security
  217. //
  218. if(!MCAInitializeWMISecurity()){
  219. return FALSE;
  220. }
  221. return isSuccess;
  222. }
  223. BOOL
  224. MCAInitializeCOMLibrary(
  225. VOID
  226. )
  227. /*++
  228. Routine Description:
  229. This function initializes the COM library.
  230. Arguments:
  231. none
  232. Return Value:
  233. TRUE - Successful.
  234. FALSE - Unsuccessful.
  235. --*/
  236. {
  237. HRESULT hResult = 0;
  238. hResult = CoInitializeEx(0, COINIT_MULTITHREADED);
  239. if (FAILED(hResult)) {
  240. wprintf(L"ERROR: COM library initialization failed!\n");
  241. wprintf(L"ERROR: Result: 0x%x\n", hResult);
  242. return FALSE;
  243. }
  244. wprintf(L"INFO: COM library initialization is successfully completed.\n");
  245. return TRUE;
  246. }
  247. BOOL
  248. MCAInitializeWMISecurity(
  249. VOID
  250. )
  251. /*++
  252. Routine Description:
  253. This function initializes the required security settings and establishes
  254. the connection to the WMI server on the local system.
  255. Arguments:
  256. none
  257. Return Value:
  258. TRUE - Successful.
  259. FALSE - Unsuccessful.
  260. --*/
  261. {
  262. HRESULT hResult = 0;
  263. LPWSTR pNamespace = L"ROOT\\WMI";
  264. //
  265. // Register security and set the security values for the current process.
  266. //
  267. hResult = CoInitializeSecurity(NULL,
  268. -1,
  269. NULL,
  270. NULL,
  271. RPC_C_AUTHN_LEVEL_CONNECT,
  272. RPC_C_IMP_LEVEL_IDENTIFY,
  273. NULL,
  274. EOAC_NONE,
  275. NULL
  276. );
  277. if (FAILED(hResult)) {
  278. wprintf(L"ERROR: Security initialization failed!\n");
  279. wprintf(L"ERROR: Result: 0x%x\n", hResult);
  280. return FALSE;
  281. }
  282. //
  283. // Create a single uninitialized object of class IWbemLocator on the local system.
  284. //
  285. hResult = CoCreateInstance(CLSID_WbemLocator,
  286. 0,
  287. CLSCTX_INPROC_SERVER,
  288. IID_IWbemLocator,
  289. (LPVOID *) &gPIWbemLocator
  290. );
  291. if (FAILED(hResult)) {
  292. wprintf(L"ERROR: IWbemLocator instance creation failed!\n");
  293. wprintf(L"ERROR: Result: 0x%x\n", hResult);
  294. return FALSE;
  295. }
  296. BSTR bNamespace = SysAllocString(pNamespace);
  297. if (bNamespace == NULL) {
  298. wprintf(L"ERROR: Memory allocation for string failed!\n");
  299. return FALSE;
  300. }
  301. //
  302. // Connect to the root\wmi namespace with the current user.
  303. //
  304. hResult = (gPIWbemLocator)->ConnectServer(bNamespace,
  305. NULL,
  306. NULL,
  307. NULL,
  308. NULL,
  309. NULL,
  310. NULL,
  311. &gPIWbemServices
  312. );
  313. if (FAILED(hResult)) {
  314. wprintf(L"ERROR: Could not connect to the WMI Server!\n");
  315. wprintf(L"ERROR: Result: 0x%x\n", hResult);
  316. return FALSE;
  317. }
  318. //
  319. // Set the authentication information on the specified proxy such that
  320. // impersonation of the client occurs.
  321. //
  322. hResult = CoSetProxyBlanket(gPIWbemServices,
  323. RPC_C_AUTHN_WINNT,
  324. RPC_C_AUTHZ_NONE,
  325. NULL,
  326. RPC_C_AUTHN_LEVEL_CALL,
  327. RPC_C_IMP_LEVEL_IMPERSONATE,
  328. NULL,
  329. EOAC_NONE
  330. );
  331. if (FAILED(hResult)) {
  332. wprintf(L"ERROR: Could not set proxy blanket!\n");
  333. wprintf(L"ERROR: Result: 0x%x\n", hResult);
  334. return FALSE;
  335. }
  336. wprintf(L"INFO: WMI security is initialized successfully.\n");
  337. //
  338. // Free the string allocated for storing the namespace.
  339. //
  340. if (bNamespace != NULL) {
  341. SysFreeString(bNamespace);
  342. }
  343. return TRUE;
  344. }
  345. #if defined(_X86_)
  346. VOID
  347. MCAPrintErrorRecordX86(
  348. PUCHAR PErrorData
  349. )
  350. /*++
  351. Routine Description:
  352. This function displays the machine check exception information on X86
  353. systems to the standard output (console screen).
  354. Arguments:
  355. PErrorData - Buffer containing the machine check exception information.
  356. Return Value:
  357. none
  358. --*/
  359. {
  360. PMCA_EXCEPTION pMCAException = NULL;
  361. pMCAException = (PMCA_EXCEPTION)PErrorData;
  362. wprintf(L"\n");
  363. wprintf(L"**************************************************\n");
  364. wprintf(L"* X86 MCA EXCEPTION *\n");
  365. wprintf(L"**************************************************\n");
  366. wprintf(L"* VersionNumber : 0x%08x\n", (ULONG) pMCAException->VersionNumber);
  367. wprintf(L"* ExceptionType : 0x%08x\n", (INT) pMCAException->ExceptionType);
  368. wprintf(L"* TimeStamp \n");
  369. wprintf(L"* LowPart : 0x%08x\n",(ULONG) pMCAException->TimeStamp.LowPart);
  370. wprintf(L"* HighPart: 0x%08x\n", (LONG) pMCAException->TimeStamp.HighPart);
  371. wprintf(L"* ProcessorNumber : 0x%08x\n", (ULONG) pMCAException->ProcessorNumber);
  372. wprintf(L"* Reserved1 : 0x%08x\n", (ULONG) pMCAException->Reserved1);
  373. if (pMCAException->ExceptionType == HAL_MCE_RECORD) {
  374. wprintf(L"* Mce \n");
  375. wprintf(L"* Address : 0x%016I64x\n", (ULONGLONG) pMCAException->u.Mce.Address);
  376. wprintf(L"* Type : 0x%016I64x\n", (ULONGLONG) pMCAException->u.Mce.Type);
  377. } else {
  378. wprintf(L"* Mca \n");
  379. wprintf(L"* BankNumber : 0x%02x\n", (UCHAR) pMCAException->u.Mca.BankNumber);
  380. for (int index = 0 ; index < 7 ; index++) {
  381. wprintf(L"* Reserved2[%d]: 0x%02x\n", index, (UCHAR) pMCAException->u.Mca.Reserved2[index]);
  382. }
  383. wprintf(L"* MciStats \n");
  384. wprintf(L"* McaCod : 0x%04x\n", (USHORT) pMCAException->u.Mca.Status.MciStats.McaCod);
  385. wprintf(L"* MsCod : 0x%04x\n", (USHORT) pMCAException->u.Mca.Status.MciStats.MsCod);
  386. wprintf(L"* OtherInfo : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStats.OtherInfo);
  387. wprintf(L"* Damage : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStats.Damage);
  388. wprintf(L"* AddressValid: 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStats.AddressValid);
  389. wprintf(L"* MiscValid : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStats.MiscValid);
  390. wprintf(L"* Enabled : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStats.Enabled);
  391. wprintf(L"* UnCorrected : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStats.UnCorrected);
  392. wprintf(L"* OverFlow : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStats.OverFlow);
  393. wprintf(L"* Valid : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStats.Valid);
  394. wprintf(L"* Address \n");
  395. wprintf(L"* Address : 0x%08x\n", (ULONG) pMCAException->u.Mca.Address.Address);
  396. wprintf(L"* Reserved: 0x%08x\n", (ULONG) pMCAException->u.Mca.Address.Reserved);
  397. wprintf(L"* Misc : 0x%016I64x\n", (ULONGLONG) pMCAException->u.Mca.Misc);
  398. }
  399. wprintf(L"* ExtCnt : 0x%08x\n", (ULONG) pMCAException->ExtCnt);
  400. wprintf(L"* Reserved3 : 0x%08x\n", (ULONG) pMCAException->Reserved3);
  401. for (int index = 0 ; index < MCA_EXTREG_V2MAX ; index++) {
  402. wprintf(L"* ExtReg[%2d] : 0x%016I64x\n" , index, (ULONGLONG) pMCAException->ExtReg[index]);
  403. }
  404. wprintf(L"*********************************************\n\n");
  405. }
  406. #endif // _X86_
  407. #if defined(_AMD64_)
  408. VOID
  409. MCAPrintErrorRecordAMD64(
  410. PUCHAR PErrorData
  411. )
  412. /*++
  413. Routine Description:
  414. This function displays the machine check exception information on AMD64
  415. systems to the standard output (console screen).
  416. Arguments:
  417. PErrorData - Buffer containing the machine check exception information.
  418. Return Value:
  419. none
  420. --*/
  421. {
  422. PMCA_EXCEPTION pMCAException = NULL;
  423. pMCAException = (PMCA_EXCEPTION)PErrorData;
  424. wprintf(L"\n");
  425. wprintf(L"*********************************************\n");
  426. wprintf(L"* X86-64 MCA EXCEPTION *\n");
  427. wprintf(L"*********************************************\n");
  428. wprintf(L"* VersionNumber : 0x%08x\n", (ULONG) pMCAException->VersionNumber);
  429. wprintf(L"* ExceptionType : 0x%08x\n", (INT) pMCAException->ExceptionType);
  430. wprintf(L"* TimeStamp \n");
  431. wprintf(L"* LowPart : 0x%08x\n", (ULONG) pMCAException->TimeStamp.LowPart);
  432. wprintf(L"* HighPart: 0x%08x\n", (LONG) pMCAException->TimeStamp.HighPart);
  433. wprintf(L"* ProcessorNumber : 0x%08x\n", (ULONG) pMCAException->ProcessorNumber);
  434. wprintf(L"* Reserved1 : 0x%08x\n", (ULONG) pMCAException->Reserved1);
  435. if (pMCAException->ExceptionType == HAL_MCE_RECORD) {
  436. wprintf(L"* Mce \n");
  437. wprintf(L"* Address : 0x%016I64x\n", (ULONGLONG) pMCAException->u.Mce.Address);
  438. wprintf(L"* Type : 0x%016I64x\n", (ULONGLONG) pMCAException->u.Mce.Type);
  439. } else {
  440. wprintf(L"* Mca \n");
  441. wprintf(L"* BankNumber : 0x%02x\n", (UCHAR) pMCAException->u.Mca.BankNumber);
  442. for (int index = 0 ; index < 7 ; index++) {
  443. wprintf(L"* Reserved2[%d]: 0x%02x\n", index, (UCHAR) pMCAException->u.Mca.Reserved2[index]);
  444. }
  445. wprintf(L"* MciStatus\n");
  446. wprintf(L"* McaErrorCode : 0x%04x\n", (USHORT) pMCAException->u.Mca.Status.MciStatus.McaErrorCode);
  447. wprintf(L"* ModelErrorCode : 0x%04x\n", (USHORT) pMCAException->u.Mca.Status.MciStatus.ModelErrorCode);
  448. wprintf(L"* OtherInformation: 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStatus.OtherInformation);
  449. wprintf(L"* ContextCorrupt : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStatus.ContextCorrupt);
  450. wprintf(L"* AddressValid : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStatus.AddressValid);
  451. wprintf(L"* MiscValid : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStatus.MiscValid);
  452. wprintf(L"* ErrorEnabled : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStatus.ErrorEnabled);
  453. wprintf(L"* UncorrectedError: 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStatus.UncorrectedError);
  454. wprintf(L"* StatusOverFlow : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStatus.StatusOverFlow);
  455. wprintf(L"* Valid : 0x%01x\n", (ULONG) pMCAException->u.Mca.Status.MciStatus.Valid);
  456. wprintf(L"* Address \n");
  457. wprintf(L"* Address : 0x%08x\n", (ULONG) pMCAException->u.Mca.Address.Address);
  458. wprintf(L"* Reserved: 0x%08x\n", (ULONG) pMCAException->u.Mca.Address.Reserved);
  459. wprintf(L"* Misc : 0x%016I64x\n", (ULONGLONG) pMCAException->u.Mca.Misc);
  460. }
  461. wprintf(L"*********************************************\n\n");
  462. }
  463. #endif // _AMD64_
  464. #if defined(_IA64_)
  465. VOID
  466. MCAPrintErrorRecordIA64(
  467. PUCHAR PErrorData
  468. )
  469. /*++
  470. Routine Description:
  471. This function displays the headers of the provided MCA error
  472. record on IA64 systems to the standard output (console screen).
  473. The Error Record Header and Section Headers are displayed in
  474. a formatted manner.
  475. Arguments:
  476. PErrorData - Buffer containing the MCA error record.
  477. Return Value:
  478. none
  479. --*/
  480. {
  481. PERROR_RECORD_HEADER pErrorRecordHeader = NULL;
  482. PERROR_SECTION_HEADER pErrorSectionHeader = NULL;
  483. ULONG sectionOffset = 0;
  484. INT sectionNumber = 0;
  485. //
  486. // The record header must be at the top of the record buffer.
  487. //
  488. pErrorRecordHeader = (PERROR_RECORD_HEADER)PErrorData;
  489. wprintf(L"\n");
  490. wprintf(L"***************************************************************************\n");
  491. wprintf(L"* IA64 MCA ERROR *\n");
  492. wprintf(L"***************************************************************************\n");
  493. wprintf(L"* Error Record Header *\n");
  494. wprintf(L"*-------------------------------------------------------------------------*\n");
  495. wprintf(L"* ID : 0x%I64x\n", (ULONGLONG)pErrorRecordHeader->Id);
  496. wprintf(L"* Revision : 0x%x\n" , (ULONG) pErrorRecordHeader->Revision.Revision);
  497. wprintf(L"* Major : %x\n" , (ULONG) pErrorRecordHeader->Revision.Major);
  498. wprintf(L"* Minor : %x\n" , (ULONG) pErrorRecordHeader->Revision.Minor);
  499. wprintf(L"* Severity : 0x%x\n" , (ULONG) pErrorRecordHeader->ErrorSeverity);
  500. wprintf(L"* Validity : 0x%x\n" , (ULONG) pErrorRecordHeader->Valid.Valid);
  501. wprintf(L"* OEMPlatformID : %x\n", (ULONG) pErrorRecordHeader->Valid.OemPlatformID);
  502. wprintf(L"* Length : 0x%x\n" , (ULONG) pErrorRecordHeader->Length);
  503. wprintf(L"* TimeStamp : 0x%I64x\n", (ULONGLONG) pErrorRecordHeader->TimeStamp.TimeStamp);
  504. wprintf(L"* Seconds : %x\n" , (ULONG) pErrorRecordHeader->TimeStamp.Seconds);
  505. wprintf(L"* Minutes : %x\n" , (ULONG) pErrorRecordHeader->TimeStamp.Minutes);
  506. wprintf(L"* Hours : %x\n" , (ULONG) pErrorRecordHeader->TimeStamp.Hours);
  507. wprintf(L"* Day : %x\n" , (ULONG) pErrorRecordHeader->TimeStamp.Day);
  508. wprintf(L"* Month : %x\n" , (ULONG) pErrorRecordHeader->TimeStamp.Month);
  509. wprintf(L"* Year : %x\n" , (ULONG) pErrorRecordHeader->TimeStamp.Year);
  510. wprintf(L"* Century : %x\n" , (ULONG) pErrorRecordHeader->TimeStamp.Century);
  511. wprintf(L"* OEMPlatformID: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
  512. (ULONG) pErrorRecordHeader->OemPlatformId[0],
  513. (ULONG) pErrorRecordHeader->OemPlatformId[1],
  514. (ULONG) pErrorRecordHeader->OemPlatformId[2],
  515. (ULONG) pErrorRecordHeader->OemPlatformId[3],
  516. (ULONG) pErrorRecordHeader->OemPlatformId[4],
  517. (ULONG) pErrorRecordHeader->OemPlatformId[5],
  518. (ULONG) pErrorRecordHeader->OemPlatformId[6],
  519. (ULONG) pErrorRecordHeader->OemPlatformId[7],
  520. (ULONG) pErrorRecordHeader->OemPlatformId[8],
  521. (ULONG) pErrorRecordHeader->OemPlatformId[9],
  522. (ULONG) pErrorRecordHeader->OemPlatformId[10],
  523. (ULONG) pErrorRecordHeader->OemPlatformId[11],
  524. (ULONG) pErrorRecordHeader->OemPlatformId[12],
  525. (ULONG) pErrorRecordHeader->OemPlatformId[13],
  526. (ULONG) pErrorRecordHeader->OemPlatformId[14],
  527. (ULONG) pErrorRecordHeader->OemPlatformId[15]);
  528. //
  529. // Now display each of the section headers in the error record.
  530. //
  531. sectionOffset = sizeof(ERROR_RECORD_HEADER);
  532. while (sectionOffset < pErrorRecordHeader->Length) {
  533. pErrorSectionHeader = (PERROR_SECTION_HEADER)(PErrorData + sectionOffset);
  534. wprintf(L"***************************************************************************\n");
  535. wprintf(L"* Section Header *\n");
  536. wprintf(L"***************************************************************************\n");
  537. wprintf(L"* GUID: 0x%x, 0x%x, 0x%x, \n",
  538. pErrorSectionHeader->Guid.Data1,
  539. pErrorSectionHeader->Guid.Data2,
  540. pErrorSectionHeader->Guid.Data3);
  541. wprintf(L"* { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }\n",
  542. pErrorSectionHeader->Guid.Data4[0],
  543. pErrorSectionHeader->Guid.Data4[1],
  544. pErrorSectionHeader->Guid.Data4[2],
  545. pErrorSectionHeader->Guid.Data4[3],
  546. pErrorSectionHeader->Guid.Data4[4],
  547. pErrorSectionHeader->Guid.Data4[5],
  548. pErrorSectionHeader->Guid.Data4[6],
  549. pErrorSectionHeader->Guid.Data4[7]);
  550. wprintf(L"* Revision: 0x%x\n", pErrorSectionHeader->Revision);
  551. wprintf(L"* Major : %x\n" , (ULONG) pErrorSectionHeader->Revision.Major);
  552. wprintf(L"* Minor : %x\n" , (ULONG) pErrorSectionHeader->Revision.Minor);
  553. wprintf(L"* Recovery: 0x%x\n", (UCHAR)pErrorSectionHeader->RecoveryInfo.RecoveryInfo);
  554. wprintf(L"* Reserved: 0x%x\n", (UCHAR)pErrorSectionHeader->Reserved);
  555. wprintf(L"* Length : 0x%x\n", (ULONG)pErrorSectionHeader->Length);
  556. sectionOffset += pErrorSectionHeader->Length;
  557. sectionNumber++;
  558. }
  559. wprintf(L"***************************************************************************\n\n");
  560. }
  561. #endif // _IA64_