xref: /reactos/base/setup/lib/utils/partlist.h (revision d6d3d0ea)
1 /*
2  * PROJECT:     ReactOS Setup Library
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Partition list functions
5  * COPYRIGHT:   Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
6  *              Copyright 2018-2024 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
7  */
8 
9 #pragma once
10 
11 /* EXTRA HANDFUL MACROS *****************************************************/
12 
13 // NOTE: They should be moved into some global header.
14 
15 /* OEM MBR partition types recognized by NT (see [MS-DMRP] Appendix B) */
16 #define PARTITION_EISA          0x12    // EISA partition
17 #define PARTITION_HIBERNATION   0x84    // Hibernation partition for laptops
18 #define PARTITION_DIAGNOSTIC    0xA0    // Diagnostic partition on some Hewlett-Packard (HP) notebooks
19 #define PARTITION_DELL          0xDE    // Dell partition
20 #define PARTITION_IBM           0xFE    // IBM Initial Microprogram Load (IML) partition
21 
22 #define IsOEMPartition(PartitionType) \
23     ( ((PartitionType) == PARTITION_EISA)        || \
24       ((PartitionType) == PARTITION_HIBERNATION) || \
25       ((PartitionType) == PARTITION_DIAGNOSTIC)  || \
26       ((PartitionType) == PARTITION_DELL)        || \
27       ((PartitionType) == PARTITION_IBM) )
28 
29 
30 /* PARTITION UTILITY FUNCTIONS **********************************************/
31 
32 typedef enum _FORMATSTATE
33 {
34     Unformatted,
35     UnformattedOrDamaged,
36     UnknownFormat,
37     Formatted
38 } FORMATSTATE, *PFORMATSTATE;
39 
40 #include "volutil.h"
41 
42 typedef struct _PARTENTRY PARTENTRY, *PPARTENTRY;
43 typedef struct _VOLENTRY
44 {
45     LIST_ENTRY ListEntry; ///< Entry in VolumesList
46 
47     VOLINFO Info;
48     FORMATSTATE FormatState;
49 
50     /* Volume must be checked */
51     BOOLEAN NeedsCheck;
52     /* Volume is new and has not yet been actually formatted and mounted */
53     BOOLEAN New;
54 
55     // union {
56     //     PVOLUME_DISK_EXTENTS pExtents;
57         PPARTENTRY PartEntry;
58     // };
59 } VOLENTRY, *PVOLENTRY;
60 
61 typedef struct _PARTENTRY
62 {
63     LIST_ENTRY ListEntry;
64 
65     /* The disk this partition belongs to */
66     struct _DISKENTRY *DiskEntry;
67 
68     /* Partition geometry */
69     ULARGE_INTEGER StartSector;
70     ULARGE_INTEGER SectorCount;
71 
72     BOOLEAN BootIndicator;  // NOTE: See comment for the PARTLIST::SystemPartition member.
73     UCHAR PartitionType;
74     ULONG OnDiskPartitionNumber; /* Enumerated partition number (primary partitions first, excluding the extended partition container, then the logical partitions) */
75     ULONG PartitionNumber;       /* Current partition number, only valid for the currently running NTOS instance */
76     ULONG PartitionIndex;        /* Index in the LayoutBuffer->PartitionEntry[] cached array of the corresponding DiskEntry */
77     WCHAR DeviceName[MAX_PATH];  ///< NT device name: "\Device\HarddiskM\PartitionN"
78 
79     BOOLEAN LogicalPartition;
80 
81     /* Partition is partitioned disk space */
82     BOOLEAN IsPartitioned;
83 
84     /* Partition is new, table does not exist on disk yet */
85     BOOLEAN New;
86 
87     /*
88      * Volume-related properties:
89      * NULL: No volume is associated to this partition (either because it is
90      *       an empty disk region, or the partition type is unrecognized).
91      * 0x1 : TBD.
92      * Valid pointer: A basic volume associated to this partition is (or will)
93      *       be mounted by the PARTMGR and enumerated by the MOUNTMGR.
94      */
95     PVOLENTRY Volume;
96 
97 } PARTENTRY, *PPARTENTRY;
98 
99 typedef struct _DISKENTRY
100 {
101     LIST_ENTRY ListEntry;
102 
103     /* The list of disks/partitions this disk belongs to */
104     struct _PARTLIST *PartList;
105 
106     MEDIA_TYPE MediaType;   /* FixedMedia or RemovableMedia */
107 
108     /* Disk geometry */
109 
110     ULONGLONG Cylinders;
111     ULONG TracksPerCylinder;
112     ULONG SectorsPerTrack;
113     ULONG BytesPerSector;
114 
115     ULARGE_INTEGER SectorCount;
116     ULONG SectorAlignment;
117     ULONG CylinderAlignment;
118 
119     /* BIOS Firmware parameters */
120     BOOLEAN BiosFound;
121     ULONG HwAdapterNumber;
122     ULONG HwControllerNumber;
123     ULONG HwDiskNumber;         /* Disk number currently assigned on the system */
124     ULONG HwFixedDiskNumber;    /* Disk number on the system when *ALL* removable disks are not connected */
125 //    ULONG Signature;  // Obtained from LayoutBuffer->Signature
126 //    ULONG Checksum;
127 
128     /* SCSI parameters */
129     ULONG DiskNumber;
130 //  SCSI_ADDRESS;
131     USHORT Port;
132     USHORT Bus;
133     USHORT Id;
134 
135     /* Has the partition list been modified? */
136     BOOLEAN Dirty;
137 
138     BOOLEAN NewDisk; /* If TRUE, the disk is uninitialized */
139     PARTITION_STYLE DiskStyle;  /* MBR/GPT-partitioned disk, or uninitialized disk (RAW) */
140 
141     UNICODE_STRING DriverName;
142 
143     PDRIVE_LAYOUT_INFORMATION LayoutBuffer;
144     // TODO: When adding support for GPT disks:
145     // Use PDRIVE_LAYOUT_INFORMATION_EX which indicates whether
146     // the disk is MBR, GPT, or unknown (uninitialized).
147     // Depending on the style, either use the MBR or GPT partition info.
148 
149     LIST_ENTRY PrimaryPartListHead; /* List of primary partitions */
150     LIST_ENTRY LogicalPartListHead; /* List of logical partitions (Valid only for MBR-partitioned disks) */
151 
152     /* Pointer to the unique extended partition on this disk (Valid only for MBR-partitioned disks) */
153     PPARTENTRY ExtendedPartition;
154 
155 } DISKENTRY, *PDISKENTRY;
156 
157 typedef struct _BIOSDISKENTRY
158 {
159     LIST_ENTRY ListEntry;
160     ULONG AdapterNumber;
161     ULONG ControllerNumber;
162     ULONG DiskNumber;
163     ULONG Signature;
164     ULONG Checksum;
165     PDISKENTRY DiskEntry;   /* Corresponding recognized disk; is NULL if the disk is not recognized */ // RecognizedDiskEntry;
166     CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
167     CM_INT13_DRIVE_PARAMETER Int13DiskData;
168 } BIOSDISKENTRY, *PBIOSDISKENTRY;
169 
170 typedef struct _PARTLIST
171 {
172     /*
173      * The system partition where the boot manager resides.
174      * The corresponding system disk is obtained via:
175      *    SystemPartition->DiskEntry.
176      */
177     // NOTE: It seems to appear that the specifications of ARC and (u)EFI
178     // actually allow for multiple system partitions to exist on the system.
179     // If so we should instead rely on the BootIndicator bit of the PARTENTRY
180     // structure in order to find these.
181     PPARTENTRY SystemPartition;
182 
183     LIST_ENTRY DiskListHead;
184     LIST_ENTRY BiosDiskListHead;
185 
186     /* (Basic) Volumes management */
187     LIST_ENTRY VolumesList;
188 
189 } PARTLIST, *PPARTLIST;
190 
191 #define PARTITION_TBL_SIZE  4
192 
193 #define PARTITION_MAGIC     0xAA55
194 
195 /* Defines system type for MBR showing that a GPT is following */
196 #define EFI_PMBR_OSTYPE_EFI 0xEE
197 
198 #include <pshpack1.h>
199 
200 typedef struct _PARTITION
201 {
202     unsigned char   BootFlags;        /* bootable?  0=no, 128=yes  */
203     unsigned char   StartingHead;     /* beginning head number */
204     unsigned char   StartingSector;   /* beginning sector number */
205     unsigned char   StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
206     unsigned char   PartitionType;    /* Operating System type indicator code */
207     unsigned char   EndingHead;       /* ending head number */
208     unsigned char   EndingSector;     /* ending sector number */
209     unsigned char   EndingCylinder;   /* also a 10 bit nmbr, with same high 2 bit trick */
210     unsigned int  StartingBlock;      /* first sector relative to start of disk */
211     unsigned int  SectorCount;        /* number of sectors in partition */
212 } PARTITION, *PPARTITION;
213 
214 typedef struct _PARTITION_SECTOR
215 {
216     UCHAR BootCode[440];                     /* 0x000 */
217     ULONG Signature;                         /* 0x1B8 */
218     UCHAR Reserved[2];                       /* 0x1BC */
219     PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */
220     USHORT Magic;                            /* 0x1FE */
221 } PARTITION_SECTOR, *PPARTITION_SECTOR;
222 
223 #include <poppack.h>
224 
225 typedef struct
226 {
227     LIST_ENTRY ListEntry;
228     ULONG DiskNumber;
229     ULONG Identifier;
230     ULONG Signature;
231 } BIOS_DISK, *PBIOS_DISK;
232 
233 
234 
235 ULONGLONG
236 AlignDown(
237     IN ULONGLONG Value,
238     IN ULONG Alignment);
239 
240 ULONGLONG
241 AlignUp(
242     IN ULONGLONG Value,
243     IN ULONG Alignment);
244 
245 ULONGLONG
246 RoundingDivide(
247    IN ULONGLONG Dividend,
248    IN ULONGLONG Divisor);
249 
250 
251 #define GetPartEntryOffsetInBytes(PartEntry) \
252     ((PartEntry)->StartSector.QuadPart * (PartEntry)->DiskEntry->BytesPerSector)
253 
254 #define GetPartEntrySizeInBytes(PartEntry) \
255     ((PartEntry)->SectorCount.QuadPart * (PartEntry)->DiskEntry->BytesPerSector)
256 
257 #define GetDiskSizeInBytes(DiskEntry) \
258     ((DiskEntry)->SectorCount.QuadPart * (DiskEntry)->BytesPerSector)
259 
260 
261 BOOLEAN
262 IsDiskSuperFloppy2(
263     _In_ const DISK_PARTITION_INFO* DiskInfo,
264     _In_opt_ const ULONGLONG* DiskSize,
265     _In_ const PARTITION_INFORMATION* PartitionInfo);
266 
267 BOOLEAN
268 IsDiskSuperFloppy(
269     _In_ const DRIVE_LAYOUT_INFORMATION* Layout,
270     _In_opt_ const ULONGLONG* DiskSize);
271 
272 BOOLEAN
273 IsDiskSuperFloppyEx(
274     _In_ const DRIVE_LAYOUT_INFORMATION_EX* LayoutEx,
275     _In_opt_ const ULONGLONG* DiskSize);
276 
277 BOOLEAN
278 IsSuperFloppy(
279     _In_ PDISKENTRY DiskEntry);
280 
281 BOOLEAN
282 IsPartitionActive(
283     IN PPARTENTRY PartEntry);
284 
285 PPARTLIST
286 CreatePartitionList(VOID);
287 
288 VOID
289 DestroyPartitionList(
290     IN PPARTLIST List);
291 
292 PDISKENTRY
293 GetDiskByBiosNumber(
294     _In_ PPARTLIST List,
295     _In_ ULONG HwDiskNumber);
296 
297 PDISKENTRY
298 GetDiskByNumber(
299     _In_ PPARTLIST List,
300     _In_ ULONG DiskNumber);
301 
302 PDISKENTRY
303 GetDiskBySCSI(
304     _In_ PPARTLIST List,
305     _In_ USHORT Port,
306     _In_ USHORT Bus,
307     _In_ USHORT Id);
308 
309 PDISKENTRY
310 GetDiskBySignature(
311     _In_ PPARTLIST List,
312     _In_ ULONG Signature);
313 
314 PPARTENTRY
315 GetPartition(
316     _In_ PDISKENTRY DiskEntry,
317     _In_ ULONG PartitionNumber);
318 
319 PPARTENTRY
320 SelectPartition(
321     _In_ PPARTLIST List,
322     _In_ ULONG DiskNumber,
323     _In_ ULONG PartitionNumber);
324 
325 PPARTENTRY
326 GetNextPartition(
327     IN PPARTLIST List,
328     IN PPARTENTRY CurrentPart OPTIONAL);
329 
330 PPARTENTRY
331 GetPrevPartition(
332     IN PPARTLIST List,
333     IN PPARTENTRY CurrentPart OPTIONAL);
334 
335 PPARTENTRY
336 GetAdjUnpartitionedEntry(
337     _In_ PPARTENTRY PartEntry,
338     _In_ BOOLEAN Direction);
339 
340 ERROR_NUMBER
341 PartitionCreationChecks(
342     _In_ PPARTENTRY PartEntry);
343 
344 ERROR_NUMBER
345 ExtendedPartitionCreationChecks(
346     _In_ PPARTENTRY PartEntry);
347 
348 BOOLEAN
349 CreatePartition(
350     _In_ PPARTLIST List,
351     _Inout_ PPARTENTRY PartEntry,
352     _In_opt_ ULONGLONG SizeBytes,
353     _In_opt_ ULONG_PTR PartitionInfo);
354 
355 BOOLEAN
356 DeletePartition(
357     _In_ PPARTLIST List,
358     _In_ PPARTENTRY PartEntry,
359     _Out_opt_ PPARTENTRY* FreeRegion);
360 
361 PPARTENTRY
362 FindSupportedSystemPartition(
363     IN PPARTLIST List,
364     IN BOOLEAN ForceSelect,
365     IN PDISKENTRY AlternativeDisk OPTIONAL,
366     IN PPARTENTRY AlternativePart OPTIONAL);
367 
368 BOOLEAN
369 SetActivePartition(
370     IN PPARTLIST List,
371     IN PPARTENTRY PartEntry,
372     IN PPARTENTRY OldActivePart OPTIONAL);
373 
374 NTSTATUS
375 WritePartitions(
376     IN PDISKENTRY DiskEntry);
377 
378 BOOLEAN
379 WritePartitionsToDisk(
380     IN PPARTLIST List);
381 
382 BOOLEAN
383 SetMountedDeviceValues(
384     _In_ PPARTLIST List);
385 
386 VOID
387 SetMBRPartitionType(
388     IN PPARTENTRY PartEntry,
389     IN UCHAR PartitionType);
390 
391 /* EOF */
392