Replaced IDEGetPartitionTable() by call to IoReadPartitionTable()

Several minor fixes

svn path=/trunk/; revision=1948
This commit is contained in:
Eric Kohl 2001-06-07 21:18:01 +00:00
parent 6d96f0e0cc
commit 77fa055814
4 changed files with 282 additions and 446 deletions

View file

@ -1,4 +1,4 @@
/* $Id: ide.c,v 1.41 2001/06/02 15:53:26 ekohl Exp $ /* $Id: ide.c,v 1.42 2001/06/07 21:18:01 ekohl Exp $
* *
* IDE.C - IDE Disk driver * IDE.C - IDE Disk driver
* written by Rex Jolliff * written by Rex Jolliff
@ -108,7 +108,6 @@ IDE_CONTROLLER_PARAMETERS Controllers[IDE_MAX_CONTROLLERS] =
}; };
static BOOLEAN IDEInitialized = FALSE; static BOOLEAN IDEInitialized = FALSE;
static int TotalPartitions = 0;
// ----------------------------------------------- Discardable Declarations // ----------------------------------------------- Discardable Declarations
@ -135,33 +134,27 @@ static int TotalPartitions = 0;
// ---------------------------------------------------- Forward Declarations // ---------------------------------------------------- Forward Declarations
static BOOLEAN IDECreateController(IN PDRIVER_OBJECT DriverObject, static BOOLEAN IDECreateController(IN PDRIVER_OBJECT DriverObject,
IN PIDE_CONTROLLER_PARAMETERS ControllerParams, IN PIDE_CONTROLLER_PARAMETERS ControllerParams,
IN int ControllerIdx); IN int ControllerIdx);
static BOOLEAN IDEResetController(IN WORD CommandPort, IN WORD ControlPort); static BOOLEAN IDEResetController(IN WORD CommandPort, IN WORD ControlPort);
static BOOLEAN IDECreateDevices(IN PDRIVER_OBJECT DriverObject, static BOOLEAN IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
IN PCONTROLLER_OBJECT ControllerObject, IN PCONTROLLER_OBJECT ControllerObject,
IN PIDE_CONTROLLER_EXTENSION ControllerExtension, IN PIDE_CONTROLLER_EXTENSION ControllerExtension,
IN int DriveIdx, IN int DriveIdx,
IN int HarddiskIdx); IN int HarddiskIdx);
static BOOLEAN IDEGetDriveIdentification(IN int CommandPort, static BOOLEAN IDEGetDriveIdentification(IN int CommandPort,
IN int DriveNum, IN int DriveNum,
OUT PIDE_DRIVE_IDENTIFY DrvParms); OUT PIDE_DRIVE_IDENTIFY DrvParms);
static BOOLEAN IDEGetPartitionTable(IN int CommandPort, static NTSTATUS IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
IN int DriveNum, OUT PDEVICE_OBJECT *DeviceObject,
IN int Offset, IN PCONTROLLER_OBJECT ControllerObject,
IN PIDE_DRIVE_IDENTIFY DrvParms,
PARTITION *PartitionTable);
static NTSTATUS IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
// IN PCHAR DeviceName,
OUT PDEVICE_OBJECT *DeviceObject,
IN PCONTROLLER_OBJECT ControllerObject,
IN int UnitNumber, IN int UnitNumber,
IN ULONG DiskNumber, IN ULONG DiskNumber,
IN ULONG PartitionNumber, IN PIDE_DRIVE_IDENTIFY DrvParms,
IN PIDE_DRIVE_IDENTIFY DrvParms, IN ULONG PartitionIdx,
IN DWORD Offset, IN ULONGLONG Offset,
IN DWORD Size); IN ULONGLONG Size);
static int IDEPolledRead(IN WORD Address, static int IDEPolledRead(IN WORD Address,
IN BYTE PreComp, IN BYTE PreComp,
IN BYTE SectorCnt, IN BYTE SectorCnt,
@ -351,6 +344,9 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
return FALSE; return FALSE;
} }
/* TEST */
IDEInitialized = TRUE;
// Create device objects for each raw device (and for partitions) // Create device objects for each raw device (and for partitions)
CreatedDevices = FALSE; CreatedDevices = FALSE;
for (DriveIdx = 0; DriveIdx < IDE_MAX_DRIVES; DriveIdx++) for (DriveIdx = 0; DriveIdx < IDE_MAX_DRIVES; DriveIdx++)
@ -413,23 +409,8 @@ IDEResetController(IN WORD CommandPort,
// Negate drive reset line // Negate drive reset line
IDEWriteDriveControl(ControlPort, 0); IDEWriteDriveControl(ControlPort, 0);
// Wait for BUSY assertion
/*for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++)
{
if (IDEReadStatus(CommandPort) & IDE_SR_BUSY)
{
break;
}
KeStallExecutionProcessor(10);
}
CHECKPOINT;
if (Retries >= IDE_MAX_BUSY_RETRIES)
{
return FALSE;
}*/
// Wait for BUSY negation // Wait for BUSY negation
for (Retries = 0; Retries < IDE_RESET_BUSY_TIMEOUT * 1000; Retries++) for (Retries = 0; Retries < IDE_RESET_BUSY_TIMEOUT * 1000; Retries++)
{ {
if (!(IDEReadStatus(CommandPort) & IDE_SR_BUSY)) if (!(IDEReadStatus(CommandPort) & IDE_SR_BUSY))
{ {
@ -479,25 +460,20 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
IN int DriveIdx, IN int DriveIdx,
IN int HarddiskIdx) IN int HarddiskIdx)
{ {
BOOLEAN CreatedDevices;
WCHAR NameBuffer[IDE_MAX_NAME_LENGTH]; WCHAR NameBuffer[IDE_MAX_NAME_LENGTH];
int CommandPort, PartitionIdx, PartitionNum; int CommandPort;
NTSTATUS RC; NTSTATUS Status;
IDE_DRIVE_IDENTIFY DrvParms; IDE_DRIVE_IDENTIFY DrvParms;
PDEVICE_OBJECT RawDeviceObject; PDEVICE_OBJECT RawDeviceObject;
PDEVICE_OBJECT PrimaryDeviceObject; PDEVICE_OBJECT PartitionDeviceObject;
PIDE_DEVICE_EXTENSION RawDeviceExtension; PIDE_DEVICE_EXTENSION RawDeviceExtension;
PARTITION PartitionTable[4], *p;
UNICODE_STRING UnicodeDeviceDirName; UNICODE_STRING UnicodeDeviceDirName;
OBJECT_ATTRIBUTES DeviceDirAttributes; OBJECT_ATTRIBUTES DeviceDirAttributes;
HANDLE Handle; HANDLE Handle;
ULONG SectorCount = 0; ULONG SectorCount = 0;
BOOLEAN ExtendedPart = FALSE; PDRIVE_LAYOUT_INFORMATION PartitionList = NULL;
ULONG PartitionOffset = 0; PPARTITION_INFORMATION PartitionEntry;
ULONG offsetToNextPartition = 0; ULONG i;
#ifdef PARTITION_FIX
ULONG ExtendedOffset;
#endif
// Copy I/O port offsets for convenience // Copy I/O port offsets for convenience
CommandPort = ControllerExtension->CommandPortBase; CommandPort = ControllerExtension->CommandPortBase;
@ -507,7 +483,7 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
CommandPort, CommandPort,
DriveIdx); DriveIdx);
// Get the Drive Identification Data /* Get the Drive Identification Data */
if (!IDEGetDriveIdentification(CommandPort, DriveIdx, &DrvParms)) if (!IDEGetDriveIdentification(CommandPort, DriveIdx, &DrvParms))
{ {
DPRINT("Giving up on drive %d on controller %d...\n", DPRINT("Giving up on drive %d on controller %d...\n",
@ -516,9 +492,7 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
return FALSE; return FALSE;
} }
CreatedDevices = FALSE; /* Create the harddisk device directory */
// Create the harddisk device directory
swprintf (NameBuffer, swprintf (NameBuffer,
L"\\Device\\Harddisk%d", L"\\Device\\Harddisk%d",
HarddiskIdx); HarddiskIdx);
@ -529,14 +503,14 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
0, 0,
NULL, NULL,
NULL); NULL);
RC = ZwCreateDirectoryObject(&Handle, 0, &DeviceDirAttributes); Status = ZwCreateDirectoryObject(&Handle, 0, &DeviceDirAttributes);
if (!NT_SUCCESS(RC)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("Could not create device dir object\n"); DbgPrint("Could not create device dir object\n");
return FALSE; return FALSE;
} }
// Create the raw device /* Create the disk device */
if (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED) if (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED)
{ {
SectorCount = SectorCount =
@ -549,129 +523,87 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
} }
DPRINT("SectorCount %lu\n", SectorCount); DPRINT("SectorCount %lu\n", SectorCount);
RC = IDECreateDevice(DriverObject, Status = IDECreateDevice(DriverObject,
&RawDeviceObject, &RawDeviceObject,
ControllerObject, ControllerObject,
DriveIdx, DriveIdx,
HarddiskIdx, HarddiskIdx,
0, &DrvParms,
&DrvParms, 0,
0, 0,
SectorCount); SectorCount);
if (!NT_SUCCESS(RC)) if (!NT_SUCCESS(Status))
{ {
DbgPrint ("IDECreateDevice call failed for raw device\n", 0); DbgPrint("IDECreateDevice call failed for raw device\n");
} return FALSE;
else
{
// Increase number of available raw disk drives
IoGetConfigurationInformation()->DiskCount++;
CreatedDevices = TRUE;
RawDeviceExtension = (PIDE_DEVICE_EXTENSION)
RawDeviceObject->DeviceExtension;
// Initialze the controller timer here (since it has to be
// tied to a device)...
if (DriveIdx == 0)
{
ControllerExtension->TimerState = IDETimerIdle;
ControllerExtension->TimerCount = 0;
ControllerExtension->TimerDevice = RawDeviceObject;
IoInitializeTimer(RawDeviceObject, IDEIoTimer, ControllerExtension);
}
} }
// read the partition table (chain) /* Increase number of available physical disk drives */
PartitionOffset = 0; IoGetConfigurationInformation()->DiskCount++;
#ifdef PARTITION_FIX
ExtendedOffset = 0;
#endif
PartitionNum = 1;
do RawDeviceExtension = (PIDE_DEVICE_EXTENSION)RawDeviceObject->DeviceExtension;
/*
* Initialize the controller timer here
* (since it has to be tied to a device)
*/
if (DriveIdx == 0)
{ {
ExtendedPart = FALSE; ControllerExtension->TimerState = IDETimerIdle;
ControllerExtension->TimerCount = 0;
// Get Next partition table for device ControllerExtension->TimerDevice = RawDeviceObject;
if (!IDEGetPartitionTable(CommandPort, DriveIdx, PartitionOffset, &DrvParms, PartitionTable)) IoInitializeTimer(RawDeviceObject,
{ IDEIoTimer,
DbgPrint("drive %d controller %d offset %lu: Could not get partition table\n", ControllerExtension);
DriveIdx,
ControllerExtension->Number,
PartitionOffset);
}
else
{
// build devices for all partitions in table
DPRINT("Read partition on %wZ at %ld\n",
&UnicodeDeviceDirName,
PartitionOffset);
for (PartitionIdx = 0; PartitionIdx < 4; PartitionIdx++)
{
// copy partition pointer for convenience
p = &PartitionTable[PartitionIdx];
// if the partition entry is in use, create a device for it
if (IsRecognizedPartition(p->PartitionType))
{
DPRINT("Partition: %wZ entry:%d type:%02x Start:%lu Size:%lu\n",
&UnicodeDeviceDirName,
PartitionIdx,
p->PartitionType,
p->StartingBlock,
p->SectorCount);
// Create Device for partition
TotalPartitions++;
RC = IDECreateDevice(DriverObject,
&PrimaryDeviceObject,
ControllerObject,
DriveIdx,
HarddiskIdx,
PartitionNum,
&DrvParms,
p->StartingBlock + PartitionOffset,
p->SectorCount);
if (!NT_SUCCESS(RC))
{
DbgPrint ("IDECreateDevice call failed\n", 0);
break;
}
PartitionNum++;
}
else if (IsExtendedPartition(p->PartitionType))
{
// Create devices for logical partitions within an extended partition
DPRINT("Extended: entry:%d type:%02x Start:%lu Size:%lu\n",
PartitionIdx,
p->PartitionType,
p->StartingBlock,
p->SectorCount);
ExtendedPart = TRUE;
#ifdef PARTITION_FIX
if (ExtendedOffset == 0)
{
ExtendedOffset = p->StartingBlock;
offsetToNextPartition = 0;
}
else
{
offsetToNextPartition = p->StartingBlock;
}
#else
offsetToNextPartition = p->StartingBlock;
#endif
}
}
#ifdef PARTITION_FIX
PartitionOffset = ExtendedOffset + offsetToNextPartition;
#else
PartitionOffset += offsetToNextPartition;
#endif
}
} }
while (ExtendedPart == TRUE);
DPRINT("DrvParms.BytesPerSector %ld\n",DrvParms.BytesPerSector);
/* Read partition table */
Status = IoReadPartitionTable(RawDeviceObject,
DrvParms.BytesPerSector,
TRUE,
&PartitionList);
if (!NT_SUCCESS(Status))
{
DbgPrint("IoReadPartitionTable() failed\n");
return FALSE;
}
DPRINT(" Number of partitions: %u\n", PartitionList->PartitionCount);
for (i=0;i < PartitionList->PartitionCount; i++)
{
PartitionEntry = &PartitionList->PartitionEntry[i];
DPRINT("Partition %02ld: nr: %d boot: %1x type: %x offset: %I64d size: %I64d\n",
i,
PartitionEntry->PartitionNumber,
PartitionEntry->BootIndicator,
PartitionEntry->PartitionType,
PartitionEntry->StartingOffset.QuadPart / 512 /*DrvParms.BytesPerSector*/,
PartitionEntry->PartitionLength.QuadPart / 512 /* DrvParms.BytesPerSector*/);
/* Create device for partition */
Status = IDECreateDevice(DriverObject,
&PartitionDeviceObject,
ControllerObject,
DriveIdx,
HarddiskIdx,
&DrvParms,
PartitionEntry->PartitionNumber,
PartitionEntry->StartingOffset.QuadPart / 512 /* DrvParms.BytesPerSector*/,
PartitionEntry->PartitionLength.QuadPart / 512 /*DrvParms.BytesPerSector*/);
if (!NT_SUCCESS(Status))
{
DbgPrint("IDECreateDevice() failed\n");
break;
}
}
if (PartitionList != NULL)
ExFreePool(PartitionList);
//for (;;);
return TRUE; return TRUE;
} }
@ -743,118 +675,11 @@ IDEGetDriveIdentification(IN int CommandPort,
DrvParms->TMSectorCountLo, DrvParms->TMSectorCountLo,
(ULONG)((DrvParms->TMSectorCountHi << 16) + DrvParms->TMSectorCountLo)); (ULONG)((DrvParms->TMSectorCountHi << 16) + DrvParms->TMSectorCountLo));
DPRINT("BytesPerSector %d\n", DrvParms->BytesPerSector);
DrvParms->BytesPerSector = 512; /* FIXME !!!*/
return TRUE; return TRUE;
} }
// IDEGetPartitionTable
//
// DESCRIPTION:
// Gets the partition table from the device at the given offset if one exists
//
// RUN LEVEL:
// PASSIVE_LEVEL
//
// ARGUMENTS:
// IN int CommandPort Address of command port for controller
// IN int DriveNum index of drive (0,1)
// IN int Offset Block offset (LBA addressing)
// OUT PARTITION *PartitionTable address to write partition table
//
// RETURNS:
// TRUE partition table was retrieved successfully
//
BOOLEAN
IDEGetPartitionTable(IN int CommandPort,
IN int DriveNum,
IN int Offset,
IN PIDE_DRIVE_IDENTIFY DrvParms,
OUT PARTITION *PartitionTable)
{
BYTE SectorBuf[512], SectorNum, DrvHead, CylinderLow, CylinderHigh;
int RC, SaveOffset;
#ifndef NDEBUG
int i;
#endif
// Get sector at offset
SaveOffset = Offset;
if (DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED)
{
SectorNum = Offset & 0xff;
CylinderLow = (Offset >> 8) & 0xff;
CylinderHigh = (Offset >> 16) & 0xff;
DrvHead = ((Offset >> 24) & 0x0f) |
(DriveNum ? IDE_DH_DRV1 : 0) |
IDE_DH_LBA;
}
else
{
SectorNum = (Offset % DrvParms->SectorsPerTrack) + 1;
Offset /= DrvParms->SectorsPerTrack;
DrvHead = (Offset % DrvParms->LogicalHeads) |
(DriveNum ? IDE_DH_DRV1 : 0);
Offset /= DrvParms->LogicalHeads;
CylinderLow = Offset & 0xff;
CylinderHigh = Offset >> 8;
}
Offset = SaveOffset;
RC = IDEPolledRead(CommandPort,
0,
1,
SectorNum,
CylinderLow,
CylinderHigh,
DrvHead,
// IDE_CMD_READ_RETRY,
IDE_CMD_READ,
SectorBuf);
if (RC != 0)
{
DbgPrint ("read failed: port %04x drive %d sector %d rc %d\n",
CommandPort,
DriveNum,
Offset,
RC);
return FALSE;
}
else if (*((WORD *)(SectorBuf + PART_MAGIC_OFFSET)) != PARTITION_MAGIC)
{
DbgPrint ("Bad partition magic: port %04x drive %d offset %d magic %d\n",
CommandPort,
DriveNum,
Offset,
*((short *)(SectorBuf + PART_MAGIC_OFFSET)));
return FALSE;
}
RtlCopyMemory(PartitionTable, SectorBuf + PARTITION_OFFSET, sizeof(PARTITION) * 4);
#ifndef NDEBUG
DPRINT("Partition Table for device %d at offset %d on port %x\n",
DriveNum,
Offset,
CommandPort);
for (i = 0; i < PARTITION_TBL_SIZE; i++)
{
DPRINT(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
i,
PartitionTable[i].BootFlags,
PartitionTable[i].PartitionType,
PartitionTable[i].StartingHead,
PartitionTable[i].StartingSector,
PartitionTable[i].StartingCylinder,
PartitionTable[i].EndingHead,
PartitionTable[i].EndingSector,
PartitionTable[i].EndingCylinder,
PartitionTable[i].StartingBlock,
PartitionTable[i].SectorCount);
}
#endif
return TRUE;
}
// IDECreateDevice // IDECreateDevice
// //
@ -885,10 +710,10 @@ IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
IN PCONTROLLER_OBJECT ControllerObject, IN PCONTROLLER_OBJECT ControllerObject,
IN int UnitNumber, IN int UnitNumber,
IN ULONG DiskNumber, IN ULONG DiskNumber,
IN ULONG PartitionNumber,
IN PIDE_DRIVE_IDENTIFY DrvParms, IN PIDE_DRIVE_IDENTIFY DrvParms,
IN DWORD Offset, IN ULONG PartitionNumber,
IN DWORD Size) IN ULONGLONG Offset,
IN ULONGLONG Size)
{ {
WCHAR NameBuffer[IDE_MAX_NAME_LENGTH]; WCHAR NameBuffer[IDE_MAX_NAME_LENGTH];
WCHAR ArcNameBuffer[IDE_MAX_NAME_LENGTH + 15]; WCHAR ArcNameBuffer[IDE_MAX_NAME_LENGTH + 15];
@ -933,9 +758,11 @@ IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
DrvParms->SectorsPerTrack; DrvParms->SectorsPerTrack;
DeviceExtension->SectorsPerLogTrk = DrvParms->SectorsPerTrack; DeviceExtension->SectorsPerLogTrk = DrvParms->SectorsPerTrack;
DeviceExtension->LogicalHeads = DrvParms->LogicalHeads; DeviceExtension->LogicalHeads = DrvParms->LogicalHeads;
DeviceExtension->LogicalCylinders =
(DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED) ? DrvParms->TMCylinders : DrvParms->LogicalCyls;
DeviceExtension->Offset = Offset; DeviceExtension->Offset = Offset;
DeviceExtension->Size = Size; DeviceExtension->Size = Size;
DPRINT("%wZ: offset %d size %d \n", DPRINT("%wZ: offset %lu size %lu \n",
&DeviceName, &DeviceName,
DeviceExtension->Offset, DeviceExtension->Offset,
DeviceExtension->Size); DeviceExtension->Size);
@ -945,7 +772,7 @@ IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
if (PartitionNumber != 0) if (PartitionNumber != 0)
{ {
DbgPrint("%wZ %dMB\n", &DeviceName, Size / 2048); DbgPrint("%wZ %luMB\n", &DeviceName, Size / 2048);
} }
/* assign arc name */ /* assign arc name */
@ -1208,13 +1035,13 @@ DPRINT("AdjOffset:%ld:%ld + Length:%ld = AdjExtent:%ld:%ld\n",
if ((AdjustedExtent.QuadPart > PartitionExtent.QuadPart) || if ((AdjustedExtent.QuadPart > PartitionExtent.QuadPart) ||
(IrpStack->Parameters.Read.Length & (DeviceExtension->BytesPerSector - 1))) (IrpStack->Parameters.Read.Length & (DeviceExtension->BytesPerSector - 1)))
{ {
DbgPrint ("Request failed on bad parameters\n"); DPRINT("Request failed on bad parameters\n",0);
DbgPrint ("AdjustedExtent=%d:%d PartitionExtent=%d:%d ReadLength=%d\n", DPRINT("AdjustedExtent=%d:%d PartitionExtent=%d:%d ReadLength=%d\n",
(unsigned int) AdjustedExtent.u.HighPart, (unsigned int) AdjustedExtent.u.HighPart,
(unsigned int) AdjustedExtent.u.LowPart, (unsigned int) AdjustedExtent.u.LowPart,
(unsigned int) PartitionExtent.u.HighPart, (unsigned int) PartitionExtent.u.HighPart,
(unsigned int) PartitionExtent.u.LowPart, (unsigned int) PartitionExtent.u.LowPart,
IrpStack->Parameters.Read.Length); IrpStack->Parameters.Read.Length);
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
@ -1248,9 +1075,9 @@ DPRINT("AdjOffset:%ld:%ld + Length:%ld = AdjExtent:%ld:%ld\n",
// NTSTATUS // NTSTATUS
// //
static NTSTATUS static NTSTATUS STDCALL
STDCALL IDEDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IDEDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
NTSTATUS RC; NTSTATUS RC;
ULONG ControlCode, InputLength, OutputLength; ULONG ControlCode, InputLength, OutputLength;
@ -1265,22 +1092,21 @@ STDCALL IDEDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
DeviceExtension = (PIDE_DEVICE_EXTENSION) DeviceObject->DeviceExtension; DeviceExtension = (PIDE_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
// A huge switch statement in a Windows program?! who would have thought? // A huge switch statement in a Windows program?! who would have thought?
switch (ControlCode) switch (ControlCode)
{ {
case IOCTL_DISK_GET_DRIVE_GEOMETRY: case IOCTL_DISK_GET_DRIVE_GEOMETRY:
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY)) if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
{ {
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
} }
else else
{ {
PDISK_GEOMETRY Geometry; PDISK_GEOMETRY Geometry;
Geometry = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer; Geometry = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
Geometry->MediaType = FixedMedia; Geometry->MediaType = FixedMedia;
// FIXME: should report for RawDevice even on partition // FIXME: should report for RawDevice even on partition
Geometry->Cylinders.QuadPart = DeviceExtension->Size / Geometry->Cylinders.QuadPart = DeviceExtension->LogicalCylinders;
DeviceExtension->SectorsPerLogCyl;
Geometry->TracksPerCylinder = DeviceExtension->SectorsPerLogTrk / Geometry->TracksPerCylinder = DeviceExtension->SectorsPerLogTrk /
DeviceExtension->SectorsPerLogCyl; DeviceExtension->SectorsPerLogCyl;
Geometry->SectorsPerTrack = DeviceExtension->SectorsPerLogTrk; Geometry->SectorsPerTrack = DeviceExtension->SectorsPerLogTrk;
@ -1344,6 +1170,8 @@ STDCALL IDEStartIo(IN PDEVICE_OBJECT DeviceObject,
PIDE_DEVICE_EXTENSION DeviceExtension; PIDE_DEVICE_EXTENSION DeviceExtension;
KIRQL OldIrql; KIRQL OldIrql;
DPRINT("IDEStartIo() called!\n");
IrpStack = IoGetCurrentIrpStackLocation(Irp); IrpStack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = (PIDE_DEVICE_EXTENSION) DeviceObject->DeviceExtension; DeviceExtension = (PIDE_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
@ -1387,6 +1215,7 @@ STDCALL IDEStartIo(IN PDEVICE_OBJECT DeviceObject,
IoStartNextPacket(DeviceObject, FALSE); IoStartNextPacket(DeviceObject, FALSE);
break; break;
} }
DPRINT("IDEStartIo() finished!\n");
} }
// IDEAllocateController // IDEAllocateController
@ -1911,19 +1740,19 @@ IDEIsr(IN PKINTERRUPT Interrupt,
// IN PIRP DpcIrp // IN PIRP DpcIrp
// IN PVOID DpcContext // IN PVOID DpcContext
// //
static VOID static VOID
IDEDpcForIsr(IN PKDPC Dpc, IDEDpcForIsr(IN PKDPC Dpc,
IN PDEVICE_OBJECT DpcDeviceObject, IN PDEVICE_OBJECT DpcDeviceObject,
IN PIRP DpcIrp, IN PIRP DpcIrp,
IN PVOID DpcContext) IN PVOID DpcContext)
{ {
DPRINT("IDEDpcForIsr()\n"); DPRINT("IDEDpcForIsr()\n");
IDEFinishOperation((PIDE_CONTROLLER_EXTENSION) DpcContext); IDEFinishOperation((PIDE_CONTROLLER_EXTENSION) DpcContext);
} }
// IDEFinishOperation // IDEFinishOperation
static VOID static VOID
IDEFinishOperation(PIDE_CONTROLLER_EXTENSION ControllerExtension) IDEFinishOperation(PIDE_CONTROLLER_EXTENSION ControllerExtension)
{ {
PIDE_DEVICE_EXTENSION DeviceExtension; PIDE_DEVICE_EXTENSION DeviceExtension;

View file

@ -24,7 +24,7 @@ extern "C" {
#define IDE_MAX_CMD_RETRIES 0 #define IDE_MAX_CMD_RETRIES 0
#define IDE_CMD_TIMEOUT 5 #define IDE_CMD_TIMEOUT 5
#define IDE_RESET_PULSE_LENGTH 500 /* maybe a little too long */ #define IDE_RESET_PULSE_LENGTH 500 /* maybe a little too long */
#define IDE_RESET_BUSY_TIMEOUT 31 #define IDE_RESET_BUSY_TIMEOUT 120
#define IDE_RESET_DRDY_TIMEOUT 120 #define IDE_RESET_DRDY_TIMEOUT 120
// Control Block offsets and masks // Control Block offsets and masks
@ -126,7 +126,8 @@ extern "C" {
// Available at any IRQL // Available at any IRQL
// //
typedef struct _IDE_DEVICE_EXTENSION { typedef struct _IDE_DEVICE_EXTENSION
{
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PCONTROLLER_OBJECT ControllerObject; PCONTROLLER_OBJECT ControllerObject;
struct _IDE_DEVICE_EXTESION *DiskExtension; struct _IDE_DEVICE_EXTESION *DiskExtension;
@ -135,6 +136,7 @@ typedef struct _IDE_DEVICE_EXTENSION {
BOOLEAN DMASupported; BOOLEAN DMASupported;
int BytesPerSector; int BytesPerSector;
int LogicalHeads; int LogicalHeads;
int LogicalCylinders;
int SectorsPerLogCyl; int SectorsPerLogCyl;
int SectorsPerLogTrk; int SectorsPerLogTrk;
int Offset; int Offset;

View file

@ -1,4 +1,4 @@
/* $Id: disk.h,v 1.4 2000/08/21 00:11:51 ekohl Exp $ /* $Id: disk.h,v 1.5 2001/06/07 21:16:17 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -101,29 +101,32 @@ typedef enum _MEDIA_TYPE {
FixedMedia FixedMedia
} MEDIA_TYPE; } MEDIA_TYPE;
typedef struct _PARTITION_INFORMATION { typedef struct _PARTITION_INFORMATION
LARGE_INTEGER StartingOffset; {
LARGE_INTEGER PartitionLength; LARGE_INTEGER StartingOffset;
DWORD HiddenSectors; LARGE_INTEGER PartitionLength;
DWORD PartitionNumber; DWORD HiddenSectors;
BYTE PartitionType; DWORD PartitionNumber;
BOOLEAN BootIndicator; BYTE PartitionType;
BOOLEAN RecognizedPartition; BOOLEAN BootIndicator;
BOOLEAN RewritePartition; BOOLEAN RecognizedPartition;
} PARTITION_INFORMATION; BOOLEAN RewritePartition;
} PARTITION_INFORMATION, *PPARTITION_INFORMATION;
typedef struct _DRIVE_LAYOUT_INFORMATION { typedef struct _DRIVE_LAYOUT_INFORMATION
DWORD PartitionCount; {
DWORD Signature; DWORD PartitionCount;
PARTITION_INFORMATION PartitionEntry[1]; DWORD Signature;
PARTITION_INFORMATION PartitionEntry[1];
} DRIVE_LAYOUT_INFORMATION, *PDRIVE_LAYOUT_INFORMATION; } DRIVE_LAYOUT_INFORMATION, *PDRIVE_LAYOUT_INFORMATION;
typedef struct _DISK_GEOMETRY { typedef struct _DISK_GEOMETRY
LARGE_INTEGER Cylinders; {
MEDIA_TYPE MediaType; LARGE_INTEGER Cylinders;
DWORD TracksPerCylinder; MEDIA_TYPE MediaType;
DWORD SectorsPerTrack; DWORD TracksPerCylinder;
DWORD BytesPerSector; DWORD SectorsPerTrack;
DWORD BytesPerSector;
} DISK_GEOMETRY, *PDISK_GEOMETRY; } DISK_GEOMETRY, *PDISK_GEOMETRY;
#endif /* __INCLUDE_DISK_H */ #endif /* __INCLUDE_DISK_H */

View file

@ -1,4 +1,4 @@
/* $Id: xhaldrv.c,v 1.8 2001/05/06 22:32:34 ekohl Exp $ /* $Id: xhaldrv.c,v 1.9 2001/06/07 21:16:41 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -142,14 +142,11 @@ xHalpQueryDriveLayout (
} }
VOID VOID FASTCALL
FASTCALL xHalExamineMBR(IN PDEVICE_OBJECT DeviceObject,
xHalExamineMBR ( IN ULONG SectorSize,
IN PDEVICE_OBJECT DeviceObject, IN ULONG MBRTypeIdentifier,
IN ULONG SectorSize, OUT PVOID *Buffer)
IN ULONG MBRTypeIdentifier,
OUT PVOID * Buffer
)
{ {
KEVENT Event; KEVENT Event;
IO_STATUS_BLOCK StatusBlock; IO_STATUS_BLOCK StatusBlock;
@ -568,18 +565,15 @@ xHalIoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
} }
NTSTATUS NTSTATUS FASTCALL
FASTCALL xHalIoReadPartitionTable(PDEVICE_OBJECT DeviceObject,
xHalIoReadPartitionTable ( ULONG SectorSize,
PDEVICE_OBJECT DeviceObject, BOOLEAN ReturnRecognizedPartitions,
ULONG SectorSize, PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
BOOLEAN ReturnRecognizedPartitions,
PDRIVE_LAYOUT_INFORMATION * PartitionBuffer
)
{ {
KEVENT Event; KEVENT Event;
IO_STATUS_BLOCK StatusBlock; IO_STATUS_BLOCK StatusBlock;
ULARGE_INTEGER Offset; ULARGE_INTEGER PartitionOffset;
PUCHAR SectorBuffer; PUCHAR SectorBuffer;
PIRP Irp; PIRP Irp;
NTSTATUS Status; NTSTATUS Status;
@ -598,57 +592,59 @@ xHalIoReadPartitionTable (
*PartitionBuffer = NULL; *PartitionBuffer = NULL;
SectorBuffer = (PUCHAR)ExAllocatePool (PagedPool, SectorBuffer = (PUCHAR)ExAllocatePool(PagedPool,
SectorSize); SectorSize);
if (SectorBuffer == NULL) if (SectorBuffer == NULL)
{ {
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
LayoutBuffer = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePool (NonPagedPool, LayoutBuffer = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePool(NonPagedPool,
0x1000); 0x1000);
if (LayoutBuffer == NULL) if (LayoutBuffer == NULL)
{ {
ExFreePool (SectorBuffer); ExFreePool (SectorBuffer);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
RtlZeroMemory (LayoutBuffer, 0x1000); RtlZeroMemory(LayoutBuffer,
0x1000);
Offset.QuadPart = 0; PartitionOffset.QuadPart = 0;
do do
{ {
KeInitializeEvent (&Event, KeInitializeEvent(&Event,
NotificationEvent, NotificationEvent,
FALSE); FALSE);
Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ, DPRINT("PartitionOffset: %I64u\n", PartitionOffset.QuadPart / SectorSize);
DeviceObject,
SectorBuffer,
SectorSize,
(PLARGE_INTEGER)&Offset,
&Event,
&StatusBlock);
Status = IoCallDriver (DeviceObject, Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
Irp); DeviceObject,
SectorBuffer,
SectorSize,
(PLARGE_INTEGER)&PartitionOffset,
&Event,
&StatusBlock);
Status = IoCallDriver(DeviceObject,
Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
KeWaitForSingleObject (&Event, KeWaitForSingleObject(&Event,
Executive, Executive,
KernelMode, KernelMode,
FALSE, FALSE,
NULL); NULL);
Status = StatusBlock.Status; Status = StatusBlock.Status;
} }
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("xHalIoReadPartitonTable failed (Status = 0x%08lx)\n", DPRINT("xHalIoReadPartitonTable failed (Status = 0x%08lx)\n",
Status); Status);
ExFreePool (SectorBuffer); ExFreePool(SectorBuffer);
ExFreePool (LayoutBuffer); ExFreePool(LayoutBuffer);
return Status; return Status;
} }
@ -658,31 +654,28 @@ xHalIoReadPartitionTable (
DPRINT("Magic %x\n", PartitionTable->Magic); DPRINT("Magic %x\n", PartitionTable->Magic);
if (PartitionTable->Magic != PARTITION_MAGIC) if (PartitionTable->Magic != PARTITION_MAGIC)
{ {
DPRINT1("Invalid partition table magic\n"); DPRINT("Invalid partition table magic\n");
ExFreePool (SectorBuffer); ExFreePool(SectorBuffer);
// ExFreePool (LayoutBuffer);
// return STATUS_UNSUCCESSFUL;
*PartitionBuffer = LayoutBuffer; *PartitionBuffer = LayoutBuffer;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
#ifndef NDEBUG #ifndef NDEBUG
for (i = 0; i < PARTITION_TBL_SIZE; i++) for (i = 0; i < PARTITION_TBL_SIZE; i++)
{ {
DPRINT(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n", DPRINT(" %d: flags:%2x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",
i, i,
PartitionTable->Partition[i].BootFlags, PartitionTable->Partition[i].BootFlags,
PartitionTable->Partition[i].PartitionType, PartitionTable->Partition[i].PartitionType,
PartitionTable->Partition[i].StartingHead, PartitionTable->Partition[i].StartingHead,
PartitionTable->Partition[i].StartingSector, PartitionTable->Partition[i].StartingSector,
PartitionTable->Partition[i].StartingCylinder, PartitionTable->Partition[i].StartingCylinder,
PartitionTable->Partition[i].EndingHead, PartitionTable->Partition[i].EndingHead,
PartitionTable->Partition[i].EndingSector, PartitionTable->Partition[i].EndingSector,
PartitionTable->Partition[i].EndingCylinder, PartitionTable->Partition[i].EndingCylinder,
PartitionTable->Partition[i].StartingBlock, PartitionTable->Partition[i].StartingBlock,
PartitionTable->Partition[i].SectorCount); PartitionTable->Partition[i].SectorCount);
} }
#endif #endif
if (ExtendedFound == FALSE); if (ExtendedFound == FALSE);
@ -691,73 +684,82 @@ xHalIoReadPartitionTable (
} }
ExtendedFound = FALSE; ExtendedFound = FALSE;
for (i = 0; i < PARTITION_TBL_SIZE; i++) for (i = 0; i < PARTITION_TBL_SIZE; i++)
{ {
/* handle normal partition */ if ((ReturnRecognizedPartitions == FALSE) ||
DPRINT("Partition %u: Normal Partition\n", i); ((ReturnRecognizedPartitions == TRUE) &&
Count = LayoutBuffer->PartitionCount; IsRecognizedPartition(PartitionTable->Partition[i].PartitionType)))
DPRINT("Logical Partition %u\n", Count);
if (PartitionTable->Partition[i].StartingBlock)
{ {
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = /* handle normal partition */
(ULONGLONG)Offset.QuadPart + DPRINT("Partition %u: Normal Partition\n", i);
Count = LayoutBuffer->PartitionCount;
DPRINT("Logical Partition %u\n", Count);
if (PartitionTable->Partition[i].StartingBlock == 0)
{
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = 0;
}
else if (IsExtendedPartition(PartitionTable->Partition[i].PartitionType))
{
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
(ULONGLONG)PartitionOffset.QuadPart;
}
else
{
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
(ULONGLONG)PartitionOffset.QuadPart +
((ULONGLONG)PartitionTable->Partition[i].StartingBlock * (ULONGLONG)SectorSize); ((ULONGLONG)PartitionTable->Partition[i].StartingBlock * (ULONGLONG)SectorSize);
}
LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart =
(ULONGLONG)PartitionTable->Partition[i].SectorCount * (ULONGLONG)SectorSize;
LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0;
if (IsRecognizedPartition(PartitionTable->Partition[i].PartitionType))
{
LayoutBuffer->PartitionEntry[Count].PartitionNumber = Number;
Number++;
}
else
{
LayoutBuffer->PartitionEntry[Count].PartitionNumber = 0;
}
LayoutBuffer->PartitionEntry[Count].PartitionType =
PartitionTable->Partition[i].PartitionType;
LayoutBuffer->PartitionEntry[Count].BootIndicator =
(PartitionTable->Partition[i].BootFlags & 0x80)?TRUE:FALSE;
LayoutBuffer->PartitionEntry[Count].RecognizedPartition =
IsRecognizedPartition (PartitionTable->Partition[i].PartitionType);
LayoutBuffer->PartitionEntry[Count].RewritePartition = FALSE;
DPRINT1(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n",
Count,
LayoutBuffer->PartitionEntry[Count].PartitionNumber,
LayoutBuffer->PartitionEntry[Count].BootIndicator,
LayoutBuffer->PartitionEntry[Count].PartitionType,
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart,
LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart);
LayoutBuffer->PartitionCount++;
} }
else
{
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart = 0;
}
LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart =
(ULONGLONG)PartitionTable->Partition[i].SectorCount * (ULONGLONG)SectorSize;
LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0;
if (IsUsablePartition(PartitionTable->Partition[i].PartitionType)) if (IsUsablePartition(PartitionTable->Partition[i].PartitionType))
{ {
LayoutBuffer->PartitionEntry[Count].PartitionNumber = Number; PartitionOffset.QuadPart = (ULONGLONG)PartitionOffset.QuadPart +
Number++; (((ULONGLONG)PartitionTable->Partition[i].StartingBlock +
} (ULONGLONG)PartitionTable->Partition[i].SectorCount)* (ULONGLONG)SectorSize);
else
{
LayoutBuffer->PartitionEntry[Count].PartitionNumber = 0;
}
LayoutBuffer->PartitionEntry[Count].PartitionType =
PartitionTable->Partition[i].PartitionType;
LayoutBuffer->PartitionEntry[Count].BootIndicator =
(PartitionTable->Partition[i].BootFlags & 0x80)?TRUE:FALSE;
LayoutBuffer->PartitionEntry[Count].RecognizedPartition =
IsRecognizedPartition (PartitionTable->Partition[i].PartitionType);
LayoutBuffer->PartitionEntry[Count].RewritePartition = FALSE;
DPRINT(" Offset: 0x%I64x", Offset.QuadPart);
if (IsUsablePartition(PartitionTable->Partition[i].PartitionType))
{
Offset.QuadPart = (ULONGLONG)Offset.QuadPart +
(((ULONGLONG)PartitionTable->Partition[i].StartingBlock + (ULONGLONG)PartitionTable->Partition[i].SectorCount)* (ULONGLONG)SectorSize);
} }
if (IsExtendedPartition(PartitionTable->Partition[i].PartitionType)) if (IsExtendedPartition(PartitionTable->Partition[i].PartitionType))
{ {
ExtendedFound = TRUE; ExtendedFound = TRUE;
} }
DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x\n",
Count,
LayoutBuffer->PartitionEntry[Count].PartitionNumber,
LayoutBuffer->PartitionEntry[Count].BootIndicator,
LayoutBuffer->PartitionEntry[Count].PartitionType,
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart,
LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart);
LayoutBuffer->PartitionCount++;
} }
} }
while (ExtendedFound == TRUE); while (ExtendedFound == TRUE);
*PartitionBuffer = LayoutBuffer; *PartitionBuffer = LayoutBuffer;
ExFreePool (SectorBuffer); ExFreePool(SectorBuffer);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }