ReactOS 0.4.16-dev-297-gc569aee
partition.c File Reference
#include <freeldr.h>
#include <debug.h>
Include dependency graph for partition.c:

Go to the source code of this file.

Macros

#define MaxDriveNumber   0xFF
 
#define XBOX_SIGNATURE_SECTOR   3
 
#define XBOX_SIGNATURE   ('B' | ('R' << 8) | ('F' << 16) | ('R' << 24))
 
#define FATX_DATA_PARTITION   1
 

Functions

 DBG_DEFAULT_CHANNEL (DISK)
 
static BOOLEAN DiskReadBootRecord (IN UCHAR DriveNumber, IN ULONGLONG LogicalSectorNumber, OUT PMASTER_BOOT_RECORD BootRecord)
 
static BOOLEAN DiskGetFirstPartitionEntry (IN PMASTER_BOOT_RECORD MasterBootRecord, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
 
static BOOLEAN DiskGetFirstExtendedPartitionEntry (IN PMASTER_BOOT_RECORD MasterBootRecord, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
 
static BOOLEAN DiskGetActivePartitionEntry (IN UCHAR DriveNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry, OUT PULONG ActivePartition)
 
static BOOLEAN DiskGetMbrPartitionEntry (IN UCHAR DriveNumber, IN ULONG PartitionNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
 
static BOOLEAN DiskGetBrfrPartitionEntry (IN UCHAR DriveNumber, IN ULONG PartitionNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
 
VOID DiskDetectPartitionType (IN UCHAR DriveNumber)
 
BOOLEAN DiskGetBootPartitionEntry (IN UCHAR DriveNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry, OUT PULONG BootPartition)
 
BOOLEAN DiskGetPartitionEntry (IN UCHAR DriveNumber, IN ULONG PartitionNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
 

Variables

static PARTITION_STYLE DiskPartitionType [MaxDriveNumber+1]
 
struct {
   ULONG   SectorCountBeforePartition
 
   ULONG   PartitionSectorCount
 
   UCHAR   SystemIndicator
 
XboxPartitions []
 

Macro Definition Documentation

◆ FATX_DATA_PARTITION

#define FATX_DATA_PARTITION   1

Definition at line 34 of file partition.c.

◆ MaxDriveNumber

#define MaxDriveNumber   0xFF

Definition at line 26 of file partition.c.

◆ XBOX_SIGNATURE

#define XBOX_SIGNATURE   ('B' | ('R' << 8) | ('F' << 16) | ('R' << 24))

Definition at line 31 of file partition.c.

◆ XBOX_SIGNATURE_SECTOR

#define XBOX_SIGNATURE_SECTOR   3

Definition at line 30 of file partition.c.

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( DISK  )

◆ DiskDetectPartitionType()

VOID DiskDetectPartitionType ( IN UCHAR  DriveNumber)

Definition at line 314 of file partition.c.

316{
317 MASTER_BOOT_RECORD MasterBootRecord;
318 ULONG Index;
319 ULONG PartitionCount = 0;
320 PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
321 BOOLEAN GPTProtect = FALSE;
322 PARTITION_TABLE_ENTRY PartitionTableEntry;
323
324 /* Probe for Master Boot Record */
325 if (DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
326 {
328
329 /* Check for GUID Partition Table */
330 for (Index = 0; Index < 4; Index++)
331 {
332 ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
333
334 if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED)
335 {
336 PartitionCount++;
337
338 if (Index == 0 && ThisPartitionTableEntry->SystemIndicator == PARTITION_GPT)
339 {
340 GPTProtect = TRUE;
341 }
342 }
343 }
344
345 if (PartitionCount == 1 && GPTProtect)
346 {
348 }
349 TRACE("Drive 0x%X partition type %s\n", DriveNumber, DiskPartitionType[DriveNumber] == PARTITION_STYLE_MBR ? "MBR" : "GPT");
350 return;
351 }
352
353 /* Probe for Xbox-BRFR partitioning */
354 if (DiskGetBrfrPartitionEntry(DriveNumber, FATX_DATA_PARTITION, &PartitionTableEntry))
355 {
356 DiskPartitionType[DriveNumber] = PARTITION_STYLE_BRFR;
357 TRACE("Drive 0x%X partition type Xbox-BRFR\n", DriveNumber);
358 return;
359 }
360
361 /* Failed to detect partitions, assume partitionless disk */
362 DiskPartitionType[DriveNumber] = PARTITION_STYLE_RAW;
363 TRACE("Drive 0x%X partition type unknown\n", DriveNumber);
364}
unsigned char BOOLEAN
static BOOLEAN DiskReadBootRecord(IN UCHAR DriveNumber, IN ULONGLONG LogicalSectorNumber, OUT PMASTER_BOOT_RECORD BootRecord)
Definition: partition.c:52
#define FATX_DATA_PARTITION
Definition: partition.c:34
static BOOLEAN DiskGetBrfrPartitionEntry(IN UCHAR DriveNumber, IN ULONG PartitionNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
Definition: partition.c:285
static PARTITION_STYLE DiskPartitionType[MaxDriveNumber+1]
Definition: partition.c:27
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:87
#define PARTITION_GPT
Definition: disk.h:106
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define TRACE(s)
Definition: solgame.cpp:4
PARTITION_TABLE_ENTRY PartitionTable[4]
Definition: parttest.c:92
Definition: parttest.c:75
Definition: disk.h:56
UCHAR SystemIndicator
Definition: disk.h:62
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by GetHarddiskInformation().

◆ DiskGetActivePartitionEntry()

static BOOLEAN DiskGetActivePartitionEntry ( IN UCHAR  DriveNumber,
OUT PPARTITION_TABLE_ENTRY  PartitionTableEntry,
OUT PULONG  ActivePartition 
)
static

Definition at line 134 of file partition.c.

138{
139 ULONG BootablePartitionCount = 0;
140 ULONG CurrentPartitionNumber;
141 ULONG Index;
142 MASTER_BOOT_RECORD MasterBootRecord;
143 PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
144
145 *ActivePartition = 0;
146
147 /* Read master boot record */
148 if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
149 {
150 return FALSE;
151 }
152
153 CurrentPartitionNumber = 0;
154 for (Index = 0; Index < 4; Index++)
155 {
156 ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
157
158 if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
159 ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
160 ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
161 {
162 CurrentPartitionNumber++;
163
164 /* Test if this is the bootable partition */
165 if (ThisPartitionTableEntry->BootIndicator == 0x80)
166 {
167 BootablePartitionCount++;
168 *ActivePartition = CurrentPartitionNumber;
169
170 /* Copy the partition table entry */
171 RtlCopyMemory(PartitionTableEntry,
172 ThisPartitionTableEntry,
173 sizeof(PARTITION_TABLE_ENTRY));
174 }
175 }
176 }
177
178 /* Make sure there was only one bootable partition */
179 if (BootablePartitionCount == 0)
180 {
181 ERR("No bootable (active) partitions found.\n");
182 return FALSE;
183 }
184 else if (BootablePartitionCount != 1)
185 {
186 ERR("Too many bootable (active) partitions found.\n");
187 return FALSE;
188 }
189
190 return TRUE;
191}
#define ERR(fmt,...)
Definition: precomp.h:57
#define PARTITION_EXTENDED
Definition: disk.h:92
#define PARTITION_XINT13_EXTENDED
Definition: disk.h:99
UCHAR BootIndicator
Definition: disk.h:57
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by DiskGetBootPartitionEntry().

◆ DiskGetBootPartitionEntry()

BOOLEAN DiskGetBootPartitionEntry ( IN UCHAR  DriveNumber,
OUT PPARTITION_TABLE_ENTRY  PartitionTableEntry,
OUT PULONG  BootPartition 
)

Definition at line 367 of file partition.c.

371{
372 switch (DiskPartitionType[DriveNumber])
373 {
375 {
376 return DiskGetActivePartitionEntry(DriveNumber, PartitionTableEntry, BootPartition);
377 }
379 {
380 FIXME("DiskGetBootPartitionEntry() unimplemented for GPT\n");
381 return FALSE;
382 }
383 case PARTITION_STYLE_RAW:
384 {
385 FIXME("DiskGetBootPartitionEntry() unimplemented for RAW\n");
386 return FALSE;
387 }
388 case PARTITION_STYLE_BRFR:
389 {
390 if (DiskGetBrfrPartitionEntry(DriveNumber, FATX_DATA_PARTITION, PartitionTableEntry))
391 {
392 *BootPartition = FATX_DATA_PARTITION;
393 return TRUE;
394 }
395 return FALSE;
396 }
397 default:
398 {
399 ERR("Drive 0x%X partition type = %d, should not happen!\n", DriveNumber, DiskPartitionType[DriveNumber]);
400 ASSERT(FALSE);
401 }
402 }
403 return FALSE;
404}
#define FIXME(fmt,...)
Definition: precomp.h:53
static BOOLEAN DiskGetActivePartitionEntry(IN UCHAR DriveNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry, OUT PULONG ActivePartition)
Definition: partition.c:134
#define ASSERT(a)
Definition: mode.c:44

Referenced by DiskGetBootPath().

◆ DiskGetBrfrPartitionEntry()

static BOOLEAN DiskGetBrfrPartitionEntry ( IN UCHAR  DriveNumber,
IN ULONG  PartitionNumber,
OUT PPARTITION_TABLE_ENTRY  PartitionTableEntry 
)
static

Definition at line 285 of file partition.c.

289{
290 /*
291 * Get partition entry of an Xbox-standard BRFR partitioned disk.
292 */
293 if (PartitionNumber >= 1 && PartitionNumber <= sizeof(XboxPartitions) / sizeof(XboxPartitions[0]) &&
295 {
297 {
298 /* No magic Xbox partitions */
299 return FALSE;
300 }
301
302 RtlZeroMemory(PartitionTableEntry, sizeof(PARTITION_TABLE_ENTRY));
303 PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
304 PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition;
305 PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount;
306 return TRUE;
307 }
308
309 /* Partition does not exist */
310 return FALSE;
311}
#define XBOX_SIGNATURE_SECTOR
Definition: partition.c:30
#define XBOX_SIGNATURE
Definition: partition.c:31
static struct @154 XboxPartitions[]
#define DiskReadBuffer
Definition: hardware.h:33
#define MachDiskReadLogicalSectors(Drive, Start, Count, Buf)
Definition: machine.h:126
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061

Referenced by DiskDetectPartitionType(), DiskGetBootPartitionEntry(), and DiskGetPartitionEntry().

◆ DiskGetFirstExtendedPartitionEntry()

static BOOLEAN DiskGetFirstExtendedPartitionEntry ( IN PMASTER_BOOT_RECORD  MasterBootRecord,
OUT PPARTITION_TABLE_ENTRY  PartitionTableEntry 
)
static

Definition at line 113 of file partition.c.

116{
117 ULONG Index;
118
119 for (Index = 0; Index < 4; Index++)
120 {
121 /* Check the system indicator. If it an extended partition then we're done. */
122 if ((MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_EXTENDED) ||
123 (MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_XINT13_EXTENDED))
124 {
125 RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
126 return TRUE;
127 }
128 }
129
130 return FALSE;
131}

Referenced by DiskGetMbrPartitionEntry().

◆ DiskGetFirstPartitionEntry()

static BOOLEAN DiskGetFirstPartitionEntry ( IN PMASTER_BOOT_RECORD  MasterBootRecord,
OUT PPARTITION_TABLE_ENTRY  PartitionTableEntry 
)
static

Definition at line 91 of file partition.c.

94{
96
97 for (Index = 0; Index < 4; Index++)
98 {
99 /* Check the system indicator. If it's not an extended or unused partition then we're done. */
100 if ((MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_ENTRY_UNUSED) &&
101 (MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_EXTENDED) &&
102 (MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_XINT13_EXTENDED))
103 {
104 RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
105 return TRUE;
106 }
107 }
108
109 return FALSE;
110}

Referenced by DiskGetMbrPartitionEntry().

◆ DiskGetMbrPartitionEntry()

static BOOLEAN DiskGetMbrPartitionEntry ( IN UCHAR  DriveNumber,
IN ULONG  PartitionNumber,
OUT PPARTITION_TABLE_ENTRY  PartitionTableEntry 
)
static

Definition at line 194 of file partition.c.

198{
199 MASTER_BOOT_RECORD MasterBootRecord;
200 PARTITION_TABLE_ENTRY ExtendedPartitionTableEntry;
201 ULONG ExtendedPartitionNumber;
202 ULONG ExtendedPartitionOffset;
203 ULONG Index;
204 ULONG CurrentPartitionNumber;
205 PPARTITION_TABLE_ENTRY ThisPartitionTableEntry;
206
207 /* Read master boot record */
208 if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
209 {
210 return FALSE;
211 }
212
213 CurrentPartitionNumber = 0;
214 for (Index = 0; Index < 4; Index++)
215 {
216 ThisPartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
217
218 if (ThisPartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED &&
219 ThisPartitionTableEntry->SystemIndicator != PARTITION_EXTENDED &&
220 ThisPartitionTableEntry->SystemIndicator != PARTITION_XINT13_EXTENDED)
221 {
222 CurrentPartitionNumber++;
223 }
224
225 if (PartitionNumber == CurrentPartitionNumber)
226 {
227 RtlCopyMemory(PartitionTableEntry, ThisPartitionTableEntry, sizeof(PARTITION_TABLE_ENTRY));
228 return TRUE;
229 }
230 }
231
232 /*
233 * They want an extended partition entry so we will need
234 * to loop through all the extended partitions on the disk
235 * and return the one they want.
236 */
237 ExtendedPartitionNumber = PartitionNumber - CurrentPartitionNumber - 1;
238
239 /*
240 * Set the initial relative starting sector to 0.
241 * This is because extended partition starting
242 * sectors a numbered relative to their parent.
243 */
244 ExtendedPartitionOffset = 0;
245
246 for (Index = 0; Index <= ExtendedPartitionNumber; Index++)
247 {
248 /* Get the extended partition table entry */
249 if (!DiskGetFirstExtendedPartitionEntry(&MasterBootRecord, &ExtendedPartitionTableEntry))
250 {
251 return FALSE;
252 }
253
254 /* Adjust the relative starting sector of the partition */
255 ExtendedPartitionTableEntry.SectorCountBeforePartition += ExtendedPartitionOffset;
256 if (ExtendedPartitionOffset == 0)
257 {
258 /* Set the start of the parrent extended partition */
259 ExtendedPartitionOffset = ExtendedPartitionTableEntry.SectorCountBeforePartition;
260 }
261 /* Read the partition boot record */
262 if (!DiskReadBootRecord(DriveNumber, ExtendedPartitionTableEntry.SectorCountBeforePartition, &MasterBootRecord))
263 {
264 return FALSE;
265 }
266
267 /* Get the first real partition table entry */
268 if (!DiskGetFirstPartitionEntry(&MasterBootRecord, PartitionTableEntry))
269 {
270 return FALSE;
271 }
272
273 /* Now correct the start sector of the partition */
274 PartitionTableEntry->SectorCountBeforePartition += ExtendedPartitionTableEntry.SectorCountBeforePartition;
275 }
276
277 /*
278 * When we get here we should have the correct entry already
279 * stored in PartitionTableEntry, so just return TRUE.
280 */
281 return TRUE;
282}
static BOOLEAN DiskGetFirstPartitionEntry(IN PMASTER_BOOT_RECORD MasterBootRecord, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
Definition: partition.c:91
static BOOLEAN DiskGetFirstExtendedPartitionEntry(IN PMASTER_BOOT_RECORD MasterBootRecord, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
Definition: partition.c:113
ULONG SectorCountBeforePartition
Definition: parttest.c:84

Referenced by DiskGetPartitionEntry().

◆ DiskGetPartitionEntry()

BOOLEAN DiskGetPartitionEntry ( IN UCHAR  DriveNumber,
IN ULONG  PartitionNumber,
OUT PPARTITION_TABLE_ENTRY  PartitionTableEntry 
)

Definition at line 407 of file partition.c.

411{
412 switch (DiskPartitionType[DriveNumber])
413 {
415 {
416 return DiskGetMbrPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
417 }
419 {
420 FIXME("DiskGetPartitionEntry() unimplemented for GPT\n");
421 return FALSE;
422 }
423 case PARTITION_STYLE_RAW:
424 {
425 FIXME("DiskGetPartitionEntry() unimplemented for RAW\n");
426 return FALSE;
427 }
428 case PARTITION_STYLE_BRFR:
429 {
430 return DiskGetBrfrPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
431 }
432 default:
433 {
434 ERR("Drive 0x%X partition type = %d, should not happen!\n", DriveNumber, DiskPartitionType[DriveNumber]);
435 ASSERT(FALSE);
436 }
437 }
438 return FALSE;
439}
static BOOLEAN DiskGetMbrPartitionEntry(IN UCHAR DriveNumber, IN ULONG PartitionNumber, OUT PPARTITION_TABLE_ENTRY PartitionTableEntry)
Definition: partition.c:194

Referenced by DiskOpen(), GetHarddiskInformation(), and UefiDiskOpen().

◆ DiskReadBootRecord()

static BOOLEAN DiskReadBootRecord ( IN UCHAR  DriveNumber,
IN ULONGLONG  LogicalSectorNumber,
OUT PMASTER_BOOT_RECORD  BootRecord 
)
static

Definition at line 52 of file partition.c.

56{
58
59 /* Read master boot record */
60 if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer))
61 {
62 return FALSE;
63 }
65
66 TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber);
67 TRACE("Boot record logical start sector = %d\n", LogicalSectorNumber);
68 TRACE("sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD));
69
70 for (Index = 0; Index < 4; Index++)
71 {
72 TRACE("-------------------------------------------\n");
73 TRACE("Partition %d\n", (Index + 1));
74 TRACE("BootIndicator: 0x%x\n", BootRecord->PartitionTable[Index].BootIndicator);
75 TRACE("StartHead: 0x%x\n", BootRecord->PartitionTable[Index].StartHead);
76 TRACE("StartSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].StartSector);
77 TRACE("StartCylinder: 0x%x\n", BootRecord->PartitionTable[Index].StartCylinder);
78 TRACE("SystemIndicator: 0x%x\n", BootRecord->PartitionTable[Index].SystemIndicator);
79 TRACE("EndHead: 0x%x\n", BootRecord->PartitionTable[Index].EndHead);
80 TRACE("EndSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].EndSector);
81 TRACE("EndCylinder: 0x%x\n", BootRecord->PartitionTable[Index].EndCylinder);
82 TRACE("SectorCountBeforePartition: 0x%x\n", BootRecord->PartitionTable[Index].SectorCountBeforePartition);
83 TRACE("PartitionSectorCount: 0x%x\n", BootRecord->PartitionTable[Index].PartitionSectorCount);
84 }
85
86 /* Check the partition table magic value */
87 return (BootRecord->MasterBootRecordMagic == 0xaa55);
88}

Referenced by DiskDetectPartitionType(), DiskGetActivePartitionEntry(), and DiskGetMbrPartitionEntry().

Variable Documentation

◆ DiskPartitionType

PARTITION_STYLE DiskPartitionType[MaxDriveNumber+1]
static

◆ PartitionSectorCount

ULONG PartitionSectorCount

Definition at line 39 of file partition.c.

Referenced by FatDetermineFatType(), and FatOpenVolume().

◆ SectorCountBeforePartition

ULONG SectorCountBeforePartition

Definition at line 38 of file partition.c.

◆ SystemIndicator

UCHAR SystemIndicator

Definition at line 40 of file partition.c.

◆ 

struct { ... } XboxPartitions[]
Initial value:
=
{
{ 0x0055F400, 0x0098F800, PARTITION_FAT32 },
{ 0x00465400, 0x000FA000, PARTITION_FAT_16 },
{ 0x00000400, 0x00177000, PARTITION_FAT_16 },
{ 0x00177400, 0x00177000, PARTITION_FAT_16 },
{ 0x002EE400, 0x00177000, PARTITION_FAT_16 }
}
#define PARTITION_FAT32
Definition: disk.h:96
#define PARTITION_FAT_16
Definition: disk.h:91

Referenced by DiskGetBrfrPartitionEntry().