ReactOS 0.4.16-dev-2617-g01a0906
partition.c
Go to the documentation of this file.
1/*
2 * PROJECT: FreeLoader
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * or MIT (https://spdx.org/licenses/MIT)
5 * PURPOSE: Block Device partition management
6 * COPYRIGHT: Copyright 2002-2003 Brian Palmer <brianp@sginet.com>
7 * Copyright 2019 Stanislav Motylkov <x86corez@gmail.com>
8 * Copyright 2025-2026 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
9 */
10
11#ifndef _M_ARM
12#include <freeldr.h>
13
14#include <debug.h>
16
17#define MaxDriveNumber 0xFF
19
20#include "part_mbr.h" // FIXME: For MASTER_BOOT_RECORD
21
24 IN UCHAR DriveNumber,
25 IN ULONGLONG LogicalSectorNumber,
26 OUT PMASTER_BOOT_RECORD BootRecord)
27{
29
30 /* Read master boot record */
31 if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer))
32 {
33 return FALSE;
34 }
36
37 TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber);
38 TRACE("Boot record logical start sector = %d\n", LogicalSectorNumber);
39 TRACE("sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD));
40
41 for (Index = 0; Index < 4; Index++)
42 {
43 TRACE("-------------------------------------------\n");
44 TRACE("Partition %d\n", (Index + 1));
45 TRACE("BootIndicator: 0x%x\n", BootRecord->PartitionTable[Index].BootIndicator);
46 TRACE("StartHead: 0x%x\n", BootRecord->PartitionTable[Index].StartHead);
47 TRACE("StartSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].StartSector);
48 TRACE("StartCylinder: 0x%x\n", BootRecord->PartitionTable[Index].StartCylinder);
49 TRACE("SystemIndicator: 0x%x\n", BootRecord->PartitionTable[Index].SystemIndicator);
50 TRACE("EndHead: 0x%x\n", BootRecord->PartitionTable[Index].EndHead);
51 TRACE("EndSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].EndSector);
52 TRACE("EndCylinder: 0x%x\n", BootRecord->PartitionTable[Index].EndCylinder);
53 TRACE("SectorCountBeforePartition: 0x%x\n", BootRecord->PartitionTable[Index].SectorCountBeforePartition);
54 TRACE("PartitionSectorCount: 0x%x\n", BootRecord->PartitionTable[Index].PartitionSectorCount);
55 }
56
57 /* Check the partition table magic value */
58 return (BootRecord->MasterBootRecordMagic == 0xaa55);
59}
60
61#include "part_mbr.c"
62#include "part_gpt.c"
63#include "part_brfr.c"
64
65VOID
67 _In_ UCHAR DriveNumber)
68{
69 MASTER_BOOT_RECORD MasterBootRecord;
70
71 /* Probe for Master Boot Record */
72 if (DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
73 {
74#if 0
75 ULONG Index, PartitionCount = 0;
76 BOOLEAN GPTProtect = FALSE;
77#else
78 GPT_TABLE_HEADER GptHeader;
79#endif
80
82
83#if 0
84 /* Check for GUID Partition Table */
85 for (Index = 0; Index < 4; Index++)
86 {
87 PPARTITION_TABLE_ENTRY PartitionTableEntry = &MasterBootRecord.PartitionTable[Index];
88
89 if (PartitionTableEntry->SystemIndicator != PARTITION_ENTRY_UNUSED)
90 {
91 PartitionCount++;
92 if (Index == 0 && PartitionTableEntry->SystemIndicator == PARTITION_GPT)
93 GPTProtect = TRUE;
94 }
95 }
96
97 if (PartitionCount == 1 && GPTProtect)
98#else
99 if (DiskReadGptHeader(DriveNumber, &GptHeader))
100#endif
101 {
103 }
104 TRACE("Drive 0x%X partition type %s\n", DriveNumber, DiskPartitionType[DriveNumber] == PARTITION_STYLE_MBR ? "MBR" : "GPT");
105 return;
106 }
107
108 /* Probe for Xbox-BRFR partitioning */
109 if (DiskIsBrfr(DriveNumber))
110 {
111 DiskPartitionType[DriveNumber] = PARTITION_STYLE_BRFR;
112 TRACE("Drive 0x%X partition type Xbox-BRFR\n", DriveNumber);
113 return;
114 }
115
116 /* Failed to detect partitions, assume non-partitioned disk */
117 DiskPartitionType[DriveNumber] = PARTITION_STYLE_RAW;
118 TRACE("Drive 0x%X partition type unknown\n", DriveNumber);
119}
120
121// FIXME: This function is specific to BIOS-based PC platform.
124 _In_ UCHAR DriveNumber,
125 _Out_opt_ PPARTITION_INFORMATION PartitionEntry,
126 _Out_ PULONG BootPartition)
127{
128#if 0
129 GEOMETRY Geometry;
130 if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
131 return FALSE;
132#endif
133
134 switch (DiskPartitionType[DriveNumber])
135 {
137 {
138 return DiskGetActivePartitionEntry(DriveNumber,
139 /* MBR partition table always uses 512-byte sectors per specification */
140 512, // Geometry.BytesPerSector
141 PartitionEntry, BootPartition);
142 }
144 {
145 FIXME("DiskGetBootPartitionEntry() unimplemented for GPT\n");
146 return FALSE;
147 }
148 case PARTITION_STYLE_RAW:
149 {
150 FIXME("DiskGetBootPartitionEntry() unimplemented for RAW\n");
151 return FALSE;
152 }
153 case PARTITION_STYLE_BRFR:
154 {
155 PARTITION_INFORMATION TempPartitionEntry;
156 if (!PartitionEntry)
157 PartitionEntry = &TempPartitionEntry;
158 if (DiskGetBrfrPartitionEntry(DriveNumber,
159 512, // Geometry.BytesPerSector
161 PartitionEntry))
162 {
163 *BootPartition = FATX_DATA_PARTITION;
164 return TRUE;
165 }
166 return FALSE;
167 }
168 default:
169 {
170 ERR("Drive 0x%X partition type = %d, should not happen!\n", DriveNumber, DiskPartitionType[DriveNumber]);
171 ASSERT(FALSE);
172 }
173 }
174 return FALSE;
175}
176
179 _In_ UCHAR DriveNumber,
182 _Out_ PPARTITION_INFORMATION PartitionEntry)
183{
184 if (SectorSize == 0)
185 {
186 GEOMETRY Geometry;
187 if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
188 return FALSE;
189 SectorSize = Geometry.BytesPerSector;
190 }
191 if (SectorSize < 512)
192 {
193 ERR("Drive 0x%X: Invalid sector size %lu\n", DriveNumber, SectorSize);
194 return FALSE;
195 }
196
197 switch (DiskPartitionType[DriveNumber])
198 {
200 {
201 return DiskGetMbrPartitionEntry(DriveNumber,
202 /* MBR partition table always uses 512-byte sectors per specification */
203 512, // SectorSize
205 PartitionEntry);
206 }
208 {
209 return DiskGetGptPartitionEntry(DriveNumber,
212 PartitionEntry);
213 }
214 case PARTITION_STYLE_RAW:
215 {
216 FIXME("DiskGetPartitionEntry() unimplemented for RAW\n");
217 return FALSE;
218 }
219 case PARTITION_STYLE_BRFR:
220 {
221 return DiskGetBrfrPartitionEntry(DriveNumber,
222 512, // SectorSize
224 PartitionEntry);
225 }
226 default:
227 {
228 ERR("Drive 0x%X partition type = %d, should not happen!\n", DriveNumber, DiskPartitionType[DriveNumber]);
229 ASSERT(FALSE);
230 }
231 }
232 return FALSE;
233}
234
235#endif
unsigned char BOOLEAN
Definition: actypes.h:127
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
VOID DiskDetectPartitionType(_In_ UCHAR DriveNumber)
Definition: partition.c:66
BOOLEAN DiskGetBootPartitionEntry(_In_ UCHAR DriveNumber, _Out_opt_ PPARTITION_INFORMATION PartitionEntry, _Out_ PULONG BootPartition)
Definition: partition.c:123
#define MaxDriveNumber
Definition: partition.c:17
BOOLEAN DiskReadBootRecord(IN UCHAR DriveNumber, IN ULONGLONG LogicalSectorNumber, OUT PMASTER_BOOT_RECORD BootRecord)
Definition: partition.c:23
BOOLEAN DiskGetPartitionEntry(_In_ UCHAR DriveNumber, _In_opt_ ULONG SectorSize, _In_ ULONG PartitionNumber, _Out_ PPARTITION_INFORMATION PartitionEntry)
Definition: partition.c:178
static PARTITION_STYLE DiskPartitionType[MaxDriveNumber+1]
Definition: partition.c:18
#define DiskReadBuffer
Definition: hardware.h:33
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
#define MachDiskGetDriveGeometry(Drive, Geom)
Definition: machine.h:122
#define MachDiskReadLogicalSectors(Drive, Start, Count, Buf)
Definition: machine.h:120
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
enum _PARTITION_STYLE PARTITION_STYLE
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define _Out_opt_
Definition: no_sal2.h:214
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
static BOOLEAN DiskIsBrfr(_In_ UCHAR DriveNumber)
Definition: part_brfr.c:35
#define FATX_DATA_PARTITION
Definition: part_brfr.c:17
BOOLEAN DiskGetBrfrPartitionEntry(_In_ UCHAR DriveNumber, _In_ ULONG SectorSize, _In_ ULONG PartitionNumber, _Out_ PPARTITION_INFORMATION PartitionEntry)
Definition: part_brfr.c:47
BOOLEAN DiskGetGptPartitionEntry(_In_ UCHAR DriveNumber, _In_ ULONG SectorSize, _In_ ULONG PartitionNumber, _Out_ PPARTITION_INFORMATION PartitionEntry)
Definition: part_gpt.c:46
#define PARTITION_GPT
Definition: part_gpt.h:27
BOOLEAN DiskGetMbrPartitionEntry(_In_ UCHAR DriveNumber, _In_ ULONG SectorSize, _In_ ULONG PartitionNumber, _Out_ PPARTITION_INFORMATION PartitionEntry)
Definition: part_mbr.c:139
BOOLEAN DiskGetActivePartitionEntry(_In_ UCHAR DriveNumber, _In_ ULONG SectorSize, _Out_opt_ PPARTITION_INFORMATION PartitionEntry, _Out_ PULONG ActivePartition)
Definition: part_mbr.c:77
#define PARTITION_ENTRY_UNUSED
Definition: part_mbr.h:50
#define TRACE(s)
Definition: solgame.cpp:4
PARTITION_TABLE_ENTRY PartitionTable[4]
Definition: parttest.c:92
Definition: disk.h:24
ULONG BytesPerSector
Number of bytes per sector.
Definition: disk.h:28
Definition: part_mbr.h:16
UCHAR SystemIndicator
Definition: part_mbr.h:22
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
BOOLEAN DiskReadGptHeader(_In_ UCHAR DriveNumber, _Out_ PGPT_TABLE_HEADER GptHeader)
Definition: part_gpt.c:22
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ ULONG SectorSize
Definition: halfuncs.h:291
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061