Implemented IoReadPartitionTable().

Implemented proper drive letter assignment.

svn path=/trunk/; revision=1310
This commit is contained in:
Eric Kohl 2000-08-21 00:15:54 +00:00
parent 8434fc42db
commit 6f1d7ad00c
7 changed files with 620 additions and 100 deletions

View file

@ -1,4 +1,4 @@
/* $Id: ide.c,v 1.30 2000/08/18 17:24:17 ekohl Exp $
/* $Id: ide.c,v 1.31 2000/08/21 00:15:53 ekohl Exp $
*
* IDE.C - IDE Disk driver
* written by Rex Jolliff
@ -157,7 +157,6 @@ static NTSTATUS IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
OUT PDEVICE_OBJECT *DeviceObject,
IN PCONTROLLER_OBJECT ControllerObject,
IN int UnitNumber,
IN char *Win32Alias,
IN PIDE_DRIVE_IDENTIFY DrvParms,
IN DWORD Offset,
IN DWORD Size);
@ -472,7 +471,6 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
char RawDeviceName[IDE_MAX_NAME_LENGTH];
char PrimaryDeviceName[IDE_MAX_NAME_LENGTH];
char LogicalDeviceName[IDE_MAX_NAME_LENGTH];
char Win32AliasName[IDE_MAX_NAME_LENGTH];
int CommandPort, PartitionIdx, PartitionNum;
int ExtPartitionIdx, ExtOffset;
NTSTATUS RC;
@ -548,7 +546,6 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
&RawDeviceObject,
ControllerObject,
DriveIdx,
NULL,
&DrvParms,
0,
DrvParms.LogicalCyls * DrvParms.LogicalHeads * DrvParms.SectorsPerTrack);
@ -596,7 +593,7 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
p = &PrimaryPartitionTable[PartitionIdx];
// if the partition entry is in use, create a device for it
if (IsRecognizedPartition(p))
if (IsRecognizedPartition(p->PartitionType))
{
DPRINT("%s ptbl entry:%d type:%02x Offset:%d Size:%d\n",
DeviceDirName,
@ -613,15 +610,12 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
strcat(PrimaryDeviceName, IDE_NT_PARTITION_NAME);
PrimaryDeviceName[strlen(PrimaryDeviceName) + 1] = '\0';
PrimaryDeviceName[strlen(PrimaryDeviceName)] = '0' + PartitionNum++;
strcpy(Win32AliasName, "\\??\\ :");
Win32AliasName[4] = 'C' + TotalPartitions;
TotalPartitions++;
RC = IDECreateDevice(DriverObject,
PrimaryDeviceName,
&PrimaryDeviceObject,
ControllerObject,
DriveIdx,
Win32AliasName,
&DrvParms,
p->StartingBlock,
p->SectorCount);
@ -633,7 +627,7 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
// Create devices for logical partitions within an extended partition
}
else if (IsExtendedPartition(p))
else if (IsExtendedPartition(p->PartitionType))
{
ExtOffset = p->StartingBlock;
@ -652,7 +646,7 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
for (ExtPartitionIdx = 0; ExtPartitionIdx < 4; ExtPartitionIdx++)
{
ep = &ExtendedPartitionTable[ExtPartitionIdx];
if (IsRecognizedPartition(ep))
if (IsRecognizedPartition(ep->PartitionType))
{
DPRINT("Harddisk%d: Type:%02x Offset:%d Size:%d\n",
HarddiskIdx,
@ -668,15 +662,12 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
strcat(LogicalDeviceName, IDE_NT_PARTITION_NAME);
LogicalDeviceName[strlen(LogicalDeviceName) + 1] = '\0';
LogicalDeviceName[strlen(LogicalDeviceName)] = '0' + PartitionNum++;
strcpy(Win32AliasName, "\\??\\ :");
Win32AliasName[4] = 'C' + TotalPartitions;
TotalPartitions++;
RC = IDECreateDevice(DriverObject,
LogicalDeviceName,
&LogicalDeviceObject,
ControllerObject,
DriveIdx,
Win32AliasName,
&DrvParms,
ep->StartingBlock + ExtOffset,
ep->SectorCount);
@ -901,15 +892,14 @@ IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
OUT PDEVICE_OBJECT *DeviceObject,
IN PCONTROLLER_OBJECT ControllerObject,
IN int UnitNumber,
IN char *Win32Alias,
IN PIDE_DRIVE_IDENTIFY DrvParms,
IN DWORD Offset,
IN DWORD Size)
{
WCHAR UnicodeBuffer[IDE_MAX_NAME_LENGTH];
NTSTATUS RC;
ANSI_STRING AnsiName, AnsiSymLink;
UNICODE_STRING UnicodeName, SymLink;
ANSI_STRING AnsiName;
UNICODE_STRING UnicodeName;
PIDE_DEVICE_EXTENSION DeviceExtension;
// Create a unicode device name
@ -953,24 +943,10 @@ IDECreateDevice(IN PDRIVER_OBJECT DriverObject,
DeviceExtension->Offset,
DeviceExtension->Size);
// FIXME: Create Win32 symbolic link (destroy device if it fails)
if (Win32Alias != NULL)
{
DPRINT("Creating SymLink %s --> %s\n", DeviceName, Win32Alias);
RtlInitAnsiString(&AnsiSymLink, Win32Alias);
RtlAnsiStringToUnicodeString(&SymLink, &AnsiSymLink, TRUE);
IoCreateSymbolicLink(&SymLink, &UnicodeName);
RtlFreeUnicodeString(&SymLink);
}
// Initialize the DPC object here
IoInitializeDpcRequest(*DeviceObject, IDEDpcForIsr);
if (Win32Alias != NULL)
{
DbgPrint("%s is %s %dMB\n", DeviceName, Win32Alias, Size / 2048);
}
DbgPrint("%s %dMB\n", DeviceName, Size / 2048);
return RC;
}

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.16 2000/08/20 17:02:10 dwelch Exp $
# $Id: makefile,v 1.17 2000/08/21 00:15:54 ekohl Exp $
#
#
PATH_TO_TOP = ../../..
@ -27,12 +27,20 @@ clean:
install: $(FLOPPY_DIR)/drivers/$(TARGET).sys
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
else
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
endif
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
else
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
endif
$(TARGET).sys $(TARGET).sys.unstripped: $(OBJECTS)

View file

@ -1,4 +1,4 @@
/* $Id: disk.h,v 1.3 2000/08/18 17:22:50 ekohl Exp $
/* $Id: disk.h,v 1.4 2000/08/21 00:11:51 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -72,17 +72,17 @@
#define IsRecognizedPartition(P) \
((P)->PartitionType == PTDOS3xPrimary || \
(P)->PartitionType == PTOLDDOS16Bit || \
(P)->PartitionType == PTDos5xPrimary || \
(P)->PartitionType == PTWin95FAT32 || \
(P)->PartitionType == PTWin95FAT32LBA || \
(P)->PartitionType == PTWin95FAT16LBA || \
(P)->PartitionType == PTLinuxExt2)
((P) == PTDOS3xPrimary || \
(P) == PTOLDDOS16Bit || \
(P) == PTDos5xPrimary || \
(P) == PTWin95FAT32 || \
(P) == PTWin95FAT32LBA || \
(P) == PTWin95FAT16LBA || \
(P) == PTLinuxExt2)
#define IsExtendedPartition(P) \
((P)->PartitionType == PTDosExtended || \
(P)->PartitionType == PTWin95ExtendedLBA)
((P) == PTDosExtended || \
(P) == PTWin95ExtendedLBA)
typedef enum _MEDIA_TYPE {
@ -102,13 +102,14 @@ typedef enum _MEDIA_TYPE {
} MEDIA_TYPE;
typedef struct _PARTITION_INFORMATION {
LARGE_INTEGER StartingOffset;
LARGE_INTEGER PartitionLength;
DWORD HiddenSectors;
DWORD PartitionNumber;
BYTE PartitionType;
BOOLEAN BootIndicator;
BOOLEAN RecognizedPartition;
BOOLEAN RewritePartition;
LARGE_INTEGER StartingOffset;
LARGE_INTEGER PartitionLength;
LARGE_INTEGER HiddenSectors;
} PARTITION_INFORMATION;
typedef struct _DRIVE_LAYOUT_INFORMATION {

View file

@ -1,4 +1,4 @@
/* $Id: parttab.c,v 1.2 2000/06/30 22:51:34 ekohl Exp $
/* $Id: parttab.c,v 1.3 2000/08/21 00:12:20 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -28,7 +28,17 @@ IoReadPartitionTable (
PDRIVE_LAYOUT_INFORMATION * PartitionBuffer
)
{
UNIMPLEMENTED;
#ifdef __NTOSKRNL__
return HalDispatchTable.HalIoReadPartitionTable(DeviceObject,
SectorSize,
ReturnRecognizedPartitions,
PartitionBuffer);
#else
return HalDispatchTable->HalIoReadPartitionTable(DeviceObject,
SectorSize,
ReturnRecognizedPartitions,
PartitionBuffer);
#endif
}
NTSTATUS

View file

@ -19,4 +19,14 @@ xHalIoAssignDriveLetters (
OUT PSTRING NtSystemPathString
);
NTSTATUS
FASTCALL
xHalIoReadPartitionTable (
PDEVICE_OBJECT DeviceObject,
ULONG SectorSize,
BOOLEAN ReturnRecognizedPartitions,
PDRIVE_LAYOUT_INFORMATION * PartitionBuffer
);
#endif

View file

@ -1,4 +1,4 @@
/* $Id: xhaldisp.c,v 1.1 2000/06/30 22:52:49 ekohl Exp $
/* $Id: xhaldisp.c,v 1.2 2000/08/21 00:14:04 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -26,9 +26,9 @@ HAL_DISPATCH EXPORTED HalDispatchTable =
NULL, // HalDeviceControl
xHalExamineMBR,
xHalIoAssignDriveLetters,
NULL, // HalIoReadPartitionTable
NULL, // HalIoSetPartitionInformation
NULL, // HalIoWritePartitionTable
xHalIoReadPartitionTable,
NULL, // xHalIoSetPartitionInformation,
NULL, // xHalIoWritePartitionTable,
NULL, // HalReferenceHandlerForBus
NULL, // HalReferenceBusHandler
NULL // HalDereferenceBusHandler

View file

@ -1,4 +1,4 @@
/* $Id: xhaldrv.c,v 1.2 2000/08/11 12:41:06 ekohl Exp $
/* $Id: xhaldrv.c,v 1.3 2000/08/21 00:14:04 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -9,16 +9,151 @@
* Created 19/06/2000
*/
/*
* TODO:
* - Check/fix 'StartingOffset' and 'PartitionLength' in
* xHalIoReadPartitionTable().
* - Fix 'ReturnRecognizesPartitions' in xHalIoReadPartitionTable().
* - Read disk signature in xHalIoReadPartitionTable().
* - Build correct system path from nt device name or arc name.
* For example: \Device\Harddisk0\Partition1\reactos ==> C:\reactos
* Or: multi(0)disk(0)rdisk(0)partition(1)\reactos ==> C:\reactos
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/xhal.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* LOCAL MACROS and TYPES ***************************************************/
#define AUTO_DRIVE ((ULONG)-1)
#define PARTITION_MAGIC 0xaa55
#define PART_MAGIC_OFFSET 0x01fe
#define PARTITION_OFFSET 0x01be
#define PARTITION_TBL_SIZE 4
/*
#define PTCHSToLBA(c, h, s, scnt, hcnt) ((s) & 0x3f) + \
(scnt) * ( (h) + (hcnt) * ((c) | (((s) & 0xc0) << 2)))
#define PTLBAToCHS(lba, c, h, s, scnt, hcnt) ( \
(s) = (lba) % (scnt) + 1, \
(lba) /= (scnt), \
(h) = (lba) % (hcnt), \
(lba) /= (heads), \
(c) = (lba) & 0xff, \
(s) |= ((lba) >> 2) & 0xc0)
*/
#define IsUsablePartition(P) \
((P) != PTEmpty && \
(P) != PTDosExtended && \
(P) != PTWin95ExtendedLBA)
typedef struct _PARTITION
{
unsigned char BootFlags;
unsigned char StartingHead;
unsigned char StartingSector;
unsigned char StartingCylinder;
unsigned char PartitionType;
unsigned char EndingHead;
unsigned char EndingSector;
unsigned char EndingCylinder;
unsigned int StartingBlock;
unsigned int SectorCount;
} PARTITION, *PPARTITION;
typedef struct _PARTITION_TABLE
{
PARTITION Partition[PARTITION_TBL_SIZE];
unsigned short Magic;
} PARTITION_TABLE, *PPARTITION_TABLE;
/* FUNCTIONS *****************************************************************/
static NTSTATUS
xHalpQueryDriveLayout (
IN PUNICODE_STRING DeviceName,
OUT PDRIVE_LAYOUT_INFORMATION *LayoutInfo
)
{
IO_STATUS_BLOCK StatusBlock;
DISK_GEOMETRY DiskGeometry;
PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
DPRINT ("xHalpQueryDriveLayout %wZ %p\n",
DeviceName,
LayoutInfo);
/*
* Get the drives sector size
*/
Status = IoGetDeviceObjectPointer (DeviceName,
FILE_READ_DATA,
&FileObject,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
DPRINT ("Status %x\n",Status);
return Status;
}
KeInitializeEvent (&Event,
NotificationEvent,
FALSE);
Irp = IoBuildDeviceIoControlRequest (IOCTL_DISK_GET_DRIVE_GEOMETRY,
DeviceObject,
NULL,
0,
&DiskGeometry,
sizeof(DISK_GEOMETRY),
FALSE,
&Event,
&StatusBlock);
if (Irp == NULL)
{
ObDereferenceObject (FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = StatusBlock.Status;
}
if (!NT_SUCCESS(Status))
{
ObDereferenceObject (FileObject);
return Status;
}
DPRINT("DiskGeometry.BytesPerSector: %d\n",
DiskGeometry.BytesPerSector);
/* read the partition table */
Status = IoReadPartitionTable (DeviceObject,
DiskGeometry.BytesPerSector,
FALSE,
LayoutInfo);
ObDereferenceObject (FileObject);
return Status;
}
VOID
FASTCALL
xHalExamineMBR (
@ -99,6 +234,71 @@ xHalExamineMBR (
*Buffer = (PVOID)LocalBuffer;
}
static VOID
HalpAssignDrive (
PUNICODE_STRING PartitionName,
PULONG DriveMap,
ULONG DriveNumber
)
{
WCHAR DriveNameBuffer[8];
UNICODE_STRING DriveName;
ULONG i;
DPRINT("HalpAssignDrive()\n");
if ((DriveNumber != AUTO_DRIVE) && (DriveNumber < 24))
{
/* force assignment */
if ((*DriveMap & (1 << DriveNumber)) != 0)
{
DbgPrint("Drive letter already used!\n");
return;
}
}
else
{
/* automatic assignment */
DriveNumber = AUTO_DRIVE;
for (i = 2; i < 24; i++)
{
if ((*DriveMap & (1 << i)) == 0)
{
DriveNumber = i;
break;
}
}
if (DriveNumber == AUTO_DRIVE)
{
DbgPrint("No drive letter available!\n");
return;
}
}
DPRINT("DriveNumber %d\n", DriveNumber);
/* set bit in drive map */
*DriveMap = *DriveMap | (1 << DriveNumber);
/* build drive name */
swprintf (DriveNameBuffer,
L"\\??\\%C:",
'A' + DriveNumber);
RtlInitUnicodeString (&DriveName,
DriveNameBuffer);
DPRINT1(" %wZ ==> %wZ\n",
&DriveName,
PartitionName);
/* create symbolic link */
IoCreateSymbolicLink (&DriveName,
PartitionName);
}
VOID
FASTCALL
xHalIoAssignDriveLetters (
@ -108,6 +308,7 @@ xHalIoAssignDriveLetters (
OUT PSTRING NtSystemPathString
)
{
PDRIVE_LAYOUT_INFORMATION LayoutInfo; // ebp-4
PCONFIGURATION_INFORMATION ConfigInfo;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK StatusBlock;
@ -118,6 +319,8 @@ xHalIoAssignDriveLetters (
PWSTR Buffer2;
ULONG i;
NTSTATUS Status;
ULONG DriveMap = 0;
ULONG j;
DPRINT("xHalIoAssignDriveLetters()\n");
@ -128,9 +331,8 @@ xHalIoAssignDriveLetters (
Buffer2 = (PWSTR)ExAllocatePool (PagedPool,
32 * sizeof(WCHAR));
// Create PhysicalDrive links
/* Create PhysicalDrive links */
DPRINT("Physical disk drives: %d\n", ConfigInfo->DiskCount);
for (i = 0; i < ConfigInfo->DiskCount; i++)
{
swprintf (Buffer1,
@ -150,37 +352,188 @@ xHalIoAssignDriveLetters (
&ObjectAttributes,
&StatusBlock,
1,
0x20);
FILE_SYNCHRONOUS_IO_NONALERT);
if (NT_SUCCESS(Status))
{
NtClose (FileHandle);
swprintf (Buffer2,
L"\\??\\PhysicalDrive%d",
i);
RtlInitUnicodeString (&UnicodeString2,
Buffer2);
DPRINT ("Creating link: %S ==> %S\n",
DPRINT1("Creating link: %S ==> %S\n",
Buffer2,
Buffer1);
IoCreateSymbolicLink (&UnicodeString2,
&UnicodeString1);
NtClose (FileHandle);
}
}
// Assign pre-assigned (registry) partitions
/* Assign pre-assigned (registry) partitions */
// Assign bootable partitions
/* Assign bootable partitions */
DPRINT("Assigning bootable partitions:\n");
for (i = 0; i < ConfigInfo->DiskCount; i++)
{
swprintf (Buffer1,
L"\\Device\\Harddisk%d\\Partition0",
i);
RtlInitUnicodeString (&UnicodeString1,
Buffer1);
// Assign remaining primary partitions
Status = xHalpQueryDriveLayout (&UnicodeString1,
&LayoutInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
Status);
continue;
}
// Assign extended (logical) partitions
DPRINT("Logical partitions: %d\n",
LayoutInfo->PartitionCount);
// Assign floppy drives
/* search for bootable partitions */
for (j = 0; j < LayoutInfo->PartitionCount; j++)
{
DPRINT(" %d: nr:%x boot:%x type:%x startblock:%lu count:%lu\n",
j,
LayoutInfo->PartitionEntry[j].PartitionNumber,
LayoutInfo->PartitionEntry[j].BootIndicator,
LayoutInfo->PartitionEntry[j].PartitionType,
LayoutInfo->PartitionEntry[j].StartingOffset.u.LowPart,
LayoutInfo->PartitionEntry[j].PartitionLength.u.LowPart);
if (LayoutInfo->PartitionEntry[j].BootIndicator)
{
swprintf (Buffer2,
L"\\Device\\Harddisk%d\\Partition%d",
i,
LayoutInfo->PartitionEntry[j].PartitionNumber);
RtlInitUnicodeString (&UnicodeString2,
Buffer2);
DPRINT(" %wZ\n", &UnicodeString2);
/* assign it */
HalpAssignDrive (&UnicodeString2,
&DriveMap,
AUTO_DRIVE);
}
}
ExFreePool (LayoutInfo);
}
/* Assign remaining primary partitions */
DPRINT("Assigning primary partitions:\n");
for (i = 0; i < ConfigInfo->DiskCount; i++)
{
swprintf (Buffer1,
L"\\Device\\Harddisk%d\\Partition0",
i);
RtlInitUnicodeString (&UnicodeString1,
Buffer1);
Status = xHalpQueryDriveLayout (&UnicodeString1,
&LayoutInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
Status);
continue;
}
DPRINT("Logical partitions: %d\n",
LayoutInfo->PartitionCount);
/* search for primary (non-bootable) partitions */
for (j = 0; j < PARTITION_TBL_SIZE; j++)
{
DPRINT(" %d: nr:%x boot:%x type:%x startblock:%lu count:%lu\n",
j,
LayoutInfo->PartitionEntry[j].PartitionNumber,
LayoutInfo->PartitionEntry[j].BootIndicator,
LayoutInfo->PartitionEntry[j].PartitionType,
LayoutInfo->PartitionEntry[j].StartingOffset.u.LowPart,
LayoutInfo->PartitionEntry[j].PartitionLength.u.LowPart);
if ((LayoutInfo->PartitionEntry[j].BootIndicator == FALSE) &&
IsUsablePartition(LayoutInfo->PartitionEntry[j].PartitionType))
{
swprintf (Buffer2,
L"\\Device\\Harddisk%d\\Partition%d",
i,
LayoutInfo->PartitionEntry[j].PartitionNumber);
RtlInitUnicodeString (&UnicodeString2,
Buffer2);
/* assign it */
DPRINT(" %wZ\n", &UnicodeString2);
HalpAssignDrive (&UnicodeString2, &DriveMap, AUTO_DRIVE);
}
}
ExFreePool (LayoutInfo);
}
/* Assign extended (logical) partitions */
DPRINT("Assigning extended (logical) partitions:\n");
for (i = 0; i < ConfigInfo->DiskCount; i++)
{
swprintf (Buffer1,
L"\\Device\\Harddisk%d\\Partition0",
i);
RtlInitUnicodeString (&UnicodeString1,
Buffer1);
Status = xHalpQueryDriveLayout (&UnicodeString1,
&LayoutInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("xHalpQueryDriveLayout() failed (Status = 0x%lx)\n",
Status);
continue;
}
DPRINT("Logical partitions: %d\n",
LayoutInfo->PartitionCount);
/* search for extended partitions */
for (j = PARTITION_TBL_SIZE; j < LayoutInfo->PartitionCount; j++)
{
DPRINT(" %d: nr:%x boot:%x type:%x startblock:%lu count:%lu\n",
j,
LayoutInfo->PartitionEntry[j].PartitionNumber,
LayoutInfo->PartitionEntry[j].BootIndicator,
LayoutInfo->PartitionEntry[j].PartitionType,
LayoutInfo->PartitionEntry[j].StartingOffset.u.LowPart,
LayoutInfo->PartitionEntry[j].PartitionLength.u.LowPart);
if (IsUsablePartition(LayoutInfo->PartitionEntry[j].PartitionType) &&
(LayoutInfo->PartitionEntry[j].PartitionNumber != 0))
{
swprintf (Buffer2,
L"\\Device\\Harddisk%d\\Partition%d",
i,
LayoutInfo->PartitionEntry[j].PartitionNumber);
RtlInitUnicodeString (&UnicodeString2,
Buffer2);
/* assign it */
DPRINT(" %wZ\n", &UnicodeString2);
HalpAssignDrive (&UnicodeString2, &DriveMap, AUTO_DRIVE);
}
}
ExFreePool (LayoutInfo);
}
/* Assign floppy drives */
DPRINT("Floppy drives: %d\n", ConfigInfo->FloppyCount);
for (i = 0; i < ConfigInfo->FloppyCount; i++)
{
swprintf (Buffer1,
@ -189,44 +542,206 @@ xHalIoAssignDriveLetters (
RtlInitUnicodeString (&UnicodeString1,
Buffer1);
InitializeObjectAttributes (&ObjectAttributes,
&UnicodeString1,
0,
NULL,
NULL);
if (i < 2)
{
/* drives A: and B: */
swprintf (Buffer2,
L"\\??\\%C:",
L'A' + i);
/* assign drive letters A: or B: or first free drive letter */
DPRINT(" %wZ\n", &UnicodeString1);
HalpAssignDrive (&UnicodeString1,
&DriveMap,
(i < 2) ? i : AUTO_DRIVE);
}
else
{
/* FIXME: append other floppy drives */
break;
}
RtlInitUnicodeString (&UnicodeString2,
Buffer2);
DPRINT ("Creating link: %S ==> %S\n",
Buffer2,
/* Assign cdrom drives */
DPRINT("CD-Rom drives: %d\n", ConfigInfo->CDRomCount);
for (i = 0; i < ConfigInfo->CDRomCount; i++)
{
swprintf (Buffer1,
L"\\Device\\Cdrom%d",
i);
RtlInitUnicodeString (&UnicodeString1,
Buffer1);
IoCreateSymbolicLink (&UnicodeString2,
&UnicodeString1);
/* assign first free drive letter */
DPRINT(" %wZ\n", &UnicodeString1);
HalpAssignDrive (&UnicodeString1,
&DriveMap,
AUTO_DRIVE);
}
// Assign cdrom drives
DPRINT("CD-Rom drives: %d\n", ConfigInfo->CDRomCount);
// Any more ??
/* Anything else ?? */
ExFreePool (Buffer2);
ExFreePool (Buffer1);
}
NTSTATUS
FASTCALL
xHalIoReadPartitionTable (
PDEVICE_OBJECT DeviceObject,
ULONG SectorSize,
BOOLEAN ReturnRecognizedPartitions,
PDRIVE_LAYOUT_INFORMATION * PartitionBuffer
)
{
KEVENT Event;
IO_STATUS_BLOCK StatusBlock;
LARGE_INTEGER Offset;
PUCHAR SectorBuffer;
PIRP Irp;
NTSTATUS Status;
PPARTITION_TABLE PartitionTable;
PDRIVE_LAYOUT_INFORMATION LayoutBuffer;
ULONG i;
ULONG Count = 0;
ULONG Number = 1;
BOOLEAN ExtendedFound = FALSE;
DPRINT("xHalIoReadPartitionTable(%p %lu %x %p)\n",
DeviceObject,
SectorSize,
ReturnRecognizedPartitions,
PartitionBuffer);
*PartitionBuffer = NULL;
SectorBuffer = (PUCHAR)ExAllocatePool (PagedPool,
SectorSize);
if (SectorBuffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
LayoutBuffer = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePool (PagedPool,
0x1000);
if (LayoutBuffer == NULL)
{
ExFreePool (SectorBuffer);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory (LayoutBuffer, 0x1000);
Offset.QuadPart = 0;
do
{
KeInitializeEvent (&Event,
NotificationEvent,
FALSE);
Irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
DeviceObject,
SectorBuffer,
SectorSize,
&Offset,
&Event,
&StatusBlock);
Status = IoCallDriver (DeviceObject,
Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject (&Event,
Executive,
KernelMode,
FALSE,
NULL);
Status = StatusBlock.Status;
}
if (!NT_SUCCESS(Status))
{
DPRINT("xHalIoReadPartitonTable failed (Status = 0x%08lx)\n",
Status);
ExFreePool (SectorBuffer);
ExFreePool (LayoutBuffer);
return Status;
}
PartitionTable = (PPARTITION_TABLE)(SectorBuffer+PARTITION_OFFSET);
/* check the boot sector id */
DPRINT("Magic %x\n", PartitionTable->Magic);
if (PartitionTable->Magic != PARTITION_MAGIC)
{
DPRINT("Invalid partition table magic\n");
ExFreePool (SectorBuffer);
ExFreePool (LayoutBuffer);
return STATUS_UNSUCCESSFUL;
}
#ifndef NDEBUG
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->Partition[i].BootFlags,
PartitionTable->Partition[i].PartitionType,
PartitionTable->Partition[i].StartingHead,
PartitionTable->Partition[i].StartingSector,
PartitionTable->Partition[i].StartingCylinder,
PartitionTable->Partition[i].EndingHead,
PartitionTable->Partition[i].EndingSector,
PartitionTable->Partition[i].EndingCylinder,
PartitionTable->Partition[i].StartingBlock,
PartitionTable->Partition[i].SectorCount);
}
#endif
/* FIXME: Set the correct value */
if (ExtendedFound == FALSE);
{
LayoutBuffer->Signature = 0xdeadbeef;
}
ExtendedFound = FALSE;
for (i = 0; i < PARTITION_TBL_SIZE; i++)
{
/* handle normal partition */
DPRINT("Partition %u: Normal Partition\n", i);
Count = LayoutBuffer->PartitionCount;
DPRINT("Logical Partition %u\n", Count);
LayoutBuffer->PartitionEntry[Count].StartingOffset.QuadPart =
PartitionTable->Partition[i].StartingBlock * SectorSize;
LayoutBuffer->PartitionEntry[Count].PartitionLength.QuadPart =
PartitionTable->Partition[i].SectorCount * SectorSize;
LayoutBuffer->PartitionEntry[Count].HiddenSectors = 0;
if (IsUsablePartition(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;
if (IsExtendedPartition(PartitionTable->Partition[i].PartitionType))
{
Offset.QuadPart +=
(PartitionTable->Partition[i].StartingBlock * SectorSize);
ExtendedFound = TRUE;
}
LayoutBuffer->PartitionCount++;
}
}
while (ExtendedFound == TRUE);
*PartitionBuffer = LayoutBuffer;
ExFreePool (SectorBuffer);
return STATUS_SUCCESS;
}
/* EOF */