From b0c64e3f9fbbfd6541dd1cd7eceea73cc8faf2a2 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 18 Jul 2002 18:09:59 +0000 Subject: [PATCH] Added IOCTL_DISK_SET_PARTITION_INFO. Added checks for user induced errors. Added basic shutdown/flush support. svn path=/trunk/; revision=3253 --- reactos/drivers/storage/cdrom/cdrom.c | 7 +- reactos/drivers/storage/disk/disk.c | 153 ++++++++++++++++---- reactos/drivers/storage/scsiport/scsiport.c | 43 ++---- reactos/include/ntos/disk.h | 42 +++--- 4 files changed, 166 insertions(+), 79 deletions(-) diff --git a/reactos/drivers/storage/cdrom/cdrom.c b/reactos/drivers/storage/cdrom/cdrom.c index 28b8ab50547..fa0f326f894 100644 --- a/reactos/drivers/storage/cdrom/cdrom.c +++ b/reactos/drivers/storage/cdrom/cdrom.c @@ -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: cdrom.c,v 1.11 2002/06/06 23:19:19 ekohl Exp $ +/* $Id: cdrom.c,v 1.12 2002/07/18 18:08:59 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -592,6 +592,11 @@ CdromClassDeviceControl(IN PDEVICE_OBJECT DeviceObject, return(ScsiClassDeviceControl(DeviceObject, Irp)); } + /* Verify the device if the user caused the error */ + if (!NT_SUCCESS(Status) && IoIsErrorUserInduced(Status)) + { + IoSetHardErrorOrVerifyDevice(Irp, DeviceObject); + } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Information; diff --git a/reactos/drivers/storage/disk/disk.c b/reactos/drivers/storage/disk/disk.c index 7d09e0cd2b4..683d92ecea1 100644 --- a/reactos/drivers/storage/disk/disk.c +++ b/reactos/drivers/storage/disk/disk.c @@ -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: disk.c,v 1.15 2002/06/06 23:19:53 ekohl Exp $ +/* $Id: disk.c,v 1.16 2002/07/18 18:09:29 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -43,6 +43,7 @@ typedef struct _DISK_DATA { ULONG HiddenSectors; ULONG PartitionNumber; + ULONG PartitionOrdinal; UCHAR PartitionType; BOOLEAN BootIndicator; BOOLEAN DriveNotReady; @@ -352,29 +353,31 @@ DiskClassCheckReadWrite(IN PDEVICE_OBJECT DeviceObject, } -// DiskClassCreateDeviceObject -// -// DESCRIPTION: -// Create the raw device and any partition devices on this drive -// -// RUN LEVEL: -// PASSIVE_LEVEL -// -// ARGUMENTS: -// IN PDRIVER_OBJECT DriverObject The system created driver object -// IN PCONTROLLER_OBJECT ControllerObject -// IN PIDE_CONTROLLER_EXTENSION ControllerExtension -// The IDE controller extension for -// this device -// IN int DriveIdx The index of the drive on this -// controller -// IN int HarddiskIdx The NT device number for this -// drive -// -// RETURNS: -// TRUE Drive exists and devices were created -// FALSE no devices were created for this device -// +/********************************************************************** + * NAME EXPORTED + * DiskClassCreateDeviceObject + * + * DESCRIPTION + * Create the raw device and any partition devices on this drive + * + * RUN LEVEL + * PASSIVE_LEVEL + * + * ARGUMENTS + * DriverObject + * The system created driver object + * RegistryPath + * PortDeviceObject + * PortNumber + * DiskNumber + * Capabilities + * InquiryData + * InitialzationData + * + * RETURN VALUE + * STATUS_SUCCESS: Device objects for disk and partitions were created. + * Others: Failure. + */ static NTSTATUS DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, @@ -643,6 +646,7 @@ DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, DiskData = (PDISK_DATA)(PartitionDeviceExtension + 1); DiskData->PartitionType = PartitionEntry->PartitionType; DiskData->PartitionNumber = PartitionNumber + 1; + DiskData->PartitionOrdinal = PartitionNumber + 1; DiskData->HiddenSectors = PartitionEntry->HiddenSectors; DiskData->BootIndicator = PartitionEntry->BootIndicator; DiskData->DriveNotReady = FALSE; @@ -770,9 +774,30 @@ DiskClassDeviceControl(IN PDEVICE_OBJECT DeviceObject, break; case IOCTL_DISK_SET_PARTITION_INFO: - DPRINT1("Unhandled IOCTL_DISK_SET_PARTITION_INFO\n"); - Status = STATUS_INVALID_DEVICE_REQUEST; - Information = 0; + if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < + sizeof(SET_PARTITION_INFORMATION)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else if (DiskData->PartitionNumber == 0) + { + Status = STATUS_INVALID_DEVICE_REQUEST; + } + else + { + PSET_PARTITION_INFORMATION PartitionInfo; + + PartitionInfo = (PSET_PARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer; + + Status = IoSetPartitionInformation(DeviceExtension->PhysicalDevice, + DeviceExtension->DiskGeometry->BytesPerSector, + DiskData->PartitionOrdinal, + PartitionInfo->PartitionType); + if (NT_SUCCESS(Status)) + { + DiskData->PartitionType = PartitionInfo->PartitionType; + } + } break; case IOCTL_DISK_GET_DRIVE_LAYOUT: @@ -837,6 +862,12 @@ DiskClassDeviceControl(IN PDEVICE_OBJECT DeviceObject, return(ScsiClassDeviceControl(DeviceObject, Irp)); } + /* Verify the device if the user caused the error */ + if (!NT_SUCCESS(Status) && IoIsErrorUserInduced(Status)) + { + IoSetHardErrorOrVerifyDevice(Irp, DeviceObject); + } + Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Information; IoCompleteRequest(Irp, @@ -871,14 +902,72 @@ NTSTATUS STDCALL DiskClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + PDEVICE_EXTENSION DeviceExtension; + PIO_STACK_LOCATION IrpStack; + PSCSI_REQUEST_BLOCK Srb; + DPRINT("DiskClassShutdownFlush() called!\n"); - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + DeviceExtension = DeviceObject->DeviceExtension; - return(STATUS_SUCCESS); + /* Allocate SRB */ + Srb = ExAllocatePool(NonPagedPool, + sizeof(SCSI_REQUEST_BLOCK)); + if (Srb == NULL) + { + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Initialize SRB */ + RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK)); + Srb->Length = sizeof(SCSI_REQUEST_BLOCK); + + /* Set device IDs */ + Srb->PathId = DeviceExtension->PathId; + Srb->TargetId = DeviceExtension->TargetId; + Srb->Lun = DeviceExtension->Lun; + + + /* FIXME: Flush write cache */ + + + /* Get current stack location */ + IrpStack = IoGetCurrentIrpStackLocation(Irp); + + + /* FIXME: Unlock removable media upon shutdown */ + + + /* No retry */ + IrpStack->Parameters.Others.Argument4 = (PVOID)0; + + /* Send shutdown or flush request to the port driver */ + Srb->CdbLength = 0; + if (IrpStack->MajorFunction == IRP_MJ_SHUTDOWN) + Srb->Function = SRB_FUNCTION_SHUTDOWN; + else + Srb->Function = SRB_FUNCTION_FLUSH; + + /* Init completion routine */ + IoSetCompletionRoutine(Irp, + ScsiClassIoComplete, + Srb, + TRUE, + TRUE, + TRUE); + + /* Prepare next stack location for a call to the port driver */ + IrpStack = IoGetNextIrpStackLocation(Irp); + IrpStack->MajorFunction = IRP_MJ_SCSI; + IrpStack->Parameters.Scsi.Srb = Srb; + Srb->OriginalRequest = Irp; + + /* Call port driver */ + return(IoCallDriver(DeviceExtension->PortDeviceObject, Irp)); } - /* EOF */ diff --git a/reactos/drivers/storage/scsiport/scsiport.c b/reactos/drivers/storage/scsiport/scsiport.c index 3f2ec5ea372..737fdf81e08 100644 --- a/reactos/drivers/storage/scsiport/scsiport.c +++ b/reactos/drivers/storage/scsiport/scsiport.c @@ -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: scsiport.c,v 1.17 2002/07/15 18:25:17 hbirr Exp $ +/* $Id: scsiport.c,v 1.18 2002/07/18 18:09:59 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -706,42 +706,17 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject, NTSTATUS Status = STATUS_SUCCESS; ULONG DataSize = 0; - DPRINT("ScsiPortDispatchScsi(DeviceObject %p Irp %p)\n", DeviceObject, Irp); DeviceExtension = DeviceObject->DeviceExtension; Stack = IoGetCurrentIrpStackLocation(Irp); - - switch(Stack->Parameters.DeviceIoControl.IoControlCode) - { - case IOCTL_SCSI_EXECUTE_IN: - { - DPRINT(" IOCTL_SCSI_EXECUTE_IN\n"); - } - break; - - case IOCTL_SCSI_EXECUTE_OUT: - { - DPRINT(" IOCTL_SCSI_EXECUTE_OUT\n"); - } - break; - - case IOCTL_SCSI_EXECUTE_NONE: - { - DPRINT(" IOCTL_SCSI_EXECUTE_NONE\n"); - } - break; - } - Srb = Stack->Parameters.Scsi.Srb; if (Srb == NULL) { - Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; @@ -757,11 +732,18 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject, switch (Srb->Function) { case SRB_FUNCTION_EXECUTE_SCSI: - DPRINT(" SRB_FUNCTION_EXECUTE_SCSI\n"); IoStartPacket(DeviceObject, Irp, NULL, NULL); - DPRINT("Returning STATUS_PENDING\n"); return(STATUS_PENDING); + case SRB_FUNCTION_SHUTDOWN: + case SRB_FUNCTION_FLUSH: + if (DeviceExtension->PortConfig.CachesData == TRUE) + { + IoStartPacket(DeviceObject, Irp, NULL, NULL); + return(STATUS_PENDING); + } + break; + case SRB_FUNCTION_CLAIM_DEVICE: { PSCSI_ADAPTER_BUS_INFO AdapterInfo; @@ -849,6 +831,11 @@ ScsiPortDispatchScsi(IN PDEVICE_OBJECT DeviceObject, } } break; + + default: + DPRINT1("SRB function not implemented (Function %lu)\n", Srb->Function); + Status = STATUS_NOT_IMPLEMENTED; + break; } Irp->IoStatus.Status = Status; diff --git a/reactos/include/ntos/disk.h b/reactos/include/ntos/disk.h index 3059f33b3dc..e2fd76cee34 100644 --- a/reactos/include/ntos/disk.h +++ b/reactos/include/ntos/disk.h @@ -1,4 +1,4 @@ -/* $Id: disk.h,v 1.8 2002/05/29 21:39:06 ekohl Exp $ +/* $Id: disk.h,v 1.9 2002/07/18 18:08:27 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -105,7 +105,8 @@ (P) == PARTITION_XINT13_EXTENDED) -typedef enum _MEDIA_TYPE { +typedef enum _MEDIA_TYPE +{ Unknown, F5_1Pt2_512, F3_1Pt44_512, @@ -123,30 +124,35 @@ typedef enum _MEDIA_TYPE { typedef struct _PARTITION_INFORMATION { - LARGE_INTEGER StartingOffset; - LARGE_INTEGER PartitionLength; - DWORD HiddenSectors; - DWORD PartitionNumber; - BYTE PartitionType; - BOOLEAN BootIndicator; - BOOLEAN RecognizedPartition; - BOOLEAN RewritePartition; + LARGE_INTEGER StartingOffset; + LARGE_INTEGER PartitionLength; + DWORD HiddenSectors; + DWORD PartitionNumber; + BYTE PartitionType; + BOOLEAN BootIndicator; + BOOLEAN RecognizedPartition; + BOOLEAN RewritePartition; } PARTITION_INFORMATION, *PPARTITION_INFORMATION; typedef struct _DRIVE_LAYOUT_INFORMATION { - DWORD PartitionCount; - DWORD Signature; - PARTITION_INFORMATION PartitionEntry[1]; + DWORD PartitionCount; + DWORD Signature; + PARTITION_INFORMATION PartitionEntry[1]; } DRIVE_LAYOUT_INFORMATION, *PDRIVE_LAYOUT_INFORMATION; +typedef struct _SET_PARTITION_INFORMATION +{ + ULONG PartitionType; +} SET_PARTITION_INFORMATION, *PSET_PARTITION_INFORMATION; + typedef struct _DISK_GEOMETRY { - LARGE_INTEGER Cylinders; - MEDIA_TYPE MediaType; - DWORD TracksPerCylinder; - DWORD SectorsPerTrack; - DWORD BytesPerSector; + LARGE_INTEGER Cylinders; + MEDIA_TYPE MediaType; + DWORD TracksPerCylinder; + DWORD SectorsPerTrack; + DWORD BytesPerSector; } DISK_GEOMETRY, *PDISK_GEOMETRY; #endif /* __INCLUDE_DISK_H */