-/* $Id: disk.c,v 1.6 2002/03/01 23:18:35 ekohl Exp $
+/*
+ * ReactOS kernel
+ * Copyright (C) 2001, 2002 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: disk.c,v 1.11 2002/03/22 20:35:09 ekohl Exp $
+ *
+ * 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)
*/
/* INCLUDES *****************************************************************/
#define NDEBUG
#include <debug.h>
-#define VERSION "V0.0.1"
+#define VERSION "0.0.1"
typedef struct _DISK_DATA
return(FALSE);
}
- DPRINT1("Found %lu unclaimed devices!\n", DeviceCount);
+ DPRINT("Found %lu unclaimed devices!\n", DeviceCount);
ConfigInfo = IoGetConfigurationInformation();
(InquiryData->DeviceTypeQualifier == 0) &&
(UnitInfo->DeviceClaimed == FALSE))
{
- DPRINT1("Vendor: '%.24s'\n",
+ DPRINT("Vendor: '%.24s'\n",
InquiryData->VendorId);
/* Create device objects for disk */
}
+/**********************************************************************
+ * NAME EXPORTED
+ * DiskClassCheckReadWrite
+ *
+ * DESCRIPTION
+ * This function checks the given IRP for correct data.
+ *
+ * RUN LEVEL
+ * PASSIVE_LEVEL
+ *
+ * ARGUMENTS
+ * DeviceObject
+ * Pointer to the device.
+ *
+ * Irp
+ * Irp to check.
+ *
+ * RETURN VALUE
+ * STATUS_SUCCESS: The IRP matches the requirements of the given device.
+ * Others: Failure.
+ */
+
NTSTATUS STDCALL
DiskClassCheckReadWrite(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- DPRINT("DiskClassCheckReadWrite() called\n");
+ PDEVICE_EXTENSION DeviceExtension;
+ PDISK_DATA DiskData;
+
+ DPRINT1("DiskClassCheckReadWrite() called\n");
+
+ DeviceExtension = DeviceObject->DeviceExtension;
+ DiskData = (PDISK_DATA)(DeviceExtension + 1);
+
+ if (DiskData->DriveNotReady == TRUE)
+ {
+ Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
+ IoSetHardErrorOrVerifyDevice(Irp,
+ DeviceObject);
+ return(STATUS_INVALID_PARAMETER);
+ }
return(STATUS_SUCCESS);
}
ULONG PartitionNumber;
NTSTATUS Status;
- WCHAR ArcNameBuffer[120];
- UNICODE_STRING ArcName;
- ANSI_STRING DeviceNameA;
- UNICODE_STRING DeviceName;
-
- DPRINT1("DiskClassCreateDeviceObject() called\n");
+ DPRINT("DiskClassCreateDeviceObject() called\n");
/* Create the harddisk device directory */
swprintf(NameBuffer,
}
DiskDeviceExtension = DiskDeviceObject->DeviceExtension;
-// DiskData = (PDISK_DEVICE_EXTENSION)((PUCHAR)DiskDeviceExtension + sizeof(DEVICE_EXTENSION));
-
DiskDeviceExtension->LockCount = 0;
DiskDeviceExtension->DeviceNumber = DiskNumber;
DiskDeviceExtension->PortDeviceObject = PortDeviceObject;
+ DiskDeviceExtension->PhysicalDevice = DiskDeviceObject;
/* FIXME: Not yet! Will cause pointer corruption! */
// DiskDeviceExtension->PortCapabilities = PortCapabilities;
}
else
{
- /* Clear the verify flag for non-removable media drives. */
+ /* Clear the verify flag for removable media drives. */
DiskDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
}
- DPRINT1("SectorSize: %lu\n", DiskDeviceExtension->DiskGeometry->BytesPerSector);
-
- /* assign arc name */
- RtlInitAnsiString(&DeviceNameA,
- NameBuffer2);
- RtlAnsiStringToUnicodeString(&DeviceName,
- &DeviceNameA,
- TRUE);
- swprintf(ArcNameBuffer,
- L"\\ArcName\\multi(0)disk(0)rdisk(%lu)",
- DiskNumber);
- RtlInitUnicodeString(&ArcName,
- ArcNameBuffer);
- DPRINT1("ArcNameBuffer '%S'\n", ArcNameBuffer);
- DPRINT1("%wZ ==> %wZ\n", &ArcName, &DeviceName);
- Status = IoAssignArcName(&ArcName,
- &DeviceName);
- RtlFreeUnicodeString(&DeviceName);
-
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("IoAssignArcName (%wZ) failed (Status %x)\n", &ArcName, Status);
- KeBugCheck(0);
- }
-
+ DPRINT("SectorSize: %lu\n", DiskDeviceExtension->DiskGeometry->BytesPerSector);
/* Read partition table */
Status = IoReadPartitionTable(DiskDeviceObject,
TRUE,
&PartitionList);
- DPRINT1("IoReadPartitionTable(): Status: %lx\n", Status);
+ DPRINT("IoReadPartitionTable(): Status: %lx\n", Status);
if ((!NT_SUCCESS(Status) || PartitionList->PartitionCount == 0) &&
DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
if (!NT_SUCCESS(Status))
{
/* Drive is not ready. */
-// diskData->DriveNotReady = TRUE;
+ DPRINT1("Drive not ready\n");
+ DiskData->DriveNotReady = TRUE;
}
else
{
if (NT_SUCCESS(Status))
{
- DPRINT1("Read partition table!\n");
+ DPRINT("Read partition table!\n");
DPRINT(" Number of partitions: %u\n", PartitionList->PartitionCount);
{
PartitionEntry = &PartitionList->PartitionEntry[PartitionNumber];
- DPRINT1("Partition %02ld: nr: %d boot: %1x type: %x offset: %I64d size: %I64d\n",
- PartitionNumber,
- PartitionEntry->PartitionNumber,
- PartitionEntry->BootIndicator,
- PartitionEntry->PartitionType,
- PartitionEntry->StartingOffset.QuadPart / 512 /*DrvParms.BytesPerSector*/,
- PartitionEntry->PartitionLength.QuadPart / 512 /* DrvParms.BytesPerSector*/);
+ DPRINT("Partition %02ld: nr: %d boot: %1x type: %x offset: %I64d size: %I64d\n",
+ PartitionNumber,
+ PartitionEntry->PartitionNumber,
+ PartitionEntry->BootIndicator,
+ PartitionEntry->PartitionType,
+ PartitionEntry->StartingOffset.QuadPart / 512 /*DrvParms.BytesPerSector*/,
+ PartitionEntry->PartitionLength.QuadPart / 512 /* DrvParms.BytesPerSector*/);
- /* Create partition device (Partition 0) */
+ /* Create partition device object */
sprintf(NameBuffer2,
"\\Device\\Harddisk%lu\\Partition%lu",
DiskNumber,
DiskDeviceObject,
&PartitionDeviceObject,
InitializationData);
- DPRINT1("ScsiClassCreateDeviceObject(): Status %x\n", Status);
+ DPRINT("ScsiClassCreateDeviceObject(): Status %x\n", Status);
if (NT_SUCCESS(Status))
{
PartitionDeviceObject->Flags = DiskDeviceObject->Flags;
PartitionDeviceExtension->DeviceNumber = DiskNumber;
PartitionDeviceExtension->PortDeviceObject = PortDeviceObject;
PartitionDeviceExtension->DiskGeometry = DiskDeviceExtension->DiskGeometry;
+ PartitionDeviceExtension->PhysicalDevice = DiskDeviceExtension->PhysicalDevice;
/* FIXME: Not yet! Will cause pointer corruption! */
// PartitionDeviceExtension->PortCapabilities = PortCapabilities;
PartitionDeviceExtension->PathId = InquiryData->PathId;
PartitionDeviceExtension->TargetId = InquiryData->TargetId;
PartitionDeviceExtension->Lun = InquiryData->Lun;
+ PartitionDeviceExtension->SectorShift = DiskDeviceExtension->SectorShift;
DiskData = (PDISK_DATA)(PartitionDeviceExtension + 1);
DiskData->PartitionType = PartitionEntry->PartitionType;
DiskData->HiddenSectors = PartitionEntry->HiddenSectors;
DiskData->BootIndicator = PartitionEntry->BootIndicator;
DiskData->DriveNotReady = FALSE;
-
-
- /* assign arc name */
- RtlInitAnsiString(&DeviceNameA,
- NameBuffer2);
- RtlAnsiStringToUnicodeString(&DeviceName,
- &DeviceNameA,
- TRUE);
- swprintf(ArcNameBuffer,
- L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
- DiskNumber,
- PartitionNumber + 1);
- RtlInitUnicodeString(&ArcName,
- ArcNameBuffer);
- DPRINT1("ArcNameBuffer '%S'\n", ArcNameBuffer);
- DPRINT1("%wZ ==> %wZ\n", &ArcName, &DeviceName);
- Status = IoAssignArcName(&ArcName,
- &DeviceName);
- RtlFreeUnicodeString(&DeviceName);
-
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("IoAssignArcName (%wZ) failed (Status %x)\n", &ArcName, Status);
- KeBugCheck(0);
- }
-
}
else
{
if (PartitionList != NULL)
ExFreePool(PartitionList);
- DPRINT1("DiskClassCreateDeviceObjects() done\n");
+ DPRINT("DiskClassCreateDeviceObjects() done\n");
return(STATUS_SUCCESS);
}
PIO_STACK_LOCATION IrpStack;
ULONG ControlCode, InputLength, OutputLength;
PDISK_DATA DiskData;
+ ULONG Information;
NTSTATUS Status;
- DPRINT1("DiskClassDeviceControl() called!\n");
+ DPRINT("DiskClassDeviceControl() called!\n");
- Status = STATUS_SUCCESS;
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ Information = 0;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
- DeviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
+ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
DiskData = (PDISK_DATA)(DeviceExtension + 1);
/* A huge switch statement in a Windows program?! who would have thought? */
switch (ControlCode)
{
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
- DPRINT1("IOCTL_DISK_GET_DRIVE_GEOMETRY\n");
+ DPRINT("IOCTL_DISK_GET_DRIVE_GEOMETRY\n");
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
{
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
- Irp->IoStatus.Information = 0;
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ else if (DeviceExtension->DiskGeometry == NULL)
+ {
+ DPRINT1("No disk geometry available!\n");
+ Status = STATUS_NO_SUCH_DEVICE;
}
else
{
DeviceExtension->DiskGeometry,
sizeof(DISK_GEOMETRY));
-#if 0
-
- RtlCopyMemory(DiskData->Geometry,
- DiskDeviceExtension->DiskGeometry,
- sizeof(DISK_GEOMETRY));
- Geometry->MediaType = FixedMedia;
- // FIXME: should report for RawDevice even on partition
- Geometry->Cylinders.QuadPart = DeviceExtension->Size /
- DeviceExtension->SectorsPerLogCyl;
- Geometry->TracksPerCylinder = DeviceExtension->SectorsPerLogTrk /
- DeviceExtension->SectorsPerLogCyl;
- Geometry->SectorsPerTrack = DeviceExtension->SectorsPerLogTrk;
- Geometry->BytesPerSector = DeviceExtension->BytesPerSector;
-#endif
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
+ Status = STATUS_SUCCESS;
+ Information = sizeof(DISK_GEOMETRY);
}
break;
case IOCTL_DISK_GET_PARTITION_INFO:
- DPRINT1("IOCTL_DISK_GET_PARTITION_INFO\n");
+ DPRINT("IOCTL_DISK_GET_PARTITION_INFO\n");
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(PARTITION_INFORMATION))
{
- Irp->IoStatus.Status = STATUS_INFO_LENGTH_MISMATCH;
- Irp->IoStatus.Information = 0;
+ Status = STATUS_INFO_LENGTH_MISMATCH;
}
else if (DiskData->PartitionNumber == 0)
{
- Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
- Irp->IoStatus.Information = 0;
+ Status = STATUS_INVALID_DEVICE_REQUEST;
}
else
{
PartitionInfo->RecognizedPartition =
IsRecognizedPartition(DiskData->PartitionType);
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
+ Status = STATUS_SUCCESS;
+ Information = sizeof(PARTITION_INFORMATION);
}
break;
case IOCTL_DISK_SET_PARTITION_INFO:
+ DPRINT1("Unhandled IOCTL_DISK_SET_PARTITION_INFO\n");
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ Information = 0;
+ break;
+
case IOCTL_DISK_GET_DRIVE_LAYOUT:
+ if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength <
+ sizeof(DRIVE_LAYOUT_INFORMATION))
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ PDRIVE_LAYOUT_INFORMATION PartitionList;
+
+ Status = IoReadPartitionTable(DeviceExtension->PhysicalDevice,
+ DeviceExtension->DiskGeometry->BytesPerSector,
+ FALSE,
+ &PartitionList);
+ if (NT_SUCCESS(Status))
+ {
+ ULONG BufferSize;
+
+ BufferSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION,
+ PartitionEntry[0]);
+ BufferSize += PartitionList->PartitionCount * sizeof(PARTITION_INFORMATION);
+
+ if (BufferSize > IrpStack->Parameters.DeviceIoControl.OutputBufferLength)
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
+ PartitionList,
+ BufferSize);
+ Status = STATUS_SUCCESS;
+ Information = BufferSize;
+ }
+ ExFreePool(PartitionList);
+ }
+ }
+ break;
+
case IOCTL_DISK_SET_DRIVE_LAYOUT:
case IOCTL_DISK_VERIFY:
case IOCTL_DISK_FORMAT_TRACKS:
default:
DPRINT1("Unhandled control code: %lx\n", ControlCode);
Status = STATUS_INVALID_DEVICE_REQUEST;
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
+ Information = 0;
break;
}
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = Information;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
}
-// DiskClassShutdownFlush
-//
-// DESCRIPTION:
-// Answer requests for shutdown and flush calls
-//
-// RUN LEVEL:
-// PASSIVE_LEVEL
-//
-// ARGUMENTS:
-// Standard dispatch arguments
-//
-// RETURNS:
-// NTSTATUS
-//
+/**********************************************************************
+ * NAME EXPORTED
+ * DiskClassShutdownFlush
+ *
+ * DESCRIPTION
+ * Answer requests for shutdown and flush calls.
+ *
+ * RUN LEVEL
+ * PASSIVE_LEVEL
+ *
+ * ARGUMENTS
+ * DeviceObject
+ * Pointer to the device.
+ *
+ * Irp
+ * Pointer to the IRP
+ *
+ * RETURN VALUE
+ * Status
+ */
NTSTATUS STDCALL
DiskClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,