mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 20:03:12 +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
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -428,7 +428,7 @@ VfatGetVolumeBitmap(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
VfatGetRetrievalPointers(PVFAT_IRP_CONTEXT IrpContext)
|
VfatGetRetrievalPointers(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
LARGE_INTEGER Vcn;
|
LARGE_INTEGER Vcn;
|
||||||
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
|
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
|
@ -524,6 +524,28 @@ VfatMoveFile(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
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)
|
NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: File system control
|
* FUNCTION: File system control
|
||||||
|
@ -554,6 +576,9 @@ NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
case FSCTL_MOVE_FILE:
|
case FSCTL_MOVE_FILE:
|
||||||
Status = VfatMoveFile(IrpContext);
|
Status = VfatMoveFile(IrpContext);
|
||||||
break;
|
break;
|
||||||
|
case FSCTL_ROS_QUERY_LCN_MAPPING:
|
||||||
|
Status = VfatRosQueryLcnMapping(IrpContext);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -441,6 +441,31 @@ ScsiClassDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
||||||
InputBufferLength = Stack->Parameters.DeviceIoControl.InputBufferLength;
|
InputBufferLength = Stack->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
OutputBufferLength = Stack->Parameters.DeviceIoControl.OutputBufferLength;
|
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)
|
if (IoControlCode == IOCTL_SCSI_GET_ADDRESS)
|
||||||
{
|
{
|
||||||
PSCSI_ADDRESS ScsiAddress;
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -132,6 +132,11 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT
|
||||||
#define SCSI_IOCTL_DATA_IN 1
|
#define SCSI_IOCTL_DATA_IN 1
|
||||||
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
|
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
|
||||||
|
|
||||||
|
typedef struct _DUMP_POINTERS
|
||||||
|
{
|
||||||
|
PVOID DeviceObject;
|
||||||
|
} DUMP_POINTERS, *PDUMP_POINTERS;
|
||||||
|
|
||||||
#endif /* __STORAGE_INCLUDE_NTDDSCSI_H */
|
#endif /* __STORAGE_INCLUDE_NTDDSCSI_H */
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -13,6 +13,14 @@ CcRosInitializeFileCache (PFILE_OBJECT FileObject,
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
CcRosReleaseFileCache (PFILE_OBJECT FileObject);
|
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/cctypes.h>
|
||||||
|
|
||||||
#include <ddk/ccfuncs.h>
|
#include <ddk/ccfuncs.h>
|
||||||
|
|
|
@ -2,9 +2,12 @@
|
||||||
#define __INCLUDE_NAPI_CORE_H
|
#define __INCLUDE_NAPI_CORE_H
|
||||||
|
|
||||||
#include "../ntoskrnl/include/internal/ke.h"
|
#include "../ntoskrnl/include/internal/ke.h"
|
||||||
|
#include <ddk/ntddscsi.h>
|
||||||
|
|
||||||
#define MM_CORE_DUMP_HEADER_MAGIC (0xdeafbead)
|
#define MM_CORE_DUMP_HEADER_MAGIC (0xdeafbead)
|
||||||
#define MM_CORE_DUMP_HEADER_VERSION (0x1)
|
#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_MINIMAL (0x1)
|
||||||
#define MM_CORE_DUMP_TYPE_FULL (0x2)
|
#define MM_CORE_DUMP_TYPE_FULL (0x2)
|
||||||
|
|
||||||
|
@ -21,15 +24,12 @@ typedef struct _MM_CORE_DUMP_HEADER
|
||||||
ULONG PhysicalMemorySize;
|
ULONG PhysicalMemorySize;
|
||||||
} MM_CORE_DUMP_HEADER, *PMM_CORE_DUMP_HEADER;
|
} MM_CORE_DUMP_HEADER, *PMM_CORE_DUMP_HEADER;
|
||||||
|
|
||||||
typedef struct _MM_DUMP_POINTERS
|
typedef struct MM_CORE_DUMP_FUNCTIONS
|
||||||
{
|
{
|
||||||
PVOID Context;
|
NTSTATUS STDCALL (*DumpPrepare)(PDEVICE_OBJECT DeviceObject, PDUMP_POINTERS DumpPointers);
|
||||||
NTSTATUS (*DeviceInit)(PVOID Context);
|
NTSTATUS STDCALL (*DumpInit)(VOID);
|
||||||
NTSTATUS (*DeviceWrite)(PVOID Context, ULONG Block, PMDL Mdl);
|
NTSTATUS STDCALL (*DumpWrite)(LARGE_INTEGER Address, PMDL Mdl);
|
||||||
NTSTATUS (*DeviceFinish)(PVOID Context);
|
NTSTATUS STDCALL (*DumpFinish)(VOID);
|
||||||
} MM_DUMP_POINTERS, *PMM_DUMP_POINTERS;
|
} MM_CORE_DUMP_FUNCTIONS, *PMM_CORE_DUMP_FUNCTIONS;
|
||||||
|
|
||||||
#define FSCTL_GET_DUMP_BLOCK_MAP (('R' << 24) | 0xF1)
|
|
||||||
#define IOCTL_GET_DUMP_POINTERS (('R' << 24) | 0xF2)
|
|
||||||
|
|
||||||
#endif /* __INCLUDE_NAPI_CORE_H */
|
#endif /* __INCLUDE_NAPI_CORE_H */
|
||||||
|
|
|
@ -646,5 +646,9 @@ VOID
|
||||||
MmRawDeleteVirtualMapping(PVOID Address);
|
MmRawDeleteVirtualMapping(PVOID Address);
|
||||||
VOID
|
VOID
|
||||||
MiStopPagerThread(VOID);
|
MiStopPagerThread(VOID);
|
||||||
|
NTSTATUS
|
||||||
|
MmCreateVirtualMappingDump(PVOID Address,
|
||||||
|
ULONG flProtect,
|
||||||
|
PHYSICAL_ADDRESS PhysicalAddress);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/bug.c
|
* FILE: ntoskrnl/ke/bug.c
|
||||||
|
@ -94,6 +94,7 @@ KeBugCheckWithTf(ULONG BugCheckCode,
|
||||||
{
|
{
|
||||||
PRTL_MESSAGE_RESOURCE_ENTRY Message;
|
PRTL_MESSAGE_RESOURCE_ENTRY Message;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
/* Make sure we're switching back to the blue screen and print messages on it */
|
/* Make sure we're switching back to the blue screen and print messages on it */
|
||||||
HalReleaseDisplayOwnership();
|
HalReleaseDisplayOwnership();
|
||||||
|
@ -103,6 +104,10 @@ KeBugCheckWithTf(ULONG BugCheckCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
__asm__("cli\n\t");
|
__asm__("cli\n\t");
|
||||||
|
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
|
||||||
|
{
|
||||||
|
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
||||||
|
}
|
||||||
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
|
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
|
||||||
BugCheckCode,
|
BugCheckCode,
|
||||||
BugCheckParameter1,
|
BugCheckParameter1,
|
||||||
|
@ -174,12 +179,17 @@ KeBugCheckEx(ULONG BugCheckCode,
|
||||||
{
|
{
|
||||||
PRTL_MESSAGE_RESOURCE_ENTRY Message;
|
PRTL_MESSAGE_RESOURCE_ENTRY Message;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
/* Make sure we're switching back to the blue screen and print messages on it */
|
/* Make sure we're switching back to the blue screen and print messages on it */
|
||||||
HalReleaseDisplayOwnership();
|
HalReleaseDisplayOwnership();
|
||||||
KdDebugState |= KD_DEBUG_SCREEN;
|
KdDebugState |= KD_DEBUG_SCREEN;
|
||||||
|
|
||||||
__asm__("cli\n\t");
|
__asm__("cli\n\t");
|
||||||
|
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
|
||||||
|
{
|
||||||
|
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
||||||
|
}
|
||||||
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
|
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
|
||||||
BugCheckCode,
|
BugCheckCode,
|
||||||
BugCheckParameter1,
|
BugCheckParameter1,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/main.c
|
* FILE: ntoskrnl/ke/main.c
|
||||||
|
@ -51,6 +51,7 @@
|
||||||
#include <internal/nls.h>
|
#include <internal/nls.h>
|
||||||
#include <reactos/bugcodes.h>
|
#include <reactos/bugcodes.h>
|
||||||
#include <ntos/bootvid.h>
|
#include <ntos/bootvid.h>
|
||||||
|
#include <napi/core.h>
|
||||||
|
|
||||||
#ifdef HALDBG
|
#ifdef HALDBG
|
||||||
#include <internal/ntosdbg.h>
|
#include <internal/ntosdbg.h>
|
||||||
|
@ -78,6 +79,7 @@ static ULONG FirstKrnlPhysAddr;
|
||||||
static ULONG LastKrnlPhysAddr;
|
static ULONG LastKrnlPhysAddr;
|
||||||
static ULONG LastKernelAddress;
|
static ULONG LastKernelAddress;
|
||||||
volatile BOOLEAN Initialized = FALSE;
|
volatile BOOLEAN Initialized = FALSE;
|
||||||
|
extern ULONG MmCoreDumpType;
|
||||||
|
|
||||||
extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
|
extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
|
||||||
|
|
||||||
|
@ -384,6 +386,22 @@ ExpInitializeExecutive(VOID)
|
||||||
p2 += 12;
|
p2 += 12;
|
||||||
NoBootScreen = TRUE;
|
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;
|
p1 = p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/i386/page.c
|
* FILE: ntoskrnl/mm/i386/page.c
|
||||||
|
@ -973,6 +973,45 @@ BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
|
||||||
return((!(Pte & PA_PRESENT)) && Pte != 0);
|
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
|
NTSTATUS
|
||||||
MmCreateVirtualMappingForKernel(PVOID Address,
|
MmCreateVirtualMappingForKernel(PVOID Address,
|
||||||
ULONG flProtect,
|
ULONG flProtect,
|
||||||
|
@ -1117,6 +1156,8 @@ MmCreatePageFileMapping(PEPROCESS Process,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/pagefile.c
|
* FILE: ntoskrnl/mm/pagefile.c
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
#include <internal/mm.h>
|
#include <internal/mm.h>
|
||||||
#include <napi/core.h>
|
#include <napi/core.h>
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
|
#include <internal/ldr.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
@ -92,12 +93,14 @@ static ULONG MiReservedSwapPages;
|
||||||
*/
|
*/
|
||||||
#define MM_PAGEFILE_COMMIT_GRACE (256)
|
#define MM_PAGEFILE_COMMIT_GRACE (256)
|
||||||
|
|
||||||
static PVOID MmCoreDumpPageFrame;
|
static PVOID MmCoreDumpPageFrame = NULL;
|
||||||
static PULONG MmCoreDumpBlockMap;
|
|
||||||
static ULONG MmCoreDumpSize;
|
static ULONG MmCoreDumpSize;
|
||||||
static PULONG MmCoreDumpBlockMap = NULL;
|
static DUMP_POINTERS MmCoreDumpPointers;
|
||||||
static MM_DUMP_POINTERS MmCoreDumpDeviceFuncs;
|
static PMM_CORE_DUMP_FUNCTIONS MmCoreDumpFunctions;
|
||||||
ULONG MmCoreDumpType;
|
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.
|
* Translate between a swap entry and a file and offset pair.
|
||||||
|
@ -279,14 +282,17 @@ MmInitPagingFile(VOID)
|
||||||
/*
|
/*
|
||||||
* Initialize the crash dump support.
|
* Initialize the crash dump support.
|
||||||
*/
|
*/
|
||||||
MmCoreDumpPageFrame = MmAllocateSection(PAGE_SIZE);
|
if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE)
|
||||||
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
|
|
||||||
{
|
{
|
||||||
MmCoreDumpSize = MmStats.NrTotalPages * 4096 + 1024 * 1024;
|
MmCoreDumpPageFrame = MmAllocateSection(PAGE_SIZE);
|
||||||
}
|
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
|
||||||
else
|
{
|
||||||
{
|
MmCoreDumpSize = MmStats.NrTotalPages * 4096 + 1024 * 1024;
|
||||||
MmCoreDumpSize = 1024 * 1024;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MmCoreDumpSize = 1024 * 1024;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,6 +434,33 @@ MmAllocSwapPage(VOID)
|
||||||
return(0);
|
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
|
NTSTATUS STDCALL
|
||||||
MmDumpToPagingFile(ULONG BugCode,
|
MmDumpToPagingFile(ULONG BugCode,
|
||||||
ULONG BugCodeParameter1,
|
ULONG BugCodeParameter1,
|
||||||
|
@ -437,22 +470,23 @@ MmDumpToPagingFile(ULONG BugCode,
|
||||||
PKTRAP_FRAME TrapFrame)
|
PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
PMM_CORE_DUMP_HEADER Headers;
|
PMM_CORE_DUMP_HEADER Headers;
|
||||||
PVOID Context;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
UCHAR MdlBase[sizeof(MDL) + sizeof(PVOID)];
|
UCHAR MdlBase[sizeof(MDL) + sizeof(PVOID)];
|
||||||
PMDL Mdl = (PMDL)MdlBase;
|
PMDL Mdl = (PMDL)MdlBase;
|
||||||
PETHREAD Thread = PsGetCurrentThread();
|
PETHREAD Thread = PsGetCurrentThread();
|
||||||
ULONG StackSize;
|
ULONG StackSize;
|
||||||
PULONG MdlMap;
|
PULONG MdlMap;
|
||||||
ULONG NextOffset = 0;
|
LONGLONG NextOffset = 0;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers;
|
||||||
|
LARGE_INTEGER DiskOffset;
|
||||||
|
|
||||||
if (MmCoreDumpBlockMap == NULL)
|
if (MmCoreDumpPageFile == 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("MM: Dumping core");
|
DbgPrint("\nMM: Dumping core: ");
|
||||||
|
|
||||||
/* Prepare the dump headers. */
|
/* Prepare the dump headers. */
|
||||||
Headers = (PMM_CORE_DUMP_HEADER)MmCoreDumpPageFrame;
|
Headers = (PMM_CORE_DUMP_HEADER)MmCoreDumpPageFrame;
|
||||||
|
@ -482,8 +516,7 @@ MmDumpToPagingFile(ULONG BugCode,
|
||||||
Headers->PhysicalMemorySize = MmStats.NrTotalPages * PAGE_SIZE;
|
Headers->PhysicalMemorySize = MmStats.NrTotalPages * PAGE_SIZE;
|
||||||
|
|
||||||
/* Initialize the dump device. */
|
/* Initialize the dump device. */
|
||||||
Context = MmCoreDumpDeviceFuncs.Context;
|
MmCoreDumpFunctions->DumpInit();
|
||||||
Status = MmCoreDumpDeviceFuncs.DeviceInit(Context);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to initialize core dump device.\n");
|
DPRINT1("MM: Failed to initialize core dump device.\n");
|
||||||
|
@ -501,36 +534,24 @@ MmDumpToPagingFile(ULONG BugCode,
|
||||||
Mdl->ByteOffset = 0;
|
Mdl->ByteOffset = 0;
|
||||||
MdlMap = (PULONG)(Mdl + 1);
|
MdlMap = (PULONG)(Mdl + 1);
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize the retrieval offsets. */
|
||||||
|
RetrievalPointers = PagingFileList[MmCoreDumpPageFile]->RetrievalPointers;
|
||||||
|
|
||||||
/* Dump the header. */
|
/* Dump the header. */
|
||||||
MdlMap[0] = MmGetPhysicalAddress(MmCoreDumpPageFrame).u.LowPart;
|
MdlMap[0] = MmGetPhysicalAddress(MmCoreDumpPageFrame).u.LowPart;
|
||||||
Status = MmCoreDumpDeviceFuncs.DeviceWrite(Context,
|
DiskOffset = MmGetOffsetPageFile(RetrievalPointers, (LARGE_INTEGER)0LL);
|
||||||
MmCoreDumpBlockMap[NextOffset],
|
DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart;
|
||||||
Mdl);
|
Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to write core dump header\n.");
|
DPRINT1("MM: Failed to write core dump header\n.");
|
||||||
|
return(Status);
|
||||||
}
|
}
|
||||||
NextOffset++;
|
NextOffset += PAGE_SIZE;;
|
||||||
DbgPrint(".");
|
DbgPrint("00");
|
||||||
|
|
||||||
/* 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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Write out the contents of physical memory. */
|
/* Write out the contents of physical memory. */
|
||||||
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
|
if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL)
|
||||||
{
|
{
|
||||||
|
@ -539,24 +560,139 @@ MmDumpToPagingFile(ULONG BugCode,
|
||||||
LARGE_INTEGER PhysicalAddress;
|
LARGE_INTEGER PhysicalAddress;
|
||||||
PhysicalAddress.QuadPart = i * PAGE_SIZE;
|
PhysicalAddress.QuadPart = i * PAGE_SIZE;
|
||||||
MdlMap[0] = i * PAGE_SIZE;
|
MdlMap[0] = i * PAGE_SIZE;
|
||||||
MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
|
MmCreateVirtualMappingDump(MmCoreDumpPageFrame,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
PhysicalAddress);
|
PhysicalAddress);
|
||||||
Status =
|
DiskOffset = MmGetOffsetPageFile(RetrievalPointers,
|
||||||
MmCoreDumpDeviceFuncs.DeviceWrite(Context,
|
(LARGE_INTEGER)NextOffset);
|
||||||
MmCoreDumpBlockMap[NextOffset],
|
DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart;
|
||||||
Mdl);
|
Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to write page to core dump.\n");
|
DPRINT1("MM: Failed to write page to core dump.\n");
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
DbgPrint(".");
|
if ((i % ((1024*1024) / PAGE_SIZE)) == 0)
|
||||||
NextOffset++;
|
{
|
||||||
|
DbgPrint("\b\b%.2d", i / ((1024*1024)/PAGE_SIZE));
|
||||||
|
}
|
||||||
|
NextOffset += PAGE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("\n");
|
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);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -795,54 +931,11 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||||
|
|
||||||
/* Check whether this pagefile can be a crash dump target. */
|
/* Check whether this pagefile can be a crash dump target. */
|
||||||
if (PagingFile->CurrentSize.QuadPart >= MmCoreDumpSize &&
|
if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE &&
|
||||||
MmCoreDumpBlockMap != NULL)
|
PagingFile->CurrentSize.QuadPart >= MmCoreDumpSize &&
|
||||||
|
MmCoreDumpPageFile == 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
MmCoreDumpBlockMap =
|
MmInitializeCrashDump(FileHandle, i);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
NtClose(FileHandle);
|
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
|
; reactos/ntoskrnl/ntoskrnl.def
|
||||||
;
|
;
|
||||||
|
@ -771,6 +771,7 @@ RtlGetDefaultCodePage@8
|
||||||
RtlGetGroupSecurityDescriptor@12
|
RtlGetGroupSecurityDescriptor@12
|
||||||
RtlGetOwnerSecurityDescriptor@12
|
RtlGetOwnerSecurityDescriptor@12
|
||||||
RtlImageNtHeader@4
|
RtlImageNtHeader@4
|
||||||
|
RtlImageDirectoryEntryToData@16
|
||||||
RtlInitAnsiString@8
|
RtlInitAnsiString@8
|
||||||
RtlInitCodePageTable@8
|
RtlInitCodePageTable@8
|
||||||
RtlInitString@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
|
; reactos/ntoskrnl/ntoskrnl.def
|
||||||
;
|
;
|
||||||
|
@ -770,6 +770,7 @@ RtlGetDefaultCodePage=RtlGetDefaultCodePage@8
|
||||||
RtlGetGroupSecurityDescriptor=RtlGetGroupSecurityDescriptor@12
|
RtlGetGroupSecurityDescriptor=RtlGetGroupSecurityDescriptor@12
|
||||||
RtlGetOwnerSecurityDescriptor=RtlGetOwnerSecurityDescriptor@12
|
RtlGetOwnerSecurityDescriptor=RtlGetOwnerSecurityDescriptor@12
|
||||||
RtlImageNtHeader=RtlImageNtHeader@4
|
RtlImageNtHeader=RtlImageNtHeader@4
|
||||||
|
RtlImageDirectoryEntryToData=RtlImageDirectoryEntryToData@16
|
||||||
RtlInitAnsiString=RtlInitAnsiString@8
|
RtlInitAnsiString=RtlInitAnsiString@8
|
||||||
RtlInitCodePageTable=RtlInitCodePageTable@8
|
RtlInitCodePageTable=RtlInitCodePageTable@8
|
||||||
RtlInitString=RtlInitString@8
|
RtlInitString=RtlInitString@8
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue