mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Implemented IoReadPartitionTable().
Implemented proper drive letter assignment. svn path=/trunk/; revision=1310
This commit is contained in:
parent
8434fc42db
commit
6f1d7ad00c
7 changed files with 620 additions and 100 deletions
|
@ -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);
|
||||
|
@ -462,17 +461,16 @@ IDEResetController(IN WORD CommandPort,
|
|||
//
|
||||
|
||||
BOOLEAN
|
||||
IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
|
||||
IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PCONTROLLER_OBJECT ControllerObject,
|
||||
IN PIDE_CONTROLLER_EXTENSION ControllerExtension,
|
||||
IN int DriveIdx,
|
||||
IN int HarddiskIdx)
|
||||
IN int HarddiskIdx)
|
||||
{
|
||||
BOOLEAN CreatedDevices;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,4 +19,14 @@ xHalIoAssignDriveLetters (
|
|||
OUT PSTRING NtSystemPathString
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
FASTCALL
|
||||
xHalIoReadPartitionTable (
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
ULONG SectorSize,
|
||||
BOOLEAN ReturnRecognizedPartitions,
|
||||
PDRIVE_LAYOUT_INFORMATION * PartitionBuffer
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,8 +319,10 @@ xHalIoAssignDriveLetters (
|
|||
PWSTR Buffer2;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
ULONG DriveMap = 0;
|
||||
ULONG j;
|
||||
|
||||
DPRINT ("xHalIoAssignDriveLetters()\n");
|
||||
DPRINT("xHalIoAssignDriveLetters()\n");
|
||||
|
||||
ConfigInfo = IoGetConfigurationInformation ();
|
||||
|
||||
|
@ -128,9 +331,8 @@ xHalIoAssignDriveLetters (
|
|||
Buffer2 = (PWSTR)ExAllocatePool (PagedPool,
|
||||
32 * sizeof(WCHAR));
|
||||
|
||||
// Create PhysicalDrive links
|
||||
DPRINT ("Physical disk drives: %d\n", ConfigInfo->DiskCount);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: append other floppy drives */
|
||||
break;
|
||||
}
|
||||
RtlInitUnicodeString (&UnicodeString2,
|
||||
Buffer2);
|
||||
|
||||
DPRINT ("Creating link: %S ==> %S\n",
|
||||
Buffer2,
|
||||
Buffer1);
|
||||
|
||||
IoCreateSymbolicLink (&UnicodeString2,
|
||||
&UnicodeString1);
|
||||
/* assign drive letters A: or B: or first free drive letter */
|
||||
DPRINT(" %wZ\n", &UnicodeString1);
|
||||
HalpAssignDrive (&UnicodeString1,
|
||||
&DriveMap,
|
||||
(i < 2) ? i : AUTO_DRIVE);
|
||||
}
|
||||
|
||||
|
||||
// Assign cdrom drives
|
||||
/* 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);
|
||||
|
||||
// Any more ??
|
||||
/* assign first free drive letter */
|
||||
DPRINT(" %wZ\n", &UnicodeString1);
|
||||
HalpAssignDrive (&UnicodeString1,
|
||||
&DriveMap,
|
||||
AUTO_DRIVE);
|
||||
}
|
||||
|
||||
/* Anything else ?? */
|
||||
|
||||
|
||||
ExFreePool (Buffer2);
|
||||
ExFreePool (Buffer1);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue