Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

triage.c

Go to the documentation of this file.
00001 00002 /*++ 00003 00004 Copyright(c) 1999 Microsoft Corporation 00005 00006 Module Name: 00007 00008 triage.c 00009 00010 Abstract: 00011 00012 Triage dump support. 00013 00014 Author: 00015 00016 Matthew D. Hendel (math) 20-Jan-1999 00017 00018 Comments: 00019 00020 Do not merge this file with some other file. By leaving it in it's own 00021 compiland, we avoid having to link with all the other random variables 00022 in crashlib. 00023 00024 00025 --*/ 00026 00027 #include "iop.h" 00028 #include <nt.h> 00029 #include <ntrtl.h> 00030 #include <windef.h> 00031 #include <stdio.h> 00032 #include <malloc.h> 00033 #include <ntiodump.h> 00034 #include <triage.h> 00035 #include <ntverp.h> 00036 00037 00038 #ifndef NtBuildNumber 00039 # if DBG 00040 # define NtBuildNumber (VER_PRODUCTBUILD | 0xC0000000) 00041 # else 00042 # define NtBuildNumber (VER_PRODUCTBUILD | 0xF0000000) 00043 # endif 00044 #endif 00045 00046 00047 // 00048 // NOTE: Pages sizes copied from ntos\inc. These must be kept in sync with 00049 // global header files. 00050 // 00051 00052 #define PAGE_SIZE_I386 0x1000 00053 #define PAGE_SIZE_ALPHA 0x2000 00054 #define PAGE_SIZE_IA64 0x2000 00055 00056 00057 ULONG TriageImagePageSize = -1; 00058 00059 BOOLEAN 00060 TriagepVerifyDump( 00061 IN LPVOID TriageDumpBlock 00062 ); 00063 00064 ULONG 00065 TriagepGetPageSize( 00066 ULONG Architecture 00067 ); 00068 00069 PTRIAGE_DUMP_HEADER 00070 TriagepGetTriagePointer( 00071 IN PVOID TriageDumpBlock 00072 ); 00073 00074 00075 #ifdef ALLOC_PRAGMA 00076 00077 #pragma alloc_text (INIT, TriagepVerifyDump) 00078 #pragma alloc_text (INIT, TriagepGetPageSize) 00079 #pragma alloc_text (INIT, TriagepGetTriagePointer) 00080 00081 #pragma alloc_text (INIT, TriageGetVersion) 00082 #pragma alloc_text (INIT, TriageGetDriverCount) 00083 #pragma alloc_text (INIT, TriageGetContext) 00084 #pragma alloc_text (INIT, TriageGetExceptionRecord) 00085 #pragma alloc_text (INIT, TriageGetBugcheckData) 00086 #pragma alloc_text (INIT, TriageGetDriverEntry) 00087 00088 #endif 00089 00090 00091 //++ 00092 // 00093 // PULONG 00094 // IndexByUlong( 00095 // PVOID Pointer, 00096 // ULONG Index 00097 // ) 00098 // 00099 // Routine Description: 00100 // 00101 // Return the address Index ULONGs into Pointer. That is, 00102 // Index * sizeof (ULONG) bytes into Pointer. 00103 // 00104 // Arguments: 00105 // 00106 // Pointer - Start of region. 00107 // 00108 // Index - Number of ULONGs to index into. 00109 // 00110 // Return Value: 00111 // 00112 // PULONG representing the pointer described above. 00113 // 00114 //-- 00115 00116 #define IndexByUlong(Pointer,Index) (&(((ULONG*) (Pointer)) [Index])) 00117 00118 00119 //++ 00120 // 00121 // PBYTE 00122 // IndexByByte( 00123 // PVOID Pointer, 00124 // ULONG Index 00125 // ) 00126 // 00127 // Routine Description: 00128 // 00129 // Return the address Index BYTEs into Pointer. That is, 00130 // Index * sizeof (BYTE) bytes into Pointer. 00131 // 00132 // Arguments: 00133 // 00134 // Pointer - Start of region. 00135 // 00136 // Index - Number of BYTEs to index into. 00137 // 00138 // Return Value: 00139 // 00140 // PBYTE representing the pointer described above. 00141 // 00142 //-- 00143 00144 #define IndexByByte(Pointer, Index) (&(((BYTE*) (Pointer)) [Index])) 00145 00146 00147 ULONG 00148 TriagepGetPageSize( 00149 ULONG Architecture 00150 ) 00151 { 00152 switch (Architecture) { 00153 00154 case IMAGE_FILE_MACHINE_I386: 00155 return PAGE_SIZE_I386; 00156 00157 case IMAGE_FILE_MACHINE_ALPHA: 00158 return PAGE_SIZE_ALPHA; 00159 00160 case IMAGE_FILE_MACHINE_IA64: 00161 return PAGE_SIZE_IA64; 00162 00163 default: 00164 return -1; 00165 } 00166 } 00167 00168 00169 00170 BOOLEAN 00171 TriagepVerifyDump( 00172 IN LPVOID TriageDumpBlock 00173 ) 00174 { 00175 BOOLEAN Succ = FALSE; 00176 PDUMP_HEADER DumpHeader = NULL; 00177 PTRIAGE_DUMP_HEADER TriageHeader = NULL; 00178 00179 if (!TriageDumpBlock) { 00180 00181 return FALSE; 00182 } 00183 00184 DumpHeader = (PDUMP_HEADER) TriageDumpBlock; 00185 00186 try { 00187 00188 if (DumpHeader->ValidDump != 'PMUD' || 00189 DumpHeader->Signature != 'EGAP' || 00190 TriagepGetPageSize (DumpHeader->MachineImageType) == -1) { 00191 00192 Succ = FALSE; 00193 leave; 00194 } 00195 00196 TriageImagePageSize = TriagepGetPageSize (DumpHeader->MachineImageType); 00197 00198 TriageHeader = (PTRIAGE_DUMP_HEADER) 00199 IndexByByte ( TriageDumpBlock, TriageImagePageSize ); 00200 00201 if ( *(ULONG*)IndexByUlong (DumpHeader, DH_DUMP_TYPE) != DUMP_TYPE_TRIAGE || 00202 *(ULONG*)IndexByByte (DumpHeader, TriageHeader->SizeOfDump - sizeof (DWORD)) != TRIAGE_DUMP_VALID ) { 00203 00204 Succ = FALSE; 00205 leave; 00206 } 00207 00208 // else 00209 00210 Succ = TRUE; 00211 } 00212 00213 except (EXCEPTION_EXECUTE_HANDLER) { 00214 00215 Succ = FALSE; 00216 } 00217 00218 return Succ; 00219 } 00220 00221 00222 PTRIAGE_DUMP_HEADER 00223 TriagepGetTriagePointer( 00224 IN PVOID TriageDumpBlock 00225 ) 00226 { 00227 ASSERT (TriageImagePageSize != -1); 00228 ASSERT (TriagepVerifyDump (TriageDumpBlock)); 00229 00230 return (PTRIAGE_DUMP_HEADER) IndexByByte (TriageDumpBlock, TriageImagePageSize); 00231 } 00232 00233 00234 00235 NTSTATUS 00236 TriageGetVersion( 00237 IN LPVOID TriageDumpBlock, 00238 OUT ULONG * MajorVersion, 00239 OUT ULONG * MinorVersion, 00240 OUT ULONG * ServicePackBuild 00241 ) 00242 { 00243 PTRIAGE_DUMP_HEADER TriageDump; 00244 PDUMP_HEADER DumpHeader; 00245 00246 if (!TriagepVerifyDump (TriageDumpBlock)) { 00247 return STATUS_INVALID_PARAMETER; 00248 } 00249 00250 TriageDump = TriagepGetTriagePointer (TriageDumpBlock); 00251 00252 if (!TriageDump) { 00253 return STATUS_INVALID_PARAMETER; 00254 } 00255 00256 DumpHeader = (PDUMP_HEADER) TriageDumpBlock; 00257 00258 if (MajorVersion) { 00259 *MajorVersion = DumpHeader->MajorVersion; 00260 } 00261 00262 if (MinorVersion) { 00263 *MinorVersion = DumpHeader->MinorVersion; 00264 } 00265 00266 if (ServicePackBuild) { 00267 *ServicePackBuild = TriageDump->ServicePackBuild; 00268 } 00269 00270 return STATUS_SUCCESS; 00271 } 00272 00273 00274 00275 NTSTATUS 00276 TriageGetDriverCount( 00277 IN LPVOID TriageDumpBlock, 00278 OUT ULONG * DriverCount 00279 ) 00280 { 00281 PTRIAGE_DUMP_HEADER TriageDump; 00282 00283 if (!TriagepVerifyDump (TriageDumpBlock)) { 00284 return STATUS_INVALID_PARAMETER; 00285 } 00286 00287 TriageDump = TriagepGetTriagePointer (TriageDumpBlock); 00288 00289 if (!TriageDump) { 00290 return STATUS_INVALID_PARAMETER; 00291 } 00292 00293 *DriverCount = TriageDump->DriverCount; 00294 00295 return STATUS_SUCCESS; 00296 } 00297 00298 00299 00300 #if 0 00301 00302 NTSTATUS 00303 TriageGetContext( 00304 IN LPVOID TriageDumpBlock, 00305 OUT LPVOID Context, 00306 IN ULONG SizeInBytes 00307 ) 00308 { 00309 PTRIAGE_DUMP_HEADER TriageDump; 00310 00311 if (!TriagepVerifyDump (TriageDumpBlock)) { 00312 return STATUS_INVALID_PARAMETER; 00313 } 00314 00315 TriageDump = TriagepGetTriagePointer (TriageDumpBlock); 00316 00317 if (!TriageDump) { 00318 return STATUS_INVALID_PARAMETER; 00319 } 00320 00321 // 00322 // Copy the CONTEXT record. 00323 // 00324 00325 if (SizeInBytes == -1) { 00326 SizeInBytes = sizeof (CONTEXT); 00327 } 00328 00329 RtlCopyMemory (Context, 00330 IndexByUlong (TriageDumpBlock, TriageDump->ContextOffset), 00331 SizeInBytes 00332 ); 00333 00334 return STATUS_SUCCESS; 00335 } 00336 00337 00338 NTSTATUS 00339 TriageGetExceptionRecord( 00340 IN LPVOID TriageDumpBlock, 00341 OUT EXCEPTION_RECORD * ExceptionRecord 00342 ) 00343 { 00344 PTRIAGE_DUMP_HEADER TriageDump; 00345 00346 if (!TriagepVerifyDump (TriageDumpBlock)) { 00347 return STATUS_INVALID_PARAMETER; 00348 } 00349 00350 TriageDump = TriagepGetTriagePointer (TriageDumpBlock); 00351 00352 if (!TriageDump) { 00353 return STATUS_INVALID_PARAMETER; 00354 } 00355 00356 RtlCopyMemory (ExceptionRecord, 00357 IndexByUlong (TriageDumpBlock, TriageDump->ExceptionOffset), 00358 sizeof (*ExceptionRecord) 00359 ); 00360 00361 return STATUS_SUCCESS; 00362 } 00363 #endif 00364 00365 00366 LOGICAL 00367 TriageActUpon( 00368 IN PVOID TriageDumpBlock 00369 ) 00370 { 00371 PTRIAGE_DUMP_HEADER TriageDump; 00372 00373 if (!TriagepVerifyDump (TriageDumpBlock)) { 00374 return FALSE; 00375 } 00376 00377 TriageDump = TriagepGetTriagePointer (TriageDumpBlock); 00378 00379 if (!TriageDump) { 00380 return FALSE; 00381 } 00382 00383 if ((TriageDump->TriageOptions & DCB_TRIAGE_DUMP_ACT_UPON_ENABLED) == 0) { 00384 return FALSE; 00385 } 00386 00387 return TRUE; 00388 } 00389 00390 00391 NTSTATUS 00392 TriageGetBugcheckData( 00393 IN LPVOID TriageDumpBlock, 00394 OUT ULONG * BugCheckCode, 00395 OUT UINT_PTR * BugCheckParam1, 00396 OUT UINT_PTR * BugCheckParam2, 00397 OUT UINT_PTR * BugCheckParam3, 00398 OUT UINT_PTR * BugCheckParam4 00399 ) 00400 { 00401 PDUMP_HEADER DumpHeader; 00402 00403 if (!TriagepVerifyDump (TriageDumpBlock)) { 00404 return STATUS_INVALID_PARAMETER; 00405 } 00406 00407 DumpHeader = (PDUMP_HEADER) TriageDumpBlock; 00408 00409 *BugCheckCode = DumpHeader->BugCheckCode; 00410 *BugCheckParam1 = DumpHeader->BugCheckParameter1; 00411 *BugCheckParam2 = DumpHeader->BugCheckParameter2; 00412 *BugCheckParam3 = DumpHeader->BugCheckParameter3; 00413 *BugCheckParam4 = DumpHeader->BugCheckParameter4; 00414 00415 return STATUS_SUCCESS; 00416 } 00417 00418 00419 00420 PLDR_DATA_TABLE_ENTRY 00421 TriageGetLoaderEntry( 00422 IN PVOID TriageDumpBlock, 00423 IN ULONG ModuleIndex 00424 ) 00425 00426 /*++ 00427 00428 Routine Description: 00429 00430 This function retrieves a loaded module list entry. 00431 00432 Arguments: 00433 00434 TriageDumpBlock - Supplies the triage dump to reference. 00435 00436 ModuleIndex - Supplies the driver index number to locate. 00437 00438 Return Value: 00439 00440 A pointer to a loader data table entry if one is available, NULL if not. 00441 00442 Environment: 00443 00444 Kernel mode, APC_LEVEL or below. Phase 0 only. 00445 00446 N.B. This function is for use by memory management ONLY. 00447 00448 --*/ 00449 00450 { 00451 ULONG i; 00452 PDUMP_STRING DriverName; 00453 PDUMP_DRIVER_ENTRY DriverList; 00454 PTRIAGE_DUMP_HEADER TriageDump; 00455 PLDR_DATA_TABLE_ENTRY DataTableEntry; 00456 00457 if (!TriagepVerifyDump (TriageDumpBlock)) { 00458 return NULL; 00459 } 00460 00461 TriageDump = TriagepGetTriagePointer (TriageDumpBlock); 00462 00463 if (ModuleIndex >= TriageDump->DriverCount) { 00464 return NULL; 00465 } 00466 00467 DriverList = (PDUMP_DRIVER_ENTRY) 00468 IndexByByte (TriageDumpBlock, TriageDump->DriverListOffset); 00469 00470 00471 DataTableEntry = &DriverList [ ModuleIndex ].LdrEntry; 00472 00473 // 00474 // Repoint the module driver name into the triage buffer. 00475 // 00476 00477 DriverName = (PDUMP_STRING) 00478 IndexByByte (TriageDumpBlock, 00479 DriverList [ ModuleIndex ].DriverNameOffset); 00480 00481 DataTableEntry->BaseDllName.Length = (USHORT) (DriverName->Length * sizeof (WCHAR)); 00482 DataTableEntry->BaseDllName.MaximumLength = DataTableEntry->BaseDllName.Length; 00483 DataTableEntry->BaseDllName.Buffer = DriverName->Buffer; 00484 00485 return DataTableEntry; 00486 } 00487 00488 00489 PVOID 00490 TriageGetMmInformation( 00491 IN PVOID TriageDumpBlock 00492 ) 00493 00494 /*++ 00495 00496 Routine Description: 00497 00498 This function retrieves a loaded module list entry. 00499 00500 Arguments: 00501 00502 TriageDumpBlock - Supplies the triage dump to reference. 00503 00504 Return Value: 00505 00506 A pointer to an opaque Mm information structure. 00507 00508 Environment: 00509 00510 Kernel mode, APC_LEVEL or below. Phase 0 only. 00511 00512 N.B. This function is for use by memory management ONLY. 00513 00514 --*/ 00515 00516 { 00517 PTRIAGE_DUMP_HEADER TriageDump; 00518 00519 if (!TriagepVerifyDump (TriageDumpBlock)) { 00520 return NULL; 00521 } 00522 00523 TriageDump = TriagepGetTriagePointer (TriageDumpBlock); 00524 00525 if (!TriageDump) { 00526 return NULL; 00527 } 00528 00529 return (PVOID)IndexByByte (TriageDumpBlock, TriageDump->MmOffset); 00530 }

Generated on Sat May 15 19:42:05 2004 for test by doxygen 1.3.7