Author: fireball
Date: Mon Sep 10 20:25:48 2007
New Revision: 28993
URL:
http://svn.reactos.org/svn/reactos?rev=28993&view=rev
Log:
- Separate creating partitions objects into a different function
(CreatePartitionsObject()).
- Slightly improve the logic of accessing the partitions list.
Modified:
trunk/reactos/drivers/storage/class/disk/disk.c
Modified: trunk/reactos/drivers/storage/class/disk/disk.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/class/disk…
==============================================================================
--- trunk/reactos/drivers/storage/class/disk/disk.c (original)
+++ trunk/reactos/drivers/storage/class/disk/disk.c Mon Sep 10 20:25:48 2007
@@ -28,6 +28,12 @@
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'DscS')
#endif
+typedef enum {
+ NotInitialized,
+ Initializing,
+ Initialized
+} PARTITION_LIST_STATE;
+
//
// Disk device data
//
@@ -100,10 +106,16 @@
//
// DriveNotReady - inidicates that the this device is currenly not ready
- // beacasue there is no media in the device.
+ // because there is no media in the device.
//
BOOLEAN DriveNotReady;
+
+ //
+ // State of PartitionList initialization
+ //
+
+ PARTITION_LIST_STATE PartitionListState;
} DISK_DATA, *PDISK_DATA;
@@ -270,6 +282,13 @@
IN PCLASS_INIT_DATA InitData
);
+NTSTATUS
+STDCALL
+CreatePartitionDeviceObjects(
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN PUNICODE_STRING RegistryPath
+ );
+
VOID
STDCALL
UpdateDeviceObjects(
@@ -628,30 +647,21 @@
CCHAR ntNameBuffer[MAXIMUM_FILENAME_LENGTH];
STRING ntNameString;
UNICODE_STRING ntUnicodeString;
- ULONG partitionNumber = 0;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE handle;
NTSTATUS status;
PDEVICE_OBJECT deviceObject = NULL;
PDEVICE_OBJECT physicalDevice;
PDISK_GEOMETRY diskGeometry = NULL;
- PDRIVE_LAYOUT_INFORMATION partitionList;
PDEVICE_EXTENSION deviceExtension = NULL;
PDEVICE_EXTENSION physicalDeviceExtension;
- PDISK_DATA diskData;
- ULONG bytesPerSector;
- UCHAR sectorShift;
UCHAR pathId = LunInfo->PathId;
UCHAR targetId = LunInfo->TargetId;
UCHAR lun = LunInfo->Lun;
BOOLEAN writeCache;
PVOID senseData = NULL;
ULONG srbFlags;
- ULONG dmByteSkew = 0;
- PULONG dmSkew;
- BOOLEAN dmActive = FALSE;
ULONG timeOut = 0;
- ULONG numberListElements = 0;
BOOLEAN srbListInitialized = FALSE;
@@ -995,19 +1005,88 @@
deviceObject->Flags &= ~DO_VERIFY_VOLUME;
}
- //
- // Set up sector size fields.
- //
- // Stack variables will be used to update
- // the partition device extensions.
- //
- // The device extension field SectorShift is
- // used to calculate sectors in I/O transfers.
- //
- // The DiskGeometry structure is used to service
- // IOCTls used by the format utility.
- //
-
+ status = CreatePartitionDeviceObjects(deviceObject, RegistryPath);
+
+ if (NT_SUCCESS(status))
+ return STATUS_SUCCESS;
+
+
+CreateDiskDeviceObjectsExit:
+
+ //
+ // Release the device since an error occurred.
+ //
+
+ ScsiClassClaimDevice(PortDeviceObject,
+ LunInfo,
+ TRUE,
+ NULL);
+
+ if (diskGeometry != NULL) {
+ ExFreePool(diskGeometry);
+ }
+
+ if (senseData != NULL) {
+ ExFreePool(senseData);
+ }
+
+ if (deviceObject != NULL) {
+
+ if (srbListInitialized) {
+ ExDeleteNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
+ }
+
+ IoDeleteDevice(deviceObject);
+ }
+
+ //
+ // Delete directory and return.
+ //
+
+ if (!NT_SUCCESS(status)) {
+ ZwMakeTemporaryObject(handle);
+ }
+
+ ZwClose(handle);
+
+ return(status);
+
+} // end CreateDiskDeviceObjects()
+
+
+NTSTATUS
+STDCALL
+CreatePartitionDeviceObjects(
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+{
+ CCHAR ntNameBuffer[MAXIMUM_FILENAME_LENGTH];
+ ULONG partitionNumber = 0;
+ NTSTATUS status;
+ PDEVICE_OBJECT deviceObject = NULL;
+ PDISK_GEOMETRY diskGeometry = NULL;
+ PDRIVE_LAYOUT_INFORMATION partitionList = NULL;
+ PDEVICE_EXTENSION deviceExtension;
+ PDEVICE_EXTENSION physicalDeviceExtension;
+ PCLASS_INIT_DATA initData = NULL;
+ PDISK_DATA diskData;
+ PDISK_DATA physicalDiskData;
+ ULONG bytesPerSector;
+ UCHAR sectorShift;
+ ULONG srbFlags;
+ ULONG dmByteSkew = 0;
+ PULONG dmSkew;
+ BOOLEAN dmActive = FALSE;
+ ULONG numberListElements = 0;
+
+
+ //
+ // Get physical device geometry information for partition table reads.
+ //
+
+ physicalDeviceExtension = PhysicalDeviceObject->DeviceExtension;
+ diskGeometry = physicalDeviceExtension->DiskGeometry;
bytesPerSector = diskGeometry->BytesPerSector;
//
@@ -1023,13 +1102,14 @@
bytesPerSector = diskGeometry->BytesPerSector = 512;
}
- sectorShift = deviceExtension->SectorShift;
+ sectorShift = physicalDeviceExtension->SectorShift;
//
// Set pointer to disk data area that follows device extension.
//
- diskData = (PDISK_DATA)(deviceExtension + 1);
+ diskData = (PDISK_DATA)(physicalDeviceExtension + 1);
+ diskData->PartitionListState = Initializing;
//
// Determine is DM Driver is loaded on an IDE drive that is
@@ -1037,8 +1117,8 @@
// an Atapi device is sharing the controller with an IDE disk.
//
- HalExamineMBR(deviceExtension->DeviceObject,
- deviceExtension->DiskGeometry->BytesPerSector,
+ HalExamineMBR(PhysicalDeviceObject,
+ physicalDeviceExtension->DiskGeometry->BytesPerSector,
(ULONG)0x54,
(PVOID)&dmSkew);
@@ -1050,9 +1130,9 @@
// to be skewed by *dmSkew sectors aka DMByteSkew.
//
- deviceExtension->DMSkew = *dmSkew;
- deviceExtension->DMActive = TRUE;
- deviceExtension->DMByteSkew = deviceExtension->DMSkew * bytesPerSector;
+ physicalDeviceExtension->DMSkew = *dmSkew;
+ physicalDeviceExtension->DMActive = TRUE;
+ physicalDeviceExtension->DMByteSkew = physicalDeviceExtension->DMSkew *
bytesPerSector;
//
// Save away the infomation that we need, since this deviceExtension will soon
be
@@ -1060,7 +1140,7 @@
//
dmActive = TRUE;
- dmByteSkew = deviceExtension->DMByteSkew;
+ dmByteSkew = physicalDeviceExtension->DMByteSkew;
}
@@ -1068,8 +1148,8 @@
// Create objects for all the partitions on the device.
//
- status = IoReadPartitionTable(deviceObject,
- deviceExtension->DiskGeometry->BytesPerSector,
+ status = IoReadPartitionTable(PhysicalDeviceObject,
+
physicalDeviceExtension->DiskGeometry->BytesPerSector,
TRUE,
(PVOID)&partitionList);
@@ -1078,9 +1158,9 @@
// then fix up the partition list to make it look like there is one
// zero length partition.
//
-
+ DPRINT1("IoReadPartitionTable() status: 0x%08X\n", status);
if ((!NT_SUCCESS(status) || partitionList->PartitionCount == 0) &&
- deviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
+ PhysicalDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
if (!NT_SUCCESS(status)) {
@@ -1136,28 +1216,53 @@
if (!diskData->Signature) {
- if (!CalculateMbrCheckSum(deviceExtension,
+ if (!CalculateMbrCheckSum(physicalDeviceExtension,
&diskData->MbrCheckSum)) {
DebugPrint((1,
"SCSIDISK: Can't calculate MBR checksum for disk
%x\n",
- deviceExtension->DeviceNumber));
+ physicalDeviceExtension->DeviceNumber));
} else {
DebugPrint((2,
"SCSIDISK: MBR checksum for disk %x is %x\n",
- deviceExtension->DeviceNumber,
+ physicalDeviceExtension->DeviceNumber,
diskData->MbrCheckSum));
}
}
-
//
// Check the registry and determine if the BIOS knew about this drive. If
// it did then update the geometry with the BIOS information.
//
- UpdateGeometry(deviceExtension);
+ UpdateGeometry(physicalDeviceExtension);
+
+ srbFlags = physicalDeviceExtension->SrbFlags;
+
+ initData = ExAllocatePool(NonPagedPool, sizeof(CLASS_INIT_DATA));
+ if (!initData)
+ {
+ DebugPrint((1,
+ "Disk.CreatePartionDeviceObjects - Allocation of initData
failed\n"));
+
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto CreatePartitionDeviceObjectsExit;
+ }
+
+ RtlZeroMemory(initData, sizeof(CLASS_INIT_DATA));
+
+ initData->InitializationDataSize = sizeof(CLASS_INIT_DATA);
+ initData->DeviceExtensionSize = DEVICE_EXTENSION_SIZE;
+ initData->DeviceType = FILE_DEVICE_DISK;
+ initData->DeviceCharacteristics =
PhysicalDeviceObject->Characteristics;
+ initData->ClassError =
physicalDeviceExtension->ClassError;
+ initData->ClassReadWriteVerification =
physicalDeviceExtension->ClassReadWriteVerification;
+ initData->ClassFindDevices =
physicalDeviceExtension->ClassFindDevices;
+ initData->ClassDeviceControl =
physicalDeviceExtension->ClassDeviceControl;
+ initData->ClassShutdownFlush =
physicalDeviceExtension->ClassShutdownFlush;
+ initData->ClassCreateClose =
physicalDeviceExtension->ClassCreateClose;
+ initData->ClassStartIo =
physicalDeviceExtension->ClassStartIo;
//
// Create device objects for the device partitions (if any).
@@ -1178,18 +1283,18 @@
sprintf(ntNameBuffer,
"\\Device\\Harddisk%lu\\Partition%lu",
- *DeviceCount,
+ physicalDeviceExtension->DeviceNumber,
partitionNumber + 1);
DebugPrint((2,
"CreateDiskDeviceObjects: Create device object %s\n",
ntNameBuffer));
- status = ScsiClassCreateDeviceObject(DriverObject,
+ status = ScsiClassCreateDeviceObject(PhysicalDeviceObject->DriverObject,
ntNameBuffer,
- physicalDevice,
+ PhysicalDeviceObject,
&deviceObject,
- InitData);
+ initData);
if (!NT_SUCCESS(status)) {
@@ -1214,7 +1319,7 @@
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}
- deviceObject->StackSize = (CCHAR)PortDeviceObject->StackSize + 1;
+ deviceObject->StackSize =
(CCHAR)physicalDeviceExtension->PortDeviceObject->StackSize + 1;
//
// Set up device extension fields.
@@ -1264,16 +1369,15 @@
// Copy port device object pointer to device extension.
//
- deviceExtension->PortDeviceObject = PortDeviceObject;
- deviceExtension->PortNumber = (UCHAR)PortNumber;
+ deviceExtension->PortDeviceObject =
physicalDeviceExtension->PortDeviceObject;
//
// Set the alignment requirements for the device based on the
// host adapter requirements
//
- if (PortDeviceObject->AlignmentRequirement >
deviceObject->AlignmentRequirement) {
- deviceObject->AlignmentRequirement =
PortDeviceObject->AlignmentRequirement;
+ if (physicalDeviceExtension->PortDeviceObject->AlignmentRequirement
> deviceObject->AlignmentRequirement) {
+ deviceObject->AlignmentRequirement =
physicalDeviceExtension->PortDeviceObject->AlignmentRequirement;
}
@@ -1297,8 +1401,8 @@
// Set the sense-data pointer in the device extension.
//
- deviceExtension->SenseData = senseData;
- deviceExtension->PortCapabilities = PortCapabilities;
+ deviceExtension->SenseData =
physicalDeviceExtension->SenseData;
+ deviceExtension->PortCapabilities =
physicalDeviceExtension->PortCapabilities;
deviceExtension->DiskGeometry = diskGeometry;
diskData->PartitionOrdinal = diskData->PartitionNumber =
partitionNumber + 1;
diskData->PartitionType =
partitionList->PartitionEntry[partitionNumber].PartitionType;
@@ -1310,16 +1414,16 @@
deviceExtension->StartingOffset =
partitionList->PartitionEntry[partitionNumber].StartingOffset;
deviceExtension->PartitionLength =
partitionList->PartitionEntry[partitionNumber].PartitionLength;
diskData->HiddenSectors =
partitionList->PartitionEntry[partitionNumber].HiddenSectors;
- deviceExtension->PortNumber = (UCHAR)PortNumber;
- deviceExtension->PathId = pathId;
- deviceExtension->TargetId = targetId;
- deviceExtension->Lun = lun;
+ deviceExtension->PortNumber =
physicalDeviceExtension->PortNumber;
+ deviceExtension->PathId = physicalDeviceExtension->PathId;
+ deviceExtension->TargetId = physicalDeviceExtension->TargetId;
+ deviceExtension->Lun = physicalDeviceExtension->Lun;
//
// Check for removable media support.
//
- if (((PINQUIRYDATA)LunInfo->InquiryData)->RemovableMedia) {
+ if (PhysicalDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
deviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
}
@@ -1327,7 +1431,7 @@
// Set timeout value in seconds.
//
- deviceExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
+ deviceExtension->TimeOutValue = physicalDeviceExtension->TimeOutValue;
deviceExtension->DiskGeometry->BytesPerSector = bytesPerSector;
deviceExtension->SectorShift = sectorShift;
deviceExtension->DeviceObject = deviceObject;
@@ -1344,54 +1448,27 @@
} else {
- DebugPrint((1,
- "CreateDiskDeviceObjects: IoReadPartitionTable
failed\n"));
+CreatePartitionDeviceObjectsExit:
+
+ if (partitionList) {
+ ExFreePool(partitionList);
+ }
+ if (initData) {
+ ExFreePool(initData);
+ }
+
+ return status;
} // end if...else
+
+ physicalDiskData = (PDISK_DATA)(physicalDeviceExtension + 1);
+ physicalDiskData->PartitionListState = Initialized;
+
return(STATUS_SUCCESS);
-CreateDiskDeviceObjectsExit:
-
- //
- // Release the device since an error occurred.
- //
-
- ScsiClassClaimDevice(PortDeviceObject,
- LunInfo,
- TRUE,
- NULL);
-
- if (diskGeometry != NULL) {
- ExFreePool(diskGeometry);
- }
-
- if (senseData != NULL) {
- ExFreePool(senseData);
- }
-
- if (deviceObject != NULL) {
-
- if (srbListInitialized) {
- ExDeleteNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
- }
-
- IoDeleteDevice(deviceObject);
- }
-
- //
- // Delete directory and return.
- //
-
- if (!NT_SUCCESS(status)) {
- ZwMakeTemporaryObject(handle);
- }
-
- ZwClose(handle);
-
- return(status);
-
-} // end CreateDiskDeviceObjects()
+
+} // end CreatePartitionDeviceObjects()
NTSTATUS
@@ -1937,6 +2014,12 @@
}
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
+ {
+
+ PDEVICE_EXTENSION physicalDeviceExtension;
+ PDISK_DATA physicalDiskData;
+ BOOLEAN removable = FALSE;
+ BOOLEAN listInitialized = FALSE;
if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof( DISK_GEOMETRY ) ) {
@@ -1945,14 +2028,26 @@
break;
}
- if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
-
+ status = STATUS_SUCCESS;
+
+ physicalDeviceExtension =
deviceExtension->PhysicalDevice->DeviceExtension;
+ physicalDiskData = (PDISK_DATA)(physicalDeviceExtension + 1);
+
+ removable = (BOOLEAN)DeviceObject->Characteristics &
FILE_REMOVABLE_MEDIA;
+ listInitialized = (physicalDiskData->PartitionListState == Initialized);
+
+ if (removable || (!listInitialized))
+ {
//
// Issue ReadCapacity to update device extension
// with information for current media.
//
status = ScsiClassReadDriveCapacity(deviceExtension->PhysicalDevice);
+
+ }
+
+ if (removable) {
if (!NT_SUCCESS(status)) {
@@ -1970,20 +2065,33 @@
//
diskData->DriveNotReady = FALSE;
- }
-
- //
- // Copy drive geometry information from device extension.
- //
-
- RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
- deviceExtension->DiskGeometry,
- sizeof(DISK_GEOMETRY));
-
- status = STATUS_SUCCESS;
- Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
+
+ } else if (NT_SUCCESS(status)) {
+
+ // ReadDriveCapacity was allright, create Partition Objects
+
+ if (physicalDiskData->PartitionListState == NotInitialized) {
+ status =
CreatePartitionDeviceObjects(deviceExtension->PhysicalDevice, NULL);
+ }
+ }
+
+ if (NT_SUCCESS(status)) {
+
+ //
+ // Copy drive geometry information from device extension.
+ //
+
+ RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
+ deviceExtension->DiskGeometry,
+ sizeof(DISK_GEOMETRY));
+
+ status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
+ }
break;
+
+ }
case IOCTL_DISK_VERIFY: