mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Added support for crash dumps:-
* Recognize the option /CRASHDUMP on the kernel command line to specify the type of dump desired. * Added a new driver (diskdump) which wraps the miniport for the disk containing the pagefile and does the crash dump i/o. * Added a FSCTL to get the mapping between LCNs and disk offsets so crash dumps don't need to go through the filesystem. svn path=/trunk/; revision=5887
This commit is contained in:
parent
1d47b45a53
commit
9231f7b9a2
20 changed files with 937 additions and 116 deletions
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: fsctl.c,v 1.22 2003/08/10 20:01:16 hbirr Exp $
|
||||
/* $Id: fsctl.c,v 1.23 2003/08/27 21:28:07 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -428,7 +428,7 @@ VfatGetVolumeBitmap(PVFAT_IRP_CONTEXT IrpContext)
|
|||
static NTSTATUS
|
||||
VfatGetRetrievalPointers(PVFAT_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
LARGE_INTEGER Vcn;
|
||||
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
|
||||
PFILE_OBJECT FileObject;
|
||||
|
@ -524,6 +524,28 @@ VfatMoveFile(PVFAT_IRP_CONTEXT IrpContext)
|
|||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
VfatRosQueryLcnMapping(PVFAT_IRP_CONTEXT IrpContext)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
PROS_QUERY_LCN_MAPPING LcnQuery;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
|
||||
DPRINT("VfatGetRetrievalPointers(IrpContext %x)\n", IrpContext);
|
||||
|
||||
DeviceExt = IrpContext->DeviceExt;
|
||||
Stack = IrpContext->Stack;
|
||||
if (IrpContext->Irp->AssociatedIrp.SystemBuffer == NULL ||
|
||||
Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ROS_QUERY_LCN_MAPPING))
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
LcnQuery = (PROS_QUERY_LCN_MAPPING)(IrpContext->Irp->AssociatedIrp.SystemBuffer);
|
||||
LcnQuery->LcnDiskOffset.QuadPart = DeviceExt->FatInfo.dataStart * DeviceExt->FatInfo.BytesPerSector;
|
||||
IrpContext->Irp->IoStatus.Information = sizeof(ROS_QUERY_LCN_MAPPING);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
|
||||
/*
|
||||
* FUNCTION: File system control
|
||||
|
@ -554,6 +576,9 @@ NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
|
|||
case FSCTL_MOVE_FILE:
|
||||
Status = VfatMoveFile(IrpContext);
|
||||
break;
|
||||
case FSCTL_ROS_QUERY_LCN_MAPPING:
|
||||
Status = VfatRosQueryLcnMapping(IrpContext);
|
||||
break;
|
||||
default:
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: class2.c,v 1.38 2003/07/12 13:10:45 ekohl Exp $
|
||||
/* $Id: class2.c,v 1.39 2003/08/27 21:28:08 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -441,6 +441,31 @@ ScsiClassDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
|||
InputBufferLength = Stack->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = Stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
if (IoControlCode == IOCTL_SCSI_GET_DUMP_POINTERS)
|
||||
{
|
||||
PDUMP_POINTERS DumpPointers;
|
||||
|
||||
if (OutputBufferLength < sizeof(DUMP_POINTERS))
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return(STATUS_BUFFER_TOO_SMALL);
|
||||
}
|
||||
DumpPointers = (PDUMP_POINTERS)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
/* Initialize next stack location for call to the port driver */
|
||||
NextStack = IoGetNextIrpStackLocation(Irp);
|
||||
|
||||
NextStack->Parameters = Stack->Parameters;
|
||||
NextStack->MajorFunction = Stack->MajorFunction;
|
||||
NextStack->MinorFunction = Stack->MinorFunction;
|
||||
|
||||
/* Call port driver */
|
||||
return(IoCallDriver(DeviceExtension->PortDeviceObject,
|
||||
Irp));
|
||||
}
|
||||
if (IoControlCode == IOCTL_SCSI_GET_ADDRESS)
|
||||
{
|
||||
PSCSI_ADDRESS ScsiAddress;
|
||||
|
|
8
reactos/drivers/storage/diskdump/.cvsignore
Normal file
8
reactos/drivers/storage/diskdump/.cvsignore
Normal file
|
@ -0,0 +1,8 @@
|
|||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
||||
diskdump.coff
|
||||
*.o
|
||||
*.sym
|
||||
*.sys
|
||||
*.map
|
19
reactos/drivers/storage/diskdump/Makefile
Normal file
19
reactos/drivers/storage/diskdump/Makefile
Normal file
|
@ -0,0 +1,19 @@
|
|||
# $Id: Makefile,v 1.1 2003/08/27 21:28:08 dwelch Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_BOOTSTRAP = yes
|
||||
|
||||
TARGET_TYPE = export_driver
|
||||
|
||||
TARGET_NAME = diskdump
|
||||
|
||||
TARGET_DDKLIBS =
|
||||
|
||||
TARGET_OBJECTS = $(TARGET_NAME).o diskdump_helper.o
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
||||
# EOF
|
432
reactos/drivers/storage/diskdump/diskdump.c
Normal file
432
reactos/drivers/storage/diskdump/diskdump.c
Normal file
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2001, 2002, 2003 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: diskdump.c,v 1.1 2003/08/27 21:28:08 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/storage/diskdump/diskdump.c
|
||||
* PURPOSE: Dumping crash data to the pagefile
|
||||
* PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/scsi.h>
|
||||
#include <ddk/class2.h>
|
||||
#include <ddk/ntddscsi.h>
|
||||
#include <napi/core.h>
|
||||
#include "../scsiport/scsiport_int.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define VERSION "0.0.1"
|
||||
|
||||
/* PROTOTYPES ***************************************************************/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DiskDumpPrepare(PDEVICE_OBJECT StorageDevice, PDUMP_POINTERS DumpPointers);
|
||||
VOID
|
||||
DiskDumpScsiInvalid(VOID);
|
||||
VOID
|
||||
_DiskDumpScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
|
||||
IN PVOID HwDeviceExtension,
|
||||
...);
|
||||
NTSTATUS STDCALL
|
||||
DiskDumpInit(VOID);
|
||||
NTSTATUS STDCALL
|
||||
DiskDumpFinish(VOID);
|
||||
NTSTATUS STDCALL
|
||||
DiskDumpWrite(LARGE_INTEGER StartAddress, PMDL Mdl);
|
||||
|
||||
typedef VOID (*SCSIPORTNOTIFICATION)(IN SCSI_NOTIFICATION_TYPE NotificationType,
|
||||
IN PVOID HwDeviceExtension,
|
||||
...);
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
MM_CORE_DUMP_FUNCTIONS DiskDumpFunctions =
|
||||
{
|
||||
DiskDumpPrepare,
|
||||
DiskDumpInit,
|
||||
DiskDumpWrite,
|
||||
DiskDumpFinish,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PCH Name;
|
||||
ULONG Ordinal;
|
||||
PVOID OldFunction;
|
||||
PVOID NewFunction;
|
||||
} SUBSTITUTE_EXPORT;
|
||||
|
||||
static SCSI_REQUEST_BLOCK CoreDumpSrb;
|
||||
static DUMP_POINTERS CoreDumpPointers;
|
||||
static PDEVICE_OBJECT CoreDumpClassDevice;
|
||||
static PDEVICE_EXTENSION CoreDumpClass2DeviceExtension;
|
||||
static PDEVICE_OBJECT CoreDumpPortDevice;
|
||||
static SCSI_PORT_DEVICE_EXTENSION* CoreDumpPortDeviceExtension;
|
||||
BOOLEAN IsDumping = FALSE;
|
||||
static PDRIVER_OBJECT DiskDumpDriver;
|
||||
static UCHAR DiskDumpSenseData[SENSE_BUFFER_SIZE];
|
||||
static BOOLEAN IrqComplete, IrqNextRequest;
|
||||
PVOID OldScsiPortNotification;
|
||||
static SUBSTITUTE_EXPORT DiskDumpExports[] =
|
||||
{
|
||||
{"ScsiPortConvertPhysicalAddressToUlong", 2, NULL, NULL},
|
||||
{"ScsiPortConvertUlongToPhysicalAddress", 3, NULL, NULL},
|
||||
{"ScsiPortFreeDeviceBase", 5, NULL, DiskDumpScsiInvalid},
|
||||
{"ScsiPortGetBusData", 6, NULL, DiskDumpScsiInvalid},
|
||||
{"ScsiPortGetDeviceBase", 7, DiskDumpScsiInvalid},
|
||||
{"ScsiPortInitialize", 13, NULL, DiskDumpScsiInvalid},
|
||||
{"ScsiPortNotification", 17, NULL, _DiskDumpScsiPortNotification},
|
||||
{"ScsiPortReadPortBufferUlong", 19, NULL},
|
||||
{"ScsiPortReadPortBufferUshort", 20, NULL},
|
||||
{"ScsiPortReadPortUchar", 21, NULL, NULL},
|
||||
{"ScsiPortReadPortUshort", 23, NULL, NULL},
|
||||
{"ScsiPortStallExecution", 31, NULL, NULL},
|
||||
{"ScsiPortWritePortBufferUlong", 34, NULL},
|
||||
{"ScsiPortWritePortBufferUshort", 35, NULL},
|
||||
{"ScsiPortWritePortUchar", 36, NULL, NULL},
|
||||
{"ScsiDebugPrint", 0, NULL, NULL},
|
||||
};
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
DiskDumpScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
|
||||
IN PVOID HwDeviceExtension,
|
||||
...)
|
||||
{
|
||||
if (NotificationType == RequestComplete)
|
||||
{
|
||||
IrqComplete = TRUE;
|
||||
}
|
||||
if (NotificationType == NextRequest)
|
||||
{
|
||||
IrqNextRequest = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
DiskDumpScsiInvalid(VOID)
|
||||
{
|
||||
DbgPrint("DISKDUMP: Error: Miniport called a function not supported at dump time.\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
DiskDumpBuildRequest(LARGE_INTEGER StartingOffset, PMDL Mdl)
|
||||
{
|
||||
LARGE_INTEGER StartingBlock;
|
||||
PSCSI_REQUEST_BLOCK Srb;
|
||||
PCDB Cdb;
|
||||
ULONG LogicalBlockAddress;
|
||||
USHORT TransferBlocks;
|
||||
|
||||
/* Calculate logical block address */
|
||||
StartingBlock.QuadPart = StartingOffset.QuadPart >> CoreDumpClass2DeviceExtension->SectorShift;
|
||||
LogicalBlockAddress = (ULONG)StartingBlock.u.LowPart;
|
||||
|
||||
DPRINT("Logical block address: %lu\n", LogicalBlockAddress);
|
||||
|
||||
/* Allocate and initialize an SRB */
|
||||
Srb = &CoreDumpSrb;
|
||||
|
||||
Srb->SrbFlags = 0;
|
||||
Srb->Length = sizeof(SCSI_REQUEST_BLOCK); //SCSI_REQUEST_BLOCK_SIZE;
|
||||
Srb->OriginalRequest = NULL;
|
||||
Srb->PathId = CoreDumpClass2DeviceExtension->PathId;
|
||||
Srb->TargetId = CoreDumpClass2DeviceExtension->TargetId;
|
||||
Srb->Lun = CoreDumpClass2DeviceExtension->Lun;
|
||||
Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
|
||||
Srb->DataBuffer = Mdl->MappedSystemVa;
|
||||
Srb->DataTransferLength = PAGE_SIZE;
|
||||
Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
|
||||
Srb->QueueSortKey = LogicalBlockAddress;
|
||||
|
||||
Srb->SenseInfoBuffer = DiskDumpSenseData;
|
||||
Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
|
||||
|
||||
Srb->TimeOutValue =
|
||||
((Srb->DataTransferLength + 0xFFFF) >> 16) * CoreDumpClass2DeviceExtension->TimeOutValue;
|
||||
|
||||
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
||||
Srb->ScsiStatus = 0;
|
||||
Srb->NextSrb = 0;
|
||||
|
||||
Srb->CdbLength = 10;
|
||||
Cdb = (PCDB)Srb->Cdb;
|
||||
|
||||
/* Initialize ATAPI packet (12 bytes) */
|
||||
RtlZeroMemory(Cdb, MAXIMUM_CDB_SIZE);
|
||||
|
||||
Cdb->CDB10.LogicalUnitNumber = CoreDumpClass2DeviceExtension->Lun;
|
||||
TransferBlocks = (USHORT)(PAGE_SIZE >>
|
||||
CoreDumpClass2DeviceExtension->SectorShift);
|
||||
|
||||
/* Copy little endian values into CDB in big endian format */
|
||||
Cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte3;
|
||||
Cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte2;
|
||||
Cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte1;
|
||||
Cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&LogicalBlockAddress)->Byte0;
|
||||
|
||||
Cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&TransferBlocks)->Byte1;
|
||||
Cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&TransferBlocks)->Byte0;
|
||||
|
||||
|
||||
/* Write Command. */
|
||||
Srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
|
||||
Cdb->CDB10.OperationCode = SCSIOP_WRITE;
|
||||
|
||||
/* Leave caching disabled. */
|
||||
}
|
||||
|
||||
BOOLEAN STDCALL
|
||||
DiskDumpIsr(PKINTERRUPT Interrupt, PVOID ServiceContext)
|
||||
{
|
||||
if (!CoreDumpPortDeviceExtension->HwInterrupt(&CoreDumpPortDeviceExtension->MiniPortDeviceExtension))
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DiskDumpInit(VOID)
|
||||
{
|
||||
KIRQL CurrentIrql = KeGetCurrentIrql();
|
||||
IsDumping = TRUE;
|
||||
if (CurrentIrql >= CoreDumpPortDeviceExtension->Interrupt->SynchLevel)
|
||||
{
|
||||
DbgPrint("DISKDUMP: Error: Crash inside high priority interrupt routine.\n");
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
CoreDumpPortDeviceExtension->Interrupt->ServiceRoutine = DiskDumpIsr;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DiskDumpFinish(VOID)
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DiskDumpWrite(LARGE_INTEGER Address, PMDL Mdl)
|
||||
{
|
||||
KIRQL OldIrql, OldIrql2;
|
||||
KIRQL CurrentIrql = KeGetCurrentIrql();
|
||||
|
||||
if (CurrentIrql < (CoreDumpPortDeviceExtension->Interrupt->SynchLevel - 1))
|
||||
{
|
||||
KeRaiseIrql(CoreDumpPortDeviceExtension->Interrupt->SynchLevel - 1, &OldIrql);
|
||||
}
|
||||
|
||||
/* Adjust the address for the start of the partition. */
|
||||
Address.QuadPart +=
|
||||
(CoreDumpClass2DeviceExtension->StartingOffset.QuadPart + CoreDumpClass2DeviceExtension->DMByteSkew);
|
||||
|
||||
/* Assume the device is always able to transfer a page so no need to split up the transfer. */
|
||||
|
||||
/* Build an SRB to describe the write. */
|
||||
DiskDumpBuildRequest(Address, Mdl);
|
||||
|
||||
/* Start i/o on the HBA. */
|
||||
IrqComplete = IrqNextRequest = FALSE;
|
||||
KeRaiseIrql(CoreDumpPortDeviceExtension->Interrupt->SynchLevel, &OldIrql2);
|
||||
if (!CoreDumpPortDeviceExtension->HwStartIo(&CoreDumpPortDeviceExtension->MiniPortDeviceExtension,
|
||||
&CoreDumpSrb))
|
||||
{
|
||||
KeLowerIrql(OldIrql);
|
||||
DbgPrint("DISKDUMP: Error: Miniport HwStartIo failed.\n");
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
KeLowerIrql(OldIrql2);
|
||||
|
||||
/* Wait for the miniport to finish. */
|
||||
__asm__ ("sti\n\t");
|
||||
while (!IrqComplete || !IrqNextRequest)
|
||||
{
|
||||
__asm__ ("hlt\n\t");
|
||||
}
|
||||
if (CurrentIrql < (CoreDumpPortDeviceExtension->Interrupt->SynchLevel - 1))
|
||||
{
|
||||
KeLowerIrql(OldIrql);
|
||||
}
|
||||
__asm__("cli\n\t");
|
||||
|
||||
/* Check the result. */
|
||||
if (SRB_STATUS(CoreDumpSrb.SrbStatus) != SRB_STATUS_SUCCESS)
|
||||
{
|
||||
DbgPrint("DISKDUMP: Error: SRB failed.\n");
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DiskDumpPrepare(PDEVICE_OBJECT StorageDevice, PDUMP_POINTERS DumpPointers)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PVOID ImportDirectory;
|
||||
ULONG ImportDirectorySize;
|
||||
PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory;
|
||||
PVOID DriverBase;
|
||||
PCH Name;
|
||||
ULONG i;
|
||||
ULONG Hint;
|
||||
PVOID* ImportAddressList;
|
||||
PULONG FunctionNameList;
|
||||
|
||||
/* Save the information from the kernel. */
|
||||
CoreDumpClassDevice = StorageDevice;
|
||||
CoreDumpPointers = *DumpPointers;
|
||||
CoreDumpClass2DeviceExtension = (PDEVICE_EXTENSION)CoreDumpClassDevice->DeviceExtension;
|
||||
CoreDumpPortDevice = DumpPointers->DeviceObject;
|
||||
CoreDumpPortDeviceExtension = CoreDumpPortDevice->DeviceExtension;
|
||||
|
||||
/* Replace all the miniport driver's imports with our functions. */
|
||||
DriverBase = CoreDumpPortDevice->DriverObject->DriverStart;
|
||||
NtHeader = RtlImageNtHeader(DriverBase);
|
||||
ImportDirectory = RtlImageDirectoryEntryToData(DriverBase,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_IMPORT,
|
||||
&ImportDirectorySize);
|
||||
if (ImportDirectory == NULL || ImportDirectorySize == 0)
|
||||
{
|
||||
DbgPrint("DISKDUMP: Error: Miniport has no imports?\n");
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
/* Process each import module */
|
||||
ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)ImportDirectory;
|
||||
DPRINT("Processeing import directory at %p\n", ImportModuleDirectory);
|
||||
while (ImportModuleDirectory->dwRVAModuleName)
|
||||
{
|
||||
/* Check to make sure that import lib is kernel */
|
||||
Name = (PCHAR) DriverBase + ImportModuleDirectory->dwRVAModuleName;
|
||||
|
||||
if (strcmp(Name, "scsiport.sys") != 0)
|
||||
{
|
||||
DbgPrint("DISKDUMP: Warning: Miniport has illegal imports.\n");
|
||||
ImportModuleDirectory++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the import address list */
|
||||
ImportAddressList = (PVOID *) ((PUCHAR)DriverBase +
|
||||
ImportModuleDirectory->dwRVAFunctionAddressList);
|
||||
|
||||
/* Get the list of functions to import */
|
||||
if (ImportModuleDirectory->dwRVAFunctionNameList != 0)
|
||||
{
|
||||
FunctionNameList = (PULONG) ((PUCHAR)DriverBase +
|
||||
ImportModuleDirectory->dwRVAFunctionNameList);
|
||||
}
|
||||
else
|
||||
{
|
||||
FunctionNameList = (PULONG) ((PUCHAR)DriverBase +
|
||||
ImportModuleDirectory->dwRVAFunctionAddressList);
|
||||
}
|
||||
/* Walk through function list and fixup addresses */
|
||||
while (*FunctionNameList != 0L)
|
||||
{
|
||||
if ((*FunctionNameList) & 0x80000000) // hint
|
||||
{
|
||||
Name = NULL;
|
||||
|
||||
Hint = (*FunctionNameList) & 0xffff;
|
||||
}
|
||||
else // hint-name
|
||||
{
|
||||
Name = (PCHAR)((DWORD)DriverBase +
|
||||
*FunctionNameList + 2);
|
||||
Hint = *(PWORD)((DWORD)DriverBase + *FunctionNameList);
|
||||
}
|
||||
DPRINT(" Hint:%04x Name:%s\n", Hint, pName);
|
||||
|
||||
for (i = 0; i < (sizeof(DiskDumpExports) / sizeof(DiskDumpExports[0])); i++)
|
||||
{
|
||||
if (DiskDumpExports[i].Ordinal == Hint ||
|
||||
(Name != NULL && strcmp(DiskDumpExports[i].Name, Name) == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == (sizeof(DiskDumpExports) / sizeof(DiskDumpExports[0])))
|
||||
{
|
||||
DbgPrint("DISKDUMP: Error: Miniport imports unknown symbol %s.\n", Name);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (strcmp(Name, "ScsiPortNotification") == 0)
|
||||
{
|
||||
OldScsiPortNotification = *ImportAddressList;
|
||||
}
|
||||
DiskDumpExports[i].OldFunction = *ImportAddressList;
|
||||
if (DiskDumpExports[i].NewFunction != NULL)
|
||||
{
|
||||
*ImportAddressList = DiskDumpExports[i].NewFunction;
|
||||
}
|
||||
|
||||
ImportAddressList++;
|
||||
FunctionNameList++;
|
||||
}
|
||||
ImportModuleDirectory++;
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NAME EXPORTED
|
||||
* DriverEntry
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function initializes the driver, locates and claims
|
||||
* hardware resources, and creates various NT objects needed
|
||||
* to process I/O requests.
|
||||
*
|
||||
* RUN LEVEL
|
||||
* PASSIVE_LEVEL
|
||||
*
|
||||
* ARGUMENTS
|
||||
* DriverObject
|
||||
* System allocated Driver Object for this driver
|
||||
*
|
||||
* RegistryPath
|
||||
* Name of registry driver service key
|
||||
*
|
||||
* RETURN VALUE
|
||||
* Status
|
||||
*/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
DiskDumpDriver = DriverObject;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
7
reactos/drivers/storage/diskdump/diskdump.def
Normal file
7
reactos/drivers/storage/diskdump/diskdump.def
Normal file
|
@ -0,0 +1,7 @@
|
|||
; $Id: diskdump.def,v 1.1 2003/08/27 21:28:08 dwelch Exp $
|
||||
;
|
||||
; diskdump.def - export definition file for crash dump driver
|
||||
;
|
||||
LIBRARY DISKDUMP.SYS
|
||||
EXPORTS
|
||||
DiskDumpFunctions
|
7
reactos/drivers/storage/diskdump/diskdump.edf
Normal file
7
reactos/drivers/storage/diskdump/diskdump.edf
Normal file
|
@ -0,0 +1,7 @@
|
|||
; $Id: diskdump.edf,v 1.1 2003/08/27 21:28:08 dwelch Exp $
|
||||
;
|
||||
; diskdump.edf - export definition file for crash dump driver
|
||||
;
|
||||
LIBRARY DISKDUMP.SYS
|
||||
EXPORTS
|
||||
DiskDumpFunctions
|
38
reactos/drivers/storage/diskdump/diskdump.rc
Normal file
38
reactos/drivers/storage/diskdump/diskdump.rc
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "Crash Dump Disk Driver\0"
|
||||
VALUE "FileVersion", "0.0.1\0"
|
||||
VALUE "InternalName", "diskdump\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "diskdump.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
9
reactos/drivers/storage/diskdump/diskdump_helper.S
Normal file
9
reactos/drivers/storage/diskdump/diskdump_helper.S
Normal file
|
@ -0,0 +1,9 @@
|
|||
.globl __DiskDumpScsiPortNotification
|
||||
__DiskDumpScsiPortNotification:
|
||||
cmp $0, _IsDumping
|
||||
je .l1
|
||||
jmp _DiskDumpScsiPortNotification
|
||||
.l1:
|
||||
jmp *_OldScsiPortNotification
|
||||
.L2:
|
||||
jmp .L2
|
70
reactos/drivers/storage/scsiport/scsiport_int.h
Normal file
70
reactos/drivers/storage/scsiport/scsiport_int.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* SCSI_PORT_TIMER_STATES
|
||||
*
|
||||
* DESCRIPTION
|
||||
* An enumeration containing the states in the timer DFA
|
||||
*/
|
||||
typedef enum _SCSI_PORT_TIMER_STATES
|
||||
{
|
||||
IDETimerIdle,
|
||||
IDETimerCmdWait,
|
||||
IDETimerResetWaitForBusyNegate,
|
||||
IDETimerResetWaitForDrdyAssert
|
||||
} SCSI_PORT_TIMER_STATES;
|
||||
|
||||
|
||||
typedef struct _SCSI_PORT_DEVICE_BASE
|
||||
{
|
||||
LIST_ENTRY List;
|
||||
|
||||
PVOID MappedAddress;
|
||||
ULONG NumberOfBytes;
|
||||
SCSI_PHYSICAL_ADDRESS IoAddress;
|
||||
ULONG SystemIoBusNumber;
|
||||
} SCSI_PORT_DEVICE_BASE, *PSCSI_PORT_DEVICE_BASE;
|
||||
|
||||
/*
|
||||
* SCSI_PORT_DEVICE_EXTENSION
|
||||
*
|
||||
* DESCRIPTION
|
||||
* First part of the port objects device extension. The second
|
||||
* part is the miniport-specific device extension.
|
||||
*/
|
||||
|
||||
typedef struct _SCSI_PORT_DEVICE_EXTENSION
|
||||
{
|
||||
ULONG Length;
|
||||
ULONG MiniPortExtensionSize;
|
||||
PORT_CONFIGURATION_INFORMATION PortConfig;
|
||||
ULONG PortNumber;
|
||||
|
||||
KSPIN_LOCK IrpLock;
|
||||
KSPIN_LOCK SpinLock;
|
||||
PKINTERRUPT Interrupt;
|
||||
PIRP CurrentIrp;
|
||||
ULONG IrpFlags;
|
||||
|
||||
SCSI_PORT_TIMER_STATES TimerState;
|
||||
LONG TimerCount;
|
||||
|
||||
BOOLEAN Initializing;
|
||||
|
||||
LIST_ENTRY DeviceBaseListHead;
|
||||
|
||||
ULONG PortBusInfoSize;
|
||||
PSCSI_ADAPTER_BUS_INFO PortBusInfo;
|
||||
|
||||
PIO_SCSI_CAPABILITIES PortCapabilities;
|
||||
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PCONTROLLER_OBJECT ControllerObject;
|
||||
|
||||
PHW_STARTIO HwStartIo;
|
||||
PHW_INTERRUPT HwInterrupt;
|
||||
|
||||
PSCSI_REQUEST_BLOCK OriginalSrb;
|
||||
SCSI_REQUEST_BLOCK InternalSrb;
|
||||
SENSE_DATA InternalSenseData;
|
||||
|
||||
UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */
|
||||
} SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION;
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: ntddscsi.h,v 1.3 2003/06/22 16:35:58 ekohl Exp $
|
||||
/* $Id: ntddscsi.h,v 1.4 2003/08/27 21:28:08 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -132,6 +132,11 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT
|
|||
#define SCSI_IOCTL_DATA_IN 1
|
||||
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
|
||||
|
||||
typedef struct _DUMP_POINTERS
|
||||
{
|
||||
PVOID DeviceObject;
|
||||
} DUMP_POINTERS, *PDUMP_POINTERS;
|
||||
|
||||
#endif /* __STORAGE_INCLUDE_NTDDSCSI_H */
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -13,6 +13,14 @@ CcRosInitializeFileCache (PFILE_OBJECT FileObject,
|
|||
NTSTATUS STDCALL
|
||||
CcRosReleaseFileCache (PFILE_OBJECT FileObject);
|
||||
|
||||
#define FSCTL_ROS_QUERY_LCN_MAPPING \
|
||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 63, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
typedef struct _ROS_QUERY_LCN_MAPPING
|
||||
{
|
||||
LARGE_INTEGER LcnDiskOffset;
|
||||
} ROS_QUERY_LCN_MAPPING, *PROS_QUERY_LCN_MAPPING;
|
||||
|
||||
#include <ddk/cctypes.h>
|
||||
|
||||
#include <ddk/ccfuncs.h>
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
#define __INCLUDE_NAPI_CORE_H
|
||||
|
||||
#include "../ntoskrnl/include/internal/ke.h"
|
||||
#include <ddk/ntddscsi.h>
|
||||
|
||||
#define MM_CORE_DUMP_HEADER_MAGIC (0xdeafbead)
|
||||
#define MM_CORE_DUMP_HEADER_VERSION (0x1)
|
||||
|
||||
#define MM_CORE_DUMP_TYPE_NONE (0x0)
|
||||
#define MM_CORE_DUMP_TYPE_MINIMAL (0x1)
|
||||
#define MM_CORE_DUMP_TYPE_FULL (0x2)
|
||||
|
||||
|
@ -21,15 +24,12 @@ typedef struct _MM_CORE_DUMP_HEADER
|
|||
ULONG PhysicalMemorySize;
|
||||
} MM_CORE_DUMP_HEADER, *PMM_CORE_DUMP_HEADER;
|
||||
|
||||
typedef struct _MM_DUMP_POINTERS
|
||||
typedef struct MM_CORE_DUMP_FUNCTIONS
|
||||
{
|
||||
PVOID Context;
|
||||
NTSTATUS (*DeviceInit)(PVOID Context);
|
||||
NTSTATUS (*DeviceWrite)(PVOID Context, ULONG Block, PMDL Mdl);
|
||||
NTSTATUS (*DeviceFinish)(PVOID Context);
|
||||
} MM_DUMP_POINTERS, *PMM_DUMP_POINTERS;
|
||||
|
||||
#define FSCTL_GET_DUMP_BLOCK_MAP (('R' << 24) | 0xF1)
|
||||
#define IOCTL_GET_DUMP_POINTERS (('R' << 24) | 0xF2)
|
||||
NTSTATUS STDCALL (*DumpPrepare)(PDEVICE_OBJECT DeviceObject, PDUMP_POINTERS DumpPointers);
|
||||
NTSTATUS STDCALL (*DumpInit)(VOID);
|
||||
NTSTATUS STDCALL (*DumpWrite)(LARGE_INTEGER Address, PMDL Mdl);
|
||||
NTSTATUS STDCALL (*DumpFinish)(VOID);
|
||||
} MM_CORE_DUMP_FUNCTIONS, *PMM_CORE_DUMP_FUNCTIONS;
|
||||
|
||||
#endif /* __INCLUDE_NAPI_CORE_H */
|
||||
|
|
|
@ -646,5 +646,9 @@ VOID
|
|||
MmRawDeleteVirtualMapping(PVOID Address);
|
||||
VOID
|
||||
MiStopPagerThread(VOID);
|
||||
NTSTATUS
|
||||
MmCreateVirtualMappingDump(PVOID Address,
|
||||
ULONG flProtect,
|
||||
PHYSICAL_ADDRESS PhysicalAddress);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: bug.c,v 1.37 2003/08/24 12:08:16 dwelch Exp $
|
||||
/* $Id: bug.c,v 1.38 2003/08/27 21:28:08 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/bug.c
|
||||
|
@ -94,6 +94,7 @@ KeBugCheckWithTf(ULONG BugCheckCode,
|
|||
{
|
||||
PRTL_MESSAGE_RESOURCE_ENTRY Message;
|
||||
NTSTATUS Status;
|
||||
KIRQL OldIrql;
|
||||
|
||||
/* Make sure we're switching back to the blue screen and print messages on it */
|
||||
HalReleaseDisplayOwnership();
|
||||
|
@ -103,6 +104,10 @@ KeBugCheckWithTf(ULONG BugCheckCode,
|
|||
}
|
||||
|
||||
__asm__("cli\n\t");
|
||||
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
|
||||
{
|
||||
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
||||
}
|
||||
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
|
||||
BugCheckCode,
|
||||
BugCheckParameter1,
|
||||
|
@ -174,12 +179,17 @@ KeBugCheckEx(ULONG BugCheckCode,
|
|||
{
|
||||
PRTL_MESSAGE_RESOURCE_ENTRY Message;
|
||||
NTSTATUS Status;
|
||||
KIRQL OldIrql;
|
||||
|
||||
/* Make sure we're switching back to the blue screen and print messages on it */
|
||||
HalReleaseDisplayOwnership();
|
||||
KdDebugState |= KD_DEBUG_SCREEN;
|
||||
|
||||
__asm__("cli\n\t");
|
||||
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
|
||||
{
|
||||
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
||||
}
|
||||
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
|
||||
BugCheckCode,
|
||||
BugCheckParameter1,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: main.c,v 1.169 2003/08/24 12:08:16 dwelch Exp $
|
||||
/* $Id: main.c,v 1.170 2003/08/27 21:28:08 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/main.c
|
||||
|
@ -51,6 +51,7 @@
|
|||
#include <internal/nls.h>
|
||||
#include <reactos/bugcodes.h>
|
||||
#include <ntos/bootvid.h>
|
||||
#include <napi/core.h>
|
||||
|
||||
#ifdef HALDBG
|
||||
#include <internal/ntosdbg.h>
|
||||
|
@ -78,6 +79,7 @@ static ULONG FirstKrnlPhysAddr;
|
|||
static ULONG LastKrnlPhysAddr;
|
||||
static ULONG LastKernelAddress;
|
||||
volatile BOOLEAN Initialized = FALSE;
|
||||
extern ULONG MmCoreDumpType;
|
||||
|
||||
extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
|
||||
|
||||
|
@ -384,6 +386,22 @@ ExpInitializeExecutive(VOID)
|
|||
p2 += 12;
|
||||
NoBootScreen = TRUE;
|
||||
}
|
||||
else if (!_strnicmp(p2, "CRASHDUMP", 9))
|
||||
{
|
||||
p2 += 9;
|
||||
if (*p2 == ':')
|
||||
{
|
||||
p2++;
|
||||
if (!_strnicmp(p2, "FULL", 4))
|
||||
{
|
||||
MmCoreDumpType = MM_CORE_DUMP_TYPE_FULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
p1 = p2;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: page.c,v 1.58 2003/08/21 04:17:15 royce Exp $
|
||||
/* $Id: page.c,v 1.59 2003/08/27 21:28:08 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/i386/page.c
|
||||
|
@ -973,6 +973,45 @@ BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
|
|||
return((!(Pte & PA_PRESENT)) && Pte != 0);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
MmCreateVirtualMappingDump(PVOID Address,
|
||||
ULONG flProtect,
|
||||
PHYSICAL_ADDRESS PhysicalAddress)
|
||||
{
|
||||
ULONG Attributes;
|
||||
PULONG Pte;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (Address < (PVOID)KERNEL_BASE)
|
||||
{
|
||||
DPRINT1("No process\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
Attributes = ProtectToPTE(flProtect);
|
||||
if (!(Attributes & PA_PRESENT) && PhysicalAddress.QuadPart != 0)
|
||||
{
|
||||
DPRINT1("Setting physical address but not allowing access at address "
|
||||
"0x%.8X with attributes %x/%x.\n",
|
||||
Address, Attributes, flProtect);
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
Status = MmGetPageEntry2(Address, &Pte, FALSE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT))
|
||||
{
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
*Pte = PhysicalAddress.QuadPart | Attributes;
|
||||
FLUSH_TLB;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
MmCreateVirtualMappingForKernel(PVOID Address,
|
||||
ULONG flProtect,
|
||||
|
@ -1117,6 +1156,8 @@ MmCreatePageFileMapping(PEPROCESS Process,
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
||||
PVOID Address,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: pagefile.c,v 1.34 2003/08/10 20:03:10 hbirr Exp $
|
||||
/* $Id: pagefile.c,v 1.35 2003/08/27 21:28:08 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/pagefile.c
|
||||
|
@ -33,6 +33,7 @@
|
|||
#include <internal/mm.h>
|
||||
#include <napi/core.h>
|
||||
#include <internal/ps.h>
|
||||
#include <internal/ldr.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -92,12 +93,14 @@ static ULONG MiReservedSwapPages;
|
|||
*/
|
||||
#define MM_PAGEFILE_COMMIT_GRACE (256)
|
||||
|
||||
static PVOID MmCoreDumpPageFrame;
|
||||
static PULONG MmCoreDumpBlockMap;
|
||||
static PVOID MmCoreDumpPageFrame = NULL;
|
||||
static ULONG MmCoreDumpSize;
|
||||
static PULONG MmCoreDumpBlockMap = NULL;
|
||||
static MM_DUMP_POINTERS MmCoreDumpDeviceFuncs;
|
||||
ULONG MmCoreDumpType;
|
||||
static DUMP_POINTERS MmCoreDumpPointers;
|
||||
static PMM_CORE_DUMP_FUNCTIONS MmCoreDumpFunctions;
|
||||
static ULONG MmCoreDumpPageFile = 0xFFFFFFFF;
|
||||
static ROS_QUERY_LCN_MAPPING MmCoreDumpLcnMapping;
|
||||
|
||||
ULONG MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
|
||||
|
||||
/*
|
||||
* Translate between a swap entry and a file and offset pair.
|
||||
|
@ -279,14 +282,17 @@ MmInitPagingFile(VOID)
|
|||
/*
|
||||
* Initialize the crash dump support.
|
||||
*/
|
||||
MmCoreDumpPageFrame = MmAllocateSection(PAGE_SIZE);
|
||||
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
|
||||
if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE)
|
||||
{
|
||||
MmCoreDumpSize = MmStats.NrTotalPages * 4096 + 1024 * 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
MmCoreDumpSize = 1024 * 1024;
|
||||
MmCoreDumpPageFrame = MmAllocateSection(PAGE_SIZE);
|
||||
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
|
||||
{
|
||||
MmCoreDumpSize = MmStats.NrTotalPages * 4096 + 1024 * 1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
MmCoreDumpSize = 1024 * 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,6 +434,33 @@ MmAllocSwapPage(VOID)
|
|||
return(0);
|
||||
}
|
||||
|
||||
LARGE_INTEGER STATIC
|
||||
MmGetOffsetPageFile(PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers, LARGE_INTEGER Offset)
|
||||
{
|
||||
ULONG j;
|
||||
for (j = 0; j < RetrievalPointers->NumberOfPairs; j++)
|
||||
{
|
||||
if (Offset.QuadPart < RetrievalPointers->Pair[j].Vcn)
|
||||
{
|
||||
if (j == 0)
|
||||
{
|
||||
Offset.QuadPart += RetrievalPointers->Pair[0].Lcn - RetrievalPointers->StartVcn;
|
||||
}
|
||||
else
|
||||
{
|
||||
Offset.QuadPart += RetrievalPointers->Pair[j].Lcn - RetrievalPointers->Pair[j-1].Vcn;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j >= RetrievalPointers->NumberOfPairs)
|
||||
{
|
||||
CHECKPOINT1;
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
return(Offset);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
MmDumpToPagingFile(ULONG BugCode,
|
||||
ULONG BugCodeParameter1,
|
||||
|
@ -437,22 +470,23 @@ MmDumpToPagingFile(ULONG BugCode,
|
|||
PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
PMM_CORE_DUMP_HEADER Headers;
|
||||
PVOID Context;
|
||||
NTSTATUS Status;
|
||||
UCHAR MdlBase[sizeof(MDL) + sizeof(PVOID)];
|
||||
PMDL Mdl = (PMDL)MdlBase;
|
||||
PETHREAD Thread = PsGetCurrentThread();
|
||||
ULONG StackSize;
|
||||
PULONG MdlMap;
|
||||
ULONG NextOffset = 0;
|
||||
LONGLONG NextOffset = 0;
|
||||
ULONG i;
|
||||
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
|
||||
LARGE_INTEGER DiskOffset;
|
||||
|
||||
if (MmCoreDumpBlockMap == NULL)
|
||||
if (MmCoreDumpPageFile == 0xFFFFFFFF)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
DbgPrint("MM: Dumping core");
|
||||
DbgPrint("\nMM: Dumping core: ");
|
||||
|
||||
/* Prepare the dump headers. */
|
||||
Headers = (PMM_CORE_DUMP_HEADER)MmCoreDumpPageFrame;
|
||||
|
@ -482,8 +516,7 @@ MmDumpToPagingFile(ULONG BugCode,
|
|||
Headers->PhysicalMemorySize = MmStats.NrTotalPages * PAGE_SIZE;
|
||||
|
||||
/* Initialize the dump device. */
|
||||
Context = MmCoreDumpDeviceFuncs.Context;
|
||||
Status = MmCoreDumpDeviceFuncs.DeviceInit(Context);
|
||||
MmCoreDumpFunctions->DumpInit();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MM: Failed to initialize core dump device.\n");
|
||||
|
@ -501,36 +534,24 @@ MmDumpToPagingFile(ULONG BugCode,
|
|||
Mdl->ByteOffset = 0;
|
||||
MdlMap = (PULONG)(Mdl + 1);
|
||||
|
||||
|
||||
/* Initialize the retrieval offsets. */
|
||||
RetrievalPointers = PagingFileList[MmCoreDumpPageFile]->RetrievalPointers;
|
||||
|
||||
/* Dump the header. */
|
||||
MdlMap[0] = MmGetPhysicalAddress(MmCoreDumpPageFrame).u.LowPart;
|
||||
Status = MmCoreDumpDeviceFuncs.DeviceWrite(Context,
|
||||
MmCoreDumpBlockMap[NextOffset],
|
||||
Mdl);
|
||||
DiskOffset = MmGetOffsetPageFile(RetrievalPointers, (LARGE_INTEGER)0LL);
|
||||
DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart;
|
||||
Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MM: Failed to write core dump header\n.");
|
||||
return(Status);
|
||||
}
|
||||
NextOffset++;
|
||||
DbgPrint(".");
|
||||
|
||||
/* Write out the kernel mode stack of the faulting thread. */
|
||||
for (i = 0; i < (StackSize / PAGE_SIZE); i++)
|
||||
{
|
||||
Mdl->MappedSystemVa = (PVOID)(Thread->Tcb.StackLimit + (i * PAGE_SIZE));
|
||||
MdlMap[0] = MmGetPhysicalAddress(Mdl->MappedSystemVa).u.LowPart;
|
||||
Status =
|
||||
MmCoreDumpDeviceFuncs.DeviceWrite(Context,
|
||||
MmCoreDumpBlockMap[NextOffset],
|
||||
Mdl);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MM: Failed to write page to core dump.\n");
|
||||
return(Status);
|
||||
}
|
||||
DbgPrint(".");
|
||||
NextOffset++;
|
||||
}
|
||||
NextOffset += PAGE_SIZE;;
|
||||
DbgPrint("00");
|
||||
|
||||
|
||||
/* Write out the contents of physical memory. */
|
||||
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
|
||||
{
|
||||
|
@ -539,24 +560,139 @@ MmDumpToPagingFile(ULONG BugCode,
|
|||
LARGE_INTEGER PhysicalAddress;
|
||||
PhysicalAddress.QuadPart = i * PAGE_SIZE;
|
||||
MdlMap[0] = i * PAGE_SIZE;
|
||||
MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
|
||||
PAGE_READWRITE,
|
||||
PhysicalAddress);
|
||||
Status =
|
||||
MmCoreDumpDeviceFuncs.DeviceWrite(Context,
|
||||
MmCoreDumpBlockMap[NextOffset],
|
||||
Mdl);
|
||||
MmCreateVirtualMappingDump(MmCoreDumpPageFrame,
|
||||
PAGE_READWRITE,
|
||||
PhysicalAddress);
|
||||
DiskOffset = MmGetOffsetPageFile(RetrievalPointers,
|
||||
(LARGE_INTEGER)NextOffset);
|
||||
DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart;
|
||||
Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MM: Failed to write page to core dump.\n");
|
||||
return(Status);
|
||||
}
|
||||
DbgPrint(".");
|
||||
NextOffset++;
|
||||
if ((i % ((1024*1024) / PAGE_SIZE)) == 0)
|
||||
{
|
||||
DbgPrint("\b\b%.2d", i / ((1024*1024)/PAGE_SIZE));
|
||||
}
|
||||
NextOffset += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
DbgPrint("\n");
|
||||
MmCoreDumpFunctions->DumpFinish();
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
MmInitializeCrashDump(HANDLE PageFileHandle, ULONG PageFileNum)
|
||||
{
|
||||
PFILE_OBJECT PageFile;
|
||||
PDEVICE_OBJECT PageFileDevice;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
UNICODE_STRING DiskDumpName;
|
||||
ANSI_STRING ProcName;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
PMODULE_OBJECT ModuleObject;
|
||||
|
||||
Status = ZwFsControlFile(PageFileHandle,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&Iosb,
|
||||
FSCTL_ROS_QUERY_LCN_MAPPING,
|
||||
NULL,
|
||||
0,
|
||||
&MmCoreDumpLcnMapping,
|
||||
sizeof(ROS_QUERY_LCN_MAPPING));
|
||||
if (!NT_SUCCESS(Status) ||
|
||||
Iosb.Information != sizeof(ROS_QUERY_LCN_MAPPING))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Get the underlying storage device. */
|
||||
Status =
|
||||
ObReferenceObjectByHandle(PageFileHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
NULL,
|
||||
KernelMode,
|
||||
(PVOID*)&PageFile,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
PageFileDevice = PageFile->Vpb->RealDevice;
|
||||
|
||||
/* Get the dump pointers. */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_GET_DUMP_POINTERS,
|
||||
PageFileDevice,
|
||||
NULL,
|
||||
0,
|
||||
&MmCoreDumpPointers,
|
||||
sizeof(MmCoreDumpPointers),
|
||||
FALSE,
|
||||
&Event,
|
||||
&Iosb);
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->FileObject = PageFile;
|
||||
StackPtr->DeviceObject = PageFileDevice;
|
||||
StackPtr->Parameters.DeviceIoControl.InputBufferLength = 0;
|
||||
StackPtr->Parameters.DeviceIoControl.OutputBufferLength = sizeof(MmCoreDumpPointers);
|
||||
|
||||
Status = IoCallDriver(PageFileDevice,Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
Status = KeWaitForSingleObject(&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
}
|
||||
if (Status != STATUS_SUCCESS ||
|
||||
Iosb.Information != sizeof(MmCoreDumpPointers))
|
||||
{
|
||||
ObDereferenceObject(PageFile);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Load the diskdump driver. */
|
||||
RtlInitUnicodeStringFromLiteral(&DiskDumpName, L"DiskDump");
|
||||
ModuleObject = LdrGetModuleObject(&DiskDumpName);
|
||||
if (ModuleObject == NULL)
|
||||
{
|
||||
return(STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
}
|
||||
RtlInitAnsiString(&ProcName, "DiskDumpFunctions");
|
||||
Status = LdrGetProcedureAddress(ModuleObject->Base,
|
||||
&ProcName,
|
||||
0,
|
||||
(PVOID*)&MmCoreDumpFunctions);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(PageFile);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
/* Prepare for disk dumping. */
|
||||
Status = MmCoreDumpFunctions->DumpPrepare(PageFileDevice,
|
||||
&MmCoreDumpPointers);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(PageFile);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
MmCoreDumpPageFile = PageFileNum;
|
||||
ObDereferenceObject(PageFile);
|
||||
*(PULONG)0 = 0;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -795,54 +931,11 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
|||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||
|
||||
/* Check whether this pagefile can be a crash dump target. */
|
||||
if (PagingFile->CurrentSize.QuadPart >= MmCoreDumpSize &&
|
||||
MmCoreDumpBlockMap != NULL)
|
||||
if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE &&
|
||||
PagingFile->CurrentSize.QuadPart >= MmCoreDumpSize &&
|
||||
MmCoreDumpPageFile == 0xFFFFFFFF)
|
||||
{
|
||||
MmCoreDumpBlockMap =
|
||||
ExAllocatePool(NonPagedPool,
|
||||
(MmCoreDumpSize / PAGE_SIZE) * sizeof(ULONG));
|
||||
if (MmCoreDumpBlockMap == NULL)
|
||||
{
|
||||
DPRINT1("Failed to allocate block map.\n");
|
||||
NtClose(FileHandle);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
Status = ZwFsControlFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
FSCTL_GET_DUMP_BLOCK_MAP,
|
||||
&MmCoreDumpSize,
|
||||
sizeof(ULONG),
|
||||
MmCoreDumpBlockMap,
|
||||
(MmCoreDumpSize / PAGE_SIZE) * sizeof(ULONG));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to get dump block map (Status %X)\n", Status);
|
||||
NtClose(FileHandle);
|
||||
ExFreePool(MmCoreDumpBlockMap);
|
||||
MmCoreDumpBlockMap = NULL;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
Status = ZwDeviceIoControlFile(FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&IoStatus,
|
||||
IOCTL_GET_DUMP_POINTERS,
|
||||
NULL,
|
||||
0,
|
||||
&MmCoreDumpDeviceFuncs,
|
||||
sizeof(MmCoreDumpDeviceFuncs));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to get dump block map (Status %X)\n", Status);
|
||||
NtClose(FileHandle);
|
||||
ExFreePool(MmCoreDumpBlockMap);
|
||||
MmCoreDumpBlockMap = NULL;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
MmInitializeCrashDump(FileHandle, i);
|
||||
}
|
||||
NtClose(FileHandle);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntoskrnl.def,v 1.162 2003/08/19 23:59:08 dwelch Exp $
|
||||
; $Id: ntoskrnl.def,v 1.163 2003/08/27 21:28:08 dwelch Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
|
@ -771,6 +771,7 @@ RtlGetDefaultCodePage@8
|
|||
RtlGetGroupSecurityDescriptor@12
|
||||
RtlGetOwnerSecurityDescriptor@12
|
||||
RtlImageNtHeader@4
|
||||
RtlImageDirectoryEntryToData@16
|
||||
RtlInitAnsiString@8
|
||||
RtlInitCodePageTable@8
|
||||
RtlInitString@8
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntoskrnl.edf,v 1.150 2003/08/19 23:59:08 dwelch Exp $
|
||||
; $Id: ntoskrnl.edf,v 1.151 2003/08/27 21:28:08 dwelch Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
|
@ -770,6 +770,7 @@ RtlGetDefaultCodePage=RtlGetDefaultCodePage@8
|
|||
RtlGetGroupSecurityDescriptor=RtlGetGroupSecurityDescriptor@12
|
||||
RtlGetOwnerSecurityDescriptor=RtlGetOwnerSecurityDescriptor@12
|
||||
RtlImageNtHeader=RtlImageNtHeader@4
|
||||
RtlImageDirectoryEntryToData=RtlImageDirectoryEntryToData@16
|
||||
RtlInitAnsiString=RtlInitAnsiString@8
|
||||
RtlInitCodePageTable=RtlInitCodePageTable@8
|
||||
RtlInitString=RtlInitString@8
|
||||
|
|
Loading…
Reference in a new issue