xref: /reactos/base/setup/lib/utils/partlist.c (revision 84f3e2df)
16f19c83bSHermès Bélusca-Maïto /*
26f19c83bSHermès Bélusca-Maïto  * PROJECT:     ReactOS Setup Library
36f19c83bSHermès Bélusca-Maïto  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
46f19c83bSHermès Bélusca-Maïto  * PURPOSE:     Partition list functions
5c1fbc2d6SHermès Bélusca-Maïto  * COPYRIGHT:   Copyright 2003-2019 Casper S. Hornstrup (chorns@users.sourceforge.net)
6c1fbc2d6SHermès Bélusca-Maïto  *              Copyright 2018-2019 Hermes Belusca-Maito
76f19c83bSHermès Bélusca-Maïto  */
86f19c83bSHermès Bélusca-Maïto 
96f19c83bSHermès Bélusca-Maïto #include "precomp.h"
106f19c83bSHermès Bélusca-Maïto #include <ntddscsi.h>
116f19c83bSHermès Bélusca-Maïto 
126f19c83bSHermès Bélusca-Maïto #include "partlist.h"
136f19c83bSHermès Bélusca-Maïto #include "fsutil.h"
146f19c83bSHermès Bélusca-Maïto 
156f19c83bSHermès Bélusca-Maïto #define NDEBUG
166f19c83bSHermès Bélusca-Maïto #include <debug.h>
176f19c83bSHermès Bélusca-Maïto 
186f19c83bSHermès Bélusca-Maïto //#define DUMP_PARTITION_TABLE
196f19c83bSHermès Bélusca-Maïto 
206f19c83bSHermès Bélusca-Maïto #include <pshpack1.h>
216f19c83bSHermès Bélusca-Maïto 
226f19c83bSHermès Bélusca-Maïto typedef struct _REG_DISK_MOUNT_INFO
236f19c83bSHermès Bélusca-Maïto {
246f19c83bSHermès Bélusca-Maïto     ULONG Signature;
256f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER StartingOffset;
266f19c83bSHermès Bélusca-Maïto } REG_DISK_MOUNT_INFO, *PREG_DISK_MOUNT_INFO;
276f19c83bSHermès Bélusca-Maïto 
286f19c83bSHermès Bélusca-Maïto #include <poppack.h>
296f19c83bSHermès Bélusca-Maïto 
306f19c83bSHermès Bélusca-Maïto 
31f41750abSHermès Bélusca-Maïto /* HELPERS FOR PARTITION TYPES **********************************************/
32f41750abSHermès Bélusca-Maïto 
33f41750abSHermès Bélusca-Maïto /*
34f41750abSHermès Bélusca-Maïto  * This partition type list was ripped from the kernelDisk.c module of
35f41750abSHermès Bélusca-Maïto  * the Visopsys Operating System (see license below), and completed with
36f41750abSHermès Bélusca-Maïto  * information from Paragon Hard-Disk Manager, and the following websites:
37f41750abSHermès Bélusca-Maïto  * http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
38f41750abSHermès Bélusca-Maïto  * https://en.wikipedia.org/wiki/Partition_type#List_of_partition_IDs
39f41750abSHermès Bélusca-Maïto  */
40f41750abSHermès Bélusca-Maïto /*
41f41750abSHermès Bélusca-Maïto  * kernelDisk.c
42f41750abSHermès Bélusca-Maïto  *
43f41750abSHermès Bélusca-Maïto  * Visopsys Operating System
44f41750abSHermès Bélusca-Maïto  * Copyright (C) 1998-2015 J. Andrew McLaughlin
45f41750abSHermès Bélusca-Maïto  *
46f41750abSHermès Bélusca-Maïto  * This program is free software; you can redistribute it and/or modify it
47f41750abSHermès Bélusca-Maïto  * under the terms of the GNU General Public License as published by the Free
48f41750abSHermès Bélusca-Maïto  * Software Foundation; either version 2 of the License, or (at your option)
49f41750abSHermès Bélusca-Maïto  * any later version.
50f41750abSHermès Bélusca-Maïto  *
51f41750abSHermès Bélusca-Maïto  * This program is distributed in the hope that it will be useful, but
52f41750abSHermès Bélusca-Maïto  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
53f41750abSHermès Bélusca-Maïto  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
54f41750abSHermès Bélusca-Maïto  * for more details.
55f41750abSHermès Bélusca-Maïto  *
56f41750abSHermès Bélusca-Maïto  * You should have received a copy of the GNU General Public License along
57f41750abSHermès Bélusca-Maïto  * with this program; if not, write to the Free Software Foundation, Inc.,
58f41750abSHermès Bélusca-Maïto  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
59f41750abSHermès Bélusca-Maïto  */
60f41750abSHermès Bélusca-Maïto 
61f41750abSHermès Bélusca-Maïto /* This is a table for keeping known partition type codes and descriptions */
62f41750abSHermès Bélusca-Maïto PARTITION_TYPE PartitionTypes[NUM_PARTITION_TYPE_ENTRIES] =
63f41750abSHermès Bélusca-Maïto {
64f41750abSHermès Bélusca-Maïto     { 0x00, "(Empty)" },
65f41750abSHermès Bélusca-Maïto     { 0x01, "FAT12" },
66f41750abSHermès Bélusca-Maïto     { 0x02, "XENIX root" },
67f41750abSHermès Bélusca-Maïto     { 0x03, "XENIX usr" },
68f41750abSHermès Bélusca-Maïto     { 0x04, "FAT16 (< 32 MB)" },
69f41750abSHermès Bélusca-Maïto     { 0x05, "Extended" },
70f41750abSHermès Bélusca-Maïto     { 0x06, "FAT16" },
71f41750abSHermès Bélusca-Maïto     { 0x07, "NTFS/HPFS/exFAT" },
72f41750abSHermès Bélusca-Maïto     { 0x08, "OS/2 or AIX boot" },
73f41750abSHermès Bélusca-Maïto     { 0x09, "AIX data" },
74f41750abSHermès Bélusca-Maïto     { 0x0A, "OS/2 Boot Manager" },
75f41750abSHermès Bélusca-Maïto     { 0x0B, "FAT32" },
76f41750abSHermès Bélusca-Maïto     { 0x0C, "FAT32 (LBA)" },
77f41750abSHermès Bélusca-Maïto     { 0x0E, "FAT16 (LBA)" },
78f41750abSHermès Bélusca-Maïto     { 0x0F, "Extended (LBA)" },
79f41750abSHermès Bélusca-Maïto     { 0x10, "OPUS" },
80f41750abSHermès Bélusca-Maïto     { 0x11, "Hidden FAT12" },
81f41750abSHermès Bélusca-Maïto     { 0x12, "FAT diagnostic (Compaq)" },
82f41750abSHermès Bélusca-Maïto     { 0x13, "BTRON" },
83f41750abSHermès Bélusca-Maïto     { 0x14, "Hidden FAT16 (< 32 MB)" },
84f41750abSHermès Bélusca-Maïto     { 0x16, "Hidden FAT16" },
85f41750abSHermès Bélusca-Maïto     { 0x17, "Hidden HPFS or NTFS" },
86f41750abSHermès Bélusca-Maïto     { 0x18, "AST SmartSleep" },
87f41750abSHermès Bélusca-Maïto     { 0x1B, "Hidden FAT32" },
88f41750abSHermès Bélusca-Maïto     { 0x1C, "Hidden FAT32 (LBA)" },
89f41750abSHermès Bélusca-Maïto     { 0x1E, "Hidden FAT16 (LBA)" },
90f41750abSHermès Bélusca-Maïto     { 0x24, "NEC DOS 3.x" },
91f41750abSHermès Bélusca-Maïto     { 0x27, "Hidden WinRE NTFS" },
92f41750abSHermès Bélusca-Maïto     { 0x2A, "AtheOS File System (AFS)" },
93f41750abSHermès Bélusca-Maïto     { 0x2B, "SyllableSecure (SylStor)" },
94f41750abSHermès Bélusca-Maïto     { 0x32, "NOS" },
95f41750abSHermès Bélusca-Maïto     { 0x35, "JFS on OS/2 or eCS" },
96f41750abSHermès Bélusca-Maïto     { 0x38, "THEOS v3.2 2GB partition" },
97f41750abSHermès Bélusca-Maïto     { 0x39, "Plan 9" },
98f41750abSHermès Bélusca-Maïto     { 0x3A, "THEOS v4 4GB partition" },
99f41750abSHermès Bélusca-Maïto     { 0x3B, "THEOS v4 extended partition" },
100f41750abSHermès Bélusca-Maïto     { 0x3C, "PartitionMagic recovery partition" },
101f41750abSHermès Bélusca-Maïto     { 0x3D, "Hidden NetWare" },
102f41750abSHermès Bélusca-Maïto     { 0x40, "Lynx" },
103f41750abSHermès Bélusca-Maïto     { 0x41, "PowerPC PReP boot" },
104f41750abSHermès Bélusca-Maïto     { 0x42, "Win2K Dynamic Volume extended" },
105f41750abSHermès Bélusca-Maïto     { 0x43, "Old Linux" },
106f41750abSHermès Bélusca-Maïto     { 0x44, "GoBack" },
107f41750abSHermès Bélusca-Maïto     { 0x45, "Priam or Boot-US Boot Manager" },
108f41750abSHermès Bélusca-Maïto     { 0x4D, "QNX4.x" },
109f41750abSHermès Bélusca-Maïto     { 0x4E, "QNX4.x 2nd partition" },
110f41750abSHermès Bélusca-Maïto     { 0x4F, "QNX4.x 3rd partition" },
111f41750abSHermès Bélusca-Maïto     { 0x50, "OnTrack Disk Manager R/O" },
112f41750abSHermès Bélusca-Maïto     { 0x51, "OnTrack Disk Manager R/W or Novell" },
113f41750abSHermès Bélusca-Maïto     { 0x52, "CP/M" },
114f41750abSHermès Bélusca-Maïto     { 0x53, "OnTrack DM6 Aux3" },
115f41750abSHermès Bélusca-Maïto     { 0x54, "OnTrack DM6 Dynamic Drive Overlay" },
116f41750abSHermès Bélusca-Maïto     { 0x55, "EZ-Drive" },
117f41750abSHermès Bélusca-Maïto     { 0x56, "Golden Bow VFeature Partitioned Volume" },
118f41750abSHermès Bélusca-Maïto     { 0x5C, "Priam EDisk" },
119f41750abSHermès Bélusca-Maïto     { 0x61, "SpeedStor" },
120f41750abSHermès Bélusca-Maïto     { 0x62, "Pick" },
121f41750abSHermès Bélusca-Maïto     { 0x63, "GNU HURD or Unix System V (SCO, ISC Unix, UnixWare)" },
122f41750abSHermès Bélusca-Maïto     { 0x64, "Novell NetWare 286, 2.xx" },
123f41750abSHermès Bélusca-Maïto     { 0x65, "Novell NetWare 386, 3.xx or 4.xx" },
124f41750abSHermès Bélusca-Maïto     { 0x66, "Novell NetWare SMS Partition" },
125f41750abSHermès Bélusca-Maïto     { 0x67, "Novell" },
126f41750abSHermès Bélusca-Maïto     { 0x68, "Novell" },
127f41750abSHermès Bélusca-Maïto     { 0x69, "Novell NetWare 5+" },
128f41750abSHermès Bélusca-Maïto     { 0x70, "DiskSecure Multi-Boot" },
129f41750abSHermès Bélusca-Maïto     { 0x75, "IBM PC/IX" },
130f41750abSHermès Bélusca-Maïto     { 0x7E, "Veritas VxVM public" },
131f41750abSHermès Bélusca-Maïto     { 0x7F, "Veritas VxVM private" },
132f41750abSHermès Bélusca-Maïto     { 0x80, "Old MINIX" },
133f41750abSHermès Bélusca-Maïto     { 0x81, "Linux or MINIX" },
134f41750abSHermès Bélusca-Maïto     { 0x82, "Linux swap or Solaris" },
135f41750abSHermès Bélusca-Maïto     { 0x83, "Linux Native" },
136f41750abSHermès Bélusca-Maïto     { 0x84, "Hibernate" },
137f41750abSHermès Bélusca-Maïto     { 0x85, "Extended Linux" },
138f41750abSHermès Bélusca-Maïto     { 0x86, "FAT16 mirrored" },
139f41750abSHermès Bélusca-Maïto     { 0x87, "HPFS or NTFS mirrored" },
140f41750abSHermès Bélusca-Maïto     { 0x88, "Linux plaintext partition table" },
141f41750abSHermès Bélusca-Maïto     { 0x8B, "FAT32 mirrored" },
142f41750abSHermès Bélusca-Maïto     { 0x8C, "FAT32 (LBA) mirrored" },
143f41750abSHermès Bélusca-Maïto     { 0x8E, "Linux LVM" },
144f41750abSHermès Bélusca-Maïto     { 0x93, "Hidden Linux" },
145f41750abSHermès Bélusca-Maïto     { 0x94, "Amoeba BBT" },
146f41750abSHermès Bélusca-Maïto     { 0x96, "CDFS/ISO-9660" },
147f41750abSHermès Bélusca-Maïto     { 0x9F, "BSD/OS" },
148f41750abSHermès Bélusca-Maïto     { 0xA0, "Laptop Hibernate" },
149f41750abSHermès Bélusca-Maïto     { 0xA1, "Laptop Hibernate (NEC 6000H)" },
150f41750abSHermès Bélusca-Maïto     { 0xA5, "BSD, NetBSD, FreeBSD" },
151f41750abSHermès Bélusca-Maïto     { 0xA6, "OpenBSD" },
152f41750abSHermès Bélusca-Maïto     { 0xA7, "NeXTStep" },
153f41750abSHermès Bélusca-Maïto     { 0xA8, "Darwin UFS" },      // Also known as "OS-X"
154f41750abSHermès Bélusca-Maïto     { 0xA9, "NetBSD" },
155f41750abSHermès Bélusca-Maïto     { 0xAB, "Darwin boot" },
156f41750abSHermès Bélusca-Maïto     { 0xAF, "Apple HFS" },
157f41750abSHermès Bélusca-Maïto     { 0xB6, "NT FAT16 corrupt mirror" },
158f41750abSHermès Bélusca-Maïto     { 0xB7, "BSDI BSD/386 FS" }, // Alternatively, "NT NTFS corrupt mirror"
159f41750abSHermès Bélusca-Maïto     { 0xB8, "BSDI BSD/386 swap" },
160f41750abSHermès Bélusca-Maïto     { 0xBB, "Boot Wizard hidden" },
161f41750abSHermès Bélusca-Maïto     { 0xBC, "Paragon Backup capsule" },
162f41750abSHermès Bélusca-Maïto     { 0xBE, "Solaris 8 boot partition" },
163f41750abSHermès Bélusca-Maïto     { 0xBF, "Solaris 10 x86" },
164f41750abSHermès Bélusca-Maïto     { 0xC0, "NTFT" },            // Alternatively, "CTOS" or "REAL/32 or DR-DOS or Novell-DOS secure partition"
165f41750abSHermès Bélusca-Maïto     { 0xC1, "DR-DOS FAT12" },
166f41750abSHermès Bélusca-Maïto     { 0xC2, "Hidden Linux" },
167f41750abSHermès Bélusca-Maïto     { 0xC3, "Hidden Linux swap" },
168f41750abSHermès Bélusca-Maïto     { 0xC4, "DR-DOS FAT16 (< 32 MB)" },
169f41750abSHermès Bélusca-Maïto     { 0xC5, "DR-DOS Extended" },
170f41750abSHermès Bélusca-Maïto     { 0xC6, "DR-DOS FAT16" },
171f41750abSHermès Bélusca-Maïto     { 0xC7, "HPFS mirrored" },   // Alternatively, "Syrinx boot"
172f41750abSHermès Bélusca-Maïto     { 0xCB, "DR-DOS FAT32" },
173f41750abSHermès Bélusca-Maïto     { 0xCC, "DR-DOS FAT32 (LBA)" },
174f41750abSHermès Bélusca-Maïto     { 0xCE, "DR-DOS FAT16 (LBA)" },
175f41750abSHermès Bélusca-Maïto     { 0xD0, "MDOS" },
176f41750abSHermès Bélusca-Maïto     { 0xD1, "MDOS FAT12" },
177f41750abSHermès Bélusca-Maïto     { 0xD4, "MDOS FAT16 (< 32 MB)" },
178f41750abSHermès Bélusca-Maïto     { 0xD5, "MDOS Extended" },
179f41750abSHermès Bélusca-Maïto     { 0xD6, "MDOS FAT16" },
180f41750abSHermès Bélusca-Maïto     { 0xD8, "CP/M-86" },
181f41750abSHermès Bélusca-Maïto     { 0xDB, "Digital Research CP/M" },
182f41750abSHermès Bélusca-Maïto     { 0xDE, "Dell OEM" },
183f41750abSHermès Bélusca-Maïto     { 0xDF, "BootIt EMBRM (FAT16/32)" },
184f41750abSHermès Bélusca-Maïto     { 0xE1, "SpeedStor FAT12" },
185f41750abSHermès Bélusca-Maïto     { 0xE3, "SpeedStor (0xE3)" },
186f41750abSHermès Bélusca-Maïto     { 0xE4, "SpeedStor FAT16" },
187f41750abSHermès Bélusca-Maïto     { 0xE5, "Tandy MSDOS" },
188f41750abSHermès Bélusca-Maïto     { 0xE6, "SpeedStor (0xE6)" },
189f41750abSHermès Bélusca-Maïto     { 0xE8, "Linux Unified Key Setup partition" },
190f41750abSHermès Bélusca-Maïto     { 0xEA, "Rufus private partition" },
191f41750abSHermès Bélusca-Maïto     { 0xEB, "BeOS BFS" },
192f41750abSHermès Bélusca-Maïto     { 0xEC, "SkyOS SkyFS" },
193f41750abSHermès Bélusca-Maïto     { 0xEE, "EFI GPT protective" },
194f41750abSHermès Bélusca-Maïto     { 0xEF, "EFI System partition" },
195f41750abSHermès Bélusca-Maïto     { 0xF0, "Linux/PA-RISC boot loader" },
196f41750abSHermès Bélusca-Maïto     { 0xF1, "SpeedStor (0xF1)" },
197f41750abSHermès Bélusca-Maïto     { 0xF2, "DOS 3.3+ second" },
198f41750abSHermès Bélusca-Maïto     { 0xF4, "SpeedStor (0xF4)" },
199f41750abSHermès Bélusca-Maïto     { 0xF5, "SpeedStor (0xF5)" },
200f41750abSHermès Bélusca-Maïto     { 0xF6, "SpeedStor (0xF6)" },
201f41750abSHermès Bélusca-Maïto     { 0xFA, "Bochs" },
202f41750abSHermès Bélusca-Maïto     { 0xFB, "VMware FS" },
203f41750abSHermès Bélusca-Maïto     { 0xFC, "VMware swap" },
204f41750abSHermès Bélusca-Maïto     { 0xFD, "Linux RAID auto" },
205f41750abSHermès Bélusca-Maïto     { 0xFE, "NT hidden partition" },
206f41750abSHermès Bélusca-Maïto     { 0xFF, "XENIX Bad Block Table" },
207f41750abSHermès Bélusca-Maïto };
208f41750abSHermès Bélusca-Maïto 
209f41750abSHermès Bélusca-Maïto 
2106f19c83bSHermès Bélusca-Maïto /* FUNCTIONS ****************************************************************/
2116f19c83bSHermès Bélusca-Maïto 
2126f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
2136f19c83bSHermès Bélusca-Maïto static
2146f19c83bSHermès Bélusca-Maïto VOID
2156f19c83bSHermès Bélusca-Maïto DumpPartitionTable(
2166f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry)
2176f19c83bSHermès Bélusca-Maïto {
2186f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
2196f19c83bSHermès Bélusca-Maïto     ULONG i;
2206f19c83bSHermès Bélusca-Maïto 
2216f19c83bSHermès Bélusca-Maïto     DbgPrint("\n");
2226f19c83bSHermès Bélusca-Maïto     DbgPrint("Index  Start         Length        Hidden      Nr  Type  Boot  RW\n");
2236f19c83bSHermès Bélusca-Maïto     DbgPrint("-----  ------------  ------------  ----------  --  ----  ----  --\n");
2246f19c83bSHermès Bélusca-Maïto 
2256f19c83bSHermès Bélusca-Maïto     for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
2266f19c83bSHermès Bélusca-Maïto     {
2276f19c83bSHermès Bélusca-Maïto         PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i];
2286f19c83bSHermès Bélusca-Maïto         DbgPrint("  %3lu  %12I64u  %12I64u  %10lu  %2lu    %2x     %c   %c\n",
2296f19c83bSHermès Bélusca-Maïto                  i,
2306f19c83bSHermès Bélusca-Maïto                  PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector,
2316f19c83bSHermès Bélusca-Maïto                  PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector,
2326f19c83bSHermès Bélusca-Maïto                  PartitionInfo->HiddenSectors,
2336f19c83bSHermès Bélusca-Maïto                  PartitionInfo->PartitionNumber,
2346f19c83bSHermès Bélusca-Maïto                  PartitionInfo->PartitionType,
2356f19c83bSHermès Bélusca-Maïto                  PartitionInfo->BootIndicator ? '*': ' ',
2366f19c83bSHermès Bélusca-Maïto                  PartitionInfo->RewritePartition ? 'Y': 'N');
2376f19c83bSHermès Bélusca-Maïto     }
2386f19c83bSHermès Bélusca-Maïto 
2396f19c83bSHermès Bélusca-Maïto     DbgPrint("\n");
2406f19c83bSHermès Bélusca-Maïto }
2416f19c83bSHermès Bélusca-Maïto #endif
2426f19c83bSHermès Bélusca-Maïto 
2436f19c83bSHermès Bélusca-Maïto 
2446f19c83bSHermès Bélusca-Maïto ULONGLONG
2456f19c83bSHermès Bélusca-Maïto AlignDown(
2466f19c83bSHermès Bélusca-Maïto     IN ULONGLONG Value,
2476f19c83bSHermès Bélusca-Maïto     IN ULONG Alignment)
2486f19c83bSHermès Bélusca-Maïto {
2496f19c83bSHermès Bélusca-Maïto     ULONGLONG Temp;
2506f19c83bSHermès Bélusca-Maïto 
2516f19c83bSHermès Bélusca-Maïto     Temp = Value / Alignment;
2526f19c83bSHermès Bélusca-Maïto 
2536f19c83bSHermès Bélusca-Maïto     return Temp * Alignment;
2546f19c83bSHermès Bélusca-Maïto }
2556f19c83bSHermès Bélusca-Maïto 
2566f19c83bSHermès Bélusca-Maïto ULONGLONG
2576f19c83bSHermès Bélusca-Maïto AlignUp(
2586f19c83bSHermès Bélusca-Maïto     IN ULONGLONG Value,
2596f19c83bSHermès Bélusca-Maïto     IN ULONG Alignment)
2606f19c83bSHermès Bélusca-Maïto {
2616f19c83bSHermès Bélusca-Maïto     ULONGLONG Temp, Result;
2626f19c83bSHermès Bélusca-Maïto 
2636f19c83bSHermès Bélusca-Maïto     Temp = Value / Alignment;
2646f19c83bSHermès Bélusca-Maïto 
2656f19c83bSHermès Bélusca-Maïto     Result = Temp * Alignment;
2666f19c83bSHermès Bélusca-Maïto     if (Value % Alignment)
2676f19c83bSHermès Bélusca-Maïto         Result += Alignment;
2686f19c83bSHermès Bélusca-Maïto 
2696f19c83bSHermès Bélusca-Maïto     return Result;
2706f19c83bSHermès Bélusca-Maïto }
2716f19c83bSHermès Bélusca-Maïto 
2726f19c83bSHermès Bélusca-Maïto ULONGLONG
2736f19c83bSHermès Bélusca-Maïto RoundingDivide(
2746f19c83bSHermès Bélusca-Maïto    IN ULONGLONG Dividend,
2756f19c83bSHermès Bélusca-Maïto    IN ULONGLONG Divisor)
2766f19c83bSHermès Bélusca-Maïto {
2776f19c83bSHermès Bélusca-Maïto     return (Dividend + Divisor / 2) / Divisor;
2786f19c83bSHermès Bélusca-Maïto }
2796f19c83bSHermès Bélusca-Maïto 
2806f19c83bSHermès Bélusca-Maïto 
2816f19c83bSHermès Bélusca-Maïto static
2826f19c83bSHermès Bélusca-Maïto VOID
2836f19c83bSHermès Bélusca-Maïto GetDriverName(
2846f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
2856f19c83bSHermès Bélusca-Maïto {
2866f19c83bSHermès Bélusca-Maïto     RTL_QUERY_REGISTRY_TABLE QueryTable[2];
2876f19c83bSHermès Bélusca-Maïto     WCHAR KeyName[32];
2886f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
2896f19c83bSHermès Bélusca-Maïto 
2906f19c83bSHermès Bélusca-Maïto     RtlInitUnicodeString(&DiskEntry->DriverName, NULL);
2916f19c83bSHermès Bélusca-Maïto 
2926f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(KeyName, ARRAYSIZE(KeyName),
2936f19c83bSHermès Bélusca-Maïto                         L"\\Scsi\\Scsi Port %hu",
2946f19c83bSHermès Bélusca-Maïto                         DiskEntry->Port);
2956f19c83bSHermès Bélusca-Maïto 
2966f19c83bSHermès Bélusca-Maïto     RtlZeroMemory(&QueryTable, sizeof(QueryTable));
2976f19c83bSHermès Bélusca-Maïto 
2986f19c83bSHermès Bélusca-Maïto     QueryTable[0].Name = L"Driver";
2996f19c83bSHermès Bélusca-Maïto     QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
3006f19c83bSHermès Bélusca-Maïto     QueryTable[0].EntryContext = &DiskEntry->DriverName;
3016f19c83bSHermès Bélusca-Maïto 
302f41750abSHermès Bélusca-Maïto     /* This will allocate DiskEntry->DriverName if needed */
3036f19c83bSHermès Bélusca-Maïto     Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
3046f19c83bSHermès Bélusca-Maïto                                     KeyName,
3056f19c83bSHermès Bélusca-Maïto                                     QueryTable,
3066f19c83bSHermès Bélusca-Maïto                                     NULL,
3076f19c83bSHermès Bélusca-Maïto                                     NULL);
3086f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
3096f19c83bSHermès Bélusca-Maïto     {
3106f19c83bSHermès Bélusca-Maïto         DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
3116f19c83bSHermès Bélusca-Maïto     }
3126f19c83bSHermès Bélusca-Maïto }
3136f19c83bSHermès Bélusca-Maïto 
3146f19c83bSHermès Bélusca-Maïto static
3156f19c83bSHermès Bélusca-Maïto VOID
3166f19c83bSHermès Bélusca-Maïto AssignDriveLetters(
3176f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
3186f19c83bSHermès Bélusca-Maïto {
3196f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
3206f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
3216f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1;
3226f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry2;
323f41750abSHermès Bélusca-Maïto     WCHAR Letter;
3246f19c83bSHermès Bélusca-Maïto 
325f41750abSHermès Bélusca-Maïto     Letter = L'C';
3266f19c83bSHermès Bélusca-Maïto 
3276f19c83bSHermès Bélusca-Maïto     /* Assign drive letters to primary partitions */
3288bed4adfSHermès Bélusca-Maïto     for (Entry1 = List->DiskListHead.Flink;
3298bed4adfSHermès Bélusca-Maïto          Entry1 != &List->DiskListHead;
3308bed4adfSHermès Bélusca-Maïto          Entry1 = Entry1->Flink)
3316f19c83bSHermès Bélusca-Maïto     {
3326f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
3336f19c83bSHermès Bélusca-Maïto 
3348bed4adfSHermès Bélusca-Maïto         for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
3358bed4adfSHermès Bélusca-Maïto              Entry2 != &DiskEntry->PrimaryPartListHead;
3368bed4adfSHermès Bélusca-Maïto              Entry2 = Entry2->Flink)
3376f19c83bSHermès Bélusca-Maïto         {
3386f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3396f19c83bSHermès Bélusca-Maïto 
3406f19c83bSHermès Bélusca-Maïto             PartEntry->DriveLetter = 0;
3416f19c83bSHermès Bélusca-Maïto 
3426f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned &&
3436f19c83bSHermès Bélusca-Maïto                 !IsContainerPartition(PartEntry->PartitionType))
3446f19c83bSHermès Bélusca-Maïto             {
34529cc1843SHermès Bélusca-Maïto                 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
34629cc1843SHermès Bélusca-Maïto 
3476f19c83bSHermès Bélusca-Maïto                 if (IsRecognizedPartition(PartEntry->PartitionType) ||
34829cc1843SHermès Bélusca-Maïto                     PartEntry->SectorCount.QuadPart != 0LL)
3496f19c83bSHermès Bélusca-Maïto                 {
350f41750abSHermès Bélusca-Maïto                     if (Letter <= L'Z')
3516f19c83bSHermès Bélusca-Maïto                     {
3526f19c83bSHermès Bélusca-Maïto                         PartEntry->DriveLetter = Letter;
3536f19c83bSHermès Bélusca-Maïto                         Letter++;
3546f19c83bSHermès Bélusca-Maïto                     }
3556f19c83bSHermès Bélusca-Maïto                 }
3566f19c83bSHermès Bélusca-Maïto             }
3576f19c83bSHermès Bélusca-Maïto         }
3586f19c83bSHermès Bélusca-Maïto     }
3596f19c83bSHermès Bélusca-Maïto 
3606f19c83bSHermès Bélusca-Maïto     /* Assign drive letters to logical drives */
3618bed4adfSHermès Bélusca-Maïto     for (Entry1 = List->DiskListHead.Flink;
3628bed4adfSHermès Bélusca-Maïto          Entry1 != &List->DiskListHead;
3638bed4adfSHermès Bélusca-Maïto          Entry1 = Entry1->Flink)
3646f19c83bSHermès Bélusca-Maïto     {
3656f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
3666f19c83bSHermès Bélusca-Maïto 
3678bed4adfSHermès Bélusca-Maïto         for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
3688bed4adfSHermès Bélusca-Maïto              Entry2 != &DiskEntry->LogicalPartListHead;
3698bed4adfSHermès Bélusca-Maïto              Entry2 = Entry2->Flink)
3706f19c83bSHermès Bélusca-Maïto         {
3716f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3726f19c83bSHermès Bélusca-Maïto 
3736f19c83bSHermès Bélusca-Maïto             PartEntry->DriveLetter = 0;
3746f19c83bSHermès Bélusca-Maïto 
3756f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned)
3766f19c83bSHermès Bélusca-Maïto             {
37729cc1843SHermès Bélusca-Maïto                 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
37829cc1843SHermès Bélusca-Maïto 
3796f19c83bSHermès Bélusca-Maïto                 if (IsRecognizedPartition(PartEntry->PartitionType) ||
38029cc1843SHermès Bélusca-Maïto                     PartEntry->SectorCount.QuadPart != 0LL)
3816f19c83bSHermès Bélusca-Maïto                 {
382f41750abSHermès Bélusca-Maïto                     if (Letter <= L'Z')
3836f19c83bSHermès Bélusca-Maïto                     {
3846f19c83bSHermès Bélusca-Maïto                         PartEntry->DriveLetter = Letter;
3856f19c83bSHermès Bélusca-Maïto                         Letter++;
3866f19c83bSHermès Bélusca-Maïto                     }
3876f19c83bSHermès Bélusca-Maïto                 }
3886f19c83bSHermès Bélusca-Maïto             }
3896f19c83bSHermès Bélusca-Maïto         }
3906f19c83bSHermès Bélusca-Maïto     }
3916f19c83bSHermès Bélusca-Maïto }
3926f19c83bSHermès Bélusca-Maïto 
3936f19c83bSHermès Bélusca-Maïto static NTSTATUS
3946f19c83bSHermès Bélusca-Maïto NTAPI
3956f19c83bSHermès Bélusca-Maïto DiskIdentifierQueryRoutine(
3966f19c83bSHermès Bélusca-Maïto     PWSTR ValueName,
3976f19c83bSHermès Bélusca-Maïto     ULONG ValueType,
3986f19c83bSHermès Bélusca-Maïto     PVOID ValueData,
3996f19c83bSHermès Bélusca-Maïto     ULONG ValueLength,
4006f19c83bSHermès Bélusca-Maïto     PVOID Context,
4016f19c83bSHermès Bélusca-Maïto     PVOID EntryContext)
4026f19c83bSHermès Bélusca-Maïto {
4036f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
4046f19c83bSHermès Bélusca-Maïto     UNICODE_STRING NameU;
4056f19c83bSHermès Bélusca-Maïto 
4066f19c83bSHermès Bélusca-Maïto     if (ValueType == REG_SZ &&
4076f19c83bSHermès Bélusca-Maïto         ValueLength == 20 * sizeof(WCHAR))
4086f19c83bSHermès Bélusca-Maïto     {
4096f19c83bSHermès Bélusca-Maïto         NameU.Buffer = (PWCHAR)ValueData;
4106f19c83bSHermès Bélusca-Maïto         NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
4116f19c83bSHermès Bélusca-Maïto         RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
4126f19c83bSHermès Bélusca-Maïto 
4136f19c83bSHermès Bélusca-Maïto         NameU.Buffer = (PWCHAR)ValueData + 9;
4146f19c83bSHermès Bélusca-Maïto         RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
4156f19c83bSHermès Bélusca-Maïto 
4166f19c83bSHermès Bélusca-Maïto         return STATUS_SUCCESS;
4176f19c83bSHermès Bélusca-Maïto     }
4186f19c83bSHermès Bélusca-Maïto 
4196f19c83bSHermès Bélusca-Maïto     return STATUS_UNSUCCESSFUL;
4206f19c83bSHermès Bélusca-Maïto }
4216f19c83bSHermès Bélusca-Maïto 
4226f19c83bSHermès Bélusca-Maïto static NTSTATUS
4236f19c83bSHermès Bélusca-Maïto NTAPI
4246f19c83bSHermès Bélusca-Maïto DiskConfigurationDataQueryRoutine(
4256f19c83bSHermès Bélusca-Maïto     PWSTR ValueName,
4266f19c83bSHermès Bélusca-Maïto     ULONG ValueType,
4276f19c83bSHermès Bélusca-Maïto     PVOID ValueData,
4286f19c83bSHermès Bélusca-Maïto     ULONG ValueLength,
4296f19c83bSHermès Bélusca-Maïto     PVOID Context,
4306f19c83bSHermès Bélusca-Maïto     PVOID EntryContext)
4316f19c83bSHermès Bélusca-Maïto {
4326f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
4336f19c83bSHermès Bélusca-Maïto     PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
4346f19c83bSHermès Bélusca-Maïto     PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
4356f19c83bSHermès Bélusca-Maïto     ULONG i;
4366f19c83bSHermès Bélusca-Maïto 
4376f19c83bSHermès Bélusca-Maïto     if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
4386f19c83bSHermès Bélusca-Maïto         ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
4396f19c83bSHermès Bélusca-Maïto         return STATUS_UNSUCCESSFUL;
4406f19c83bSHermès Bélusca-Maïto 
4416f19c83bSHermès Bélusca-Maïto     FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
4426f19c83bSHermès Bélusca-Maïto 
4436f19c83bSHermès Bélusca-Maïto     /* Hm. Version and Revision are not set on Microsoft Windows XP... */
4446f19c83bSHermès Bélusca-Maïto #if 0
4456f19c83bSHermès Bélusca-Maïto     if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
4466f19c83bSHermès Bélusca-Maïto         FullResourceDescriptor->PartialResourceList.Revision != 1)
4476f19c83bSHermès Bélusca-Maïto         return STATUS_UNSUCCESSFUL;
4486f19c83bSHermès Bélusca-Maïto #endif
4496f19c83bSHermès Bélusca-Maïto 
4506f19c83bSHermès Bélusca-Maïto     for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
4516f19c83bSHermès Bélusca-Maïto     {
4526f19c83bSHermès Bélusca-Maïto         if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
4536f19c83bSHermès Bélusca-Maïto             FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
4546f19c83bSHermès Bélusca-Maïto             continue;
4556f19c83bSHermès Bélusca-Maïto 
4566f19c83bSHermès Bélusca-Maïto         DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
4576f19c83bSHermès Bélusca-Maïto         BiosDiskEntry->DiskGeometry = *DiskGeometry;
4586f19c83bSHermès Bélusca-Maïto 
4596f19c83bSHermès Bélusca-Maïto         return STATUS_SUCCESS;
4606f19c83bSHermès Bélusca-Maïto     }
4616f19c83bSHermès Bélusca-Maïto 
4626f19c83bSHermès Bélusca-Maïto     return STATUS_UNSUCCESSFUL;
4636f19c83bSHermès Bélusca-Maïto }
4646f19c83bSHermès Bélusca-Maïto 
4656f19c83bSHermès Bélusca-Maïto static NTSTATUS
4666f19c83bSHermès Bélusca-Maïto NTAPI
4676f19c83bSHermès Bélusca-Maïto SystemConfigurationDataQueryRoutine(
4686f19c83bSHermès Bélusca-Maïto     PWSTR ValueName,
4696f19c83bSHermès Bélusca-Maïto     ULONG ValueType,
4706f19c83bSHermès Bélusca-Maïto     PVOID ValueData,
4716f19c83bSHermès Bélusca-Maïto     ULONG ValueLength,
4726f19c83bSHermès Bélusca-Maïto     PVOID Context,
4736f19c83bSHermès Bélusca-Maïto     PVOID EntryContext)
4746f19c83bSHermès Bélusca-Maïto {
4756f19c83bSHermès Bélusca-Maïto     PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
4766f19c83bSHermès Bélusca-Maïto     PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context;
4776f19c83bSHermès Bélusca-Maïto     ULONG i;
4786f19c83bSHermès Bélusca-Maïto 
4796f19c83bSHermès Bélusca-Maïto     if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
4806f19c83bSHermès Bélusca-Maïto         ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
4816f19c83bSHermès Bélusca-Maïto         return STATUS_UNSUCCESSFUL;
4826f19c83bSHermès Bélusca-Maïto 
4836f19c83bSHermès Bélusca-Maïto     FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
4846f19c83bSHermès Bélusca-Maïto 
4856f19c83bSHermès Bélusca-Maïto     /* Hm. Version and Revision are not set on Microsoft Windows XP... */
4866f19c83bSHermès Bélusca-Maïto #if 0
4876f19c83bSHermès Bélusca-Maïto     if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
4886f19c83bSHermès Bélusca-Maïto         FullResourceDescriptor->PartialResourceList.Revision != 1)
4896f19c83bSHermès Bélusca-Maïto         return STATUS_UNSUCCESSFUL;
4906f19c83bSHermès Bélusca-Maïto #endif
4916f19c83bSHermès Bélusca-Maïto 
4926f19c83bSHermès Bélusca-Maïto     for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
4936f19c83bSHermès Bélusca-Maïto     {
4946f19c83bSHermès Bélusca-Maïto         if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
4956f19c83bSHermès Bélusca-Maïto             FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
4966f19c83bSHermès Bélusca-Maïto             continue;
4976f19c83bSHermès Bélusca-Maïto 
4986f19c83bSHermès Bélusca-Maïto         *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(ProcessHeap, 0,
4996f19c83bSHermès Bélusca-Maïto                        FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
5006f19c83bSHermès Bélusca-Maïto         if (*Int13Drives == NULL)
5016f19c83bSHermès Bélusca-Maïto             return STATUS_NO_MEMORY;
5026f19c83bSHermès Bélusca-Maïto 
5036f19c83bSHermès Bélusca-Maïto         memcpy(*Int13Drives,
5046f19c83bSHermès Bélusca-Maïto                &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
5056f19c83bSHermès Bélusca-Maïto                FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
5066f19c83bSHermès Bélusca-Maïto         return STATUS_SUCCESS;
5076f19c83bSHermès Bélusca-Maïto     }
5086f19c83bSHermès Bélusca-Maïto 
5096f19c83bSHermès Bélusca-Maïto     return STATUS_UNSUCCESSFUL;
5106f19c83bSHermès Bélusca-Maïto }
5116f19c83bSHermès Bélusca-Maïto 
5126f19c83bSHermès Bélusca-Maïto 
5136f19c83bSHermès Bélusca-Maïto static VOID
5146f19c83bSHermès Bélusca-Maïto EnumerateBiosDiskEntries(
5156f19c83bSHermès Bélusca-Maïto     IN PPARTLIST PartList)
5166f19c83bSHermès Bélusca-Maïto {
5176f19c83bSHermès Bélusca-Maïto     RTL_QUERY_REGISTRY_TABLE QueryTable[3];
5186f19c83bSHermès Bélusca-Maïto     WCHAR Name[120];
5196f19c83bSHermès Bélusca-Maïto     ULONG AdapterCount;
5206f19c83bSHermès Bélusca-Maïto     ULONG DiskCount;
5216f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
5226f19c83bSHermès Bélusca-Maïto     PCM_INT13_DRIVE_PARAMETER Int13Drives;
5236f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry;
5246f19c83bSHermès Bélusca-Maïto 
525f41750abSHermès Bélusca-Maïto #define ROOT_NAME   L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
526f41750abSHermès Bélusca-Maïto 
5276f19c83bSHermès Bélusca-Maïto     memset(QueryTable, 0, sizeof(QueryTable));
5286f19c83bSHermès Bélusca-Maïto 
5296f19c83bSHermès Bélusca-Maïto     QueryTable[1].Name = L"Configuration Data";
5306f19c83bSHermès Bélusca-Maïto     QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
5316f19c83bSHermès Bélusca-Maïto     Int13Drives = NULL;
5326f19c83bSHermès Bélusca-Maïto     Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5336f19c83bSHermès Bélusca-Maïto                                     L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
5346f19c83bSHermès Bélusca-Maïto                                     &QueryTable[1],
5356f19c83bSHermès Bélusca-Maïto                                     (PVOID)&Int13Drives,
5366f19c83bSHermès Bélusca-Maïto                                     NULL);
5376f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
5386f19c83bSHermès Bélusca-Maïto     {
5396f19c83bSHermès Bélusca-Maïto         DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
5406f19c83bSHermès Bélusca-Maïto         return;
5416f19c83bSHermès Bélusca-Maïto     }
5426f19c83bSHermès Bélusca-Maïto 
5436f19c83bSHermès Bélusca-Maïto     AdapterCount = 0;
5446f19c83bSHermès Bélusca-Maïto     while (TRUE)
5456f19c83bSHermès Bélusca-Maïto     {
5466f19c83bSHermès Bélusca-Maïto         RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
5476f19c83bSHermès Bélusca-Maïto                             L"%s\\%lu",
5486f19c83bSHermès Bélusca-Maïto                             ROOT_NAME, AdapterCount);
5496f19c83bSHermès Bélusca-Maïto         Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5506f19c83bSHermès Bélusca-Maïto                                         Name,
5516f19c83bSHermès Bélusca-Maïto                                         &QueryTable[2],
5526f19c83bSHermès Bélusca-Maïto                                         NULL,
5536f19c83bSHermès Bélusca-Maïto                                         NULL);
5546f19c83bSHermès Bélusca-Maïto         if (!NT_SUCCESS(Status))
5556f19c83bSHermès Bélusca-Maïto         {
5566f19c83bSHermès Bélusca-Maïto             break;
5576f19c83bSHermès Bélusca-Maïto         }
5586f19c83bSHermès Bélusca-Maïto 
5596f19c83bSHermès Bélusca-Maïto         RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
5606f19c83bSHermès Bélusca-Maïto                             L"%s\\%lu\\DiskController",
5616f19c83bSHermès Bélusca-Maïto                             ROOT_NAME, AdapterCount);
5626f19c83bSHermès Bélusca-Maïto         Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5636f19c83bSHermès Bélusca-Maïto                                         Name,
5646f19c83bSHermès Bélusca-Maïto                                         &QueryTable[2],
5656f19c83bSHermès Bélusca-Maïto                                         NULL,
5666f19c83bSHermès Bélusca-Maïto                                         NULL);
5676f19c83bSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
5686f19c83bSHermès Bélusca-Maïto         {
5696f19c83bSHermès Bélusca-Maïto             while (TRUE)
5706f19c83bSHermès Bélusca-Maïto             {
5716f19c83bSHermès Bélusca-Maïto                 RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
5726f19c83bSHermès Bélusca-Maïto                                     L"%s\\%lu\\DiskController\\0",
5736f19c83bSHermès Bélusca-Maïto                                     ROOT_NAME, AdapterCount);
5746f19c83bSHermès Bélusca-Maïto                 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5756f19c83bSHermès Bélusca-Maïto                                                 Name,
5766f19c83bSHermès Bélusca-Maïto                                                 &QueryTable[2],
5776f19c83bSHermès Bélusca-Maïto                                                 NULL,
5786f19c83bSHermès Bélusca-Maïto                                                 NULL);
5796f19c83bSHermès Bélusca-Maïto                 if (!NT_SUCCESS(Status))
5806f19c83bSHermès Bélusca-Maïto                 {
5816f19c83bSHermès Bélusca-Maïto                     RtlFreeHeap(ProcessHeap, 0, Int13Drives);
5826f19c83bSHermès Bélusca-Maïto                     return;
5836f19c83bSHermès Bélusca-Maïto                 }
5846f19c83bSHermès Bélusca-Maïto 
5856f19c83bSHermès Bélusca-Maïto                 RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
5866f19c83bSHermès Bélusca-Maïto                                     L"%s\\%lu\\DiskController\\0\\DiskPeripheral",
5876f19c83bSHermès Bélusca-Maïto                                     ROOT_NAME, AdapterCount);
5886f19c83bSHermès Bélusca-Maïto                 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5896f19c83bSHermès Bélusca-Maïto                                                 Name,
5906f19c83bSHermès Bélusca-Maïto                                                 &QueryTable[2],
5916f19c83bSHermès Bélusca-Maïto                                                 NULL,
5926f19c83bSHermès Bélusca-Maïto                                                 NULL);
5936f19c83bSHermès Bélusca-Maïto                 if (NT_SUCCESS(Status))
5946f19c83bSHermès Bélusca-Maïto                 {
5956f19c83bSHermès Bélusca-Maïto                     QueryTable[0].Name = L"Identifier";
5966f19c83bSHermès Bélusca-Maïto                     QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
5976f19c83bSHermès Bélusca-Maïto                     QueryTable[1].Name = L"Configuration Data";
5986f19c83bSHermès Bélusca-Maïto                     QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;
5996f19c83bSHermès Bélusca-Maïto 
6006f19c83bSHermès Bélusca-Maïto                     DiskCount = 0;
6016f19c83bSHermès Bélusca-Maïto                     while (TRUE)
6026f19c83bSHermès Bélusca-Maïto                     {
6036f19c83bSHermès Bélusca-Maïto                         BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
6046f19c83bSHermès Bélusca-Maïto                         if (BiosDiskEntry == NULL)
6056f19c83bSHermès Bélusca-Maïto                         {
6066f19c83bSHermès Bélusca-Maïto                             break;
6076f19c83bSHermès Bélusca-Maïto                         }
6086f19c83bSHermès Bélusca-Maïto 
6096f19c83bSHermès Bélusca-Maïto                         RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
6106f19c83bSHermès Bélusca-Maïto                                             L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu",
6116f19c83bSHermès Bélusca-Maïto                                             ROOT_NAME, AdapterCount, DiskCount);
6126f19c83bSHermès Bélusca-Maïto                         Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
6136f19c83bSHermès Bélusca-Maïto                                                         Name,
6146f19c83bSHermès Bélusca-Maïto                                                         QueryTable,
6156f19c83bSHermès Bélusca-Maïto                                                         (PVOID)BiosDiskEntry,
6166f19c83bSHermès Bélusca-Maïto                                                         NULL);
6176f19c83bSHermès Bélusca-Maïto                         if (!NT_SUCCESS(Status))
6186f19c83bSHermès Bélusca-Maïto                         {
6196f19c83bSHermès Bélusca-Maïto                             RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
6206f19c83bSHermès Bélusca-Maïto                             break;
6216f19c83bSHermès Bélusca-Maïto                         }
6226f19c83bSHermès Bélusca-Maïto 
6236f19c83bSHermès Bélusca-Maïto                         BiosDiskEntry->DiskNumber = DiskCount;
6246f19c83bSHermès Bélusca-Maïto                         BiosDiskEntry->Recognized = FALSE;
6256f19c83bSHermès Bélusca-Maïto 
6266f19c83bSHermès Bélusca-Maïto                         if (DiskCount < Int13Drives[0].NumberDrives)
6276f19c83bSHermès Bélusca-Maïto                         {
6286f19c83bSHermès Bélusca-Maïto                             BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
6296f19c83bSHermès Bélusca-Maïto                         }
6306f19c83bSHermès Bélusca-Maïto                         else
6316f19c83bSHermès Bélusca-Maïto                         {
6326f19c83bSHermès Bélusca-Maïto                             DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
6336f19c83bSHermès Bélusca-Maïto                         }
6346f19c83bSHermès Bélusca-Maïto 
6356f19c83bSHermès Bélusca-Maïto                         InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);
6366f19c83bSHermès Bélusca-Maïto 
6376f19c83bSHermès Bélusca-Maïto                         DPRINT("DiskNumber:        %lu\n", BiosDiskEntry->DiskNumber);
6386f19c83bSHermès Bélusca-Maïto                         DPRINT("Signature:         %08lx\n", BiosDiskEntry->Signature);
6396f19c83bSHermès Bélusca-Maïto                         DPRINT("Checksum:          %08lx\n", BiosDiskEntry->Checksum);
6406f19c83bSHermès Bélusca-Maïto                         DPRINT("BytesPerSector:    %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
6416f19c83bSHermès Bélusca-Maïto                         DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
6426f19c83bSHermès Bélusca-Maïto                         DPRINT("NumberOfHeads:     %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
6436f19c83bSHermès Bélusca-Maïto                         DPRINT("DriveSelect:       %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
6446f19c83bSHermès Bélusca-Maïto                         DPRINT("MaxCylinders:      %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
6456f19c83bSHermès Bélusca-Maïto                         DPRINT("SectorsPerTrack:   %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
6466f19c83bSHermès Bélusca-Maïto                         DPRINT("MaxHeads:          %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
6476f19c83bSHermès Bélusca-Maïto                         DPRINT("NumberDrives:      %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
6486f19c83bSHermès Bélusca-Maïto 
6496f19c83bSHermès Bélusca-Maïto                         DiskCount++;
6506f19c83bSHermès Bélusca-Maïto                     }
6516f19c83bSHermès Bélusca-Maïto                 }
6526f19c83bSHermès Bélusca-Maïto 
6536f19c83bSHermès Bélusca-Maïto                 RtlFreeHeap(ProcessHeap, 0, Int13Drives);
6546f19c83bSHermès Bélusca-Maïto                 return;
6556f19c83bSHermès Bélusca-Maïto             }
6566f19c83bSHermès Bélusca-Maïto         }
6576f19c83bSHermès Bélusca-Maïto 
6586f19c83bSHermès Bélusca-Maïto         AdapterCount++;
6596f19c83bSHermès Bélusca-Maïto     }
6606f19c83bSHermès Bélusca-Maïto 
6616f19c83bSHermès Bélusca-Maïto     RtlFreeHeap(ProcessHeap, 0, Int13Drives);
662f41750abSHermès Bélusca-Maïto 
663f41750abSHermès Bélusca-Maïto #undef ROOT_NAME
6646f19c83bSHermès Bélusca-Maïto }
6656f19c83bSHermès Bélusca-Maïto 
6667df92966SHermès Bélusca-Maïto 
6677df92966SHermès Bélusca-Maïto 
6687df92966SHermès Bélusca-Maïto /*
6697df92966SHermès Bélusca-Maïto  * Inserts the disk region represented by PartEntry into either the primary
6707df92966SHermès Bélusca-Maïto  * or the logical partition list of the given disk.
6717df92966SHermès Bélusca-Maïto  * The lists are kept sorted by increasing order of start sectors.
6727df92966SHermès Bélusca-Maïto  * Of course no disk region should overlap at all with one another.
6737df92966SHermès Bélusca-Maïto  */
6747df92966SHermès Bélusca-Maïto static
6757df92966SHermès Bélusca-Maïto VOID
6767df92966SHermès Bélusca-Maïto InsertDiskRegion(
6777df92966SHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
6787df92966SHermès Bélusca-Maïto     IN PPARTENTRY PartEntry,
6797df92966SHermès Bélusca-Maïto     IN BOOLEAN LogicalPartition)
6807df92966SHermès Bélusca-Maïto {
6817df92966SHermès Bélusca-Maïto     PLIST_ENTRY List;
6827df92966SHermès Bélusca-Maïto     PLIST_ENTRY Entry;
6837df92966SHermès Bélusca-Maïto     PPARTENTRY PartEntry2;
6847df92966SHermès Bélusca-Maïto 
6857df92966SHermès Bélusca-Maïto     /* Use the correct partition list */
6867df92966SHermès Bélusca-Maïto     if (LogicalPartition)
6877df92966SHermès Bélusca-Maïto         List = &DiskEntry->LogicalPartListHead;
6887df92966SHermès Bélusca-Maïto     else
6897df92966SHermès Bélusca-Maïto         List = &DiskEntry->PrimaryPartListHead;
6907df92966SHermès Bélusca-Maïto 
6917df92966SHermès Bélusca-Maïto     /* Find the first disk region before which we need to insert the new one */
6927df92966SHermès Bélusca-Maïto     for (Entry = List->Flink; Entry != List; Entry = Entry->Flink)
6937df92966SHermès Bélusca-Maïto     {
6947df92966SHermès Bélusca-Maïto         PartEntry2 = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
6957df92966SHermès Bélusca-Maïto 
6967df92966SHermès Bélusca-Maïto         /* Ignore any unused empty region */
6977df92966SHermès Bélusca-Maïto         if ((PartEntry2->PartitionType == PARTITION_ENTRY_UNUSED &&
6987df92966SHermès Bélusca-Maïto              PartEntry2->StartSector.QuadPart == 0) || PartEntry2->SectorCount.QuadPart == 0)
6997df92966SHermès Bélusca-Maïto         {
7007df92966SHermès Bélusca-Maïto             continue;
7017df92966SHermès Bélusca-Maïto         }
7027df92966SHermès Bélusca-Maïto 
7037df92966SHermès Bélusca-Maïto         /* If the current region ends before the one to be inserted, try again */
7047df92966SHermès Bélusca-Maïto         if (PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1 < PartEntry->StartSector.QuadPart)
7057df92966SHermès Bélusca-Maïto             continue;
7067df92966SHermès Bélusca-Maïto 
7077df92966SHermès Bélusca-Maïto         /*
7087df92966SHermès Bélusca-Maïto          * One of the disk region boundaries crosses the desired region
7097df92966SHermès Bélusca-Maïto          * (it starts after the desired region, or ends before the end
7107df92966SHermès Bélusca-Maïto          * of the desired region): this is an impossible situation because
7117df92966SHermès Bélusca-Maïto          * disk regions (partitions) cannot overlap!
7127df92966SHermès Bélusca-Maïto          * Throw an error and bail out.
7137df92966SHermès Bélusca-Maïto          */
7147df92966SHermès Bélusca-Maïto         if (max(PartEntry->StartSector.QuadPart, PartEntry2->StartSector.QuadPart)
7157df92966SHermès Bélusca-Maïto             <=
7167df92966SHermès Bélusca-Maïto             min( PartEntry->StartSector.QuadPart +  PartEntry->SectorCount.QuadPart - 1,
7177df92966SHermès Bélusca-Maïto                 PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1))
7187df92966SHermès Bélusca-Maïto         {
7197df92966SHermès Bélusca-Maïto             DPRINT1("Disk region overlap problem, stopping there!\n"
7207df92966SHermès Bélusca-Maïto                     "Partition to be inserted:\n"
7217df92966SHermès Bélusca-Maïto                     "    StartSector = %I64u ; EndSector = %I64u\n"
7227df92966SHermès Bélusca-Maïto                     "Existing disk region:\n"
7237df92966SHermès Bélusca-Maïto                     "    StartSector = %I64u ; EndSector = %I64u\n",
7247df92966SHermès Bélusca-Maïto                      PartEntry->StartSector.QuadPart,
7257df92966SHermès Bélusca-Maïto                      PartEntry->StartSector.QuadPart +  PartEntry->SectorCount.QuadPart - 1,
7267df92966SHermès Bélusca-Maïto                     PartEntry2->StartSector.QuadPart,
7277df92966SHermès Bélusca-Maïto                     PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1);
7287df92966SHermès Bélusca-Maïto             return;
7297df92966SHermès Bélusca-Maïto         }
7307df92966SHermès Bélusca-Maïto 
7317df92966SHermès Bélusca-Maïto         /* We have found the first region before which the new one has to be inserted */
7327df92966SHermès Bélusca-Maïto         break;
7337df92966SHermès Bélusca-Maïto     }
7347df92966SHermès Bélusca-Maïto 
7357df92966SHermès Bélusca-Maïto     /* Insert the disk region */
7367df92966SHermès Bélusca-Maïto     InsertTailList(Entry, &PartEntry->ListEntry);
7377df92966SHermès Bélusca-Maïto }
7387df92966SHermès Bélusca-Maïto 
7397df92966SHermès Bélusca-Maïto static
7407df92966SHermès Bélusca-Maïto PPARTENTRY
7417df92966SHermès Bélusca-Maïto CreateInsertBlankRegion(
7427df92966SHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
7437df92966SHermès Bélusca-Maïto     IN OUT PLIST_ENTRY ListHead,
7447df92966SHermès Bélusca-Maïto     IN ULONGLONG StartSector,
7457df92966SHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
7467df92966SHermès Bélusca-Maïto     IN BOOLEAN LogicalSpace)
7477df92966SHermès Bélusca-Maïto {
7487df92966SHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
7497df92966SHermès Bélusca-Maïto 
7507df92966SHermès Bélusca-Maïto     NewPartEntry = RtlAllocateHeap(ProcessHeap,
7517df92966SHermès Bélusca-Maïto                                    HEAP_ZERO_MEMORY,
7527df92966SHermès Bélusca-Maïto                                    sizeof(PARTENTRY));
7537df92966SHermès Bélusca-Maïto     if (NewPartEntry == NULL)
7547df92966SHermès Bélusca-Maïto         return NULL;
7557df92966SHermès Bélusca-Maïto 
7567df92966SHermès Bélusca-Maïto     NewPartEntry->DiskEntry = DiskEntry;
7577df92966SHermès Bélusca-Maïto 
7587df92966SHermès Bélusca-Maïto     NewPartEntry->StartSector.QuadPart = StartSector;
7597df92966SHermès Bélusca-Maïto     NewPartEntry->SectorCount.QuadPart = SectorCount;
7607df92966SHermès Bélusca-Maïto 
761c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->IsPartitioned = FALSE;
762c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
763c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->FormatState = Unformatted;
764c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->FileSystem[0] = L'\0';
765c1fbc2d6SHermès Bélusca-Maïto 
7667df92966SHermès Bélusca-Maïto     DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
7677df92966SHermès Bélusca-Maïto     DPRINT1("Last Sector  : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
7687df92966SHermès Bélusca-Maïto     DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
7697df92966SHermès Bélusca-Maïto 
770c1fbc2d6SHermès Bélusca-Maïto     /* Insert the new entry into the list */
7717df92966SHermès Bélusca-Maïto     InsertTailList(ListHead, &NewPartEntry->ListEntry);
7727df92966SHermès Bélusca-Maïto 
7737df92966SHermès Bélusca-Maïto     return NewPartEntry;
7747df92966SHermès Bélusca-Maïto }
7757df92966SHermès Bélusca-Maïto 
7767df92966SHermès Bélusca-Maïto static
7777df92966SHermès Bélusca-Maïto // BOOLEAN
7787df92966SHermès Bélusca-Maïto PPARTENTRY
7797df92966SHermès Bélusca-Maïto InitializePartitionEntry(
7807df92966SHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
7817df92966SHermès Bélusca-Maïto     IN PPARTENTRY PartEntry,
7827df92966SHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
7837df92966SHermès Bélusca-Maïto     IN BOOLEAN AutoCreate)
7847df92966SHermès Bélusca-Maïto {
7857df92966SHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
7867df92966SHermès Bélusca-Maïto 
7877df92966SHermès Bélusca-Maïto     DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
7887df92966SHermès Bélusca-Maïto 
7897df92966SHermès Bélusca-Maïto     if ((AutoCreate != FALSE) ||
7907df92966SHermès Bélusca-Maïto         (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
7917df92966SHermès Bélusca-Maïto                    PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
7927df92966SHermès Bélusca-Maïto     {
7937df92966SHermès Bélusca-Maïto         DPRINT1("Convert existing partition entry\n");
7947df92966SHermès Bélusca-Maïto 
7957df92966SHermès Bélusca-Maïto         NewPartEntry = PartEntry;
796c1fbc2d6SHermès Bélusca-Maïto         NewPartEntry->AutoCreate = AutoCreate;
7977df92966SHermès Bélusca-Maïto     }
7987df92966SHermès Bélusca-Maïto     else
7997df92966SHermès Bélusca-Maïto     {
8007df92966SHermès Bélusca-Maïto         DPRINT1("Add new partition entry\n");
8017df92966SHermès Bélusca-Maïto 
8027df92966SHermès Bélusca-Maïto         /* Insert and initialize a new partition entry */
8037df92966SHermès Bélusca-Maïto         NewPartEntry = RtlAllocateHeap(ProcessHeap,
8047df92966SHermès Bélusca-Maïto                                        HEAP_ZERO_MEMORY,
8057df92966SHermès Bélusca-Maïto                                        sizeof(PARTENTRY));
8067df92966SHermès Bélusca-Maïto         if (NewPartEntry == NULL)
8077df92966SHermès Bélusca-Maïto             return NULL;
8087df92966SHermès Bélusca-Maïto 
8097df92966SHermès Bélusca-Maïto         NewPartEntry->DiskEntry = DiskEntry;
8107df92966SHermès Bélusca-Maïto 
8117df92966SHermès Bélusca-Maïto         NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
8127df92966SHermès Bélusca-Maïto         NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
8137df92966SHermès Bélusca-Maïto                                              NewPartEntry->StartSector.QuadPart;
8147df92966SHermès Bélusca-Maïto 
8157df92966SHermès Bélusca-Maïto         PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
8167df92966SHermès Bélusca-Maïto         PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
817c1fbc2d6SHermès Bélusca-Maïto 
818c1fbc2d6SHermès Bélusca-Maïto         /* Insert the new entry into the list */
819c1fbc2d6SHermès Bélusca-Maïto         InsertTailList(&PartEntry->ListEntry, &NewPartEntry->ListEntry);
8207df92966SHermès Bélusca-Maïto     }
8217df92966SHermès Bélusca-Maïto 
822c1fbc2d6SHermès Bélusca-Maïto     /* Create entry as 'New (Unformatted)' */
823c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->New = TRUE;
824c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->IsPartitioned = TRUE;
825c1fbc2d6SHermès Bélusca-Maïto 
826c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->PartitionType = FileSystemToPartitionType(L"RAW", &NewPartEntry->StartSector, &NewPartEntry->SectorCount);
827c1fbc2d6SHermès Bélusca-Maïto     ASSERT(NewPartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
828c1fbc2d6SHermès Bélusca-Maïto 
829c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->FormatState = Unformatted;
830c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->FileSystem[0] = L'\0';
831c1fbc2d6SHermès Bélusca-Maïto     // NewPartEntry->AutoCreate = AutoCreate;
832c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->BootIndicator = FALSE;
833c1fbc2d6SHermès Bélusca-Maïto     NewPartEntry->LogicalPartition = FALSE;
834c1fbc2d6SHermès Bélusca-Maïto 
8357df92966SHermès Bélusca-Maïto     DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
8367df92966SHermès Bélusca-Maïto     DPRINT1("Last Sector  : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
8377df92966SHermès Bélusca-Maïto     DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
8387df92966SHermès Bélusca-Maïto 
8397df92966SHermès Bélusca-Maïto     return NewPartEntry;
8407df92966SHermès Bélusca-Maïto }
8417df92966SHermès Bélusca-Maïto 
8427df92966SHermès Bélusca-Maïto 
8436f19c83bSHermès Bélusca-Maïto static
8446f19c83bSHermès Bélusca-Maïto VOID
8456f19c83bSHermès Bélusca-Maïto AddPartitionToDisk(
8466f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
8476f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
8486f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionIndex,
8496f19c83bSHermès Bélusca-Maïto     IN BOOLEAN LogicalPartition)
8506f19c83bSHermès Bélusca-Maïto {
851f41750abSHermès Bélusca-Maïto     NTSTATUS Status;
8526f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
8536f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
854c1fbc2d6SHermès Bélusca-Maïto     HANDLE PartitionHandle;
855f41750abSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
856f41750abSHermès Bélusca-Maïto     IO_STATUS_BLOCK IoStatusBlock;
857c1fbc2d6SHermès Bélusca-Maïto     WCHAR PathBuffer[MAX_PATH];
858f41750abSHermès Bélusca-Maïto     UNICODE_STRING Name;
859f41750abSHermès Bélusca-Maïto     UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
860f41750abSHermès Bélusca-Maïto     PFILE_FS_VOLUME_INFORMATION LabelInfo = (PFILE_FS_VOLUME_INFORMATION)LabelBuffer;
8616f19c83bSHermès Bélusca-Maïto 
8626f19c83bSHermès Bélusca-Maïto     PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
8636f19c83bSHermès Bélusca-Maïto 
8646f19c83bSHermès Bélusca-Maïto     if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED ||
8656f19c83bSHermès Bélusca-Maïto         ((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType)))
8666f19c83bSHermès Bélusca-Maïto     {
8676f19c83bSHermès Bélusca-Maïto         return;
8686f19c83bSHermès Bélusca-Maïto     }
8696f19c83bSHermès Bélusca-Maïto 
8706f19c83bSHermès Bélusca-Maïto     PartEntry = RtlAllocateHeap(ProcessHeap,
8716f19c83bSHermès Bélusca-Maïto                                 HEAP_ZERO_MEMORY,
8726f19c83bSHermès Bélusca-Maïto                                 sizeof(PARTENTRY));
8736f19c83bSHermès Bélusca-Maïto     if (PartEntry == NULL)
8746f19c83bSHermès Bélusca-Maïto         return;
8756f19c83bSHermès Bélusca-Maïto 
8766f19c83bSHermès Bélusca-Maïto     PartEntry->DiskEntry = DiskEntry;
8776f19c83bSHermès Bélusca-Maïto 
8786f19c83bSHermès Bélusca-Maïto     PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
8796f19c83bSHermès Bélusca-Maïto     PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
8806f19c83bSHermès Bélusca-Maïto 
8816f19c83bSHermès Bélusca-Maïto     PartEntry->BootIndicator = PartitionInfo->BootIndicator;
8826f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionType = PartitionInfo->PartitionType;
8836f19c83bSHermès Bélusca-Maïto     PartEntry->HiddenSectors = PartitionInfo->HiddenSectors;
8846f19c83bSHermès Bélusca-Maïto 
8856f19c83bSHermès Bélusca-Maïto     PartEntry->LogicalPartition = LogicalPartition;
8866f19c83bSHermès Bélusca-Maïto     PartEntry->IsPartitioned = TRUE;
8877df92966SHermès Bélusca-Maïto     PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
8886f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
8896f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionIndex = PartitionIndex;
8906f19c83bSHermès Bélusca-Maïto 
891c1fbc2d6SHermès Bélusca-Maïto     /* Specify the partition as initially unformatted */
892c1fbc2d6SHermès Bélusca-Maïto     PartEntry->FormatState = Unformatted;
893c1fbc2d6SHermès Bélusca-Maïto     PartEntry->FileSystem[0] = L'\0';
894c1fbc2d6SHermès Bélusca-Maïto 
895c1fbc2d6SHermès Bélusca-Maïto     /* Initialize the partition volume label */
896c1fbc2d6SHermès Bélusca-Maïto     RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
897c1fbc2d6SHermès Bélusca-Maïto 
8986f19c83bSHermès Bélusca-Maïto     if (IsContainerPartition(PartEntry->PartitionType))
8996f19c83bSHermès Bélusca-Maïto     {
9006f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = Unformatted;
9016f19c83bSHermès Bélusca-Maïto 
9026f19c83bSHermès Bélusca-Maïto         if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
9036f19c83bSHermès Bélusca-Maïto             DiskEntry->ExtendedPartition = PartEntry;
9046f19c83bSHermès Bélusca-Maïto     }
9056f19c83bSHermès Bélusca-Maïto     else if (IsRecognizedPartition(PartEntry->PartitionType))
9066f19c83bSHermès Bélusca-Maïto     {
9077df92966SHermès Bélusca-Maïto         ASSERT(PartitionInfo->RecognizedPartition);
90829cc1843SHermès Bélusca-Maïto         ASSERT(PartEntry->IsPartitioned && PartEntry->PartitionNumber != 0);
9097df92966SHermès Bélusca-Maïto 
910f41750abSHermès Bélusca-Maïto         /* Open the volume, ignore any errors */
911c1fbc2d6SHermès Bélusca-Maïto         RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
912f41750abSHermès Bélusca-Maïto                             L"\\Device\\Harddisk%lu\\Partition%lu",
9137df92966SHermès Bélusca-Maïto                             DiskEntry->DiskNumber,
9147df92966SHermès Bélusca-Maïto                             PartEntry->PartitionNumber);
915c1fbc2d6SHermès Bélusca-Maïto         RtlInitUnicodeString(&Name, PathBuffer);
916f41750abSHermès Bélusca-Maïto 
917f41750abSHermès Bélusca-Maïto         InitializeObjectAttributes(&ObjectAttributes,
918f41750abSHermès Bélusca-Maïto                                    &Name,
919f41750abSHermès Bélusca-Maïto                                    OBJ_CASE_INSENSITIVE,
920f41750abSHermès Bélusca-Maïto                                    NULL,
921f41750abSHermès Bélusca-Maïto                                    NULL);
922f41750abSHermès Bélusca-Maïto 
923c1fbc2d6SHermès Bélusca-Maïto         PartitionHandle = NULL;
924c1fbc2d6SHermès Bélusca-Maïto         Status = NtOpenFile(&PartitionHandle,
925f41750abSHermès Bélusca-Maïto                             FILE_READ_DATA | SYNCHRONIZE,
926f41750abSHermès Bélusca-Maïto                             &ObjectAttributes,
927f41750abSHermès Bélusca-Maïto                             &IoStatusBlock,
928f41750abSHermès Bélusca-Maïto                             FILE_SHARE_READ | FILE_SHARE_WRITE,
929f41750abSHermès Bélusca-Maïto                             FILE_SYNCHRONOUS_IO_NONALERT);
930c1fbc2d6SHermès Bélusca-Maïto         if (!NT_SUCCESS(Status))
931f41750abSHermès Bélusca-Maïto         {
932c1fbc2d6SHermès Bélusca-Maïto             DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
933c1fbc2d6SHermès Bélusca-Maïto         }
934c1fbc2d6SHermès Bélusca-Maïto 
935c1fbc2d6SHermès Bélusca-Maïto         if (/* NT_SUCCESS(Status) && */ PartitionHandle)
936c1fbc2d6SHermès Bélusca-Maïto         {
937c1fbc2d6SHermès Bélusca-Maïto             /* We don't have a FS, try to guess one */
938c1fbc2d6SHermès Bélusca-Maïto             Status = InferFileSystemByHandle(PartitionHandle,
939c1fbc2d6SHermès Bélusca-Maïto                                              PartEntry->PartitionType,
940c1fbc2d6SHermès Bélusca-Maïto                                              PartEntry->FileSystem,
941c1fbc2d6SHermès Bélusca-Maïto                                              sizeof(PartEntry->FileSystem));
942c1fbc2d6SHermès Bélusca-Maïto             if (!NT_SUCCESS(Status))
943c1fbc2d6SHermès Bélusca-Maïto                 DPRINT1("InferFileSystemByHandle() failed, Status 0x%08lx\n", Status);
944c1fbc2d6SHermès Bélusca-Maïto         }
945c1fbc2d6SHermès Bélusca-Maïto         if (*PartEntry->FileSystem)
946c1fbc2d6SHermès Bélusca-Maïto         {
947c1fbc2d6SHermès Bélusca-Maïto             if (wcsicmp(PartEntry->FileSystem, L"RAW") == 0)
948c1fbc2d6SHermès Bélusca-Maïto                 PartEntry->FormatState = Unformatted;
949c1fbc2d6SHermès Bélusca-Maïto             else
950c1fbc2d6SHermès Bélusca-Maïto                 PartEntry->FormatState = Preformatted;
951c1fbc2d6SHermès Bélusca-Maïto         }
952c1fbc2d6SHermès Bélusca-Maïto         else
953c1fbc2d6SHermès Bélusca-Maïto         {
954c1fbc2d6SHermès Bélusca-Maïto             PartEntry->FormatState = UnknownFormat;
955c1fbc2d6SHermès Bélusca-Maïto         }
956c1fbc2d6SHermès Bélusca-Maïto 
957f41750abSHermès Bélusca-Maïto         /* Retrieve the partition volume label */
958c1fbc2d6SHermès Bélusca-Maïto         if (PartitionHandle)
959c1fbc2d6SHermès Bélusca-Maïto         {
960c1fbc2d6SHermès Bélusca-Maïto             Status = NtQueryVolumeInformationFile(PartitionHandle,
961f41750abSHermès Bélusca-Maïto                                                   &IoStatusBlock,
962f41750abSHermès Bélusca-Maïto                                                   &LabelBuffer,
963f41750abSHermès Bélusca-Maïto                                                   sizeof(LabelBuffer),
964f41750abSHermès Bélusca-Maïto                                                   FileFsVolumeInformation);
965f41750abSHermès Bélusca-Maïto             if (NT_SUCCESS(Status))
966f41750abSHermès Bélusca-Maïto             {
967f41750abSHermès Bélusca-Maïto                 /* Copy the (possibly truncated) volume label and NULL-terminate it */
968f41750abSHermès Bélusca-Maïto                 RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
969f41750abSHermès Bélusca-Maïto                                   LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
970f41750abSHermès Bélusca-Maïto             }
971f41750abSHermès Bélusca-Maïto             else
972f41750abSHermès Bélusca-Maïto             {
973f41750abSHermès Bélusca-Maïto                 DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
974f41750abSHermès Bélusca-Maïto             }
975f41750abSHermès Bélusca-Maïto         }
976c1fbc2d6SHermès Bélusca-Maïto 
977c1fbc2d6SHermès Bélusca-Maïto         /* Close the partition */
978c1fbc2d6SHermès Bélusca-Maïto         if (PartitionHandle)
979c1fbc2d6SHermès Bélusca-Maïto             NtClose(PartitionHandle);
980c1fbc2d6SHermès Bélusca-Maïto     }
981f41750abSHermès Bélusca-Maïto     else
982f41750abSHermès Bélusca-Maïto     {
983c1fbc2d6SHermès Bélusca-Maïto         /* Unknown partition, hence unknown partition format (may or may not be actually formatted) */
984c1fbc2d6SHermès Bélusca-Maïto         PartEntry->FormatState = UnknownFormat;
985f41750abSHermès Bélusca-Maïto     }
986f41750abSHermès Bélusca-Maïto 
9877df92966SHermès Bélusca-Maïto     InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
9886f19c83bSHermès Bélusca-Maïto }
9896f19c83bSHermès Bélusca-Maïto 
9906f19c83bSHermès Bélusca-Maïto static
9916f19c83bSHermès Bélusca-Maïto VOID
9926f19c83bSHermès Bélusca-Maïto ScanForUnpartitionedDiskSpace(
9936f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
9946f19c83bSHermès Bélusca-Maïto {
9957df92966SHermès Bélusca-Maïto     ULONGLONG StartSector;
9967df92966SHermès Bélusca-Maïto     ULONGLONG SectorCount;
9976f19c83bSHermès Bélusca-Maïto     ULONGLONG LastStartSector;
9986f19c83bSHermès Bélusca-Maïto     ULONGLONG LastSectorCount;
9996f19c83bSHermès Bélusca-Maïto     ULONGLONG LastUnusedSectorCount;
10006f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
10016f19c83bSHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
10026f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
10036f19c83bSHermès Bélusca-Maïto 
10046f19c83bSHermès Bélusca-Maïto     DPRINT("ScanForUnpartitionedDiskSpace()\n");
10056f19c83bSHermès Bélusca-Maïto 
10066f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
10076f19c83bSHermès Bélusca-Maïto     {
10086f19c83bSHermès Bélusca-Maïto         DPRINT1("No primary partition!\n");
10096f19c83bSHermès Bélusca-Maïto 
10106f19c83bSHermès Bélusca-Maïto         /* Create a partition entry that represents the empty disk */
10116f19c83bSHermès Bélusca-Maïto 
101226408b02SPierre Schweitzer         if (DiskEntry->SectorAlignment < 2048)
10137df92966SHermès Bélusca-Maïto             StartSector = 2048ULL;
101426408b02SPierre Schweitzer         else
10157df92966SHermès Bélusca-Maïto             StartSector = (ULONGLONG)DiskEntry->SectorAlignment;
10167df92966SHermès Bélusca-Maïto         SectorCount = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - StartSector;
10176f19c83bSHermès Bélusca-Maïto 
10187df92966SHermès Bélusca-Maïto         NewPartEntry = CreateInsertBlankRegion(DiskEntry,
10197df92966SHermès Bélusca-Maïto                                                &DiskEntry->PrimaryPartListHead,
10207df92966SHermès Bélusca-Maïto                                                StartSector,
10217df92966SHermès Bélusca-Maïto                                                SectorCount,
10227df92966SHermès Bélusca-Maïto                                                FALSE);
10237df92966SHermès Bélusca-Maïto         if (NewPartEntry == NULL)
10247df92966SHermès Bélusca-Maïto             DPRINT1("Failed to create a new empty region for full disk space!\n");
10256f19c83bSHermès Bélusca-Maïto 
10266f19c83bSHermès Bélusca-Maïto         return;
10276f19c83bSHermès Bélusca-Maïto     }
10286f19c83bSHermès Bélusca-Maïto 
10296f19c83bSHermès Bélusca-Maïto     /* Start partition at head 1, cylinder 0 */
103026408b02SPierre Schweitzer     if (DiskEntry->SectorAlignment < 2048)
103126408b02SPierre Schweitzer         LastStartSector = 2048ULL;
103226408b02SPierre Schweitzer     else
10337df92966SHermès Bélusca-Maïto         LastStartSector = (ULONGLONG)DiskEntry->SectorAlignment;
10346f19c83bSHermès Bélusca-Maïto     LastSectorCount = 0ULL;
10356f19c83bSHermès Bélusca-Maïto     LastUnusedSectorCount = 0ULL;
10366f19c83bSHermès Bélusca-Maïto 
10378bed4adfSHermès Bélusca-Maïto     for (Entry = DiskEntry->PrimaryPartListHead.Flink;
10388bed4adfSHermès Bélusca-Maïto          Entry != &DiskEntry->PrimaryPartListHead;
10398bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
10406f19c83bSHermès Bélusca-Maïto     {
10416f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
10426f19c83bSHermès Bélusca-Maïto 
10436f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
10446f19c83bSHermès Bélusca-Maïto             PartEntry->SectorCount.QuadPart != 0ULL)
10456f19c83bSHermès Bélusca-Maïto         {
10466f19c83bSHermès Bélusca-Maïto             LastUnusedSectorCount =
10476f19c83bSHermès Bélusca-Maïto                 PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
10486f19c83bSHermès Bélusca-Maïto 
10496f19c83bSHermès Bélusca-Maïto             if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
10506f19c83bSHermès Bélusca-Maïto                 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
10516f19c83bSHermès Bélusca-Maïto             {
10526f19c83bSHermès Bélusca-Maïto                 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
10536f19c83bSHermès Bélusca-Maïto 
10547df92966SHermès Bélusca-Maïto                 StartSector = LastStartSector + LastSectorCount;
10557df92966SHermès Bélusca-Maïto                 SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
10566f19c83bSHermès Bélusca-Maïto 
10576f19c83bSHermès Bélusca-Maïto                 /* Insert the table into the list */
10587df92966SHermès Bélusca-Maïto                 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
10597df92966SHermès Bélusca-Maïto                                                        &PartEntry->ListEntry,
10607df92966SHermès Bélusca-Maïto                                                        StartSector,
10617df92966SHermès Bélusca-Maïto                                                        SectorCount,
10627df92966SHermès Bélusca-Maïto                                                        FALSE);
10637df92966SHermès Bélusca-Maïto                 if (NewPartEntry == NULL)
10647df92966SHermès Bélusca-Maïto                 {
10657df92966SHermès Bélusca-Maïto                     DPRINT1("Failed to create a new empty region for disk space!\n");
10667df92966SHermès Bélusca-Maïto                     return;
10677df92966SHermès Bélusca-Maïto                 }
10686f19c83bSHermès Bélusca-Maïto             }
10696f19c83bSHermès Bélusca-Maïto 
10706f19c83bSHermès Bélusca-Maïto             LastStartSector = PartEntry->StartSector.QuadPart;
10716f19c83bSHermès Bélusca-Maïto             LastSectorCount = PartEntry->SectorCount.QuadPart;
10726f19c83bSHermès Bélusca-Maïto         }
10736f19c83bSHermès Bélusca-Maïto     }
10746f19c83bSHermès Bélusca-Maïto 
10756f19c83bSHermès Bélusca-Maïto     /* Check for trailing unpartitioned disk space */
10766f19c83bSHermès Bélusca-Maïto     if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
10776f19c83bSHermès Bélusca-Maïto     {
10786f19c83bSHermès Bélusca-Maïto         LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
10796f19c83bSHermès Bélusca-Maïto 
10806f19c83bSHermès Bélusca-Maïto         if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
10816f19c83bSHermès Bélusca-Maïto         {
10826f19c83bSHermès Bélusca-Maïto             DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
10836f19c83bSHermès Bélusca-Maïto 
10847df92966SHermès Bélusca-Maïto             StartSector = LastStartSector + LastSectorCount;
10857df92966SHermès Bélusca-Maïto             SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
10866f19c83bSHermès Bélusca-Maïto 
10876f19c83bSHermès Bélusca-Maïto             /* Append the table to the list */
10887df92966SHermès Bélusca-Maïto             NewPartEntry = CreateInsertBlankRegion(DiskEntry,
10897df92966SHermès Bélusca-Maïto                                                    &DiskEntry->PrimaryPartListHead,
10907df92966SHermès Bélusca-Maïto                                                    StartSector,
10917df92966SHermès Bélusca-Maïto                                                    SectorCount,
10927df92966SHermès Bélusca-Maïto                                                    FALSE);
10937df92966SHermès Bélusca-Maïto             if (NewPartEntry == NULL)
10947df92966SHermès Bélusca-Maïto             {
10957df92966SHermès Bélusca-Maïto                 DPRINT1("Failed to create a new empty region for trailing disk space!\n");
10967df92966SHermès Bélusca-Maïto                 return;
10977df92966SHermès Bélusca-Maïto             }
10986f19c83bSHermès Bélusca-Maïto         }
10996f19c83bSHermès Bélusca-Maïto     }
11006f19c83bSHermès Bélusca-Maïto 
11016f19c83bSHermès Bélusca-Maïto     if (DiskEntry->ExtendedPartition != NULL)
11026f19c83bSHermès Bélusca-Maïto     {
11036f19c83bSHermès Bélusca-Maïto         if (IsListEmpty(&DiskEntry->LogicalPartListHead))
11046f19c83bSHermès Bélusca-Maïto         {
11056f19c83bSHermès Bélusca-Maïto             DPRINT1("No logical partition!\n");
11066f19c83bSHermès Bélusca-Maïto 
11076f19c83bSHermès Bélusca-Maïto             /* Create a partition entry that represents the empty extended partition */
11087df92966SHermès Bélusca-Maïto 
11097df92966SHermès Bélusca-Maïto             StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
11107df92966SHermès Bélusca-Maïto             SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
11117df92966SHermès Bélusca-Maïto 
11127df92966SHermès Bélusca-Maïto             NewPartEntry = CreateInsertBlankRegion(DiskEntry,
11137df92966SHermès Bélusca-Maïto                                                    &DiskEntry->LogicalPartListHead,
11147df92966SHermès Bélusca-Maïto                                                    StartSector,
11157df92966SHermès Bélusca-Maïto                                                    SectorCount,
11167df92966SHermès Bélusca-Maïto                                                    TRUE);
11176f19c83bSHermès Bélusca-Maïto             if (NewPartEntry == NULL)
11187df92966SHermès Bélusca-Maïto             {
11197df92966SHermès Bélusca-Maïto                 DPRINT1("Failed to create a new empty region for full extended partition space!\n");
11206f19c83bSHermès Bélusca-Maïto                 return;
11217df92966SHermès Bélusca-Maïto             }
11226f19c83bSHermès Bélusca-Maïto             NewPartEntry->LogicalPartition = TRUE;
11236f19c83bSHermès Bélusca-Maïto 
11246f19c83bSHermès Bélusca-Maïto             return;
11256f19c83bSHermès Bélusca-Maïto         }
11266f19c83bSHermès Bélusca-Maïto 
11276f19c83bSHermès Bélusca-Maïto         /* Start partition at head 1, cylinder 0 */
11286f19c83bSHermès Bélusca-Maïto         LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
11296f19c83bSHermès Bélusca-Maïto         LastSectorCount = 0ULL;
11306f19c83bSHermès Bélusca-Maïto         LastUnusedSectorCount = 0ULL;
11316f19c83bSHermès Bélusca-Maïto 
11328bed4adfSHermès Bélusca-Maïto         for (Entry = DiskEntry->LogicalPartListHead.Flink;
11338bed4adfSHermès Bélusca-Maïto              Entry != &DiskEntry->LogicalPartListHead;
11348bed4adfSHermès Bélusca-Maïto              Entry = Entry->Flink)
11356f19c83bSHermès Bélusca-Maïto         {
11366f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
11376f19c83bSHermès Bélusca-Maïto 
11386f19c83bSHermès Bélusca-Maïto             if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
11396f19c83bSHermès Bélusca-Maïto                 PartEntry->SectorCount.QuadPart != 0ULL)
11406f19c83bSHermès Bélusca-Maïto             {
11416f19c83bSHermès Bélusca-Maïto                 LastUnusedSectorCount =
11426f19c83bSHermès Bélusca-Maïto                     PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
11436f19c83bSHermès Bélusca-Maïto 
11446f19c83bSHermès Bélusca-Maïto                 if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
11456f19c83bSHermès Bélusca-Maïto                     LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
11466f19c83bSHermès Bélusca-Maïto                 {
11476f19c83bSHermès Bélusca-Maïto                     DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
11486f19c83bSHermès Bélusca-Maïto 
11497df92966SHermès Bélusca-Maïto                     StartSector = LastStartSector + LastSectorCount;
11507df92966SHermès Bélusca-Maïto                     SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
11516f19c83bSHermès Bélusca-Maïto 
11526f19c83bSHermès Bélusca-Maïto                     /* Insert the table into the list */
11537df92966SHermès Bélusca-Maïto                     NewPartEntry = CreateInsertBlankRegion(DiskEntry,
11547df92966SHermès Bélusca-Maïto                                                            &PartEntry->ListEntry,
11557df92966SHermès Bélusca-Maïto                                                            StartSector,
11567df92966SHermès Bélusca-Maïto                                                            SectorCount,
11577df92966SHermès Bélusca-Maïto                                                            TRUE);
11587df92966SHermès Bélusca-Maïto                     if (NewPartEntry == NULL)
11597df92966SHermès Bélusca-Maïto                     {
11607df92966SHermès Bélusca-Maïto                         DPRINT1("Failed to create a new empty region for extended partition space!\n");
11617df92966SHermès Bélusca-Maïto                         return;
11627df92966SHermès Bélusca-Maïto                     }
11637df92966SHermès Bélusca-Maïto                     NewPartEntry->LogicalPartition = TRUE;
11646f19c83bSHermès Bélusca-Maïto                 }
11656f19c83bSHermès Bélusca-Maïto 
11666f19c83bSHermès Bélusca-Maïto                 LastStartSector = PartEntry->StartSector.QuadPart;
11676f19c83bSHermès Bélusca-Maïto                 LastSectorCount = PartEntry->SectorCount.QuadPart;
11686f19c83bSHermès Bélusca-Maïto             }
11696f19c83bSHermès Bélusca-Maïto         }
11706f19c83bSHermès Bélusca-Maïto 
11716f19c83bSHermès Bélusca-Maïto         /* Check for trailing unpartitioned disk space */
11726f19c83bSHermès Bélusca-Maïto         if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
11736f19c83bSHermès Bélusca-Maïto         {
11747df92966SHermès Bélusca-Maïto             LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart +
11757df92966SHermès Bélusca-Maïto                                               DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
11767df92966SHermès Bélusca-Maïto                                               DiskEntry->SectorAlignment);
11776f19c83bSHermès Bélusca-Maïto 
11786f19c83bSHermès Bélusca-Maïto             if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
11796f19c83bSHermès Bélusca-Maïto             {
11806f19c83bSHermès Bélusca-Maïto                 DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
11816f19c83bSHermès Bélusca-Maïto 
11827df92966SHermès Bélusca-Maïto                 StartSector = LastStartSector + LastSectorCount;
11837df92966SHermès Bélusca-Maïto                 SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
11846f19c83bSHermès Bélusca-Maïto 
11856f19c83bSHermès Bélusca-Maïto                 /* Append the table to the list */
11867df92966SHermès Bélusca-Maïto                 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
11877df92966SHermès Bélusca-Maïto                                                        &DiskEntry->LogicalPartListHead,
11887df92966SHermès Bélusca-Maïto                                                        StartSector,
11897df92966SHermès Bélusca-Maïto                                                        SectorCount,
11907df92966SHermès Bélusca-Maïto                                                        TRUE);
11917df92966SHermès Bélusca-Maïto                 if (NewPartEntry == NULL)
11927df92966SHermès Bélusca-Maïto                 {
11937df92966SHermès Bélusca-Maïto                     DPRINT1("Failed to create a new empty region for extended partition space!\n");
11947df92966SHermès Bélusca-Maïto                     return;
11957df92966SHermès Bélusca-Maïto                 }
11967df92966SHermès Bélusca-Maïto                 NewPartEntry->LogicalPartition = TRUE;
11976f19c83bSHermès Bélusca-Maïto             }
11986f19c83bSHermès Bélusca-Maïto         }
11996f19c83bSHermès Bélusca-Maïto     }
12006f19c83bSHermès Bélusca-Maïto 
12016f19c83bSHermès Bélusca-Maïto     DPRINT("ScanForUnpartitionedDiskSpace() done\n");
12026f19c83bSHermès Bélusca-Maïto }
12036f19c83bSHermès Bélusca-Maïto 
12046f19c83bSHermès Bélusca-Maïto static
12056f19c83bSHermès Bélusca-Maïto VOID
12066f19c83bSHermès Bélusca-Maïto SetDiskSignature(
12076f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
12086f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
12096f19c83bSHermès Bélusca-Maïto {
12106f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER SystemTime;
12116f19c83bSHermès Bélusca-Maïto     TIME_FIELDS TimeFields;
12126f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry2;
12136f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry2;
12146f19c83bSHermès Bélusca-Maïto     PUCHAR Buffer;
12156f19c83bSHermès Bélusca-Maïto 
1216a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1217a3168373SHermès Bélusca-Maïto     {
1218a3168373SHermès Bélusca-Maïto         DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1219a3168373SHermès Bélusca-Maïto         return;
1220a3168373SHermès Bélusca-Maïto     }
1221a3168373SHermès Bélusca-Maïto 
12226f19c83bSHermès Bélusca-Maïto     Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature;
12236f19c83bSHermès Bélusca-Maïto 
12246f19c83bSHermès Bélusca-Maïto     while (TRUE)
12256f19c83bSHermès Bélusca-Maïto     {
12266f19c83bSHermès Bélusca-Maïto         NtQuerySystemTime(&SystemTime);
12276f19c83bSHermès Bélusca-Maïto         RtlTimeToTimeFields(&SystemTime, &TimeFields);
12286f19c83bSHermès Bélusca-Maïto 
12296f19c83bSHermès Bélusca-Maïto         Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
12306f19c83bSHermès Bélusca-Maïto         Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
12316f19c83bSHermès Bélusca-Maïto         Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
12326f19c83bSHermès Bélusca-Maïto         Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
12336f19c83bSHermès Bélusca-Maïto 
12346f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer->Signature == 0)
12356f19c83bSHermès Bélusca-Maïto         {
12366f19c83bSHermès Bélusca-Maïto             continue;
12376f19c83bSHermès Bélusca-Maïto         }
12386f19c83bSHermès Bélusca-Maïto 
12396f19c83bSHermès Bélusca-Maïto         /* Check if the signature already exist */
12406f19c83bSHermès Bélusca-Maïto         /* FIXME:
12416f19c83bSHermès Bélusca-Maïto          *   Check also signatures from disks, which are
12426f19c83bSHermès Bélusca-Maïto          *   not visible (bootable) by the bios.
12436f19c83bSHermès Bélusca-Maïto          */
12448bed4adfSHermès Bélusca-Maïto         for (Entry2 = List->DiskListHead.Flink;
12458bed4adfSHermès Bélusca-Maïto              Entry2 != &List->DiskListHead;
12468bed4adfSHermès Bélusca-Maïto              Entry2 = Entry2->Flink)
12476f19c83bSHermès Bélusca-Maïto         {
12486f19c83bSHermès Bélusca-Maïto             DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry);
12496f19c83bSHermès Bélusca-Maïto 
1250a3168373SHermès Bélusca-Maïto             if (DiskEntry2->DiskStyle == PARTITION_STYLE_GPT)
1251a3168373SHermès Bélusca-Maïto             {
1252a3168373SHermès Bélusca-Maïto                 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1253a3168373SHermès Bélusca-Maïto                 continue;
1254a3168373SHermès Bélusca-Maïto             }
1255a3168373SHermès Bélusca-Maïto 
12566f19c83bSHermès Bélusca-Maïto             if (DiskEntry != DiskEntry2 &&
12576f19c83bSHermès Bélusca-Maïto                 DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature)
12586f19c83bSHermès Bélusca-Maïto                 break;
12596f19c83bSHermès Bélusca-Maïto         }
12606f19c83bSHermès Bélusca-Maïto 
12616f19c83bSHermès Bélusca-Maïto         if (Entry2 == &List->DiskListHead)
12626f19c83bSHermès Bélusca-Maïto             break;
12636f19c83bSHermès Bélusca-Maïto     }
12646f19c83bSHermès Bélusca-Maïto }
12656f19c83bSHermès Bélusca-Maïto 
12666f19c83bSHermès Bélusca-Maïto static
12676f19c83bSHermès Bélusca-Maïto VOID
12686f19c83bSHermès Bélusca-Maïto UpdateDiskSignatures(
12696f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
12706f19c83bSHermès Bélusca-Maïto {
12716f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
12726f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
12736f19c83bSHermès Bélusca-Maïto 
1274a3168373SHermès Bélusca-Maïto     /* Update each disk */
12758bed4adfSHermès Bélusca-Maïto     for (Entry = List->DiskListHead.Flink;
12768bed4adfSHermès Bélusca-Maïto          Entry != &List->DiskListHead;
12778bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
12786f19c83bSHermès Bélusca-Maïto     {
12796f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
12806f19c83bSHermès Bélusca-Maïto 
1281a3168373SHermès Bélusca-Maïto         if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1282a3168373SHermès Bélusca-Maïto         {
1283a3168373SHermès Bélusca-Maïto             DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1284a3168373SHermès Bélusca-Maïto             continue;
1285a3168373SHermès Bélusca-Maïto         }
1286a3168373SHermès Bélusca-Maïto 
12876f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer &&
12886f19c83bSHermès Bélusca-Maïto             DiskEntry->LayoutBuffer->Signature == 0)
12896f19c83bSHermès Bélusca-Maïto         {
12906f19c83bSHermès Bélusca-Maïto             SetDiskSignature(List, DiskEntry);
12916f19c83bSHermès Bélusca-Maïto             DiskEntry->LayoutBuffer->PartitionEntry[0].RewritePartition = TRUE;
12926f19c83bSHermès Bélusca-Maïto         }
12936f19c83bSHermès Bélusca-Maïto     }
12946f19c83bSHermès Bélusca-Maïto }
12956f19c83bSHermès Bélusca-Maïto 
12966f19c83bSHermès Bélusca-Maïto static
12976f19c83bSHermès Bélusca-Maïto VOID
12986f19c83bSHermès Bélusca-Maïto AddDiskToList(
12996f19c83bSHermès Bélusca-Maïto     IN HANDLE FileHandle,
13006f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
13016f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
13026f19c83bSHermès Bélusca-Maïto {
13036f19c83bSHermès Bélusca-Maïto     DISK_GEOMETRY DiskGeometry;
13046f19c83bSHermès Bélusca-Maïto     SCSI_ADDRESS ScsiAddress;
13056f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
13066f19c83bSHermès Bélusca-Maïto     IO_STATUS_BLOCK Iosb;
13076f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
13086f19c83bSHermès Bélusca-Maïto     PPARTITION_SECTOR Mbr;
13096f19c83bSHermès Bélusca-Maïto     PULONG Buffer;
13106f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER FileOffset;
13116f19c83bSHermès Bélusca-Maïto     WCHAR Identifier[20];
13126f19c83bSHermès Bélusca-Maïto     ULONG Checksum;
13136f19c83bSHermès Bélusca-Maïto     ULONG Signature;
13146f19c83bSHermès Bélusca-Maïto     ULONG i;
13156f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
13166f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry;
13176f19c83bSHermès Bélusca-Maïto     ULONG LayoutBufferSize;
13186f19c83bSHermès Bélusca-Maïto     PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
13196f19c83bSHermès Bélusca-Maïto 
1320f41750abSHermès Bélusca-Maïto     /* Retrieve the drive geometry */
13216f19c83bSHermès Bélusca-Maïto     Status = NtDeviceIoControlFile(FileHandle,
13226f19c83bSHermès Bélusca-Maïto                                    NULL,
13236f19c83bSHermès Bélusca-Maïto                                    NULL,
13246f19c83bSHermès Bélusca-Maïto                                    NULL,
13256f19c83bSHermès Bélusca-Maïto                                    &Iosb,
13266f19c83bSHermès Bélusca-Maïto                                    IOCTL_DISK_GET_DRIVE_GEOMETRY,
13276f19c83bSHermès Bélusca-Maïto                                    NULL,
13286f19c83bSHermès Bélusca-Maïto                                    0,
13296f19c83bSHermès Bélusca-Maïto                                    &DiskGeometry,
1330f41750abSHermès Bélusca-Maïto                                    sizeof(DiskGeometry));
13316f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
13326f19c83bSHermès Bélusca-Maïto         return;
13336f19c83bSHermès Bélusca-Maïto 
13346f19c83bSHermès Bélusca-Maïto     if (DiskGeometry.MediaType != FixedMedia &&
13356f19c83bSHermès Bélusca-Maïto         DiskGeometry.MediaType != RemovableMedia)
13366f19c83bSHermès Bélusca-Maïto     {
13376f19c83bSHermès Bélusca-Maïto         return;
13386f19c83bSHermès Bélusca-Maïto     }
13396f19c83bSHermès Bélusca-Maïto 
1340f41750abSHermès Bélusca-Maïto     /*
1341f41750abSHermès Bélusca-Maïto      * FIXME: Here we suppose the disk is always SCSI. What if it is
1342f41750abSHermès Bélusca-Maïto      * of another type? To check this we need to retrieve the name of
1343f41750abSHermès Bélusca-Maïto      * the driver the disk device belongs to.
1344f41750abSHermès Bélusca-Maïto      */
13456f19c83bSHermès Bélusca-Maïto     Status = NtDeviceIoControlFile(FileHandle,
13466f19c83bSHermès Bélusca-Maïto                                    NULL,
13476f19c83bSHermès Bélusca-Maïto                                    NULL,
13486f19c83bSHermès Bélusca-Maïto                                    NULL,
13496f19c83bSHermès Bélusca-Maïto                                    &Iosb,
13506f19c83bSHermès Bélusca-Maïto                                    IOCTL_SCSI_GET_ADDRESS,
13516f19c83bSHermès Bélusca-Maïto                                    NULL,
13526f19c83bSHermès Bélusca-Maïto                                    0,
13536f19c83bSHermès Bélusca-Maïto                                    &ScsiAddress,
1354f41750abSHermès Bélusca-Maïto                                    sizeof(ScsiAddress));
13556f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
13566f19c83bSHermès Bélusca-Maïto         return;
13576f19c83bSHermès Bélusca-Maïto 
13586f19c83bSHermès Bélusca-Maïto     /*
13596f19c83bSHermès Bélusca-Maïto      * Check whether the disk is initialized, by looking at its MBR.
13606f19c83bSHermès Bélusca-Maïto      * NOTE that this must be generalized to GPT disks as well!
13616f19c83bSHermès Bélusca-Maïto      */
13626f19c83bSHermès Bélusca-Maïto 
13636f19c83bSHermès Bélusca-Maïto     Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap,
13646f19c83bSHermès Bélusca-Maïto                                              0,
13656f19c83bSHermès Bélusca-Maïto                                              DiskGeometry.BytesPerSector);
13666f19c83bSHermès Bélusca-Maïto     if (Mbr == NULL)
13676f19c83bSHermès Bélusca-Maïto         return;
13686f19c83bSHermès Bélusca-Maïto 
13696f19c83bSHermès Bélusca-Maïto     FileOffset.QuadPart = 0;
13706f19c83bSHermès Bélusca-Maïto     Status = NtReadFile(FileHandle,
13716f19c83bSHermès Bélusca-Maïto                         NULL,
13726f19c83bSHermès Bélusca-Maïto                         NULL,
13736f19c83bSHermès Bélusca-Maïto                         NULL,
13746f19c83bSHermès Bélusca-Maïto                         &Iosb,
13756f19c83bSHermès Bélusca-Maïto                         (PVOID)Mbr,
13766f19c83bSHermès Bélusca-Maïto                         DiskGeometry.BytesPerSector,
13776f19c83bSHermès Bélusca-Maïto                         &FileOffset,
13786f19c83bSHermès Bélusca-Maïto                         NULL);
13796f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
13806f19c83bSHermès Bélusca-Maïto     {
13816f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, Mbr);
13826f19c83bSHermès Bélusca-Maïto         DPRINT1("NtReadFile failed, status=%x\n", Status);
13836f19c83bSHermès Bélusca-Maïto         return;
13846f19c83bSHermès Bélusca-Maïto     }
13856f19c83bSHermès Bélusca-Maïto     Signature = Mbr->Signature;
13866f19c83bSHermès Bélusca-Maïto 
13876f19c83bSHermès Bélusca-Maïto     /* Calculate the MBR checksum */
13886f19c83bSHermès Bélusca-Maïto     Checksum = 0;
13896f19c83bSHermès Bélusca-Maïto     Buffer = (PULONG)Mbr;
13906f19c83bSHermès Bélusca-Maïto     for (i = 0; i < 128; i++)
13916f19c83bSHermès Bélusca-Maïto     {
13926f19c83bSHermès Bélusca-Maïto         Checksum += Buffer[i];
13936f19c83bSHermès Bélusca-Maïto     }
13946f19c83bSHermès Bélusca-Maïto     Checksum = ~Checksum + 1;
13956f19c83bSHermès Bélusca-Maïto 
13966f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier),
13976f19c83bSHermès Bélusca-Maïto                         L"%08x-%08x-A", Checksum, Signature);
13986f19c83bSHermès Bélusca-Maïto     DPRINT("Identifier: %S\n", Identifier);
13996f19c83bSHermès Bélusca-Maïto 
14006f19c83bSHermès Bélusca-Maïto     DiskEntry = RtlAllocateHeap(ProcessHeap,
14016f19c83bSHermès Bélusca-Maïto                                 HEAP_ZERO_MEMORY,
14026f19c83bSHermès Bélusca-Maïto                                 sizeof(DISKENTRY));
14036f19c83bSHermès Bélusca-Maïto     if (DiskEntry == NULL)
14046f19c83bSHermès Bélusca-Maïto     {
1405f41750abSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, Mbr);
1406f41750abSHermès Bélusca-Maïto         DPRINT1("Failed to allocate a new disk entry.\n");
14076f19c83bSHermès Bélusca-Maïto         return;
14086f19c83bSHermès Bélusca-Maïto     }
14096f19c83bSHermès Bélusca-Maïto 
1410*84f3e2dfSHermès Bélusca-Maïto     DiskEntry->PartList = List;
1411*84f3e2dfSHermès Bélusca-Maïto 
14126f19c83bSHermès Bélusca-Maïto //    DiskEntry->Checksum = Checksum;
14136f19c83bSHermès Bélusca-Maïto //    DiskEntry->Signature = Signature;
14146f19c83bSHermès Bélusca-Maïto     DiskEntry->BiosFound = FALSE;
14156f19c83bSHermès Bélusca-Maïto 
14166f19c83bSHermès Bélusca-Maïto     /*
14176f19c83bSHermès Bélusca-Maïto      * Check if this disk has a valid MBR: verify its signature,
14186f19c83bSHermès Bélusca-Maïto      * and whether its two first bytes are a valid instruction
14196f19c83bSHermès Bélusca-Maïto      * (related to this, see IsThereAValidBootSector() in partlist.c).
1420a3168373SHermès Bélusca-Maïto      *
1421a3168373SHermès Bélusca-Maïto      * See also ntoskrnl/fstub/fstubex.c!FstubDetectPartitionStyle().
14226f19c83bSHermès Bélusca-Maïto      */
1423a3168373SHermès Bélusca-Maïto 
1424a3168373SHermès Bélusca-Maïto     // DiskEntry->NoMbr = (Mbr->Magic != PARTITION_MAGIC || (*(PUSHORT)Mbr->BootCode) == 0x0000);
1425a3168373SHermès Bélusca-Maïto 
1426a3168373SHermès Bélusca-Maïto     /* If we have not the 0xAA55 then it's raw partition */
1427a3168373SHermès Bélusca-Maïto     if (Mbr->Magic != PARTITION_MAGIC)
1428a3168373SHermès Bélusca-Maïto     {
1429a3168373SHermès Bélusca-Maïto         DiskEntry->DiskStyle = PARTITION_STYLE_RAW;
1430a3168373SHermès Bélusca-Maïto     }
1431a3168373SHermès Bélusca-Maïto     /* Check partitions types: if first is 0xEE and all the others 0, we have GPT */
1432a3168373SHermès Bélusca-Maïto     else if (Mbr->Partition[0].PartitionType == EFI_PMBR_OSTYPE_EFI &&
1433a3168373SHermès Bélusca-Maïto              Mbr->Partition[1].PartitionType == 0 &&
1434a3168373SHermès Bélusca-Maïto              Mbr->Partition[2].PartitionType == 0 &&
1435a3168373SHermès Bélusca-Maïto              Mbr->Partition[3].PartitionType == 0)
1436a3168373SHermès Bélusca-Maïto     {
1437a3168373SHermès Bélusca-Maïto         DiskEntry->DiskStyle = PARTITION_STYLE_GPT;
1438a3168373SHermès Bélusca-Maïto     }
1439a3168373SHermès Bélusca-Maïto     /* Otherwise, partition table is in MBR */
14406f19c83bSHermès Bélusca-Maïto     else
1441a3168373SHermès Bélusca-Maïto     {
1442a3168373SHermès Bélusca-Maïto         DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
1443a3168373SHermès Bélusca-Maïto     }
14446f19c83bSHermès Bélusca-Maïto 
14456f19c83bSHermès Bélusca-Maïto     /* Free the MBR sector buffer */
14466f19c83bSHermès Bélusca-Maïto     RtlFreeHeap(ProcessHeap, 0, Mbr);
14476f19c83bSHermès Bélusca-Maïto 
14486f19c83bSHermès Bélusca-Maïto 
14498bed4adfSHermès Bélusca-Maïto     for (ListEntry = List->BiosDiskListHead.Flink;
14508bed4adfSHermès Bélusca-Maïto          ListEntry != &List->BiosDiskListHead;
14518bed4adfSHermès Bélusca-Maïto          ListEntry = ListEntry->Flink)
14526f19c83bSHermès Bélusca-Maïto     {
14536f19c83bSHermès Bélusca-Maïto         BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
14546f19c83bSHermès Bélusca-Maïto         /* FIXME:
14556f19c83bSHermès Bélusca-Maïto          *   Compare the size from bios and the reported size from driver.
14566f19c83bSHermès Bélusca-Maïto          *   If we have more than one disk with a zero or with the same signature
14576f19c83bSHermès Bélusca-Maïto          *   we must create new signatures and reboot. After the reboot,
14586f19c83bSHermès Bélusca-Maïto          *   it is possible to identify the disks.
14596f19c83bSHermès Bélusca-Maïto          */
14606f19c83bSHermès Bélusca-Maïto         if (BiosDiskEntry->Signature == Signature &&
14616f19c83bSHermès Bélusca-Maïto             BiosDiskEntry->Checksum == Checksum &&
14626f19c83bSHermès Bélusca-Maïto             !BiosDiskEntry->Recognized)
14636f19c83bSHermès Bélusca-Maïto         {
14646f19c83bSHermès Bélusca-Maïto             if (!DiskEntry->BiosFound)
14656f19c83bSHermès Bélusca-Maïto             {
14666f19c83bSHermès Bélusca-Maïto                 DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
14676f19c83bSHermès Bélusca-Maïto                 DiskEntry->BiosFound = TRUE;
14686f19c83bSHermès Bélusca-Maïto                 BiosDiskEntry->Recognized = TRUE;
14696f19c83bSHermès Bélusca-Maïto             }
14706f19c83bSHermès Bélusca-Maïto             else
14716f19c83bSHermès Bélusca-Maïto             {
1472f41750abSHermès Bélusca-Maïto                 // FIXME: What to do?
14736f19c83bSHermès Bélusca-Maïto             }
14746f19c83bSHermès Bélusca-Maïto         }
14756f19c83bSHermès Bélusca-Maïto     }
14766f19c83bSHermès Bélusca-Maïto 
14776f19c83bSHermès Bélusca-Maïto     if (!DiskEntry->BiosFound)
14786f19c83bSHermès Bélusca-Maïto     {
14796f19c83bSHermès Bélusca-Maïto #if 0
14806f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, DiskEntry);
14816f19c83bSHermès Bélusca-Maïto         return;
14826f19c83bSHermès Bélusca-Maïto #else
14836f19c83bSHermès Bélusca-Maïto         DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber);
14846f19c83bSHermès Bélusca-Maïto #endif
14856f19c83bSHermès Bélusca-Maïto     }
14866f19c83bSHermès Bélusca-Maïto 
14876f19c83bSHermès Bélusca-Maïto     InitializeListHead(&DiskEntry->PrimaryPartListHead);
14886f19c83bSHermès Bélusca-Maïto     InitializeListHead(&DiskEntry->LogicalPartListHead);
14896f19c83bSHermès Bélusca-Maïto 
14906f19c83bSHermès Bélusca-Maïto     DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
14916f19c83bSHermès Bélusca-Maïto     DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
14926f19c83bSHermès Bélusca-Maïto     DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
14936f19c83bSHermès Bélusca-Maïto     DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
14946f19c83bSHermès Bélusca-Maïto 
14956f19c83bSHermès Bélusca-Maïto     DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
14966f19c83bSHermès Bélusca-Maïto     DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
14976f19c83bSHermès Bélusca-Maïto     DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
14986f19c83bSHermès Bélusca-Maïto     DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
14996f19c83bSHermès Bélusca-Maïto 
15006f19c83bSHermès Bélusca-Maïto     DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
15016f19c83bSHermès Bélusca-Maïto                                       (ULONGLONG)DiskGeometry.TracksPerCylinder *
15026f19c83bSHermès Bélusca-Maïto                                       (ULONGLONG)DiskGeometry.SectorsPerTrack;
15036f19c83bSHermès Bélusca-Maïto 
15046f19c83bSHermès Bélusca-Maïto     DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
15056f19c83bSHermès Bélusca-Maïto     DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
15066f19c83bSHermès Bélusca-Maïto                                    DiskGeometry.SectorsPerTrack;
15076f19c83bSHermès Bélusca-Maïto 
15086f19c83bSHermès Bélusca-Maïto     DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
15096f19c83bSHermès Bélusca-Maïto     DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
15106f19c83bSHermès Bélusca-Maïto 
15116f19c83bSHermès Bélusca-Maïto     DiskEntry->DiskNumber = DiskNumber;
15126f19c83bSHermès Bélusca-Maïto     DiskEntry->Port = ScsiAddress.PortNumber;
15136f19c83bSHermès Bélusca-Maïto     DiskEntry->Bus = ScsiAddress.PathId;
15146f19c83bSHermès Bélusca-Maïto     DiskEntry->Id = ScsiAddress.TargetId;
15156f19c83bSHermès Bélusca-Maïto 
15166f19c83bSHermès Bélusca-Maïto     GetDriverName(DiskEntry);
15176f19c83bSHermès Bélusca-Maïto     /*
15186f19c83bSHermès Bélusca-Maïto      * Actually it would be more correct somehow to use:
15196f19c83bSHermès Bélusca-Maïto      *
15206f19c83bSHermès Bélusca-Maïto      * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
15216f19c83bSHermès Bélusca-Maïto      * ULONG ReturnedLength;
15226f19c83bSHermès Bélusca-Maïto      *
15236f19c83bSHermès Bélusca-Maïto      * Status = NtQueryObject(SomeHandleToTheDisk,
15246f19c83bSHermès Bélusca-Maïto      *                        ObjectNameInformation,
15256f19c83bSHermès Bélusca-Maïto      *                        &NameInfo,
15266f19c83bSHermès Bélusca-Maïto      *                        sizeof(NameInfo),
15276f19c83bSHermès Bélusca-Maïto      *                        &ReturnedLength);
15286f19c83bSHermès Bélusca-Maïto      * etc...
15296f19c83bSHermès Bélusca-Maïto      *
15306f19c83bSHermès Bélusca-Maïto      * See examples in https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267
15316f19c83bSHermès Bélusca-Maïto      */
15326f19c83bSHermès Bélusca-Maïto 
15336f19c83bSHermès Bélusca-Maïto     InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
15346f19c83bSHermès Bélusca-Maïto 
1535f41750abSHermès Bélusca-Maïto 
1536f41750abSHermès Bélusca-Maïto     /*
1537f41750abSHermès Bélusca-Maïto      * We now retrieve the disk partition layout
1538f41750abSHermès Bélusca-Maïto      */
1539f41750abSHermès Bélusca-Maïto 
1540a3168373SHermès Bélusca-Maïto     /*
1541a3168373SHermès Bélusca-Maïto      * Stop there now if the disk is GPT-partitioned,
1542a3168373SHermès Bélusca-Maïto      * since we currently do not support such disks.
1543a3168373SHermès Bélusca-Maïto      */
1544a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1545a3168373SHermès Bélusca-Maïto     {
1546a3168373SHermès Bélusca-Maïto         DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1547a3168373SHermès Bélusca-Maïto         return;
1548a3168373SHermès Bélusca-Maïto     }
1549a3168373SHermès Bélusca-Maïto 
15506f19c83bSHermès Bélusca-Maïto     /* Allocate a layout buffer with 4 partition entries first */
15516f19c83bSHermès Bélusca-Maïto     LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
15526f19c83bSHermès Bélusca-Maïto                        ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
15536f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer = RtlAllocateHeap(ProcessHeap,
15546f19c83bSHermès Bélusca-Maïto                                               HEAP_ZERO_MEMORY,
15556f19c83bSHermès Bélusca-Maïto                                               LayoutBufferSize);
15566f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer == NULL)
15576f19c83bSHermès Bélusca-Maïto     {
15586f19c83bSHermès Bélusca-Maïto         DPRINT1("Failed to allocate the disk layout buffer!\n");
15596f19c83bSHermès Bélusca-Maïto         return;
15606f19c83bSHermès Bélusca-Maïto     }
15616f19c83bSHermès Bélusca-Maïto 
1562f41750abSHermès Bélusca-Maïto     /* Keep looping while the drive layout buffer is too small */
15636f19c83bSHermès Bélusca-Maïto     for (;;)
15646f19c83bSHermès Bélusca-Maïto     {
15656f19c83bSHermès Bélusca-Maïto         DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
15666f19c83bSHermès Bélusca-Maïto         Status = NtDeviceIoControlFile(FileHandle,
15676f19c83bSHermès Bélusca-Maïto                                        NULL,
15686f19c83bSHermès Bélusca-Maïto                                        NULL,
15696f19c83bSHermès Bélusca-Maïto                                        NULL,
15706f19c83bSHermès Bélusca-Maïto                                        &Iosb,
15716f19c83bSHermès Bélusca-Maïto                                        IOCTL_DISK_GET_DRIVE_LAYOUT,
15726f19c83bSHermès Bélusca-Maïto                                        NULL,
15736f19c83bSHermès Bélusca-Maïto                                        0,
15746f19c83bSHermès Bélusca-Maïto                                        DiskEntry->LayoutBuffer,
15756f19c83bSHermès Bélusca-Maïto                                        LayoutBufferSize);
15766f19c83bSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
15776f19c83bSHermès Bélusca-Maïto             break;
15786f19c83bSHermès Bélusca-Maïto 
15796f19c83bSHermès Bélusca-Maïto         if (Status != STATUS_BUFFER_TOO_SMALL)
15806f19c83bSHermès Bélusca-Maïto         {
15816f19c83bSHermès Bélusca-Maïto             DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
15826f19c83bSHermès Bélusca-Maïto             return;
15836f19c83bSHermès Bélusca-Maïto         }
15846f19c83bSHermès Bélusca-Maïto 
15856f19c83bSHermès Bélusca-Maïto         LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
15866f19c83bSHermès Bélusca-Maïto         NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
15876f19c83bSHermès Bélusca-Maïto                                             HEAP_ZERO_MEMORY,
15886f19c83bSHermès Bélusca-Maïto                                             DiskEntry->LayoutBuffer,
15896f19c83bSHermès Bélusca-Maïto                                             LayoutBufferSize);
15906f19c83bSHermès Bélusca-Maïto         if (NewLayoutBuffer == NULL)
15916f19c83bSHermès Bélusca-Maïto         {
15926f19c83bSHermès Bélusca-Maïto             DPRINT1("Failed to reallocate the disk layout buffer!\n");
15936f19c83bSHermès Bélusca-Maïto             return;
15946f19c83bSHermès Bélusca-Maïto         }
15956f19c83bSHermès Bélusca-Maïto 
15966f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer = NewLayoutBuffer;
15976f19c83bSHermès Bélusca-Maïto     }
15986f19c83bSHermès Bélusca-Maïto 
15996f19c83bSHermès Bélusca-Maïto     DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
16006f19c83bSHermès Bélusca-Maïto 
16016f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
16026f19c83bSHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
16036f19c83bSHermès Bélusca-Maïto #endif
16046f19c83bSHermès Bélusca-Maïto 
16056f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
16066f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
16076f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != PARTITION_ENTRY_UNUSED)
16086f19c83bSHermès Bélusca-Maïto     {
16096f19c83bSHermès Bélusca-Maïto         if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
16106f19c83bSHermès Bélusca-Maïto         {
16116f19c83bSHermès Bélusca-Maïto             DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
16126f19c83bSHermès Bélusca-Maïto         }
16136f19c83bSHermès Bélusca-Maïto         else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
16146f19c83bSHermès Bélusca-Maïto         {
16156f19c83bSHermès Bélusca-Maïto             DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
16166f19c83bSHermès Bélusca-Maïto         }
16176f19c83bSHermès Bélusca-Maïto         else
16186f19c83bSHermès Bélusca-Maïto         {
16196f19c83bSHermès Bélusca-Maïto             DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
16206f19c83bSHermès Bélusca-Maïto         }
16216f19c83bSHermès Bélusca-Maïto     }
16226f19c83bSHermès Bélusca-Maïto     else
16236f19c83bSHermès Bélusca-Maïto     {
16246f19c83bSHermès Bélusca-Maïto         DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
16256f19c83bSHermès Bélusca-Maïto     }
16266f19c83bSHermès Bélusca-Maïto 
16276f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer->PartitionCount == 0)
16286f19c83bSHermès Bélusca-Maïto     {
16296f19c83bSHermès Bélusca-Maïto         DiskEntry->NewDisk = TRUE;
16306f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer->PartitionCount = 4;
16316f19c83bSHermès Bélusca-Maïto 
16326f19c83bSHermès Bélusca-Maïto         for (i = 0; i < 4; i++)
16337df92966SHermès Bélusca-Maïto         {
16346f19c83bSHermès Bélusca-Maïto             DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
16356f19c83bSHermès Bélusca-Maïto         }
16367df92966SHermès Bélusca-Maïto     }
16376f19c83bSHermès Bélusca-Maïto     else
16386f19c83bSHermès Bélusca-Maïto     {
16397df92966SHermès Bélusca-Maïto         /* Enumerate and add the first four primary partitions */
16406f19c83bSHermès Bélusca-Maïto         for (i = 0; i < 4; i++)
16416f19c83bSHermès Bélusca-Maïto         {
16426f19c83bSHermès Bélusca-Maïto             AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
16436f19c83bSHermès Bélusca-Maïto         }
16446f19c83bSHermès Bélusca-Maïto 
16457df92966SHermès Bélusca-Maïto         /* Enumerate and add the remaining partitions as logical ones */
16466f19c83bSHermès Bélusca-Maïto         for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
16476f19c83bSHermès Bélusca-Maïto         {
16486f19c83bSHermès Bélusca-Maïto             AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
16496f19c83bSHermès Bélusca-Maïto         }
16506f19c83bSHermès Bélusca-Maïto     }
16516f19c83bSHermès Bélusca-Maïto 
16526f19c83bSHermès Bélusca-Maïto     ScanForUnpartitionedDiskSpace(DiskEntry);
16536f19c83bSHermès Bélusca-Maïto }
16546f19c83bSHermès Bélusca-Maïto 
16556f19c83bSHermès Bélusca-Maïto PPARTLIST
16566f19c83bSHermès Bélusca-Maïto CreatePartitionList(VOID)
16576f19c83bSHermès Bélusca-Maïto {
16586f19c83bSHermès Bélusca-Maïto     PPARTLIST List;
16596f19c83bSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
16606f19c83bSHermès Bélusca-Maïto     SYSTEM_DEVICE_INFORMATION Sdi;
16616f19c83bSHermès Bélusca-Maïto     IO_STATUS_BLOCK Iosb;
16626f19c83bSHermès Bélusca-Maïto     ULONG ReturnSize;
16636f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
16646f19c83bSHermès Bélusca-Maïto     ULONG DiskNumber;
16656f19c83bSHermès Bélusca-Maïto     WCHAR Buffer[MAX_PATH];
16666f19c83bSHermès Bélusca-Maïto     UNICODE_STRING Name;
16676f19c83bSHermès Bélusca-Maïto     HANDLE FileHandle;
16686f19c83bSHermès Bélusca-Maïto 
16696f19c83bSHermès Bélusca-Maïto     List = (PPARTLIST)RtlAllocateHeap(ProcessHeap,
16706f19c83bSHermès Bélusca-Maïto                                       0,
16716f19c83bSHermès Bélusca-Maïto                                       sizeof(PARTLIST));
16726f19c83bSHermès Bélusca-Maïto     if (List == NULL)
16736f19c83bSHermès Bélusca-Maïto         return NULL;
16746f19c83bSHermès Bélusca-Maïto 
16756f19c83bSHermès Bélusca-Maïto     List->SystemPartition = NULL;
16766f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = NULL;
16776f19c83bSHermès Bélusca-Maïto 
16786f19c83bSHermès Bélusca-Maïto     InitializeListHead(&List->DiskListHead);
16796f19c83bSHermès Bélusca-Maïto     InitializeListHead(&List->BiosDiskListHead);
16806f19c83bSHermès Bélusca-Maïto 
1681f41750abSHermès Bélusca-Maïto     /*
1682f41750abSHermès Bélusca-Maïto      * Enumerate the disks seen by the BIOS; this will be used later
1683f41750abSHermès Bélusca-Maïto      * to map drives seen by NTOS with their corresponding BIOS names.
1684f41750abSHermès Bélusca-Maïto      */
16856f19c83bSHermès Bélusca-Maïto     EnumerateBiosDiskEntries(List);
16866f19c83bSHermès Bélusca-Maïto 
1687f41750abSHermès Bélusca-Maïto     /* Enumerate disks seen by NTOS */
16886f19c83bSHermès Bélusca-Maïto     Status = NtQuerySystemInformation(SystemDeviceInformation,
16896f19c83bSHermès Bélusca-Maïto                                       &Sdi,
16906f19c83bSHermès Bélusca-Maïto                                       sizeof(Sdi),
16916f19c83bSHermès Bélusca-Maïto                                       &ReturnSize);
16926f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
16936f19c83bSHermès Bélusca-Maïto     {
16946f19c83bSHermès Bélusca-Maïto         DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status);
16956f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, List);
16966f19c83bSHermès Bélusca-Maïto         return NULL;
16976f19c83bSHermès Bélusca-Maïto     }
16986f19c83bSHermès Bélusca-Maïto 
16996f19c83bSHermès Bélusca-Maïto     for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
17006f19c83bSHermès Bélusca-Maïto     {
17016f19c83bSHermès Bélusca-Maïto         RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
17026f19c83bSHermès Bélusca-Maïto                             L"\\Device\\Harddisk%lu\\Partition0",
17036f19c83bSHermès Bélusca-Maïto                             DiskNumber);
17046f19c83bSHermès Bélusca-Maïto         RtlInitUnicodeString(&Name, Buffer);
17056f19c83bSHermès Bélusca-Maïto 
17066f19c83bSHermès Bélusca-Maïto         InitializeObjectAttributes(&ObjectAttributes,
17076f19c83bSHermès Bélusca-Maïto                                    &Name,
1708765994c9SHermès Bélusca-Maïto                                    OBJ_CASE_INSENSITIVE,
17096f19c83bSHermès Bélusca-Maïto                                    NULL,
17106f19c83bSHermès Bélusca-Maïto                                    NULL);
17116f19c83bSHermès Bélusca-Maïto 
17126f19c83bSHermès Bélusca-Maïto         Status = NtOpenFile(&FileHandle,
17136f19c83bSHermès Bélusca-Maïto                             FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
17146f19c83bSHermès Bélusca-Maïto                             &ObjectAttributes,
17156f19c83bSHermès Bélusca-Maïto                             &Iosb,
1716f41750abSHermès Bélusca-Maïto                             FILE_SHARE_READ | FILE_SHARE_WRITE,
17176f19c83bSHermès Bélusca-Maïto                             FILE_SYNCHRONOUS_IO_NONALERT);
17186f19c83bSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
17196f19c83bSHermès Bélusca-Maïto         {
17206f19c83bSHermès Bélusca-Maïto             AddDiskToList(FileHandle, DiskNumber, List);
17216f19c83bSHermès Bélusca-Maïto             NtClose(FileHandle);
17226f19c83bSHermès Bélusca-Maïto         }
17236f19c83bSHermès Bélusca-Maïto     }
17246f19c83bSHermès Bélusca-Maïto 
17256f19c83bSHermès Bélusca-Maïto     UpdateDiskSignatures(List);
17266f19c83bSHermès Bélusca-Maïto 
17276f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
17286f19c83bSHermès Bélusca-Maïto 
17296f19c83bSHermès Bélusca-Maïto     return List;
17306f19c83bSHermès Bélusca-Maïto }
17316f19c83bSHermès Bélusca-Maïto 
17326f19c83bSHermès Bélusca-Maïto VOID
17336f19c83bSHermès Bélusca-Maïto DestroyPartitionList(
17346f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
17356f19c83bSHermès Bélusca-Maïto {
17366f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
17376f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry;
17386f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
17396f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
17406f19c83bSHermès Bélusca-Maïto 
17416f19c83bSHermès Bélusca-Maïto     /* Release disk and partition info */
17426f19c83bSHermès Bélusca-Maïto     while (!IsListEmpty(&List->DiskListHead))
17436f19c83bSHermès Bélusca-Maïto     {
17446f19c83bSHermès Bélusca-Maïto         Entry = RemoveHeadList(&List->DiskListHead);
17456f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
17466f19c83bSHermès Bélusca-Maïto 
17476f19c83bSHermès Bélusca-Maïto         /* Release driver name */
17486f19c83bSHermès Bélusca-Maïto         RtlFreeUnicodeString(&DiskEntry->DriverName);
17496f19c83bSHermès Bélusca-Maïto 
17506f19c83bSHermès Bélusca-Maïto         /* Release primary partition list */
17516f19c83bSHermès Bélusca-Maïto         while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
17526f19c83bSHermès Bélusca-Maïto         {
17536f19c83bSHermès Bélusca-Maïto             Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
17546f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
17556f19c83bSHermès Bélusca-Maïto 
17566f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, PartEntry);
17576f19c83bSHermès Bélusca-Maïto         }
17586f19c83bSHermès Bélusca-Maïto 
17596f19c83bSHermès Bélusca-Maïto         /* Release logical partition list */
17606f19c83bSHermès Bélusca-Maïto         while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
17616f19c83bSHermès Bélusca-Maïto         {
17626f19c83bSHermès Bélusca-Maïto             Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
17636f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
17646f19c83bSHermès Bélusca-Maïto 
17656f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, PartEntry);
17666f19c83bSHermès Bélusca-Maïto         }
17676f19c83bSHermès Bélusca-Maïto 
17686f19c83bSHermès Bélusca-Maïto         /* Release layout buffer */
17696f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer != NULL)
17706f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
17716f19c83bSHermès Bélusca-Maïto 
17726f19c83bSHermès Bélusca-Maïto         /* Release disk entry */
17736f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, DiskEntry);
17746f19c83bSHermès Bélusca-Maïto     }
17756f19c83bSHermès Bélusca-Maïto 
17766f19c83bSHermès Bélusca-Maïto     /* Release the bios disk info */
17776f19c83bSHermès Bélusca-Maïto     while (!IsListEmpty(&List->BiosDiskListHead))
17786f19c83bSHermès Bélusca-Maïto     {
17796f19c83bSHermès Bélusca-Maïto         Entry = RemoveHeadList(&List->BiosDiskListHead);
17806f19c83bSHermès Bélusca-Maïto         BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
17816f19c83bSHermès Bélusca-Maïto 
17826f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
17836f19c83bSHermès Bélusca-Maïto     }
17846f19c83bSHermès Bélusca-Maïto 
17856f19c83bSHermès Bélusca-Maïto     /* Release list head */
17866f19c83bSHermès Bélusca-Maïto     RtlFreeHeap(ProcessHeap, 0, List);
17876f19c83bSHermès Bélusca-Maïto }
17886f19c83bSHermès Bélusca-Maïto 
17896f19c83bSHermès Bélusca-Maïto PDISKENTRY
17906f19c83bSHermès Bélusca-Maïto GetDiskByBiosNumber(
17916f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
17926f19c83bSHermès Bélusca-Maïto     IN ULONG BiosDiskNumber)
17936f19c83bSHermès Bélusca-Maïto {
17946f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
17956f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
17966f19c83bSHermès Bélusca-Maïto 
17976f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
17988bed4adfSHermès Bélusca-Maïto     for (Entry = List->DiskListHead.Flink;
17998bed4adfSHermès Bélusca-Maïto          Entry != &List->DiskListHead;
18008bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
18016f19c83bSHermès Bélusca-Maïto     {
18026f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
18036f19c83bSHermès Bélusca-Maïto 
18046f19c83bSHermès Bélusca-Maïto         if (DiskEntry->BiosDiskNumber == BiosDiskNumber)
18056f19c83bSHermès Bélusca-Maïto         {
18066f19c83bSHermès Bélusca-Maïto             /* Disk found */
18076f19c83bSHermès Bélusca-Maïto             return DiskEntry;
18086f19c83bSHermès Bélusca-Maïto         }
18096f19c83bSHermès Bélusca-Maïto     }
18106f19c83bSHermès Bélusca-Maïto 
18116f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
18126f19c83bSHermès Bélusca-Maïto     return NULL;
18136f19c83bSHermès Bélusca-Maïto }
18146f19c83bSHermès Bélusca-Maïto 
18156f19c83bSHermès Bélusca-Maïto PDISKENTRY
18166f19c83bSHermès Bélusca-Maïto GetDiskByNumber(
18176f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
18186f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber)
18196f19c83bSHermès Bélusca-Maïto {
18206f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
18216f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
18226f19c83bSHermès Bélusca-Maïto 
18236f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
18248bed4adfSHermès Bélusca-Maïto     for (Entry = List->DiskListHead.Flink;
18258bed4adfSHermès Bélusca-Maïto          Entry != &List->DiskListHead;
18268bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
18276f19c83bSHermès Bélusca-Maïto     {
18286f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
18296f19c83bSHermès Bélusca-Maïto 
18306f19c83bSHermès Bélusca-Maïto         if (DiskEntry->DiskNumber == DiskNumber)
18316f19c83bSHermès Bélusca-Maïto         {
18326f19c83bSHermès Bélusca-Maïto             /* Disk found */
18336f19c83bSHermès Bélusca-Maïto             return DiskEntry;
18346f19c83bSHermès Bélusca-Maïto         }
18356f19c83bSHermès Bélusca-Maïto     }
18366f19c83bSHermès Bélusca-Maïto 
18376f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
18386f19c83bSHermès Bélusca-Maïto     return NULL;
18396f19c83bSHermès Bélusca-Maïto }
18406f19c83bSHermès Bélusca-Maïto 
18416f19c83bSHermès Bélusca-Maïto PDISKENTRY
18426f19c83bSHermès Bélusca-Maïto GetDiskBySCSI(
18436f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
18446f19c83bSHermès Bélusca-Maïto     IN USHORT Port,
18456f19c83bSHermès Bélusca-Maïto     IN USHORT Bus,
18466f19c83bSHermès Bélusca-Maïto     IN USHORT Id)
18476f19c83bSHermès Bélusca-Maïto {
18486f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
18496f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
18506f19c83bSHermès Bélusca-Maïto 
18516f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
18528bed4adfSHermès Bélusca-Maïto     for (Entry = List->DiskListHead.Flink;
18538bed4adfSHermès Bélusca-Maïto          Entry != &List->DiskListHead;
18548bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
18556f19c83bSHermès Bélusca-Maïto     {
18566f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
18576f19c83bSHermès Bélusca-Maïto 
18586f19c83bSHermès Bélusca-Maïto         if (DiskEntry->Port == Port &&
18596f19c83bSHermès Bélusca-Maïto             DiskEntry->Bus  == Bus  &&
18606f19c83bSHermès Bélusca-Maïto             DiskEntry->Id   == Id)
18616f19c83bSHermès Bélusca-Maïto         {
18626f19c83bSHermès Bélusca-Maïto             /* Disk found */
18636f19c83bSHermès Bélusca-Maïto             return DiskEntry;
18646f19c83bSHermès Bélusca-Maïto         }
18656f19c83bSHermès Bélusca-Maïto     }
18666f19c83bSHermès Bélusca-Maïto 
18676f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
18686f19c83bSHermès Bélusca-Maïto     return NULL;
18696f19c83bSHermès Bélusca-Maïto }
18706f19c83bSHermès Bélusca-Maïto 
18716f19c83bSHermès Bélusca-Maïto PDISKENTRY
18726f19c83bSHermès Bélusca-Maïto GetDiskBySignature(
18736f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
18746f19c83bSHermès Bélusca-Maïto     IN ULONG Signature)
18756f19c83bSHermès Bélusca-Maïto {
18766f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
18776f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
18786f19c83bSHermès Bélusca-Maïto 
18796f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
18808bed4adfSHermès Bélusca-Maïto     for (Entry = List->DiskListHead.Flink;
18818bed4adfSHermès Bélusca-Maïto          Entry != &List->DiskListHead;
18828bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
18836f19c83bSHermès Bélusca-Maïto     {
18846f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
18856f19c83bSHermès Bélusca-Maïto 
18866f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer->Signature == Signature)
18876f19c83bSHermès Bélusca-Maïto         {
18886f19c83bSHermès Bélusca-Maïto             /* Disk found */
18896f19c83bSHermès Bélusca-Maïto             return DiskEntry;
18906f19c83bSHermès Bélusca-Maïto         }
18916f19c83bSHermès Bélusca-Maïto     }
18926f19c83bSHermès Bélusca-Maïto 
18936f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
18946f19c83bSHermès Bélusca-Maïto     return NULL;
18956f19c83bSHermès Bélusca-Maïto }
18966f19c83bSHermès Bélusca-Maïto 
18976f19c83bSHermès Bélusca-Maïto PPARTENTRY
18986f19c83bSHermès Bélusca-Maïto GetPartition(
18996f19c83bSHermès Bélusca-Maïto     // IN PPARTLIST List,
19006f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
19016f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionNumber)
19026f19c83bSHermès Bélusca-Maïto {
19036f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
19046f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
19056f19c83bSHermès Bélusca-Maïto 
1906a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1907a3168373SHermès Bélusca-Maïto     {
1908a3168373SHermès Bélusca-Maïto         DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1909a3168373SHermès Bélusca-Maïto         return NULL;
1910a3168373SHermès Bélusca-Maïto     }
1911a3168373SHermès Bélusca-Maïto 
19126f19c83bSHermès Bélusca-Maïto     /* Disk found, loop over the primary partitions first... */
19138bed4adfSHermès Bélusca-Maïto     for (Entry = DiskEntry->PrimaryPartListHead.Flink;
19148bed4adfSHermès Bélusca-Maïto          Entry != &DiskEntry->PrimaryPartListHead;
19158bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
19166f19c83bSHermès Bélusca-Maïto     {
19176f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
19186f19c83bSHermès Bélusca-Maïto 
19196f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionNumber == PartitionNumber)
19206f19c83bSHermès Bélusca-Maïto         {
19216f19c83bSHermès Bélusca-Maïto             /* Partition found */
19226f19c83bSHermès Bélusca-Maïto             return PartEntry;
19236f19c83bSHermès Bélusca-Maïto         }
19246f19c83bSHermès Bélusca-Maïto     }
19256f19c83bSHermès Bélusca-Maïto 
19266f19c83bSHermès Bélusca-Maïto     /* ... then over the logical partitions if needed */
19278bed4adfSHermès Bélusca-Maïto     for (Entry = DiskEntry->LogicalPartListHead.Flink;
19288bed4adfSHermès Bélusca-Maïto          Entry != &DiskEntry->LogicalPartListHead;
19298bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
19306f19c83bSHermès Bélusca-Maïto     {
19316f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
19326f19c83bSHermès Bélusca-Maïto 
19336f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionNumber == PartitionNumber)
19346f19c83bSHermès Bélusca-Maïto         {
19356f19c83bSHermès Bélusca-Maïto             /* Partition found */
19366f19c83bSHermès Bélusca-Maïto             return PartEntry;
19376f19c83bSHermès Bélusca-Maïto         }
19386f19c83bSHermès Bélusca-Maïto     }
19396f19c83bSHermès Bélusca-Maïto 
19406f19c83bSHermès Bélusca-Maïto     /* The partition was not found on the disk, stop there */
19416f19c83bSHermès Bélusca-Maïto     return NULL;
19426f19c83bSHermès Bélusca-Maïto }
19436f19c83bSHermès Bélusca-Maïto 
19446f19c83bSHermès Bélusca-Maïto BOOLEAN
19456f19c83bSHermès Bélusca-Maïto GetDiskOrPartition(
19466f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
19476f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
19486f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionNumber OPTIONAL,
19496f19c83bSHermès Bélusca-Maïto     OUT PDISKENTRY* pDiskEntry,
19506f19c83bSHermès Bélusca-Maïto     OUT PPARTENTRY* pPartEntry OPTIONAL)
19516f19c83bSHermès Bélusca-Maïto {
19526f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
19536f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry = NULL;
19546f19c83bSHermès Bélusca-Maïto 
19556f19c83bSHermès Bélusca-Maïto     /* Find the disk */
19566f19c83bSHermès Bélusca-Maïto     DiskEntry = GetDiskByNumber(List, DiskNumber);
19576f19c83bSHermès Bélusca-Maïto     if (!DiskEntry)
19586f19c83bSHermès Bélusca-Maïto         return FALSE;
19596f19c83bSHermès Bélusca-Maïto 
19606f19c83bSHermès Bélusca-Maïto     /* If we have a partition (PartitionNumber != 0), find it */
19616f19c83bSHermès Bélusca-Maïto     if (PartitionNumber != 0)
19626f19c83bSHermès Bélusca-Maïto     {
1963a3168373SHermès Bélusca-Maïto         if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
1964a3168373SHermès Bélusca-Maïto         {
1965a3168373SHermès Bélusca-Maïto             DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
1966a3168373SHermès Bélusca-Maïto             return FALSE;
1967a3168373SHermès Bélusca-Maïto         }
1968a3168373SHermès Bélusca-Maïto 
19696f19c83bSHermès Bélusca-Maïto         PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
19706f19c83bSHermès Bélusca-Maïto         if (!PartEntry)
19716f19c83bSHermès Bélusca-Maïto             return FALSE;
19726f19c83bSHermès Bélusca-Maïto         ASSERT(PartEntry->DiskEntry == DiskEntry);
19736f19c83bSHermès Bélusca-Maïto     }
19746f19c83bSHermès Bélusca-Maïto 
19756f19c83bSHermès Bélusca-Maïto     /* Return the disk (and optionally the partition) */
19766f19c83bSHermès Bélusca-Maïto     *pDiskEntry = DiskEntry;
19776f19c83bSHermès Bélusca-Maïto     if (pPartEntry) *pPartEntry = PartEntry;
19786f19c83bSHermès Bélusca-Maïto     return TRUE;
19796f19c83bSHermès Bélusca-Maïto }
19806f19c83bSHermès Bélusca-Maïto 
19816f19c83bSHermès Bélusca-Maïto //
19826f19c83bSHermès Bélusca-Maïto // NOTE: Was introduced broken in r6258 by Casper
19836f19c83bSHermès Bélusca-Maïto //
1984*84f3e2dfSHermès Bélusca-Maïto PPARTENTRY
19856f19c83bSHermès Bélusca-Maïto SelectPartition(
19866f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
19876f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
19886f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionNumber)
19896f19c83bSHermès Bélusca-Maïto {
19906f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
19916f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
19926f19c83bSHermès Bélusca-Maïto 
19936f19c83bSHermès Bélusca-Maïto     DiskEntry = GetDiskByNumber(List, DiskNumber);
19946f19c83bSHermès Bélusca-Maïto     if (!DiskEntry)
1995*84f3e2dfSHermès Bélusca-Maïto         return NULL;
19966f19c83bSHermès Bélusca-Maïto 
19976f19c83bSHermès Bélusca-Maïto     PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
19986f19c83bSHermès Bélusca-Maïto     if (!PartEntry)
1999*84f3e2dfSHermès Bélusca-Maïto         return NULL;
20006f19c83bSHermès Bélusca-Maïto 
20016f19c83bSHermès Bélusca-Maïto     ASSERT(PartEntry->DiskEntry == DiskEntry);
20026f19c83bSHermès Bélusca-Maïto     ASSERT(DiskEntry->DiskNumber == DiskNumber);
20036f19c83bSHermès Bélusca-Maïto     ASSERT(PartEntry->PartitionNumber == PartitionNumber);
20046f19c83bSHermès Bélusca-Maïto 
2005*84f3e2dfSHermès Bélusca-Maïto     return PartEntry;
20066f19c83bSHermès Bélusca-Maïto }
20076f19c83bSHermès Bélusca-Maïto 
20086f19c83bSHermès Bélusca-Maïto PPARTENTRY
20096f19c83bSHermès Bélusca-Maïto GetNextPartition(
2010*84f3e2dfSHermès Bélusca-Maïto     IN PPARTLIST List,
2011*84f3e2dfSHermès Bélusca-Maïto     IN PPARTENTRY CurrentPart OPTIONAL)
20126f19c83bSHermès Bélusca-Maïto {
20136f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY DiskListEntry;
20146f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY PartListEntry;
2015*84f3e2dfSHermès Bélusca-Maïto     PDISKENTRY CurrentDisk;
20166f19c83bSHermès Bélusca-Maïto 
20176f19c83bSHermès Bélusca-Maïto     /* Fail if no disks are available */
20186f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
20196f19c83bSHermès Bélusca-Maïto         return NULL;
20206f19c83bSHermès Bélusca-Maïto 
2021*84f3e2dfSHermès Bélusca-Maïto     /* Check for the next usable entry on the current partition's disk */
2022*84f3e2dfSHermès Bélusca-Maïto     if (CurrentPart != NULL)
20236f19c83bSHermès Bélusca-Maïto     {
2024*84f3e2dfSHermès Bélusca-Maïto         CurrentDisk = CurrentPart->DiskEntry;
2025*84f3e2dfSHermès Bélusca-Maïto 
2026*84f3e2dfSHermès Bélusca-Maïto         if (CurrentPart->LogicalPartition)
20276f19c83bSHermès Bélusca-Maïto         {
20286f19c83bSHermès Bélusca-Maïto             /* Logical partition */
20296f19c83bSHermès Bélusca-Maïto 
2030*84f3e2dfSHermès Bélusca-Maïto             PartListEntry = CurrentPart->ListEntry.Flink;
2031*84f3e2dfSHermès Bélusca-Maïto             if (PartListEntry != &CurrentDisk->LogicalPartListHead)
20326f19c83bSHermès Bélusca-Maïto             {
20336f19c83bSHermès Bélusca-Maïto                 /* Next logical partition */
2034*84f3e2dfSHermès Bélusca-Maïto                 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2035*84f3e2dfSHermès Bélusca-Maïto                 return CurrentPart;
20366f19c83bSHermès Bélusca-Maïto             }
20376f19c83bSHermès Bélusca-Maïto             else
20386f19c83bSHermès Bélusca-Maïto             {
2039*84f3e2dfSHermès Bélusca-Maïto                 PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2040*84f3e2dfSHermès Bélusca-Maïto                 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
20416f19c83bSHermès Bélusca-Maïto                 {
2042*84f3e2dfSHermès Bélusca-Maïto                     CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2043*84f3e2dfSHermès Bélusca-Maïto                     return CurrentPart;
20446f19c83bSHermès Bélusca-Maïto                 }
20456f19c83bSHermès Bélusca-Maïto             }
20466f19c83bSHermès Bélusca-Maïto         }
20476f19c83bSHermès Bélusca-Maïto         else
20486f19c83bSHermès Bélusca-Maïto         {
20496f19c83bSHermès Bélusca-Maïto             /* Primary or extended partition */
20506f19c83bSHermès Bélusca-Maïto 
2051*84f3e2dfSHermès Bélusca-Maïto             if (CurrentPart->IsPartitioned &&
2052*84f3e2dfSHermès Bélusca-Maïto                 IsContainerPartition(CurrentPart->PartitionType))
20536f19c83bSHermès Bélusca-Maïto             {
20546f19c83bSHermès Bélusca-Maïto                 /* First logical partition */
2055*84f3e2dfSHermès Bélusca-Maïto                 PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2056*84f3e2dfSHermès Bélusca-Maïto                 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
20576f19c83bSHermès Bélusca-Maïto                 {
2058*84f3e2dfSHermès Bélusca-Maïto                     CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2059*84f3e2dfSHermès Bélusca-Maïto                     return CurrentPart;
20606f19c83bSHermès Bélusca-Maïto                 }
20616f19c83bSHermès Bélusca-Maïto             }
20626f19c83bSHermès Bélusca-Maïto             else
20636f19c83bSHermès Bélusca-Maïto             {
20646f19c83bSHermès Bélusca-Maïto                 /* Next primary partition */
2065*84f3e2dfSHermès Bélusca-Maïto                 PartListEntry = CurrentPart->ListEntry.Flink;
2066*84f3e2dfSHermès Bélusca-Maïto                 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
20676f19c83bSHermès Bélusca-Maïto                 {
2068*84f3e2dfSHermès Bélusca-Maïto                     CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2069*84f3e2dfSHermès Bélusca-Maïto                     return CurrentPart;
20706f19c83bSHermès Bélusca-Maïto                 }
20716f19c83bSHermès Bélusca-Maïto             }
20726f19c83bSHermès Bélusca-Maïto         }
20736f19c83bSHermès Bélusca-Maïto     }
20746f19c83bSHermès Bélusca-Maïto 
20756f19c83bSHermès Bélusca-Maïto     /* Search for the first partition entry on the next disk */
2076*84f3e2dfSHermès Bélusca-Maïto     for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2077*84f3e2dfSHermès Bélusca-Maïto                                       : List->DiskListHead.Flink);
20788bed4adfSHermès Bélusca-Maïto          DiskListEntry != &List->DiskListHead;
20798bed4adfSHermès Bélusca-Maïto          DiskListEntry = DiskListEntry->Flink)
20806f19c83bSHermès Bélusca-Maïto     {
2081*84f3e2dfSHermès Bélusca-Maïto         CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
20826f19c83bSHermès Bélusca-Maïto 
2083*84f3e2dfSHermès Bélusca-Maïto         if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT)
2084a3168373SHermès Bélusca-Maïto         {
2085a3168373SHermès Bélusca-Maïto             DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2086a3168373SHermès Bélusca-Maïto             continue;
2087a3168373SHermès Bélusca-Maïto         }
2088a3168373SHermès Bélusca-Maïto 
2089*84f3e2dfSHermès Bélusca-Maïto         PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2090*84f3e2dfSHermès Bélusca-Maïto         if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
20916f19c83bSHermès Bélusca-Maïto         {
2092*84f3e2dfSHermès Bélusca-Maïto             CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2093*84f3e2dfSHermès Bélusca-Maïto             return CurrentPart;
20946f19c83bSHermès Bélusca-Maïto         }
20956f19c83bSHermès Bélusca-Maïto     }
20966f19c83bSHermès Bélusca-Maïto 
20976f19c83bSHermès Bélusca-Maïto     return NULL;
20986f19c83bSHermès Bélusca-Maïto }
20996f19c83bSHermès Bélusca-Maïto 
21006f19c83bSHermès Bélusca-Maïto PPARTENTRY
21016f19c83bSHermès Bélusca-Maïto GetPrevPartition(
2102*84f3e2dfSHermès Bélusca-Maïto     IN PPARTLIST List,
2103*84f3e2dfSHermès Bélusca-Maïto     IN PPARTENTRY CurrentPart OPTIONAL)
21046f19c83bSHermès Bélusca-Maïto {
21056f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY DiskListEntry;
21066f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY PartListEntry;
2107*84f3e2dfSHermès Bélusca-Maïto     PDISKENTRY CurrentDisk;
21086f19c83bSHermès Bélusca-Maïto 
21096f19c83bSHermès Bélusca-Maïto     /* Fail if no disks are available */
21106f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
21116f19c83bSHermès Bélusca-Maïto         return NULL;
21126f19c83bSHermès Bélusca-Maïto 
2113*84f3e2dfSHermès Bélusca-Maïto     /* Check for the previous usable entry on the current partition's disk */
2114*84f3e2dfSHermès Bélusca-Maïto     if (CurrentPart != NULL)
21156f19c83bSHermès Bélusca-Maïto     {
2116*84f3e2dfSHermès Bélusca-Maïto         CurrentDisk = CurrentPart->DiskEntry;
2117*84f3e2dfSHermès Bélusca-Maïto 
2118*84f3e2dfSHermès Bélusca-Maïto         if (CurrentPart->LogicalPartition)
21196f19c83bSHermès Bélusca-Maïto         {
21206f19c83bSHermès Bélusca-Maïto             /* Logical partition */
2121*84f3e2dfSHermès Bélusca-Maïto 
2122*84f3e2dfSHermès Bélusca-Maïto             PartListEntry = CurrentPart->ListEntry.Blink;
2123*84f3e2dfSHermès Bélusca-Maïto             if (PartListEntry != &CurrentDisk->LogicalPartListHead)
21246f19c83bSHermès Bélusca-Maïto             {
21256f19c83bSHermès Bélusca-Maïto                 /* Previous logical partition */
2126*84f3e2dfSHermès Bélusca-Maïto                 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
21276f19c83bSHermès Bélusca-Maïto             }
21286f19c83bSHermès Bélusca-Maïto             else
21296f19c83bSHermès Bélusca-Maïto             {
21306f19c83bSHermès Bélusca-Maïto                 /* Extended partition */
2131*84f3e2dfSHermès Bélusca-Maïto                 CurrentPart = CurrentDisk->ExtendedPartition;
21326f19c83bSHermès Bélusca-Maïto             }
2133*84f3e2dfSHermès Bélusca-Maïto             return CurrentPart;
21346f19c83bSHermès Bélusca-Maïto         }
21356f19c83bSHermès Bélusca-Maïto         else
21366f19c83bSHermès Bélusca-Maïto         {
21376f19c83bSHermès Bélusca-Maïto             /* Primary or extended partition */
21386f19c83bSHermès Bélusca-Maïto 
2139*84f3e2dfSHermès Bélusca-Maïto             PartListEntry = CurrentPart->ListEntry.Blink;
2140*84f3e2dfSHermès Bélusca-Maïto             if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
21416f19c83bSHermès Bélusca-Maïto             {
2142*84f3e2dfSHermès Bélusca-Maïto                 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
21436f19c83bSHermès Bélusca-Maïto 
2144*84f3e2dfSHermès Bélusca-Maïto                 if (CurrentPart->IsPartitioned &&
2145*84f3e2dfSHermès Bélusca-Maïto                     IsContainerPartition(CurrentPart->PartitionType))
21466f19c83bSHermès Bélusca-Maïto                 {
2147*84f3e2dfSHermès Bélusca-Maïto                     PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2148*84f3e2dfSHermès Bélusca-Maïto                     CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
21496f19c83bSHermès Bélusca-Maïto                 }
21506f19c83bSHermès Bélusca-Maïto 
2151*84f3e2dfSHermès Bélusca-Maïto                 return CurrentPart;
21526f19c83bSHermès Bélusca-Maïto             }
21536f19c83bSHermès Bélusca-Maïto         }
21546f19c83bSHermès Bélusca-Maïto     }
21556f19c83bSHermès Bélusca-Maïto 
21566f19c83bSHermès Bélusca-Maïto     /* Search for the last partition entry on the previous disk */
2157*84f3e2dfSHermès Bélusca-Maïto     for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2158*84f3e2dfSHermès Bélusca-Maïto                                       : List->DiskListHead.Blink);
21598bed4adfSHermès Bélusca-Maïto          DiskListEntry != &List->DiskListHead;
21608bed4adfSHermès Bélusca-Maïto          DiskListEntry = DiskListEntry->Blink)
21616f19c83bSHermès Bélusca-Maïto     {
2162*84f3e2dfSHermès Bélusca-Maïto         CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
21636f19c83bSHermès Bélusca-Maïto 
2164*84f3e2dfSHermès Bélusca-Maïto         if (CurrentDisk->DiskStyle == PARTITION_STYLE_GPT)
2165a3168373SHermès Bélusca-Maïto         {
2166a3168373SHermès Bélusca-Maïto             DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2167a3168373SHermès Bélusca-Maïto             continue;
2168a3168373SHermès Bélusca-Maïto         }
2169a3168373SHermès Bélusca-Maïto 
2170*84f3e2dfSHermès Bélusca-Maïto         PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2171*84f3e2dfSHermès Bélusca-Maïto         if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
21726f19c83bSHermès Bélusca-Maïto         {
2173*84f3e2dfSHermès Bélusca-Maïto             CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
21746f19c83bSHermès Bélusca-Maïto 
2175*84f3e2dfSHermès Bélusca-Maïto             if (CurrentPart->IsPartitioned &&
2176*84f3e2dfSHermès Bélusca-Maïto                 IsContainerPartition(CurrentPart->PartitionType))
21776f19c83bSHermès Bélusca-Maïto             {
2178*84f3e2dfSHermès Bélusca-Maïto                 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2179*84f3e2dfSHermès Bélusca-Maïto                 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
21806f19c83bSHermès Bélusca-Maïto                 {
2181*84f3e2dfSHermès Bélusca-Maïto                     CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2182*84f3e2dfSHermès Bélusca-Maïto                     return CurrentPart;
21836f19c83bSHermès Bélusca-Maïto                 }
21846f19c83bSHermès Bélusca-Maïto             }
21856f19c83bSHermès Bélusca-Maïto             else
21866f19c83bSHermès Bélusca-Maïto             {
2187*84f3e2dfSHermès Bélusca-Maïto                 return CurrentPart;
21886f19c83bSHermès Bélusca-Maïto             }
21896f19c83bSHermès Bélusca-Maïto         }
21906f19c83bSHermès Bélusca-Maïto     }
21916f19c83bSHermès Bélusca-Maïto 
21926f19c83bSHermès Bélusca-Maïto     return NULL;
21936f19c83bSHermès Bélusca-Maïto }
21946f19c83bSHermès Bélusca-Maïto 
21956f19c83bSHermès Bélusca-Maïto // static
21966f19c83bSHermès Bélusca-Maïto FORCEINLINE
21976f19c83bSHermès Bélusca-Maïto BOOLEAN
21986f19c83bSHermès Bélusca-Maïto IsEmptyLayoutEntry(
21996f19c83bSHermès Bélusca-Maïto     IN PPARTITION_INFORMATION PartitionInfo)
22006f19c83bSHermès Bélusca-Maïto {
22016f19c83bSHermès Bélusca-Maïto     if (PartitionInfo->StartingOffset.QuadPart == 0 &&
22026f19c83bSHermès Bélusca-Maïto         PartitionInfo->PartitionLength.QuadPart == 0)
22036f19c83bSHermès Bélusca-Maïto     {
22046f19c83bSHermès Bélusca-Maïto         return TRUE;
22056f19c83bSHermès Bélusca-Maïto     }
22066f19c83bSHermès Bélusca-Maïto 
22076f19c83bSHermès Bélusca-Maïto     return FALSE;
22086f19c83bSHermès Bélusca-Maïto }
22096f19c83bSHermès Bélusca-Maïto 
22106f19c83bSHermès Bélusca-Maïto // static
22116f19c83bSHermès Bélusca-Maïto FORCEINLINE
22126f19c83bSHermès Bélusca-Maïto BOOLEAN
22136f19c83bSHermès Bélusca-Maïto IsSamePrimaryLayoutEntry(
22146f19c83bSHermès Bélusca-Maïto     IN PPARTITION_INFORMATION PartitionInfo,
22156f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
22166f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
22176f19c83bSHermès Bélusca-Maïto {
22186f19c83bSHermès Bélusca-Maïto     if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector &&
22196f19c83bSHermès Bélusca-Maïto         PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector)
22206f19c83bSHermès Bélusca-Maïto //        PartitionInfo->PartitionType == PartEntry->PartitionType
22216f19c83bSHermès Bélusca-Maïto     {
22226f19c83bSHermès Bélusca-Maïto         return TRUE;
22236f19c83bSHermès Bélusca-Maïto     }
22246f19c83bSHermès Bélusca-Maïto 
22256f19c83bSHermès Bélusca-Maïto     return FALSE;
22266f19c83bSHermès Bélusca-Maïto }
22276f19c83bSHermès Bélusca-Maïto 
22286f19c83bSHermès Bélusca-Maïto static
22296f19c83bSHermès Bélusca-Maïto ULONG
22306f19c83bSHermès Bélusca-Maïto GetPrimaryPartitionCount(
22316f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
22326f19c83bSHermès Bélusca-Maïto {
22336f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
22346f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
22356f19c83bSHermès Bélusca-Maïto     ULONG Count = 0;
22366f19c83bSHermès Bélusca-Maïto 
2237a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2238a3168373SHermès Bélusca-Maïto     {
2239a3168373SHermès Bélusca-Maïto         DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2240a3168373SHermès Bélusca-Maïto         return 0;
2241a3168373SHermès Bélusca-Maïto     }
2242a3168373SHermès Bélusca-Maïto 
22438bed4adfSHermès Bélusca-Maïto     for (Entry = DiskEntry->PrimaryPartListHead.Flink;
22448bed4adfSHermès Bélusca-Maïto          Entry != &DiskEntry->PrimaryPartListHead;
22458bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
22466f19c83bSHermès Bélusca-Maïto     {
22476f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
22486f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
22496f19c83bSHermès Bélusca-Maïto             Count++;
22506f19c83bSHermès Bélusca-Maïto     }
22516f19c83bSHermès Bélusca-Maïto 
22526f19c83bSHermès Bélusca-Maïto     return Count;
22536f19c83bSHermès Bélusca-Maïto }
22546f19c83bSHermès Bélusca-Maïto 
22556f19c83bSHermès Bélusca-Maïto static
22566f19c83bSHermès Bélusca-Maïto ULONG
22576f19c83bSHermès Bélusca-Maïto GetLogicalPartitionCount(
22586f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
22596f19c83bSHermès Bélusca-Maïto {
22606f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
22616f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
22626f19c83bSHermès Bélusca-Maïto     ULONG Count = 0;
22636f19c83bSHermès Bélusca-Maïto 
2264a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2265a3168373SHermès Bélusca-Maïto     {
2266a3168373SHermès Bélusca-Maïto         DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2267a3168373SHermès Bélusca-Maïto         return 0;
2268a3168373SHermès Bélusca-Maïto     }
2269a3168373SHermès Bélusca-Maïto 
22708bed4adfSHermès Bélusca-Maïto     for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
22718bed4adfSHermès Bélusca-Maïto          ListEntry != &DiskEntry->LogicalPartListHead;
22728bed4adfSHermès Bélusca-Maïto          ListEntry = ListEntry->Flink)
22736f19c83bSHermès Bélusca-Maïto     {
22746f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
22756f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
22766f19c83bSHermès Bélusca-Maïto             Count++;
22776f19c83bSHermès Bélusca-Maïto     }
22786f19c83bSHermès Bélusca-Maïto 
22796f19c83bSHermès Bélusca-Maïto     return Count;
22806f19c83bSHermès Bélusca-Maïto }
22816f19c83bSHermès Bélusca-Maïto 
22826f19c83bSHermès Bélusca-Maïto static
22836f19c83bSHermès Bélusca-Maïto BOOLEAN
22846f19c83bSHermès Bélusca-Maïto ReAllocateLayoutBuffer(
22856f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
22866f19c83bSHermès Bélusca-Maïto {
22876f19c83bSHermès Bélusca-Maïto     PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
22886f19c83bSHermès Bélusca-Maïto     ULONG NewPartitionCount;
22896f19c83bSHermès Bélusca-Maïto     ULONG CurrentPartitionCount = 0;
22906f19c83bSHermès Bélusca-Maïto     ULONG LayoutBufferSize;
22916f19c83bSHermès Bélusca-Maïto     ULONG i;
22926f19c83bSHermès Bélusca-Maïto 
22936f19c83bSHermès Bélusca-Maïto     DPRINT1("ReAllocateLayoutBuffer()\n");
22946f19c83bSHermès Bélusca-Maïto 
22956f19c83bSHermès Bélusca-Maïto     NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
22966f19c83bSHermès Bélusca-Maïto 
22976f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer)
22986f19c83bSHermès Bélusca-Maïto         CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
22996f19c83bSHermès Bélusca-Maïto 
23007df92966SHermès Bélusca-Maïto     DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
23016f19c83bSHermès Bélusca-Maïto             CurrentPartitionCount, NewPartitionCount);
23026f19c83bSHermès Bélusca-Maïto 
23036f19c83bSHermès Bélusca-Maïto     if (CurrentPartitionCount == NewPartitionCount)
23046f19c83bSHermès Bélusca-Maïto         return TRUE;
23056f19c83bSHermès Bélusca-Maïto 
23066f19c83bSHermès Bélusca-Maïto     LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
23076f19c83bSHermès Bélusca-Maïto                        ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
23086f19c83bSHermès Bélusca-Maïto     NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
23096f19c83bSHermès Bélusca-Maïto                                         HEAP_ZERO_MEMORY,
23106f19c83bSHermès Bélusca-Maïto                                         DiskEntry->LayoutBuffer,
23116f19c83bSHermès Bélusca-Maïto                                         LayoutBufferSize);
23126f19c83bSHermès Bélusca-Maïto     if (NewLayoutBuffer == NULL)
23136f19c83bSHermès Bélusca-Maïto     {
23146f19c83bSHermès Bélusca-Maïto         DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
23156f19c83bSHermès Bélusca-Maïto         return FALSE;
23166f19c83bSHermès Bélusca-Maïto     }
23176f19c83bSHermès Bélusca-Maïto 
23187df92966SHermès Bélusca-Maïto     NewLayoutBuffer->PartitionCount = NewPartitionCount;
23197df92966SHermès Bélusca-Maïto 
23206f19c83bSHermès Bélusca-Maïto     /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
23216f19c83bSHermès Bélusca-Maïto     if (NewPartitionCount > CurrentPartitionCount)
23226f19c83bSHermès Bélusca-Maïto     {
23236f19c83bSHermès Bélusca-Maïto         for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
23247df92966SHermès Bélusca-Maïto         {
23256f19c83bSHermès Bélusca-Maïto             NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
23266f19c83bSHermès Bélusca-Maïto         }
23277df92966SHermès Bélusca-Maïto     }
23286f19c83bSHermès Bélusca-Maïto 
23296f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer = NewLayoutBuffer;
23306f19c83bSHermès Bélusca-Maïto 
23316f19c83bSHermès Bélusca-Maïto     return TRUE;
23326f19c83bSHermès Bélusca-Maïto }
23336f19c83bSHermès Bélusca-Maïto 
23346f19c83bSHermès Bélusca-Maïto static
23356f19c83bSHermès Bélusca-Maïto VOID
23366f19c83bSHermès Bélusca-Maïto UpdateDiskLayout(
23376f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
23386f19c83bSHermès Bélusca-Maïto {
23396f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
23406f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION LinkInfo = NULL;
23416f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
23426f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
23436f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER HiddenSectors64;
23446f19c83bSHermès Bélusca-Maïto     ULONG Index;
23456f19c83bSHermès Bélusca-Maïto     ULONG PartitionNumber = 1;
23466f19c83bSHermès Bélusca-Maïto 
23476f19c83bSHermès Bélusca-Maïto     DPRINT1("UpdateDiskLayout()\n");
23486f19c83bSHermès Bélusca-Maïto 
2349a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2350a3168373SHermès Bélusca-Maïto     {
235129cc1843SHermès Bélusca-Maïto         DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2352a3168373SHermès Bélusca-Maïto         return;
2353a3168373SHermès Bélusca-Maïto     }
2354a3168373SHermès Bélusca-Maïto 
23556f19c83bSHermès Bélusca-Maïto     /* Resize the layout buffer if necessary */
23566f19c83bSHermès Bélusca-Maïto     if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
23576f19c83bSHermès Bélusca-Maïto     {
23586f19c83bSHermès Bélusca-Maïto         DPRINT("ReAllocateLayoutBuffer() failed.\n");
23596f19c83bSHermès Bélusca-Maïto         return;
23606f19c83bSHermès Bélusca-Maïto     }
23616f19c83bSHermès Bélusca-Maïto 
23626f19c83bSHermès Bélusca-Maïto     /* Update the primary partition table */
23636f19c83bSHermès Bélusca-Maïto     Index = 0;
23648bed4adfSHermès Bélusca-Maïto     for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
23658bed4adfSHermès Bélusca-Maïto          ListEntry != &DiskEntry->PrimaryPartListHead;
23668bed4adfSHermès Bélusca-Maïto          ListEntry = ListEntry->Flink)
23676f19c83bSHermès Bélusca-Maïto     {
23686f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
23696f19c83bSHermès Bélusca-Maïto 
23707df92966SHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
23716f19c83bSHermès Bélusca-Maïto         {
237229cc1843SHermès Bélusca-Maïto             ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
237329cc1843SHermès Bélusca-Maïto 
23746f19c83bSHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
23757df92966SHermès Bélusca-Maïto             PartEntry->PartitionIndex = Index;
23767df92966SHermès Bélusca-Maïto 
237729cc1843SHermès Bélusca-Maïto             /* Reset the current partition number only for newly-created (unmounted) partitions */
23787df92966SHermès Bélusca-Maïto             if (PartEntry->New)
23797df92966SHermès Bélusca-Maïto                 PartEntry->PartitionNumber = 0;
23807df92966SHermès Bélusca-Maïto 
238129cc1843SHermès Bélusca-Maïto             PartEntry->OnDiskPartitionNumber = (!IsContainerPartition(PartEntry->PartitionType) ? PartitionNumber : 0);
23826f19c83bSHermès Bélusca-Maïto 
23836f19c83bSHermès Bélusca-Maïto             if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
23846f19c83bSHermès Bélusca-Maïto             {
23856f19c83bSHermès Bélusca-Maïto                 DPRINT1("Updating primary partition entry %lu\n", Index);
23866f19c83bSHermès Bélusca-Maïto 
23876f19c83bSHermès Bélusca-Maïto                 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
23886f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
23896f19c83bSHermès Bélusca-Maïto                 PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart;
23907df92966SHermès Bélusca-Maïto                 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
23916f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionType = PartEntry->PartitionType;
23926f19c83bSHermès Bélusca-Maïto                 PartitionInfo->BootIndicator = PartEntry->BootIndicator;
23937df92966SHermès Bélusca-Maïto                 PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
23946f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RewritePartition = TRUE;
23956f19c83bSHermès Bélusca-Maïto             }
23966f19c83bSHermès Bélusca-Maïto 
23976f19c83bSHermès Bélusca-Maïto             if (!IsContainerPartition(PartEntry->PartitionType))
23986f19c83bSHermès Bélusca-Maïto                 PartitionNumber++;
23996f19c83bSHermès Bélusca-Maïto 
24006f19c83bSHermès Bélusca-Maïto             Index++;
24016f19c83bSHermès Bélusca-Maïto         }
24026f19c83bSHermès Bélusca-Maïto     }
24036f19c83bSHermès Bélusca-Maïto 
240470fa2e2eSHermès Bélusca-Maïto     ASSERT(Index <= 4);
240570fa2e2eSHermès Bélusca-Maïto 
24066f19c83bSHermès Bélusca-Maïto     /* Update the logical partition table */
24076f19c83bSHermès Bélusca-Maïto     Index = 4;
24088bed4adfSHermès Bélusca-Maïto     for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
24098bed4adfSHermès Bélusca-Maïto          ListEntry != &DiskEntry->LogicalPartListHead;
24108bed4adfSHermès Bélusca-Maïto          ListEntry = ListEntry->Flink)
24116f19c83bSHermès Bélusca-Maïto     {
24126f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
24136f19c83bSHermès Bélusca-Maïto 
24146f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
24156f19c83bSHermès Bélusca-Maïto         {
241629cc1843SHermès Bélusca-Maïto             ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
241729cc1843SHermès Bélusca-Maïto 
24186f19c83bSHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
24197df92966SHermès Bélusca-Maïto             PartEntry->PartitionIndex = Index;
24206f19c83bSHermès Bélusca-Maïto 
242129cc1843SHermès Bélusca-Maïto             /* Reset the current partition number only for newly-created (unmounted) partitions */
24227df92966SHermès Bélusca-Maïto             if (PartEntry->New)
24237df92966SHermès Bélusca-Maïto                 PartEntry->PartitionNumber = 0;
24247df92966SHermès Bélusca-Maïto 
24257df92966SHermès Bélusca-Maïto             PartEntry->OnDiskPartitionNumber = PartitionNumber;
24267df92966SHermès Bélusca-Maïto 
242729cc1843SHermès Bélusca-Maïto             DPRINT1("Updating logical partition entry %lu\n", Index);
242829cc1843SHermès Bélusca-Maïto 
24296f19c83bSHermès Bélusca-Maïto             PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
24306f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
24316f19c83bSHermès Bélusca-Maïto             PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment;
24327df92966SHermès Bélusca-Maïto             PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
24336f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionType = PartEntry->PartitionType;
24346f19c83bSHermès Bélusca-Maïto             PartitionInfo->BootIndicator = FALSE;
24357df92966SHermès Bélusca-Maïto             PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
24366f19c83bSHermès Bélusca-Maïto             PartitionInfo->RewritePartition = TRUE;
24376f19c83bSHermès Bélusca-Maïto 
24386f19c83bSHermès Bélusca-Maïto             /* Fill the link entry of the previous partition entry */
24396f19c83bSHermès Bélusca-Maïto             if (LinkInfo != NULL)
24406f19c83bSHermès Bélusca-Maïto             {
24416f19c83bSHermès Bélusca-Maïto                 LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
24426f19c83bSHermès Bélusca-Maïto                 LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
24436f19c83bSHermès Bélusca-Maïto                 HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
24446f19c83bSHermès Bélusca-Maïto                 LinkInfo->HiddenSectors = HiddenSectors64.LowPart;
24456f19c83bSHermès Bélusca-Maïto                 LinkInfo->PartitionNumber = 0;
24466f19c83bSHermès Bélusca-Maïto                 LinkInfo->PartitionType = PARTITION_EXTENDED;
24476f19c83bSHermès Bélusca-Maïto                 LinkInfo->BootIndicator = FALSE;
24486f19c83bSHermès Bélusca-Maïto                 LinkInfo->RecognizedPartition = FALSE;
24496f19c83bSHermès Bélusca-Maïto                 LinkInfo->RewritePartition = TRUE;
24506f19c83bSHermès Bélusca-Maïto             }
24516f19c83bSHermès Bélusca-Maïto 
24526f19c83bSHermès Bélusca-Maïto             /* Save a pointer to the link entry of the current partition entry */
24536f19c83bSHermès Bélusca-Maïto             LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
24546f19c83bSHermès Bélusca-Maïto 
24556f19c83bSHermès Bélusca-Maïto             PartitionNumber++;
24566f19c83bSHermès Bélusca-Maïto             Index += 4;
24576f19c83bSHermès Bélusca-Maïto         }
24586f19c83bSHermès Bélusca-Maïto     }
24596f19c83bSHermès Bélusca-Maïto 
24606f19c83bSHermès Bélusca-Maïto     /* Wipe unused primary partition entries */
24616f19c83bSHermès Bélusca-Maïto     for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
24626f19c83bSHermès Bélusca-Maïto     {
24636f19c83bSHermès Bélusca-Maïto         DPRINT1("Primary partition entry %lu\n", Index);
24646f19c83bSHermès Bélusca-Maïto 
24656f19c83bSHermès Bélusca-Maïto         PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
24666f19c83bSHermès Bélusca-Maïto 
24676f19c83bSHermès Bélusca-Maïto         if (!IsEmptyLayoutEntry(PartitionInfo))
24686f19c83bSHermès Bélusca-Maïto         {
24696f19c83bSHermès Bélusca-Maïto             DPRINT1("Wiping primary partition entry %lu\n", Index);
24706f19c83bSHermès Bélusca-Maïto 
24716f19c83bSHermès Bélusca-Maïto             PartitionInfo->StartingOffset.QuadPart = 0;
24726f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionLength.QuadPart = 0;
24736f19c83bSHermès Bélusca-Maïto             PartitionInfo->HiddenSectors = 0;
24746f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionNumber = 0;
24756f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
24766f19c83bSHermès Bélusca-Maïto             PartitionInfo->BootIndicator = FALSE;
24776f19c83bSHermès Bélusca-Maïto             PartitionInfo->RecognizedPartition = FALSE;
24786f19c83bSHermès Bélusca-Maïto             PartitionInfo->RewritePartition = TRUE;
24796f19c83bSHermès Bélusca-Maïto         }
24806f19c83bSHermès Bélusca-Maïto     }
24816f19c83bSHermès Bélusca-Maïto 
24826f19c83bSHermès Bélusca-Maïto     /* Wipe unused logical partition entries */
24836f19c83bSHermès Bélusca-Maïto     for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
24846f19c83bSHermès Bélusca-Maïto     {
24856f19c83bSHermès Bélusca-Maïto         if (Index % 4 >= 2)
24866f19c83bSHermès Bélusca-Maïto         {
24876f19c83bSHermès Bélusca-Maïto             DPRINT1("Logical partition entry %lu\n", Index);
24886f19c83bSHermès Bélusca-Maïto 
24896f19c83bSHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
24906f19c83bSHermès Bélusca-Maïto 
24916f19c83bSHermès Bélusca-Maïto             if (!IsEmptyLayoutEntry(PartitionInfo))
24926f19c83bSHermès Bélusca-Maïto             {
24936f19c83bSHermès Bélusca-Maïto                 DPRINT1("Wiping partition entry %lu\n", Index);
24946f19c83bSHermès Bélusca-Maïto 
24956f19c83bSHermès Bélusca-Maïto                 PartitionInfo->StartingOffset.QuadPart = 0;
24966f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionLength.QuadPart = 0;
24976f19c83bSHermès Bélusca-Maïto                 PartitionInfo->HiddenSectors = 0;
24986f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionNumber = 0;
24996f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
25006f19c83bSHermès Bélusca-Maïto                 PartitionInfo->BootIndicator = FALSE;
25016f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RecognizedPartition = FALSE;
25026f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RewritePartition = TRUE;
25036f19c83bSHermès Bélusca-Maïto             }
25046f19c83bSHermès Bélusca-Maïto         }
25056f19c83bSHermès Bélusca-Maïto     }
25066f19c83bSHermès Bélusca-Maïto 
25077df92966SHermès Bélusca-Maïto     DiskEntry->Dirty = TRUE;
25087df92966SHermès Bélusca-Maïto 
25096f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
25106f19c83bSHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
25116f19c83bSHermès Bélusca-Maïto #endif
25126f19c83bSHermès Bélusca-Maïto }
25136f19c83bSHermès Bélusca-Maïto 
25146f19c83bSHermès Bélusca-Maïto static
25156f19c83bSHermès Bélusca-Maïto PPARTENTRY
25166f19c83bSHermès Bélusca-Maïto GetPrevUnpartitionedEntry(
25176f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
25186f19c83bSHermès Bélusca-Maïto {
2519*84f3e2dfSHermès Bélusca-Maïto     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
25206f19c83bSHermès Bélusca-Maïto     PPARTENTRY PrevPartEntry;
25216f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListHead;
25226f19c83bSHermès Bélusca-Maïto 
2523a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2524a3168373SHermès Bélusca-Maïto     {
2525a3168373SHermès Bélusca-Maïto         DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2526a3168373SHermès Bélusca-Maïto         return NULL;
2527a3168373SHermès Bélusca-Maïto     }
2528a3168373SHermès Bélusca-Maïto 
25296f19c83bSHermès Bélusca-Maïto     if (PartEntry->LogicalPartition)
25306f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->LogicalPartListHead;
25316f19c83bSHermès Bélusca-Maïto     else
25326f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->PrimaryPartListHead;
25336f19c83bSHermès Bélusca-Maïto 
25346f19c83bSHermès Bélusca-Maïto     if (PartEntry->ListEntry.Blink != ListHead)
25356f19c83bSHermès Bélusca-Maïto     {
25366f19c83bSHermès Bélusca-Maïto         PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
25376f19c83bSHermès Bélusca-Maïto                                           PARTENTRY,
25386f19c83bSHermès Bélusca-Maïto                                           ListEntry);
2539*84f3e2dfSHermès Bélusca-Maïto         if (!PrevPartEntry->IsPartitioned)
254029cc1843SHermès Bélusca-Maïto         {
254129cc1843SHermès Bélusca-Maïto             ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
25426f19c83bSHermès Bélusca-Maïto             return PrevPartEntry;
25436f19c83bSHermès Bélusca-Maïto         }
254429cc1843SHermès Bélusca-Maïto     }
25456f19c83bSHermès Bélusca-Maïto 
25466f19c83bSHermès Bélusca-Maïto     return NULL;
25476f19c83bSHermès Bélusca-Maïto }
25486f19c83bSHermès Bélusca-Maïto 
25496f19c83bSHermès Bélusca-Maïto static
25506f19c83bSHermès Bélusca-Maïto PPARTENTRY
25516f19c83bSHermès Bélusca-Maïto GetNextUnpartitionedEntry(
25526f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
25536f19c83bSHermès Bélusca-Maïto {
2554*84f3e2dfSHermès Bélusca-Maïto     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
25556f19c83bSHermès Bélusca-Maïto     PPARTENTRY NextPartEntry;
25566f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListHead;
25576f19c83bSHermès Bélusca-Maïto 
2558a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2559a3168373SHermès Bélusca-Maïto     {
2560a3168373SHermès Bélusca-Maïto         DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2561a3168373SHermès Bélusca-Maïto         return NULL;
2562a3168373SHermès Bélusca-Maïto     }
2563a3168373SHermès Bélusca-Maïto 
25646f19c83bSHermès Bélusca-Maïto     if (PartEntry->LogicalPartition)
25656f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->LogicalPartListHead;
25666f19c83bSHermès Bélusca-Maïto     else
25676f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->PrimaryPartListHead;
25686f19c83bSHermès Bélusca-Maïto 
25696f19c83bSHermès Bélusca-Maïto     if (PartEntry->ListEntry.Flink != ListHead)
25706f19c83bSHermès Bélusca-Maïto     {
25716f19c83bSHermès Bélusca-Maïto         NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
25726f19c83bSHermès Bélusca-Maïto                                           PARTENTRY,
25736f19c83bSHermès Bélusca-Maïto                                           ListEntry);
2574*84f3e2dfSHermès Bélusca-Maïto         if (!NextPartEntry->IsPartitioned)
257529cc1843SHermès Bélusca-Maïto         {
257629cc1843SHermès Bélusca-Maïto             ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
25776f19c83bSHermès Bélusca-Maïto             return NextPartEntry;
25786f19c83bSHermès Bélusca-Maïto         }
257929cc1843SHermès Bélusca-Maïto     }
25806f19c83bSHermès Bélusca-Maïto 
25816f19c83bSHermès Bélusca-Maïto     return NULL;
25826f19c83bSHermès Bélusca-Maïto }
25836f19c83bSHermès Bélusca-Maïto 
258470fa2e2eSHermès Bélusca-Maïto BOOLEAN
25856f19c83bSHermès Bélusca-Maïto CreatePrimaryPartition(
25866f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
258729cc1843SHermès Bélusca-Maïto     IN PPARTENTRY SelectedEntry,
25886f19c83bSHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
25896f19c83bSHermès Bélusca-Maïto     IN BOOLEAN AutoCreate)
25906f19c83bSHermès Bélusca-Maïto {
259170fa2e2eSHermès Bélusca-Maïto     ERROR_NUMBER Error;
25926f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
25936f19c83bSHermès Bélusca-Maïto 
25946f19c83bSHermès Bélusca-Maïto     DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
25956f19c83bSHermès Bélusca-Maïto 
25966f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
259729cc1843SHermès Bélusca-Maïto         SelectedEntry == NULL ||
259829cc1843SHermès Bélusca-Maïto         SelectedEntry->DiskEntry == NULL ||
259929cc1843SHermès Bélusca-Maïto         SelectedEntry->IsPartitioned)
26006f19c83bSHermès Bélusca-Maïto     {
260170fa2e2eSHermès Bélusca-Maïto         return FALSE;
260270fa2e2eSHermès Bélusca-Maïto     }
260370fa2e2eSHermès Bélusca-Maïto 
260429cc1843SHermès Bélusca-Maïto     Error = PrimaryPartitionCreationChecks(SelectedEntry);
260570fa2e2eSHermès Bélusca-Maïto     if (Error != NOT_AN_ERROR)
260670fa2e2eSHermès Bélusca-Maïto     {
260770fa2e2eSHermès Bélusca-Maïto         DPRINT1("PrimaryPartitionCreationChecks() failed with error %lu\n", Error);
260870fa2e2eSHermès Bélusca-Maïto         return FALSE;
26096f19c83bSHermès Bélusca-Maïto     }
26106f19c83bSHermès Bélusca-Maïto 
26117df92966SHermès Bélusca-Maïto     /* Convert the current entry, or insert and initialize a new partition entry */
261229cc1843SHermès Bélusca-Maïto     PartEntry = InitializePartitionEntry(SelectedEntry->DiskEntry, SelectedEntry, SectorCount, AutoCreate);
26137df92966SHermès Bélusca-Maïto     if (PartEntry == NULL)
261470fa2e2eSHermès Bélusca-Maïto         return FALSE;
26156f19c83bSHermès Bélusca-Maïto 
261629cc1843SHermès Bélusca-Maïto     UpdateDiskLayout(PartEntry->DiskEntry);
26176f19c83bSHermès Bélusca-Maïto 
26186f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
261970fa2e2eSHermès Bélusca-Maïto 
262070fa2e2eSHermès Bélusca-Maïto     return TRUE;
26216f19c83bSHermès Bélusca-Maïto }
26226f19c83bSHermès Bélusca-Maïto 
26236f19c83bSHermès Bélusca-Maïto static
26246f19c83bSHermès Bélusca-Maïto VOID
26256f19c83bSHermès Bélusca-Maïto AddLogicalDiskSpace(
26266f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
26276f19c83bSHermès Bélusca-Maïto {
26287df92966SHermès Bélusca-Maïto     ULONGLONG StartSector;
26297df92966SHermès Bélusca-Maïto     ULONGLONG SectorCount;
26306f19c83bSHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
26316f19c83bSHermès Bélusca-Maïto 
26326f19c83bSHermès Bélusca-Maïto     DPRINT1("AddLogicalDiskSpace()\n");
26336f19c83bSHermès Bélusca-Maïto 
26346f19c83bSHermès Bélusca-Maïto     /* Create a partition entry that represents the empty space in the container partition */
26357df92966SHermès Bélusca-Maïto 
26367df92966SHermès Bélusca-Maïto     StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
26377df92966SHermès Bélusca-Maïto     SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
26387df92966SHermès Bélusca-Maïto 
26397df92966SHermès Bélusca-Maïto     NewPartEntry = CreateInsertBlankRegion(DiskEntry,
26407df92966SHermès Bélusca-Maïto                                            &DiskEntry->LogicalPartListHead,
26417df92966SHermès Bélusca-Maïto                                            StartSector,
26427df92966SHermès Bélusca-Maïto                                            SectorCount,
26437df92966SHermès Bélusca-Maïto                                            TRUE);
26446f19c83bSHermès Bélusca-Maïto     if (NewPartEntry == NULL)
26457df92966SHermès Bélusca-Maïto     {
26467df92966SHermès Bélusca-Maïto         DPRINT1("Failed to create a new empty region for extended partition space!\n");
26476f19c83bSHermès Bélusca-Maïto         return;
26487df92966SHermès Bélusca-Maïto     }
26496f19c83bSHermès Bélusca-Maïto     NewPartEntry->LogicalPartition = TRUE;
26506f19c83bSHermès Bélusca-Maïto }
26516f19c83bSHermès Bélusca-Maïto 
265270fa2e2eSHermès Bélusca-Maïto BOOLEAN
26536f19c83bSHermès Bélusca-Maïto CreateExtendedPartition(
26546f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
265529cc1843SHermès Bélusca-Maïto     IN PPARTENTRY SelectedEntry,
26566f19c83bSHermès Bélusca-Maïto     IN ULONGLONG SectorCount)
26576f19c83bSHermès Bélusca-Maïto {
265870fa2e2eSHermès Bélusca-Maïto     ERROR_NUMBER Error;
26596f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
26606f19c83bSHermès Bélusca-Maïto 
26616f19c83bSHermès Bélusca-Maïto     DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
26626f19c83bSHermès Bélusca-Maïto 
26636f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
266429cc1843SHermès Bélusca-Maïto         SelectedEntry == NULL ||
266529cc1843SHermès Bélusca-Maïto         SelectedEntry->DiskEntry == NULL ||
266629cc1843SHermès Bélusca-Maïto         SelectedEntry->IsPartitioned)
26676f19c83bSHermès Bélusca-Maïto     {
266870fa2e2eSHermès Bélusca-Maïto         return FALSE;
266970fa2e2eSHermès Bélusca-Maïto     }
267070fa2e2eSHermès Bélusca-Maïto 
267129cc1843SHermès Bélusca-Maïto     Error = ExtendedPartitionCreationChecks(SelectedEntry);
267270fa2e2eSHermès Bélusca-Maïto     if (Error != NOT_AN_ERROR)
267370fa2e2eSHermès Bélusca-Maïto     {
267470fa2e2eSHermès Bélusca-Maïto         DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
267570fa2e2eSHermès Bélusca-Maïto         return FALSE;
26766f19c83bSHermès Bélusca-Maïto     }
26776f19c83bSHermès Bélusca-Maïto 
26787df92966SHermès Bélusca-Maïto     /* Convert the current entry, or insert and initialize a new partition entry */
267929cc1843SHermès Bélusca-Maïto     PartEntry = InitializePartitionEntry(SelectedEntry->DiskEntry, SelectedEntry, SectorCount, FALSE);
26807df92966SHermès Bélusca-Maïto     if (PartEntry == NULL)
26817df92966SHermès Bélusca-Maïto         return FALSE;
26826f19c83bSHermès Bélusca-Maïto 
26836f19c83bSHermès Bélusca-Maïto     if (PartEntry->StartSector.QuadPart < 1450560)
26846f19c83bSHermès Bélusca-Maïto     {
26856f19c83bSHermès Bélusca-Maïto         /* Partition starts below the 8.4GB boundary ==> CHS partition */
26866f19c83bSHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_EXTENDED;
26876f19c83bSHermès Bélusca-Maïto     }
26886f19c83bSHermès Bélusca-Maïto     else
26896f19c83bSHermès Bélusca-Maïto     {
26906f19c83bSHermès Bélusca-Maïto         /* Partition starts above the 8.4GB boundary ==> LBA partition */
26916f19c83bSHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
26926f19c83bSHermès Bélusca-Maïto     }
26936f19c83bSHermès Bélusca-Maïto 
26947df92966SHermès Bélusca-Maïto     // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
26957df92966SHermès Bélusca-Maïto     PartEntry->New = FALSE;
26967df92966SHermès Bélusca-Maïto     PartEntry->FormatState = Formatted;
26977df92966SHermès Bélusca-Maïto 
269829cc1843SHermès Bélusca-Maïto     PartEntry->DiskEntry->ExtendedPartition = PartEntry;
26996f19c83bSHermès Bélusca-Maïto 
270029cc1843SHermès Bélusca-Maïto     AddLogicalDiskSpace(PartEntry->DiskEntry);
27016f19c83bSHermès Bélusca-Maïto 
270229cc1843SHermès Bélusca-Maïto     UpdateDiskLayout(PartEntry->DiskEntry);
27036f19c83bSHermès Bélusca-Maïto 
27046f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
270570fa2e2eSHermès Bélusca-Maïto 
270670fa2e2eSHermès Bélusca-Maïto     return TRUE;
27076f19c83bSHermès Bélusca-Maïto }
27086f19c83bSHermès Bélusca-Maïto 
270970fa2e2eSHermès Bélusca-Maïto BOOLEAN
27106f19c83bSHermès Bélusca-Maïto CreateLogicalPartition(
27116f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
271229cc1843SHermès Bélusca-Maïto     IN PPARTENTRY SelectedEntry,
27136f19c83bSHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
27146f19c83bSHermès Bélusca-Maïto     IN BOOLEAN AutoCreate)
27156f19c83bSHermès Bélusca-Maïto {
271670fa2e2eSHermès Bélusca-Maïto     ERROR_NUMBER Error;
27176f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
27186f19c83bSHermès Bélusca-Maïto 
27196f19c83bSHermès Bélusca-Maïto     DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
27206f19c83bSHermès Bélusca-Maïto 
27216f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
272229cc1843SHermès Bélusca-Maïto         SelectedEntry == NULL ||
272329cc1843SHermès Bélusca-Maïto         SelectedEntry->DiskEntry == NULL ||
272429cc1843SHermès Bélusca-Maïto         SelectedEntry->IsPartitioned)
27256f19c83bSHermès Bélusca-Maïto     {
272670fa2e2eSHermès Bélusca-Maïto         return FALSE;
272770fa2e2eSHermès Bélusca-Maïto     }
272870fa2e2eSHermès Bélusca-Maïto 
272929cc1843SHermès Bélusca-Maïto     Error = LogicalPartitionCreationChecks(SelectedEntry);
273070fa2e2eSHermès Bélusca-Maïto     if (Error != NOT_AN_ERROR)
273170fa2e2eSHermès Bélusca-Maïto     {
273270fa2e2eSHermès Bélusca-Maïto         DPRINT1("LogicalPartitionCreationChecks() failed with error %lu\n", Error);
273370fa2e2eSHermès Bélusca-Maïto         return FALSE;
27346f19c83bSHermès Bélusca-Maïto     }
27356f19c83bSHermès Bélusca-Maïto 
27367df92966SHermès Bélusca-Maïto     /* Convert the current entry, or insert and initialize a new partition entry */
273729cc1843SHermès Bélusca-Maïto     PartEntry = InitializePartitionEntry(SelectedEntry->DiskEntry, SelectedEntry, SectorCount, AutoCreate);
27387df92966SHermès Bélusca-Maïto     if (PartEntry == NULL)
273970fa2e2eSHermès Bélusca-Maïto         return FALSE;
27406f19c83bSHermès Bélusca-Maïto 
27417df92966SHermès Bélusca-Maïto     PartEntry->LogicalPartition = TRUE;
27426f19c83bSHermès Bélusca-Maïto 
274329cc1843SHermès Bélusca-Maïto     UpdateDiskLayout(PartEntry->DiskEntry);
27446f19c83bSHermès Bélusca-Maïto 
27456f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
274670fa2e2eSHermès Bélusca-Maïto 
274770fa2e2eSHermès Bélusca-Maïto     return TRUE;
27486f19c83bSHermès Bélusca-Maïto }
27496f19c83bSHermès Bélusca-Maïto 
27509504a38fSHermès Bélusca-Maïto static
27519504a38fSHermès Bélusca-Maïto NTSTATUS
27529504a38fSHermès Bélusca-Maïto DismountVolume(
27539504a38fSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
27549504a38fSHermès Bélusca-Maïto {
27559504a38fSHermès Bélusca-Maïto     NTSTATUS Status;
27569504a38fSHermès Bélusca-Maïto     NTSTATUS LockStatus;
27579504a38fSHermès Bélusca-Maïto     UNICODE_STRING Name;
27589504a38fSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
27599504a38fSHermès Bélusca-Maïto     IO_STATUS_BLOCK IoStatusBlock;
27609504a38fSHermès Bélusca-Maïto     HANDLE PartitionHandle;
27619504a38fSHermès Bélusca-Maïto     WCHAR Buffer[MAX_PATH];
27629504a38fSHermès Bélusca-Maïto 
276329cc1843SHermès Bélusca-Maïto     /* Check whether the partition is valid and was mounted by the system */
27649504a38fSHermès Bélusca-Maïto     if (!PartEntry->IsPartitioned ||
27659504a38fSHermès Bélusca-Maïto         IsContainerPartition(PartEntry->PartitionType)   ||
27669504a38fSHermès Bélusca-Maïto         !IsRecognizedPartition(PartEntry->PartitionType) ||
27679504a38fSHermès Bélusca-Maïto         PartEntry->FormatState == Unformatted /* || PartEntry->FormatState == UnknownFormat */ ||
2768c1fbc2d6SHermès Bélusca-Maïto         !*PartEntry->FileSystem ||
27699504a38fSHermès Bélusca-Maïto         PartEntry->PartitionNumber == 0)
27709504a38fSHermès Bélusca-Maïto     {
27719504a38fSHermès Bélusca-Maïto         /* The partition is not mounted, so just return success */
27729504a38fSHermès Bélusca-Maïto         return STATUS_SUCCESS;
27739504a38fSHermès Bélusca-Maïto     }
27749504a38fSHermès Bélusca-Maïto 
277529cc1843SHermès Bélusca-Maïto     ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
277629cc1843SHermès Bélusca-Maïto 
27779504a38fSHermès Bélusca-Maïto     /* Open the volume */
27789504a38fSHermès Bélusca-Maïto     RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
27799504a38fSHermès Bélusca-Maïto                         L"\\Device\\Harddisk%lu\\Partition%lu",
27809504a38fSHermès Bélusca-Maïto                         PartEntry->DiskEntry->DiskNumber,
27819504a38fSHermès Bélusca-Maïto                         PartEntry->PartitionNumber);
27829504a38fSHermès Bélusca-Maïto     RtlInitUnicodeString(&Name, Buffer);
27839504a38fSHermès Bélusca-Maïto 
27849504a38fSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
27859504a38fSHermès Bélusca-Maïto                                &Name,
27869504a38fSHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
27879504a38fSHermès Bélusca-Maïto                                NULL,
27889504a38fSHermès Bélusca-Maïto                                NULL);
27899504a38fSHermès Bélusca-Maïto 
27909504a38fSHermès Bélusca-Maïto     Status = NtOpenFile(&PartitionHandle,
27919504a38fSHermès Bélusca-Maïto                         GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
27929504a38fSHermès Bélusca-Maïto                         &ObjectAttributes,
27939504a38fSHermès Bélusca-Maïto                         &IoStatusBlock,
27949504a38fSHermès Bélusca-Maïto                         FILE_SHARE_READ | FILE_SHARE_WRITE,
27959504a38fSHermès Bélusca-Maïto                         FILE_SYNCHRONOUS_IO_NONALERT);
27969504a38fSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
27979504a38fSHermès Bélusca-Maïto     {
27989504a38fSHermès Bélusca-Maïto         DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
27999504a38fSHermès Bélusca-Maïto         return Status;
28009504a38fSHermès Bélusca-Maïto     }
28019504a38fSHermès Bélusca-Maïto 
28029504a38fSHermès Bélusca-Maïto     /* Lock the volume */
28039504a38fSHermès Bélusca-Maïto     LockStatus = NtFsControlFile(PartitionHandle,
28049504a38fSHermès Bélusca-Maïto                                  NULL,
28059504a38fSHermès Bélusca-Maïto                                  NULL,
28069504a38fSHermès Bélusca-Maïto                                  NULL,
28079504a38fSHermès Bélusca-Maïto                                  &IoStatusBlock,
28089504a38fSHermès Bélusca-Maïto                                  FSCTL_LOCK_VOLUME,
28099504a38fSHermès Bélusca-Maïto                                  NULL,
28109504a38fSHermès Bélusca-Maïto                                  0,
28119504a38fSHermès Bélusca-Maïto                                  NULL,
28129504a38fSHermès Bélusca-Maïto                                  0);
28139504a38fSHermès Bélusca-Maïto     if (!NT_SUCCESS(LockStatus))
28149504a38fSHermès Bélusca-Maïto     {
28159504a38fSHermès Bélusca-Maïto         DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
28169504a38fSHermès Bélusca-Maïto     }
28179504a38fSHermès Bélusca-Maïto 
28189504a38fSHermès Bélusca-Maïto     /* Dismount the volume */
28199504a38fSHermès Bélusca-Maïto     Status = NtFsControlFile(PartitionHandle,
28209504a38fSHermès Bélusca-Maïto                              NULL,
28219504a38fSHermès Bélusca-Maïto                              NULL,
28229504a38fSHermès Bélusca-Maïto                              NULL,
28239504a38fSHermès Bélusca-Maïto                              &IoStatusBlock,
28249504a38fSHermès Bélusca-Maïto                              FSCTL_DISMOUNT_VOLUME,
28259504a38fSHermès Bélusca-Maïto                              NULL,
28269504a38fSHermès Bélusca-Maïto                              0,
28279504a38fSHermès Bélusca-Maïto                              NULL,
28289504a38fSHermès Bélusca-Maïto                              0);
28299504a38fSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
28309504a38fSHermès Bélusca-Maïto     {
28319504a38fSHermès Bélusca-Maïto         DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
28329504a38fSHermès Bélusca-Maïto     }
28339504a38fSHermès Bélusca-Maïto 
28349504a38fSHermès Bélusca-Maïto     /* Unlock the volume */
28359504a38fSHermès Bélusca-Maïto     LockStatus = NtFsControlFile(PartitionHandle,
28369504a38fSHermès Bélusca-Maïto                                  NULL,
28379504a38fSHermès Bélusca-Maïto                                  NULL,
28389504a38fSHermès Bélusca-Maïto                                  NULL,
28399504a38fSHermès Bélusca-Maïto                                  &IoStatusBlock,
28409504a38fSHermès Bélusca-Maïto                                  FSCTL_UNLOCK_VOLUME,
28419504a38fSHermès Bélusca-Maïto                                  NULL,
28429504a38fSHermès Bélusca-Maïto                                  0,
28439504a38fSHermès Bélusca-Maïto                                  NULL,
28449504a38fSHermès Bélusca-Maïto                                  0);
28459504a38fSHermès Bélusca-Maïto     if (!NT_SUCCESS(LockStatus))
28469504a38fSHermès Bélusca-Maïto     {
28479504a38fSHermès Bélusca-Maïto         DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
28489504a38fSHermès Bélusca-Maïto     }
28499504a38fSHermès Bélusca-Maïto 
28509504a38fSHermès Bélusca-Maïto     /* Close the volume */
28519504a38fSHermès Bélusca-Maïto     NtClose(PartitionHandle);
28529504a38fSHermès Bélusca-Maïto 
28539504a38fSHermès Bélusca-Maïto     return Status;
28549504a38fSHermès Bélusca-Maïto }
28559504a38fSHermès Bélusca-Maïto 
2856*84f3e2dfSHermès Bélusca-Maïto BOOLEAN
285729cc1843SHermès Bélusca-Maïto DeletePartition(
285829cc1843SHermès Bélusca-Maïto     IN PPARTLIST List,
2859*84f3e2dfSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry,
2860*84f3e2dfSHermès Bélusca-Maïto     OUT PPARTENTRY* FreeRegion OPTIONAL)
28616f19c83bSHermès Bélusca-Maïto {
28626f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
28636f19c83bSHermès Bélusca-Maïto     PPARTENTRY PrevPartEntry;
28646f19c83bSHermès Bélusca-Maïto     PPARTENTRY NextPartEntry;
28656f19c83bSHermès Bélusca-Maïto     PPARTENTRY LogicalPartEntry;
28666f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
28676f19c83bSHermès Bélusca-Maïto 
28686f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
286929cc1843SHermès Bélusca-Maïto         PartEntry == NULL ||
287029cc1843SHermès Bélusca-Maïto         PartEntry->DiskEntry == NULL ||
287129cc1843SHermès Bélusca-Maïto         PartEntry->IsPartitioned == FALSE)
28726f19c83bSHermès Bélusca-Maïto     {
2873*84f3e2dfSHermès Bélusca-Maïto         return FALSE;
28746f19c83bSHermès Bélusca-Maïto     }
28756f19c83bSHermès Bélusca-Maïto 
287629cc1843SHermès Bélusca-Maïto     ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
287729cc1843SHermès Bélusca-Maïto 
287829cc1843SHermès Bélusca-Maïto     /* Clear the system partition pointers if it is being deleted */
287929cc1843SHermès Bélusca-Maïto     if (List->SystemPartition == PartEntry)
28806f19c83bSHermès Bélusca-Maïto     {
288129cc1843SHermès Bélusca-Maïto         ASSERT(List->SystemPartition);
288229cc1843SHermès Bélusca-Maïto 
288329cc1843SHermès Bélusca-Maïto         if (List->SystemPartition == List->OriginalSystemPartition)
288429cc1843SHermès Bélusca-Maïto             List->OriginalSystemPartition = NULL;
28856f19c83bSHermès Bélusca-Maïto         List->SystemPartition = NULL;
28866f19c83bSHermès Bélusca-Maïto     }
28876f19c83bSHermès Bélusca-Maïto 
288829cc1843SHermès Bélusca-Maïto     DiskEntry = PartEntry->DiskEntry;
28896f19c83bSHermès Bélusca-Maïto 
28909504a38fSHermès Bélusca-Maïto     /* Check which type of partition (primary/logical or extended) is being deleted */
28916f19c83bSHermès Bélusca-Maïto     if (DiskEntry->ExtendedPartition == PartEntry)
28926f19c83bSHermès Bélusca-Maïto     {
28939504a38fSHermès Bélusca-Maïto         /* An extended partition is being deleted: delete all logical partition entries */
28946f19c83bSHermès Bélusca-Maïto         while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
28956f19c83bSHermès Bélusca-Maïto         {
28966f19c83bSHermès Bélusca-Maïto             Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
28976f19c83bSHermès Bélusca-Maïto             LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
28986f19c83bSHermès Bélusca-Maïto 
28999504a38fSHermès Bélusca-Maïto             /* Dismount the logical partition */
29009504a38fSHermès Bélusca-Maïto             DismountVolume(LogicalPartEntry);
29019504a38fSHermès Bélusca-Maïto 
29029504a38fSHermès Bélusca-Maïto             /* Delete it */
29036f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
29046f19c83bSHermès Bélusca-Maïto         }
29056f19c83bSHermès Bélusca-Maïto 
29066f19c83bSHermès Bélusca-Maïto         DiskEntry->ExtendedPartition = NULL;
29076f19c83bSHermès Bélusca-Maïto     }
29089504a38fSHermès Bélusca-Maïto     else
29099504a38fSHermès Bélusca-Maïto     {
29109504a38fSHermès Bélusca-Maïto         /* A primary partition is being deleted: dismount it */
29119504a38fSHermès Bélusca-Maïto         DismountVolume(PartEntry);
29129504a38fSHermès Bélusca-Maïto     }
29136f19c83bSHermès Bélusca-Maïto 
2914*84f3e2dfSHermès Bélusca-Maïto     /* Adjust the unpartitioned disk space entries */
29156f19c83bSHermès Bélusca-Maïto 
29166f19c83bSHermès Bélusca-Maïto     /* Get pointer to previous and next unpartitioned entries */
2917*84f3e2dfSHermès Bélusca-Maïto     PrevPartEntry = GetPrevUnpartitionedEntry(PartEntry);
2918*84f3e2dfSHermès Bélusca-Maïto     NextPartEntry = GetNextUnpartitionedEntry(PartEntry);
29196f19c83bSHermès Bélusca-Maïto 
29206f19c83bSHermès Bélusca-Maïto     if (PrevPartEntry != NULL && NextPartEntry != NULL)
29216f19c83bSHermès Bélusca-Maïto     {
2922*84f3e2dfSHermès Bélusca-Maïto         /* Merge the previous, current and next unpartitioned entries */
29236f19c83bSHermès Bélusca-Maïto 
2924*84f3e2dfSHermès Bélusca-Maïto         /* Adjust the previous entry length */
29256f19c83bSHermès Bélusca-Maïto         PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
29266f19c83bSHermès Bélusca-Maïto 
2927*84f3e2dfSHermès Bélusca-Maïto         /* Remove the current and next entries */
29286f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&PartEntry->ListEntry);
29296f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, PartEntry);
29306f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&NextPartEntry->ListEntry);
29316f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
29326f19c83bSHermès Bélusca-Maïto 
2933*84f3e2dfSHermès Bélusca-Maïto         /* Optionally return the freed region */
2934*84f3e2dfSHermès Bélusca-Maïto         if (FreeRegion)
2935*84f3e2dfSHermès Bélusca-Maïto             *FreeRegion = PrevPartEntry;
293629cc1843SHermès Bélusca-Maïto     }
29376f19c83bSHermès Bélusca-Maïto     else if (PrevPartEntry != NULL && NextPartEntry == NULL)
29386f19c83bSHermès Bélusca-Maïto     {
2939*84f3e2dfSHermès Bélusca-Maïto         /* Merge the current and the previous unpartitioned entries */
29406f19c83bSHermès Bélusca-Maïto 
2941*84f3e2dfSHermès Bélusca-Maïto         /* Adjust the previous entry length */
29426f19c83bSHermès Bélusca-Maïto         PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
29436f19c83bSHermès Bélusca-Maïto 
29446f19c83bSHermès Bélusca-Maïto         /* Remove the current entry */
29456f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&PartEntry->ListEntry);
29466f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, PartEntry);
29476f19c83bSHermès Bélusca-Maïto 
2948*84f3e2dfSHermès Bélusca-Maïto         /* Optionally return the freed region */
2949*84f3e2dfSHermès Bélusca-Maïto         if (FreeRegion)
2950*84f3e2dfSHermès Bélusca-Maïto             *FreeRegion = PrevPartEntry;
295129cc1843SHermès Bélusca-Maïto     }
29526f19c83bSHermès Bélusca-Maïto     else if (PrevPartEntry == NULL && NextPartEntry != NULL)
29536f19c83bSHermès Bélusca-Maïto     {
2954*84f3e2dfSHermès Bélusca-Maïto         /* Merge the current and the next unpartitioned entries */
29556f19c83bSHermès Bélusca-Maïto 
2956*84f3e2dfSHermès Bélusca-Maïto         /* Adjust the next entry offset and length */
29576f19c83bSHermès Bélusca-Maïto         NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
29586f19c83bSHermès Bélusca-Maïto         NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
29596f19c83bSHermès Bélusca-Maïto 
29606f19c83bSHermès Bélusca-Maïto         /* Remove the current entry */
29616f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&PartEntry->ListEntry);
29626f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, PartEntry);
29636f19c83bSHermès Bélusca-Maïto 
2964*84f3e2dfSHermès Bélusca-Maïto         /* Optionally return the freed region */
2965*84f3e2dfSHermès Bélusca-Maïto         if (FreeRegion)
2966*84f3e2dfSHermès Bélusca-Maïto             *FreeRegion = NextPartEntry;
296729cc1843SHermès Bélusca-Maïto     }
29686f19c83bSHermès Bélusca-Maïto     else
29696f19c83bSHermès Bélusca-Maïto     {
2970*84f3e2dfSHermès Bélusca-Maïto         /* Nothing to merge but change the current entry */
29716f19c83bSHermès Bélusca-Maïto         PartEntry->IsPartitioned = FALSE;
29726f19c83bSHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
29736f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = Unformatted;
2974c1fbc2d6SHermès Bélusca-Maïto         PartEntry->FileSystem[0] = L'\0';
29756f19c83bSHermès Bélusca-Maïto         PartEntry->DriveLetter = 0;
29767df92966SHermès Bélusca-Maïto         PartEntry->OnDiskPartitionNumber = 0;
29777df92966SHermès Bélusca-Maïto         PartEntry->PartitionNumber = 0;
29787df92966SHermès Bélusca-Maïto         // PartEntry->PartitionIndex = 0;
2979*84f3e2dfSHermès Bélusca-Maïto 
2980*84f3e2dfSHermès Bélusca-Maïto         /* Optionally return the freed region */
2981*84f3e2dfSHermès Bélusca-Maïto         if (FreeRegion)
2982*84f3e2dfSHermès Bélusca-Maïto             *FreeRegion = PartEntry;
29836f19c83bSHermès Bélusca-Maïto     }
29846f19c83bSHermès Bélusca-Maïto 
29856f19c83bSHermès Bélusca-Maïto     UpdateDiskLayout(DiskEntry);
29866f19c83bSHermès Bélusca-Maïto 
29876f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
29886f19c83bSHermès Bélusca-Maïto 
2989*84f3e2dfSHermès Bélusca-Maïto     return TRUE;
299029cc1843SHermès Bélusca-Maïto }
299129cc1843SHermès Bélusca-Maïto 
29920d9ebb67SHermès Bélusca-Maïto /*
29930d9ebb67SHermès Bélusca-Maïto  * Retrieve the actual "active" partition of the given disk.
29940d9ebb67SHermès Bélusca-Maïto  * On MBR disks, partition with the Active/Boot flag set;
29950d9ebb67SHermès Bélusca-Maïto  * on GPT disks, partition with the correct GUID.
29960d9ebb67SHermès Bélusca-Maïto  */
29970d9ebb67SHermès Bélusca-Maïto static
29980d9ebb67SHermès Bélusca-Maïto PPARTENTRY
29990d9ebb67SHermès Bélusca-Maïto GetActiveDiskPartition(
30000d9ebb67SHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
30010d9ebb67SHermès Bélusca-Maïto {
30020d9ebb67SHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
30030d9ebb67SHermès Bélusca-Maïto     PPARTENTRY PartEntry;
30040d9ebb67SHermès Bélusca-Maïto     PPARTENTRY ActivePartition = NULL;
30050d9ebb67SHermès Bélusca-Maïto 
30060d9ebb67SHermès Bélusca-Maïto     /* Check for empty disk list */
30070d9ebb67SHermès Bélusca-Maïto     // ASSERT(DiskEntry);
30080d9ebb67SHermès Bélusca-Maïto     if (!DiskEntry)
30090d9ebb67SHermès Bélusca-Maïto         return NULL;
30100d9ebb67SHermès Bélusca-Maïto 
30110d9ebb67SHermès Bélusca-Maïto     /* Check for empty partition list */
30120d9ebb67SHermès Bélusca-Maïto     if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
30130d9ebb67SHermès Bélusca-Maïto         return NULL;
30140d9ebb67SHermès Bélusca-Maïto 
30150d9ebb67SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
30160d9ebb67SHermès Bélusca-Maïto     {
30170d9ebb67SHermès Bélusca-Maïto         DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
30180d9ebb67SHermès Bélusca-Maïto         return NULL;
30190d9ebb67SHermès Bélusca-Maïto     }
30200d9ebb67SHermès Bélusca-Maïto 
30210d9ebb67SHermès Bélusca-Maïto     /* Scan all (primary) partitions to find the active disk partition */
30220d9ebb67SHermès Bélusca-Maïto     for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
30230d9ebb67SHermès Bélusca-Maïto          ListEntry != &DiskEntry->PrimaryPartListHead;
30240d9ebb67SHermès Bélusca-Maïto          ListEntry = ListEntry->Flink)
30250d9ebb67SHermès Bélusca-Maïto     {
30260d9ebb67SHermès Bélusca-Maïto         /* Retrieve the partition */
30270d9ebb67SHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
30280d9ebb67SHermès Bélusca-Maïto 
30290d9ebb67SHermès Bélusca-Maïto         // TODO: Support for GPT disks!
30300d9ebb67SHermès Bélusca-Maïto 
30310d9ebb67SHermès Bélusca-Maïto         /* Check if the partition is partitioned, used and active */
30320d9ebb67SHermès Bélusca-Maïto         if (PartEntry->IsPartitioned &&
30330d9ebb67SHermès Bélusca-Maïto             // !IsContainerPartition(PartEntry->PartitionType) &&
30340d9ebb67SHermès Bélusca-Maïto             PartEntry->BootIndicator)
30350d9ebb67SHermès Bélusca-Maïto         {
30360d9ebb67SHermès Bélusca-Maïto             /* Yes, we found it */
30370d9ebb67SHermès Bélusca-Maïto             ASSERT(DiskEntry == PartEntry->DiskEntry);
30380d9ebb67SHermès Bélusca-Maïto             ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
30390d9ebb67SHermès Bélusca-Maïto 
30400d9ebb67SHermès Bélusca-Maïto             ActivePartition = PartEntry;
30410d9ebb67SHermès Bélusca-Maïto 
30420d9ebb67SHermès Bélusca-Maïto             DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
30430d9ebb67SHermès Bélusca-Maïto                     PartEntry->PartitionNumber, DiskEntry->DiskNumber,
30440d9ebb67SHermès Bélusca-Maïto                     (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
30450d9ebb67SHermès Bélusca-Maïto             break;
30460d9ebb67SHermès Bélusca-Maïto         }
30470d9ebb67SHermès Bélusca-Maïto     }
30480d9ebb67SHermès Bélusca-Maïto 
30490d9ebb67SHermès Bélusca-Maïto     /* Check if the disk is new and if so, use its first partition as the active system partition */
30500d9ebb67SHermès Bélusca-Maïto     if (DiskEntry->NewDisk && ActivePartition != NULL)
30510d9ebb67SHermès Bélusca-Maïto     {
30520d9ebb67SHermès Bélusca-Maïto         // FIXME: What to do??
30530d9ebb67SHermès Bélusca-Maïto         DPRINT1("NewDisk TRUE but already existing active partition?\n");
30540d9ebb67SHermès Bélusca-Maïto     }
30550d9ebb67SHermès Bélusca-Maïto 
30560d9ebb67SHermès Bélusca-Maïto     /* Return the active partition found (or none) */
30570d9ebb67SHermès Bélusca-Maïto     return ActivePartition;
30580d9ebb67SHermès Bélusca-Maïto }
30590d9ebb67SHermès Bélusca-Maïto 
3060c1fbc2d6SHermès Bélusca-Maïto static
3061c1fbc2d6SHermès Bélusca-Maïto BOOLEAN
3062c1fbc2d6SHermès Bélusca-Maïto IsSupportedActivePartition(
3063c1fbc2d6SHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
3064c1fbc2d6SHermès Bélusca-Maïto {
3065c1fbc2d6SHermès Bélusca-Maïto     /* Check the type and the filesystem of this partition */
3066c1fbc2d6SHermès Bélusca-Maïto 
3067c1fbc2d6SHermès Bélusca-Maïto     /*
3068c1fbc2d6SHermès Bélusca-Maïto      * We do not support extended partition containers (on MBR disks) marked
3069c1fbc2d6SHermès Bélusca-Maïto      * as active, and containing code inside their extended boot records.
3070c1fbc2d6SHermès Bélusca-Maïto      */
3071c1fbc2d6SHermès Bélusca-Maïto     if (IsContainerPartition(PartEntry->PartitionType))
3072c1fbc2d6SHermès Bélusca-Maïto     {
3073c1fbc2d6SHermès Bélusca-Maïto         DPRINT1("System partition %lu in disk %lu is an extended partition container?!\n",
3074c1fbc2d6SHermès Bélusca-Maïto                 PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3075c1fbc2d6SHermès Bélusca-Maïto         return FALSE;
3076c1fbc2d6SHermès Bélusca-Maïto     }
3077c1fbc2d6SHermès Bélusca-Maïto 
3078c1fbc2d6SHermès Bélusca-Maïto     /*
3079c1fbc2d6SHermès Bélusca-Maïto      * ADDITIONAL CHECKS / BIG HACK:
3080c1fbc2d6SHermès Bélusca-Maïto      *
3081c1fbc2d6SHermès Bélusca-Maïto      * Retrieve its file system and check whether we have
3082c1fbc2d6SHermès Bélusca-Maïto      * write support for it. If that is the case we are fine
3083c1fbc2d6SHermès Bélusca-Maïto      * and we can use it directly. However if we don't have
3084c1fbc2d6SHermès Bélusca-Maïto      * write support we will need to change the active system
3085c1fbc2d6SHermès Bélusca-Maïto      * partition.
3086c1fbc2d6SHermès Bélusca-Maïto      *
3087c1fbc2d6SHermès Bélusca-Maïto      * NOTE that this is completely useless on architectures
3088c1fbc2d6SHermès Bélusca-Maïto      * where a real system partition is required, as on these
3089c1fbc2d6SHermès Bélusca-Maïto      * architectures the partition uses the FAT FS, for which
3090c1fbc2d6SHermès Bélusca-Maïto      * we do have write support.
3091c1fbc2d6SHermès Bélusca-Maïto      * NOTE also that for those architectures looking for a
3092c1fbc2d6SHermès Bélusca-Maïto      * partition boot indicator is insufficient.
3093c1fbc2d6SHermès Bélusca-Maïto      */
3094c1fbc2d6SHermès Bélusca-Maïto     if ((PartEntry->FormatState == Unformatted ) ||
3095c1fbc2d6SHermès Bélusca-Maïto         (PartEntry->FormatState == Preformatted) ||
3096c1fbc2d6SHermès Bélusca-Maïto         (PartEntry->FormatState == Formatted   ))
3097c1fbc2d6SHermès Bélusca-Maïto     {
3098c1fbc2d6SHermès Bélusca-Maïto         ASSERT(*PartEntry->FileSystem);
3099c1fbc2d6SHermès Bélusca-Maïto 
3100c1fbc2d6SHermès Bélusca-Maïto         /* NOTE: Please keep in sync with the RegisteredFileSystems list! */
3101c1fbc2d6SHermès Bélusca-Maïto         if (wcsicmp(PartEntry->FileSystem, L"FAT")   == 0 ||
3102c1fbc2d6SHermès Bélusca-Maïto             wcsicmp(PartEntry->FileSystem, L"FAT32") == 0 ||
3103c1fbc2d6SHermès Bélusca-Maïto          // wcsicmp(PartEntry->FileSystem, L"NTFS")  == 0 ||
3104c1fbc2d6SHermès Bélusca-Maïto             wcsicmp(PartEntry->FileSystem, L"BTRFS") == 0 ||
3105c1fbc2d6SHermès Bélusca-Maïto             wcsicmp(PartEntry->FileSystem, L"RAW")   == 0)
3106c1fbc2d6SHermès Bélusca-Maïto         {
3107c1fbc2d6SHermès Bélusca-Maïto             return TRUE;
3108c1fbc2d6SHermès Bélusca-Maïto         }
3109c1fbc2d6SHermès Bélusca-Maïto         else
3110c1fbc2d6SHermès Bélusca-Maïto         {
3111c1fbc2d6SHermès Bélusca-Maïto             // WARNING: We cannot write on this FS yet!
3112c1fbc2d6SHermès Bélusca-Maïto             DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
3113c1fbc2d6SHermès Bélusca-Maïto                     PartEntry->FileSystem);
3114c1fbc2d6SHermès Bélusca-Maïto             return FALSE;
3115c1fbc2d6SHermès Bélusca-Maïto         }
3116c1fbc2d6SHermès Bélusca-Maïto     }
3117c1fbc2d6SHermès Bélusca-Maïto     else // if (PartEntry->FormatState == UnknownFormat)
3118c1fbc2d6SHermès Bélusca-Maïto     {
3119c1fbc2d6SHermès Bélusca-Maïto         ASSERT(!*PartEntry->FileSystem);
3120c1fbc2d6SHermès Bélusca-Maïto 
3121c1fbc2d6SHermès Bélusca-Maïto         DPRINT1("System partition %lu in disk %lu with no or unknown FS?!\n",
3122c1fbc2d6SHermès Bélusca-Maïto                 PartEntry->PartitionNumber, PartEntry->DiskEntry->DiskNumber);
3123c1fbc2d6SHermès Bélusca-Maïto         return FALSE;
3124c1fbc2d6SHermès Bélusca-Maïto     }
3125c1fbc2d6SHermès Bélusca-Maïto 
3126c1fbc2d6SHermès Bélusca-Maïto     // HACK: WARNING: We cannot write on this FS yet!
3127c1fbc2d6SHermès Bélusca-Maïto     // See fsutil.c:InferFileSystem()
3128c1fbc2d6SHermès Bélusca-Maïto     if (PartEntry->PartitionType == PARTITION_IFS)
3129c1fbc2d6SHermès Bélusca-Maïto     {
3130c1fbc2d6SHermès Bélusca-Maïto         DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
3131c1fbc2d6SHermès Bélusca-Maïto                 PartEntry->FileSystem);
3132c1fbc2d6SHermès Bélusca-Maïto         return FALSE;
3133c1fbc2d6SHermès Bélusca-Maïto     }
3134c1fbc2d6SHermès Bélusca-Maïto 
3135c1fbc2d6SHermès Bélusca-Maïto     return TRUE;
3136c1fbc2d6SHermès Bélusca-Maïto }
3137c1fbc2d6SHermès Bélusca-Maïto 
31386f19c83bSHermès Bélusca-Maïto VOID
31396f19c83bSHermès Bélusca-Maïto CheckActiveSystemPartition(
3140*84f3e2dfSHermès Bélusca-Maïto     IN PPARTLIST List,
3141*84f3e2dfSHermès Bélusca-Maïto     IN BOOLEAN ForceSelect,
3142*84f3e2dfSHermès Bélusca-Maïto     IN PDISKENTRY AlternateDisk OPTIONAL,
3143*84f3e2dfSHermès Bélusca-Maïto     IN PPARTENTRY AlternatePart OPTIONAL)
31446f19c83bSHermès Bélusca-Maïto {
31450d9ebb67SHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
31466f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
31476f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
31480d9ebb67SHermès Bélusca-Maïto     PPARTENTRY ActivePartition;
31490d9ebb67SHermès Bélusca-Maïto     PPARTENTRY CandidatePartition = NULL;
31506f19c83bSHermès Bélusca-Maïto 
31516f19c83bSHermès Bélusca-Maïto     /* Check for empty disk list */
31526f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
31536f19c83bSHermès Bélusca-Maïto     {
31540d9ebb67SHermès Bélusca-Maïto         /* No system partition! */
31556f19c83bSHermès Bélusca-Maïto         List->SystemPartition = NULL;
31566f19c83bSHermès Bélusca-Maïto         List->OriginalSystemPartition = NULL;
3157*84f3e2dfSHermès Bélusca-Maïto         goto NoSystemPartition;
31586f19c83bSHermès Bélusca-Maïto     }
31596f19c83bSHermès Bélusca-Maïto 
31606f19c83bSHermès Bélusca-Maïto     if (List->SystemPartition != NULL)
31616f19c83bSHermès Bélusca-Maïto     {
31626f19c83bSHermès Bélusca-Maïto         /* We already have an active system partition */
3163f41750abSHermès Bélusca-Maïto         DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n",
31646f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->PartitionNumber,
31656f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->DiskEntry->DiskNumber,
3166f41750abSHermès Bélusca-Maïto                 (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
31676f19c83bSHermès Bélusca-Maïto         return;
31686f19c83bSHermès Bélusca-Maïto     }
31696f19c83bSHermès Bélusca-Maïto 
31700d9ebb67SHermès Bélusca-Maïto     /* Start fresh */
31716f19c83bSHermès Bélusca-Maïto     List->SystemPartition = NULL;
31726f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = NULL;
31736f19c83bSHermès Bélusca-Maïto 
3174*84f3e2dfSHermès Bélusca-Maïto     /* Adjust the optional alternate disk if needed */
3175*84f3e2dfSHermès Bélusca-Maïto     if (!AlternateDisk && AlternatePart)
3176*84f3e2dfSHermès Bélusca-Maïto         AlternateDisk = AlternatePart->DiskEntry;
3177*84f3e2dfSHermès Bélusca-Maïto 
3178*84f3e2dfSHermès Bélusca-Maïto     /* Ensure that the alternate partition is on the alternate disk */
3179*84f3e2dfSHermès Bélusca-Maïto     if (AlternatePart)
3180*84f3e2dfSHermès Bélusca-Maïto         ASSERT(AlternateDisk && (AlternatePart->DiskEntry == AlternateDisk));
3181*84f3e2dfSHermès Bélusca-Maïto 
3182*84f3e2dfSHermès Bélusca-Maïto     /* Ensure that the alternate disk is in the list */
3183*84f3e2dfSHermès Bélusca-Maïto     if (AlternateDisk)
3184*84f3e2dfSHermès Bélusca-Maïto         ASSERT(AlternateDisk->PartList == List);
31850d9ebb67SHermès Bélusca-Maïto 
31860d9ebb67SHermès Bélusca-Maïto //
3187*84f3e2dfSHermès Bélusca-Maïto // Pass == 1 : Check the first (system) disk.
31880d9ebb67SHermès Bélusca-Maïto //
31890d9ebb67SHermès Bélusca-Maïto 
31900d9ebb67SHermès Bélusca-Maïto     /*
31910d9ebb67SHermès Bélusca-Maïto      * First, check whether the first disk (the one that will be booted
31920d9ebb67SHermès Bélusca-Maïto      * by default by the hardware) contains an active partition. If so
31930d9ebb67SHermès Bélusca-Maïto      * this should be our system partition.
31940d9ebb67SHermès Bélusca-Maïto      */
31950d9ebb67SHermès Bélusca-Maïto     DiskEntry = CONTAINING_RECORD(List->DiskListHead.Flink,
31960d9ebb67SHermès Bélusca-Maïto                                   DISKENTRY, ListEntry);
31970d9ebb67SHermès Bélusca-Maïto 
3198*84f3e2dfSHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3199*84f3e2dfSHermès Bélusca-Maïto     {
3200*84f3e2dfSHermès Bélusca-Maïto         DPRINT1("First (system) disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3201*84f3e2dfSHermès Bélusca-Maïto         goto UseAlternateDisk;
3202*84f3e2dfSHermès Bélusca-Maïto     }
32030d9ebb67SHermès Bélusca-Maïto 
32040d9ebb67SHermès Bélusca-Maïto     ActivePartition = GetActiveDiskPartition(DiskEntry);
32050d9ebb67SHermès Bélusca-Maïto     if (ActivePartition)
32060d9ebb67SHermès Bélusca-Maïto     {
32070d9ebb67SHermès Bélusca-Maïto         /* Save the actual system partition */
32080d9ebb67SHermès Bélusca-Maïto         List->OriginalSystemPartition = ActivePartition;
32090d9ebb67SHermès Bélusca-Maïto 
32100d9ebb67SHermès Bélusca-Maïto         /* If we get a candidate active partition in the first disk, validate it */
32110d9ebb67SHermès Bélusca-Maïto         if (IsSupportedActivePartition(ActivePartition))
32120d9ebb67SHermès Bélusca-Maïto         {
32130d9ebb67SHermès Bélusca-Maïto             CandidatePartition = ActivePartition;
32140d9ebb67SHermès Bélusca-Maïto             goto SystemPartitionFound;
32150d9ebb67SHermès Bélusca-Maïto         }
32160d9ebb67SHermès Bélusca-Maïto     }
32170d9ebb67SHermès Bélusca-Maïto 
3218*84f3e2dfSHermès Bélusca-Maïto     /* If this first disk is not the optional alternate disk, perform the minimal checks */
3219*84f3e2dfSHermès Bélusca-Maïto     if (DiskEntry != AlternateDisk)
32200d9ebb67SHermès Bélusca-Maïto     {
32210d9ebb67SHermès Bélusca-Maïto         /*
3222*84f3e2dfSHermès Bélusca-Maïto          * No active partition has been recognized. Enumerate all the (primary)
3223*84f3e2dfSHermès Bélusca-Maïto          * partitions in the first disk, excluding the possible current active
3224*84f3e2dfSHermès Bélusca-Maïto          * partition, to find a new candidate.
32250d9ebb67SHermès Bélusca-Maïto          */
32260d9ebb67SHermès Bélusca-Maïto         for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
32270d9ebb67SHermès Bélusca-Maïto              ListEntry != &DiskEntry->PrimaryPartListHead;
32280d9ebb67SHermès Bélusca-Maïto              ListEntry = ListEntry->Flink)
32290d9ebb67SHermès Bélusca-Maïto         {
32300d9ebb67SHermès Bélusca-Maïto             /* Retrieve the partition */
32310d9ebb67SHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
32320d9ebb67SHermès Bélusca-Maïto 
32330d9ebb67SHermès Bélusca-Maïto             /* Skip the current active partition */
32340d9ebb67SHermès Bélusca-Maïto             if (/* ActivePartition != NULL && */ PartEntry == ActivePartition)
32350d9ebb67SHermès Bélusca-Maïto                 continue;
32360d9ebb67SHermès Bélusca-Maïto 
32370d9ebb67SHermès Bélusca-Maïto             /* Check if the partition is partitioned and used */
32380d9ebb67SHermès Bélusca-Maïto             if (PartEntry->IsPartitioned &&
32390d9ebb67SHermès Bélusca-Maïto                 !IsContainerPartition(PartEntry->PartitionType))
32400d9ebb67SHermès Bélusca-Maïto             {
32410d9ebb67SHermès Bélusca-Maïto                 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
32420d9ebb67SHermès Bélusca-Maïto 
32430d9ebb67SHermès Bélusca-Maïto                 /* If we get a candidate active partition in the first disk, validate it */
32440d9ebb67SHermès Bélusca-Maïto                 if (IsSupportedActivePartition(PartEntry))
32450d9ebb67SHermès Bélusca-Maïto                 {
32460d9ebb67SHermès Bélusca-Maïto                     CandidatePartition = PartEntry;
32470d9ebb67SHermès Bélusca-Maïto                     goto FindAndUseAlternativeSystemPartition;
32480d9ebb67SHermès Bélusca-Maïto                 }
32490d9ebb67SHermès Bélusca-Maïto             }
32500d9ebb67SHermès Bélusca-Maïto 
32510d9ebb67SHermès Bélusca-Maïto #if 0
32520d9ebb67SHermès Bélusca-Maïto             /* Check if the partition is partitioned and used */
32530d9ebb67SHermès Bélusca-Maïto             if (!PartEntry->IsPartitioned)
32540d9ebb67SHermès Bélusca-Maïto             {
32550d9ebb67SHermès Bélusca-Maïto                 ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
32560d9ebb67SHermès Bélusca-Maïto 
32570d9ebb67SHermès Bélusca-Maïto                 // TODO: Check for minimal size!!
32580d9ebb67SHermès Bélusca-Maïto                 CandidatePartition = PartEntry;
32590d9ebb67SHermès Bélusca-Maïto                 goto FindAndUseAlternativeSystemPartition;
32600d9ebb67SHermès Bélusca-Maïto             }
32610d9ebb67SHermès Bélusca-Maïto #endif
32620d9ebb67SHermès Bélusca-Maïto         }
32630d9ebb67SHermès Bélusca-Maïto 
32640d9ebb67SHermès Bélusca-Maïto         /*
32650d9ebb67SHermès Bélusca-Maïto          * Still nothing, look whether there is some free space that we can use
32660d9ebb67SHermès Bélusca-Maïto          * for the new system partition. We must be sure that the total number
32670d9ebb67SHermès Bélusca-Maïto          * of partition is less than the maximum allowed, and that the minimal
32680d9ebb67SHermès Bélusca-Maïto          * size is fine.
32690d9ebb67SHermès Bélusca-Maïto          */
32700d9ebb67SHermès Bélusca-Maïto //
32710d9ebb67SHermès Bélusca-Maïto // TODO: Fix the handling of system partition being created in unpartitioned space!!
32720d9ebb67SHermès Bélusca-Maïto // --> When to partition it? etc...
32730d9ebb67SHermès Bélusca-Maïto //
32740d9ebb67SHermès Bélusca-Maïto         if (GetPrimaryPartitionCount(DiskEntry) < 4)
32750d9ebb67SHermès Bélusca-Maïto         {
32760d9ebb67SHermès Bélusca-Maïto             for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
32770d9ebb67SHermès Bélusca-Maïto                  ListEntry != &DiskEntry->PrimaryPartListHead;
32780d9ebb67SHermès Bélusca-Maïto                  ListEntry = ListEntry->Flink)
32790d9ebb67SHermès Bélusca-Maïto             {
32800d9ebb67SHermès Bélusca-Maïto                 /* Retrieve the partition */
32810d9ebb67SHermès Bélusca-Maïto                 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
32820d9ebb67SHermès Bélusca-Maïto 
32830d9ebb67SHermès Bélusca-Maïto                 /* Skip the current active partition */
32840d9ebb67SHermès Bélusca-Maïto                 if (/* ActivePartition != NULL && */ PartEntry == ActivePartition)
32850d9ebb67SHermès Bélusca-Maïto                     continue;
32860d9ebb67SHermès Bélusca-Maïto 
32870d9ebb67SHermès Bélusca-Maïto                 /* Check for unpartitioned space */
32880d9ebb67SHermès Bélusca-Maïto                 if (!PartEntry->IsPartitioned)
32890d9ebb67SHermès Bélusca-Maïto                 {
32900d9ebb67SHermès Bélusca-Maïto                     ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
32910d9ebb67SHermès Bélusca-Maïto 
32920d9ebb67SHermès Bélusca-Maïto                     // TODO: Check for minimal size!!
32930d9ebb67SHermès Bélusca-Maïto                     CandidatePartition = PartEntry;
32940d9ebb67SHermès Bélusca-Maïto                     goto FindAndUseAlternativeSystemPartition;
32950d9ebb67SHermès Bélusca-Maïto                 }
32960d9ebb67SHermès Bélusca-Maïto             }
32970d9ebb67SHermès Bélusca-Maïto         }
32980d9ebb67SHermès Bélusca-Maïto     }
32990d9ebb67SHermès Bélusca-Maïto 
33000d9ebb67SHermès Bélusca-Maïto 
33010d9ebb67SHermès Bélusca-Maïto //
3302*84f3e2dfSHermès Bélusca-Maïto // Pass == 2 : No active partition found: Check the alternate disk if specified.
33030d9ebb67SHermès Bélusca-Maïto //
33040d9ebb67SHermès Bélusca-Maïto 
3305*84f3e2dfSHermès Bélusca-Maïto UseAlternateDisk:
3306*84f3e2dfSHermès Bélusca-Maïto     if (!AlternateDisk || (!ForceSelect && (DiskEntry != AlternateDisk)))
3307*84f3e2dfSHermès Bélusca-Maïto         goto NoSystemPartition;
33080d9ebb67SHermès Bélusca-Maïto 
3309*84f3e2dfSHermès Bélusca-Maïto     if (AlternateDisk->DiskStyle == PARTITION_STYLE_GPT)
33100d9ebb67SHermès Bélusca-Maïto     {
3311*84f3e2dfSHermès Bélusca-Maïto         DPRINT1("Alternate disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3312*84f3e2dfSHermès Bélusca-Maïto         goto NoSystemPartition;
33130d9ebb67SHermès Bélusca-Maïto     }
33140d9ebb67SHermès Bélusca-Maïto 
3315*84f3e2dfSHermès Bélusca-Maïto     if (DiskEntry != AlternateDisk)
3316*84f3e2dfSHermès Bélusca-Maïto     {
3317*84f3e2dfSHermès Bélusca-Maïto         /* Choose the alternate disk */
3318*84f3e2dfSHermès Bélusca-Maïto         DiskEntry = AlternateDisk;
33190d9ebb67SHermès Bélusca-Maïto 
33200d9ebb67SHermès Bélusca-Maïto         ActivePartition = GetActiveDiskPartition(DiskEntry);
33210d9ebb67SHermès Bélusca-Maïto         if (ActivePartition)
33220d9ebb67SHermès Bélusca-Maïto         {
33230d9ebb67SHermès Bélusca-Maïto             /* If we get a candidate active partition, validate it */
33240d9ebb67SHermès Bélusca-Maïto             if (IsSupportedActivePartition(ActivePartition))
33250d9ebb67SHermès Bélusca-Maïto             {
33260d9ebb67SHermès Bélusca-Maïto                 CandidatePartition = ActivePartition;
33270d9ebb67SHermès Bélusca-Maïto                 goto FindAndUseAlternativeSystemPartition;
33280d9ebb67SHermès Bélusca-Maïto             }
33290d9ebb67SHermès Bélusca-Maïto         }
33300d9ebb67SHermès Bélusca-Maïto     }
33310d9ebb67SHermès Bélusca-Maïto 
3332*84f3e2dfSHermès Bélusca-Maïto     /* We now may have an unsupported active partition, or none */
33330d9ebb67SHermès Bélusca-Maïto 
33340d9ebb67SHermès Bélusca-Maïto /***
33350d9ebb67SHermès Bélusca-Maïto  *** TODO: Improve the selection:
33360d9ebb67SHermès Bélusca-Maïto  *** - If we want a really separate system partition from the partition where
33370d9ebb67SHermès Bélusca-Maïto  ***   we install, do something similar to what's done below in the code.
33380d9ebb67SHermès Bélusca-Maïto  *** - Otherwise if we allow for the system partition to be also the partition
3339*84f3e2dfSHermès Bélusca-Maïto  ***   where we install, just directly fall down to using AlternatePart.
33400d9ebb67SHermès Bélusca-Maïto  ***/
33410d9ebb67SHermès Bélusca-Maïto 
33426f19c83bSHermès Bélusca-Maïto     /* Retrieve the first partition of the disk */
33436f19c83bSHermès Bélusca-Maïto     PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
33440d9ebb67SHermès Bélusca-Maïto                                   PARTENTRY, ListEntry);
33456f19c83bSHermès Bélusca-Maïto     ASSERT(DiskEntry == PartEntry->DiskEntry);
33460d9ebb67SHermès Bélusca-Maïto 
33470d9ebb67SHermès Bélusca-Maïto     CandidatePartition = PartEntry;
33486f19c83bSHermès Bélusca-Maïto 
33496f19c83bSHermès Bélusca-Maïto     //
33506f19c83bSHermès Bélusca-Maïto     // See: https://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/partlist.c?r1=63355&r2=63354&pathrev=63355#l2318
33516f19c83bSHermès Bélusca-Maïto     //
33526f19c83bSHermès Bélusca-Maïto 
33536f19c83bSHermès Bélusca-Maïto     /* Check if the disk is new and if so, use its first partition as the active system partition */
33546f19c83bSHermès Bélusca-Maïto     if (DiskEntry->NewDisk)
33556f19c83bSHermès Bélusca-Maïto     {
33560d9ebb67SHermès Bélusca-Maïto         // !IsContainerPartition(PartEntry->PartitionType);
33570d9ebb67SHermès Bélusca-Maïto         if (!CandidatePartition->IsPartitioned || !CandidatePartition->BootIndicator) /* CandidatePartition != ActivePartition */
33586f19c83bSHermès Bélusca-Maïto         {
33590d9ebb67SHermès Bélusca-Maïto             ASSERT(DiskEntry == CandidatePartition->DiskEntry);
33606f19c83bSHermès Bélusca-Maïto 
33610d9ebb67SHermès Bélusca-Maïto             List->SystemPartition = CandidatePartition;
33626f19c83bSHermès Bélusca-Maïto             List->OriginalSystemPartition = List->SystemPartition;
33636f19c83bSHermès Bélusca-Maïto 
3364f41750abSHermès Bélusca-Maïto             DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
33656f19c83bSHermès Bélusca-Maïto                     List->SystemPartition->PartitionNumber,
33666f19c83bSHermès Bélusca-Maïto                     List->SystemPartition->DiskEntry->DiskNumber,
3367f41750abSHermès Bélusca-Maïto                     (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
33686f19c83bSHermès Bélusca-Maïto 
33696f19c83bSHermès Bélusca-Maïto             goto SetSystemPartition;
33706f19c83bSHermès Bélusca-Maïto         }
33716f19c83bSHermès Bélusca-Maïto 
33726f19c83bSHermès Bélusca-Maïto         // FIXME: What to do??
33736f19c83bSHermès Bélusca-Maïto         DPRINT1("NewDisk TRUE but first partition is used?\n");
33746f19c83bSHermès Bélusca-Maïto     }
33756f19c83bSHermès Bélusca-Maïto 
33766f19c83bSHermès Bélusca-Maïto     /*
33776f19c83bSHermès Bélusca-Maïto      * The disk is not new, check if any partition is initialized;
33786f19c83bSHermès Bélusca-Maïto      * if not, the first one becomes the system partition.
33796f19c83bSHermès Bélusca-Maïto      */
33808bed4adfSHermès Bélusca-Maïto     for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
33818bed4adfSHermès Bélusca-Maïto          ListEntry != &DiskEntry->PrimaryPartListHead;
33828bed4adfSHermès Bélusca-Maïto          ListEntry = ListEntry->Flink)
33836f19c83bSHermès Bélusca-Maïto     {
33848bed4adfSHermès Bélusca-Maïto         /* Retrieve the partition */
33850d9ebb67SHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
33866f19c83bSHermès Bélusca-Maïto 
33876f19c83bSHermès Bélusca-Maïto         /* Check if the partition is partitioned and is used */
33880d9ebb67SHermès Bélusca-Maïto         // !IsContainerPartition(PartEntry->PartitionType);
33890d9ebb67SHermès Bélusca-Maïto         if (/* PartEntry->IsPartitioned && */
33900d9ebb67SHermès Bélusca-Maïto             PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator)
33916f19c83bSHermès Bélusca-Maïto         {
33926f19c83bSHermès Bélusca-Maïto             break;
33936f19c83bSHermès Bélusca-Maïto         }
33946f19c83bSHermès Bélusca-Maïto     }
33956f19c83bSHermès Bélusca-Maïto     if (ListEntry == &DiskEntry->PrimaryPartListHead)
33966f19c83bSHermès Bélusca-Maïto     {
33976f19c83bSHermès Bélusca-Maïto         /*
33986f19c83bSHermès Bélusca-Maïto          * OK we haven't encountered any used and active partition,
33996f19c83bSHermès Bélusca-Maïto          * so use the first one as the system partition.
34006f19c83bSHermès Bélusca-Maïto          */
34010d9ebb67SHermès Bélusca-Maïto         ASSERT(DiskEntry == CandidatePartition->DiskEntry);
34020d9ebb67SHermès Bélusca-Maïto         List->SystemPartition = CandidatePartition; // The first PartEntry
34030d9ebb67SHermès Bélusca-Maïto         List->OriginalSystemPartition = List->SystemPartition;
34046f19c83bSHermès Bélusca-Maïto 
3405f41750abSHermès Bélusca-Maïto         DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
34066f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->PartitionNumber,
34076f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->DiskEntry->DiskNumber,
3408f41750abSHermès Bélusca-Maïto                 (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
34096f19c83bSHermès Bélusca-Maïto 
34106f19c83bSHermès Bélusca-Maïto         goto SetSystemPartition;
34116f19c83bSHermès Bélusca-Maïto     }
34126f19c83bSHermès Bélusca-Maïto 
34130d9ebb67SHermès Bélusca-Maïto     /*
34140d9ebb67SHermès Bélusca-Maïto      * The disk is not new, we did not find any actual active partition,
34150d9ebb67SHermès Bélusca-Maïto      * or the one we found was not supported, or any possible other canditate
3416*84f3e2dfSHermès Bélusca-Maïto      * is not supported. We then use the alternate partition if specified.
34170d9ebb67SHermès Bélusca-Maïto      */
3418*84f3e2dfSHermès Bélusca-Maïto     if (AlternatePart)
3419*84f3e2dfSHermès Bélusca-Maïto     {
34206f19c83bSHermès Bélusca-Maïto         DPRINT1("No system partition found, use the alternative partition!\n");
3421*84f3e2dfSHermès Bélusca-Maïto         CandidatePartition = AlternatePart;
34226f19c83bSHermès Bélusca-Maïto         goto UseAlternativeSystemPartition;
3423*84f3e2dfSHermès Bélusca-Maïto     }
3424*84f3e2dfSHermès Bélusca-Maïto     else
3425*84f3e2dfSHermès Bélusca-Maïto     {
3426*84f3e2dfSHermès Bélusca-Maïto NoSystemPartition:
3427*84f3e2dfSHermès Bélusca-Maïto         DPRINT1("No valid or supported system partition has been found on this system!\n");
3428*84f3e2dfSHermès Bélusca-Maïto         return;
3429*84f3e2dfSHermès Bélusca-Maïto     }
34306f19c83bSHermès Bélusca-Maïto 
34316f19c83bSHermès Bélusca-Maïto 
34320d9ebb67SHermès Bélusca-Maïto SystemPartitionFound:
3433*84f3e2dfSHermès Bélusca-Maïto     ASSERT(CandidatePartition);
34340d9ebb67SHermès Bélusca-Maïto     List->SystemPartition = CandidatePartition;
34356f19c83bSHermès Bélusca-Maïto 
3436f41750abSHermès Bélusca-Maïto     DPRINT1("Use existing active system partition %lu in disk %lu, drive letter %C\n",
34376f19c83bSHermès Bélusca-Maïto             List->SystemPartition->PartitionNumber,
34386f19c83bSHermès Bélusca-Maïto             List->SystemPartition->DiskEntry->DiskNumber,
3439f41750abSHermès Bélusca-Maïto             (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
34406f19c83bSHermès Bélusca-Maïto 
34416f19c83bSHermès Bélusca-Maïto     return;
34426f19c83bSHermès Bélusca-Maïto 
34436f19c83bSHermès Bélusca-Maïto FindAndUseAlternativeSystemPartition:
34446f19c83bSHermès Bélusca-Maïto     /*
34456f19c83bSHermès Bélusca-Maïto      * We are here because we have not found any (active) candidate
34466f19c83bSHermès Bélusca-Maïto      * system partition that we know how to support. What we are going
34476f19c83bSHermès Bélusca-Maïto      * to do is to change the existing system partition and use the
34486f19c83bSHermès Bélusca-Maïto      * partition on which we install ReactOS as the new system partition,
34496f19c83bSHermès Bélusca-Maïto      * and then we will need to add in FreeLdr's entry a boot entry to boot
34506f19c83bSHermès Bélusca-Maïto      * from the original system partition.
34516f19c83bSHermès Bélusca-Maïto      */
34526f19c83bSHermès Bélusca-Maïto 
34536f19c83bSHermès Bélusca-Maïto     /* Unset the old system partition */
34540d9ebb67SHermès Bélusca-Maïto     if (List->OriginalSystemPartition)
34550d9ebb67SHermès Bélusca-Maïto     {
34560d9ebb67SHermès Bélusca-Maïto         List->OriginalSystemPartition->BootIndicator = FALSE;
34570d9ebb67SHermès Bélusca-Maïto         List->OriginalSystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->OriginalSystemPartition->PartitionIndex].BootIndicator = FALSE;
34580d9ebb67SHermès Bélusca-Maïto         List->OriginalSystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->OriginalSystemPartition->PartitionIndex].RewritePartition = TRUE;
34590d9ebb67SHermès Bélusca-Maïto         List->OriginalSystemPartition->DiskEntry->Dirty = TRUE;
34600d9ebb67SHermès Bélusca-Maïto     }
34616f19c83bSHermès Bélusca-Maïto 
34626f19c83bSHermès Bélusca-Maïto UseAlternativeSystemPartition:
3463*84f3e2dfSHermès Bélusca-Maïto     ASSERT(CandidatePartition);
34640d9ebb67SHermès Bélusca-Maïto     List->SystemPartition = CandidatePartition;
34656f19c83bSHermès Bélusca-Maïto 
3466f41750abSHermès Bélusca-Maïto     DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
34676f19c83bSHermès Bélusca-Maïto             List->SystemPartition->PartitionNumber,
34686f19c83bSHermès Bélusca-Maïto             List->SystemPartition->DiskEntry->DiskNumber,
3469f41750abSHermès Bélusca-Maïto             (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
34706f19c83bSHermès Bélusca-Maïto 
34716f19c83bSHermès Bélusca-Maïto SetSystemPartition:
34726f19c83bSHermès Bélusca-Maïto     /* Set the new active system partition */
34736f19c83bSHermès Bélusca-Maïto     List->SystemPartition->BootIndicator = TRUE;
34746f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = TRUE;
34756f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
34766f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->Dirty = TRUE;
34776f19c83bSHermès Bélusca-Maïto }
34786f19c83bSHermès Bélusca-Maïto 
34796f19c83bSHermès Bélusca-Maïto NTSTATUS
34806f19c83bSHermès Bélusca-Maïto WritePartitions(
34816f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
34826f19c83bSHermès Bélusca-Maïto {
34836f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
34847df92966SHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
34857df92966SHermès Bélusca-Maïto     UNICODE_STRING Name;
34867df92966SHermès Bélusca-Maïto     HANDLE FileHandle;
34877df92966SHermès Bélusca-Maïto     IO_STATUS_BLOCK Iosb;
34887df92966SHermès Bélusca-Maïto     ULONG BufferSize;
34897df92966SHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
34907df92966SHermès Bélusca-Maïto     ULONG PartitionCount;
34917df92966SHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
34927df92966SHermès Bélusca-Maïto     PPARTENTRY PartEntry;
34937df92966SHermès Bélusca-Maïto     WCHAR DstPath[MAX_PATH];
34946f19c83bSHermès Bélusca-Maïto 
34956f19c83bSHermès Bélusca-Maïto     DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
34966f19c83bSHermès Bélusca-Maïto 
349729cc1843SHermès Bélusca-Maïto     /* If the disk is not dirty, there is nothing to do */
349829cc1843SHermès Bélusca-Maïto     if (!DiskEntry->Dirty)
349929cc1843SHermès Bélusca-Maïto         return STATUS_SUCCESS;
350029cc1843SHermès Bélusca-Maïto 
35016f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
35026f19c83bSHermès Bélusca-Maïto                         L"\\Device\\Harddisk%lu\\Partition0",
35036f19c83bSHermès Bélusca-Maïto                         DiskEntry->DiskNumber);
35046f19c83bSHermès Bélusca-Maïto     RtlInitUnicodeString(&Name, DstPath);
3505765994c9SHermès Bélusca-Maïto 
35066f19c83bSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
35076f19c83bSHermès Bélusca-Maïto                                &Name,
3508765994c9SHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
35096f19c83bSHermès Bélusca-Maïto                                NULL,
35106f19c83bSHermès Bélusca-Maïto                                NULL);
35116f19c83bSHermès Bélusca-Maïto 
35126f19c83bSHermès Bélusca-Maïto     Status = NtOpenFile(&FileHandle,
35136f19c83bSHermès Bélusca-Maïto                         GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
35146f19c83bSHermès Bélusca-Maïto                         &ObjectAttributes,
35156f19c83bSHermès Bélusca-Maïto                         &Iosb,
35166f19c83bSHermès Bélusca-Maïto                         0,
35176f19c83bSHermès Bélusca-Maïto                         FILE_SYNCHRONOUS_IO_NONALERT);
35186f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
35196f19c83bSHermès Bélusca-Maïto     {
35206f19c83bSHermès Bélusca-Maïto         DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
35216f19c83bSHermès Bélusca-Maïto         return Status;
35226f19c83bSHermès Bélusca-Maïto     }
35236f19c83bSHermès Bélusca-Maïto 
35246f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
35256f19c83bSHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
35266f19c83bSHermès Bélusca-Maïto #endif
35276f19c83bSHermès Bélusca-Maïto 
3528f41750abSHermès Bélusca-Maïto     //
3529f41750abSHermès Bélusca-Maïto     // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3530f41750abSHermès Bélusca-Maïto     // the disk in MBR or GPT format in case the disk was not initialized!!
3531f41750abSHermès Bélusca-Maïto     // For this we must ask the user which format to use.
3532f41750abSHermès Bélusca-Maïto     //
3533f41750abSHermès Bélusca-Maïto 
35347df92966SHermès Bélusca-Maïto     /* Save the original partition count to be restored later (see comment below) */
35357df92966SHermès Bélusca-Maïto     PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
35367df92966SHermès Bélusca-Maïto 
35377df92966SHermès Bélusca-Maïto     /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
35386f19c83bSHermès Bélusca-Maïto     BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
35397df92966SHermès Bélusca-Maïto                  ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
35406f19c83bSHermès Bélusca-Maïto     Status = NtDeviceIoControlFile(FileHandle,
35416f19c83bSHermès Bélusca-Maïto                                    NULL,
35426f19c83bSHermès Bélusca-Maïto                                    NULL,
35436f19c83bSHermès Bélusca-Maïto                                    NULL,
35446f19c83bSHermès Bélusca-Maïto                                    &Iosb,
35456f19c83bSHermès Bélusca-Maïto                                    IOCTL_DISK_SET_DRIVE_LAYOUT,
35466f19c83bSHermès Bélusca-Maïto                                    DiskEntry->LayoutBuffer,
35476f19c83bSHermès Bélusca-Maïto                                    BufferSize,
35487df92966SHermès Bélusca-Maïto                                    DiskEntry->LayoutBuffer,
35497df92966SHermès Bélusca-Maïto                                    BufferSize);
35507df92966SHermès Bélusca-Maïto     NtClose(FileHandle);
35517df92966SHermès Bélusca-Maïto 
35527df92966SHermès Bélusca-Maïto     /*
35537df92966SHermès Bélusca-Maïto      * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
35547df92966SHermès Bélusca-Maïto      * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
35557df92966SHermès Bélusca-Maïto      * where such a table is expected to enumerate up to 4 partitions:
35567df92966SHermès Bélusca-Maïto      * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
35577df92966SHermès Bélusca-Maïto      * Due to this we need to restore the original PartitionCount number.
35587df92966SHermès Bélusca-Maïto      */
35597df92966SHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
35607df92966SHermès Bélusca-Maïto 
35617df92966SHermès Bélusca-Maïto     /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
35626f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
35636f19c83bSHermès Bélusca-Maïto     {
35646f19c83bSHermès Bélusca-Maïto         DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
35657df92966SHermès Bélusca-Maïto         return Status;
35666f19c83bSHermès Bélusca-Maïto     }
35676f19c83bSHermès Bélusca-Maïto 
35687df92966SHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
35697df92966SHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
35707df92966SHermès Bélusca-Maïto #endif
35717df92966SHermès Bélusca-Maïto 
35727df92966SHermès Bélusca-Maïto     /* Update the partition numbers */
35737df92966SHermès Bélusca-Maïto 
35747df92966SHermès Bélusca-Maïto     /* Update the primary partition table */
35758bed4adfSHermès Bélusca-Maïto     for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
35768bed4adfSHermès Bélusca-Maïto          ListEntry != &DiskEntry->PrimaryPartListHead;
35778bed4adfSHermès Bélusca-Maïto          ListEntry = ListEntry->Flink)
35787df92966SHermès Bélusca-Maïto     {
35797df92966SHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
35807df92966SHermès Bélusca-Maïto 
35817df92966SHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
35827df92966SHermès Bélusca-Maïto         {
358329cc1843SHermès Bélusca-Maïto             ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
35847df92966SHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
35857df92966SHermès Bélusca-Maïto             PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
35867df92966SHermès Bélusca-Maïto         }
35877df92966SHermès Bélusca-Maïto     }
35887df92966SHermès Bélusca-Maïto 
35897df92966SHermès Bélusca-Maïto     /* Update the logical partition table */
35908bed4adfSHermès Bélusca-Maïto     for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
35918bed4adfSHermès Bélusca-Maïto          ListEntry != &DiskEntry->LogicalPartListHead;
35928bed4adfSHermès Bélusca-Maïto          ListEntry = ListEntry->Flink)
35937df92966SHermès Bélusca-Maïto     {
35947df92966SHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
35957df92966SHermès Bélusca-Maïto 
35967df92966SHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
35977df92966SHermès Bélusca-Maïto         {
359829cc1843SHermès Bélusca-Maïto             ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
35997df92966SHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
36007df92966SHermès Bélusca-Maïto             PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
36017df92966SHermès Bélusca-Maïto         }
36027df92966SHermès Bélusca-Maïto     }
36036f19c83bSHermès Bélusca-Maïto 
36046f19c83bSHermès Bélusca-Maïto     //
36056f19c83bSHermès Bélusca-Maïto     // NOTE: Originally (see r40437), we used to install here also a new MBR
36066f19c83bSHermès Bélusca-Maïto     // for this disk (by calling InstallMbrBootCodeToDisk), only if:
36076f19c83bSHermès Bélusca-Maïto     // DiskEntry->NewDisk == TRUE and DiskEntry->BiosDiskNumber == 0.
36086f19c83bSHermès Bélusca-Maïto     // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
36096f19c83bSHermès Bélusca-Maïto     // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
36106f19c83bSHermès Bélusca-Maïto     // was called too, the installation test was modified by checking whether
36116f19c83bSHermès Bélusca-Maïto     // DiskEntry->NoMbr was TRUE (instead of NewDisk).
36126f19c83bSHermès Bélusca-Maïto     //
36136f19c83bSHermès Bélusca-Maïto 
361429cc1843SHermès Bélusca-Maïto     /* The layout has been successfully updated, the disk is not dirty anymore */
361529cc1843SHermès Bélusca-Maïto     DiskEntry->Dirty = FALSE;
36167df92966SHermès Bélusca-Maïto 
36176f19c83bSHermès Bélusca-Maïto     return Status;
36186f19c83bSHermès Bélusca-Maïto }
36196f19c83bSHermès Bélusca-Maïto 
36206f19c83bSHermès Bélusca-Maïto BOOLEAN
36216f19c83bSHermès Bélusca-Maïto WritePartitionsToDisk(
36226f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
36236f19c83bSHermès Bélusca-Maïto {
362429cc1843SHermès Bélusca-Maïto     NTSTATUS Status;
36256f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
36266f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
36276f19c83bSHermès Bélusca-Maïto 
36286f19c83bSHermès Bélusca-Maïto     if (List == NULL)
36296f19c83bSHermès Bélusca-Maïto         return TRUE;
36306f19c83bSHermès Bélusca-Maïto 
36318bed4adfSHermès Bélusca-Maïto     for (Entry = List->DiskListHead.Flink;
36328bed4adfSHermès Bélusca-Maïto          Entry != &List->DiskListHead;
36338bed4adfSHermès Bélusca-Maïto          Entry = Entry->Flink)
36346f19c83bSHermès Bélusca-Maïto     {
36356f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
36366f19c83bSHermès Bélusca-Maïto 
3637a3168373SHermès Bélusca-Maïto         if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3638a3168373SHermès Bélusca-Maïto         {
3639a3168373SHermès Bélusca-Maïto             DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3640a3168373SHermès Bélusca-Maïto             continue;
3641a3168373SHermès Bélusca-Maïto         }
3642a3168373SHermès Bélusca-Maïto 
36436f19c83bSHermès Bélusca-Maïto         if (DiskEntry->Dirty != FALSE)
36446f19c83bSHermès Bélusca-Maïto         {
364529cc1843SHermès Bélusca-Maïto             Status = WritePartitions(DiskEntry);
364629cc1843SHermès Bélusca-Maïto             if (!NT_SUCCESS(Status))
364729cc1843SHermès Bélusca-Maïto             {
364829cc1843SHermès Bélusca-Maïto                 DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
364929cc1843SHermès Bélusca-Maïto                         DiskEntry->DiskNumber, Status);
365029cc1843SHermès Bélusca-Maïto             }
36516f19c83bSHermès Bélusca-Maïto         }
36526f19c83bSHermès Bélusca-Maïto     }
36536f19c83bSHermès Bélusca-Maïto 
36546f19c83bSHermès Bélusca-Maïto     return TRUE;
36556f19c83bSHermès Bélusca-Maïto }
36566f19c83bSHermès Bélusca-Maïto 
36576f19c83bSHermès Bélusca-Maïto BOOLEAN
36586f19c83bSHermès Bélusca-Maïto SetMountedDeviceValue(
3659f41750abSHermès Bélusca-Maïto     IN WCHAR Letter,
36606f19c83bSHermès Bélusca-Maïto     IN ULONG Signature,
36616f19c83bSHermès Bélusca-Maïto     IN LARGE_INTEGER StartingOffset)
36626f19c83bSHermès Bélusca-Maïto {
36636f19c83bSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
36646f19c83bSHermès Bélusca-Maïto     WCHAR ValueNameBuffer[16];
36656f19c83bSHermès Bélusca-Maïto     UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\MountedDevices");
36666f19c83bSHermès Bélusca-Maïto     UNICODE_STRING ValueName;
36676f19c83bSHermès Bélusca-Maïto     REG_DISK_MOUNT_INFO MountInfo;
36686f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
36696f19c83bSHermès Bélusca-Maïto     HANDLE KeyHandle;
36706f19c83bSHermès Bélusca-Maïto 
36716f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(ValueNameBuffer, ARRAYSIZE(ValueNameBuffer),
3672f41750abSHermès Bélusca-Maïto                         L"\\DosDevices\\%c:", Letter);
36736f19c83bSHermès Bélusca-Maïto     RtlInitUnicodeString(&ValueName, ValueNameBuffer);
36746f19c83bSHermès Bélusca-Maïto 
36756f19c83bSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
36766f19c83bSHermès Bélusca-Maïto                                &KeyName,
36776f19c83bSHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
36786f19c83bSHermès Bélusca-Maïto                                NULL,
36796f19c83bSHermès Bélusca-Maïto                                NULL);
3680765994c9SHermès Bélusca-Maïto 
36816f19c83bSHermès Bélusca-Maïto     Status =  NtOpenKey(&KeyHandle,
36826f19c83bSHermès Bélusca-Maïto                         KEY_ALL_ACCESS,
36836f19c83bSHermès Bélusca-Maïto                         &ObjectAttributes);
36846f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
36856f19c83bSHermès Bélusca-Maïto     {
36866f19c83bSHermès Bélusca-Maïto         Status = NtCreateKey(&KeyHandle,
36876f19c83bSHermès Bélusca-Maïto                              KEY_ALL_ACCESS,
36886f19c83bSHermès Bélusca-Maïto                              &ObjectAttributes,
36896f19c83bSHermès Bélusca-Maïto                              0,
36906f19c83bSHermès Bélusca-Maïto                              NULL,
36916f19c83bSHermès Bélusca-Maïto                              REG_OPTION_NON_VOLATILE,
36926f19c83bSHermès Bélusca-Maïto                              NULL);
36936f19c83bSHermès Bélusca-Maïto     }
36946f19c83bSHermès Bélusca-Maïto 
36956f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
36966f19c83bSHermès Bélusca-Maïto     {
36976f19c83bSHermès Bélusca-Maïto         DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
36986f19c83bSHermès Bélusca-Maïto         return FALSE;
36996f19c83bSHermès Bélusca-Maïto     }
37006f19c83bSHermès Bélusca-Maïto 
37016f19c83bSHermès Bélusca-Maïto     MountInfo.Signature = Signature;
37026f19c83bSHermès Bélusca-Maïto     MountInfo.StartingOffset = StartingOffset;
37036f19c83bSHermès Bélusca-Maïto     Status = NtSetValueKey(KeyHandle,
37046f19c83bSHermès Bélusca-Maïto                            &ValueName,
37056f19c83bSHermès Bélusca-Maïto                            0,
37066f19c83bSHermès Bélusca-Maïto                            REG_BINARY,
37076f19c83bSHermès Bélusca-Maïto                            (PVOID)&MountInfo,
37086f19c83bSHermès Bélusca-Maïto                            sizeof(MountInfo));
37096f19c83bSHermès Bélusca-Maïto     NtClose(KeyHandle);
37106f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
37116f19c83bSHermès Bélusca-Maïto     {
37126f19c83bSHermès Bélusca-Maïto         DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
37136f19c83bSHermès Bélusca-Maïto         return FALSE;
37146f19c83bSHermès Bélusca-Maïto     }
37156f19c83bSHermès Bélusca-Maïto 
37166f19c83bSHermès Bélusca-Maïto     return TRUE;
37176f19c83bSHermès Bélusca-Maïto }
37186f19c83bSHermès Bélusca-Maïto 
37196f19c83bSHermès Bélusca-Maïto BOOLEAN
37206f19c83bSHermès Bélusca-Maïto SetMountedDeviceValues(
37216f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
37226f19c83bSHermès Bélusca-Maïto {
37236f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1, Entry2;
37246f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
37256f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
37266f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER StartingOffset;
37276f19c83bSHermès Bélusca-Maïto 
37286f19c83bSHermès Bélusca-Maïto     if (List == NULL)
37296f19c83bSHermès Bélusca-Maïto         return FALSE;
37306f19c83bSHermès Bélusca-Maïto 
37318bed4adfSHermès Bélusca-Maïto     for (Entry1 = List->DiskListHead.Flink;
37328bed4adfSHermès Bélusca-Maïto          Entry1 != &List->DiskListHead;
37338bed4adfSHermès Bélusca-Maïto          Entry1 = Entry1->Flink)
37346f19c83bSHermès Bélusca-Maïto     {
37356f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1,
37366f19c83bSHermès Bélusca-Maïto                                       DISKENTRY,
37376f19c83bSHermès Bélusca-Maïto                                       ListEntry);
37386f19c83bSHermès Bélusca-Maïto 
3739a3168373SHermès Bélusca-Maïto         if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3740a3168373SHermès Bélusca-Maïto         {
3741a3168373SHermès Bélusca-Maïto             DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3742a3168373SHermès Bélusca-Maïto             continue;
3743a3168373SHermès Bélusca-Maïto         }
3744a3168373SHermès Bélusca-Maïto 
37458bed4adfSHermès Bélusca-Maïto         for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
37468bed4adfSHermès Bélusca-Maïto              Entry2 != &DiskEntry->PrimaryPartListHead;
37478bed4adfSHermès Bélusca-Maïto              Entry2 = Entry2->Flink)
37486f19c83bSHermès Bélusca-Maïto         {
37496f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
375029cc1843SHermès Bélusca-Maïto             if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
37516f19c83bSHermès Bélusca-Maïto             {
375229cc1843SHermès Bélusca-Maïto                 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
375329cc1843SHermès Bélusca-Maïto 
37546f19c83bSHermès Bélusca-Maïto                 /* Assign a "\DosDevices\#:" mount point to this partition */
37556f19c83bSHermès Bélusca-Maïto                 if (PartEntry->DriveLetter)
37566f19c83bSHermès Bélusca-Maïto                 {
37576f19c83bSHermès Bélusca-Maïto                     StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
37586f19c83bSHermès Bélusca-Maïto                     if (!SetMountedDeviceValue(PartEntry->DriveLetter,
37596f19c83bSHermès Bélusca-Maïto                                                DiskEntry->LayoutBuffer->Signature,
37606f19c83bSHermès Bélusca-Maïto                                                StartingOffset))
37616f19c83bSHermès Bélusca-Maïto                     {
37626f19c83bSHermès Bélusca-Maïto                         return FALSE;
37636f19c83bSHermès Bélusca-Maïto                     }
37646f19c83bSHermès Bélusca-Maïto                 }
37656f19c83bSHermès Bélusca-Maïto             }
37666f19c83bSHermès Bélusca-Maïto         }
37676f19c83bSHermès Bélusca-Maïto 
37688bed4adfSHermès Bélusca-Maïto         for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
37698bed4adfSHermès Bélusca-Maïto              Entry2 != &DiskEntry->LogicalPartListHead;
37708bed4adfSHermès Bélusca-Maïto              Entry2 = Entry2->Flink)
37716f19c83bSHermès Bélusca-Maïto         {
37726f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
377329cc1843SHermès Bélusca-Maïto             if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
37746f19c83bSHermès Bélusca-Maïto             {
377529cc1843SHermès Bélusca-Maïto                 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
377629cc1843SHermès Bélusca-Maïto 
37776f19c83bSHermès Bélusca-Maïto                 /* Assign a "\DosDevices\#:" mount point to this partition */
37786f19c83bSHermès Bélusca-Maïto                 if (PartEntry->DriveLetter)
37796f19c83bSHermès Bélusca-Maïto                 {
37806f19c83bSHermès Bélusca-Maïto                     StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
37816f19c83bSHermès Bélusca-Maïto                     if (!SetMountedDeviceValue(PartEntry->DriveLetter,
37826f19c83bSHermès Bélusca-Maïto                                                DiskEntry->LayoutBuffer->Signature,
37836f19c83bSHermès Bélusca-Maïto                                                StartingOffset))
37846f19c83bSHermès Bélusca-Maïto                     {
37856f19c83bSHermès Bélusca-Maïto                         return FALSE;
37866f19c83bSHermès Bélusca-Maïto                     }
37876f19c83bSHermès Bélusca-Maïto                 }
37886f19c83bSHermès Bélusca-Maïto             }
37896f19c83bSHermès Bélusca-Maïto         }
37906f19c83bSHermès Bélusca-Maïto     }
37916f19c83bSHermès Bélusca-Maïto 
37926f19c83bSHermès Bélusca-Maïto     return TRUE;
37936f19c83bSHermès Bélusca-Maïto }
37946f19c83bSHermès Bélusca-Maïto 
37956f19c83bSHermès Bélusca-Maïto VOID
37966f19c83bSHermès Bélusca-Maïto SetPartitionType(
37976f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry,
37986f19c83bSHermès Bélusca-Maïto     IN UCHAR PartitionType)
37996f19c83bSHermès Bélusca-Maïto {
38006f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
38016f19c83bSHermès Bélusca-Maïto 
38026f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionType = PartitionType;
38036f19c83bSHermès Bélusca-Maïto 
38046f19c83bSHermès Bélusca-Maïto     DiskEntry->Dirty = TRUE;
38056f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
38067df92966SHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
38076f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
38086f19c83bSHermès Bélusca-Maïto }
38096f19c83bSHermès Bélusca-Maïto 
38106f19c83bSHermès Bélusca-Maïto ERROR_NUMBER
38116f19c83bSHermès Bélusca-Maïto PrimaryPartitionCreationChecks(
381229cc1843SHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
38136f19c83bSHermès Bélusca-Maïto {
381429cc1843SHermès Bélusca-Maïto     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
38156f19c83bSHermès Bélusca-Maïto 
3816a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3817a3168373SHermès Bélusca-Maïto     {
3818a3168373SHermès Bélusca-Maïto         DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3819a3168373SHermès Bélusca-Maïto         return ERROR_WARN_PARTITION;
3820a3168373SHermès Bélusca-Maïto     }
3821a3168373SHermès Bélusca-Maïto 
38226f19c83bSHermès Bélusca-Maïto     /* Fail if the partition is already in use */
382370fa2e2eSHermès Bélusca-Maïto     if (PartEntry->IsPartitioned)
38246f19c83bSHermès Bélusca-Maïto         return ERROR_NEW_PARTITION;
38256f19c83bSHermès Bélusca-Maïto 
38266f19c83bSHermès Bélusca-Maïto     /* Fail if there are already 4 primary partitions in the list */
38276f19c83bSHermès Bélusca-Maïto     if (GetPrimaryPartitionCount(DiskEntry) >= 4)
38286f19c83bSHermès Bélusca-Maïto         return ERROR_PARTITION_TABLE_FULL;
38296f19c83bSHermès Bélusca-Maïto 
38306f19c83bSHermès Bélusca-Maïto     return ERROR_SUCCESS;
38316f19c83bSHermès Bélusca-Maïto }
38326f19c83bSHermès Bélusca-Maïto 
38336f19c83bSHermès Bélusca-Maïto ERROR_NUMBER
38346f19c83bSHermès Bélusca-Maïto ExtendedPartitionCreationChecks(
383529cc1843SHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
38366f19c83bSHermès Bélusca-Maïto {
383729cc1843SHermès Bélusca-Maïto     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
38386f19c83bSHermès Bélusca-Maïto 
3839a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3840a3168373SHermès Bélusca-Maïto     {
3841a3168373SHermès Bélusca-Maïto         DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3842a3168373SHermès Bélusca-Maïto         return ERROR_WARN_PARTITION;
3843a3168373SHermès Bélusca-Maïto     }
3844a3168373SHermès Bélusca-Maïto 
38456f19c83bSHermès Bélusca-Maïto     /* Fail if the partition is already in use */
384670fa2e2eSHermès Bélusca-Maïto     if (PartEntry->IsPartitioned)
38476f19c83bSHermès Bélusca-Maïto         return ERROR_NEW_PARTITION;
38486f19c83bSHermès Bélusca-Maïto 
38496f19c83bSHermès Bélusca-Maïto     /* Fail if there are already 4 primary partitions in the list */
38506f19c83bSHermès Bélusca-Maïto     if (GetPrimaryPartitionCount(DiskEntry) >= 4)
38516f19c83bSHermès Bélusca-Maïto         return ERROR_PARTITION_TABLE_FULL;
38526f19c83bSHermès Bélusca-Maïto 
38536f19c83bSHermès Bélusca-Maïto     /* Fail if there is another extended partition in the list */
38546f19c83bSHermès Bélusca-Maïto     if (DiskEntry->ExtendedPartition != NULL)
38556f19c83bSHermès Bélusca-Maïto         return ERROR_ONLY_ONE_EXTENDED;
38566f19c83bSHermès Bélusca-Maïto 
38576f19c83bSHermès Bélusca-Maïto     return ERROR_SUCCESS;
38586f19c83bSHermès Bélusca-Maïto }
38596f19c83bSHermès Bélusca-Maïto 
38606f19c83bSHermès Bélusca-Maïto ERROR_NUMBER
38616f19c83bSHermès Bélusca-Maïto LogicalPartitionCreationChecks(
386229cc1843SHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
38636f19c83bSHermès Bélusca-Maïto {
386429cc1843SHermès Bélusca-Maïto     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
38656f19c83bSHermès Bélusca-Maïto 
3866a3168373SHermès Bélusca-Maïto     if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3867a3168373SHermès Bélusca-Maïto     {
3868a3168373SHermès Bélusca-Maïto         DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3869a3168373SHermès Bélusca-Maïto         return ERROR_WARN_PARTITION;
3870a3168373SHermès Bélusca-Maïto     }
3871a3168373SHermès Bélusca-Maïto 
38726f19c83bSHermès Bélusca-Maïto     /* Fail if the partition is already in use */
387370fa2e2eSHermès Bélusca-Maïto     if (PartEntry->IsPartitioned)
38746f19c83bSHermès Bélusca-Maïto         return ERROR_NEW_PARTITION;
38756f19c83bSHermès Bélusca-Maïto 
38766f19c83bSHermès Bélusca-Maïto     return ERROR_SUCCESS;
38776f19c83bSHermès Bélusca-Maïto }
38786f19c83bSHermès Bélusca-Maïto 
38796f19c83bSHermès Bélusca-Maïto BOOLEAN
38806f19c83bSHermès Bélusca-Maïto GetNextUnformattedPartition(
38816f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
38826f19c83bSHermès Bélusca-Maïto     OUT PDISKENTRY *pDiskEntry OPTIONAL,
38836f19c83bSHermès Bélusca-Maïto     OUT PPARTENTRY *pPartEntry)
38846f19c83bSHermès Bélusca-Maïto {
38856f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1, Entry2;
38866f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
38876f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
38886f19c83bSHermès Bélusca-Maïto 
38898bed4adfSHermès Bélusca-Maïto     for (Entry1 = List->DiskListHead.Flink;
38908bed4adfSHermès Bélusca-Maïto          Entry1 != &List->DiskListHead;
38918bed4adfSHermès Bélusca-Maïto          Entry1 = Entry1->Flink)
38926f19c83bSHermès Bélusca-Maïto     {
38936f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1,
38946f19c83bSHermès Bélusca-Maïto                                       DISKENTRY,
38956f19c83bSHermès Bélusca-Maïto                                       ListEntry);
38966f19c83bSHermès Bélusca-Maïto 
3897a3168373SHermès Bélusca-Maïto         if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3898a3168373SHermès Bélusca-Maïto         {
3899a3168373SHermès Bélusca-Maïto             DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3900a3168373SHermès Bélusca-Maïto             continue;
3901a3168373SHermès Bélusca-Maïto         }
3902a3168373SHermès Bélusca-Maïto 
39038bed4adfSHermès Bélusca-Maïto         for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
39048bed4adfSHermès Bélusca-Maïto              Entry2 != &DiskEntry->PrimaryPartListHead;
39058bed4adfSHermès Bélusca-Maïto              Entry2 = Entry2->Flink)
39066f19c83bSHermès Bélusca-Maïto         {
39076f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
39086f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned && PartEntry->New)
39096f19c83bSHermès Bélusca-Maïto             {
39106f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
39116f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
39126f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
39136f19c83bSHermès Bélusca-Maïto                 return TRUE;
39146f19c83bSHermès Bélusca-Maïto             }
39156f19c83bSHermès Bélusca-Maïto         }
39166f19c83bSHermès Bélusca-Maïto 
39178bed4adfSHermès Bélusca-Maïto         for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
39188bed4adfSHermès Bélusca-Maïto              Entry2 != &DiskEntry->LogicalPartListHead;
39198bed4adfSHermès Bélusca-Maïto              Entry2 = Entry2->Flink)
39206f19c83bSHermès Bélusca-Maïto         {
39216f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
39226f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned && PartEntry->New)
39236f19c83bSHermès Bélusca-Maïto             {
39246f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
39256f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
39266f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
39276f19c83bSHermès Bélusca-Maïto                 return TRUE;
39286f19c83bSHermès Bélusca-Maïto             }
39296f19c83bSHermès Bélusca-Maïto         }
39306f19c83bSHermès Bélusca-Maïto     }
39316f19c83bSHermès Bélusca-Maïto 
39326f19c83bSHermès Bélusca-Maïto     if (pDiskEntry) *pDiskEntry = NULL;
39336f19c83bSHermès Bélusca-Maïto     *pPartEntry = NULL;
39346f19c83bSHermès Bélusca-Maïto 
39356f19c83bSHermès Bélusca-Maïto     return FALSE;
39366f19c83bSHermès Bélusca-Maïto }
39376f19c83bSHermès Bélusca-Maïto 
39386f19c83bSHermès Bélusca-Maïto BOOLEAN
39396f19c83bSHermès Bélusca-Maïto GetNextUncheckedPartition(
39406f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
39416f19c83bSHermès Bélusca-Maïto     OUT PDISKENTRY *pDiskEntry OPTIONAL,
39426f19c83bSHermès Bélusca-Maïto     OUT PPARTENTRY *pPartEntry)
39436f19c83bSHermès Bélusca-Maïto {
39446f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1, Entry2;
39456f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
39466f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
39476f19c83bSHermès Bélusca-Maïto 
39488bed4adfSHermès Bélusca-Maïto     for (Entry1 = List->DiskListHead.Flink;
39498bed4adfSHermès Bélusca-Maïto          Entry1 != &List->DiskListHead;
39508bed4adfSHermès Bélusca-Maïto          Entry1 = Entry1->Flink)
39516f19c83bSHermès Bélusca-Maïto     {
39526f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1,
39536f19c83bSHermès Bélusca-Maïto                                       DISKENTRY,
39546f19c83bSHermès Bélusca-Maïto                                       ListEntry);
39556f19c83bSHermès Bélusca-Maïto 
3956a3168373SHermès Bélusca-Maïto         if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3957a3168373SHermès Bélusca-Maïto         {
3958a3168373SHermès Bélusca-Maïto             DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3959a3168373SHermès Bélusca-Maïto             continue;
3960a3168373SHermès Bélusca-Maïto         }
3961a3168373SHermès Bélusca-Maïto 
39628bed4adfSHermès Bélusca-Maïto         for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
39638bed4adfSHermès Bélusca-Maïto              Entry2 != &DiskEntry->PrimaryPartListHead;
39648bed4adfSHermès Bélusca-Maïto              Entry2 = Entry2->Flink)
39656f19c83bSHermès Bélusca-Maïto         {
39666f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
396729cc1843SHermès Bélusca-Maïto             if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
39686f19c83bSHermès Bélusca-Maïto             {
39696f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
39706f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
39716f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
39726f19c83bSHermès Bélusca-Maïto                 return TRUE;
39736f19c83bSHermès Bélusca-Maïto             }
39746f19c83bSHermès Bélusca-Maïto         }
39756f19c83bSHermès Bélusca-Maïto 
39768bed4adfSHermès Bélusca-Maïto         for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
39778bed4adfSHermès Bélusca-Maïto              Entry2 != &DiskEntry->LogicalPartListHead;
39788bed4adfSHermès Bélusca-Maïto              Entry2 = Entry2->Flink)
39796f19c83bSHermès Bélusca-Maïto         {
39806f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
398129cc1843SHermès Bélusca-Maïto             if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
39826f19c83bSHermès Bélusca-Maïto             {
39836f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
39846f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
39856f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
39866f19c83bSHermès Bélusca-Maïto                 return TRUE;
39876f19c83bSHermès Bélusca-Maïto             }
39886f19c83bSHermès Bélusca-Maïto         }
39896f19c83bSHermès Bélusca-Maïto     }
39906f19c83bSHermès Bélusca-Maïto 
39916f19c83bSHermès Bélusca-Maïto     if (pDiskEntry) *pDiskEntry = NULL;
39926f19c83bSHermès Bélusca-Maïto     *pPartEntry = NULL;
39936f19c83bSHermès Bélusca-Maïto 
39946f19c83bSHermès Bélusca-Maïto     return FALSE;
39956f19c83bSHermès Bélusca-Maïto }
39966f19c83bSHermès Bélusca-Maïto 
39976f19c83bSHermès Bélusca-Maïto /* EOF */
3998