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
#include "iop.h"
00027
#include "ntddft.h"
00028
#include <inbv.h>
00029
#include <windef.h>
00030
00031
00032
00033
00034
00035
#if defined (i386)
00036
00037
#define PROGRAM_COUNTER(_context) ((_context)->Eip)
00038
#define STACK_POINTER(_context) ((_context)->Esp)
00039
#define CURRENT_IMAGE_TYPE() IMAGE_FILE_MACHINE_I386
00040
#define PaeEnabled() X86PaeEnabled()
00041
00042
#elif defined (ALPHA)
00043
00044
#define PROGRAM_COUNTER(_context) ((_context)->Fir)
00045
#define STACK_POINTER(_context) ((_context)->IntSp)
00046
#define CURRENT_IMAGE_TYPE() IMAGE_FILE_MACHINE_ALPHA
00047
#define PaeEnabled() (FALSE)
00048
00049
#elif defined (_IA64_)
00050
00051
#define PROGRAM_COUNTER(_context) ((_context)->StIIP)
00052
#define STACK_POINTER(_context) ((_context)->IntSp)
00053
#define CURRENT_IMAGE_TYPE() IMAGE_FILE_MACHINE_IA64
00054
#define PaeEnabled() (FALSE)
00055
00056
#else
00057
00058
#error ("unknown processor type")
00059
00060
#endif
00061
00062
00063
00064
00065
00066
00067
00068 #define min3(_a,_b,_c) ( min ( min ((_a), (_b)), min ((_a), (_c))) )
00069
00070
00071
00072
00073
00074
00075 extern PVOID
MmPfnDatabase;
00076 extern PFN_NUMBER
MmHighestPossiblePhysicalPage;
00077
00078 NTSTATUS IopFinalCrashDumpStatus = -1;
00079 ULONG
IopCrashDumpStateChange = 0;
00080 BOOLEAN
IopDumpFileContainsNewDump =
FALSE;
00081
00082
00083
00084
00085
00086 #define IO_DUMP_MAXIMUM_TRANSFER_SIZE ( 1024 * 64 )
00087 #define IO_DUMP_MINIMUM_TRANSFER_SIZE ( 1024 * 32 )
00088 #define IO_DUMP_MINIMUM_FILE_SIZE ( PAGE_SIZE * 256 )
00089 #define MAX_UNICODE_LENGTH ( 512 )
00090
00091 #define DEFAULT_DRIVER_PATH L"\\SystemRoot\\System32\\Drivers\\"
00092 #define DEFAULT_DUMP_DRIVER L"\\SystemRoot\\System32\\Drivers\\diskdump.sys"
00093 #define SCSIPORT_DRIVER_NAME L"scsiport.sys"
00094 #define MAX_TRIAGE_STACK_SIZE ( 16 * 1024 )
00095 #define DEFAULT_TRIAGE_DUMP_FLAGS (0xFFFFFFFF)
00096
00097
00098
00099
00100
00101
00102
00103
NTSTATUS
00104
IopWriteTriageDump(
00105 IN ULONG FieldsToWrite,
00106 IN
PDUMP_DRIVER_WRITE WriteRoutine,
00107 IN OUT PLARGE_INTEGER Mcb,
00108 IN OUT
PMDL Mdl,
00109 IN ULONG DiverTransferSize,
00110 IN PCONTEXT Context,
00111 IN LPBYTE Buffer,
00112 IN ULONG BufferSize,
00113 IN ULONG ServicePackBuild,
00114 IN ULONG TriageOptions
00115 );
00116
00117
NTSTATUS
00118
IopWriteSummaryDump(
00119 IN PRTL_BITMAP PageMap,
00120 IN PDUMP_DRIVER_WRITE WriteRoutine,
00121 IN PANSI_STRING ProgressMessage,
00122 IN PUCHAR MessageBuffer,
00123 IN OUT PLARGE_INTEGER Mcb,
00124 IN ULONG DiverTransferSize
00125 );
00126
00127
NTSTATUS
00128
IopWriteToDisk(
00129 IN PVOID Buffer,
00130 IN ULONG WriteLength,
00131 IN PDUMP_DRIVER_WRITE DriverWriteRoutine,
00132 IN OUT PLARGE_INTEGER * Mcb,
00133 IN OUT
PMDL Mdl,
00134 IN ULONG DriverTransferSize
00135 );
00136
00137
VOID
00138
IopMapPhysicalMemory(
00139 IN OUT
PMDL Mdl,
00140 IN ULONG_PTR MemoryAddress,
00141 IN
PPHYSICAL_MEMORY_RUN PhysicalMemoryRun,
00142 IN ULONG Length
00143 );
00144
00145
NTSTATUS
00146
IopLoadDumpDriver (
00147 IN OUT
PDUMP_STACK_CONTEXT DumpStack,
00148 IN PWCHAR DriverNameString,
00149 IN PWCHAR NewBaseNameString
00150 );
00151
00152
NTSTATUS
00153
IoSetCrashDumpState(
00154 IN SYSTEM_CRASH_STATE_INFORMATION *pDumpState
00155 );
00156
00157 PSUMMARY_DUMP_HEADER
00158
IopInitializeSummaryDump(
00159 IN
PDUMP_CONTROL_BLOCK pDcb
00160 );
00161
00162
NTSTATUS
00163
IopWriteSummaryHeader(
00164 IN PSUMMARY_DUMP_HEADER pSummaryHeader,
00165 IN PDUMP_DRIVER_WRITE pfWrite,
00166 IN OUT PLARGE_INTEGER * pMcbBuffer,
00167 IN OUT
PMDL pMdl,
00168 IN ULONG dwWriteSize,
00169 IN ULONG dwLength
00170 );
00171
00172
VOID
00173
IopMapVirtualToPhysicalMdl(
00174 IN OUT
PMDL pMdl,
00175 IN ULONG_PTR dwMemoryAddress,
00176 IN ULONG dwLength
00177 );
00178
00179 ULONG
00180
IopCreateSummaryDump (
00181 IN PSUMMARY_DUMP_HEADER pHeader
00182 );
00183
00184
VOID
00185
IopDeleteNonExistentMemory(
00186 PSUMMARY_DUMP_HEADER pHeader,
00187
PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock
00188 );
00189
00190
00191
NTSTATUS
00192
IopGetDumpStack (
00193 IN PWCHAR ModulePrefix,
00194 OUT PDUMP_STACK_CONTEXT *pDumpStack,
00195 IN PUNICODE_STRING pUniDeviceName,
00196 IN PWSTR pDumpDriverName,
00197 IN
DEVICE_USAGE_NOTIFICATION_TYPE UsageType,
00198 IN ULONG IgnoreDeviceUsageFailure
00199 );
00200
00201 BOOLEAN
00202
IopInitializeDCB(
00203 );
00204
00205 LARGE_INTEGER
00206
IopCalculateRequiredDumpSpace(
00207 IN ULONG dwDmpFlags,
00208 IN ULONG dwHeaderSize,
00209 IN PFN_NUMBER dwMaxPages,
00210 IN PFN_NUMBER dwMaxSummaryPages
00211 );
00212
00213
NTSTATUS
00214
IopCompleteDumpInitialization(
00215 IN HANDLE FileHandle
00216 );
00217
00218
#if DBG
00219
00220
VOID
00221 IopDebugPrint(
00222 ULONG DebugPrintLevel,
00223 PCCHAR DebugMessage,
00224 ...
00225 );
00226
00227
#define IoDebugPrint(X) IopDebugPrint X
00228
00229
#else
00230
00231 #define IoDebugPrint(X)
00232
00233
#endif //DBG
00234
00235
00236
#ifdef ALLOC_PRAGMA
00237
#pragma alloc_text(PAGE,IoGetDumpStack)
00238
#pragma alloc_text(PAGE,IopLoadDumpDriver)
00239
#pragma alloc_text(PAGE,IoFreeDumpStack)
00240
#pragma alloc_text(PAGE,IoGetCrashDumpInformation)
00241
#pragma alloc_text(PAGE,IoGetCrashDumpStateInformation)
00242
#pragma alloc_text(PAGE,IoSetCrashDumpState)
00243
#endif
00244
00245
00246
#if defined (i386)
00247
00248
00249
00250
00251
00252
00253
BOOL
00254 X86PaeEnabled(
00255 )
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 {
00270 ULONG Reg_Cr4;
00271
00272 _asm {
00273 _emit 0Fh
00274 _emit 20h
00275 _emit 0E0h ;; mov eax, cr4
00276 mov Reg_Cr4, eax
00277 }
00278
00279
return (Reg_Cr4 & CR4_PAE ?
TRUE :
FALSE);
00280 }
00281
00282
#endif
00283
00284
00285
00286 BOOLEAN
00287 IopIsAddressRangeValid(
00288 IN PVOID VirtualAddress,
00289 IN SIZE_T Length
00290 )
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 {
00313 UINT_PTR Va;
00314 ULONG Pages;
00315
00316 Va = (UINT_PTR)
PAGE_ALIGN (VirtualAddress);
00317 Pages =
COMPUTE_PAGES_SPANNED (VirtualAddress, Length);
00318
00319
while (Pages) {
00320
00321
if (!
MmIsAddressValid ( (
LPVOID) Va)) {
00322
return FALSE;
00323 }
00324
00325 Va +=
PAGE_SIZE;
00326 Pages--;
00327 }
00328
00329
return TRUE;
00330 }
00331
00332
00333
00334
NTSTATUS
00335 IoGetDumpStack (
00336 IN PWCHAR ModulePrefix,
00337 OUT PDUMP_STACK_CONTEXT * pDumpStack,
00338 IN DEVICE_USAGE_NOTIFICATION_TYPE UsageType,
00339 IN ULONG IgnoreDeviceUsageFailure
00340 )
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 {
00370
00371
PAGED_CODE();
00372
return IopGetDumpStack(ModulePrefix,
00373 pDumpStack,
00374 &
IoArcBootDeviceName,
00375
DEFAULT_DUMP_DRIVER,
00376 UsageType,
00377 IgnoreDeviceUsageFailure
00378 );
00379 }
00380
00381
00382
00383
NTSTATUS
00384 IopGetDumpStack (
00385 IN PWCHAR ModulePrefix,
00386 OUT PDUMP_STACK_CONTEXT * pDumpStack,
00387 IN PUNICODE_STRING pUniDeviceName,
00388 IN PWCHAR pDumpDriverName,
00389 IN DEVICE_USAGE_NOTIFICATION_TYPE UsageType,
00390 IN ULONG IgnoreDeviceUsageFailure
00391 )
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 {
00425
PDUMP_STACK_CONTEXT DumpStack;
00426 PUCHAR
Buffer;
00427 PUCHAR PartitionName;
00428 ANSI_STRING AnsiString;
00429 UNICODE_STRING TempName;
00430 OBJECT_ATTRIBUTES
ObjectAttributes;
00431
NTSTATUS Status;
00432 HANDLE DeviceHandle;
00433 SCSI_ADDRESS ScsiAddress;
00434 BOOLEAN ScsiDump;
00435 PARTITION_INFORMATION PartitionInfo;
00436
PFILE_OBJECT FileObject;
00437
PDEVICE_OBJECT DeviceObject;
00438
PINITIALIZATION_CONTEXT DumpInit;
00439 PDUMP_POINTERS DumpPointers;
00440 UNICODE_STRING DriverName;
00441
PDRIVER_OBJECT DriverObject;
00442
PIRP Irp;
00443
PIO_STACK_LOCATION IrpSp;
00444 IO_STATUS_BLOCK IoStatus;
00445 PWCHAR DumpName, NameOffset;
00446
KEVENT Event;
00447 PVOID p1;
00448 PHYSICAL_ADDRESS pa;
00449 ULONG i;
00450
IO_STACK_LOCATION irpSp;
00451 ULONG information;
00452
00453
IoDebugPrint((2,
"IopGetDumpStack: Prefix:%ws stk: %x device:%ws driver:%ws\n",
00454 ModulePrefix, pDumpStack, pUniDeviceName->Buffer,pDumpDriverName));
00455
00456
ASSERT (
DeviceUsageTypeUndefined != UsageType);
00457
00458 DumpStack =
ExAllocatePoolWithTag (
00459
NonPagedPool,
00460
sizeof (
DUMP_STACK_CONTEXT) +
sizeof (DUMP_POINTERS),
00461 'pmuD'
00462 );
00463
00464
if (!DumpStack) {
00465
return STATUS_INSUFFICIENT_RESOURCES;
00466 }
00467
00468 RtlZeroMemory(DumpStack,
sizeof(DUMP_STACK_CONTEXT)+
sizeof(DUMP_POINTERS));
00469 DumpInit = &DumpStack->Init;
00470 DumpPointers = (PDUMP_POINTERS) (DumpStack + 1);
00471 DumpStack->DumpPointers = DumpPointers;
00472 InitializeListHead (&DumpStack->DriverList);
00473 DumpName =
NULL;
00474
00475
00476
00477
00478
00479
Buffer =
ExAllocatePoolWithTag (
PagedPool,
PAGE_SIZE, 'pmuD');
00480
if (!
Buffer) {
00481
ExFreePool (DumpStack);
00482
return STATUS_INSUFFICIENT_RESOURCES;
00483 }
00484
00485
if (!
KeGetBugMessageText(BUGCODE_PSS_CRASH_INIT, &DumpStack->InitMsg) ||
00486 !
KeGetBugMessageText(BUGCODE_PSS_CRASH_PROGRESS, &DumpStack->ProgMsg) ||
00487 !
KeGetBugMessageText(BUGCODE_PSS_CRASH_DONE, &DumpStack->DoneMsg)) {
00488
Status = STATUS_UNSUCCESSFUL;
00489
goto Done;
00490 }
00491
00492 InitializeObjectAttributes(
00493 &
ObjectAttributes,
00494 pUniDeviceName,
00495 0,
00496
NULL,
00497
NULL
00498 );
00499
00500
Status =
ZwOpenFile(
00501 &DeviceHandle,
00502 FILE_READ_DATA | SYNCHRONIZE,
00503 &
ObjectAttributes,
00504 &IoStatus,
00505 FILE_SHARE_READ | FILE_SHARE_WRITE,
00506 FILE_NON_DIRECTORY_FILE
00507 );
00508
00509
if (!
NT_SUCCESS(
Status)) {
00510
IoDebugPrint ((0,
00511
"IODUMP: Could not open boot device partition, %s\n",
00512
Buffer
00513 ));
00514
goto Done;
00515 }
00516
00517
00518
00519
00520
00521
Status = ZwDeviceIoControlFile (
00522 DeviceHandle,
00523
NULL,
00524
NULL,
00525
NULL,
00526 &IoStatus,
00527 IOCTL_SCSI_GET_ADDRESS,
00528
NULL,
00529 0,
00530 &ScsiAddress,
00531
sizeof( SCSI_ADDRESS )
00532 );
00533
00534
if (
Status == STATUS_PENDING) {
00535 ZwWaitForSingleObject (
00536 DeviceHandle,
00537
FALSE,
00538
NULL
00539 );
00540
00541
Status = IoStatus.Status;
00542 }
00543
00544 ScsiDump = (BOOLEAN) (
NT_SUCCESS(
Status));
00545
00546
00547
00548
00549
00550 DumpInit->
TargetAddress =
NULL;
00551
00552
if (ScsiDump) {
00553
00554 DumpInit->
TargetAddress =
ExAllocatePoolWithTag (
00555
NonPagedPool,
00556
sizeof (SCSI_ADDRESS),
00557 'pmuD'
00558 );
00559
00560
00561
00562
00563
00564
if (DumpInit->
TargetAddress) {
00565 RtlCopyMemory(DumpInit->
TargetAddress,&ScsiAddress,
sizeof(SCSI_ADDRESS));
00566 }
00567 }
00568
00569
00570
00571
00572
00573
00574
Status = ZwDeviceIoControlFile(
00575 DeviceHandle,
00576
NULL,
00577
NULL,
00578
NULL,
00579 &IoStatus,
00580 IOCTL_DISK_GET_PARTITION_INFO,
00581
NULL,
00582 0,
00583 &PartitionInfo,
00584
sizeof( PARTITION_INFORMATION )
00585 );
00586
00587
if (
Status == STATUS_PENDING) {
00588 ZwWaitForSingleObject (
00589 DeviceHandle,
00590
FALSE,
00591
NULL
00592 );
00593
00594
Status = IoStatus.Status;
00595 }
00596
00597
IoDebugPrint((2,
"Partition Type = %x\n",PartitionInfo.PartitionType));
00598
IoDebugPrint((2,
"Boot Indicator = %x\n",PartitionInfo.BootIndicator));
00599
00600
Status = ZwDeviceIoControlFile(
00601 DeviceHandle,
00602
NULL,
00603
NULL,
00604
NULL,
00605 &IoStatus,
00606 IOCTL_DISK_GET_DRIVE_LAYOUT,
00607
NULL,
00608 0,
00609
Buffer,
00610
PAGE_SIZE
00611 );
00612
00613
if (
Status == STATUS_PENDING) {
00614 ZwWaitForSingleObject (
00615 DeviceHandle,
00616
FALSE,
00617
NULL
00618 );
00619
00620
Status = IoStatus.Status;
00621 }
00622
00623 DumpInit->
DiskSignature = ((PDRIVE_LAYOUT_INFORMATION)
Buffer)->Signature;
00624
00625
00626
00627
00628
00629
00630
00631
00632
ObReferenceObjectByHandle (
00633 DeviceHandle,
00634 0,
00635
IoFileObjectType,
00636
KernelMode,
00637 (PVOID *) &FileObject,
00638
NULL
00639 );
00640
00641
00642 DeviceObject =
IoGetRelatedDeviceObject (FileObject);
00643
00644
KeInitializeEvent( &
Event, NotificationEvent,
FALSE );
00645
00646
Irp =
IoBuildDeviceIoControlRequest(
00647 IOCTL_SCSI_GET_DUMP_POINTERS,
00648 DeviceObject,
00649
NULL,
00650 0,
00651 DumpPointers,
00652
sizeof (DUMP_POINTERS),
00653
FALSE,
00654 &
Event,
00655 &IoStatus
00656 );
00657
00658
if (!
Irp) {
00659
ObDereferenceObject (FileObject);
00660 ZwClose (DeviceHandle);
00661
Status = STATUS_INSUFFICIENT_RESOURCES;
00662
goto Done;
00663 }
00664
00665 IrpSp =
IoGetNextIrpStackLocation (
Irp);
00666
00667 IrpSp->
FileObject = FileObject;
00668
00669
Status =
IoCallDriver( DeviceObject,
Irp );
00670
00671
if (
Status == STATUS_PENDING) {
00672
KeWaitForSingleObject(&
Event,
Executive,
KernelMode,
FALSE,
NULL);
00673
Status = IoStatus.Status;
00674 }
00675
00676
if (!
NT_SUCCESS(
Status) || IoStatus.Information < FIELD_OFFSET(DUMP_POINTERS, DeviceObject)) {
00677
00678
IoDebugPrint ((0,
00679
"IODUMP: Could not get dump pointers; error = %x, length %x\n",
00680
Status,
00681 IoStatus.Information
00682 ));
00683
ObDereferenceObject (FileObject);
00684
00685 ZwClose (DeviceHandle);
00686
goto Done;
00687 }
00688 DumpStack->PointersLength = (ULONG) IoStatus.Information;
00689
00690
00691
00692
00693
00694
00695 DeviceObject = (
PDEVICE_OBJECT) DumpPointers->DeviceObject;
00696
if (DeviceObject) {
00697 DriverObject = DeviceObject->
DriverObject;
00698
00699
00700
00701
00702
00703
00704 DumpName = DriverObject->
DriverName.Buffer;
00705
while ( NameOffset = wcsstr( DumpName,
L"\\" )) {
00706 DumpName = ++NameOffset;
00707 }
00708
00709 ScsiDump =
FALSE;
00710 }
00711
00712
00713
00714
00715
00716
00717 DumpStack->FileObject = FileObject;
00718 ZwClose (DeviceHandle);
00719
00720
00721
00722
00723
00724 DumpInit->
Length =
sizeof (
INITIALIZATION_CONTEXT);
00725 DumpInit->
StallRoutine = &
KeStallExecutionProcessor;
00726 DumpInit->
AdapterObject = DumpPointers->AdapterObject;
00727 DumpInit->
MappedRegisterBase = DumpPointers->MappedRegisterBase;
00728 DumpInit->
PortConfiguration = DumpPointers->DumpData;
00729
00730 DumpStack->ModulePrefix = ModulePrefix;
00731 DumpStack->PartitionOffset = PartitionInfo.StartingOffset;
00732 DumpStack->UsageType =
DeviceUsageTypeUndefined;
00733
00734
00735
00736
00737
00738
if (DumpPointers->CommonBufferSize <
IO_DUMP_COMMON_BUFFER_SIZE) {
00739 DumpPointers->CommonBufferSize =
IO_DUMP_COMMON_BUFFER_SIZE;
00740 }
00741 DumpInit->
CommonBufferSize = DumpPointers->CommonBufferSize;
00742
00743
00744
00745
00746
00747
if (DumpPointers->AllocateCommonBuffers) {
00748 pa.QuadPart = 0x1000000 - 1;
00749
for (i=0; i < 2; i++) {
00750
if (DumpInit->
AdapterObject) {
00751
00752
#if !defined(NO_LEGACY_DRIVERS)
00753
p1 =
HalAllocateCommonBuffer(
00754 DumpInit->
AdapterObject,
00755 DumpPointers->CommonBufferSize,
00756 &pa,
00757
FALSE
00758 );
00759
00760
#else
00761
p1 = (*((
PDMA_ADAPTER)DumpInit->
AdapterObject)->DmaOperations->
00762 AllocateCommonBuffer)(
00763 (
PDMA_ADAPTER)DumpInit->
AdapterObject,
00764 DumpPointers->CommonBufferSize,
00765 &pa,
00766
FALSE
00767 );
00768
00769
#endif // NO_LEGACY_DRIVERS
00770
00771 }
else {
00772 p1 =
MmAllocateContiguousMemory (
00773 DumpPointers->CommonBufferSize,
00774 pa
00775 );
00776
00777
if (!p1) {
00778 p1 =
MmAllocateNonCachedMemory (DumpPointers->CommonBufferSize);
00779 }
00780 pa =
MmGetPhysicalAddress(p1);
00781 }
00782
00783
if (!p1) {
00784
IoDebugPrint ((0,
"IODUMP: Could not allocate common buffers for dump\n"));
00785
Status = STATUS_INSUFFICIENT_RESOURCES;
00786
goto Done;
00787 }
00788
00789 DumpInit->
CommonBuffer[i] = p1;
00790 DumpInit->
PhysicalAddress[i] = pa;
00791 }
00792 }
00793
00794
00795
00796
00797
00798
if (ScsiDump) {
00799
00800
00801
00802
00803
00804
00805
Status =
IopLoadDumpDriver (
00806 DumpStack,
00807 pDumpDriverName,
00808
SCSIPORT_DRIVER_NAME
00809 );
00810
00811
if (!
NT_SUCCESS(
Status)) {
00812
00813
IopLogErrorEvent(0,9,STATUS_SUCCESS,IO_DUMP_DRIVER_LOAD_FAILURE,0,
NULL,0,
NULL);
00814
goto Done;
00815 }
00816
00817
00818
00819
00820
00821
00822 DriverName.Length = 0;
00823 DriverName.Buffer = (PVOID)
Buffer;
00824 DriverName.MaximumLength =
PAGE_SIZE;
00825
00826
00827
00828
00829
00830
00831
00832
sprintf(
Buffer,
"\\Device\\ScsiPort%d", ScsiAddress.PortNumber );
00833
RtlInitAnsiString( &AnsiString,
Buffer );
00834
RtlAnsiStringToUnicodeString( &TempName, &AnsiString,
TRUE );
00835 InitializeObjectAttributes(
00836 &
ObjectAttributes,
00837 &TempName,
00838 0,
00839
NULL,
00840
NULL
00841 );
00842
00843
Status =
ZwOpenFile(
00844 &DeviceHandle,
00845 FILE_READ_ATTRIBUTES,
00846 &
ObjectAttributes,
00847 &IoStatus,
00848 FILE_SHARE_READ | FILE_SHARE_WRITE,
00849 FILE_NON_DIRECTORY_FILE
00850 );
00851
00852
RtlFreeUnicodeString( &TempName );
00853
if (!
NT_SUCCESS(
Status )) {
00854
IoDebugPrint ((0,
00855
"IODUMP: Could not open SCSI port %d, error = %x\n",
00856 ScsiAddress.PortNumber,
00857
Status
00858 ));
00859
goto Done;
00860 }
00861
00862
00863
00864
00865
00866
00867
ObReferenceObjectByHandle(
00868 DeviceHandle,
00869 0,
00870
IoFileObjectType,
00871
KernelMode,
00872 (PVOID *) &FileObject,
00873
NULL
00874 );
00875
00876 DriverObject = FileObject->
DeviceObject->
DriverObject;
00877
ObDereferenceObject( FileObject );
00878 ZwClose( DeviceHandle );
00879
00880
00881
00882
00883
00884 DumpName = DriverObject->
DriverName.Buffer;
00885
while ( NameOffset = wcsstr( DumpName,
L"\\" )) {
00886 DumpName = ++NameOffset;
00887 }
00888 }
00889
00890
00891
00892
00893
00894
if (!DumpName) {
00895
Status = STATUS_NOT_SUPPORTED;
00896
goto Done;
00897 }
00898
00899 swprintf ((PWCHAR)
Buffer,
L"\\SystemRoot\\System32\\Drivers\\%s.sys", DumpName);
00900
Status =
IopLoadDumpDriver (
00901 DumpStack,
00902 (PWCHAR)
Buffer,
00903
NULL
00904 );
00905
if (!
NT_SUCCESS(
Status)) {
00906
00907
IopLogErrorEvent(0,10,STATUS_SUCCESS,IO_DUMP_DRIVER_LOAD_FAILURE,0,
NULL,0,
NULL);
00908
goto Done;
00909 }
00910
00911
00912
00913
00914
00915 FileObject = DumpStack->FileObject;
00916 DeviceObject =
IoGetRelatedDeviceObject (FileObject);
00917
00918 RtlZeroMemory (&irpSp,
sizeof (
IO_STACK_LOCATION));
00919
00920 irpSp.
MajorFunction =
IRP_MJ_PNP;
00921 irpSp.
MinorFunction =
IRP_MN_DEVICE_USAGE_NOTIFICATION;
00922 irpSp.
Parameters.UsageNotification.Type = UsageType;
00923 irpSp.
Parameters.UsageNotification.InPath =
TRUE;
00924 irpSp.
FileObject = FileObject;
00925
00926
Status =
IopSynchronousCall (DeviceObject, &irpSp, (
VOID **) &information);
00927
ASSERT (0 == information);
00928
00929
if (!
NT_SUCCESS(
Status) && IgnoreDeviceUsageFailure) {
00930
IoDebugPrint ((0,
00931
"IopGetDumpStack: DEVICE_USAGE_NOTIFICATION "
00932
"Error ignored (%x)\n",
00933
Status));
00934
Status = STATUS_SUCCESS;
00935 }
00936
00937
if (
NT_SUCCESS(
Status)) {
00938 DumpStack->UsageType = UsageType;
00939 }
00940
00941 Done:
00942
if (
NT_SUCCESS(
Status)) {
00943 *pDumpStack = DumpStack;
00944 }
else {
00945
IoFreeDumpStack (DumpStack);
00946 }
00947
ExFreePool (
Buffer);
00948
return Status;
00949 }
00950
00951
00952
00953
NTSTATUS
00954 IopLoadDumpDriver (
00955 IN OUT PDUMP_STACK_CONTEXT DumpStack,
00956 IN PWCHAR DriverNameString,
00957 IN PWCHAR NewBaseNameString OPTIONAL
00958 )
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 {
00980
NTSTATUS Status;
00981
PDUMP_STACK_IMAGE DumpImage;
00982 PLDR_DATA_TABLE_ENTRY ImageLdrInfo;
00983 UNICODE_STRING DriverName;
00984 UNICODE_STRING
BaseName;
00985 UNICODE_STRING Prefix;
00986 PUNICODE_STRING LoadBaseName;
00987
00988
00989
00990
00991
00992 DumpImage =
ExAllocatePoolWithTag (
00993
NonPagedPool,
00994
sizeof (
DUMP_STACK_IMAGE),
00995 'pmuD'
00996 );
00997
00998
if (!DumpImage) {
00999
return STATUS_INSUFFICIENT_RESOURCES;
01000 }
01001
01002
01003
01004
01005
01006
RtlInitUnicodeString (&DriverName, DriverNameString);
01007
RtlInitUnicodeString (&Prefix, DumpStack->ModulePrefix);
01008 LoadBaseName =
NULL;
01009
if (NewBaseNameString) {
01010 LoadBaseName = &
BaseName;
01011
RtlInitUnicodeString (&
BaseName, NewBaseNameString);
01012
BaseName.MaximumLength = Prefix.Length +
BaseName.Length;
01013
BaseName.Buffer =
ExAllocatePoolWithTag (
01014
NonPagedPool,
01015
BaseName.MaximumLength,
01016 'pmuD'
01017 );
01018
01019
01020
if (!
BaseName.Buffer) {
01021
ExFreePool (DumpImage);
01022
return STATUS_INSUFFICIENT_RESOURCES;
01023 }
01024
01025
BaseName.Length = 0;
01026
RtlAppendUnicodeStringToString (&
BaseName, &Prefix);
01027
RtlAppendUnicodeToString (&
BaseName, NewBaseNameString);
01028 }
01029
01030
Status =
MmLoadAndLockSystemImage(
01031 &DriverName,
01032 &Prefix,
01033 LoadBaseName,
01034 &DumpImage->Image,
01035 &DumpImage->ImageBase
01036 );
01037
01038
if (NewBaseNameString) {
01039
ExFreePool (
BaseName.Buffer);
01040 }
01041
01042
if (!
NT_SUCCESS (
Status)) {
01043
IoDebugPrint ((0,
01044
"IODUMP: Could not load %wZ; error = %x\n",
01045 &DriverName,
01046
Status));
01047
ExFreePool (DumpImage);
01048
return Status;
01049 }
01050
01051
01052
01053
01054
01055 DumpImage->SizeOfImage = DumpImage->Image->SizeOfImage;
01056 InsertTailList (&DumpStack->DriverList, &DumpImage->Link);
01057
return STATUS_SUCCESS;
01058 }
01059
01060
01061 ULONG
01062 IopGetDumpControlBlockCheck (
01063 IN
PDUMP_CONTROL_BLOCK Dcb
01064 )
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 {
01081 ULONG Check;
01082 PLIST_ENTRY Link;
01083
PDUMP_STACK_IMAGE DumpImage;
01084 PMAPPED_ADDRESS MappedAddress;
01085
PDUMP_STACK_CONTEXT DumpStack;
01086
01087
01088
01089
01090
01091
01092 Check =
PoSimpleCheck(0, Dcb,
sizeof(
DUMP_CONTROL_BLOCK));
01093 Check =
PoSimpleCheck(
01094 Check,
01095 Dcb->MemoryDescriptor,
01096 Dcb->MemoryDescriptorLength
01097 );
01098
01099 Check =
PoSimpleCheck(Check, Dcb->FileDescriptorArray, Dcb->FileDescriptorSize);
01100
01101 DumpStack = Dcb->DumpStack;
01102
if (DumpStack) {
01103
01104
01105
01106
01107
01108 Check =
PoSimpleCheck(Check, DumpStack,
sizeof(
DUMP_STACK_CONTEXT));
01109 Check =
PoSimpleCheck(Check, DumpStack->DumpPointers, DumpStack->PointersLength);
01110
01111
for (Link = DumpStack->DriverList.Flink;
01112 Link != &DumpStack->DriverList;
01113 Link = Link->Flink) {
01114
01115 DumpImage = CONTAINING_RECORD(Link,
DUMP_STACK_IMAGE, Link);
01116 Check =
PoSimpleCheck(Check, DumpImage,
sizeof(
DUMP_STACK_IMAGE));
01117 Check =
PoSimpleCheck(Check, DumpImage->ImageBase, DumpImage->SizeOfImage);
01118 }
01119
01120
01121
01122
01123
01124
01125
if (DumpStack->Init.MappedRegisterBase !=
NULL) {
01126 MappedAddress = *(PMAPPED_ADDRESS *)DumpStack->Init.MappedRegisterBase;
01127 }
else {
01128 MappedAddress =
NULL;
01129 }
01130
01131
while (MappedAddress) {
01132 Check =
PoSimpleCheck (Check, MappedAddress,
sizeof(MAPPED_ADDRESS));
01133 MappedAddress = MappedAddress->NextMappedAddress;
01134 }
01135 }
01136
01137
return Check;
01138 }
01139
01140
01141
NTSTATUS
01142 IoInitializeDumpStack (
01143 IN PDUMP_STACK_CONTEXT DumpStack,
01144 IN PUCHAR MessageBuffer OPTIONAL
01145 )
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 {
01162
01163
PINITIALIZATION_CONTEXT DumpInit;
01164 PLIST_ENTRY Link;
01165 ULONG Check;
01166
NTSTATUS Status;
01167
PDRIVER_INITIALIZE DriverInit;
01168
PDUMP_STACK_IMAGE DumpImage;
01169
01170
01171 DumpInit = &DumpStack->Init;
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
for (Link = DumpStack->DriverList.Flink;
01184 Link != &DumpStack->DriverList;
01185 Link = Link->Flink) {
01186
01187 DumpImage = CONTAINING_RECORD(Link,
DUMP_STACK_IMAGE, Link);
01188
01189
01190
01191
01192
01193
01194 DriverInit = DumpImage->Image->EntryPoint;
01195
Status = DriverInit (
NULL, (PUNICODE_STRING) DumpInit);
01196 DumpInit =
NULL;
01197
01198
if (!
NT_SUCCESS(
Status)) {
01199
IoDebugPrint ((0,
01200
"IODUMP: Unable to initialize driver; error = %x\n",
01201
Status
01202 ));
01203
return Status;
01204 }
01205 }
01206
01207 DumpInit = &DumpStack->Init;
01208
01209
01210
01211
01212
01213
if (MessageBuffer) {
01214
InbvDisplayString (MessageBuffer);
01215 }
01216
01217
01218
01219
01220
01221
01222
01223
if (!DumpInit->
OpenRoutine (DumpStack->PartitionOffset)) {
01224
IoDebugPrint (( 0,
"IODUMP: Could not find/open partition offset\n" ));
01225
return STATUS_UNSUCCESSFUL;
01226 }
01227
01228
return STATUS_SUCCESS;
01229 }
01230
01231
01232
VOID
01233 IoGetDumpHiberRanges (
01234 IN PVOID HiberContext,
01235 IN PDUMP_STACK_CONTEXT DumpStack
01236 )
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 {
01258 PDUMP_POINTERS DumpPointers;
01259
PDUMP_STACK_IMAGE DumpImage;
01260 PLIST_ENTRY Link;
01261
01262 DumpPointers = DumpStack->DumpPointers;
01263
01264
01265
01266
01267
01268
if (DumpPointers->CommonBufferVa) {
01269
PoSetHiberRange (
01270 HiberContext,
01271
PO_MEM_CL_OR_NCHK,
01272 DumpPointers->CommonBufferVa,
01273 DumpPointers->CommonBufferSize,
01274 'fubc'
01275 );
01276 }
01277
01278
01279
01280
01281
01282
for (Link = DumpStack->DriverList.Flink;
01283 Link != &DumpStack->DriverList;
01284 Link = Link->Flink) {
01285
01286 DumpImage = CONTAINING_RECORD(Link,
DUMP_STACK_IMAGE, Link);
01287
01288
PoSetHiberRange (
01289 HiberContext,
01290
PO_MEM_CL_OR_NCHK,
01291 DumpImage->ImageBase,
01292 DumpImage->SizeOfImage,
01293 'gmID'
01294 );
01295 }
01296 }
01297
01298
01299
VOID
01300 IoFreeDumpStack (
01301 IN PDUMP_STACK_CONTEXT DumpStack
01302 )
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318 {
01319
PINITIALIZATION_CONTEXT DumpInit;
01320
PDUMP_STACK_IMAGE DumpImage;
01321
PDEVICE_OBJECT DeviceObject;
01322
PIO_STACK_LOCATION IrpSp;
01323 IO_STATUS_BLOCK IoStatus;
01324
PIRP Irp;
01325
KEVENT Event;
01326
NTSTATUS Status;
01327 ULONG i;
01328
PFILE_OBJECT FileObject;
01329
IO_STACK_LOCATION irpSp;
01330 ULONG information;
01331
01332
PAGED_CODE();
01333 DumpInit = &DumpStack->Init;
01334
01335
01336
01337
01338
01339 FileObject = DumpStack->FileObject;
01340
if (FileObject) {
01341 DeviceObject =
IoGetRelatedDeviceObject (FileObject);
01342
01343 RtlZeroMemory (&irpSp,
sizeof (
IO_STACK_LOCATION));
01344
01345 irpSp.
MajorFunction =
IRP_MJ_PNP;
01346 irpSp.
MinorFunction =
IRP_MN_DEVICE_USAGE_NOTIFICATION;
01347 irpSp.
Parameters.UsageNotification.Type = DumpStack->UsageType;
01348 irpSp.
Parameters.UsageNotification.InPath =
FALSE;
01349 irpSp.
FileObject = FileObject;
01350
01351
if (
DeviceUsageTypeUndefined != DumpStack->UsageType) {
01352
Status =
IopSynchronousCall (DeviceObject, &irpSp, (
VOID **) &information);
01353
ASSERT (0 == information);
01354 }
else {
01355
Status = STATUS_SUCCESS;
01356 }
01357 }
01358
01359
01360
01361
01362
01363
for (i=0; i < 2; i++) {
01364
if (DumpInit->
CommonBuffer[i]) {
01365
if (DumpInit->
AdapterObject) {
01366
01367
#if !defined(NO_LEGACY_DRIVERS)
01368
HalFreeCommonBuffer (
01369 DumpInit->
AdapterObject,
01370 ((PDUMP_POINTERS)DumpStack->DumpPointers)->CommonBufferSize,
01371 DumpInit->
PhysicalAddress[i],
01372 DumpInit->
CommonBuffer[i],
01373
FALSE
01374 );
01375
#else
01376
(*((
PDMA_ADAPTER)DumpInit->
AdapterObject)->DmaOperations->
01377 FreeCommonBuffer )(
01378 (
PDMA_ADAPTER)DumpInit->
AdapterObject,
01379 ((PDUMP_POINTERS)DumpStack->DumpPointers)->CommonBufferSize,
01380 DumpInit->
PhysicalAddress[i],
01381 DumpInit->
CommonBuffer[i],
01382
FALSE
01383 );
01384
01385
#endif // NO_LEGACY_DRIVERS
01386
01387
01388 }
else {
01389
MmFreeContiguousMemory (DumpInit->
CommonBuffer[i]);
01390 }
01391 }
01392 DumpInit->
CommonBuffer[i] =
NULL;
01393 }
01394
01395
01396
01397
01398
01399
while (!IsListEmpty(&DumpStack->DriverList)) {
01400 DumpImage = CONTAINING_RECORD(DumpStack->DriverList.Blink,
DUMP_STACK_IMAGE, Link);
01401 RemoveEntryList (&DumpImage->Link);
01402
MmUnloadSystemImage (DumpImage->Image);
01403
ExFreePool (DumpImage);
01404 }
01405
01406
01407
01408
01409
01410
if (DumpStack->FileObject) {
01411 DeviceObject =
IoGetRelatedDeviceObject ((
PFILE_OBJECT) DumpStack->FileObject);
01412
01413
KeInitializeEvent( &
Event, NotificationEvent,
FALSE );
01414
Irp =
IoBuildDeviceIoControlRequest(
01415 IOCTL_SCSI_FREE_DUMP_POINTERS,
01416 DeviceObject,
01417 DumpStack->DumpPointers,
01418 sizeof (DUMP_POINTERS),
01419
NULL,
01420 0,
01421
FALSE,
01422 &
Event,
01423 &IoStatus
01424 );
01425
01426 IrpSp =
IoGetNextIrpStackLocation (
Irp);
01427 IrpSp->
FileObject = DumpStack->FileObject;
01428
01429
Status =
IoCallDriver( DeviceObject,
Irp );
01430
01431
if (
Status == STATUS_PENDING) {
01432
KeWaitForSingleObject(&
Event,
Executive,
KernelMode,
FALSE,
NULL);
01433
Status = IoStatus.Status;
01434 }
01435
ObDereferenceObject( DumpStack->FileObject );
01436 }
01437
01438
01439
01440
if (DumpStack->Init.TargetAddress) {
01441
ExFreePool( DumpStack->Init.TargetAddress);
01442 }
01443
01444
01445
01446
01447
ExFreePool (DumpStack);
01448 }
01449
01450
01451
NTSTATUS
01452 IopInitializeDumpSpaceAndType(
01453 IN
PDUMP_CONTROL_BLOCK dcb,
01454 IN OUT PULONG block,
01455 IN PSUMMARY_DUMP_HEADER pSummaryHeader
01456 )
01457 {
01458 LARGE_INTEGER
Space;
01459
01460
Space.QuadPart = 0;
01461
01462
if (dcb->Flags &
DCB_TRIAGE_DUMP_ENABLED) {
01463
01464
01465
01466
01467
01468 block [ DH_DUMP_TYPE ] = DUMP_TYPE_TRIAGE;
01469
Space.QuadPart = TRIAGE_DUMP_SIZE;
01470
01471
01472 }
else if (dcb->Flags &
DCB_SUMMARY_DUMP_ENABLED) {
01473
01474 block [ DH_DUMP_TYPE ] = DUMP_TYPE_SUMMARY;
01475
01476
Space =
IopCalculateRequiredDumpSpace(
01477 dcb->Flags,
01478 dcb->HeaderSize,
01479 dcb->MemoryDescriptor->NumberOfPages,
01480 pSummaryHeader->Pages
01481 );
01482 }
else {
01483
01484
if (dcb->Flags &
DCB_DUMP_HEADER_ENABLED) {
01485 block [ DH_DUMP_TYPE ] = DUMP_TYPE_HEADER;
01486 }
01487
01488
Space =
IopCalculateRequiredDumpSpace(
01489 dcb->Flags,
01490 dcb->HeaderSize,
01491 dcb->MemoryDescriptor->NumberOfPages,
01492 dcb->MemoryDescriptor->NumberOfPages
01493 );
01494 }
01495
01496
01497
01498
01499
01500
01501
if (
Space.QuadPart > dcb->DumpFileSize.QuadPart) {
01502
Space.QuadPart = dcb->DumpFileSize.QuadPart;
01503 }
01504
01505 block [ DH_REQUIRED_DUMP_SPACE ] =
Space.LowPart;
01506 block [ DH_REQUIRED_DUMP_SPACE + 1 ] =
Space.HighPart;
01507
01508
IoDebugPrint((2,
"IODUMP: dcb File Size %x Block Size %x\n",
01509 block [DH_REQUIRED_DUMP_SPACE],
01510 (ULONG)dcb->DumpFileSize.LowPart
01511 ));
01512
01513
return STATUS_SUCCESS;
01514 }
01515
01516
01517
01518 BOOLEAN
01519 IoWriteCrashDump(
01520 IN ULONG BugCheckCode,
01521 IN ULONG_PTR BugCheckParameter1,
01522 IN ULONG_PTR BugCheckParameter2,
01523 IN ULONG_PTR BugCheckParameter3,
01524 IN ULONG_PTR BugCheckParameter4,
01525 IN PVOID ContextSave
01526 )
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545 {
01546
PDUMP_CONTROL_BLOCK dcb;
01547
PDUMP_STACK_CONTEXT dumpStack;
01548
PDUMP_DRIVER_WRITE write;
01549
PDUMP_DRIVER_FINISH finishUp;
01550 PDUMP_HEADER header;
01551 EXCEPTION_RECORD exception;
01552 PCONTEXT context = ContextSave;
01553 PULONG block;
01554 LARGE_INTEGER diskByteOffset;
01555 PPFN_NUMBER page;
01556 PFN_NUMBER localMdl[(
sizeof(
MDL )/
sizeof(PFN_NUMBER)) + 17];
01557
PMDL mdl;
01558 PLARGE_INTEGER mcb;
01559 ULONG_PTR memoryAddress;
01560 ULONG byteOffset;
01561 ULONG byteCount;
01562 ULONG bytesRemaining;
01563
NTSTATUS status;
01564 UCHAR messageBuffer[128];
01565 PFN_NUMBER ActualPages;
01566 PSUMMARY_DUMP_HEADER pSummaryHeader;
01567 ULONG dwTransferSize;
01568 LARGE_INTEGER requiredDumpSpace;
01569 ULONG_PTR DirBasePage;
01570
01571
01572
01573
01574
01575
01576
01577 dcb =
IopDumpControlBlock;
01578
if (!dcb) {
01579
return FALSE;
01580 }
01581
01582
if (dcb->
Flags &
DCB_DUMP_ENABLED || dcb->
Flags &
DCB_SUMMARY_ENABLED) {
01583
01584
IopFinalCrashDumpStatus = STATUS_PENDING;
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
if (
IopGetDumpControlBlockCheck(dcb) !=
IopDumpControlBlockChecksum) {
01595
IoDebugPrint (( 0,
01596
"CRASHDUMP: Disk dump routine returning due to DCB integrity error\n"
01597
" No dump will be created\n" ));
01598
IopFinalCrashDumpStatus = STATUS_UNSUCCESSFUL;
01599
return FALSE;
01600 }
01601
01602
01603
01604
01605
01606 dumpStack = dcb->
DumpStack;
01607
sprintf( messageBuffer,
"%Z\n", &dumpStack->InitMsg );
01608
01609
01610
01611
01612
01613 status =
IoInitializeDumpStack (dumpStack, messageBuffer);
01614
if (!
NT_SUCCESS( status )) {
01615
IopFinalCrashDumpStatus = STATUS_UNSUCCESSFUL;
01616
return FALSE;
01617 }
01618
01619
01620
01621
01622
01623 write = dumpStack->Init.WriteRoutine;
01624 finishUp = dumpStack->Init.FinishRoutine;
01625
01626
01627 dwTransferSize = dumpStack->Init.MaximumTransferSize;
01628
01629
if ( ( !dwTransferSize ) || ( dwTransferSize >
IO_DUMP_MAXIMUM_TRANSFER_SIZE ) ) {
01630 dwTransferSize =
IO_DUMP_MINIMUM_TRANSFER_SIZE;
01631 }
01632
01633
IoDebugPrint((2,
"CRASHDUMP: Maximum Transfer Size = %x\n",dwTransferSize));
01634
01635
01636
01637
01638
01639
01640
01641 block = dcb->
HeaderPage;
01642 header = (PDUMP_HEADER) block;
01643
01644 RtlFillMemoryUlong( header,
PAGE_SIZE, 'EGAP' );
01645 header->ValidDump = 'PMUD';
01646 header->BugCheckCode = BugCheckCode;
01647 header->BugCheckParameter1 = BugCheckParameter1;
01648 header->BugCheckParameter2 = BugCheckParameter2;
01649 header->BugCheckParameter3 = BugCheckParameter3;
01650 header->BugCheckParameter4 = BugCheckParameter4;
01651
#if defined (i386)
01652
01653
01654
01655
01656
01657
01658 _asm {
01659 mov eax, cr3
01660 mov DirBasePage, eax
01661 }
01662 header->DirectoryTableBase = DirBasePage;
01663
#else
01664
header->DirectoryTableBase =
KeGetCurrentThread()->ApcState.Process->DirectoryTableBase[0];
01665
#endif
01666
header->PfnDataBase =
MmPfnDatabase;
01667 header->PsLoadedModuleList = &
PsLoadedModuleList;
01668 header->PsActiveProcessHead = &
PsActiveProcessHead;
01669 header->NumberProcessors = dcb->
NumberProcessors;
01670 header->MajorVersion = dcb->
MajorVersion;
01671 header->MinorVersion = dcb->
MinorVersion;
01672 header->KdDebuggerDataBlock =
KdGetDataBlock();
01673 header->PaeEnabled = PaeEnabled ();
01674
01675 header->MachineImageType = CURRENT_IMAGE_TYPE ();
01676
01677
if (!(dcb->
Flags &
DCB_DUMP_ENABLED)) {
01678 dcb->
MemoryDescriptor->
NumberOfPages = 1;
01679 }
01680
01681 strcpy( header->VersionUser, dcb->
VersionUser );
01682
01683 RtlCopyMemory( &block[DH_PHYSICAL_MEMORY_BLOCK],
01684 dcb->
MemoryDescriptor,
01685
sizeof(
PHYSICAL_MEMORY_DESCRIPTOR ) +
01686 ((dcb->
MemoryDescriptor->
NumberOfRuns - 1) *
01687
sizeof(
PHYSICAL_MEMORY_RUN )) );
01688
01689 RtlCopyMemory( &block[DH_CONTEXT_RECORD],
01690 context,
01691
sizeof( CONTEXT ) );
01692
01693 exception.ExceptionCode = STATUS_BREAKPOINT;
01694 exception.ExceptionRecord = (PEXCEPTION_RECORD)
NULL;
01695 exception.NumberParameters = 0;
01696 exception.ExceptionFlags =
EXCEPTION_NONCONTINUABLE;
01697 exception.ExceptionAddress = (PVOID) PROGRAM_COUNTER (context);
01698
01699 RtlCopyMemory( &block[DH_EXCEPTION_RECORD],
01700 &exception,
01701
sizeof( EXCEPTION_RECORD ) );
01702
01703
01704
01705
01706
01707 block[DH_DUMP_TYPE] = DUMP_TYPE_FULL;
01708
01709
01710
01711
01712
#ifdef _WIN64
01713
RtlCopyMemory( &block[DH_CRASH_DUMP_TIMESTAMP],
01714 (PCHAR)( &SharedUserData->SystemLowTime),
01715
sizeof( LARGE_INTEGER) );
01716
#else
01717
RtlCopyMemory( &block[DH_CRASH_DUMP_TIMESTAMP],
01718 (PCHAR)( &SharedUserData->SystemTime),
01719
sizeof( LARGE_INTEGER) );
01720
#endif
01721
01722
01723
01724
01725
01726
01727
01728 RtlZeroMemory( &block[DH_REQUIRED_DUMP_SPACE],
sizeof(LARGE_INTEGER));
01729
01730
if (dcb->
Flags &
DCB_DUMP_ENABLED) {
01731
01732
01733
01734
01735
01736
if ( (dcb->
Flags &
DCB_SUMMARY_DUMP_ENABLED) ) {
01737
01738
01739
01740
01741
01742 pSummaryHeader =
IopInitializeSummaryDump(dcb);
01743
01744
if ( !pSummaryHeader ) {
01745
01746
01747
01748
01749
01750
IoDebugPrint((1,
"IoWriteCrashDump: Error Null summary dump header\n"));
01751
01752
IopFinalCrashDumpStatus = STATUS_UNSUCCESSFUL;
01753
01754
return FALSE;
01755 }
01756 }
01757
01758
IopInitializeDumpSpaceAndType (dcb, block, pSummaryHeader);
01759 }
01760
01761
01762
01763
01764
01765
01766
01767
01768 KeSweepCurrentDcache();
01769 KeSweepCurrentIcache();
01770
01771
01772
01773
01774
01775 mdl = (
PMDL) &localMdl[0];
01776
MmCreateMdl( mdl,
NULL,
PAGE_SIZE );
01777 mdl->
MdlFlags |=
MDL_PAGES_LOCKED;
01778
01779 mcb = dcb->
FileDescriptorArray;
01780
01781 page =
MmGetMdlPfnArray(mdl);
01782 *page = dcb->
HeaderPfn;
01783 mdl->
MdlFlags |=
MDL_MAPPED_TO_SYSTEM_VA;
01784
01785 bytesRemaining =
PAGE_SIZE;
01786 memoryAddress = (ULONG_PTR) dcb->
HeaderPage;
01787
01788
01789
01790
01791
01792
01793
01794
IoDebugPrint((2,
"IoWriteCrashDump: Writing dump header to disk\n"));
01795
01796
while (bytesRemaining) {
01797
01798
if (mcb[0].QuadPart <= bytesRemaining) {
01799 byteCount = mcb[0].LowPart;
01800 }
else {
01801 byteCount = bytesRemaining;
01802 }
01803
01804 mdl->
ByteCount = byteCount;
01805 mdl->
ByteOffset = (ULONG)(memoryAddress & (
PAGE_SIZE - 1));
01806 mdl->
MappedSystemVa = (PVOID) memoryAddress;
01807 mdl->
StartVa =
PAGE_ALIGN ((PVOID)memoryAddress);
01808
01809
01810
01811
01812
01813
if (!
NT_SUCCESS( write( &mcb[1], mdl ) )) {
01814
IopFinalCrashDumpStatus = STATUS_UNSUCCESSFUL;
01815
return FALSE;
01816 }
01817
01818
01819
01820
01821
01822 bytesRemaining -= byteCount;
01823 memoryAddress += byteCount;
01824 mcb[0].QuadPart = mcb[0].QuadPart - byteCount;
01825 mcb[1].QuadPart = mcb[1].QuadPart + byteCount;
01826
01827
if (!mcb[0].QuadPart) {
01828 mcb += 2;
01829 }
01830 }
01831
01832
IoDebugPrint((2,
"IoWriteCrashDump: Header Page written\n"));
01833
01834
01835
01836
01837
01838
01839
if (dcb->
Flags &
DCB_DUMP_HEADER_ENABLED) {
01840
IoDebugPrint((2,
"IoWriteCrashDump: Only Dumping Dump Header\n"));
01841
goto FinishDump;
01842 }
01843
01844
01845
01846
01847
01848
01849
01850
if (dcb->
Flags &
DCB_TRIAGE_DUMP_ENABLED) {
01851 status =
IopWriteTriageDump (dcb->
TriageDumpFlags,
01852 write,
01853 mcb,
01854 mdl,
01855 dwTransferSize,
01856 context,
01857 dcb->
TriageDumpBuffer,
01858 dcb->
TriageDumpBufferSize -
PAGE_SIZE,
01859 dcb->
BuildNumber,
01860 dcb->
Flags
01861 );
01862
01863
if (!
NT_SUCCESS (status)) {
01864
IoDebugPrint((1,
"IoWriteCrashDump: Failed to write triage-dump\n"));
01865
IopFinalCrashDumpStatus = STATUS_UNSUCCESSFUL;
01866
return FALSE;
01867 }
01868
01869
IoDebugPrint((1,
"IoWriteCrashDump: Successfully wrote triage-dump\n"));
01870
goto FinishDump;
01871 }
01872
01873
01874
01875
01876
01877
01878
if (dcb->
Flags &
DCB_DUMP_ENABLED) {
01879
01880 PFN_NUMBER pagesDoneSoFar = 0;
01881 ULONG currentPercentage = 0;
01882 ULONG maximumPercentage = 0;
01883
01884
01885
01886
01887
01888
01889 ActualPages = dcb->
MemoryDescriptor->
NumberOfPages;
01890
01891
if (dcb->
Flags &
DCB_SUMMARY_DUMP_ENABLED) {
01892
01893 PRTL_BITMAP PageMap;
01894
01895
ASSERT ( pSummaryHeader !=
NULL );
01896
01897 PageMap = (PRTL_BITMAP)(pSummaryHeader + 1);
01898
ASSERT (PageMap !=
NULL);
01899
01900
01901
01902
01903
01904
01905 status =
IopWriteSummaryHeader(
01906 pSummaryHeader,
01907 write,
01908 &mcb,
01909 mdl,
01910 dwTransferSize,
01911 (dcb->
HeaderSize -
PAGE_SIZE)
01912 );
01913
01914
if (!
NT_SUCCESS (status)) {
01915
IoDebugPrint((1,
"IoWriteCrashDump: Error writing summary dump header\n"));
01916
IopFinalCrashDumpStatus = status;
01917
return FALSE;
01918 }
01919
01920
IoDebugPrint((2,
"IoWriteCrashDump: Sucessfully wrote summary dump header\n"));
01921
01922 ActualPages = pSummaryHeader->Pages;
01923
01924 }
01925
01926
IoDebugPrint((2,
"IoWriteCrashDump: Writing Memory Dump\n"));
01927
01928
01929
01930
01931
01932
01933 memoryAddress = (ULONG_PTR)dcb->
MemoryDescriptor->
Run[0].
BasePage *
PAGE_SIZE;
01934
01935
if ( dcb->
Flags &
DCB_SUMMARY_DUMP_ENABLED ) {
01936
01937 PRTL_BITMAP
BitMap;
01938
01939
BitMap = (PRTL_BITMAP)(pSummaryHeader+1);
01940
01941 status =
IopWriteSummaryDump (
01942
BitMap,
01943 write,
01944 &dumpStack->ProgMsg,
01945 messageBuffer,
01946 mcb,
01947 dwTransferSize
01948 );
01949
01950
if (!
NT_SUCCESS (status)) {
01951
IoDebugPrint((1,
"IoWriteCrashDump: Failed to write triage-dump\n"));
01952
IopFinalCrashDumpStatus = STATUS_UNSUCCESSFUL;
01953
return FALSE;
01954 }
01955
01956
IoDebugPrint((1,
"IoWriteCrashDump: Successfully wrote triage-dump\n"));
01957
goto FinishDump;
01958 }
01959
01960
01961
01962
01963
01964
while (mcb[0].QuadPart) {
01965
01966 diskByteOffset = mcb[1];
01967
01968
01969
01970
01971
01972 byteOffset = (ULONG)(memoryAddress & (
PAGE_SIZE - 1));
01973
01974
if (dwTransferSize <= mcb[0].QuadPart) {
01975 byteCount = dwTransferSize - byteOffset;
01976 }
else {
01977 byteCount = mcb[0].LowPart;
01978 }
01979 pagesDoneSoFar += byteCount /
PAGE_SIZE;
01980
01981 currentPercentage = (ULONG)((pagesDoneSoFar * 100) /
01982 ActualPages);
01983
01984
if (currentPercentage > maximumPercentage) {
01985
01986 maximumPercentage = currentPercentage;
01987
01988
01989
01990
01991
sprintf( messageBuffer,
"%Z: %3d\r", &dumpStack->ProgMsg, maximumPercentage );
01992
InbvDisplayString( messageBuffer );
01993
01994 }
01995
01996
01997
01998
01999
02000
02001
IopMapPhysicalMemory( mdl,
02002 memoryAddress,
02003 &dcb->
MemoryDescriptor->
Run[0],
02004 byteCount
02005 );
02006
02007
02008
02009
02010
02011
02012
if (!
NT_SUCCESS( write( &diskByteOffset, mdl ) )) {
02013
IopFinalCrashDumpStatus = STATUS_UNSUCCESSFUL;
02014
return FALSE;
02015 }
02016
02017
02018
02019
02020
02021 memoryAddress += byteCount;
02022 mcb[0].QuadPart = mcb[0].QuadPart - byteCount;
02023 mcb[1].QuadPart = mcb[1].QuadPart + byteCount;
02024
02025
if (!mcb[0].QuadPart) {
02026 mcb += 2;
02027 }
02028
02029
if (pagesDoneSoFar >= ActualPages) {
02030
break;
02031
02032 }
02033
02034 }
02035
02036
IoDebugPrint((2,
"IoWriteCrashDump: memory dump written\n"));
02037 }
02038
02039 FinishDump:
02040
02041
sprintf( messageBuffer,
"%Z", &dumpStack->DoneMsg );
02042
InbvDisplayString( messageBuffer );
02043
02044
02045
02046
02047
02048 KeSweepCurrentDcache();
02049 KeSweepCurrentIcache();
02050
02051
02052
02053
02054
02055 finishUp();
02056
02057
02058
02059
02060
02061
02062
IopFinalCrashDumpStatus = STATUS_SUCCESS;
02063 }
02064
02065
02066
02067
02068
02069
02070
if (dcb->
Flags &
DCB_AUTO_REBOOT) {
02071
IoDebugPrint (( 0,
"IODUMP: Autorebooting\n" ));
02072
KeReturnToFirmware(
HalRebootRoutine );
02073 }
02074
02075
return TRUE;
02076 }
02077
02078
02079
02080
VOID
02081 IopMapPhysicalMemory(
02082 IN OUT
PMDL Mdl,
02083 IN ULONG_PTR MemoryAddress,
02084 IN
PPHYSICAL_MEMORY_RUN PhysicalMemoryRun,
02085 IN ULONG Length
02086 )
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112 {
02113
PPHYSICAL_MEMORY_RUN pmr = PhysicalMemoryRun;
02114 PPFN_NUMBER page;
02115 PFN_NUMBER pages;
02116 PFN_NUMBER base;
02117 PFN_NUMBER currentBase;
02118
02119
02120
02121
02122
02123 Mdl->StartVa =
PAGE_ALIGN( (PVOID) (MemoryAddress) );
02124 Mdl->ByteOffset = (ULONG)(MemoryAddress & (
PAGE_SIZE - 1));
02125 Mdl->ByteCount = Length;
02126
02127
02128
02129
02130
02131 base = (PFN_NUMBER) ((ULONG_PTR)(Mdl->StartVa) >>
PAGE_SHIFT);
02132 pages =
COMPUTE_PAGES_SPANNED(MemoryAddress, Length);
02133 currentBase = pmr->
BasePage;
02134 page =
MmGetMdlPfnArray(Mdl);
02135
02136
02137
02138
02139
02140
02141
while (pages) {
02142
02143
02144
02145
02146
02147
while (currentBase + pmr->
PageCount <= base) {
02148 currentBase += pmr->
PageCount;
02149 pmr++;
02150 }
02151
02152
02153
02154
02155
02156
02157 *page++ = pmr->
BasePage + (PFN_NUMBER)(base++ - currentBase);
02158 pages--;
02159 }
02160
02161
02162
02163
02164
02165
02166
MmMapMemoryDumpMdl( Mdl );
02167 }
02168
02169
02170
02171
VOID
02172 IopAddPageToPageMap(
02173 IN ULONG dwMaxPage,
02174 IN PRTL_BITMAP pBitMapHeader,
02175 IN ULONG dwPageFrameIndex,
02176 IN ULONG dwNumberOfPages
02177 )
02178 {
02179
02180
02181
02182
02183
if (dwPageFrameIndex >= dwMaxPage) {
02184
return;
02185 }
02186
02187
RtlSetBits (pBitMapHeader, dwPageFrameIndex, dwNumberOfPages);
02188 }
02189
02190
02191
02192
VOID
02193 IopRemovePageFromPageMap(
02194 IN ULONG dwMaxPage,
02195 IN PRTL_BITMAP pBitMapHeader,
02196 IN ULONG dwPageFrameIndex,
02197 IN ULONG dwNumberOfPages
02198 )
02199 {
02200
02201
02202
02203
02204
if (dwPageFrameIndex >= dwMaxPage) {
02205
return;
02206 }
02207
02208
IoDebugPrint( (6,
"RtlClearBits max:%x pfn:%x, pages:%x\n",(dwMaxPage), (dwPageFrameIndex), (dwNumberOfPages) )); \
02209
RtlClearBits (pBitMapHeader, dwPageFrameIndex, dwNumberOfPages);
02210
02211 }
02212
02213
02214
02215
NTKERNELAPI
02216
NTSTATUS
02217 IoGetCrashDumpInformation(
02218 OUT PSYSTEM_CRASH_DUMP_INFORMATION pCrashDumpInfo
02219 )
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241 {
02242
02243
if (!
IopDumpControlBlock) {
02244
return STATUS_NOT_FOUND;
02245 }
02246
02247
02248
02249
02250
02251
02252 pCrashDumpInfo->hDumpSection =
NULL;
02253
return STATUS_SUCCESS;
02254 }
02255
02256
02257
02258
NTKERNELAPI
02259
NTSTATUS
02260 IoGetCrashDumpStateInformation(
02261 OUT PSYSTEM_CRASH_STATE_INFORMATION pCrashDumpState
02262 )
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283 {
02284 pCrashDumpState->ValidDirectDump =
FALSE;
02285
02286
return STATUS_SUCCESS;
02287 }
02288
02289
02290
NTSTATUS
02291 IoSetDumpRange(
02292 IN PVOID DumpContext,
02293 IN PVOID StartVa,
02294 IN ULONG_PTR Pages,
02295 IN BOOLEAN IsPhysicalAddress
02296 )
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321 {
02322 PCHAR Va;
02323 PRTL_BITMAP pBitMapHeader;
02324 PHYSICAL_ADDRESS phyAddr;
02325 PSUMMARY_DUMP_HEADER pHeader;
02326 BOOLEAN AllPagesSet;
02327
02328
02329 Va = StartVa;
02330 pHeader = (PSUMMARY_DUMP_HEADER) DumpContext;
02331 pBitMapHeader = (PRTL_BITMAP)(pHeader + 1);
02332 AllPagesSet =
TRUE;
02333
02334
02335
02336
02337
02338
02339
02340
ASSERT(Pages <= MAXULONG);
02341
02342
02343
02344
02345
02346
02347
if (IsPhysicalAddress) {
02348
02349 phyAddr =
MmGetPhysicalAddress (Va);
02350
IopAddPageToPageMap (pHeader->BitmapSize,
02351 pBitMapHeader,
02352 (ULONG)(phyAddr.QuadPart >>
PAGE_SHIFT),
02353 (ULONG) Pages
02354 );
02355
02356 }
else {
02357
02358
02359
02360
02361
02362
while (Pages) {
02363
02364
02365
02366
02367
02368
if (
MmIsAddressValid(Va) ) {
02369
02370
02371
02372
02373
02374 phyAddr =
MmGetPhysicalAddress (Va);
02375
02376
IopAddPageToPageMap (pHeader->BitmapSize,
02377 pBitMapHeader,
02378 (ULONG)(phyAddr.QuadPart >>
PAGE_SHIFT),
02379 1);
02380
02381
if (phyAddr.QuadPart >>
PAGE_SHIFT > pHeader->BitmapSize) {
02382 AllPagesSet =
FALSE;
02383 }
02384 }
02385
02386 Va +=
PAGE_SIZE;
02387 Pages--;
02388 }
02389 }
02390
02391
if (AllPagesSet) {
02392
return STATUS_SUCCESS;
02393 }
02394
02395
return STATUS_INVALID_ADDRESS;
02396 }
02397
02398
02399
NTSTATUS
02400 IoFreeDumpRange(
02401 IN PVOID DumpContext,
02402 IN PVOID StartVa,
02403 IN ULONG_PTR Pages,
02404 IN BOOLEAN IsPhysicalAddress
02405 )
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429 {
02430 PCHAR Va;
02431 PRTL_BITMAP pBitMapHeader;
02432 PHYSICAL_ADDRESS phyAddr;
02433 PSUMMARY_DUMP_HEADER pHeader;
02434
02435
02436
02437
02438
02439 Va = StartVa;
02440 pHeader = (PSUMMARY_DUMP_HEADER)DumpContext;
02441 pBitMapHeader = (PRTL_BITMAP)(pHeader + 1);
02442
02443
02444
02445
02446
02447
02448
02449
ASSERT (Pages <= MAXULONG);
02450
02451
if (IsPhysicalAddress) {
02452
02453 phyAddr =
MmGetPhysicalAddress(Va);
02454
02455
IopRemovePageFromPageMap (pHeader->BitmapSize,
02456 pBitMapHeader,
02457 (ULONG)(phyAddr.QuadPart >>
PAGE_SHIFT),
02458 (ULONG) Pages
02459 );
02460 }
else {
02461
02462
while (Pages) {
02463
02464
02465
02466
02467
02468
if (
MmIsAddressValid (Va) ) {
02469 phyAddr =
MmGetPhysicalAddress (Va);
02470
02471
IoDebugPrint((3,
"IoFreeDumpRange:Va: %x Pages: %x IsPhysical: %x phyAddr %I64x\n",
02472 StartVa,Pages,IsPhysicalAddress, phyAddr.QuadPart));
02473
02474
IopRemovePageFromPageMap (pHeader->BitmapSize,
02475 pBitMapHeader,
02476 (ULONG)(phyAddr.QuadPart >>
PAGE_SHIFT),
02477 1);
02478
02479 }
02480
02481 Va +=
PAGE_SIZE;
02482 Pages--;
02483 }
02484 }
02485
02486
return STATUS_SUCCESS;
02487 }
02488
02489
02490
02491 LARGE_INTEGER
02492 IopCalculateRequiredDumpSpace(
02493 IN ULONG dwDmpFlags,
02494 IN ULONG dwHeaderSize,
02495 IN PFN_NUMBER dwMaxPages,
02496 IN PFN_NUMBER dwMaxSummaryPages
02497 )
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527 {
02528 LARGE_INTEGER maxMemorySize;
02529
02530
02531
02532
02533
02534
if ( (dwDmpFlags &
DCB_DUMP_HEADER_ENABLED) ||
02535 ( !( dwDmpFlags &
DCB_DUMP_ENABLED ) &&
02536 ( dwDmpFlags &
DCB_SUMMARY_ENABLED ) ) ) {
02537
02538 maxMemorySize.QuadPart =
IO_DUMP_MINIMUM_FILE_SIZE;
02539
return maxMemorySize;
02540 }
02541
02542
if (dwDmpFlags &
DCB_TRIAGE_DUMP_ENABLED) {
02543
02544 maxMemorySize.QuadPart = TRIAGE_DUMP_SIZE;
02545
return maxMemorySize;
02546 }
02547
02548
if (dwDmpFlags &
DCB_SUMMARY_DUMP_ENABLED) {
02549 ULONG summaryHeaderSize;
02550 ULONG dwGB;
02551
02552 maxMemorySize.QuadPart = (dwMaxSummaryPages) *
PAGE_SIZE;
02553
02554
02555
02556
02557
02558 dwGB = 1024 * 1024 * 1024;
02559
02560
if (maxMemorySize.QuadPart > (2 * dwGB) ) {
02561
if (
MmVirtualBias) {
02562 maxMemorySize.QuadPart = dwGB;
02563 }
else {
02564 maxMemorySize.QuadPart = (2 * dwGB);
02565 }
02566 }
02567
02568
02569
02570
02571 summaryHeaderSize = (ULONG)
ROUND_TO_PAGES(
02572
sizeof(SUMMARY_DUMP_HEADER) +
02573
sizeof(RTL_BITMAP) +
02574 ( ( (maxMemorySize.QuadPart >>
PAGE_SHIFT ) >> 5 ) << 2 ) +
02575 dwHeaderSize
02576 );
02577
02578 maxMemorySize.QuadPart+= summaryHeaderSize;
02579
02580
return maxMemorySize;
02581
02582 }
02583
02584
02585
02586
02587
02588 maxMemorySize.QuadPart = (dwMaxPages *
PAGE_SIZE) + dwHeaderSize;
02589
02590
return maxMemorySize;
02591
02592 }
02593
02594
02595
02596
02597
02598
02599
02600
02601
NTSTATUS
02602 IopGetLoadedDriverInfo(
02603 OUT ULONG * lpDriverCount,
02604 OUT ULONG * lpSizeOfStringData
02605 )
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628 {
02629 ULONG DriverCount = 0;
02630 ULONG SizeOfStringData = 0;
02631 PLIST_ENTRY NextEntry;
02632 PLDR_DATA_TABLE_ENTRY
DriverEntry;
02633
02634
02635 NextEntry =
PsLoadedModuleList.Flink;
02636
while (NextEntry != &
PsLoadedModuleList) {
02637
02638
DriverEntry = CONTAINING_RECORD (NextEntry,
02639 LDR_DATA_TABLE_ENTRY,
02640 InLoadOrderLinks
02641 );
02642
02643
if (!
IopIsAddressRangeValid (
DriverEntry,
sizeof (*
DriverEntry)) ||
02644 !
IopIsAddressRangeValid (
DriverEntry->BaseDllName.Buffer,
02645
DriverEntry->BaseDllName.Length)) {
02646
02647
return STATUS_UNSUCCESSFUL;
02648 }
02649
02650 DriverCount++;
02651 SizeOfStringData +=
DriverEntry->FullDllName.Length;
02652 NextEntry = NextEntry->Flink;
02653 }
02654
02655 *lpDriverCount = DriverCount;
02656 *lpSizeOfStringData = SizeOfStringData;
02657
02658
return STATUS_SUCCESS;
02659 }
02660
02661 #define DmpPoolStringSize(DumpString)\
02662
(sizeof (DUMP_STRING) + sizeof (WCHAR) * ( DumpString->Length + 1 ))
02663
02664 #define DmpNextPoolString(DumpString) \
02665
(PDUMP_STRING) ( \
02666
ALIGN_UP_POINTER( \
02667
((LPBYTE) DumpString) + DmpPoolStringSize (DumpString), \
02668
ULONGLONG \
02669
) \
02670
)
02671
02672 #define ALIGN_8(_x) ALIGN_UP(_x, DWORDLONG)
02673
02674
02675
#ifndef IndexByByte
02676 #define IndexByByte(Pointer, Index) (&(((BYTE*) (Pointer)) [Index]))
02677
#endif
02678
02679
02680
NTSTATUS
02681 IopWriteDriverList(
02682 IN ULONG_PTR BufferAddress,
02683 IN ULONG BufferSize,
02684 IN ULONG DriverListOffset,
02685 IN ULONG StringPoolOffset
02686 )
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714 {
02715 ULONG i = 0;
02716 PLIST_ENTRY NextEntry;
02717 PLDR_DATA_TABLE_ENTRY
DriverEntry;
02718 PDUMP_DRIVER_ENTRY DumpImageArray;
02719 PDUMP_STRING DumpStringName =
NULL;
02720 PIMAGE_NT_HEADERS NtHeaders;
02721
02722
ASSERT (DriverListOffset != 0);
02723
ASSERT (StringPoolOffset != 0);
02724
02725
02726 DumpImageArray = (PDUMP_DRIVER_ENTRY) (BufferAddress + DriverListOffset);
02727 DumpStringName = (PDUMP_STRING) (BufferAddress + StringPoolOffset);
02728
02729 NextEntry =
PsLoadedModuleList.Flink;
02730
02731
while (NextEntry != &
PsLoadedModuleList) {
02732
02733
DriverEntry = CONTAINING_RECORD (NextEntry,
02734 LDR_DATA_TABLE_ENTRY,
02735 InLoadOrderLinks);
02736
02737
02738
02739
02740
02741
if (!
IopIsAddressRangeValid (
DriverEntry,
sizeof (*
DriverEntry)) ||
02742 !
IopIsAddressRangeValid (
DriverEntry->BaseDllName.Buffer,
02743
DriverEntry->BaseDllName.Length)) {
02744
02745
return STATUS_UNSUCCESSFUL;
02746 }
02747
02748
02749
02750
02751
02752
02753 DumpStringName->Length =
DriverEntry->BaseDllName.Length / 2;
02754 RtlCopyMemory (DumpStringName->Buffer,
02755
DriverEntry->BaseDllName.Buffer,
02756 DumpStringName->Length * sizeof (WCHAR)
02757 );
02758
02759 DumpStringName->Buffer[ DumpStringName->Length ] =
'\000';
02760
02761 RtlCopyMemory (&DumpImageArray [i].LdrEntry,
02762
DriverEntry,
02763
sizeof (DumpImageArray [i].LdrEntry)
02764 );
02765
02766
02767
02768
02769
02770 DumpImageArray[i].LdrEntry.TimeDateStamp = 0;
02771 DumpImageArray[i].LdrEntry.SizeOfImage = 0;
02772
02773
if (
MmDbgReadCheck (
DriverEntry->DllBase ) !=
NULL ) {
02774
02775 NtHeaders =
RtlImageNtHeader (
DriverEntry->DllBase);
02776
ASSERT ( NtHeaders );
02777 DumpImageArray[i].LdrEntry.TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp;
02778 DumpImageArray[i].LdrEntry.SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
02779 }
02780
02781 DumpImageArray [i].DriverNameOffset =
02782 (ULONG)((ULONG_PTR) DumpStringName - BufferAddress);
02783
02784 i++;
02785 DumpStringName =
DmpNextPoolString (DumpStringName);
02786 NextEntry = NextEntry->Flink;
02787 }
02788
02789
return STATUS_SUCCESS;
02790 }
02791
02792
02793
02794
NTSTATUS
02795 IopWriteTriageDump(
02796 IN ULONG Fields,
02797 IN PDUMP_DRIVER_WRITE DriverWriteRoutine,
02798 IN OUT PLARGE_INTEGER Mcb,
02799 IN OUT
PMDL Mdl,
02800 IN ULONG DriverTransferSize,
02801 IN PCONTEXT Context,
02802 IN BYTE* Buffer,
02803 IN ULONG BufferSize,
02804 IN ULONG ServicePackBuild,
02805 IN ULONG TriageOptions
02806 )
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848 {
02849 ULONG SizeOfSection;
02850 ULONG SizeOfStringData;
02851 ULONG DriverCount = 0;
02852
LPVOID Address =
NULL;
02853 ULONG BytesToWrite = 0;
02854 ULONG_PTR BufferAddress = 0;
02855
NTSTATUS Status;
02856 ULONG_PTR
Offset;
02857 ULONG_PTR StartOfStackRegion = 0;
02858 PTRIAGE_DUMP_HEADER TriageDumpHeader =
NULL;
02859 PLDR_DATA_TABLE_ENTRY
DriverEntry =
NULL;
02860 PDUMP_DRIVER_ENTRY DumpImageArray =
NULL;
02861 PDUMP_STRING DumpStringName =
NULL;
02862
PETHREAD Thread =
NULL;
02863
02864
IoDebugPrint ((0,
"[IopWriteTriageDump] BufferSize = %#x ServicePackBuild = %d\n",
02865
BufferSize,
02866 ServicePackBuild));
02867
02868
02869
02870
02871
02872
if (
BufferSize <
sizeof (TRIAGE_DUMP_HEADER) +
sizeof (
DWORD)) {
02873
return STATUS_NO_MEMORY;
02874 }
02875
02876 TriageDumpHeader = (PTRIAGE_DUMP_HEADER)
Buffer;
02877 RtlZeroMemory (TriageDumpHeader,
sizeof (*TriageDumpHeader));
02878
02879
02880
02881
02882
02883 TriageDumpHeader->SizeOfDump =
BufferSize +
PAGE_SIZE;
02884
02885
02886
02887
02888
02889
02890
BufferSize -=
sizeof (
DWORD);
02891 RtlZeroMemory (
IndexByByte (
Buffer,
BufferSize),
sizeof (
DWORD));
02892
02893 TriageDumpHeader->ValidOffset = ( TriageDumpHeader->SizeOfDump -
sizeof (ULONG) );
02894 TriageDumpHeader->ContextOffset = DH_CONTEXT_RECORD *
sizeof (ULONG);
02895 TriageDumpHeader->ExceptionOffset = DH_EXCEPTION_RECORD *
sizeof (ULONG);
02896 TriageDumpHeader->BrokenDriverOffset = 0;
02897 TriageDumpHeader->ServicePackBuild = ServicePackBuild;
02898 TriageDumpHeader->TriageOptions = TriageOptions;
02899
02900
Offset =
ALIGN_8 (
PAGE_SIZE +
sizeof (TRIAGE_DUMP_HEADER));
02901
02902
02903
02904
02905
02906 SizeOfSection =
ALIGN_8 (
MmSizeOfTriageInformation());
02907
02908
if (
Offset + SizeOfSection <
BufferSize) {
02909 TriageDumpHeader->MmOffset = (ULONG)
Offset;
02910
Offset += SizeOfSection;
02911 }
02912
02913
02914
02915
02916
02917 SizeOfSection =
ALIGN_8 (
MmSizeOfUnloadedDriverInformation());
02918
02919
if (
Offset + SizeOfSection <
BufferSize) {
02920 TriageDumpHeader->UnloadedDriversOffset = (ULONG)
Offset;
02921
Offset += SizeOfSection;
02922 }
02923
02924
02925
02926
02927
02928
if (Fields & TRIAGE_DUMP_PRCB) {
02929 SizeOfSection =
ALIGN_8 (
sizeof (KPRCB));
02930
02931
if (
Offset + SizeOfSection <
BufferSize) {
02932 TriageDumpHeader->PrcbOffset = (ULONG)
Offset;
02933
Offset += SizeOfSection;
02934 }
02935 }
02936
02937
02938
02939
02940
02941
if (Fields & TRIAGE_DUMP_PROCESS) {
02942 SizeOfSection =
ALIGN_8 (
sizeof (
EPROCESS));
02943
02944
if (
Offset + SizeOfSection <
BufferSize) {
02945 TriageDumpHeader->ProcessOffset = (ULONG)
Offset;
02946
Offset += SizeOfSection;
02947 }
02948 }
02949
02950
02951
02952
02953
02954
if (Fields & TRIAGE_DUMP_THREAD) {
02955 SizeOfSection =
ALIGN_8 (
sizeof (
ETHREAD));
02956
02957
if (
Offset + SizeOfSection <
BufferSize) {
02958 TriageDumpHeader->ThreadOffset = (ULONG)
Offset;
02959
Offset += SizeOfSection;
02960 }
02961 }
02962
02963
02964
02965
02966
02967 Thread =
PsGetCurrentThread ();
02968
02969
if (Fields & TRIAGE_DUMP_STACK) {
02970
02971
02972
02973
02974
02975
if (Thread->
Tcb.
KernelStackResident) {
02976
02977 ULONG_PTR StackBase;
02978
02979 StackBase = (ULONG_PTR) Thread->
Tcb.
InitialStack;
02980
02981
ASSERT ( StackBase > STACK_POINTER (Context));
02982
02983
02984
02985
02986
02987
02988
02989 StartOfStackRegion = (ULONG_PTR) STACK_POINTER (Context);
02990 SizeOfSection = (ULONG)
min ( StackBase - (ULONG_PTR) STACK_POINTER (Context),
02991
MAX_TRIAGE_STACK_SIZE
02992 );
02993
02994
ASSERT ( StartOfStackRegion + SizeOfSection <= StackBase);
02995
02996 }
else {
02997
02998
02999
03000
03001
03002 SizeOfSection = 0;
03003 }
03004
03005
if (SizeOfSection &&
Offset + SizeOfSection <
BufferSize) {
03006 TriageDumpHeader->CallStackOffset = (ULONG)
Offset;
03007 TriageDumpHeader->SizeOfCallStack = SizeOfSection;
03008 TriageDumpHeader->BaseOfStack = (ULONG) StartOfStackRegion;
03009
Offset += SizeOfSection;
03010 }
03011 }
03012
03013
03014
03015
03016
03017
Status =
IopGetLoadedDriverInfo (&DriverCount, &SizeOfStringData);
03018
03019
if (
NT_SUCCESS (
Status) && Fields & TRIAGE_DUMP_DRIVER_LIST) {
03020 SizeOfSection =
ALIGN_8 (DriverCount *
sizeof (DUMP_DRIVER_ENTRY));
03021
03022
if (SizeOfSection && (
Offset + SizeOfSection <
BufferSize)) {
03023 TriageDumpHeader->DriverListOffset = (ULONG)
Offset;
03024 TriageDumpHeader->DriverCount = DriverCount;
03025
Offset += SizeOfSection;
03026 }
03027
03028 }
else {
03029
03030 SizeOfSection = 0;
03031 SizeOfStringData = 0;
03032 }
03033
03034
03035
03036
03037
03038 SizeOfSection =
ALIGN_8 (SizeOfStringData +
03039 DriverCount * (
sizeof (WCHAR) +
sizeof (DUMP_STRING)));
03040
03041
if (SizeOfSection && (
Offset + SizeOfSection <
BufferSize)) {
03042 TriageDumpHeader->StringPoolOffset = (ULONG)
Offset;
03043 TriageDumpHeader->StringPoolSize = SizeOfSection;
03044
Offset += SizeOfSection;
03045 }
03046
03047
03048 BytesToWrite = (ULONG)
Offset;
03049 BufferAddress = ((ULONG_PTR)
Buffer) -
PAGE_SIZE ;
03050
03051
03052
03053
03054
03055
if (TriageDumpHeader->MmOffset) {
03056
03057 Address = (
LPVOID) (BufferAddress + TriageDumpHeader->MmOffset);
03058
MmWriteTriageInformation (Address);
03059 }
03060
03061
if (TriageDumpHeader->UnloadedDriversOffset) {
03062
03063 Address = (
LPVOID) (BufferAddress + TriageDumpHeader->UnloadedDriversOffset);
03064
MmWriteUnloadedDriverInformation (Address);
03065 }
03066
03067
03068
03069
03070
03071
if (TriageDumpHeader->PrcbOffset) {
03072
03073 Address = (
LPVOID) (BufferAddress + TriageDumpHeader->PrcbOffset);
03074 RtlCopyMemory (Address,
03075
KeGetCurrentPrcb (),
03076
sizeof (KPRCB)
03077 );
03078 }
03079
03080
03081
03082
03083
03084
if (TriageDumpHeader->ProcessOffset) {
03085
03086 Address = (
LPVOID) (BufferAddress + TriageDumpHeader->ProcessOffset);
03087 RtlCopyMemory (Address,
03088
PsGetCurrentProcess (),
03089
sizeof (
EPROCESS)
03090 );
03091 }
03092
03093
03094
03095
03096
03097
if (TriageDumpHeader->ThreadOffset) {
03098
03099 Address = (
LPVOID) (BufferAddress + TriageDumpHeader->ThreadOffset);
03100 RtlCopyMemory (Address,
03101
KeGetCurrentThread (),
03102
sizeof (
ETHREAD)
03103 );
03104 }
03105
03106
03107
03108
03109
03110
if (TriageDumpHeader->CallStackOffset) {
03111
03112
ASSERT (Thread);
03113
ASSERT (TriageDumpHeader->SizeOfCallStack != 0);
03114
03115 Address = (
LPVOID) (BufferAddress + TriageDumpHeader->CallStackOffset);
03116 RtlCopyMemory (Address,
03117 (PVOID) StartOfStackRegion,
03118 TriageDumpHeader->SizeOfCallStack
03119 );
03120 }
03121
03122
03123
03124
03125
03126
if (TriageDumpHeader->DriverListOffset &&
03127 TriageDumpHeader->StringPoolOffset) {
03128
03129
Status =
IopWriteDriverList (BufferAddress,
03130
BufferSize,
03131 TriageDumpHeader->DriverListOffset,
03132 TriageDumpHeader->StringPoolOffset
03133 );
03134
03135
if (!
NT_SUCCESS (
Status)) {
03136 TriageDumpHeader->DriverListOffset = 0;
03137 }
03138 }
03139
03140
ASSERT (BytesToWrite <
BufferSize);
03141
ASSERT (
ALIGN_UP (BytesToWrite,
PAGE_SIZE) <
BufferSize);
03142
03143
IoDebugPrint ((3,
"TRIAGEDUMP: Calling IopWriteToDisk with:\n"
03144
"\tBytesToWrite = %#x\n"
03145
"\tBytesToWrite (Aligned) = %#x\n"
03146
"\tBufferSize = %#x\n",
03147 BytesToWrite,
03148
ALIGN_UP (BytesToWrite,
PAGE_SIZE),
03149
BufferSize));
03150
03151
03152
03153
03154
03155
03156 *((ULONG *)
IndexByByte (
Buffer,
BufferSize)) = TRIAGE_DUMP_VALID ;
03157
03158
03159
03160
03161
03162
BufferSize +=
sizeof (
DWORD);
03163
03164
03165
03166
03167
03168
03169
Status =
IopWriteToDisk (
Buffer,
03170
BufferSize,
03171 DriverWriteRoutine,
03172 &Mcb,
03173 Mdl,
03174 DriverTransferSize
03175 );
03176
03177
return Status;
03178 }
03179
03180
03181
03182
NTSTATUS
03183 IopWritePageToDisk(
03184 IN PDUMP_DRIVER_WRITE DriverWrite,
03185 IN OUT PLARGE_INTEGER * McbBuffer,
03186 IN OUT ULONG DriverTransferSize,
03187 IN PFN_NUMBER PageFrameIndex
03188 )
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218 {
03219
NTSTATUS Status;
03220 PFN_NUMBER MdlHack [ (
sizeof (
MDL) /
sizeof (PFN_NUMBER)) + 1];
03221 PPFN_NUMBER PfnArray;
03222 PLARGE_INTEGER Mcb;
03223 ULONG ByteCount;
03224 ULONG ByteOffset;
03225 ULONG BytesToWrite;
03226
PMDL TempMdl;
03227
03228
03229
ASSERT ( DriverWrite );
03230
ASSERT ( McbBuffer );
03231
ASSERT ( DriverTransferSize && DriverTransferSize >=
PAGE_SIZE );
03232
03233
03234
03235
03236
03237 TempMdl = (
PMDL) &MdlHack;
03238 Mcb = *McbBuffer;
03239 BytesToWrite =
PAGE_SIZE;
03240
03241
03242
03243
03244
03245
03246
MmInitializeMdl (TempMdl,
NULL,
PAGE_SIZE);
03247
03248 PfnArray =
MmGetMdlPfnArray ( TempMdl );
03249 PfnArray[0] = PageFrameIndex;
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261 ByteOffset = 0;
03262
03263
while ( BytesToWrite ) {
03264
03265
ASSERT ( Mcb[0].QuadPart != 0 );
03266
03267 ByteCount = (ULONG)
min3 ((LONGLONG) BytesToWrite,
03268 (LONGLONG) DriverTransferSize,
03269 Mcb[0].QuadPart
03270 );
03271
03272
ASSERT ( ByteCount != 0 );
03273
03274
03275
03276
03277
03278 TempMdl->
ByteCount = ByteCount;
03279 TempMdl->
ByteOffset = ByteOffset;
03280
03281
03282
03283
03284
03285
03286
MmMapMemoryDumpMdl ( TempMdl );
03287 TempMdl->
MdlFlags |= (
MDL_PAGES_LOCKED |
MDL_MAPPED_TO_SYSTEM_VA );
03288 TempMdl->
StartVa =
PAGE_ALIGN (TempMdl->
MappedSystemVa);
03289
03290
Status = DriverWrite ( &Mcb[1], TempMdl );
03291
03292
03293
if (!
NT_SUCCESS (
Status)) {
03294
return Status;
03295 }
03296
03297 BytesToWrite -= ByteCount;
03298 ByteOffset += ByteCount;
03299
03300 Mcb[0].QuadPart -= ByteCount;
03301 Mcb[1].QuadPart += ByteCount;
03302
03303
03304
03305
03306
03307
03308
if ( Mcb[0].QuadPart == 0 ) {
03309
03310 Mcb += 2;
03311
03312
03313
03314
03315
03316
if ( Mcb[0].QuadPart == 0) {
03317
return STATUS_END_OF_FILE;
03318 }
03319 }
03320 }
03321
03322 *McbBuffer = Mcb;
03323
03324
return Status;
03325 }
03326
03327
03328
NTSTATUS
03329 IopWriteSummaryDump(
03330 IN PRTL_BITMAP PageMap,
03331 IN PDUMP_DRIVER_WRITE DriverWriteRoutine,
03332 IN PANSI_STRING ProgressMessage,
03333 IN PUCHAR MessageBuffer,
03334 IN OUT PLARGE_INTEGER Mcb,
03335 IN OUT ULONG DriverTransferSize
03336 )
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366 {
03367 PVOID Va;
03368 PFN_NUMBER PageFrameIndex;
03369 PHYSICAL_ADDRESS PhysicalAddress;
03370
NTSTATUS Status;
03371
03372 ULONG WriteCount;
03373 ULONG MaxWriteCount;
03374 ULONG Step;
03375
03376
03377
ASSERT ( DriverWriteRoutine !=
NULL );
03378
ASSERT ( Mcb !=
NULL );
03379
ASSERT ( DriverTransferSize != 0 );
03380
03381
03382 MaxWriteCount =
RtlNumberOfSetBits ( PageMap );
03383 Step = MaxWriteCount / 100;
03384
03385
IoDebugPrint ((1,
"IODUMP: Summary Dump\n"
03386
" Writing %x pages to disk from a total of %x\n",
03387 MaxWriteCount,
03388 PageMap->SizeOfBitMap));
03389
03390
03391
03392
03393
03394
03395 WriteCount = 0;
03396
for ( PageFrameIndex = 0;
03397 PageFrameIndex < PageMap->SizeOfBitMap;
03398 PageFrameIndex++) {
03399
03400
03401
03402
03403
03404
03405
if ( RtlCheckBit (PageMap, PageFrameIndex) ) {
03406
03407
if (++WriteCount % Step == 0) {
03408
03409
sprintf (MessageBuffer,
03410
"%Z: %3d\r",
03411 ProgressMessage,
03412 (WriteCount * 100) / MaxWriteCount);
03413
03414
InbvDisplayString ( MessageBuffer );
03415 }
03416
03417
ASSERT ( WriteCount <= MaxWriteCount );
03418
03419
03420
03421
03422
03423
Status =
IopWritePageToDisk (
03424 DriverWriteRoutine,
03425 &Mcb,
03426 DriverTransferSize,
03427 PageFrameIndex
03428 );
03429
03430
if (!
NT_SUCCESS (
Status)) {
03431
03432
return STATUS_UNSUCCESSFUL;
03433 }
03434 }
03435 }
03436
03437
return STATUS_SUCCESS;
03438 }
03439
03440
03441 PSUMMARY_DUMP_HEADER
03442 IopInitializeSummaryDump(
03443 IN
PDUMP_CONTROL_BLOCK pDcb
03444 )
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463 {
03464 PULONG pdwBlock;
03465 PSUMMARY_DUMP_HEADER pSummaryHeader;
03466 ULONG dwActualPages;
03467
03468
03469
03470
03471
03472 pdwBlock = pDcb->HeaderPage;
03473
03474
03475
03476
03477
03478 pSummaryHeader = (PSUMMARY_DUMP_HEADER)&pdwBlock[ DH_SUMMARY_DUMP_RECORD ];
03479
03480
03481
03482
03483 RtlFillMemoryUlong( pSummaryHeader,
03484
sizeof(SUMMARY_DUMP_HEADER),
03485 'PMDS' );
03486
03487
03488
03489
03490
03491 pSummaryHeader->BitmapSize = (ULONG)(
MmPhysicalMemoryBlock->
Run[
MmPhysicalMemoryBlock->
NumberOfRuns-1].
BasePage +
03492
MmPhysicalMemoryBlock->
Run[
MmPhysicalMemoryBlock->
NumberOfRuns-1].
PageCount );
03493 pSummaryHeader->ValidDump = 'PMUD';
03494
03495
03496
03497
03498
03499 dwActualPages =
IopCreateSummaryDump(pSummaryHeader);
03500
03501
IoDebugPrint((2,
"[IopInitializeSummaryDump]: Kernel Pages = %x\n",dwActualPages));
03502
03503
if (!dwActualPages) {
03504
return NULL;
03505 }
03506
03507
03508
03509
03510
03511 pSummaryHeader->Pages = dwActualPages;
03512 pSummaryHeader->HeaderSize = pDcb->HeaderSize;
03513
03514
return pSummaryHeader;
03515 }
03516
03517
03518
03519
NTSTATUS
03520 IopWriteSummaryHeader(
03521 IN PSUMMARY_DUMP_HEADER pSummaryHeader,
03522 IN PDUMP_DRIVER_WRITE pfWrite,
03523 IN OUT PLARGE_INTEGER * McbBuffer,
03524 IN OUT
PMDL pMdl,
03525 IN ULONG dwWriteSize,
03526 IN ULONG dwLength
03527 )
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553 {
03554
NTSTATUS Status;
03555 ULONG dwBytesRemaining;
03556 ULONG_PTR dwMemoryAddress;
03557 ULONG dwByteOffset;
03558 ULONG dwByteCount;
03559 PLARGE_INTEGER pMcb;
03560
03561 dwBytesRemaining = dwLength;
03562 dwMemoryAddress = (ULONG_PTR) pSummaryHeader;
03563 pMcb = *McbBuffer;
03564
03565
IoDebugPrint (( 0,
"IoWriteCrashDump: Writing SUMMARY dump header to disk\n" ));
03566
03567
while (dwBytesRemaining) {
03568
03569
03570 dwByteOffset = (ULONG)(dwMemoryAddress & (
PAGE_SIZE - 1));
03571
03572
03573
03574
03575
03576
03577
if (dwBytesRemaining <= dwWriteSize) {
03578 dwByteCount = dwBytesRemaining;
03579 }
else {
03580 dwByteCount = dwWriteSize;
03581 }
03582
03583
03584
03585
03586
03587
if (dwByteCount > pMcb[0].QuadPart) {
03588 dwByteCount = pMcb[0].LowPart;
03589 }
03590
03591 pMdl->ByteCount = dwByteCount;
03592 pMdl->ByteOffset = dwByteOffset;
03593 pMdl->MappedSystemVa = (PVOID) dwMemoryAddress;
03594
03595
03596
03597
03598
03599
IopMapVirtualToPhysicalMdl(pMdl, dwMemoryAddress, dwByteCount);
03600
03601
03602
03603
03604
Status = pfWrite( &pMcb[1], pMdl );
03605
03606
if ( !
NT_SUCCESS (
Status) ) {
03607
return Status;
03608 }
03609
03610
03611
03612
03613
03614 dwBytesRemaining -= dwByteCount;
03615 dwMemoryAddress += dwByteCount;
03616
03617 pMcb[0].QuadPart = pMcb[0].QuadPart - dwByteCount;
03618 pMcb[1].QuadPart = pMcb[1].QuadPart + dwByteCount;
03619
03620
if (pMcb[0].QuadPart == 0) {
03621 pMcb += 2;
03622 }
03623
03624
if (pMcb[0].QuadPart == 0) {
03625
return STATUS_END_OF_FILE;
03626 }
03627 }
03628
03629
IoDebugPrint((2,
"IoWriteCrashDump: Writing SUMMARY dump header to disk\n" ));
03630
03631 *McbBuffer = pMcb;
03632
return STATUS_SUCCESS;
03633 }
03634
03635
03636
03637
NTSTATUS
03638 IopWriteToDisk(
03639 IN PVOID Buffer,
03640 IN ULONG WriteLength,
03641 IN PDUMP_DRIVER_WRITE DriverWriteRoutine,
03642 IN OUT PLARGE_INTEGER * McbBuffer,
03643 IN OUT
PMDL Mdl,
03644 IN ULONG DriverTransferSize
03645 )
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671 {
03672 ULONG dwBytesRemaining;
03673 ULONG_PTR dwMemoryAddress;
03674 ULONG dwByteOffset;
03675 ULONG dwByteCount;
03676 PLARGE_INTEGER Mcb;
03677
03678
ASSERT (
Buffer);
03679
ASSERT (WriteLength);
03680
ASSERT (DriverWriteRoutine);
03681
ASSERT (McbBuffer && *McbBuffer);
03682
ASSERT (Mdl);
03683
ASSERT (DriverTransferSize >=
IO_DUMP_MINIMUM_TRANSFER_SIZE &&
03684 DriverTransferSize <=
IO_DUMP_MAXIMUM_TRANSFER_SIZE);
03685
03686
03687 Mcb = *McbBuffer;
03688 dwBytesRemaining = WriteLength;
03689 dwMemoryAddress = (ULONG_PTR)
Buffer;
03690
03691
IoDebugPrint(( 2,
"IoWriteToDisk: Writing %d bytes to disk.\n", WriteLength ));
03692
03693
while (dwBytesRemaining) {
03694
03695
ASSERT (Mcb [0].QuadPart != 0);
03696
ASSERT (
IopDumpControlBlock->
FileDescriptorArray <= Mcb &&
03697 (LPBYTE) Mcb < (LPBYTE) IopDumpControlBlock->FileDescriptorArray +
03698
IopDumpControlBlock->
FileDescriptorSize
03699 );
03700
03701 dwByteOffset =
BYTE_OFFSET (dwMemoryAddress);
03702
03703
03704
03705
03706
03707
03708 dwByteCount =
min ( dwBytesRemaining, DriverTransferSize );
03709
03710
03711
03712
03713
03714
if (dwByteCount > Mcb[0].QuadPart) {
03715 dwByteCount = Mcb[0].LowPart;
03716 }
03717
03718 Mdl->ByteCount = dwByteCount;
03719 Mdl->ByteOffset = dwByteOffset;
03720 Mdl->MappedSystemVa = (PVOID) dwMemoryAddress;
03721
03722
03723
03724
03725
03726
IopMapVirtualToPhysicalMdl(Mdl, dwMemoryAddress, dwByteCount);
03727
03728
if (!
NT_SUCCESS( DriverWriteRoutine ( &Mcb[1], Mdl ) )) {
03729
IoDebugPrint ((1,
"IopWriteToDisk: Failed write.\n"));
03730
return STATUS_UNSUCCESSFUL;
03731 }
03732
03733
03734
03735
03736
03737
ASSERT (dwBytesRemaining >= dwByteCount);
03738
ASSERT (dwByteCount != 0);
03739
03740 dwBytesRemaining -= dwByteCount;
03741 dwMemoryAddress += dwByteCount;
03742
03743 Mcb[0].QuadPart -= dwByteCount;
03744 Mcb[1].QuadPart += dwByteCount;
03745
03746
if (Mcb[0].QuadPart == 0) {
03747 Mcb += 2;
03748 }
03749 }
03750
03751
IoDebugPrint ((2,
"IopWriteToDisk: Successfully wrote %d bytes.\n", WriteLength));
03752
03753 *McbBuffer = Mcb;
03754
return STATUS_SUCCESS;
03755 }
03756
03757
03758
VOID
03759 IopMapVirtualToPhysicalMdl(
03760 IN OUT
PMDL pMdl,
03761 IN ULONG_PTR dwMemoryAddress,
03762 IN ULONG dwLength
03763 )
03764 {
03765 PPFN_NUMBER pdwPage;
03766 ULONG dwPages;
03767 ULONG dwBase;
03768 ULONG dwCurrentBase;
03769 ULONG_PTR dwBaseVa;
03770 PHYSICAL_ADDRESS PhysicalAddress;
03771
03772
03773
03774
03775
03776
03777 pMdl->StartVa =
PAGE_ALIGN((PVOID)dwMemoryAddress);
03778 pMdl->ByteOffset= (ULONG)(dwMemoryAddress & (
PAGE_SIZE - 1));
03779 pMdl->ByteCount = dwLength;
03780 dwBaseVa = dwMemoryAddress & ~(
PAGE_SIZE -1);
03781 pMdl->MdlFlags |=
MDL_MAPPED_TO_SYSTEM_VA;
03782
03783
03784
03785
03786
03787 dwPages =
COMPUTE_PAGES_SPANNED( dwMemoryAddress, dwLength );
03788 pdwPage =
MmGetMdlPfnArray(pMdl);
03789
03790
03791
03792
03793
03794
IoDebugPrint((3,
"MapVirtualToPhysical: VA: %08x off: %08x Len:%08x base: %08x \n",pMdl->StartVa,pMdl->ByteOffset,pMdl->ByteCount,dwBaseVa));
03795
03796
while (dwPages) {
03797 PhysicalAddress =
MmGetPhysicalAddress( (PVOID)dwBaseVa );
03798
IoDebugPrint( (3,
"Physical Frame: %08x Adr: %08x\n",( PhysicalAddress.QuadPart >>
PAGE_SHIFT),dwBaseVa ) );
03799 *pdwPage++ = (PFN_NUMBER)(PhysicalAddress.QuadPart >>
PAGE_SHIFT);
03800 dwBaseVa +=
PAGE_SIZE;
03801 dwPages--;
03802 }
03803
03804
03805
03806
03807
03808
03809
03810 }
03811
03812
03813
03814 ULONG
03815 IopCreateSummaryDump (
03816 IN PSUMMARY_DUMP_HEADER pHeader
03817 )
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840 {
03841 PRTL_BITMAP pBitMapHeader = (PRTL_BITMAP)(pHeader+1);
03842 ULONG Pages;
03843 PCHAR VA;
03844 ULONG UserPages;
03845 PHYSICAL_ADDRESS PhyAddr;
03846 ULONG i;
03847 PULONG pBitMapBuffer;
03848 PUCHAR pBitMapBytes;
03849 LARGE_INTEGER dumpFileSize;
03850 PULONG block;
03851 ULONG numDumpPages;
03852
03853
03854
03855
03856
03857
03858
03859
03860 pBitMapHeader->SizeOfBitMap = pHeader->BitmapSize;
03861 pBitMapBuffer = (PULONG)( pBitMapHeader + 1);
03862 pBitMapHeader->Buffer = pBitMapBuffer;
03863 pBitMapBytes = (PUCHAR)pBitMapBuffer;
03864
03865
03866
03867
03868
03869
RtlClearAllBits (pBitMapHeader);
03870
03871
03872
03873
03874
03875
MmSetKernelDumpRange(pHeader);
03876
03877
03878
03879
03880
03881
IopDeleteNonExistentMemory(pHeader,
MmPhysicalMemoryBlock);
03882
03883
03884 Pages =
RtlNumberOfSetBits ( pBitMapHeader );
03885
IoDebugPrint((2,
"IopLocalSetBits = %x\n",Pages));
03886
03887
03888
03889
03890
03891 block =
IopDumpControlBlock->
HeaderPage;
03892 dumpFileSize.LowPart= block [DH_REQUIRED_DUMP_SPACE];
03893 dumpFileSize.HighPart= block [DH_REQUIRED_DUMP_SPACE + 1];
03894
03895 dumpFileSize.QuadPart -=
IopDumpControlBlock->
HeaderSize;
03896
03897
03898
03899
03900
03901 numDumpPages= (ULONG)(dumpFileSize.QuadPart >>
PAGE_SHIFT);
03902
IoDebugPrint ((2,
"IopCreateSummaryDump: numDumpPages: %x Pages : %x\n", numDumpPages,Pages));
03903
03904
03905
03906
03907
03908 UserPages = 0;
03909
03910
if (Pages < numDumpPages ) {
03911
03912
03913
03914
03915
03916
for (VA = 0; VA < (PCHAR)
MmHighestUserAddress; VA+=
PAGE_SIZE ) {
03917
03918
if (
MmIsAddressValid( VA ) ) {
03919
03920
if (
NT_SUCCESS(
IoSetDumpRange(pHeader,VA, 1,
FALSE ) ) ) {
03921
03922 UserPages++;
03923
03924
03925
03926
03927
03928
if (UserPages+Pages >= numDumpPages ) {
03929
break;
03930 }
03931 }
03932 }
03933 }
03934
03935 }
03936
03937 Pages+= UserPages;
03938
03939
IoDebugPrint((2,
"IopCreateSummaryDump number of user mode pages = %x\n",UserPages));
03940
03941
IoDebugPrint((2,
"SummaryDump: Dump SummaryDumpHeader\n"));
03942
IoDebugPrint((2,
"SdBitmapSize =%x\n", pHeader->BitmapSize));
03943
IoDebugPrint((2,
"SdAllBits =%x\n", Pages));
03944
IoDebugPrint((2,
"&SdBitmapBuffer[0]=%x\n", pBitMapHeader->Buffer));
03945
03946
03947
return Pages;
03948
03949 }
03950
03951
03952
VOID
03953 IopDeleteNonExistentMemory(
03954 PSUMMARY_DUMP_HEADER pHeader,
03955
PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock
03956 )
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984 {
03985
PPHYSICAL_MEMORY_RUN Run;
03986 ULONG NumberOfRuns;
03987 ULONG i;
03988 PFN_NUMBER CurrentPageFrame, NextPageFrame;
03989 PRTL_BITMAP pBitMapHeader;
03990
03991 NumberOfRuns =
MmPhysicalMemoryBlock->
NumberOfRuns;
03992
03993 Run = &
MmPhysicalMemoryBlock->
Run[0];
03994
03995 pBitMapHeader = (PRTL_BITMAP)(pHeader + 1);
03996 i = 0;
03997
03998 CurrentPageFrame = 1;
03999
04000 NextPageFrame = Run->
BasePage;
04001
04002
04003
04004
04005
04006
if (NextPageFrame > CurrentPageFrame) {
04007
04008
IoDebugPrint( (2,
"DeleteNonExistentMemory: %x - %x\n",
04009 CurrentPageFrame,
04010 (NextPageFrame - CurrentPageFrame) ) );
04011
04012
04013
04014
04015
04016
IopRemovePageFromPageMap (pHeader->BitmapSize,
04017 pBitMapHeader,
04018 (ULONG)CurrentPageFrame,
04019 (ULONG)(NextPageFrame-CurrentPageFrame)
04020 );
04021
04022 }
04023
04024
04025
04026
04027
04028
while (i < NumberOfRuns - 1) {
04029
04030 CurrentPageFrame = Run->
BasePage + Run->
PageCount;
04031
IoDebugPrint((2,
"Run[%x]: Base=%x, Pages=%x\n", i, Run->
BasePage, Run->
PageCount));
04032
04033 i++;
04034 Run++;
04035
04036
04037
04038
04039
04040 NextPageFrame = Run->
BasePage;
04041
04042
if (NextPageFrame != CurrentPageFrame) {
04043
04044
IoDebugPrint((2,
"DeleteNonExistentMemory: %x - %x\n", NextPageFrame, CurrentPageFrame));
04045
04046
04047
04048
04049
04050
IopRemovePageFromPageMap (pHeader->BitmapSize,
04051 pBitMapHeader,
04052 (ULONG)CurrentPageFrame,
04053 (ULONG)(NextPageFrame - CurrentPageFrame)
04054 );
04055 }
04056 }
04057 }
04058
04059
04060
NTSTATUS
04061 IopCompleteDumpInitialization(
04062 IN HANDLE FileHandle
04063 )
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092 {
04093
NTSTATUS Status;
04094
NTSTATUS ErrorToLog;
04095 ULONG i;
04096 LARGE_INTEGER RequestedFileSize;
04097 PLARGE_INTEGER mcb;
04098
PFILE_OBJECT FileObject;
04099
PDEVICE_OBJECT DeviceObject;
04100 IO_STATUS_BLOCK IoStatusBlock;
04101 FILE_STANDARD_INFORMATION StandardFileInfo;
04102
04103
Status = STATUS_UNSUCCESSFUL;
04104 ErrorToLog = STATUS_SUCCESS;
04105 FileObject =
NULL;
04106 DeviceObject =
NULL;
04107
04108
Status =
ObReferenceObjectByHandle( FileHandle,
04109 0,
04110
IoFileObjectType,
04111
KernelMode,
04112 (PVOID *) &FileObject,
04113
NULL
04114 );
04115
04116
if ( !
NT_SUCCESS (
Status) ) {
04117
ASSERT (
FALSE);
04118
goto Cleanup;
04119 }
04120
04121
04122 DeviceObject = FileObject->DeviceObject;
04123
04124
04125
04126
04127
04128
04129
if ( !(DeviceObject->
Flags &
DO_SYSTEM_BOOT_PARTITION) ) {
04130
04131 KdPrint ((
"IODUMP: Cannot dump to pagefile on non-system partition.\n"));
04132
goto Cleanup;
04133 }
04134
04135
Status = ZwQueryInformationFile(
04136 FileHandle,
04137 &IoStatusBlock,
04138 &StandardFileInfo,
04139
sizeof (StandardFileInfo),
04140 FileStandardInformation
04141 );
04142
04143
if (
Status == STATUS_PENDING) {
04144
Status =
KeWaitForSingleObject( &FileObject->Event,
04145
Executive,
04146
KernelMode,
04147
FALSE,
04148
NULL
04149 );
04150
Status = IoStatusBlock.Status;
04151 }
04152
04153
if ( !
NT_SUCCESS (
Status) ) {
04154 KdPrint ((
"CRASHDUMP: Failed ZwQueryInformationFile\n"));
04155
goto Cleanup;
04156 }
04157
04158
04159
04160
04161
04162 RequestedFileSize =
IopDumpControlBlock->
DumpFileSize;
04163
04164
if (RequestedFileSize.QuadPart > StandardFileInfo.EndOfFile.QuadPart) {
04165 RequestedFileSize = StandardFileInfo.EndOfFile;
04166 }
04167
04168
Status = ZwFsControlFile(
04169 FileHandle,
04170
NULL,
04171
NULL,
04172
NULL,
04173 &IoStatusBlock,
04174 FSCTL_QUERY_RETRIEVAL_POINTERS,
04175 &RequestedFileSize,
04176
sizeof( LARGE_INTEGER ),
04177 &mcb,
04178
sizeof( PVOID )
04179 );
04180
04181
if (
Status == STATUS_PENDING) {
04182
Status =
KeWaitForSingleObject( &FileObject->Event,
04183
Executive,
04184
KernelMode,
04185
FALSE,
04186
NULL );
04187
Status = IoStatusBlock.Status;
04188 }
04189
04190
04191
04192
04193
04194
04195
04196
if ( !
NT_SUCCESS (
Status) ) {
04197 KdPrint ((
"CRASHDUMP: ZwFsControlFile returnd %d\n",
Status));
04198 ErrorToLog = IO_DUMP_POINTER_FAILURE;
04199
goto Cleanup;
04200 }
04201
04202
04203
04204
04205
04206
04207
04208
for (i = 0; mcb [i].QuadPart; i++) {
04209 NOTHING;
04210 }
04211
04212
04213
04214
04215
04216
IopDumpControlBlock->
FileDescriptorArray = mcb;
04217
IopDumpControlBlock->
FileDescriptorSize = (i + 1) *
sizeof (LARGE_INTEGER);
04218
IopDumpControlBlock->
DumpFileSize = RequestedFileSize;
04219
IopDumpControlBlockChecksum =
IopGetDumpControlBlockCheck (
IopDumpControlBlock );
04220
04221
Status = STATUS_SUCCESS;
04222
04223 Cleanup:
04224
04225
if (
Status != STATUS_SUCCESS &&
04226 ErrorToLog != STATUS_SUCCESS ) {
04227
04228
IopLogErrorEvent (0,
04229 4,
04230 STATUS_SUCCESS,
04231 ErrorToLog,
04232 0,
04233
NULL,
04234 0,
04235
NULL
04236 );
04237 }
04238
04239 DeviceObject =
NULL;
04240
04241
if ( FileObject ) {
04242
ObDereferenceObject( FileObject );
04243 FileObject =
NULL;
04244 }
04245
04246
return Status;
04247
04248 }
04249
04250
04251
VOID
04252 IopFreeDCB(
04253 BOOLEAN FreeDCB
04254 )
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267
04268
04269
04270
04271 {
04272
PDUMP_CONTROL_BLOCK dcb;
04273
NTSTATUS dwStatus;
04274 BOOLEAN ShouldFreeDCB;
04275
04276 dcb =
IopDumpControlBlock;
04277
04278
04279
if (dcb) {
04280
04281
if (dcb->
MemoryDescriptor) {
04282
ExFreePool (dcb->
MemoryDescriptor);
04283 dcb->
MemoryDescriptor =
NULL;
04284 }
04285
04286
if (dcb->
HeaderPage) {
04287
ExFreePool (dcb->
HeaderPage);
04288 dcb->
HeaderPage =
NULL;
04289 }
04290
04291
if (dcb->
FileDescriptorArray) {
04292
ExFreePool (dcb->
FileDescriptorArray);
04293 dcb->
FileDescriptorArray =
NULL;
04294 }
04295
04296
if (dcb->
DumpStack) {
04297
IoFreeDumpStack (dcb->
DumpStack);
04298 dcb->
DumpStack =
NULL;
04299 }
04300
04301 ShouldFreeDCB = FreeDCB | !( dcb->
Flags &
DCB_AUTO_REBOOT);
04302
04303
04304
04305
04306
04307 dcb->
Flags = dcb->
Flags &
DCB_AUTO_REBOOT;
04308
04309
IoDebugPrint((2,
"[IopFreeDCB] Should Free DCB = %s\n",(ShouldFreeDCB ?
"TRUE" :
"FALSE")));
04310
04311
if (ShouldFreeDCB) {
04312
IopDumpControlBlock =
NULL;
04313
ExFreePool( dcb );
04314
IoDebugPrint((2,
"[IopFreeDCB]: Freeing Dump Control Block\n"));
04315 }
04316 }
04317
04318
IoDebugPrint((2,
"[IopFreeDCB]: CRASH DUMP DISABLED\n"));
04319
04320 }
04321
04322
04323
04324
NTSTATUS
04325 IoSetCrashDumpState(
04326 IN SYSTEM_CRASH_STATE_INFORMATION *pDumpState
04327 )
04328
04329
04330
04331
04332
04333
04334
04335
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345
04346
04347 {
04348
NTSTATUS Status;
04349 ULONG crashConfigurationInProgress;
04350
04351
04352
04353
04354
04355 crashConfigurationInProgress = InterlockedExchange(&
IopCrashDumpStateChange,1);
04356
04357
if (crashConfigurationInProgress) {
04358
return STATUS_SUCCESS;
04359 }
04360
04361
04362
04363
04364
04365
if (!pDumpState->ValidDirectDump) {
04366
IopFreeDCB(
FALSE);
04367
Status = STATUS_SUCCESS;
04368 }
else {
04369
Status = STATUS_INVALID_DEVICE_REQUEST;
04370 }
04371
04372 InterlockedExchange(&
IopCrashDumpStateChange,0);
04373
04374
return Status;
04375 }
04376
04377
04378
VOID
04379 IopReadDumpRegistry(
04380 OUT PULONG dumpControl,
04381 OUT PULONG numberOfHeaderPages,
04382 OUT PULONG autoReboot,
04383 OUT PULONG dumpFileSize
04384 )
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401 {
04402 HANDLE keyHandle;
04403 HANDLE crashHandle;
04404 LOGICAL crashHandleOpened;
04405 UNICODE_STRING keyName;
04406
NTSTATUS status;
04407 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
04408
PDUMP_CONTROL_BLOCK dcb;
04409 ULONG handleValue;
04410
04411 *dumpControl = 0;
04412 *autoReboot = 0;
04413 *dumpFileSize = 0;
04414
04415 *numberOfHeaderPages = 1;
04416
04417
04418
04419
04420
04421
04422 crashHandleOpened =
FALSE;
04423
04424
RtlInitUnicodeString( &keyName,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control" );
04425
04426 status =
IopOpenRegistryKey( &keyHandle,
04427 (HANDLE)
NULL,
04428 &keyName,
04429 KEY_READ,
04430
FALSE );
04431
04432
if (!
NT_SUCCESS( status )) {
04433
return;
04434 }
04435
04436
RtlInitUnicodeString( &keyName,
L"CrashControl" );
04437 status =
IopOpenRegistryKey( &crashHandle,
04438 keyHandle,
04439 &keyName,
04440 KEY_READ,
04441
FALSE );
04442
04443
NtClose( keyHandle );
04444
04445
if (!
NT_SUCCESS( status )) {
04446
return;
04447 }
04448
04449 crashHandleOpened =
TRUE;
04450
04451
04452
04453
04454
04455
04456 status =
IopGetRegistryValue( crashHandle,
04457
L"CrashDumpEnabled",
04458 &keyValueInformation );
04459
04460
if (
NT_SUCCESS (status)) {
04461
04462
if (keyValueInformation->DataLength) {
04463
04464 handleValue = * ((PULONG) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset));
04465
ExFreePool( keyValueInformation );
04466
04467
if (handleValue) {
04468
04469 *dumpControl |=
DCB_DUMP_ENABLED;
04470
04471
04472
04473
04474
04475
04476
if ( handleValue == 3 ) {
04477
04478 *dumpControl |=
DCB_TRIAGE_DUMP_ENABLED;
04479
04480 }
else if ( handleValue == 4 ) {
04481
04482 *dumpControl |= (
DCB_TRIAGE_DUMP_ENABLED |
DCB_TRIAGE_DUMP_ACT_UPON_ENABLED );
04483
04484 }
else if ( ( handleValue == 2 ) ||
04485 (
MmPhysicalMemoryBlock->
NumberOfPages >= ( 0x80000000 >>
PAGE_SHIFT ) ) ) {
04486
04487 *dumpControl |=
DCB_SUMMARY_DUMP_ENABLED;
04488
04489
IoDebugPrint((2,
"IopInitializeDCB: SUMMARY DUMP ENABLED \n"));
04490
04491
04492
04493
04494
04495
04496 *numberOfHeaderPages =
BYTES_TO_PAGES(
04497
PAGE_SIZE +
04498 ( (
MmPhysicalMemoryBlock->
NumberOfPages >> 5) << 2 ) +
04499
sizeof(SUMMARY_DUMP_HEADER)
04500 );
04501
04502
IoDebugPrint((2,
"IopInitializeDCB: NumberOfHeader Pages = %x\n",numberOfHeaderPages));
04503
04504 }
04505 }
04506 }
04507 }
04508
04509 status =
IopGetRegistryValue( crashHandle,
04510
L"LogEvent",
04511 &keyValueInformation );
04512
04513
if (
NT_SUCCESS( status )) {
04514
if (keyValueInformation->DataLength) {
04515 handleValue = * ((PULONG) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset));
04516
ExFreePool( keyValueInformation);
04517
if (handleValue) {
04518 *dumpControl |=
DCB_SUMMARY_ENABLED;
04519 }
04520 }
04521 }
04522
04523 status =
IopGetRegistryValue( crashHandle,
04524
L"SendAlert",
04525 &keyValueInformation );
04526
04527
if (
NT_SUCCESS( status )) {
04528
if (keyValueInformation->DataLength) {
04529 handleValue = * ((PULONG) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset));
04530
ExFreePool( keyValueInformation);
04531
if (handleValue) {
04532 *dumpControl |=
DCB_SUMMARY_ENABLED;
04533 }
04534 }
04535 }
04536
04537
04538
04539
04540
04541 status =
IopGetRegistryValue( crashHandle,
04542
L"AutoReboot",
04543 &keyValueInformation );
04544
04545
04546
if (
NT_SUCCESS( status )) {
04547
if (keyValueInformation->DataLength) {
04548 *autoReboot = * ((PULONG) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset));
04549 }
04550
ExFreePool( keyValueInformation );
04551 }
04552
04553
04554
04555
04556
04557
if (*dumpControl == 0 && *autoReboot == 0) {
04558
if (crashHandleOpened ==
TRUE) {
04559
NtClose( crashHandle );
04560 }
04561
return;
04562 }
04563
04564 status =
IopGetRegistryValue( crashHandle,
04565
L"DumpFileSize",
04566 &keyValueInformation );
04567
04568
if (
NT_SUCCESS( status )) {
04569
if (keyValueInformation->DataLength) {
04570 *dumpFileSize = * ((PULONG) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset));
04571 }
04572
04573
ExFreePool( keyValueInformation );
04574 }
04575
return;
04576 }
04577
04578
04579 BOOLEAN
04580 IopInitializeDCB(
04581 )
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594
04595
04596
04597
04598 {
04599 HANDLE keyHandle;
04600 HANDLE crashHandle;
04601 LOGICAL crashHandleOpened;
04602 UNICODE_STRING keyName;
04603
NTSTATUS status;
04604 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
04605
PDUMP_CONTROL_BLOCK dcb;
04606 ULONG dumpControl;
04607 ULONG handleValue;
04608 ULONG autoReboot;
04609 PCHAR partitionName;
04610 ULONG dcbSize;
04611 LARGE_INTEGER page;
04612 ULONG numberOfHeaderPages;
04613 ULONG dumpFileSize;
04614
04615
04616
04617
04618
04619
IopReadDumpRegistry ( &dumpControl,
04620 &numberOfHeaderPages,
04621 &autoReboot,
04622 &dumpFileSize);
04623
04624
04625
04626
04627
04628
if (dumpControl == 0 && autoReboot == 0) {
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639
return TRUE;
04640 }
04641
04642
if (dumpControl &
DCB_TRIAGE_DUMP_ENABLED) {
04643 dumpControl &= ~
DCB_SUMMARY_ENABLED;
04644 dumpFileSize = TRIAGE_DUMP_SIZE;
04645 }
04646
04647
04648
04649
04650
04651
04652 dcbSize =
sizeof(
DUMP_CONTROL_BLOCK ) +
sizeof(
MINIPORT_NODE );
04653 dcb =
ExAllocatePoolWithTag(
NonPagedPool, dcbSize, 'pmuD' );
04654
if (!dcb) {
04655
IoDebugPrint((1,
"IopInitializeDCB: Not enough pool to allocate DCB0\n" ));
04656
IopLogErrorEvent(0,1,STATUS_SUCCESS,IO_DUMP_INITIALIZATION_FAILURE,0,
NULL,0,
NULL);
04657
return FALSE;
04658 }
04659
04660 RtlZeroMemory( dcb, dcbSize );
04661 dcb->
Type =
IO_TYPE_DCB;
04662 dcb->
Size = (
USHORT) dcbSize;
04663 dcb->
Flags = (UCHAR) (dumpControl | (autoReboot ?
DCB_AUTO_REBOOT : 0));
04664 dcb->
NumberProcessors =
KeNumberProcessors;
04665 dcb->
ProcessorArchitecture =
KeProcessorArchitecture;
04666 dcb->
MinorVersion = (
USHORT)
NtBuildNumber;
04667 dcb->
MajorVersion = (
USHORT) ((
NtBuildNumber >> 28) & 0xfffffff);
04668 dcb->
BuildNumber =
CmNtCSDVersion;
04669 dcb->
TriageDumpFlags =
DEFAULT_TRIAGE_DUMP_FLAGS;
04670
04671 dcb->
DumpFileSize.QuadPart = dumpFileSize;
04672
04673
04674
04675
04676
04677 dcb->
MemoryDescriptorLength =
sizeof(
PHYSICAL_MEMORY_DESCRIPTOR ) -
sizeof(
PHYSICAL_MEMORY_RUN ) +
04678 (
MmPhysicalMemoryBlock->
NumberOfRuns *
sizeof(
PHYSICAL_MEMORY_RUN ));
04679 dcb->
MemoryDescriptor =
ExAllocatePoolWithTag (
04680
NonPagedPool,
04681 dcb->
MemoryDescriptorLength,
04682 'pmuD'
04683 );
04684
if (!dcb->
MemoryDescriptor) {
04685
ExFreePool (dcb);
04686
04687
IoDebugPrint((1,
"IopInitializeDCB: Not enough pool to allocate DCB1\n" ));
04688
IopLogErrorEvent(0,1,STATUS_SUCCESS,IO_DUMP_INITIALIZATION_FAILURE,0,
NULL,0,
NULL);
04689
return FALSE;
04690 }
04691
04692 RtlCopyMemory (
04693 dcb->
MemoryDescriptor,
04694
MmPhysicalMemoryBlock,
04695 dcb->
MemoryDescriptorLength
04696 );
04697
04698
04699
04700
04701
04702 dcb->
HeaderSize = numberOfHeaderPages *
PAGE_SIZE;
04703 dcb->
HeaderPage =
ExAllocatePoolWithTag(
NonPagedPool, dcb->
HeaderSize, 'pmuD' );
04704
04705
if (!dcb->
HeaderPage) {
04706
ExFreePool (dcb->
MemoryDescriptor);
04707
ExFreePool (dcb);
04708
IoDebugPrint((1,
"IopInitializeDCB: Not enough pool to allocate DCB2\n" ));
04709
IopLogErrorEvent(0,1,STATUS_SUCCESS,IO_DUMP_INITIALIZATION_FAILURE,0,
NULL,0,
NULL);
04710
return FALSE;
04711 }
04712 page =
MmGetPhysicalAddress( dcb->
HeaderPage );
04713 dcb->
HeaderPfn = (ULONG)(page.QuadPart >>
PAGE_SHIFT);
04714
04715
04716
04717
04718
04719
04720
if (dumpControl &
DCB_TRIAGE_DUMP_ENABLED) {
04721
04722 dcb->
TriageDumpBuffer =
ExAllocatePoolWithTag (
NonPagedPool,
04723 dumpFileSize,
04724 'pmuD'
04725 );
04726
04727
if (!dcb->
TriageDumpBuffer) {
04728
ExFreePool (dcb->
HeaderPage);
04729
ExFreePool (dcb->
MemoryDescriptor);
04730
ExFreePool (dcb);
04731
IoDebugPrint((1,
"IopInitializeDCB: Not enough pool to allocate DCB3\n" ));
04732
IopLogErrorEvent(0,1,STATUS_SUCCESS,IO_DUMP_INITIALIZATION_FAILURE,0,
NULL,0,
NULL);
04733
return FALSE;
04734 }
04735
04736 dcb->
TriageDumpBufferSize = dumpFileSize;
04737 }
04738
04739
IopDumpControlBlock = dcb;
04740
04741
return TRUE;
04742 }
04743
04744
04745 BOOLEAN
04746 IopConfigureCrashDump(
04747 IN HANDLE hPageFile
04748 )
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772
04773
04774
04775
04776
04777
04778
04779 {
04780 ULONG dwStatus;
04781
PFILE_OBJECT fileObject;
04782
PDEVICE_OBJECT deviceObject;
04783
04784
04785
04786
04787
04788
if (!
IopDumpControlBlock) {
04789
if (!
IopInitializeDCB()) {
04790
return TRUE;
04791 }
04792 }
04793
04794
04795
04796
04797
if (!
IopDumpControlBlock){
04798
return TRUE;
04799 }
04800
04801
04802
04803
04804
04805
if ( !(
IopDumpControlBlock->
Flags & (
DCB_DUMP_ENABLED |
DCB_SUMMARY_ENABLED) ) ) {
04806
return TRUE;
04807 }
04808
04809
04810
04811
04812
04813
IoDebugPrint((2,
"[IoPageFileCreated]: Page file dump\n"));
04814
04815
04816 dwStatus =
ObReferenceObjectByHandle(
04817 hPageFile,
04818 0,
04819
IoFileObjectType,
04820
KernelMode,
04821 (PVOID *) &fileObject,
04822
NULL
04823 );
04824
04825
if (!
NT_SUCCESS( dwStatus )) {
04826
IoDebugPrint((1,
"[IoPageFileCreated]: ObReferenceObjectByHandle for Paging file failed status = %x\n",dwStatus));
04827
goto error_return;
04828 }
04829
04830
04831
04832
04833
04834
04835
04836 deviceObject = fileObject->DeviceObject;
04837
04838
ObDereferenceObject( fileObject );
04839
04840
04841
04842
04843
04844
04845
if ( ! (deviceObject->
Flags &
DO_SYSTEM_BOOT_PARTITION) ) {
04846
return FALSE;
04847 }
04848
04849
04850
04851
04852
04853 dwStatus =
IoGetDumpStack (
L"dump_",
04854 &
IopDumpControlBlock->
DumpStack,
04855
DeviceUsageTypeDumpFile,
04856
FALSE);
04857
04858
if (!
NT_SUCCESS(dwStatus)) {
04859
IoDebugPrint((1,
"IoPageFileCreated: Could not load dump stack status = %x\n",dwStatus) );
04860
goto error_return;
04861 }
04862
04863
IopDumpControlBlock->
DumpStack->Init.CrashDump =
TRUE;
04864
04865
IopDumpControlBlock->
DumpStack->Init.MemoryBlock =
ExAllocatePoolWithTag (
04866
NonPagedPool,
04867
IO_DUMP_MEMORY_BLOCK_PAGES *
PAGE_SIZE,
04868 'pmuD'
04869 );
04870
04871
if (!
IopDumpControlBlock->
DumpStack->Init.MemoryBlock) {
04872 dwStatus = STATUS_NO_MEMORY;
04873
goto error_return;
04874 }
04875
04876
04877
04878
04879
04880
IopDumpControlBlock->
DumpFileSize =
IopCalculateRequiredDumpSpace(
04881
IopDumpControlBlock->
Flags,
04882
IopDumpControlBlock->
HeaderSize,
04883
IopDumpControlBlock->
MemoryDescriptor->
NumberOfPages,
04884
IopDumpControlBlock->
MemoryDescriptor->
NumberOfPages
04885 );
04886
04887
04888
04889
04890
04891
04892 dwStatus =
IopCompleteDumpInitialization(hPageFile);
04893
04894 error_return:
04895
04896
04897
04898
04899
04900
04901
04902
if (!
NT_SUCCESS(dwStatus)) {
04903
IoDebugPrint((1,
"IopPageFileCreated: Page File dump init FAILED status = %x\n",dwStatus));
04904
04905
IopLogErrorEvent(0,3,STATUS_SUCCESS,IO_DUMP_PAGE_CONFIG_FAILED,0,
NULL,0,
NULL);
04906
04907
IopFreeDCB(
FALSE);
04908
04909 }
04910
04911
return TRUE;
04912 }
04913
04914
04915
04916
04917
04918
04919
#if DBG
04920
04921 ULONG IopDebugLevel = 0;
04922 UCHAR IopBuffer[128];
04923
04924
04925
VOID
04926 IopDebugPrint(
04927 ULONG Level,
04928 PCHAR Format,
04929 ...
04930 )
04931 {
04932 va_list ap;
04933
04934 va_start(ap, Format);
04935
04936
if (IopDebugLevel >= Level) {
04937 vsprintf(IopBuffer, Format, ap);
04938
DbgPrint(IopBuffer);
04939 }
04940
04941 va_end(ap);
04942 }
04943
04944
#endif //DBG