xref: /reactos/base/setup/lib/utils/partlist.h (revision 2d4c0b87)
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 NTAPI
287 CreatePartitionList(VOID);
288 
289 VOID
290 NTAPI
291 DestroyPartitionList(
292     IN PPARTLIST List);
293 
294 PDISKENTRY
295 GetDiskByBiosNumber(
296     _In_ PPARTLIST List,
297     _In_ ULONG HwDiskNumber);
298 
299 PDISKENTRY
300 GetDiskByNumber(
301     _In_ PPARTLIST List,
302     _In_ ULONG DiskNumber);
303 
304 PDISKENTRY
305 GetDiskBySCSI(
306     _In_ PPARTLIST List,
307     _In_ USHORT Port,
308     _In_ USHORT Bus,
309     _In_ USHORT Id);
310 
311 PDISKENTRY
312 GetDiskBySignature(
313     _In_ PPARTLIST List,
314     _In_ ULONG Signature);
315 
316 PPARTENTRY
317 GetPartition(
318     _In_ PDISKENTRY DiskEntry,
319     _In_ ULONG PartitionNumber);
320 
321 PPARTENTRY
322 SelectPartition(
323     _In_ PPARTLIST List,
324     _In_ ULONG DiskNumber,
325     _In_ ULONG PartitionNumber);
326 
327 PPARTENTRY
328 NTAPI
329 GetNextPartition(
330     IN PPARTLIST List,
331     IN PPARTENTRY CurrentPart OPTIONAL);
332 
333 PPARTENTRY
334 NTAPI
335 GetPrevPartition(
336     IN PPARTLIST List,
337     IN PPARTENTRY CurrentPart OPTIONAL);
338 
339 PPARTENTRY
340 NTAPI
341 GetAdjUnpartitionedEntry(
342     _In_ PPARTENTRY PartEntry,
343     _In_ BOOLEAN Direction);
344 
345 ERROR_NUMBER
346 NTAPI
347 PartitionCreateChecks(
348     _In_ PPARTENTRY PartEntry,
349     _In_opt_ ULONGLONG SizeBytes,
350     _In_opt_ ULONG_PTR PartitionInfo);
351 
352 BOOLEAN
353 NTAPI
354 CreatePartition(
355     _In_ PPARTLIST List,
356     _Inout_ PPARTENTRY PartEntry,
357     _In_opt_ ULONGLONG SizeBytes,
358     _In_opt_ ULONG_PTR PartitionInfo);
359 
360 BOOLEAN
361 NTAPI
362 DeletePartition(
363     _In_ PPARTLIST List,
364     _In_ PPARTENTRY PartEntry,
365     _Out_opt_ PPARTENTRY* FreeRegion);
366 
367 PPARTENTRY
368 FindSupportedSystemPartition(
369     IN PPARTLIST List,
370     IN BOOLEAN ForceSelect,
371     IN PDISKENTRY AlternativeDisk OPTIONAL,
372     IN PPARTENTRY AlternativePart OPTIONAL);
373 
374 BOOLEAN
375 SetActivePartition(
376     IN PPARTLIST List,
377     IN PPARTENTRY PartEntry,
378     IN PPARTENTRY OldActivePart OPTIONAL);
379 
380 NTSTATUS
381 WritePartitions(
382     IN PDISKENTRY DiskEntry);
383 
384 BOOLEAN
385 WritePartitionsToDisk(
386     IN PPARTLIST List);
387 
388 BOOLEAN
389 SetMountedDeviceValues(
390     _In_ PPARTLIST List);
391 
392 VOID
393 SetMBRPartitionType(
394     IN PPARTENTRY PartEntry,
395     IN UCHAR PartitionType);
396 
397 /* EOF */
398