-/* $Id: disk.c,v 1.7 2002/03/04 22:31: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.8 2002/03/08 12:01:26 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");
+ DPRINT1("DiskClassCheckReadWrite() called\n");
return(STATUS_SUCCESS);
}
ANSI_STRING DeviceNameA;
UNICODE_STRING DeviceName;
- DPRINT1("DiskClassCreateDeviceObject() called\n");
+ DPRINT("DiskClassCreateDeviceObject() called\n");
/* Create the harddisk device directory */
swprintf(NameBuffer,
DiskDeviceExtension->LockCount = 0;
DiskDeviceExtension->DeviceNumber = DiskNumber;
DiskDeviceExtension->PortDeviceObject = PortDeviceObject;
+ DiskDeviceExtension->PhysicalDevice = DiskDeviceObject;
/* FIXME: Not yet! Will cause pointer corruption! */
// DiskDeviceExtension->PortCapabilities = PortCapabilities;
DiskDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
}
- DPRINT1("SectorSize: %lu\n", DiskDeviceExtension->DiskGeometry->BytesPerSector);
+ DPRINT("SectorSize: %lu\n", DiskDeviceExtension->DiskGeometry->BytesPerSector);
/* assign arc name */
RtlInitAnsiString(&DeviceNameA,
DiskNumber);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
- DPRINT1("ArcNameBuffer '%S'\n", ArcNameBuffer);
- DPRINT1("%wZ ==> %wZ\n", &ArcName, &DeviceName);
+ DPRINT("ArcNameBuffer '%S'\n", ArcNameBuffer);
+ DPRINT("%wZ ==> %wZ\n", &ArcName, &DeviceName);
Status = IoAssignArcName(&ArcName,
&DeviceName);
RtlFreeUnicodeString(&DeviceName);
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))
{
- 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) */
sprintf(NameBuffer2,
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;
PartitionNumber + 1);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
- DPRINT1("ArcNameBuffer '%S'\n", ArcNameBuffer);
- DPRINT1("%wZ ==> %wZ\n", &ArcName, &DeviceName);
+ DPRINT("ArcNameBuffer '%S'\n", ArcNameBuffer);
+ DPRINT("%wZ ==> %wZ\n", &ArcName, &DeviceName);
Status = IoAssignArcName(&ArcName,
&DeviceName);
RtlFreeUnicodeString(&DeviceName);
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");
- Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
- Irp->IoStatus.Information = 0;
+ 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");
+ 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);