/*
* ReactOS kernel
- * Copyright (C) 2001, 2002, 2003 ReactOS Team
+ * Copyright (C) 2001, 2002, 2003, 2004 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
* 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.38 2004/03/31 05:25:36 jimtabor Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/storage/disk/disk.c
* PURPOSE: disk class driver
- * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ * PROGRAMMER: Eric Kohl
*/
/* INCLUDES *****************************************************************/
BOOLEAN BootIndicator;
BOOLEAN DriveNotReady;
} DISK_DATA, *PDISK_DATA;
-
+
BOOLEAN STDCALL
DiskClassFindDevices(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath,
PCHAR Buffer;
ULONG Bus;
ULONG DeviceCount;
- BOOLEAN FoundDevice;
+ BOOLEAN FoundDevice = FALSE;
NTSTATUS Status;
DPRINT("DiskClassFindDevices() called.\n");
{
PDEVICE_EXTENSION DeviceExtension;
PDISK_DATA DiskData;
+ PIO_STACK_LOCATION IrpStack;
+ ULARGE_INTEGER EndingOffset;
DPRINT("DiskClassCheckReadWrite() called\n");
return(STATUS_INVALID_PARAMETER);
}
+
+
+ IrpStack = IoGetCurrentIrpStackLocation(Irp);
+ EndingOffset.QuadPart = IrpStack->Parameters.Read.ByteOffset.QuadPart +
+ IrpStack->Parameters.Read.Length;
+
+
+ DPRINT("Ending %I64d, and RealEnding %I64d! PartSize %I64d\n",EndingOffset.QuadPart,
+ DeviceExtension->PartitionLength.QuadPart,
+ DeviceExtension->PartitionLength.QuadPart /
+ DeviceExtension->DiskGeometry->BytesPerSector);
+
+ if ((DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
+ (DeviceExtension->DiskGeometry->MediaType == RemovableMedia))
+ {
+/* Assume if removable media and if Partition length is 0, Partition not built yet! */
+ if (DeviceExtension->PartitionLength.QuadPart == 0)
+ return(STATUS_SUCCESS);
+ }
+
+ if (EndingOffset.QuadPart > DeviceExtension->PartitionLength.QuadPart)
+ {
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ return(STATUS_INVALID_PARAMETER);
+ }
+
return(STATUS_SUCCESS);
}
DiskDeviceExtension->PathId = InquiryData->PathId;
DiskDeviceExtension->TargetId = InquiryData->TargetId;
DiskDeviceExtension->Lun = InquiryData->Lun;
+ DiskDeviceExtension->SrbFlags = 0;
+
+ /* Enable the command queueing, if it possible */
+ if (Capabilities->TaggedQueuing &&
+ ((PINQUIRYDATA)InquiryData->InquiryData)->CommandQueue)
+ {
+ DiskDeviceExtension->SrbFlags |= SRB_FLAGS_QUEUE_ACTION_ENABLE;
+ }
/* Get timeout value */
DiskDeviceExtension->TimeOutValue =
}
/* Allocate sense data buffer */
- DiskDeviceExtension->SenseData = ExAllocatePool(NonPagedPool,
+ DiskDeviceExtension->SenseData = ExAllocatePool(NonPagedPoolCacheAligned,
SENSE_BUFFER_SIZE);
if (DiskDeviceExtension->SenseData == NULL)
{
if ((DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
(DiskDeviceExtension->DiskGeometry->MediaType == RemovableMedia))
- {
-
- DiskClassCreateMediaChangeEvent(DiskDeviceExtension,DiskNumber);
- if(DiskDeviceExtension->MediaChangeEvent != NULL)
+ {
+ DiskClassCreateMediaChangeEvent(DiskDeviceExtension,DiskNumber);
+ if (DiskDeviceExtension->MediaChangeEvent != NULL)
{
- DPRINT("Allocated media change event!\n");
+ DPRINT("Allocated media change event!\n");
}
-
}
/* Check disk for presence of a disk manager */
ExFreePool(MbrBuffer);
MbrBuffer = NULL;
}
+
if ((DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
(DiskDeviceExtension->DiskGeometry->MediaType == RemovableMedia))
- {
+ {
/* Allocate a partition list for a single entry. */
PartitionList = ExAllocatePool(NonPagedPool,
sizeof(DRIVE_LAYOUT_INFORMATION));
PartitionEntry->PartitionNumber,
PartitionEntry->BootIndicator,
PartitionEntry->PartitionType,
- PartitionEntry->StartingOffset.QuadPart / 512 /*DrvParms.BytesPerSector*/,
- PartitionEntry->PartitionLength.QuadPart / 512 /* DrvParms.BytesPerSector*/);
+ PartitionEntry->StartingOffset.QuadPart /
+ DiskDeviceExtension->DiskGeometry->BytesPerSector,
+ PartitionEntry->PartitionLength.QuadPart /
+ DiskDeviceExtension->DiskGeometry->BytesPerSector);
/* Create partition device object */
sprintf(NameBuffer2,
static NTSTATUS
DiskBuildPartitionTable(IN PDEVICE_OBJECT DiskDeviceObject,
- IN PIRP Irp)
+ IN PIRP Irp)
{
PDRIVE_LAYOUT_INFORMATION PartitionList = NULL;
- PDEVICE_EXTENSION DiskDeviceExtension;
- PDISK_DATA DiskData;
+ PDEVICE_EXTENSION DiskDeviceExtension, DDE;
+ PDISK_DATA DiskData, DD;
PPARTITION_INFORMATION PartitionEntry;
ULONG PartitionNumber;
NTSTATUS Status;
DiskDeviceExtension = (PDEVICE_EXTENSION)DiskDeviceObject->DeviceExtension;
DiskData = (PDISK_DATA)(DiskDeviceExtension + 1);
- if (DiskDeviceExtension->StartingOffset.QuadPart)
+ DDE = (PDEVICE_EXTENSION) DiskDeviceExtension->PhysicalDevice->DeviceExtension;
+ DD = (PDISK_DATA)(DDE +1);
+
+ /* Clear flag for Partition0, just incase it was set. */
+ DD->DriveNotReady = FALSE;
+
+ Status = ScsiClassReadDriveCapacity(DiskDeviceObject);
+ if (!NT_SUCCESS(Status))
{
- DPRINT("Partition already installed\n");
- return(STATUS_SUCCESS);
+ /* Drive is not ready. */
+ DPRINT("Drive not ready\n");
+ DiskData->DriveNotReady = TRUE;
+ return Status;
}
- /* Read partition table */
- Status = IoReadPartitionTable(DiskDeviceObject,
+ /* Read partition table */
+ Status = IoReadPartitionTable(DiskDeviceExtension->PhysicalDevice,
DiskDeviceExtension->DiskGeometry->BytesPerSector,
TRUE,
&PartitionList);
-
DPRINT("IoReadPartitionTable(): Status: %lx\n", Status);
if (!NT_SUCCESS(Status))
/* Drive is not ready. */
DPRINT("Drive not ready\n");
DiskData->DriveNotReady = TRUE;
+ if (PartitionList != NULL)
+ ExFreePool(PartitionList);
return Status;
}
/* Set disk signature */
DiskData->Signature = PartitionList->Signature;
- for (PartitionNumber = 0; PartitionNumber < PartitionList->PartitionCount; PartitionNumber++)
- {
- PartitionEntry = &PartitionList->PartitionEntry[PartitionNumber];
+ DiskData->NextPartition = NULL;
- DiskData->NextPartition = NULL;
- DiskData->PartitionType = PartitionEntry->PartitionType;
- DiskData->PartitionNumber = PartitionNumber + 1;
- DiskData->PartitionOrdinal = PartitionNumber + 1;
- DiskData->HiddenSectors = PartitionEntry->HiddenSectors;
- DiskData->BootIndicator = PartitionEntry->BootIndicator;
- DiskData->DriveNotReady = FALSE;
- DiskDeviceExtension->StartingOffset = PartitionEntry->StartingOffset;
- DiskDeviceExtension->PartitionLength = PartitionEntry->PartitionLength;
-
- DPRINT("Partition %02ld: nr: %d boot: %1x type: %x offset: %I64d size: %I64d\n",
- PartitionNumber,
- DiskData->PartitionNumber,
- DiskData->BootIndicator,
- DiskData->PartitionType,
- DiskDeviceExtension->StartingOffset.QuadPart / 512 /*DrvParms.BytesPerSector*/,
- DiskDeviceExtension->PartitionLength.QuadPart / 512 /* DrvParms.BytesPerSector*/);
- }
+ if (PartitionList->PartitionCount)
+ {
+ for (PartitionNumber = 0; PartitionNumber < PartitionList->PartitionCount; PartitionNumber++)
+ {
+ PartitionEntry = &PartitionList->PartitionEntry[PartitionNumber];
+
+ DiskData->PartitionType = PartitionEntry->PartitionType;
+ DiskData->PartitionNumber = PartitionNumber + 1;
+ DiskData->PartitionOrdinal = PartitionNumber + 1;
+ DiskData->HiddenSectors = PartitionEntry->HiddenSectors;
+ DiskData->BootIndicator = PartitionEntry->BootIndicator;
+ DiskData->DriveNotReady = FALSE;
+ DiskDeviceExtension->StartingOffset = PartitionEntry->StartingOffset;
+ DiskDeviceExtension->PartitionLength = PartitionEntry->PartitionLength;
+
+ DPRINT1("Partition %02ld: nr: %d boot: %1x type: %x offset: %I64d size: %I64d\n",
+ PartitionNumber,
+ DiskData->PartitionNumber,
+ DiskData->BootIndicator,
+ DiskData->PartitionType,
+ DiskDeviceExtension->StartingOffset.QuadPart /
+ DiskDeviceExtension->DiskGeometry->BytesPerSector,
+ DiskDeviceExtension->PartitionLength.QuadPart /
+ DiskDeviceExtension->DiskGeometry->BytesPerSector);
+ }
+ }
+ else
+ {
+ DiskData->PartitionType = 0;
+ DiskData->PartitionNumber = 1;
+ DiskData->PartitionOrdinal = 0;
+ DiskData->HiddenSectors = 0;
+ DiskData->BootIndicator = 0;
+ DiskData->DriveNotReady = FALSE;
+ DiskDeviceExtension->StartingOffset.QuadPart = 0;
+ DiskDeviceExtension->PartitionLength.QuadPart += DiskDeviceExtension->StartingOffset.QuadPart;
+ }
}
DPRINT("DiskBuildPartitionTable() done\n");
-
+ if (PartitionList != NULL)
+ ExFreePool(PartitionList);
return(STATUS_SUCCESS);
}
if (!NT_SUCCESS(Status))
{
/* Drive is not ready */
- DiskData->DriveNotReady = FALSE;
+ DiskData->DriveNotReady = TRUE;
break;
}
if ((DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
(DeviceExtension->DiskGeometry->MediaType == RemovableMedia))
{
- /* Allocate a partition list for a single entry. */
+ /* Update a partition list for a single entry. */
Status = DiskBuildPartitionTable(DeviceObject,Irp);
}
ExFreePool (ModeData);
}
break;
-
-
- case IOCTL_DISK_CHECK_VERIFY:
- DPRINT("IOCTL_DISK_CHECK_VERIFY\n");
- if (DeviceObject->Flags & DO_VERIFY_VOLUME)
- {
- DPRINT("Do Verify Set\n");
- Status = STATUS_VERIFY_REQUIRED;
- Information = 0;
- }
- else
- {
- DPRINT("Do Verify Clear\n");
- Status = STATUS_SUCCESS;
- Information = 0;
- }
- break;
case IOCTL_DISK_VERIFY:
case IOCTL_DISK_FORMAT_TRACKS: