mirror of
https://github.com/reactos/reactos.git
synced 2024-07-28 23:29:19 +00:00
- Separate creating partitions objects into a different function (CreatePartitionsObject()).
- Slightly improve the logic of accessing the partitions list. svn path=/trunk/; revision=28993
This commit is contained in:
parent
743a10f834
commit
6f31706927
|
@ -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,11 +106,17 @@ typedef struct _DISK_DATA {
|
|||
|
||||
//
|
||||
// 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 @@ CreateDiskDeviceObject(
|
|||
IN PCLASS_INIT_DATA InitData
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
CreatePartitionDeviceObjects(
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
||||
IN PUNICODE_STRING RegistryPath
|
||||
);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
UpdateDeviceObjects(
|
||||
|
@ -628,30 +647,21 @@ Return Value:
|
|||
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 @@ Return Value:
|
|||
deviceObject->Flags &= ~DO_VERIFY_VOLUME;
|
||||
}
|
||||
|
||||
status = CreatePartitionDeviceObjects(deviceObject, RegistryPath);
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
|
||||
CreateDiskDeviceObjectsExit:
|
||||
|
||||
//
|
||||
// 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.
|
||||
// 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 @@ Return Value:
|
|||
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 @@ Return Value:
|
|||
// 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 @@ Return Value:
|
|||
// 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 @@ Return Value:
|
|||
//
|
||||
|
||||
dmActive = TRUE;
|
||||
dmByteSkew = deviceExtension->DMByteSkew;
|
||||
dmByteSkew = physicalDeviceExtension->DMByteSkew;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1068,8 +1148,8 @@ Return Value:
|
|||
// 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 @@ Return Value:
|
|||
// 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 @@ Return Value:
|
|||
|
||||
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 @@ Return Value:
|
|||
|
||||
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 @@ Return Value:
|
|||
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 @@ Return Value:
|
|||
// 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 @@ Return Value:
|
|||
// 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 @@ Return Value:
|
|||
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 @@ Return Value:
|
|||
// 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 @@ Return Value:
|
|||
|
||||
} 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 @@ Return Value:
|
|||
}
|
||||
|
||||
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,8 +2028,16 @@ Return Value:
|
|||
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.
|
||||
|
@ -1954,6 +2045,10 @@ Return Value:
|
|||
|
||||
status = ScsiClassReadDriveCapacity(deviceExtension->PhysicalDevice);
|
||||
|
||||
}
|
||||
|
||||
if (removable) {
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
|
||||
//
|
||||
|
@ -1970,21 +2065,34 @@ Return Value:
|
|||
//
|
||||
|
||||
diskData->DriveNotReady = FALSE;
|
||||
|
||||
} else if (NT_SUCCESS(status)) {
|
||||
|
||||
// ReadDriveCapacity was allright, create Partition Objects
|
||||
|
||||
if (physicalDiskData->PartitionListState == NotInitialized) {
|
||||
status = CreatePartitionDeviceObjects(deviceExtension->PhysicalDevice, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Copy drive geometry information from device extension.
|
||||
//
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
|
||||
deviceExtension->DiskGeometry,
|
||||
sizeof(DISK_GEOMETRY));
|
||||
//
|
||||
// Copy drive geometry information from device extension.
|
||||
//
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
|
||||
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
|
||||
deviceExtension->DiskGeometry,
|
||||
sizeof(DISK_GEOMETRY));
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case IOCTL_DISK_VERIFY:
|
||||
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue