|
11 | 11 | #include <freeldr.h> |
12 | 12 | #include <ntoskrnl.h> |
13 | 13 |
|
| 14 | +#ifndef UNIMPLEMENTED |
| 15 | +#define UNIMPLEMENTED ASSERT(FALSE) |
| 16 | +#endif |
| 17 | + |
14 | 18 | /* FUNCTIONS *****************************************************************/ |
15 | 19 |
|
16 | 20 | VOID |
@@ -52,17 +56,154 @@ IoSetPartitionInformation( |
52 | 56 | return STATUS_NOT_IMPLEMENTED; |
53 | 57 | } |
54 | 58 |
|
55 | | -/* |
56 | | - * NTSTATUS |
57 | | - * FASTCALL |
58 | | - * IoReadPartitionTable( |
59 | | - * IN PDEVICE_OBJECT DeviceObject, |
60 | | - * IN ULONG SectorSize, |
61 | | - * IN BOOLEAN ReturnRecognizedPartitions, |
62 | | - * OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer); |
63 | | - * |
64 | | - * See boot/freeldr/freeldr/disk/partition.c |
65 | | - */ |
| 59 | +#ifndef _M_AMD64 |
| 60 | +NTSTATUS |
| 61 | +NTAPI |
| 62 | +IopReadBootRecord( |
| 63 | + IN PDEVICE_OBJECT DeviceObject, |
| 64 | + IN ULONGLONG LogicalSectorNumber, |
| 65 | + IN ULONG SectorSize, |
| 66 | + OUT PMASTER_BOOT_RECORD BootRecord) |
| 67 | +{ |
| 68 | + ULONG_PTR FileId = (ULONG_PTR)DeviceObject; |
| 69 | + LARGE_INTEGER Position; |
| 70 | + ULONG BytesRead; |
| 71 | + ARC_STATUS Status; |
| 72 | + |
| 73 | + Position.QuadPart = LogicalSectorNumber * SectorSize; |
| 74 | + Status = ArcSeek(FileId, &Position, SeekAbsolute); |
| 75 | + if (Status != ESUCCESS) |
| 76 | + return STATUS_IO_DEVICE_ERROR; |
| 77 | + |
| 78 | + Status = ArcRead(FileId, BootRecord, SectorSize, &BytesRead); |
| 79 | + if (Status != ESUCCESS || BytesRead != SectorSize) |
| 80 | + return STATUS_IO_DEVICE_ERROR; |
| 81 | + |
| 82 | + return STATUS_SUCCESS; |
| 83 | +} |
| 84 | + |
| 85 | +BOOLEAN |
| 86 | +NTAPI |
| 87 | +IopCopyPartitionRecord( |
| 88 | + IN BOOLEAN ReturnRecognizedPartitions, |
| 89 | + IN ULONG SectorSize, |
| 90 | + IN PPARTITION_TABLE_ENTRY PartitionTableEntry, |
| 91 | + OUT PARTITION_INFORMATION *PartitionEntry) |
| 92 | +{ |
| 93 | + BOOLEAN IsRecognized; |
| 94 | + |
| 95 | + IsRecognized = TRUE; /* FIXME */ |
| 96 | + if (!IsRecognized && ReturnRecognizedPartitions) |
| 97 | + return FALSE; |
| 98 | + |
| 99 | + PartitionEntry->StartingOffset.QuadPart = (ULONGLONG)PartitionTableEntry->SectorCountBeforePartition * SectorSize; |
| 100 | + PartitionEntry->PartitionLength.QuadPart = (ULONGLONG)PartitionTableEntry->PartitionSectorCount * SectorSize; |
| 101 | + PartitionEntry->HiddenSectors = 0; |
| 102 | + PartitionEntry->PartitionNumber = 0; /* Will be filled later */ |
| 103 | + PartitionEntry->PartitionType = PartitionTableEntry->SystemIndicator; |
| 104 | + PartitionEntry->BootIndicator = (PartitionTableEntry->BootIndicator & 0x80) ? TRUE : FALSE; |
| 105 | + PartitionEntry->RecognizedPartition = IsRecognized; |
| 106 | + PartitionEntry->RewritePartition = FALSE; |
| 107 | + |
| 108 | + return TRUE; |
| 109 | +} |
| 110 | + |
| 111 | +NTSTATUS |
| 112 | +FASTCALL |
| 113 | +IoReadPartitionTable( |
| 114 | + IN PDEVICE_OBJECT DeviceObject, |
| 115 | + IN ULONG SectorSize, |
| 116 | + IN BOOLEAN ReturnRecognizedPartitions, |
| 117 | + OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer) |
| 118 | +{ |
| 119 | + NTSTATUS Status; |
| 120 | + PMASTER_BOOT_RECORD MasterBootRecord; |
| 121 | + PDRIVE_LAYOUT_INFORMATION Partitions; |
| 122 | + ULONG NbPartitions, i, Size; |
| 123 | + |
| 124 | + *PartitionBuffer = NULL; |
| 125 | + |
| 126 | + if (SectorSize < sizeof(MASTER_BOOT_RECORD)) |
| 127 | + return STATUS_NOT_SUPPORTED; |
| 128 | + |
| 129 | + MasterBootRecord = ExAllocatePool(NonPagedPool, SectorSize); |
| 130 | + if (!MasterBootRecord) |
| 131 | + return STATUS_NO_MEMORY; |
| 132 | + |
| 133 | + /* Read disk MBR */ |
| 134 | + Status = IopReadBootRecord(DeviceObject, 0, SectorSize, MasterBootRecord); |
| 135 | + if (!NT_SUCCESS(Status)) |
| 136 | + { |
| 137 | + ExFreePool(MasterBootRecord); |
| 138 | + return Status; |
| 139 | + } |
| 140 | + |
| 141 | + /* Check validity of boot record */ |
| 142 | + if (MasterBootRecord->MasterBootRecordMagic != 0xaa55) |
| 143 | + { |
| 144 | + ExFreePool(MasterBootRecord); |
| 145 | + return STATUS_NOT_SUPPORTED; |
| 146 | + } |
| 147 | + |
| 148 | + /* Count number of partitions */ |
| 149 | + NbPartitions = 0; |
| 150 | + for (i = 0; i < 4; i++) |
| 151 | + { |
| 152 | + NbPartitions++; |
| 153 | + |
| 154 | + if (MasterBootRecord->PartitionTable[i].SystemIndicator == PARTITION_EXTENDED || |
| 155 | + MasterBootRecord->PartitionTable[i].SystemIndicator == PARTITION_XINT13_EXTENDED) |
| 156 | + { |
| 157 | + /* FIXME: unhandled case; count number of partitions */ |
| 158 | + UNIMPLEMENTED; |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + if (NbPartitions == 0) |
| 163 | + { |
| 164 | + ExFreePool(MasterBootRecord); |
| 165 | + return STATUS_NOT_SUPPORTED; |
| 166 | + } |
| 167 | + |
| 168 | + /* Allocation space to store partitions */ |
| 169 | + Size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry) + |
| 170 | + NbPartitions * sizeof(PARTITION_INFORMATION); |
| 171 | + Partitions = ExAllocatePool(NonPagedPool, Size); |
| 172 | + if (!Partitions) |
| 173 | + { |
| 174 | + ExFreePool(MasterBootRecord); |
| 175 | + return STATUS_NO_MEMORY; |
| 176 | + } |
| 177 | + |
| 178 | + /* Count number of partitions */ |
| 179 | + NbPartitions = 0; |
| 180 | + for (i = 0; i < 4; i++) |
| 181 | + { |
| 182 | + if (IopCopyPartitionRecord(ReturnRecognizedPartitions, |
| 183 | + SectorSize, |
| 184 | + &MasterBootRecord->PartitionTable[i], |
| 185 | + &Partitions->PartitionEntry[NbPartitions])) |
| 186 | + { |
| 187 | + Partitions->PartitionEntry[NbPartitions].PartitionNumber = NbPartitions + 1; |
| 188 | + NbPartitions++; |
| 189 | + } |
| 190 | + |
| 191 | + if (MasterBootRecord->PartitionTable[i].SystemIndicator == PARTITION_EXTENDED || |
| 192 | + MasterBootRecord->PartitionTable[i].SystemIndicator == PARTITION_XINT13_EXTENDED) |
| 193 | + { |
| 194 | + /* FIXME: unhandled case; copy partitions */ |
| 195 | + UNIMPLEMENTED; |
| 196 | + } |
| 197 | + } |
| 198 | + |
| 199 | + Partitions->PartitionCount = NbPartitions; |
| 200 | + Partitions->Signature = MasterBootRecord->Signature; |
| 201 | + ExFreePool(MasterBootRecord); |
| 202 | + |
| 203 | + *PartitionBuffer = Partitions; |
| 204 | + return STATUS_SUCCESS; |
| 205 | +} |
| 206 | +#endif // _M_AMD64 |
66 | 207 |
|
67 | 208 | NTSTATUS |
68 | 209 | FASTCALL |
|
0 commit comments