diff --git a/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c b/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c index 4b080ec4cf0..f0f7c3a78f3 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c @@ -99,6 +99,123 @@ GetHarddiskConfigurationData(ULONG DriveNumber, ULONG* pSize) return PartialResourceList; } +typedef struct tagDISKCONTEXT +{ + ULONG DriveNumber; + ULONG SectorSize; + ULONGLONG SectorOffset; + ULONGLONG SectorCount; + ULONGLONG SectorNumber; +} DISKCONTEXT; + +static LONG DiskClose(ULONG FileId) +{ + DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); + + MmHeapFree(Context); + return ESUCCESS; +} + +static LONG DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information) +{ + DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); + + RtlZeroMemory(Information, sizeof(FILEINFORMATION)); + Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize; + Information->CurrentAddress.LowPart = (Context->SectorOffset + Context->SectorNumber) * Context->SectorSize; + + return ESUCCESS; +} + +static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) +{ + DISKCONTEXT* Context; + ULONG DriveNumber, DrivePartition, SectorSize; + ULONGLONG SectorOffset = 0; + ULONGLONG SectorCount = 0; + PARTITION_TABLE_ENTRY PartitionTableEntry; + CHAR FileName[1]; + + if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition)) + return EINVAL; + SectorSize = (DrivePartition == 0xff ? 2048 : 512); + if (DrivePartition != 0xff && DrivePartition != 0) + { + if (!MachDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry)) + return EINVAL; + SectorOffset = PartitionTableEntry.SectorCountBeforePartition; + SectorCount = PartitionTableEntry.PartitionSectorCount; + } + else + { + SectorCount = 0; /* FIXME */ + } + + Context = MmHeapAlloc(sizeof(DISKCONTEXT)); + if (!Context) + return ENOMEM; + Context->DriveNumber = DriveNumber; + Context->SectorSize = SectorSize; + Context->SectorOffset = SectorOffset; + Context->SectorCount = SectorCount; + Context->SectorNumber = 0; + FsSetDeviceSpecific(*FileId, Context); + + return ESUCCESS; +} + +static LONG DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) +{ + DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); + UCHAR* Ptr = (UCHAR*)Buffer; + ULONG i, Length; + BOOLEAN ret; + + *Count = 0; + i = 0; + while (N > 0) + { + Length = N; + if (Length > Context->SectorSize) + Length = Context->SectorSize; + ret = MachDiskReadLogicalSectors( + Context->DriveNumber, + Context->SectorNumber + Context->SectorOffset + i, + 1, + (PVOID)DISKREADBUFFER); + if (!ret) + return EIO; + RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length); + Ptr += Length; + *Count += Length; + N -= Length; + i++; + } + + return ESUCCESS; +} + +static LONG DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) +{ + DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); + + if (SeekMode != SeekAbsolute) + return EINVAL; + if (Position->LowPart & (Context->SectorSize - 1)) + return EINVAL; + + /* FIXME: take HighPart into account */ + Context->SectorNumber = Position->LowPart / Context->SectorSize; + return ESUCCESS; +} + +static const DEVVTBL DiskVtbl = { + DiskClose, + DiskGetFileInformation, + DiskOpen, + DiskRead, + DiskSeek, +}; static VOID GetHarddiskIdentifier(PCHAR Identifier, @@ -110,6 +227,7 @@ GetHarddiskIdentifier(PCHAR Identifier, ULONG Checksum; ULONG Signature; CHAR ArcName[256]; + PARTITION_TABLE_ENTRY PartitionTableEntry; /* Read the MBR */ if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER)) @@ -142,6 +260,23 @@ GetHarddiskIdentifier(PCHAR Identifier, reactos_arc_strings[reactos_disk_count]; reactos_disk_count++; + sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)partition(0)", DriveNumber - 0x80); + FsRegisterDevice(ArcName, &DiskVtbl); + + /* Add partitions */ + i = 1; + DiskReportError(FALSE); + while (MachDiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry)) + { + if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED) + { + sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)partition(%lu)", DriveNumber - 0x80, i); + FsRegisterDevice(ArcName, &DiskVtbl); + } + i++; + } + DiskReportError(TRUE); + /* Convert checksum and signature to identifier string */ Identifier[0] = Hex[(Checksum >> 28) & 0x0F]; Identifier[1] = Hex[(Checksum >> 24) & 0x0F]; diff --git a/reactos/hal/halx86/xbox/part_xbox.c b/reactos/hal/halx86/xbox/part_xbox.c index 1ae2591502e..bab0a530bde 100644 --- a/reactos/hal/halx86/xbox/part_xbox.c +++ b/reactos/hal/halx86/xbox/part_xbox.c @@ -199,10 +199,11 @@ HalpXboxIoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, ReturnRecognizedPartitions, PartitionBuffer); } - *PartitionBuffer = (PDRIVE_LAYOUT_INFORMATION) - ExAllocatePool(PagedPool, - sizeof(DRIVE_LAYOUT_INFORMATION) + - XBOX_PARTITION_COUNT * sizeof(PARTITION_INFORMATION)); + *PartitionBuffer = (PDRIVE_LAYOUT_INFORMATION)ExAllocatePoolWithTag( + PagedPool, + sizeof(DRIVE_LAYOUT_INFORMATION) + + XBOX_PARTITION_COUNT * sizeof(PARTITION_INFORMATION), + 'SYSF'); if (NULL == *PartitionBuffer) { return STATUS_NO_MEMORY;