#include <ntddscsi.h>
#include <mountdev.h>
#include <mountmgr.h>
+#include <ntiologc.h>
#include <include/class2.h>
#include <stdio.h>
#define NDEBUG
#include <debug.h>
-#define IO_WRITE_CACHE_ENABLED ((NTSTATUS)0x80040020L)
-#define IO_WRITE_CACHE_DISABLED ((NTSTATUS)0x80040022L)
#ifdef POOL_TAGGING
#ifdef ExAllocatePool
// Partition number of this device object
//
// This field is set during driver initialization or when the partition
- // is created to identify a parition to the system.
+ // is created to identify a partition to the system.
//
ULONG PartitionNumber;
BOOLEAN BootIndicator;
//
- // DriveNotReady - inidicates that the this device is currenly not ready
+ // DriveNotReady - indicates that the this device is currently not ready
// because there is no media in the device.
//
PARTITION_LIST_STATE PartitionListState;
+#ifdef __REACTOS__
+ //
+ // HACK so that we can use NT5+ NTOS functions with this NT4 driver
+ // for removable devices and avoid an infinite recursive loop between
+ // disk!UpdateRemovableGeometry() and ntos!IoReadPartitionTable().
+ //
+ ULONG UpdateRemovableGeometryCount;
+#endif
+
} DISK_DATA, *PDISK_DATA;
//
-// Define a general structure of identfing disk controllers with bad
+// Define a general structure of identifying disk controllers with bad
// hardware.
//
IN PDEVICE_OBJECT DeviceObject
);
+NTSTATUS
+NTAPI
+ScsiDiskFileSystemControl(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp);
+
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, DriverEntry)
#pragma alloc_text(PAGE, FindScsiDisks)
// SRB zone elements to allocate.
//
- adapterDisk = 0;
adapterInfo = (PVOID) buffer;
adapterDisk = ScsiClassFindUnclaimedDevices(InitializationData, adapterInfo);
// IsFloppyDevice also checks for write cache enabled.
//
+#if 0
if (IsFloppyDevice(deviceObject) && deviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
(((PINQUIRYDATA)LunInfo->InquiryData)->DeviceType == DIRECT_ACCESS_DEVICE)) {
status = STATUS_NO_SUCH_DEVICE;
goto CreateDiskDeviceObjectsExit;
}
+#endif
DisableWriteCache(deviceObject,LunInfo);
status = ScsiClassReadDriveCapacity(deviceObject);
//
- // If the read capcity failed then just return, unless this is a
+ // If the read capacity failed then just return, unless this is a
// removable disk where a device object partition needs to be created.
//
physicalDeviceExtension->DMByteSkew = physicalDeviceExtension->DMSkew * bytesPerSector;
//
- // Save away the infomation that we need, since this deviceExtension will soon be
+ // Save away the information that we need, since this deviceExtension will soon be
// blown away.
//
}
+#ifdef __REACTOS__
+ //
+ // HACK so that we can use NT5+ NTOS functions with this NT4 driver
+ // for removable devices and avoid an infinite recursive loop between
+ // disk!UpdateRemovableGeometry() and ntos!IoReadPartitionTable().
+ //
+ diskData->UpdateRemovableGeometryCount = 0;
+#endif
+
//
// Create objects for all the partitions on the device.
//
if (!initData)
{
DebugPrint((1,
- "Disk.CreatePartionDeviceObjects - Allocation of initData failed\n"));
+ "Disk.CreatePartitionDeviceObjects - Allocation of initData failed\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
goto CreatePartitionDeviceObjectsExit;
ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
LARGE_INTEGER startingOffset;
+ //
+ // HACK: How can we end here with null sector size?!
+ //
+
+ if (deviceExtension->DiskGeometry->Geometry.BytesPerSector == 0) {
+ DPRINT1("Hack! Received invalid sector size\n");
+ deviceExtension->DiskGeometry->Geometry.BytesPerSector = 512;
+ }
+
//
// Verify parameters of this request.
// Check that ending sector is within partition and
if (((PDISK_DATA)(deviceExtension + 1))->DriveNotReady) {
//
- // Flag this as a user errror so that a popup is generated.
+ // Flag this as a user error so that a popup is generated.
//
Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
+ if (startingOffset.QuadPart > deviceExtension->PartitionLength.QuadPart) {
+ DPRINT1("Reading beyond partition end! startingOffset: %I64d, PartitionLength: %I64d\n", startingOffset.QuadPart, deviceExtension->PartitionLength.QuadPart);
+ }
+
+ if (transferByteCount & (deviceExtension->DiskGeometry->Geometry.BytesPerSector - 1)) {
+ DPRINT1("Not reading sectors! TransferByteCount: %lu, BytesPerSector: %lu\n", transferByteCount, deviceExtension->DiskGeometry->Geometry.BytesPerSector);
+ }
+
+ if (Irp->IoStatus.Status == STATUS_DEVICE_NOT_READY) {
+ DPRINT1("Failing due to device not ready!\n");
+ }
+
return STATUS_INVALID_PARAMETER;
}
PDISK_DATA physicalDiskData;
BOOLEAN removable = FALSE;
BOOLEAN listInitialized = FALSE;
+ ULONG copyLength;
- if ((irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY &&
- irpStack->Parameters.DeviceIoControl.OutputBufferLength <
- sizeof(DISK_GEOMETRY)) ||
- (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX &&
- irpStack->Parameters.DeviceIoControl.OutputBufferLength <
- sizeof(DISK_GEOMETRY_EX))) {
+ if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) {
+ if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
- status = STATUS_INFO_LENGTH_MISMATCH;
- break;
+ copyLength = sizeof(DISK_GEOMETRY);
+ } else {
+ ASSERT(irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX);
+ if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(DISK_GEOMETRY_EX, Data)) {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(DISK_GEOMETRY_EX)) {
+ copyLength = sizeof(DISK_GEOMETRY_EX);
+ } else {
+ copyLength = FIELD_OFFSET(DISK_GEOMETRY_EX, Data);
+ }
}
status = STATUS_SUCCESS;
} else if (NT_SUCCESS(status)) {
- // ReadDriveCapacity was allright, create Partition Objects
+ // ReadDriveCapacity was alright, create Partition Objects
if (physicalDiskData->PartitionListState == NotInitialized) {
status = CreatePartitionDeviceObjects(deviceExtension->PhysicalDevice, NULL);
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
deviceExtension->DiskGeometry,
- (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) ?
- sizeof(DISK_GEOMETRY) :
- sizeof(DISK_GEOMETRY_EX));
+ copyLength);
status = STATUS_SUCCESS;
- Irp->IoStatus.Information =
- (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) ?
- sizeof(DISK_GEOMETRY) :
- sizeof(DISK_GEOMETRY_EX);
+ Irp->IoStatus.Information = copyLength;
}
break;
sizeof(PARTITION_INFORMATION)) {
status = STATUS_INFO_LENGTH_MISMATCH;
-
+ break;
}
-#if 0 // HACK: ReactOS partition numbers must be wrong
- else if (diskData->PartitionNumber == 0) {
+
+ //
+ // Update the geometry in case it has changed.
+ //
+
+ status = UpdateRemovableGeometry (DeviceObject, Irp);
+
+ if (!NT_SUCCESS(status)) {
//
- // Paritition zero is not a partition so this is not a
- // reasonable request.
+ // Note the drive is not ready.
//
- status = STATUS_INVALID_DEVICE_REQUEST;
-
+ diskData->DriveNotReady = TRUE;
+ break;
}
-#endif
- else {
+
+ //
+ // Note the drive is now ready.
+ //
+
+ diskData->DriveNotReady = FALSE;
+
+ //
+ // Handle the case were we query the whole disk
+ //
+
+ if (diskData->PartitionNumber == 0) {
PPARTITION_INFORMATION outputBuffer;
- //
- // Update the geometry in case it has changed.
- //
+ outputBuffer =
+ (PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
- status = UpdateRemovableGeometry (DeviceObject, Irp);
+ outputBuffer->PartitionType = PARTITION_ENTRY_UNUSED;
+ outputBuffer->StartingOffset = deviceExtension->StartingOffset;
+ outputBuffer->PartitionLength.QuadPart = deviceExtension->PartitionLength.QuadPart;
+ outputBuffer->HiddenSectors = 0;
+ outputBuffer->PartitionNumber = diskData->PartitionNumber;
+ outputBuffer->BootIndicator = FALSE;
+ outputBuffer->RewritePartition = FALSE;
+ outputBuffer->RecognizedPartition = FALSE;
- if (!NT_SUCCESS(status)) {
+ status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
- //
- // Note the drive is not ready.
- //
+ } else {
- diskData->DriveNotReady = TRUE;
- break;
- }
+ PPARTITION_INFORMATION outputBuffer;
//
- // Note the drive is now ready.
+ // We query a single partition here
+ // FIXME: this can only work for MBR-based disks, check for this!
//
- diskData->DriveNotReady = FALSE;
-// HACK: ReactOS partition numbers must be wrong (>0 part)
- if (diskData->PartitionType == 0 && (diskData->PartitionNumber > 0)) {
-
- status = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
-
outputBuffer =
(PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
outputBuffer->PartitionType = diskData->PartitionType;
outputBuffer->StartingOffset = deviceExtension->StartingOffset;
- outputBuffer->PartitionLength.QuadPart = (diskData->PartitionNumber) ?
- deviceExtension->PartitionLength.QuadPart : 2305843009213693951LL; // HACK
+ outputBuffer->PartitionLength.QuadPart = deviceExtension->PartitionLength.QuadPart;
outputBuffer->HiddenSectors = diskData->HiddenSectors;
outputBuffer->PartitionNumber = diskData->PartitionNumber;
outputBuffer->BootIndicator = diskData->BootIndicator;
status = STATUS_INFO_LENGTH_MISMATCH;
}
+#if 0 // HACK: ReactOS partition numbers must be wrong
else if (diskData->PartitionNumber == 0) {
//
- // Paritition zero is not a partition so this is not a
+ // Partition zero is not a partition so this is not a
// reasonable request.
//
status = STATUS_INVALID_DEVICE_REQUEST;
}
+#endif
else {
PPARTITION_INFORMATION_EX outputBuffer;
+ if (diskData->PartitionNumber == 0) {
+ DPRINT1("HACK: Handling partition 0 request!\n");
+ //ASSERT(FALSE);
+ }
+
//
// Update the geometry in case it has changed.
//
//
// The disk layout has been returned in the partitionList
// buffer. Determine its size and, if the data will fit
- // into the intermediatery buffer, return it.
+ // into the intermediary buffer, return it.
//
tempSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION,PartitionEntry[0]);
partitionEntry = &partitionList->PartitionEntry[i];
//
- // Check if empty, or describes extended partiton or hasn't changed.
+ // Check if empty, or describes extended partition or hasn't changed.
//
if (partitionEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
0,
TRUE);
- DebugPrint((1, "ScsiDiskShutdownFlush: Synchonize cache sent. Status = %lx\n", status ));
+ DebugPrint((1, "ScsiDiskShutdownFlush: Synchronize cache sent. Status = %lx\n", status ));
}
//
The routine performs the necessary functions to determine if a device is
really a floppy rather than a harddisk. This is done by a mode sense
- command. First, a check is made to see if the medimum type is set. Second
+ command. First, a check is made to see if the media type is set. Second
a check is made for the flexible parameters mode page. Also a check is
made to see if the write cache is enabled.
Routine Description:
The routine queries the registry to determine if this disk is visible to
- the BIOS. If the disk is visable to the BIOS, then the geometry information
+ the BIOS. If the disk is visible to the BIOS, then the geometry information
is updated.
Arguments:
ZwClose(targetKey);
if (!NT_SUCCESS(status)) {
+ ExFreePool(keyData);
+ continue;
+ }
+
+ if (keyData->DataLength < 9*sizeof(WCHAR)) {
+ //
+ // the data is too short to use (we subtract 9 chars in normal path)
+ //
+ DebugPrint((1, "EnumerateBusKey: Saved data was invalid, "
+ "not enough data in registry!\n"));
+ ExFreePool(keyData);
continue;
}
TRUE);
if (!NT_SUCCESS(status)) {
+ ExFreePool(keyData);
continue;
}
ExFreePool(keyData);
//
- // Readjust indentifier string if necessary.
+ // Readjust identifier string if necessary.
//
if (!diskData->MbrCheckSum) {
Routine Description:
The routine queries the registry to determine if this disk is visible to
- the BIOS. If the disk is visable to the BIOS, then the geometry information
+ the BIOS. If the disk is visible to the BIOS, then the geometry information
is updated.
Arguments:
DebugPrint((1,
"SCSIDISK: ExtractBiosGeometry: Can't query configuration data (%x)\n",
status));
+ ZwClose(hardwareKey);
ExFreePool(keyData);
return;
}
//
// Check that the data is long enough to hold a full resource descriptor,
- // and that the last resouce list is device-specific and long enough.
+ // and that the last resource list is device-specific and long enough.
//
if (keyData->DataLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR) ||
DeviceExtension->DiskGeometry->Geometry.SectorsPerTrack = sectorsPerTrack;
DeviceExtension->DiskGeometry->Geometry.TracksPerCylinder = tracksPerCylinder;
DeviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)cylinders;
- DeviceExtension->DiskGeometry->DiskSize.QuadPart = cylinders * tracksPerCylinder * sectorsPerTrack *
+ DeviceExtension->DiskGeometry->DiskSize.QuadPart = (LONGLONG)cylinders * tracksPerCylinder * sectorsPerTrack *
DeviceExtension->DiskGeometry->Geometry.BytesPerSector;
DebugPrint((3,
Return Value:
- Returns the status of the opertion.
+ Returns the status of the operation.
--*/
{
diskData = (PDISK_DATA) (deviceExtension + 1);
//
- // Read the drive capcity. If that fails, give up.
+ // Read the drive capacity. If that fails, give up.
//
status = ScsiClassReadDriveCapacity(deviceExtension->PhysicalDevice);
return(status);
}
+#ifdef __REACTOS__
//
- // Read the partition table agian.
+ // HACK so that we can use NT5+ NTOS functions with this NT4 driver
+ // for removable devices and avoid an infinite recursive loop between
+ // disk!UpdateRemovableGeometry() and ntos!IoReadPartitionTable().
+ //
+ // Check whether the update-count is greater or equal than one
+ // (and increase it) and if so, reset it and return success.
+ if (diskData->UpdateRemovableGeometryCount++ >= 1)
+ {
+ diskData->UpdateRemovableGeometryCount = 0;
+ return(STATUS_SUCCESS);
+ }
+#endif
+
+ //
+ // Read the partition table again.
//
status = IoReadPartitionTable(deviceExtension->PhysicalDevice,
TRUE,
&partitionList);
+#ifdef __REACTOS__
+ //
+ // HACK so that we can use NT5+ NTOS functions with this NT4 driver
+ // for removable devices and avoid an infinite recursive loop between
+ // disk!UpdateRemovableGeometry() and ntos!IoReadPartitionTable().
+ //
+ // Inconditionally reset the update-count.
+ diskData->UpdateRemovableGeometryCount = 0;
+#endif
if (!NT_SUCCESS(status)) {
partitionNumber = diskData->PartitionNumber - 1;
//
- // Update the partition information for this parition.
+ // Update the partition information for this partition.
//
diskData->PartitionType =
} else if (diskData->PartitionNumber != 0) {
//
- // The paritition does not exist. Zero all the data.
+ // The partition does not exist. Zero all the data.
//
diskData->PartitionType = 0;
}
//
- // Free the parition list allocate by I/O read partition table.
+ // Free the partition list allocate by I/O read partition table.
//
ExFreePool(partitionList);
Routine Description:
- This function checks to see if an SCSI logical unit requires speical
+ This function checks to see if an SCSI logical unit requires special
flags to be set.
Arguments:
partitionEntry = &partitionList->PartitionEntry[partition];
//
- // Check if empty, or describes extended partiton or hasn't changed.
+ // Check if empty, or describes extended partition or hasn't changed.
//
if (partitionEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
partitionEntry = &partitionList->PartitionEntry[partition];
//
- // Check if empty, or describes an extended partiton.
+ // Check if empty, or describes an extended partition.
//
if (partitionEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
}
} // end UpdateDeviceObjects()
+