00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00049
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
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 #define IndexByUlong(Pointer,Index) (&(((ULONG*) (Pointer)) [Index]))
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
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
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
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
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
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
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
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
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 }