xref: /reactos/base/setup/lib/utils/partlist.c (revision 7df92966)
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
56f19c83bSHermès Bélusca-Maïto  * COPYRIGHT:   Copyright 2003-2018 Casper S. Hornstrup (chorns@users.sourceforge.net)
66f19c83bSHermès Bélusca-Maïto  */
76f19c83bSHermès Bélusca-Maïto 
86f19c83bSHermès Bélusca-Maïto #include "precomp.h"
96f19c83bSHermès Bélusca-Maïto #include <ntddscsi.h>
106f19c83bSHermès Bélusca-Maïto 
116f19c83bSHermès Bélusca-Maïto #include "partlist.h"
126f19c83bSHermès Bélusca-Maïto #include "fsutil.h"
136f19c83bSHermès Bélusca-Maïto 
146f19c83bSHermès Bélusca-Maïto #define NDEBUG
156f19c83bSHermès Bélusca-Maïto #include <debug.h>
166f19c83bSHermès Bélusca-Maïto 
176f19c83bSHermès Bélusca-Maïto //#define DUMP_PARTITION_TABLE
186f19c83bSHermès Bélusca-Maïto 
196f19c83bSHermès Bélusca-Maïto #include <pshpack1.h>
206f19c83bSHermès Bélusca-Maïto 
216f19c83bSHermès Bélusca-Maïto typedef struct _REG_DISK_MOUNT_INFO
226f19c83bSHermès Bélusca-Maïto {
236f19c83bSHermès Bélusca-Maïto     ULONG Signature;
246f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER StartingOffset;
256f19c83bSHermès Bélusca-Maïto } REG_DISK_MOUNT_INFO, *PREG_DISK_MOUNT_INFO;
266f19c83bSHermès Bélusca-Maïto 
276f19c83bSHermès Bélusca-Maïto #include <poppack.h>
286f19c83bSHermès Bélusca-Maïto 
296f19c83bSHermès Bélusca-Maïto 
30f41750abSHermès Bélusca-Maïto /* HELPERS FOR PARTITION TYPES **********************************************/
31f41750abSHermès Bélusca-Maïto 
32f41750abSHermès Bélusca-Maïto /*
33f41750abSHermès Bélusca-Maïto  * This partition type list was ripped from the kernelDisk.c module of
34f41750abSHermès Bélusca-Maïto  * the Visopsys Operating System (see license below), and completed with
35f41750abSHermès Bélusca-Maïto  * information from Paragon Hard-Disk Manager, and the following websites:
36f41750abSHermès Bélusca-Maïto  * http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
37f41750abSHermès Bélusca-Maïto  * https://en.wikipedia.org/wiki/Partition_type#List_of_partition_IDs
38f41750abSHermès Bélusca-Maïto  */
39f41750abSHermès Bélusca-Maïto /*
40f41750abSHermès Bélusca-Maïto  * kernelDisk.c
41f41750abSHermès Bélusca-Maïto  *
42f41750abSHermès Bélusca-Maïto  * Visopsys Operating System
43f41750abSHermès Bélusca-Maïto  * Copyright (C) 1998-2015 J. Andrew McLaughlin
44f41750abSHermès Bélusca-Maïto  *
45f41750abSHermès Bélusca-Maïto  * This program is free software; you can redistribute it and/or modify it
46f41750abSHermès Bélusca-Maïto  * under the terms of the GNU General Public License as published by the Free
47f41750abSHermès Bélusca-Maïto  * Software Foundation; either version 2 of the License, or (at your option)
48f41750abSHermès Bélusca-Maïto  * any later version.
49f41750abSHermès Bélusca-Maïto  *
50f41750abSHermès Bélusca-Maïto  * This program is distributed in the hope that it will be useful, but
51f41750abSHermès Bélusca-Maïto  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
52f41750abSHermès Bélusca-Maïto  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
53f41750abSHermès Bélusca-Maïto  * for more details.
54f41750abSHermès Bélusca-Maïto  *
55f41750abSHermès Bélusca-Maïto  * You should have received a copy of the GNU General Public License along
56f41750abSHermès Bélusca-Maïto  * with this program; if not, write to the Free Software Foundation, Inc.,
57f41750abSHermès Bélusca-Maïto  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
58f41750abSHermès Bélusca-Maïto  */
59f41750abSHermès Bélusca-Maïto 
60f41750abSHermès Bélusca-Maïto /* This is a table for keeping known partition type codes and descriptions */
61f41750abSHermès Bélusca-Maïto PARTITION_TYPE PartitionTypes[NUM_PARTITION_TYPE_ENTRIES] =
62f41750abSHermès Bélusca-Maïto {
63f41750abSHermès Bélusca-Maïto     { 0x00, "(Empty)" },
64f41750abSHermès Bélusca-Maïto     { 0x01, "FAT12" },
65f41750abSHermès Bélusca-Maïto     { 0x02, "XENIX root" },
66f41750abSHermès Bélusca-Maïto     { 0x03, "XENIX usr" },
67f41750abSHermès Bélusca-Maïto     { 0x04, "FAT16 (< 32 MB)" },
68f41750abSHermès Bélusca-Maïto     { 0x05, "Extended" },
69f41750abSHermès Bélusca-Maïto     { 0x06, "FAT16" },
70f41750abSHermès Bélusca-Maïto     { 0x07, "NTFS/HPFS/exFAT" },
71f41750abSHermès Bélusca-Maïto     { 0x08, "OS/2 or AIX boot" },
72f41750abSHermès Bélusca-Maïto     { 0x09, "AIX data" },
73f41750abSHermès Bélusca-Maïto     { 0x0A, "OS/2 Boot Manager" },
74f41750abSHermès Bélusca-Maïto     { 0x0B, "FAT32" },
75f41750abSHermès Bélusca-Maïto     { 0x0C, "FAT32 (LBA)" },
76f41750abSHermès Bélusca-Maïto     { 0x0E, "FAT16 (LBA)" },
77f41750abSHermès Bélusca-Maïto     { 0x0F, "Extended (LBA)" },
78f41750abSHermès Bélusca-Maïto     { 0x10, "OPUS" },
79f41750abSHermès Bélusca-Maïto     { 0x11, "Hidden FAT12" },
80f41750abSHermès Bélusca-Maïto     { 0x12, "FAT diagnostic (Compaq)" },
81f41750abSHermès Bélusca-Maïto     { 0x13, "BTRON" },
82f41750abSHermès Bélusca-Maïto     { 0x14, "Hidden FAT16 (< 32 MB)" },
83f41750abSHermès Bélusca-Maïto     { 0x16, "Hidden FAT16" },
84f41750abSHermès Bélusca-Maïto     { 0x17, "Hidden HPFS or NTFS" },
85f41750abSHermès Bélusca-Maïto     { 0x18, "AST SmartSleep" },
86f41750abSHermès Bélusca-Maïto     { 0x1B, "Hidden FAT32" },
87f41750abSHermès Bélusca-Maïto     { 0x1C, "Hidden FAT32 (LBA)" },
88f41750abSHermès Bélusca-Maïto     { 0x1E, "Hidden FAT16 (LBA)" },
89f41750abSHermès Bélusca-Maïto     { 0x24, "NEC DOS 3.x" },
90f41750abSHermès Bélusca-Maïto     { 0x27, "Hidden WinRE NTFS" },
91f41750abSHermès Bélusca-Maïto     { 0x2A, "AtheOS File System (AFS)" },
92f41750abSHermès Bélusca-Maïto     { 0x2B, "SyllableSecure (SylStor)" },
93f41750abSHermès Bélusca-Maïto     { 0x32, "NOS" },
94f41750abSHermès Bélusca-Maïto     { 0x35, "JFS on OS/2 or eCS" },
95f41750abSHermès Bélusca-Maïto     { 0x38, "THEOS v3.2 2GB partition" },
96f41750abSHermès Bélusca-Maïto     { 0x39, "Plan 9" },
97f41750abSHermès Bélusca-Maïto     { 0x3A, "THEOS v4 4GB partition" },
98f41750abSHermès Bélusca-Maïto     { 0x3B, "THEOS v4 extended partition" },
99f41750abSHermès Bélusca-Maïto     { 0x3C, "PartitionMagic recovery partition" },
100f41750abSHermès Bélusca-Maïto     { 0x3D, "Hidden NetWare" },
101f41750abSHermès Bélusca-Maïto     { 0x40, "Lynx" },
102f41750abSHermès Bélusca-Maïto     { 0x41, "PowerPC PReP boot" },
103f41750abSHermès Bélusca-Maïto     { 0x42, "Win2K Dynamic Volume extended" },
104f41750abSHermès Bélusca-Maïto     { 0x43, "Old Linux" },
105f41750abSHermès Bélusca-Maïto     { 0x44, "GoBack" },
106f41750abSHermès Bélusca-Maïto     { 0x45, "Priam or Boot-US Boot Manager" },
107f41750abSHermès Bélusca-Maïto     { 0x4D, "QNX4.x" },
108f41750abSHermès Bélusca-Maïto     { 0x4E, "QNX4.x 2nd partition" },
109f41750abSHermès Bélusca-Maïto     { 0x4F, "QNX4.x 3rd partition" },
110f41750abSHermès Bélusca-Maïto     { 0x50, "OnTrack Disk Manager R/O" },
111f41750abSHermès Bélusca-Maïto     { 0x51, "OnTrack Disk Manager R/W or Novell" },
112f41750abSHermès Bélusca-Maïto     { 0x52, "CP/M" },
113f41750abSHermès Bélusca-Maïto     { 0x53, "OnTrack DM6 Aux3" },
114f41750abSHermès Bélusca-Maïto     { 0x54, "OnTrack DM6 Dynamic Drive Overlay" },
115f41750abSHermès Bélusca-Maïto     { 0x55, "EZ-Drive" },
116f41750abSHermès Bélusca-Maïto     { 0x56, "Golden Bow VFeature Partitioned Volume" },
117f41750abSHermès Bélusca-Maïto     { 0x5C, "Priam EDisk" },
118f41750abSHermès Bélusca-Maïto     { 0x61, "SpeedStor" },
119f41750abSHermès Bélusca-Maïto     { 0x62, "Pick" },
120f41750abSHermès Bélusca-Maïto     { 0x63, "GNU HURD or Unix System V (SCO, ISC Unix, UnixWare)" },
121f41750abSHermès Bélusca-Maïto     { 0x64, "Novell NetWare 286, 2.xx" },
122f41750abSHermès Bélusca-Maïto     { 0x65, "Novell NetWare 386, 3.xx or 4.xx" },
123f41750abSHermès Bélusca-Maïto     { 0x66, "Novell NetWare SMS Partition" },
124f41750abSHermès Bélusca-Maïto     { 0x67, "Novell" },
125f41750abSHermès Bélusca-Maïto     { 0x68, "Novell" },
126f41750abSHermès Bélusca-Maïto     { 0x69, "Novell NetWare 5+" },
127f41750abSHermès Bélusca-Maïto     { 0x70, "DiskSecure Multi-Boot" },
128f41750abSHermès Bélusca-Maïto     { 0x75, "IBM PC/IX" },
129f41750abSHermès Bélusca-Maïto     { 0x7E, "Veritas VxVM public" },
130f41750abSHermès Bélusca-Maïto     { 0x7F, "Veritas VxVM private" },
131f41750abSHermès Bélusca-Maïto     { 0x80, "Old MINIX" },
132f41750abSHermès Bélusca-Maïto     { 0x81, "Linux or MINIX" },
133f41750abSHermès Bélusca-Maïto     { 0x82, "Linux swap or Solaris" },
134f41750abSHermès Bélusca-Maïto     { 0x83, "Linux Native" },
135f41750abSHermès Bélusca-Maïto     { 0x84, "Hibernate" },
136f41750abSHermès Bélusca-Maïto     { 0x85, "Extended Linux" },
137f41750abSHermès Bélusca-Maïto     { 0x86, "FAT16 mirrored" },
138f41750abSHermès Bélusca-Maïto     { 0x87, "HPFS or NTFS mirrored" },
139f41750abSHermès Bélusca-Maïto     { 0x88, "Linux plaintext partition table" },
140f41750abSHermès Bélusca-Maïto     { 0x8B, "FAT32 mirrored" },
141f41750abSHermès Bélusca-Maïto     { 0x8C, "FAT32 (LBA) mirrored" },
142f41750abSHermès Bélusca-Maïto     { 0x8E, "Linux LVM" },
143f41750abSHermès Bélusca-Maïto     { 0x93, "Hidden Linux" },
144f41750abSHermès Bélusca-Maïto     { 0x94, "Amoeba BBT" },
145f41750abSHermès Bélusca-Maïto     { 0x96, "CDFS/ISO-9660" },
146f41750abSHermès Bélusca-Maïto     { 0x9F, "BSD/OS" },
147f41750abSHermès Bélusca-Maïto     { 0xA0, "Laptop Hibernate" },
148f41750abSHermès Bélusca-Maïto     { 0xA1, "Laptop Hibernate (NEC 6000H)" },
149f41750abSHermès Bélusca-Maïto     { 0xA5, "BSD, NetBSD, FreeBSD" },
150f41750abSHermès Bélusca-Maïto     { 0xA6, "OpenBSD" },
151f41750abSHermès Bélusca-Maïto     { 0xA7, "NeXTStep" },
152f41750abSHermès Bélusca-Maïto     { 0xA8, "Darwin UFS" },      // Also known as "OS-X"
153f41750abSHermès Bélusca-Maïto     { 0xA9, "NetBSD" },
154f41750abSHermès Bélusca-Maïto     { 0xAB, "Darwin boot" },
155f41750abSHermès Bélusca-Maïto     { 0xAF, "Apple HFS" },
156f41750abSHermès Bélusca-Maïto     { 0xB6, "NT FAT16 corrupt mirror" },
157f41750abSHermès Bélusca-Maïto     { 0xB7, "BSDI BSD/386 FS" }, // Alternatively, "NT NTFS corrupt mirror"
158f41750abSHermès Bélusca-Maïto     { 0xB8, "BSDI BSD/386 swap" },
159f41750abSHermès Bélusca-Maïto     { 0xBB, "Boot Wizard hidden" },
160f41750abSHermès Bélusca-Maïto     { 0xBC, "Paragon Backup capsule" },
161f41750abSHermès Bélusca-Maïto     { 0xBE, "Solaris 8 boot partition" },
162f41750abSHermès Bélusca-Maïto     { 0xBF, "Solaris 10 x86" },
163f41750abSHermès Bélusca-Maïto     { 0xC0, "NTFT" },            // Alternatively, "CTOS" or "REAL/32 or DR-DOS or Novell-DOS secure partition"
164f41750abSHermès Bélusca-Maïto     { 0xC1, "DR-DOS FAT12" },
165f41750abSHermès Bélusca-Maïto     { 0xC2, "Hidden Linux" },
166f41750abSHermès Bélusca-Maïto     { 0xC3, "Hidden Linux swap" },
167f41750abSHermès Bélusca-Maïto     { 0xC4, "DR-DOS FAT16 (< 32 MB)" },
168f41750abSHermès Bélusca-Maïto     { 0xC5, "DR-DOS Extended" },
169f41750abSHermès Bélusca-Maïto     { 0xC6, "DR-DOS FAT16" },
170f41750abSHermès Bélusca-Maïto     { 0xC7, "HPFS mirrored" },   // Alternatively, "Syrinx boot"
171f41750abSHermès Bélusca-Maïto     { 0xCB, "DR-DOS FAT32" },
172f41750abSHermès Bélusca-Maïto     { 0xCC, "DR-DOS FAT32 (LBA)" },
173f41750abSHermès Bélusca-Maïto     { 0xCE, "DR-DOS FAT16 (LBA)" },
174f41750abSHermès Bélusca-Maïto     { 0xD0, "MDOS" },
175f41750abSHermès Bélusca-Maïto     { 0xD1, "MDOS FAT12" },
176f41750abSHermès Bélusca-Maïto     { 0xD4, "MDOS FAT16 (< 32 MB)" },
177f41750abSHermès Bélusca-Maïto     { 0xD5, "MDOS Extended" },
178f41750abSHermès Bélusca-Maïto     { 0xD6, "MDOS FAT16" },
179f41750abSHermès Bélusca-Maïto     { 0xD8, "CP/M-86" },
180f41750abSHermès Bélusca-Maïto     { 0xDB, "Digital Research CP/M" },
181f41750abSHermès Bélusca-Maïto     { 0xDE, "Dell OEM" },
182f41750abSHermès Bélusca-Maïto     { 0xDF, "BootIt EMBRM (FAT16/32)" },
183f41750abSHermès Bélusca-Maïto     { 0xE1, "SpeedStor FAT12" },
184f41750abSHermès Bélusca-Maïto     { 0xE3, "SpeedStor (0xE3)" },
185f41750abSHermès Bélusca-Maïto     { 0xE4, "SpeedStor FAT16" },
186f41750abSHermès Bélusca-Maïto     { 0xE5, "Tandy MSDOS" },
187f41750abSHermès Bélusca-Maïto     { 0xE6, "SpeedStor (0xE6)" },
188f41750abSHermès Bélusca-Maïto     { 0xE8, "Linux Unified Key Setup partition" },
189f41750abSHermès Bélusca-Maïto     { 0xEA, "Rufus private partition" },
190f41750abSHermès Bélusca-Maïto     { 0xEB, "BeOS BFS" },
191f41750abSHermès Bélusca-Maïto     { 0xEC, "SkyOS SkyFS" },
192f41750abSHermès Bélusca-Maïto     { 0xEE, "EFI GPT protective" },
193f41750abSHermès Bélusca-Maïto     { 0xEF, "EFI System partition" },
194f41750abSHermès Bélusca-Maïto     { 0xF0, "Linux/PA-RISC boot loader" },
195f41750abSHermès Bélusca-Maïto     { 0xF1, "SpeedStor (0xF1)" },
196f41750abSHermès Bélusca-Maïto     { 0xF2, "DOS 3.3+ second" },
197f41750abSHermès Bélusca-Maïto     { 0xF4, "SpeedStor (0xF4)" },
198f41750abSHermès Bélusca-Maïto     { 0xF5, "SpeedStor (0xF5)" },
199f41750abSHermès Bélusca-Maïto     { 0xF6, "SpeedStor (0xF6)" },
200f41750abSHermès Bélusca-Maïto     { 0xFA, "Bochs" },
201f41750abSHermès Bélusca-Maïto     { 0xFB, "VMware FS" },
202f41750abSHermès Bélusca-Maïto     { 0xFC, "VMware swap" },
203f41750abSHermès Bélusca-Maïto     { 0xFD, "Linux RAID auto" },
204f41750abSHermès Bélusca-Maïto     { 0xFE, "NT hidden partition" },
205f41750abSHermès Bélusca-Maïto     { 0xFF, "XENIX Bad Block Table" },
206f41750abSHermès Bélusca-Maïto };
207f41750abSHermès Bélusca-Maïto 
208f41750abSHermès Bélusca-Maïto 
2096f19c83bSHermès Bélusca-Maïto /* FUNCTIONS ****************************************************************/
2106f19c83bSHermès Bélusca-Maïto 
2116f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
2126f19c83bSHermès Bélusca-Maïto static
2136f19c83bSHermès Bélusca-Maïto VOID
2146f19c83bSHermès Bélusca-Maïto DumpPartitionTable(
2156f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry)
2166f19c83bSHermès Bélusca-Maïto {
2176f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
2186f19c83bSHermès Bélusca-Maïto     ULONG i;
2196f19c83bSHermès Bélusca-Maïto 
2206f19c83bSHermès Bélusca-Maïto     DbgPrint("\n");
2216f19c83bSHermès Bélusca-Maïto     DbgPrint("Index  Start         Length        Hidden      Nr  Type  Boot  RW\n");
2226f19c83bSHermès Bélusca-Maïto     DbgPrint("-----  ------------  ------------  ----------  --  ----  ----  --\n");
2236f19c83bSHermès Bélusca-Maïto 
2246f19c83bSHermès Bélusca-Maïto     for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++)
2256f19c83bSHermès Bélusca-Maïto     {
2266f19c83bSHermès Bélusca-Maïto         PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i];
2276f19c83bSHermès Bélusca-Maïto         DbgPrint("  %3lu  %12I64u  %12I64u  %10lu  %2lu    %2x     %c   %c\n",
2286f19c83bSHermès Bélusca-Maïto                  i,
2296f19c83bSHermès Bélusca-Maïto                  PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector,
2306f19c83bSHermès Bélusca-Maïto                  PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector,
2316f19c83bSHermès Bélusca-Maïto                  PartitionInfo->HiddenSectors,
2326f19c83bSHermès Bélusca-Maïto                  PartitionInfo->PartitionNumber,
2336f19c83bSHermès Bélusca-Maïto                  PartitionInfo->PartitionType,
2346f19c83bSHermès Bélusca-Maïto                  PartitionInfo->BootIndicator ? '*': ' ',
2356f19c83bSHermès Bélusca-Maïto                  PartitionInfo->RewritePartition ? 'Y': 'N');
2366f19c83bSHermès Bélusca-Maïto     }
2376f19c83bSHermès Bélusca-Maïto 
2386f19c83bSHermès Bélusca-Maïto     DbgPrint("\n");
2396f19c83bSHermès Bélusca-Maïto }
2406f19c83bSHermès Bélusca-Maïto #endif
2416f19c83bSHermès Bélusca-Maïto 
2426f19c83bSHermès Bélusca-Maïto 
2436f19c83bSHermès Bélusca-Maïto ULONGLONG
2446f19c83bSHermès Bélusca-Maïto AlignDown(
2456f19c83bSHermès Bélusca-Maïto     IN ULONGLONG Value,
2466f19c83bSHermès Bélusca-Maïto     IN ULONG Alignment)
2476f19c83bSHermès Bélusca-Maïto {
2486f19c83bSHermès Bélusca-Maïto     ULONGLONG Temp;
2496f19c83bSHermès Bélusca-Maïto 
2506f19c83bSHermès Bélusca-Maïto     Temp = Value / Alignment;
2516f19c83bSHermès Bélusca-Maïto 
2526f19c83bSHermès Bélusca-Maïto     return Temp * Alignment;
2536f19c83bSHermès Bélusca-Maïto }
2546f19c83bSHermès Bélusca-Maïto 
2556f19c83bSHermès Bélusca-Maïto ULONGLONG
2566f19c83bSHermès Bélusca-Maïto AlignUp(
2576f19c83bSHermès Bélusca-Maïto     IN ULONGLONG Value,
2586f19c83bSHermès Bélusca-Maïto     IN ULONG Alignment)
2596f19c83bSHermès Bélusca-Maïto {
2606f19c83bSHermès Bélusca-Maïto     ULONGLONG Temp, Result;
2616f19c83bSHermès Bélusca-Maïto 
2626f19c83bSHermès Bélusca-Maïto     Temp = Value / Alignment;
2636f19c83bSHermès Bélusca-Maïto 
2646f19c83bSHermès Bélusca-Maïto     Result = Temp * Alignment;
2656f19c83bSHermès Bélusca-Maïto     if (Value % Alignment)
2666f19c83bSHermès Bélusca-Maïto         Result += Alignment;
2676f19c83bSHermès Bélusca-Maïto 
2686f19c83bSHermès Bélusca-Maïto     return Result;
2696f19c83bSHermès Bélusca-Maïto }
2706f19c83bSHermès Bélusca-Maïto 
2716f19c83bSHermès Bélusca-Maïto ULONGLONG
2726f19c83bSHermès Bélusca-Maïto RoundingDivide(
2736f19c83bSHermès Bélusca-Maïto    IN ULONGLONG Dividend,
2746f19c83bSHermès Bélusca-Maïto    IN ULONGLONG Divisor)
2756f19c83bSHermès Bélusca-Maïto {
2766f19c83bSHermès Bélusca-Maïto     return (Dividend + Divisor / 2) / Divisor;
2776f19c83bSHermès Bélusca-Maïto }
2786f19c83bSHermès Bélusca-Maïto 
2796f19c83bSHermès Bélusca-Maïto 
2806f19c83bSHermès Bélusca-Maïto static
2816f19c83bSHermès Bélusca-Maïto VOID
2826f19c83bSHermès Bélusca-Maïto GetDriverName(
2836f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
2846f19c83bSHermès Bélusca-Maïto {
2856f19c83bSHermès Bélusca-Maïto     RTL_QUERY_REGISTRY_TABLE QueryTable[2];
2866f19c83bSHermès Bélusca-Maïto     WCHAR KeyName[32];
2876f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
2886f19c83bSHermès Bélusca-Maïto 
2896f19c83bSHermès Bélusca-Maïto     RtlInitUnicodeString(&DiskEntry->DriverName, NULL);
2906f19c83bSHermès Bélusca-Maïto 
2916f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(KeyName, ARRAYSIZE(KeyName),
2926f19c83bSHermès Bélusca-Maïto                         L"\\Scsi\\Scsi Port %hu",
2936f19c83bSHermès Bélusca-Maïto                         DiskEntry->Port);
2946f19c83bSHermès Bélusca-Maïto 
2956f19c83bSHermès Bélusca-Maïto     RtlZeroMemory(&QueryTable, sizeof(QueryTable));
2966f19c83bSHermès Bélusca-Maïto 
2976f19c83bSHermès Bélusca-Maïto     QueryTable[0].Name = L"Driver";
2986f19c83bSHermès Bélusca-Maïto     QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
2996f19c83bSHermès Bélusca-Maïto     QueryTable[0].EntryContext = &DiskEntry->DriverName;
3006f19c83bSHermès Bélusca-Maïto 
301f41750abSHermès Bélusca-Maïto     /* This will allocate DiskEntry->DriverName if needed */
3026f19c83bSHermès Bélusca-Maïto     Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
3036f19c83bSHermès Bélusca-Maïto                                     KeyName,
3046f19c83bSHermès Bélusca-Maïto                                     QueryTable,
3056f19c83bSHermès Bélusca-Maïto                                     NULL,
3066f19c83bSHermès Bélusca-Maïto                                     NULL);
3076f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
3086f19c83bSHermès Bélusca-Maïto     {
3096f19c83bSHermès Bélusca-Maïto         DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
3106f19c83bSHermès Bélusca-Maïto     }
3116f19c83bSHermès Bélusca-Maïto }
3126f19c83bSHermès Bélusca-Maïto 
3136f19c83bSHermès Bélusca-Maïto static
3146f19c83bSHermès Bélusca-Maïto VOID
3156f19c83bSHermès Bélusca-Maïto AssignDriveLetters(
3166f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
3176f19c83bSHermès Bélusca-Maïto {
3186f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
3196f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
3206f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1;
3216f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry2;
322f41750abSHermès Bélusca-Maïto     WCHAR Letter;
3236f19c83bSHermès Bélusca-Maïto 
324f41750abSHermès Bélusca-Maïto     Letter = L'C';
3256f19c83bSHermès Bélusca-Maïto 
3266f19c83bSHermès Bélusca-Maïto     /* Assign drive letters to primary partitions */
3276f19c83bSHermès Bélusca-Maïto     Entry1 = List->DiskListHead.Flink;
3286f19c83bSHermès Bélusca-Maïto     while (Entry1 != &List->DiskListHead)
3296f19c83bSHermès Bélusca-Maïto     {
3306f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
3316f19c83bSHermès Bélusca-Maïto 
3326f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->PrimaryPartListHead.Flink;
3336f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->PrimaryPartListHead)
3346f19c83bSHermès Bélusca-Maïto         {
3356f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3366f19c83bSHermès Bélusca-Maïto 
3376f19c83bSHermès Bélusca-Maïto             PartEntry->DriveLetter = 0;
3386f19c83bSHermès Bélusca-Maïto 
3396f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned &&
3406f19c83bSHermès Bélusca-Maïto                 !IsContainerPartition(PartEntry->PartitionType))
3416f19c83bSHermès Bélusca-Maïto             {
3426f19c83bSHermès Bélusca-Maïto                 if (IsRecognizedPartition(PartEntry->PartitionType) ||
3436f19c83bSHermès Bélusca-Maïto                     (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED &&
3446f19c83bSHermès Bélusca-Maïto                      PartEntry->SectorCount.QuadPart != 0LL))
3456f19c83bSHermès Bélusca-Maïto                 {
346f41750abSHermès Bélusca-Maïto                     if (Letter <= L'Z')
3476f19c83bSHermès Bélusca-Maïto                     {
3486f19c83bSHermès Bélusca-Maïto                         PartEntry->DriveLetter = Letter;
3496f19c83bSHermès Bélusca-Maïto                         Letter++;
3506f19c83bSHermès Bélusca-Maïto                     }
3516f19c83bSHermès Bélusca-Maïto                 }
3526f19c83bSHermès Bélusca-Maïto             }
3536f19c83bSHermès Bélusca-Maïto 
3546f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
3556f19c83bSHermès Bélusca-Maïto         }
3566f19c83bSHermès Bélusca-Maïto 
3576f19c83bSHermès Bélusca-Maïto         Entry1 = Entry1->Flink;
3586f19c83bSHermès Bélusca-Maïto     }
3596f19c83bSHermès Bélusca-Maïto 
3606f19c83bSHermès Bélusca-Maïto     /* Assign drive letters to logical drives */
3616f19c83bSHermès Bélusca-Maïto     Entry1 = List->DiskListHead.Flink;
3626f19c83bSHermès Bélusca-Maïto     while (Entry1 != &List->DiskListHead)
3636f19c83bSHermès Bélusca-Maïto     {
3646f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry);
3656f19c83bSHermès Bélusca-Maïto 
3666f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->LogicalPartListHead.Flink;
3676f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->LogicalPartListHead)
3686f19c83bSHermès Bélusca-Maïto         {
3696f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3706f19c83bSHermès Bélusca-Maïto 
3716f19c83bSHermès Bélusca-Maïto             PartEntry->DriveLetter = 0;
3726f19c83bSHermès Bélusca-Maïto 
3736f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned)
3746f19c83bSHermès Bélusca-Maïto             {
3756f19c83bSHermès Bélusca-Maïto                 if (IsRecognizedPartition(PartEntry->PartitionType) ||
3766f19c83bSHermès Bélusca-Maïto                     (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED &&
3776f19c83bSHermès Bélusca-Maïto                      PartEntry->SectorCount.QuadPart != 0LL))
3786f19c83bSHermès Bélusca-Maïto                 {
379f41750abSHermès Bélusca-Maïto                     if (Letter <= L'Z')
3806f19c83bSHermès Bélusca-Maïto                     {
3816f19c83bSHermès Bélusca-Maïto                         PartEntry->DriveLetter = Letter;
3826f19c83bSHermès Bélusca-Maïto                         Letter++;
3836f19c83bSHermès Bélusca-Maïto                     }
3846f19c83bSHermès Bélusca-Maïto                 }
3856f19c83bSHermès Bélusca-Maïto             }
3866f19c83bSHermès Bélusca-Maïto 
3876f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
3886f19c83bSHermès Bélusca-Maïto         }
3896f19c83bSHermès Bélusca-Maïto 
3906f19c83bSHermès Bélusca-Maïto         Entry1 = Entry1->Flink;
3916f19c83bSHermès Bélusca-Maïto     }
3926f19c83bSHermès Bélusca-Maïto }
3936f19c83bSHermès Bélusca-Maïto 
3946f19c83bSHermès Bélusca-Maïto static NTSTATUS
3956f19c83bSHermès Bélusca-Maïto NTAPI
3966f19c83bSHermès Bélusca-Maïto DiskIdentifierQueryRoutine(
3976f19c83bSHermès Bélusca-Maïto     PWSTR ValueName,
3986f19c83bSHermès Bélusca-Maïto     ULONG ValueType,
3996f19c83bSHermès Bélusca-Maïto     PVOID ValueData,
4006f19c83bSHermès Bélusca-Maïto     ULONG ValueLength,
4016f19c83bSHermès Bélusca-Maïto     PVOID Context,
4026f19c83bSHermès Bélusca-Maïto     PVOID EntryContext)
4036f19c83bSHermès Bélusca-Maïto {
4046f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
4056f19c83bSHermès Bélusca-Maïto     UNICODE_STRING NameU;
4066f19c83bSHermès Bélusca-Maïto 
4076f19c83bSHermès Bélusca-Maïto     if (ValueType == REG_SZ &&
4086f19c83bSHermès Bélusca-Maïto         ValueLength == 20 * sizeof(WCHAR))
4096f19c83bSHermès Bélusca-Maïto     {
4106f19c83bSHermès Bélusca-Maïto         NameU.Buffer = (PWCHAR)ValueData;
4116f19c83bSHermès Bélusca-Maïto         NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
4126f19c83bSHermès Bélusca-Maïto         RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
4136f19c83bSHermès Bélusca-Maïto 
4146f19c83bSHermès Bélusca-Maïto         NameU.Buffer = (PWCHAR)ValueData + 9;
4156f19c83bSHermès Bélusca-Maïto         RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
4166f19c83bSHermès Bélusca-Maïto 
4176f19c83bSHermès Bélusca-Maïto         return STATUS_SUCCESS;
4186f19c83bSHermès Bélusca-Maïto     }
4196f19c83bSHermès Bélusca-Maïto 
4206f19c83bSHermès Bélusca-Maïto     return STATUS_UNSUCCESSFUL;
4216f19c83bSHermès Bélusca-Maïto }
4226f19c83bSHermès Bélusca-Maïto 
4236f19c83bSHermès Bélusca-Maïto static NTSTATUS
4246f19c83bSHermès Bélusca-Maïto NTAPI
4256f19c83bSHermès Bélusca-Maïto DiskConfigurationDataQueryRoutine(
4266f19c83bSHermès Bélusca-Maïto     PWSTR ValueName,
4276f19c83bSHermès Bélusca-Maïto     ULONG ValueType,
4286f19c83bSHermès Bélusca-Maïto     PVOID ValueData,
4296f19c83bSHermès Bélusca-Maïto     ULONG ValueLength,
4306f19c83bSHermès Bélusca-Maïto     PVOID Context,
4316f19c83bSHermès Bélusca-Maïto     PVOID EntryContext)
4326f19c83bSHermès Bélusca-Maïto {
4336f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
4346f19c83bSHermès Bélusca-Maïto     PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
4356f19c83bSHermès Bélusca-Maïto     PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
4366f19c83bSHermès Bélusca-Maïto     ULONG i;
4376f19c83bSHermès Bélusca-Maïto 
4386f19c83bSHermès Bélusca-Maïto     if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
4396f19c83bSHermès Bélusca-Maïto         ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
4406f19c83bSHermès Bélusca-Maïto         return STATUS_UNSUCCESSFUL;
4416f19c83bSHermès Bélusca-Maïto 
4426f19c83bSHermès Bélusca-Maïto     FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
4436f19c83bSHermès Bélusca-Maïto 
4446f19c83bSHermès Bélusca-Maïto     /* Hm. Version and Revision are not set on Microsoft Windows XP... */
4456f19c83bSHermès Bélusca-Maïto #if 0
4466f19c83bSHermès Bélusca-Maïto     if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
4476f19c83bSHermès Bélusca-Maïto         FullResourceDescriptor->PartialResourceList.Revision != 1)
4486f19c83bSHermès Bélusca-Maïto         return STATUS_UNSUCCESSFUL;
4496f19c83bSHermès Bélusca-Maïto #endif
4506f19c83bSHermès Bélusca-Maïto 
4516f19c83bSHermès Bélusca-Maïto     for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
4526f19c83bSHermès Bélusca-Maïto     {
4536f19c83bSHermès Bélusca-Maïto         if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
4546f19c83bSHermès Bélusca-Maïto             FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
4556f19c83bSHermès Bélusca-Maïto             continue;
4566f19c83bSHermès Bélusca-Maïto 
4576f19c83bSHermès Bélusca-Maïto         DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
4586f19c83bSHermès Bélusca-Maïto         BiosDiskEntry->DiskGeometry = *DiskGeometry;
4596f19c83bSHermès Bélusca-Maïto 
4606f19c83bSHermès Bélusca-Maïto         return STATUS_SUCCESS;
4616f19c83bSHermès Bélusca-Maïto     }
4626f19c83bSHermès Bélusca-Maïto 
4636f19c83bSHermès Bélusca-Maïto     return STATUS_UNSUCCESSFUL;
4646f19c83bSHermès Bélusca-Maïto }
4656f19c83bSHermès Bélusca-Maïto 
4666f19c83bSHermès Bélusca-Maïto static NTSTATUS
4676f19c83bSHermès Bélusca-Maïto NTAPI
4686f19c83bSHermès Bélusca-Maïto SystemConfigurationDataQueryRoutine(
4696f19c83bSHermès Bélusca-Maïto     PWSTR ValueName,
4706f19c83bSHermès Bélusca-Maïto     ULONG ValueType,
4716f19c83bSHermès Bélusca-Maïto     PVOID ValueData,
4726f19c83bSHermès Bélusca-Maïto     ULONG ValueLength,
4736f19c83bSHermès Bélusca-Maïto     PVOID Context,
4746f19c83bSHermès Bélusca-Maïto     PVOID EntryContext)
4756f19c83bSHermès Bélusca-Maïto {
4766f19c83bSHermès Bélusca-Maïto     PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
4776f19c83bSHermès Bélusca-Maïto     PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context;
4786f19c83bSHermès Bélusca-Maïto     ULONG i;
4796f19c83bSHermès Bélusca-Maïto 
4806f19c83bSHermès Bélusca-Maïto     if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
4816f19c83bSHermès Bélusca-Maïto         ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
4826f19c83bSHermès Bélusca-Maïto         return STATUS_UNSUCCESSFUL;
4836f19c83bSHermès Bélusca-Maïto 
4846f19c83bSHermès Bélusca-Maïto     FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
4856f19c83bSHermès Bélusca-Maïto 
4866f19c83bSHermès Bélusca-Maïto     /* Hm. Version and Revision are not set on Microsoft Windows XP... */
4876f19c83bSHermès Bélusca-Maïto #if 0
4886f19c83bSHermès Bélusca-Maïto     if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
4896f19c83bSHermès Bélusca-Maïto         FullResourceDescriptor->PartialResourceList.Revision != 1)
4906f19c83bSHermès Bélusca-Maïto         return STATUS_UNSUCCESSFUL;
4916f19c83bSHermès Bélusca-Maïto #endif
4926f19c83bSHermès Bélusca-Maïto 
4936f19c83bSHermès Bélusca-Maïto     for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
4946f19c83bSHermès Bélusca-Maïto     {
4956f19c83bSHermès Bélusca-Maïto         if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific ||
4966f19c83bSHermès Bélusca-Maïto             FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
4976f19c83bSHermès Bélusca-Maïto             continue;
4986f19c83bSHermès Bélusca-Maïto 
4996f19c83bSHermès Bélusca-Maïto         *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(ProcessHeap, 0,
5006f19c83bSHermès Bélusca-Maïto                        FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
5016f19c83bSHermès Bélusca-Maïto         if (*Int13Drives == NULL)
5026f19c83bSHermès Bélusca-Maïto             return STATUS_NO_MEMORY;
5036f19c83bSHermès Bélusca-Maïto 
5046f19c83bSHermès Bélusca-Maïto         memcpy(*Int13Drives,
5056f19c83bSHermès Bélusca-Maïto                &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
5066f19c83bSHermès Bélusca-Maïto                FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
5076f19c83bSHermès Bélusca-Maïto         return STATUS_SUCCESS;
5086f19c83bSHermès Bélusca-Maïto     }
5096f19c83bSHermès Bélusca-Maïto 
5106f19c83bSHermès Bélusca-Maïto     return STATUS_UNSUCCESSFUL;
5116f19c83bSHermès Bélusca-Maïto }
5126f19c83bSHermès Bélusca-Maïto 
5136f19c83bSHermès Bélusca-Maïto 
5146f19c83bSHermès Bélusca-Maïto static VOID
5156f19c83bSHermès Bélusca-Maïto EnumerateBiosDiskEntries(
5166f19c83bSHermès Bélusca-Maïto     IN PPARTLIST PartList)
5176f19c83bSHermès Bélusca-Maïto {
5186f19c83bSHermès Bélusca-Maïto     RTL_QUERY_REGISTRY_TABLE QueryTable[3];
5196f19c83bSHermès Bélusca-Maïto     WCHAR Name[120];
5206f19c83bSHermès Bélusca-Maïto     ULONG AdapterCount;
5216f19c83bSHermès Bélusca-Maïto     ULONG DiskCount;
5226f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
5236f19c83bSHermès Bélusca-Maïto     PCM_INT13_DRIVE_PARAMETER Int13Drives;
5246f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry;
5256f19c83bSHermès Bélusca-Maïto 
526f41750abSHermès Bélusca-Maïto #define ROOT_NAME   L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
527f41750abSHermès Bélusca-Maïto 
5286f19c83bSHermès Bélusca-Maïto     memset(QueryTable, 0, sizeof(QueryTable));
5296f19c83bSHermès Bélusca-Maïto 
5306f19c83bSHermès Bélusca-Maïto     QueryTable[1].Name = L"Configuration Data";
5316f19c83bSHermès Bélusca-Maïto     QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
5326f19c83bSHermès Bélusca-Maïto     Int13Drives = NULL;
5336f19c83bSHermès Bélusca-Maïto     Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5346f19c83bSHermès Bélusca-Maïto                                     L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
5356f19c83bSHermès Bélusca-Maïto                                     &QueryTable[1],
5366f19c83bSHermès Bélusca-Maïto                                     (PVOID)&Int13Drives,
5376f19c83bSHermès Bélusca-Maïto                                     NULL);
5386f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
5396f19c83bSHermès Bélusca-Maïto     {
5406f19c83bSHermès Bélusca-Maïto         DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
5416f19c83bSHermès Bélusca-Maïto         return;
5426f19c83bSHermès Bélusca-Maïto     }
5436f19c83bSHermès Bélusca-Maïto 
5446f19c83bSHermès Bélusca-Maïto     AdapterCount = 0;
5456f19c83bSHermès Bélusca-Maïto     while (TRUE)
5466f19c83bSHermès Bélusca-Maïto     {
5476f19c83bSHermès Bélusca-Maïto         RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
5486f19c83bSHermès Bélusca-Maïto                             L"%s\\%lu",
5496f19c83bSHermès Bélusca-Maïto                             ROOT_NAME, AdapterCount);
5506f19c83bSHermès Bélusca-Maïto         Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5516f19c83bSHermès Bélusca-Maïto                                         Name,
5526f19c83bSHermès Bélusca-Maïto                                         &QueryTable[2],
5536f19c83bSHermès Bélusca-Maïto                                         NULL,
5546f19c83bSHermès Bélusca-Maïto                                         NULL);
5556f19c83bSHermès Bélusca-Maïto         if (!NT_SUCCESS(Status))
5566f19c83bSHermès Bélusca-Maïto         {
5576f19c83bSHermès Bélusca-Maïto             break;
5586f19c83bSHermès Bélusca-Maïto         }
5596f19c83bSHermès Bélusca-Maïto 
5606f19c83bSHermès Bélusca-Maïto         RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
5616f19c83bSHermès Bélusca-Maïto                             L"%s\\%lu\\DiskController",
5626f19c83bSHermès Bélusca-Maïto                             ROOT_NAME, AdapterCount);
5636f19c83bSHermès Bélusca-Maïto         Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5646f19c83bSHermès Bélusca-Maïto                                         Name,
5656f19c83bSHermès Bélusca-Maïto                                         &QueryTable[2],
5666f19c83bSHermès Bélusca-Maïto                                         NULL,
5676f19c83bSHermès Bélusca-Maïto                                         NULL);
5686f19c83bSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
5696f19c83bSHermès Bélusca-Maïto         {
5706f19c83bSHermès Bélusca-Maïto             while (TRUE)
5716f19c83bSHermès Bélusca-Maïto             {
5726f19c83bSHermès Bélusca-Maïto                 RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
5736f19c83bSHermès Bélusca-Maïto                                     L"%s\\%lu\\DiskController\\0",
5746f19c83bSHermès Bélusca-Maïto                                     ROOT_NAME, AdapterCount);
5756f19c83bSHermès Bélusca-Maïto                 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5766f19c83bSHermès Bélusca-Maïto                                                 Name,
5776f19c83bSHermès Bélusca-Maïto                                                 &QueryTable[2],
5786f19c83bSHermès Bélusca-Maïto                                                 NULL,
5796f19c83bSHermès Bélusca-Maïto                                                 NULL);
5806f19c83bSHermès Bélusca-Maïto                 if (!NT_SUCCESS(Status))
5816f19c83bSHermès Bélusca-Maïto                 {
5826f19c83bSHermès Bélusca-Maïto                     RtlFreeHeap(ProcessHeap, 0, Int13Drives);
5836f19c83bSHermès Bélusca-Maïto                     return;
5846f19c83bSHermès Bélusca-Maïto                 }
5856f19c83bSHermès Bélusca-Maïto 
5866f19c83bSHermès Bélusca-Maïto                 RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
5876f19c83bSHermès Bélusca-Maïto                                     L"%s\\%lu\\DiskController\\0\\DiskPeripheral",
5886f19c83bSHermès Bélusca-Maïto                                     ROOT_NAME, AdapterCount);
5896f19c83bSHermès Bélusca-Maïto                 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
5906f19c83bSHermès Bélusca-Maïto                                                 Name,
5916f19c83bSHermès Bélusca-Maïto                                                 &QueryTable[2],
5926f19c83bSHermès Bélusca-Maïto                                                 NULL,
5936f19c83bSHermès Bélusca-Maïto                                                 NULL);
5946f19c83bSHermès Bélusca-Maïto                 if (NT_SUCCESS(Status))
5956f19c83bSHermès Bélusca-Maïto                 {
5966f19c83bSHermès Bélusca-Maïto                     QueryTable[0].Name = L"Identifier";
5976f19c83bSHermès Bélusca-Maïto                     QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
5986f19c83bSHermès Bélusca-Maïto                     QueryTable[1].Name = L"Configuration Data";
5996f19c83bSHermès Bélusca-Maïto                     QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;
6006f19c83bSHermès Bélusca-Maïto 
6016f19c83bSHermès Bélusca-Maïto                     DiskCount = 0;
6026f19c83bSHermès Bélusca-Maïto                     while (TRUE)
6036f19c83bSHermès Bélusca-Maïto                     {
6046f19c83bSHermès Bélusca-Maïto                         BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
6056f19c83bSHermès Bélusca-Maïto                         if (BiosDiskEntry == NULL)
6066f19c83bSHermès Bélusca-Maïto                         {
6076f19c83bSHermès Bélusca-Maïto                             break;
6086f19c83bSHermès Bélusca-Maïto                         }
6096f19c83bSHermès Bélusca-Maïto 
6106f19c83bSHermès Bélusca-Maïto                         RtlStringCchPrintfW(Name, ARRAYSIZE(Name),
6116f19c83bSHermès Bélusca-Maïto                                             L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu",
6126f19c83bSHermès Bélusca-Maïto                                             ROOT_NAME, AdapterCount, DiskCount);
6136f19c83bSHermès Bélusca-Maïto                         Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
6146f19c83bSHermès Bélusca-Maïto                                                         Name,
6156f19c83bSHermès Bélusca-Maïto                                                         QueryTable,
6166f19c83bSHermès Bélusca-Maïto                                                         (PVOID)BiosDiskEntry,
6176f19c83bSHermès Bélusca-Maïto                                                         NULL);
6186f19c83bSHermès Bélusca-Maïto                         if (!NT_SUCCESS(Status))
6196f19c83bSHermès Bélusca-Maïto                         {
6206f19c83bSHermès Bélusca-Maïto                             RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
6216f19c83bSHermès Bélusca-Maïto                             break;
6226f19c83bSHermès Bélusca-Maïto                         }
6236f19c83bSHermès Bélusca-Maïto 
6246f19c83bSHermès Bélusca-Maïto                         BiosDiskEntry->DiskNumber = DiskCount;
6256f19c83bSHermès Bélusca-Maïto                         BiosDiskEntry->Recognized = FALSE;
6266f19c83bSHermès Bélusca-Maïto 
6276f19c83bSHermès Bélusca-Maïto                         if (DiskCount < Int13Drives[0].NumberDrives)
6286f19c83bSHermès Bélusca-Maïto                         {
6296f19c83bSHermès Bélusca-Maïto                             BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
6306f19c83bSHermès Bélusca-Maïto                         }
6316f19c83bSHermès Bélusca-Maïto                         else
6326f19c83bSHermès Bélusca-Maïto                         {
6336f19c83bSHermès Bélusca-Maïto                             DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
6346f19c83bSHermès Bélusca-Maïto                         }
6356f19c83bSHermès Bélusca-Maïto 
6366f19c83bSHermès Bélusca-Maïto                         InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry);
6376f19c83bSHermès Bélusca-Maïto 
6386f19c83bSHermès Bélusca-Maïto                         DPRINT("DiskNumber:        %lu\n", BiosDiskEntry->DiskNumber);
6396f19c83bSHermès Bélusca-Maïto                         DPRINT("Signature:         %08lx\n", BiosDiskEntry->Signature);
6406f19c83bSHermès Bélusca-Maïto                         DPRINT("Checksum:          %08lx\n", BiosDiskEntry->Checksum);
6416f19c83bSHermès Bélusca-Maïto                         DPRINT("BytesPerSector:    %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
6426f19c83bSHermès Bélusca-Maïto                         DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
6436f19c83bSHermès Bélusca-Maïto                         DPRINT("NumberOfHeads:     %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
6446f19c83bSHermès Bélusca-Maïto                         DPRINT("DriveSelect:       %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
6456f19c83bSHermès Bélusca-Maïto                         DPRINT("MaxCylinders:      %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
6466f19c83bSHermès Bélusca-Maïto                         DPRINT("SectorsPerTrack:   %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
6476f19c83bSHermès Bélusca-Maïto                         DPRINT("MaxHeads:          %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
6486f19c83bSHermès Bélusca-Maïto                         DPRINT("NumberDrives:      %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
6496f19c83bSHermès Bélusca-Maïto 
6506f19c83bSHermès Bélusca-Maïto                         DiskCount++;
6516f19c83bSHermès Bélusca-Maïto                     }
6526f19c83bSHermès Bélusca-Maïto                 }
6536f19c83bSHermès Bélusca-Maïto 
6546f19c83bSHermès Bélusca-Maïto                 RtlFreeHeap(ProcessHeap, 0, Int13Drives);
6556f19c83bSHermès Bélusca-Maïto                 return;
6566f19c83bSHermès Bélusca-Maïto             }
6576f19c83bSHermès Bélusca-Maïto         }
6586f19c83bSHermès Bélusca-Maïto 
6596f19c83bSHermès Bélusca-Maïto         AdapterCount++;
6606f19c83bSHermès Bélusca-Maïto     }
6616f19c83bSHermès Bélusca-Maïto 
6626f19c83bSHermès Bélusca-Maïto     RtlFreeHeap(ProcessHeap, 0, Int13Drives);
663f41750abSHermès Bélusca-Maïto 
664f41750abSHermès Bélusca-Maïto #undef ROOT_NAME
6656f19c83bSHermès Bélusca-Maïto }
6666f19c83bSHermès Bélusca-Maïto 
667*7df92966SHermès Bélusca-Maïto 
668*7df92966SHermès Bélusca-Maïto 
669*7df92966SHermès Bélusca-Maïto /*
670*7df92966SHermès Bélusca-Maïto  * Inserts the disk region represented by PartEntry into either the primary
671*7df92966SHermès Bélusca-Maïto  * or the logical partition list of the given disk.
672*7df92966SHermès Bélusca-Maïto  * The lists are kept sorted by increasing order of start sectors.
673*7df92966SHermès Bélusca-Maïto  * Of course no disk region should overlap at all with one another.
674*7df92966SHermès Bélusca-Maïto  */
675*7df92966SHermès Bélusca-Maïto static
676*7df92966SHermès Bélusca-Maïto VOID
677*7df92966SHermès Bélusca-Maïto InsertDiskRegion(
678*7df92966SHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
679*7df92966SHermès Bélusca-Maïto     IN PPARTENTRY PartEntry,
680*7df92966SHermès Bélusca-Maïto     IN BOOLEAN LogicalPartition)
681*7df92966SHermès Bélusca-Maïto {
682*7df92966SHermès Bélusca-Maïto     PLIST_ENTRY List;
683*7df92966SHermès Bélusca-Maïto     PLIST_ENTRY Entry;
684*7df92966SHermès Bélusca-Maïto     PPARTENTRY PartEntry2;
685*7df92966SHermès Bélusca-Maïto 
686*7df92966SHermès Bélusca-Maïto     /* Use the correct partition list */
687*7df92966SHermès Bélusca-Maïto     if (LogicalPartition)
688*7df92966SHermès Bélusca-Maïto         List = &DiskEntry->LogicalPartListHead;
689*7df92966SHermès Bélusca-Maïto     else
690*7df92966SHermès Bélusca-Maïto         List = &DiskEntry->PrimaryPartListHead;
691*7df92966SHermès Bélusca-Maïto 
692*7df92966SHermès Bélusca-Maïto     /* Find the first disk region before which we need to insert the new one */
693*7df92966SHermès Bélusca-Maïto     for (Entry = List->Flink; Entry != List; Entry = Entry->Flink)
694*7df92966SHermès Bélusca-Maïto     {
695*7df92966SHermès Bélusca-Maïto         PartEntry2 = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
696*7df92966SHermès Bélusca-Maïto 
697*7df92966SHermès Bélusca-Maïto         /* Ignore any unused empty region */
698*7df92966SHermès Bélusca-Maïto         if ((PartEntry2->PartitionType == PARTITION_ENTRY_UNUSED &&
699*7df92966SHermès Bélusca-Maïto              PartEntry2->StartSector.QuadPart == 0) || PartEntry2->SectorCount.QuadPart == 0)
700*7df92966SHermès Bélusca-Maïto         {
701*7df92966SHermès Bélusca-Maïto             continue;
702*7df92966SHermès Bélusca-Maïto         }
703*7df92966SHermès Bélusca-Maïto 
704*7df92966SHermès Bélusca-Maïto         /* If the current region ends before the one to be inserted, try again */
705*7df92966SHermès Bélusca-Maïto         if (PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1 < PartEntry->StartSector.QuadPart)
706*7df92966SHermès Bélusca-Maïto             continue;
707*7df92966SHermès Bélusca-Maïto 
708*7df92966SHermès Bélusca-Maïto         /*
709*7df92966SHermès Bélusca-Maïto          * One of the disk region boundaries crosses the desired region
710*7df92966SHermès Bélusca-Maïto          * (it starts after the desired region, or ends before the end
711*7df92966SHermès Bélusca-Maïto          * of the desired region): this is an impossible situation because
712*7df92966SHermès Bélusca-Maïto          * disk regions (partitions) cannot overlap!
713*7df92966SHermès Bélusca-Maïto          * Throw an error and bail out.
714*7df92966SHermès Bélusca-Maïto          */
715*7df92966SHermès Bélusca-Maïto         if (max(PartEntry->StartSector.QuadPart, PartEntry2->StartSector.QuadPart)
716*7df92966SHermès Bélusca-Maïto             <=
717*7df92966SHermès Bélusca-Maïto             min( PartEntry->StartSector.QuadPart +  PartEntry->SectorCount.QuadPart - 1,
718*7df92966SHermès Bélusca-Maïto                 PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1))
719*7df92966SHermès Bélusca-Maïto         {
720*7df92966SHermès Bélusca-Maïto             DPRINT1("Disk region overlap problem, stopping there!\n"
721*7df92966SHermès Bélusca-Maïto                     "Partition to be inserted:\n"
722*7df92966SHermès Bélusca-Maïto                     "    StartSector = %I64u ; EndSector = %I64u\n"
723*7df92966SHermès Bélusca-Maïto                     "Existing disk region:\n"
724*7df92966SHermès Bélusca-Maïto                     "    StartSector = %I64u ; EndSector = %I64u\n",
725*7df92966SHermès Bélusca-Maïto                      PartEntry->StartSector.QuadPart,
726*7df92966SHermès Bélusca-Maïto                      PartEntry->StartSector.QuadPart +  PartEntry->SectorCount.QuadPart - 1,
727*7df92966SHermès Bélusca-Maïto                     PartEntry2->StartSector.QuadPart,
728*7df92966SHermès Bélusca-Maïto                     PartEntry2->StartSector.QuadPart + PartEntry2->SectorCount.QuadPart - 1);
729*7df92966SHermès Bélusca-Maïto             return;
730*7df92966SHermès Bélusca-Maïto         }
731*7df92966SHermès Bélusca-Maïto 
732*7df92966SHermès Bélusca-Maïto         /* We have found the first region before which the new one has to be inserted */
733*7df92966SHermès Bélusca-Maïto         break;
734*7df92966SHermès Bélusca-Maïto     }
735*7df92966SHermès Bélusca-Maïto 
736*7df92966SHermès Bélusca-Maïto     /* Insert the disk region */
737*7df92966SHermès Bélusca-Maïto     InsertTailList(Entry, &PartEntry->ListEntry);
738*7df92966SHermès Bélusca-Maïto }
739*7df92966SHermès Bélusca-Maïto 
740*7df92966SHermès Bélusca-Maïto static
741*7df92966SHermès Bélusca-Maïto PPARTENTRY
742*7df92966SHermès Bélusca-Maïto CreateInsertBlankRegion(
743*7df92966SHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
744*7df92966SHermès Bélusca-Maïto     IN OUT PLIST_ENTRY ListHead,
745*7df92966SHermès Bélusca-Maïto     IN ULONGLONG StartSector,
746*7df92966SHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
747*7df92966SHermès Bélusca-Maïto     IN BOOLEAN LogicalSpace)
748*7df92966SHermès Bélusca-Maïto {
749*7df92966SHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
750*7df92966SHermès Bélusca-Maïto 
751*7df92966SHermès Bélusca-Maïto     NewPartEntry = RtlAllocateHeap(ProcessHeap,
752*7df92966SHermès Bélusca-Maïto                                    HEAP_ZERO_MEMORY,
753*7df92966SHermès Bélusca-Maïto                                    sizeof(PARTENTRY));
754*7df92966SHermès Bélusca-Maïto     if (NewPartEntry == NULL)
755*7df92966SHermès Bélusca-Maïto         return NULL;
756*7df92966SHermès Bélusca-Maïto 
757*7df92966SHermès Bélusca-Maïto     NewPartEntry->DiskEntry = DiskEntry;
758*7df92966SHermès Bélusca-Maïto 
759*7df92966SHermès Bélusca-Maïto     NewPartEntry->IsPartitioned = FALSE;
760*7df92966SHermès Bélusca-Maïto     NewPartEntry->FormatState = Unformatted;
761*7df92966SHermès Bélusca-Maïto     NewPartEntry->FileSystem  = NULL;
762*7df92966SHermès Bélusca-Maïto 
763*7df92966SHermès Bélusca-Maïto     NewPartEntry->StartSector.QuadPart = StartSector;
764*7df92966SHermès Bélusca-Maïto     NewPartEntry->SectorCount.QuadPart = SectorCount;
765*7df92966SHermès Bélusca-Maïto 
766*7df92966SHermès Bélusca-Maïto     DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
767*7df92966SHermès Bélusca-Maïto     DPRINT1("Last Sector  : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
768*7df92966SHermès Bélusca-Maïto     DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
769*7df92966SHermès Bélusca-Maïto 
770*7df92966SHermès Bélusca-Maïto     /* Insert the table into the list */
771*7df92966SHermès Bélusca-Maïto     InsertTailList(ListHead, &NewPartEntry->ListEntry);
772*7df92966SHermès Bélusca-Maïto 
773*7df92966SHermès Bélusca-Maïto     return NewPartEntry;
774*7df92966SHermès Bélusca-Maïto }
775*7df92966SHermès Bélusca-Maïto 
776*7df92966SHermès Bélusca-Maïto static
777*7df92966SHermès Bélusca-Maïto // BOOLEAN
778*7df92966SHermès Bélusca-Maïto PPARTENTRY
779*7df92966SHermès Bélusca-Maïto InitializePartitionEntry(
780*7df92966SHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
781*7df92966SHermès Bélusca-Maïto     IN PPARTENTRY PartEntry,
782*7df92966SHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
783*7df92966SHermès Bélusca-Maïto     IN BOOLEAN AutoCreate)
784*7df92966SHermès Bélusca-Maïto {
785*7df92966SHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
786*7df92966SHermès Bélusca-Maïto 
787*7df92966SHermès Bélusca-Maïto     DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
788*7df92966SHermès Bélusca-Maïto 
789*7df92966SHermès Bélusca-Maïto     if ((AutoCreate != FALSE) ||
790*7df92966SHermès Bélusca-Maïto         (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
791*7df92966SHermès Bélusca-Maïto                    PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
792*7df92966SHermès Bélusca-Maïto     {
793*7df92966SHermès Bélusca-Maïto         DPRINT1("Convert existing partition entry\n");
794*7df92966SHermès Bélusca-Maïto 
795*7df92966SHermès Bélusca-Maïto         /* Convert current entry to 'new (unformatted)' */
796*7df92966SHermès Bélusca-Maïto         PartEntry->IsPartitioned = TRUE;
797*7df92966SHermès Bélusca-Maïto         PartEntry->New = TRUE;
798*7df92966SHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
799*7df92966SHermès Bélusca-Maïto         PartEntry->FormatState = Unformatted;
800*7df92966SHermès Bélusca-Maïto         PartEntry->FileSystem  = NULL;
801*7df92966SHermès Bélusca-Maïto         PartEntry->AutoCreate = AutoCreate;
802*7df92966SHermès Bélusca-Maïto         PartEntry->BootIndicator = FALSE;
803*7df92966SHermès Bélusca-Maïto         PartEntry->LogicalPartition = FALSE;
804*7df92966SHermès Bélusca-Maïto 
805*7df92966SHermès Bélusca-Maïto         NewPartEntry = PartEntry;
806*7df92966SHermès Bélusca-Maïto     }
807*7df92966SHermès Bélusca-Maïto     else
808*7df92966SHermès Bélusca-Maïto     {
809*7df92966SHermès Bélusca-Maïto         DPRINT1("Add new partition entry\n");
810*7df92966SHermès Bélusca-Maïto 
811*7df92966SHermès Bélusca-Maïto         /* Insert and initialize a new partition entry */
812*7df92966SHermès Bélusca-Maïto         NewPartEntry = RtlAllocateHeap(ProcessHeap,
813*7df92966SHermès Bélusca-Maïto                                        HEAP_ZERO_MEMORY,
814*7df92966SHermès Bélusca-Maïto                                        sizeof(PARTENTRY));
815*7df92966SHermès Bélusca-Maïto         if (NewPartEntry == NULL)
816*7df92966SHermès Bélusca-Maïto             return NULL;
817*7df92966SHermès Bélusca-Maïto 
818*7df92966SHermès Bélusca-Maïto         /* Insert the new entry into the list */
819*7df92966SHermès Bélusca-Maïto         InsertTailList(&PartEntry->ListEntry,
820*7df92966SHermès Bélusca-Maïto                        &NewPartEntry->ListEntry);
821*7df92966SHermès Bélusca-Maïto 
822*7df92966SHermès Bélusca-Maïto         NewPartEntry->DiskEntry = DiskEntry;
823*7df92966SHermès Bélusca-Maïto 
824*7df92966SHermès Bélusca-Maïto         NewPartEntry->IsPartitioned = TRUE;
825*7df92966SHermès Bélusca-Maïto         NewPartEntry->New = TRUE;
826*7df92966SHermès Bélusca-Maïto         NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
827*7df92966SHermès Bélusca-Maïto         NewPartEntry->FormatState = Unformatted;
828*7df92966SHermès Bélusca-Maïto         NewPartEntry->FileSystem  = NULL;
829*7df92966SHermès Bélusca-Maïto         NewPartEntry->BootIndicator = FALSE;
830*7df92966SHermès Bélusca-Maïto         NewPartEntry->LogicalPartition = FALSE;
831*7df92966SHermès Bélusca-Maïto 
832*7df92966SHermès Bélusca-Maïto         NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
833*7df92966SHermès Bélusca-Maïto         NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
834*7df92966SHermès Bélusca-Maïto                                              NewPartEntry->StartSector.QuadPart;
835*7df92966SHermès Bélusca-Maïto 
836*7df92966SHermès Bélusca-Maïto         PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
837*7df92966SHermès Bélusca-Maïto         PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
838*7df92966SHermès Bélusca-Maïto     }
839*7df92966SHermès Bélusca-Maïto 
840*7df92966SHermès Bélusca-Maïto     DPRINT1("First Sector : %I64u\n", NewPartEntry->StartSector.QuadPart);
841*7df92966SHermès Bélusca-Maïto     DPRINT1("Last Sector  : %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
842*7df92966SHermès Bélusca-Maïto     DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
843*7df92966SHermès Bélusca-Maïto 
844*7df92966SHermès Bélusca-Maïto     return NewPartEntry;
845*7df92966SHermès Bélusca-Maïto }
846*7df92966SHermès Bélusca-Maïto 
847*7df92966SHermès Bélusca-Maïto 
8486f19c83bSHermès Bélusca-Maïto static
8496f19c83bSHermès Bélusca-Maïto VOID
8506f19c83bSHermès Bélusca-Maïto AddPartitionToDisk(
8516f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
8526f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
8536f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionIndex,
8546f19c83bSHermès Bélusca-Maïto     IN BOOLEAN LogicalPartition)
8556f19c83bSHermès Bélusca-Maïto {
856f41750abSHermès Bélusca-Maïto     NTSTATUS Status;
8576f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
8586f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
859f41750abSHermès Bélusca-Maïto     HANDLE FileHandle;
860f41750abSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
861f41750abSHermès Bélusca-Maïto     IO_STATUS_BLOCK IoStatusBlock;
862f41750abSHermès Bélusca-Maïto     WCHAR Buffer[MAX_PATH];
863f41750abSHermès Bélusca-Maïto     UNICODE_STRING Name;
864f41750abSHermès Bélusca-Maïto     UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
865f41750abSHermès Bélusca-Maïto     PFILE_FS_VOLUME_INFORMATION LabelInfo = (PFILE_FS_VOLUME_INFORMATION)LabelBuffer;
8666f19c83bSHermès Bélusca-Maïto 
8676f19c83bSHermès Bélusca-Maïto     PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
8686f19c83bSHermès Bélusca-Maïto 
8696f19c83bSHermès Bélusca-Maïto     if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED ||
8706f19c83bSHermès Bélusca-Maïto         ((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType)))
8716f19c83bSHermès Bélusca-Maïto     {
8726f19c83bSHermès Bélusca-Maïto         return;
8736f19c83bSHermès Bélusca-Maïto     }
8746f19c83bSHermès Bélusca-Maïto 
8756f19c83bSHermès Bélusca-Maïto     PartEntry = RtlAllocateHeap(ProcessHeap,
8766f19c83bSHermès Bélusca-Maïto                                 HEAP_ZERO_MEMORY,
8776f19c83bSHermès Bélusca-Maïto                                 sizeof(PARTENTRY));
8786f19c83bSHermès Bélusca-Maïto     if (PartEntry == NULL)
8796f19c83bSHermès Bélusca-Maïto         return;
8806f19c83bSHermès Bélusca-Maïto 
8816f19c83bSHermès Bélusca-Maïto     PartEntry->DiskEntry = DiskEntry;
8826f19c83bSHermès Bélusca-Maïto 
8836f19c83bSHermès Bélusca-Maïto     PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
8846f19c83bSHermès Bélusca-Maïto     PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
8856f19c83bSHermès Bélusca-Maïto 
8866f19c83bSHermès Bélusca-Maïto     PartEntry->BootIndicator = PartitionInfo->BootIndicator;
8876f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionType = PartitionInfo->PartitionType;
8886f19c83bSHermès Bélusca-Maïto     PartEntry->HiddenSectors = PartitionInfo->HiddenSectors;
8896f19c83bSHermès Bélusca-Maïto 
8906f19c83bSHermès Bélusca-Maïto     PartEntry->LogicalPartition = LogicalPartition;
8916f19c83bSHermès Bélusca-Maïto     PartEntry->IsPartitioned = TRUE;
892*7df92966SHermès Bélusca-Maïto     PartEntry->OnDiskPartitionNumber = PartitionInfo->PartitionNumber;
8936f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
8946f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionIndex = PartitionIndex;
8956f19c83bSHermès Bélusca-Maïto 
8966f19c83bSHermès Bélusca-Maïto     if (IsContainerPartition(PartEntry->PartitionType))
8976f19c83bSHermès Bélusca-Maïto     {
8986f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = Unformatted;
8996f19c83bSHermès Bélusca-Maïto         PartEntry->FileSystem  = NULL;
9006f19c83bSHermès Bélusca-Maïto 
9016f19c83bSHermès Bélusca-Maïto         if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
9026f19c83bSHermès Bélusca-Maïto             DiskEntry->ExtendedPartition = PartEntry;
9036f19c83bSHermès Bélusca-Maïto     }
9046f19c83bSHermès Bélusca-Maïto     else if (IsRecognizedPartition(PartEntry->PartitionType))
9056f19c83bSHermès Bélusca-Maïto     {
906*7df92966SHermès Bélusca-Maïto         ASSERT(PartitionInfo->RecognizedPartition);
907*7df92966SHermès Bélusca-Maïto 
9086f19c83bSHermès Bélusca-Maïto         PartEntry->FileSystem = GetFileSystem(PartEntry);
9096f19c83bSHermès Bélusca-Maïto         if (PartEntry->FileSystem)
9106f19c83bSHermès Bélusca-Maïto             PartEntry->FormatState = Preformatted;
9116f19c83bSHermès Bélusca-Maïto         else
9126f19c83bSHermès Bélusca-Maïto             PartEntry->FormatState = Unformatted;
9136f19c83bSHermès Bélusca-Maïto         // PartEntry->FormatState = UnknownFormat;
9146f19c83bSHermès Bélusca-Maïto     }
9156f19c83bSHermès Bélusca-Maïto     else
9166f19c83bSHermès Bélusca-Maïto     {
9176f19c83bSHermès Bélusca-Maïto         /* Unknown partition, hence unknown partition format (may or may not be actually formatted) */
9186f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = UnknownFormat;
9196f19c83bSHermès Bélusca-Maïto     }
9206f19c83bSHermès Bélusca-Maïto 
921f41750abSHermès Bélusca-Maïto     /* Initialize the partition volume label */
922f41750abSHermès Bélusca-Maïto     RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
923f41750abSHermès Bélusca-Maïto 
924f41750abSHermès Bélusca-Maïto     /* Open the volume, ignore any errors */
925f41750abSHermès Bélusca-Maïto     RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
926f41750abSHermès Bélusca-Maïto                         L"\\Device\\Harddisk%lu\\Partition%lu",
927*7df92966SHermès Bélusca-Maïto                         DiskEntry->DiskNumber,
928*7df92966SHermès Bélusca-Maïto                         PartEntry->PartitionNumber);
929f41750abSHermès Bélusca-Maïto     RtlInitUnicodeString(&Name, Buffer);
930f41750abSHermès Bélusca-Maïto 
931f41750abSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
932f41750abSHermès Bélusca-Maïto                                &Name,
933f41750abSHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
934f41750abSHermès Bélusca-Maïto                                NULL,
935f41750abSHermès Bélusca-Maïto                                NULL);
936f41750abSHermès Bélusca-Maïto 
937f41750abSHermès Bélusca-Maïto     Status = NtOpenFile(&FileHandle,
938f41750abSHermès Bélusca-Maïto                         FILE_READ_DATA | SYNCHRONIZE,
939f41750abSHermès Bélusca-Maïto                         &ObjectAttributes,
940f41750abSHermès Bélusca-Maïto                         &IoStatusBlock,
941f41750abSHermès Bélusca-Maïto                         FILE_SHARE_READ | FILE_SHARE_WRITE,
942f41750abSHermès Bélusca-Maïto                         FILE_SYNCHRONOUS_IO_NONALERT);
943f41750abSHermès Bélusca-Maïto     if (NT_SUCCESS(Status))
944f41750abSHermès Bélusca-Maïto     {
945f41750abSHermès Bélusca-Maïto         /* Retrieve the partition volume label */
946f41750abSHermès Bélusca-Maïto         Status = NtQueryVolumeInformationFile(FileHandle,
947f41750abSHermès Bélusca-Maïto                                               &IoStatusBlock,
948f41750abSHermès Bélusca-Maïto                                               &LabelBuffer,
949f41750abSHermès Bélusca-Maïto                                               sizeof(LabelBuffer),
950f41750abSHermès Bélusca-Maïto                                               FileFsVolumeInformation);
951f41750abSHermès Bélusca-Maïto         /* Close the handle */
952f41750abSHermès Bélusca-Maïto         NtClose(FileHandle);
953f41750abSHermès Bélusca-Maïto 
954f41750abSHermès Bélusca-Maïto         /* Check for success */
955f41750abSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
956f41750abSHermès Bélusca-Maïto         {
957f41750abSHermès Bélusca-Maïto             /* Copy the (possibly truncated) volume label and NULL-terminate it */
958f41750abSHermès Bélusca-Maïto             RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
959f41750abSHermès Bélusca-Maïto                               LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
960f41750abSHermès Bélusca-Maïto         }
961f41750abSHermès Bélusca-Maïto         else
962f41750abSHermès Bélusca-Maïto         {
963f41750abSHermès Bélusca-Maïto             DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
964f41750abSHermès Bélusca-Maïto         }
965f41750abSHermès Bélusca-Maïto     }
966f41750abSHermès Bélusca-Maïto     else
967f41750abSHermès Bélusca-Maïto     {
968f41750abSHermès Bélusca-Maïto         DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
969f41750abSHermès Bélusca-Maïto     }
970f41750abSHermès Bélusca-Maïto 
971*7df92966SHermès Bélusca-Maïto     InsertDiskRegion(DiskEntry, PartEntry, LogicalPartition);
9726f19c83bSHermès Bélusca-Maïto }
9736f19c83bSHermès Bélusca-Maïto 
9746f19c83bSHermès Bélusca-Maïto static
9756f19c83bSHermès Bélusca-Maïto VOID
9766f19c83bSHermès Bélusca-Maïto ScanForUnpartitionedDiskSpace(
9776f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
9786f19c83bSHermès Bélusca-Maïto {
979*7df92966SHermès Bélusca-Maïto     ULONGLONG StartSector;
980*7df92966SHermès Bélusca-Maïto     ULONGLONG SectorCount;
9816f19c83bSHermès Bélusca-Maïto     ULONGLONG LastStartSector;
9826f19c83bSHermès Bélusca-Maïto     ULONGLONG LastSectorCount;
9836f19c83bSHermès Bélusca-Maïto     ULONGLONG LastUnusedSectorCount;
9846f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
9856f19c83bSHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
9866f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
9876f19c83bSHermès Bélusca-Maïto 
9886f19c83bSHermès Bélusca-Maïto     DPRINT("ScanForUnpartitionedDiskSpace()\n");
9896f19c83bSHermès Bélusca-Maïto 
9906f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
9916f19c83bSHermès Bélusca-Maïto     {
9926f19c83bSHermès Bélusca-Maïto         DPRINT1("No primary partition!\n");
9936f19c83bSHermès Bélusca-Maïto 
9946f19c83bSHermès Bélusca-Maïto         /* Create a partition entry that represents the empty disk */
9956f19c83bSHermès Bélusca-Maïto 
99626408b02SPierre Schweitzer         if (DiskEntry->SectorAlignment < 2048)
997*7df92966SHermès Bélusca-Maïto             StartSector = 2048ULL;
99826408b02SPierre Schweitzer         else
999*7df92966SHermès Bélusca-Maïto             StartSector = (ULONGLONG)DiskEntry->SectorAlignment;
1000*7df92966SHermès Bélusca-Maïto         SectorCount = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - StartSector;
10016f19c83bSHermès Bélusca-Maïto 
1002*7df92966SHermès Bélusca-Maïto         NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1003*7df92966SHermès Bélusca-Maïto                                                &DiskEntry->PrimaryPartListHead,
1004*7df92966SHermès Bélusca-Maïto                                                StartSector,
1005*7df92966SHermès Bélusca-Maïto                                                SectorCount,
1006*7df92966SHermès Bélusca-Maïto                                                FALSE);
1007*7df92966SHermès Bélusca-Maïto         if (NewPartEntry == NULL)
1008*7df92966SHermès Bélusca-Maïto             DPRINT1("Failed to create a new empty region for full disk space!\n");
10096f19c83bSHermès Bélusca-Maïto 
10106f19c83bSHermès Bélusca-Maïto         return;
10116f19c83bSHermès Bélusca-Maïto     }
10126f19c83bSHermès Bélusca-Maïto 
10136f19c83bSHermès Bélusca-Maïto     /* Start partition at head 1, cylinder 0 */
101426408b02SPierre Schweitzer     if (DiskEntry->SectorAlignment < 2048)
101526408b02SPierre Schweitzer         LastStartSector = 2048ULL;
101626408b02SPierre Schweitzer     else
1017*7df92966SHermès Bélusca-Maïto         LastStartSector = (ULONGLONG)DiskEntry->SectorAlignment;
10186f19c83bSHermès Bélusca-Maïto     LastSectorCount = 0ULL;
10196f19c83bSHermès Bélusca-Maïto     LastUnusedSectorCount = 0ULL;
10206f19c83bSHermès Bélusca-Maïto 
10216f19c83bSHermès Bélusca-Maïto     Entry = DiskEntry->PrimaryPartListHead.Flink;
10226f19c83bSHermès Bélusca-Maïto     while (Entry != &DiskEntry->PrimaryPartListHead)
10236f19c83bSHermès Bélusca-Maïto     {
10246f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
10256f19c83bSHermès Bélusca-Maïto 
10266f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
10276f19c83bSHermès Bélusca-Maïto             PartEntry->SectorCount.QuadPart != 0ULL)
10286f19c83bSHermès Bélusca-Maïto         {
10296f19c83bSHermès Bélusca-Maïto             LastUnusedSectorCount =
10306f19c83bSHermès Bélusca-Maïto                 PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
10316f19c83bSHermès Bélusca-Maïto 
10326f19c83bSHermès Bélusca-Maïto             if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
10336f19c83bSHermès Bélusca-Maïto                 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
10346f19c83bSHermès Bélusca-Maïto             {
10356f19c83bSHermès Bélusca-Maïto                 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
10366f19c83bSHermès Bélusca-Maïto 
1037*7df92966SHermès Bélusca-Maïto                 StartSector = LastStartSector + LastSectorCount;
1038*7df92966SHermès Bélusca-Maïto                 SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
10396f19c83bSHermès Bélusca-Maïto 
10406f19c83bSHermès Bélusca-Maïto                 /* Insert the table into the list */
1041*7df92966SHermès Bélusca-Maïto                 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1042*7df92966SHermès Bélusca-Maïto                                                        &PartEntry->ListEntry,
1043*7df92966SHermès Bélusca-Maïto                                                        StartSector,
1044*7df92966SHermès Bélusca-Maïto                                                        SectorCount,
1045*7df92966SHermès Bélusca-Maïto                                                        FALSE);
1046*7df92966SHermès Bélusca-Maïto                 if (NewPartEntry == NULL)
1047*7df92966SHermès Bélusca-Maïto                 {
1048*7df92966SHermès Bélusca-Maïto                     DPRINT1("Failed to create a new empty region for disk space!\n");
1049*7df92966SHermès Bélusca-Maïto                     return;
1050*7df92966SHermès Bélusca-Maïto                 }
10516f19c83bSHermès Bélusca-Maïto             }
10526f19c83bSHermès Bélusca-Maïto 
10536f19c83bSHermès Bélusca-Maïto             LastStartSector = PartEntry->StartSector.QuadPart;
10546f19c83bSHermès Bélusca-Maïto             LastSectorCount = PartEntry->SectorCount.QuadPart;
10556f19c83bSHermès Bélusca-Maïto         }
10566f19c83bSHermès Bélusca-Maïto 
10576f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
10586f19c83bSHermès Bélusca-Maïto     }
10596f19c83bSHermès Bélusca-Maïto 
10606f19c83bSHermès Bélusca-Maïto     /* Check for trailing unpartitioned disk space */
10616f19c83bSHermès Bélusca-Maïto     if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
10626f19c83bSHermès Bélusca-Maïto     {
10636f19c83bSHermès Bélusca-Maïto         LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
10646f19c83bSHermès Bélusca-Maïto 
10656f19c83bSHermès Bélusca-Maïto         if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
10666f19c83bSHermès Bélusca-Maïto         {
10676f19c83bSHermès Bélusca-Maïto             DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
10686f19c83bSHermès Bélusca-Maïto 
1069*7df92966SHermès Bélusca-Maïto             StartSector = LastStartSector + LastSectorCount;
1070*7df92966SHermès Bélusca-Maïto             SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
10716f19c83bSHermès Bélusca-Maïto 
10726f19c83bSHermès Bélusca-Maïto             /* Append the table to the list */
1073*7df92966SHermès Bélusca-Maïto             NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1074*7df92966SHermès Bélusca-Maïto                                                    &DiskEntry->PrimaryPartListHead,
1075*7df92966SHermès Bélusca-Maïto                                                    StartSector,
1076*7df92966SHermès Bélusca-Maïto                                                    SectorCount,
1077*7df92966SHermès Bélusca-Maïto                                                    FALSE);
1078*7df92966SHermès Bélusca-Maïto             if (NewPartEntry == NULL)
1079*7df92966SHermès Bélusca-Maïto             {
1080*7df92966SHermès Bélusca-Maïto                 DPRINT1("Failed to create a new empty region for trailing disk space!\n");
1081*7df92966SHermès Bélusca-Maïto                 return;
1082*7df92966SHermès Bélusca-Maïto             }
10836f19c83bSHermès Bélusca-Maïto         }
10846f19c83bSHermès Bélusca-Maïto     }
10856f19c83bSHermès Bélusca-Maïto 
10866f19c83bSHermès Bélusca-Maïto     if (DiskEntry->ExtendedPartition != NULL)
10876f19c83bSHermès Bélusca-Maïto     {
10886f19c83bSHermès Bélusca-Maïto         if (IsListEmpty(&DiskEntry->LogicalPartListHead))
10896f19c83bSHermès Bélusca-Maïto         {
10906f19c83bSHermès Bélusca-Maïto             DPRINT1("No logical partition!\n");
10916f19c83bSHermès Bélusca-Maïto 
10926f19c83bSHermès Bélusca-Maïto             /* Create a partition entry that represents the empty extended partition */
1093*7df92966SHermès Bélusca-Maïto 
1094*7df92966SHermès Bélusca-Maïto             StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
1095*7df92966SHermès Bélusca-Maïto             SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
1096*7df92966SHermès Bélusca-Maïto 
1097*7df92966SHermès Bélusca-Maïto             NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1098*7df92966SHermès Bélusca-Maïto                                                    &DiskEntry->LogicalPartListHead,
1099*7df92966SHermès Bélusca-Maïto                                                    StartSector,
1100*7df92966SHermès Bélusca-Maïto                                                    SectorCount,
1101*7df92966SHermès Bélusca-Maïto                                                    TRUE);
11026f19c83bSHermès Bélusca-Maïto             if (NewPartEntry == NULL)
1103*7df92966SHermès Bélusca-Maïto             {
1104*7df92966SHermès Bélusca-Maïto                 DPRINT1("Failed to create a new empty region for full extended partition space!\n");
11056f19c83bSHermès Bélusca-Maïto                 return;
1106*7df92966SHermès Bélusca-Maïto             }
11076f19c83bSHermès Bélusca-Maïto             NewPartEntry->LogicalPartition = TRUE;
11086f19c83bSHermès Bélusca-Maïto 
11096f19c83bSHermès Bélusca-Maïto             return;
11106f19c83bSHermès Bélusca-Maïto         }
11116f19c83bSHermès Bélusca-Maïto 
11126f19c83bSHermès Bélusca-Maïto         /* Start partition at head 1, cylinder 0 */
11136f19c83bSHermès Bélusca-Maïto         LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
11146f19c83bSHermès Bélusca-Maïto         LastSectorCount = 0ULL;
11156f19c83bSHermès Bélusca-Maïto         LastUnusedSectorCount = 0ULL;
11166f19c83bSHermès Bélusca-Maïto 
11176f19c83bSHermès Bélusca-Maïto         Entry = DiskEntry->LogicalPartListHead.Flink;
11186f19c83bSHermès Bélusca-Maïto         while (Entry != &DiskEntry->LogicalPartListHead)
11196f19c83bSHermès Bélusca-Maïto         {
11206f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
11216f19c83bSHermès Bélusca-Maïto 
11226f19c83bSHermès Bélusca-Maïto             if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
11236f19c83bSHermès Bélusca-Maïto                 PartEntry->SectorCount.QuadPart != 0ULL)
11246f19c83bSHermès Bélusca-Maïto             {
11256f19c83bSHermès Bélusca-Maïto                 LastUnusedSectorCount =
11266f19c83bSHermès Bélusca-Maïto                     PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
11276f19c83bSHermès Bélusca-Maïto 
11286f19c83bSHermès Bélusca-Maïto                 if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
11296f19c83bSHermès Bélusca-Maïto                     LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
11306f19c83bSHermès Bélusca-Maïto                 {
11316f19c83bSHermès Bélusca-Maïto                     DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
11326f19c83bSHermès Bélusca-Maïto 
1133*7df92966SHermès Bélusca-Maïto                     StartSector = LastStartSector + LastSectorCount;
1134*7df92966SHermès Bélusca-Maïto                     SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
11356f19c83bSHermès Bélusca-Maïto 
11366f19c83bSHermès Bélusca-Maïto                     /* Insert the table into the list */
1137*7df92966SHermès Bélusca-Maïto                     NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1138*7df92966SHermès Bélusca-Maïto                                                            &PartEntry->ListEntry,
1139*7df92966SHermès Bélusca-Maïto                                                            StartSector,
1140*7df92966SHermès Bélusca-Maïto                                                            SectorCount,
1141*7df92966SHermès Bélusca-Maïto                                                            TRUE);
1142*7df92966SHermès Bélusca-Maïto                     if (NewPartEntry == NULL)
1143*7df92966SHermès Bélusca-Maïto                     {
1144*7df92966SHermès Bélusca-Maïto                         DPRINT1("Failed to create a new empty region for extended partition space!\n");
1145*7df92966SHermès Bélusca-Maïto                         return;
1146*7df92966SHermès Bélusca-Maïto                     }
1147*7df92966SHermès Bélusca-Maïto                     NewPartEntry->LogicalPartition = TRUE;
11486f19c83bSHermès Bélusca-Maïto                 }
11496f19c83bSHermès Bélusca-Maïto 
11506f19c83bSHermès Bélusca-Maïto                 LastStartSector = PartEntry->StartSector.QuadPart;
11516f19c83bSHermès Bélusca-Maïto                 LastSectorCount = PartEntry->SectorCount.QuadPart;
11526f19c83bSHermès Bélusca-Maïto             }
11536f19c83bSHermès Bélusca-Maïto 
11546f19c83bSHermès Bélusca-Maïto             Entry = Entry->Flink;
11556f19c83bSHermès Bélusca-Maïto         }
11566f19c83bSHermès Bélusca-Maïto 
11576f19c83bSHermès Bélusca-Maïto         /* Check for trailing unpartitioned disk space */
11586f19c83bSHermès Bélusca-Maïto         if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
11596f19c83bSHermès Bélusca-Maïto         {
1160*7df92966SHermès Bélusca-Maïto             LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart +
1161*7df92966SHermès Bélusca-Maïto                                               DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
1162*7df92966SHermès Bélusca-Maïto                                               DiskEntry->SectorAlignment);
11636f19c83bSHermès Bélusca-Maïto 
11646f19c83bSHermès Bélusca-Maïto             if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
11656f19c83bSHermès Bélusca-Maïto             {
11666f19c83bSHermès Bélusca-Maïto                 DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
11676f19c83bSHermès Bélusca-Maïto 
1168*7df92966SHermès Bélusca-Maïto                 StartSector = LastStartSector + LastSectorCount;
1169*7df92966SHermès Bélusca-Maïto                 SectorCount = AlignDown(StartSector + LastUnusedSectorCount, DiskEntry->SectorAlignment) - StartSector;
11706f19c83bSHermès Bélusca-Maïto 
11716f19c83bSHermès Bélusca-Maïto                 /* Append the table to the list */
1172*7df92966SHermès Bélusca-Maïto                 NewPartEntry = CreateInsertBlankRegion(DiskEntry,
1173*7df92966SHermès Bélusca-Maïto                                                        &DiskEntry->LogicalPartListHead,
1174*7df92966SHermès Bélusca-Maïto                                                        StartSector,
1175*7df92966SHermès Bélusca-Maïto                                                        SectorCount,
1176*7df92966SHermès Bélusca-Maïto                                                        TRUE);
1177*7df92966SHermès Bélusca-Maïto                 if (NewPartEntry == NULL)
1178*7df92966SHermès Bélusca-Maïto                 {
1179*7df92966SHermès Bélusca-Maïto                     DPRINT1("Failed to create a new empty region for extended partition space!\n");
1180*7df92966SHermès Bélusca-Maïto                     return;
1181*7df92966SHermès Bélusca-Maïto                 }
1182*7df92966SHermès Bélusca-Maïto                 NewPartEntry->LogicalPartition = TRUE;
11836f19c83bSHermès Bélusca-Maïto             }
11846f19c83bSHermès Bélusca-Maïto         }
11856f19c83bSHermès Bélusca-Maïto     }
11866f19c83bSHermès Bélusca-Maïto 
11876f19c83bSHermès Bélusca-Maïto     DPRINT("ScanForUnpartitionedDiskSpace() done\n");
11886f19c83bSHermès Bélusca-Maïto }
11896f19c83bSHermès Bélusca-Maïto 
11906f19c83bSHermès Bélusca-Maïto static
11916f19c83bSHermès Bélusca-Maïto VOID
11926f19c83bSHermès Bélusca-Maïto SetDiskSignature(
11936f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
11946f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
11956f19c83bSHermès Bélusca-Maïto {
11966f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER SystemTime;
11976f19c83bSHermès Bélusca-Maïto     TIME_FIELDS TimeFields;
11986f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry2;
11996f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry2;
12006f19c83bSHermès Bélusca-Maïto     PUCHAR Buffer;
12016f19c83bSHermès Bélusca-Maïto 
12026f19c83bSHermès Bélusca-Maïto     Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature;
12036f19c83bSHermès Bélusca-Maïto 
12046f19c83bSHermès Bélusca-Maïto     while (TRUE)
12056f19c83bSHermès Bélusca-Maïto     {
12066f19c83bSHermès Bélusca-Maïto         NtQuerySystemTime(&SystemTime);
12076f19c83bSHermès Bélusca-Maïto         RtlTimeToTimeFields(&SystemTime, &TimeFields);
12086f19c83bSHermès Bélusca-Maïto 
12096f19c83bSHermès Bélusca-Maïto         Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
12106f19c83bSHermès Bélusca-Maïto         Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
12116f19c83bSHermès Bélusca-Maïto         Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
12126f19c83bSHermès Bélusca-Maïto         Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
12136f19c83bSHermès Bélusca-Maïto 
12146f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer->Signature == 0)
12156f19c83bSHermès Bélusca-Maïto         {
12166f19c83bSHermès Bélusca-Maïto             continue;
12176f19c83bSHermès Bélusca-Maïto         }
12186f19c83bSHermès Bélusca-Maïto 
12196f19c83bSHermès Bélusca-Maïto         /* Check if the signature already exist */
12206f19c83bSHermès Bélusca-Maïto         /* FIXME:
12216f19c83bSHermès Bélusca-Maïto          *   Check also signatures from disks, which are
12226f19c83bSHermès Bélusca-Maïto          *   not visible (bootable) by the bios.
12236f19c83bSHermès Bélusca-Maïto          */
12246f19c83bSHermès Bélusca-Maïto         Entry2 = List->DiskListHead.Flink;
12256f19c83bSHermès Bélusca-Maïto         while (Entry2 != &List->DiskListHead)
12266f19c83bSHermès Bélusca-Maïto         {
12276f19c83bSHermès Bélusca-Maïto             DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry);
12286f19c83bSHermès Bélusca-Maïto 
12296f19c83bSHermès Bélusca-Maïto             if (DiskEntry != DiskEntry2 &&
12306f19c83bSHermès Bélusca-Maïto                 DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature)
12316f19c83bSHermès Bélusca-Maïto                 break;
12326f19c83bSHermès Bélusca-Maïto 
12336f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
12346f19c83bSHermès Bélusca-Maïto         }
12356f19c83bSHermès Bélusca-Maïto 
12366f19c83bSHermès Bélusca-Maïto         if (Entry2 == &List->DiskListHead)
12376f19c83bSHermès Bélusca-Maïto             break;
12386f19c83bSHermès Bélusca-Maïto     }
12396f19c83bSHermès Bélusca-Maïto }
12406f19c83bSHermès Bélusca-Maïto 
12416f19c83bSHermès Bélusca-Maïto static
12426f19c83bSHermès Bélusca-Maïto VOID
12436f19c83bSHermès Bélusca-Maïto UpdateDiskSignatures(
12446f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
12456f19c83bSHermès Bélusca-Maïto {
12466f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
12476f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
12486f19c83bSHermès Bélusca-Maïto 
12496f19c83bSHermès Bélusca-Maïto     /* Print partition lines */
12506f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
12516f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
12526f19c83bSHermès Bélusca-Maïto     {
12536f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
12546f19c83bSHermès Bélusca-Maïto 
12556f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer &&
12566f19c83bSHermès Bélusca-Maïto             DiskEntry->LayoutBuffer->Signature == 0)
12576f19c83bSHermès Bélusca-Maïto         {
12586f19c83bSHermès Bélusca-Maïto             SetDiskSignature(List, DiskEntry);
12596f19c83bSHermès Bélusca-Maïto             DiskEntry->LayoutBuffer->PartitionEntry[0].RewritePartition = TRUE;
12606f19c83bSHermès Bélusca-Maïto         }
12616f19c83bSHermès Bélusca-Maïto 
12626f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
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 AddDiskToList(
12696f19c83bSHermès Bélusca-Maïto     IN HANDLE FileHandle,
12706f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
12716f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
12726f19c83bSHermès Bélusca-Maïto {
12736f19c83bSHermès Bélusca-Maïto     DISK_GEOMETRY DiskGeometry;
12746f19c83bSHermès Bélusca-Maïto     SCSI_ADDRESS ScsiAddress;
12756f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
12766f19c83bSHermès Bélusca-Maïto     IO_STATUS_BLOCK Iosb;
12776f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
12786f19c83bSHermès Bélusca-Maïto     PPARTITION_SECTOR Mbr;
12796f19c83bSHermès Bélusca-Maïto     PULONG Buffer;
12806f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER FileOffset;
12816f19c83bSHermès Bélusca-Maïto     WCHAR Identifier[20];
12826f19c83bSHermès Bélusca-Maïto     ULONG Checksum;
12836f19c83bSHermès Bélusca-Maïto     ULONG Signature;
12846f19c83bSHermès Bélusca-Maïto     ULONG i;
12856f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
12866f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry;
12876f19c83bSHermès Bélusca-Maïto     ULONG LayoutBufferSize;
12886f19c83bSHermès Bélusca-Maïto     PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
12896f19c83bSHermès Bélusca-Maïto 
1290f41750abSHermès Bélusca-Maïto     /* Retrieve the drive geometry */
12916f19c83bSHermès Bélusca-Maïto     Status = NtDeviceIoControlFile(FileHandle,
12926f19c83bSHermès Bélusca-Maïto                                    NULL,
12936f19c83bSHermès Bélusca-Maïto                                    NULL,
12946f19c83bSHermès Bélusca-Maïto                                    NULL,
12956f19c83bSHermès Bélusca-Maïto                                    &Iosb,
12966f19c83bSHermès Bélusca-Maïto                                    IOCTL_DISK_GET_DRIVE_GEOMETRY,
12976f19c83bSHermès Bélusca-Maïto                                    NULL,
12986f19c83bSHermès Bélusca-Maïto                                    0,
12996f19c83bSHermès Bélusca-Maïto                                    &DiskGeometry,
1300f41750abSHermès Bélusca-Maïto                                    sizeof(DiskGeometry));
13016f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
13026f19c83bSHermès Bélusca-Maïto         return;
13036f19c83bSHermès Bélusca-Maïto 
13046f19c83bSHermès Bélusca-Maïto     if (DiskGeometry.MediaType != FixedMedia &&
13056f19c83bSHermès Bélusca-Maïto         DiskGeometry.MediaType != RemovableMedia)
13066f19c83bSHermès Bélusca-Maïto     {
13076f19c83bSHermès Bélusca-Maïto         return;
13086f19c83bSHermès Bélusca-Maïto     }
13096f19c83bSHermès Bélusca-Maïto 
1310f41750abSHermès Bélusca-Maïto     /*
1311f41750abSHermès Bélusca-Maïto      * FIXME: Here we suppose the disk is always SCSI. What if it is
1312f41750abSHermès Bélusca-Maïto      * of another type? To check this we need to retrieve the name of
1313f41750abSHermès Bélusca-Maïto      * the driver the disk device belongs to.
1314f41750abSHermès Bélusca-Maïto      */
13156f19c83bSHermès Bélusca-Maïto     Status = NtDeviceIoControlFile(FileHandle,
13166f19c83bSHermès Bélusca-Maïto                                    NULL,
13176f19c83bSHermès Bélusca-Maïto                                    NULL,
13186f19c83bSHermès Bélusca-Maïto                                    NULL,
13196f19c83bSHermès Bélusca-Maïto                                    &Iosb,
13206f19c83bSHermès Bélusca-Maïto                                    IOCTL_SCSI_GET_ADDRESS,
13216f19c83bSHermès Bélusca-Maïto                                    NULL,
13226f19c83bSHermès Bélusca-Maïto                                    0,
13236f19c83bSHermès Bélusca-Maïto                                    &ScsiAddress,
1324f41750abSHermès Bélusca-Maïto                                    sizeof(ScsiAddress));
13256f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
13266f19c83bSHermès Bélusca-Maïto         return;
13276f19c83bSHermès Bélusca-Maïto 
13286f19c83bSHermès Bélusca-Maïto     /*
13296f19c83bSHermès Bélusca-Maïto      * Check whether the disk is initialized, by looking at its MBR.
13306f19c83bSHermès Bélusca-Maïto      * NOTE that this must be generalized to GPT disks as well!
13316f19c83bSHermès Bélusca-Maïto      */
13326f19c83bSHermès Bélusca-Maïto 
13336f19c83bSHermès Bélusca-Maïto     Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap,
13346f19c83bSHermès Bélusca-Maïto                                              0,
13356f19c83bSHermès Bélusca-Maïto                                              DiskGeometry.BytesPerSector);
13366f19c83bSHermès Bélusca-Maïto     if (Mbr == NULL)
13376f19c83bSHermès Bélusca-Maïto         return;
13386f19c83bSHermès Bélusca-Maïto 
13396f19c83bSHermès Bélusca-Maïto     FileOffset.QuadPart = 0;
13406f19c83bSHermès Bélusca-Maïto     Status = NtReadFile(FileHandle,
13416f19c83bSHermès Bélusca-Maïto                         NULL,
13426f19c83bSHermès Bélusca-Maïto                         NULL,
13436f19c83bSHermès Bélusca-Maïto                         NULL,
13446f19c83bSHermès Bélusca-Maïto                         &Iosb,
13456f19c83bSHermès Bélusca-Maïto                         (PVOID)Mbr,
13466f19c83bSHermès Bélusca-Maïto                         DiskGeometry.BytesPerSector,
13476f19c83bSHermès Bélusca-Maïto                         &FileOffset,
13486f19c83bSHermès Bélusca-Maïto                         NULL);
13496f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
13506f19c83bSHermès Bélusca-Maïto     {
13516f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, Mbr);
13526f19c83bSHermès Bélusca-Maïto         DPRINT1("NtReadFile failed, status=%x\n", Status);
13536f19c83bSHermès Bélusca-Maïto         return;
13546f19c83bSHermès Bélusca-Maïto     }
13556f19c83bSHermès Bélusca-Maïto     Signature = Mbr->Signature;
13566f19c83bSHermès Bélusca-Maïto 
13576f19c83bSHermès Bélusca-Maïto     /* Calculate the MBR checksum */
13586f19c83bSHermès Bélusca-Maïto     Checksum = 0;
13596f19c83bSHermès Bélusca-Maïto     Buffer = (PULONG)Mbr;
13606f19c83bSHermès Bélusca-Maïto     for (i = 0; i < 128; i++)
13616f19c83bSHermès Bélusca-Maïto     {
13626f19c83bSHermès Bélusca-Maïto         Checksum += Buffer[i];
13636f19c83bSHermès Bélusca-Maïto     }
13646f19c83bSHermès Bélusca-Maïto     Checksum = ~Checksum + 1;
13656f19c83bSHermès Bélusca-Maïto 
13666f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier),
13676f19c83bSHermès Bélusca-Maïto                         L"%08x-%08x-A", Checksum, Signature);
13686f19c83bSHermès Bélusca-Maïto     DPRINT("Identifier: %S\n", Identifier);
13696f19c83bSHermès Bélusca-Maïto 
13706f19c83bSHermès Bélusca-Maïto     DiskEntry = RtlAllocateHeap(ProcessHeap,
13716f19c83bSHermès Bélusca-Maïto                                 HEAP_ZERO_MEMORY,
13726f19c83bSHermès Bélusca-Maïto                                 sizeof(DISKENTRY));
13736f19c83bSHermès Bélusca-Maïto     if (DiskEntry == NULL)
13746f19c83bSHermès Bélusca-Maïto     {
1375f41750abSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, Mbr);
1376f41750abSHermès Bélusca-Maïto         DPRINT1("Failed to allocate a new disk entry.\n");
13776f19c83bSHermès Bélusca-Maïto         return;
13786f19c83bSHermès Bélusca-Maïto     }
13796f19c83bSHermès Bélusca-Maïto 
13806f19c83bSHermès Bélusca-Maïto //    DiskEntry->Checksum = Checksum;
13816f19c83bSHermès Bélusca-Maïto //    DiskEntry->Signature = Signature;
13826f19c83bSHermès Bélusca-Maïto     DiskEntry->BiosFound = FALSE;
13836f19c83bSHermès Bélusca-Maïto 
13846f19c83bSHermès Bélusca-Maïto     /*
13856f19c83bSHermès Bélusca-Maïto      * Check if this disk has a valid MBR: verify its signature,
13866f19c83bSHermès Bélusca-Maïto      * and whether its two first bytes are a valid instruction
13876f19c83bSHermès Bélusca-Maïto      * (related to this, see IsThereAValidBootSector() in partlist.c).
13886f19c83bSHermès Bélusca-Maïto      */
13896f19c83bSHermès Bélusca-Maïto     if (Mbr->Magic != 0xaa55 || (*(PUSHORT)Mbr->BootCode) == 0x0000)
13906f19c83bSHermès Bélusca-Maïto         DiskEntry->NoMbr = TRUE;
13916f19c83bSHermès Bélusca-Maïto     else
13926f19c83bSHermès Bélusca-Maïto         DiskEntry->NoMbr = FALSE;
13936f19c83bSHermès Bélusca-Maïto 
13946f19c83bSHermès Bélusca-Maïto     /* Free the MBR sector buffer */
13956f19c83bSHermès Bélusca-Maïto     RtlFreeHeap(ProcessHeap, 0, Mbr);
13966f19c83bSHermès Bélusca-Maïto 
13976f19c83bSHermès Bélusca-Maïto 
13986f19c83bSHermès Bélusca-Maïto     ListEntry = List->BiosDiskListHead.Flink;
13996f19c83bSHermès Bélusca-Maïto     while (ListEntry != &List->BiosDiskListHead)
14006f19c83bSHermès Bélusca-Maïto     {
14016f19c83bSHermès Bélusca-Maïto         BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
14026f19c83bSHermès Bélusca-Maïto         /* FIXME:
14036f19c83bSHermès Bélusca-Maïto          *   Compare the size from bios and the reported size from driver.
14046f19c83bSHermès Bélusca-Maïto          *   If we have more than one disk with a zero or with the same signature
14056f19c83bSHermès Bélusca-Maïto          *   we must create new signatures and reboot. After the reboot,
14066f19c83bSHermès Bélusca-Maïto          *   it is possible to identify the disks.
14076f19c83bSHermès Bélusca-Maïto          */
14086f19c83bSHermès Bélusca-Maïto         if (BiosDiskEntry->Signature == Signature &&
14096f19c83bSHermès Bélusca-Maïto             BiosDiskEntry->Checksum == Checksum &&
14106f19c83bSHermès Bélusca-Maïto             !BiosDiskEntry->Recognized)
14116f19c83bSHermès Bélusca-Maïto         {
14126f19c83bSHermès Bélusca-Maïto             if (!DiskEntry->BiosFound)
14136f19c83bSHermès Bélusca-Maïto             {
14146f19c83bSHermès Bélusca-Maïto                 DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
14156f19c83bSHermès Bélusca-Maïto                 DiskEntry->BiosFound = TRUE;
14166f19c83bSHermès Bélusca-Maïto                 BiosDiskEntry->Recognized = TRUE;
14176f19c83bSHermès Bélusca-Maïto             }
14186f19c83bSHermès Bélusca-Maïto             else
14196f19c83bSHermès Bélusca-Maïto             {
1420f41750abSHermès Bélusca-Maïto                 // FIXME: What to do?
14216f19c83bSHermès Bélusca-Maïto             }
14226f19c83bSHermès Bélusca-Maïto         }
14236f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
14246f19c83bSHermès Bélusca-Maïto     }
14256f19c83bSHermès Bélusca-Maïto 
14266f19c83bSHermès Bélusca-Maïto     if (!DiskEntry->BiosFound)
14276f19c83bSHermès Bélusca-Maïto     {
14286f19c83bSHermès Bélusca-Maïto #if 0
14296f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, DiskEntry);
14306f19c83bSHermès Bélusca-Maïto         return;
14316f19c83bSHermès Bélusca-Maïto #else
14326f19c83bSHermè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);
14336f19c83bSHermès Bélusca-Maïto #endif
14346f19c83bSHermès Bélusca-Maïto     }
14356f19c83bSHermès Bélusca-Maïto 
14366f19c83bSHermès Bélusca-Maïto     InitializeListHead(&DiskEntry->PrimaryPartListHead);
14376f19c83bSHermès Bélusca-Maïto     InitializeListHead(&DiskEntry->LogicalPartListHead);
14386f19c83bSHermès Bélusca-Maïto 
14396f19c83bSHermès Bélusca-Maïto     DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
14406f19c83bSHermès Bélusca-Maïto     DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
14416f19c83bSHermès Bélusca-Maïto     DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
14426f19c83bSHermès Bélusca-Maïto     DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
14436f19c83bSHermès Bélusca-Maïto 
14446f19c83bSHermès Bélusca-Maïto     DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
14456f19c83bSHermès Bélusca-Maïto     DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
14466f19c83bSHermès Bélusca-Maïto     DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
14476f19c83bSHermès Bélusca-Maïto     DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
14486f19c83bSHermès Bélusca-Maïto 
14496f19c83bSHermès Bélusca-Maïto     DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
14506f19c83bSHermès Bélusca-Maïto                                       (ULONGLONG)DiskGeometry.TracksPerCylinder *
14516f19c83bSHermès Bélusca-Maïto                                       (ULONGLONG)DiskGeometry.SectorsPerTrack;
14526f19c83bSHermès Bélusca-Maïto 
14536f19c83bSHermès Bélusca-Maïto     DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
14546f19c83bSHermès Bélusca-Maïto     DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
14556f19c83bSHermès Bélusca-Maïto                                    DiskGeometry.SectorsPerTrack;
14566f19c83bSHermès Bélusca-Maïto 
14576f19c83bSHermès Bélusca-Maïto     DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
14586f19c83bSHermès Bélusca-Maïto     DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
14596f19c83bSHermès Bélusca-Maïto 
14606f19c83bSHermès Bélusca-Maïto     DiskEntry->DiskNumber = DiskNumber;
14616f19c83bSHermès Bélusca-Maïto     DiskEntry->Port = ScsiAddress.PortNumber;
14626f19c83bSHermès Bélusca-Maïto     DiskEntry->Bus = ScsiAddress.PathId;
14636f19c83bSHermès Bélusca-Maïto     DiskEntry->Id = ScsiAddress.TargetId;
14646f19c83bSHermès Bélusca-Maïto 
14656f19c83bSHermès Bélusca-Maïto     GetDriverName(DiskEntry);
14666f19c83bSHermès Bélusca-Maïto     /*
14676f19c83bSHermès Bélusca-Maïto      * Actually it would be more correct somehow to use:
14686f19c83bSHermès Bélusca-Maïto      *
14696f19c83bSHermès Bélusca-Maïto      * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
14706f19c83bSHermès Bélusca-Maïto      * ULONG ReturnedLength;
14716f19c83bSHermès Bélusca-Maïto      *
14726f19c83bSHermès Bélusca-Maïto      * Status = NtQueryObject(SomeHandleToTheDisk,
14736f19c83bSHermès Bélusca-Maïto      *                        ObjectNameInformation,
14746f19c83bSHermès Bélusca-Maïto      *                        &NameInfo,
14756f19c83bSHermès Bélusca-Maïto      *                        sizeof(NameInfo),
14766f19c83bSHermès Bélusca-Maïto      *                        &ReturnedLength);
14776f19c83bSHermès Bélusca-Maïto      * etc...
14786f19c83bSHermès Bélusca-Maïto      *
14796f19c83bSHermè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
14806f19c83bSHermès Bélusca-Maïto      */
14816f19c83bSHermès Bélusca-Maïto 
14826f19c83bSHermès Bélusca-Maïto     InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
14836f19c83bSHermès Bélusca-Maïto 
1484f41750abSHermès Bélusca-Maïto 
1485f41750abSHermès Bélusca-Maïto     /*
1486f41750abSHermès Bélusca-Maïto      * We now retrieve the disk partition layout
1487f41750abSHermès Bélusca-Maïto      */
1488f41750abSHermès Bélusca-Maïto 
14896f19c83bSHermès Bélusca-Maïto     /* Allocate a layout buffer with 4 partition entries first */
14906f19c83bSHermès Bélusca-Maïto     LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
14916f19c83bSHermès Bélusca-Maïto                        ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
14926f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer = RtlAllocateHeap(ProcessHeap,
14936f19c83bSHermès Bélusca-Maïto                                               HEAP_ZERO_MEMORY,
14946f19c83bSHermès Bélusca-Maïto                                               LayoutBufferSize);
14956f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer == NULL)
14966f19c83bSHermès Bélusca-Maïto     {
14976f19c83bSHermès Bélusca-Maïto         DPRINT1("Failed to allocate the disk layout buffer!\n");
14986f19c83bSHermès Bélusca-Maïto         return;
14996f19c83bSHermès Bélusca-Maïto     }
15006f19c83bSHermès Bélusca-Maïto 
1501f41750abSHermès Bélusca-Maïto     /* Keep looping while the drive layout buffer is too small */
15026f19c83bSHermès Bélusca-Maïto     for (;;)
15036f19c83bSHermès Bélusca-Maïto     {
15046f19c83bSHermès Bélusca-Maïto         DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
15056f19c83bSHermès Bélusca-Maïto         Status = NtDeviceIoControlFile(FileHandle,
15066f19c83bSHermès Bélusca-Maïto                                        NULL,
15076f19c83bSHermès Bélusca-Maïto                                        NULL,
15086f19c83bSHermès Bélusca-Maïto                                        NULL,
15096f19c83bSHermès Bélusca-Maïto                                        &Iosb,
15106f19c83bSHermès Bélusca-Maïto                                        IOCTL_DISK_GET_DRIVE_LAYOUT,
15116f19c83bSHermès Bélusca-Maïto                                        NULL,
15126f19c83bSHermès Bélusca-Maïto                                        0,
15136f19c83bSHermès Bélusca-Maïto                                        DiskEntry->LayoutBuffer,
15146f19c83bSHermès Bélusca-Maïto                                        LayoutBufferSize);
15156f19c83bSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
15166f19c83bSHermès Bélusca-Maïto             break;
15176f19c83bSHermès Bélusca-Maïto 
15186f19c83bSHermès Bélusca-Maïto         if (Status != STATUS_BUFFER_TOO_SMALL)
15196f19c83bSHermès Bélusca-Maïto         {
15206f19c83bSHermès Bélusca-Maïto             DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
15216f19c83bSHermès Bélusca-Maïto             return;
15226f19c83bSHermès Bélusca-Maïto         }
15236f19c83bSHermès Bélusca-Maïto 
15246f19c83bSHermès Bélusca-Maïto         LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
15256f19c83bSHermès Bélusca-Maïto         NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
15266f19c83bSHermès Bélusca-Maïto                                             HEAP_ZERO_MEMORY,
15276f19c83bSHermès Bélusca-Maïto                                             DiskEntry->LayoutBuffer,
15286f19c83bSHermès Bélusca-Maïto                                             LayoutBufferSize);
15296f19c83bSHermès Bélusca-Maïto         if (NewLayoutBuffer == NULL)
15306f19c83bSHermès Bélusca-Maïto         {
15316f19c83bSHermès Bélusca-Maïto             DPRINT1("Failed to reallocate the disk layout buffer!\n");
15326f19c83bSHermès Bélusca-Maïto             return;
15336f19c83bSHermès Bélusca-Maïto         }
15346f19c83bSHermès Bélusca-Maïto 
15356f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer = NewLayoutBuffer;
15366f19c83bSHermès Bélusca-Maïto     }
15376f19c83bSHermès Bélusca-Maïto 
15386f19c83bSHermès Bélusca-Maïto     DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
15396f19c83bSHermès Bélusca-Maïto 
15406f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
15416f19c83bSHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
15426f19c83bSHermès Bélusca-Maïto #endif
15436f19c83bSHermès Bélusca-Maïto 
15446f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
15456f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
15466f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != PARTITION_ENTRY_UNUSED)
15476f19c83bSHermès Bélusca-Maïto     {
15486f19c83bSHermès Bélusca-Maïto         if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
15496f19c83bSHermès Bélusca-Maïto         {
15506f19c83bSHermès Bélusca-Maïto             DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
15516f19c83bSHermès Bélusca-Maïto         }
15526f19c83bSHermès Bélusca-Maïto         else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
15536f19c83bSHermès Bélusca-Maïto         {
15546f19c83bSHermès Bélusca-Maïto             DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
15556f19c83bSHermès Bélusca-Maïto         }
15566f19c83bSHermès Bélusca-Maïto         else
15576f19c83bSHermès Bélusca-Maïto         {
15586f19c83bSHermès Bélusca-Maïto             DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
15596f19c83bSHermès Bélusca-Maïto         }
15606f19c83bSHermès Bélusca-Maïto     }
15616f19c83bSHermès Bélusca-Maïto     else
15626f19c83bSHermès Bélusca-Maïto     {
15636f19c83bSHermès Bélusca-Maïto         DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
15646f19c83bSHermès Bélusca-Maïto     }
15656f19c83bSHermès Bélusca-Maïto 
15666f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer->PartitionCount == 0)
15676f19c83bSHermès Bélusca-Maïto     {
15686f19c83bSHermès Bélusca-Maïto         DiskEntry->NewDisk = TRUE;
15696f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer->PartitionCount = 4;
15706f19c83bSHermès Bélusca-Maïto 
15716f19c83bSHermès Bélusca-Maïto         for (i = 0; i < 4; i++)
1572*7df92966SHermès Bélusca-Maïto         {
15736f19c83bSHermès Bélusca-Maïto             DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
15746f19c83bSHermès Bélusca-Maïto         }
1575*7df92966SHermès Bélusca-Maïto     }
15766f19c83bSHermès Bélusca-Maïto     else
15776f19c83bSHermès Bélusca-Maïto     {
1578*7df92966SHermès Bélusca-Maïto         /* Enumerate and add the first four primary partitions */
15796f19c83bSHermès Bélusca-Maïto         for (i = 0; i < 4; i++)
15806f19c83bSHermès Bélusca-Maïto         {
15816f19c83bSHermès Bélusca-Maïto             AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
15826f19c83bSHermès Bélusca-Maïto         }
15836f19c83bSHermès Bélusca-Maïto 
1584*7df92966SHermès Bélusca-Maïto         /* Enumerate and add the remaining partitions as logical ones */
15856f19c83bSHermès Bélusca-Maïto         for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
15866f19c83bSHermès Bélusca-Maïto         {
15876f19c83bSHermès Bélusca-Maïto             AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
15886f19c83bSHermès Bélusca-Maïto         }
15896f19c83bSHermès Bélusca-Maïto     }
15906f19c83bSHermès Bélusca-Maïto 
15916f19c83bSHermès Bélusca-Maïto     ScanForUnpartitionedDiskSpace(DiskEntry);
15926f19c83bSHermès Bélusca-Maïto }
15936f19c83bSHermès Bélusca-Maïto 
15946f19c83bSHermès Bélusca-Maïto PPARTLIST
15956f19c83bSHermès Bélusca-Maïto CreatePartitionList(VOID)
15966f19c83bSHermès Bélusca-Maïto {
15976f19c83bSHermès Bélusca-Maïto     PPARTLIST List;
15986f19c83bSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
15996f19c83bSHermès Bélusca-Maïto     SYSTEM_DEVICE_INFORMATION Sdi;
16006f19c83bSHermès Bélusca-Maïto     IO_STATUS_BLOCK Iosb;
16016f19c83bSHermès Bélusca-Maïto     ULONG ReturnSize;
16026f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
16036f19c83bSHermès Bélusca-Maïto     ULONG DiskNumber;
16046f19c83bSHermès Bélusca-Maïto     WCHAR Buffer[MAX_PATH];
16056f19c83bSHermès Bélusca-Maïto     UNICODE_STRING Name;
16066f19c83bSHermès Bélusca-Maïto     HANDLE FileHandle;
16076f19c83bSHermès Bélusca-Maïto 
16086f19c83bSHermès Bélusca-Maïto     List = (PPARTLIST)RtlAllocateHeap(ProcessHeap,
16096f19c83bSHermès Bélusca-Maïto                                       0,
16106f19c83bSHermès Bélusca-Maïto                                       sizeof(PARTLIST));
16116f19c83bSHermès Bélusca-Maïto     if (List == NULL)
16126f19c83bSHermès Bélusca-Maïto         return NULL;
16136f19c83bSHermès Bélusca-Maïto 
16146f19c83bSHermès Bélusca-Maïto     List->CurrentDisk = NULL;
16156f19c83bSHermès Bélusca-Maïto     List->CurrentPartition = NULL;
16166f19c83bSHermès Bélusca-Maïto 
16176f19c83bSHermès Bélusca-Maïto     List->SystemPartition = NULL;
16186f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = NULL;
16196f19c83bSHermès Bélusca-Maïto 
16206f19c83bSHermès Bélusca-Maïto     InitializeListHead(&List->DiskListHead);
16216f19c83bSHermès Bélusca-Maïto     InitializeListHead(&List->BiosDiskListHead);
16226f19c83bSHermès Bélusca-Maïto 
1623f41750abSHermès Bélusca-Maïto     /*
1624f41750abSHermès Bélusca-Maïto      * Enumerate the disks seen by the BIOS; this will be used later
1625f41750abSHermès Bélusca-Maïto      * to map drives seen by NTOS with their corresponding BIOS names.
1626f41750abSHermès Bélusca-Maïto      */
16276f19c83bSHermès Bélusca-Maïto     EnumerateBiosDiskEntries(List);
16286f19c83bSHermès Bélusca-Maïto 
1629f41750abSHermès Bélusca-Maïto     /* Enumerate disks seen by NTOS */
16306f19c83bSHermès Bélusca-Maïto     Status = NtQuerySystemInformation(SystemDeviceInformation,
16316f19c83bSHermès Bélusca-Maïto                                       &Sdi,
16326f19c83bSHermès Bélusca-Maïto                                       sizeof(Sdi),
16336f19c83bSHermès Bélusca-Maïto                                       &ReturnSize);
16346f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
16356f19c83bSHermès Bélusca-Maïto     {
16366f19c83bSHermès Bélusca-Maïto         DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status);
16376f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, List);
16386f19c83bSHermès Bélusca-Maïto         return NULL;
16396f19c83bSHermès Bélusca-Maïto     }
16406f19c83bSHermès Bélusca-Maïto 
16416f19c83bSHermès Bélusca-Maïto     for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
16426f19c83bSHermès Bélusca-Maïto     {
16436f19c83bSHermès Bélusca-Maïto         RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
16446f19c83bSHermès Bélusca-Maïto                             L"\\Device\\Harddisk%lu\\Partition0",
16456f19c83bSHermès Bélusca-Maïto                             DiskNumber);
16466f19c83bSHermès Bélusca-Maïto         RtlInitUnicodeString(&Name, Buffer);
16476f19c83bSHermès Bélusca-Maïto 
16486f19c83bSHermès Bélusca-Maïto         InitializeObjectAttributes(&ObjectAttributes,
16496f19c83bSHermès Bélusca-Maïto                                    &Name,
1650765994c9SHermès Bélusca-Maïto                                    OBJ_CASE_INSENSITIVE,
16516f19c83bSHermès Bélusca-Maïto                                    NULL,
16526f19c83bSHermès Bélusca-Maïto                                    NULL);
16536f19c83bSHermès Bélusca-Maïto 
16546f19c83bSHermès Bélusca-Maïto         Status = NtOpenFile(&FileHandle,
16556f19c83bSHermès Bélusca-Maïto                             FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
16566f19c83bSHermès Bélusca-Maïto                             &ObjectAttributes,
16576f19c83bSHermès Bélusca-Maïto                             &Iosb,
1658f41750abSHermès Bélusca-Maïto                             FILE_SHARE_READ | FILE_SHARE_WRITE,
16596f19c83bSHermès Bélusca-Maïto                             FILE_SYNCHRONOUS_IO_NONALERT);
16606f19c83bSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
16616f19c83bSHermès Bélusca-Maïto         {
16626f19c83bSHermès Bélusca-Maïto             AddDiskToList(FileHandle, DiskNumber, List);
16636f19c83bSHermès Bélusca-Maïto             NtClose(FileHandle);
16646f19c83bSHermès Bélusca-Maïto         }
16656f19c83bSHermès Bélusca-Maïto     }
16666f19c83bSHermès Bélusca-Maïto 
16676f19c83bSHermès Bélusca-Maïto     UpdateDiskSignatures(List);
16686f19c83bSHermès Bélusca-Maïto 
16696f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
16706f19c83bSHermès Bélusca-Maïto 
16716f19c83bSHermès Bélusca-Maïto     /* Search for first usable disk and partition */
16726f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
16736f19c83bSHermès Bélusca-Maïto     {
16746f19c83bSHermès Bélusca-Maïto         List->CurrentDisk = NULL;
16756f19c83bSHermès Bélusca-Maïto         List->CurrentPartition = NULL;
16766f19c83bSHermès Bélusca-Maïto     }
16776f19c83bSHermès Bélusca-Maïto     else
16786f19c83bSHermès Bélusca-Maïto     {
16796f19c83bSHermès Bélusca-Maïto         List->CurrentDisk = CONTAINING_RECORD(List->DiskListHead.Flink,
16806f19c83bSHermès Bélusca-Maïto                                               DISKENTRY,
16816f19c83bSHermès Bélusca-Maïto                                               ListEntry);
16826f19c83bSHermès Bélusca-Maïto 
16836f19c83bSHermès Bélusca-Maïto         if (IsListEmpty(&List->CurrentDisk->PrimaryPartListHead))
16846f19c83bSHermès Bélusca-Maïto         {
16856f19c83bSHermès Bélusca-Maïto             List->CurrentPartition = NULL;
16866f19c83bSHermès Bélusca-Maïto         }
16876f19c83bSHermès Bélusca-Maïto         else
16886f19c83bSHermès Bélusca-Maïto         {
16896f19c83bSHermès Bélusca-Maïto             List->CurrentPartition = CONTAINING_RECORD(List->CurrentDisk->PrimaryPartListHead.Flink,
16906f19c83bSHermès Bélusca-Maïto                                                        PARTENTRY,
16916f19c83bSHermès Bélusca-Maïto                                                        ListEntry);
16926f19c83bSHermès Bélusca-Maïto         }
16936f19c83bSHermès Bélusca-Maïto     }
16946f19c83bSHermès Bélusca-Maïto 
16956f19c83bSHermès Bélusca-Maïto     return List;
16966f19c83bSHermès Bélusca-Maïto }
16976f19c83bSHermès Bélusca-Maïto 
16986f19c83bSHermès Bélusca-Maïto VOID
16996f19c83bSHermès Bélusca-Maïto DestroyPartitionList(
17006f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
17016f19c83bSHermès Bélusca-Maïto {
17026f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
17036f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry;
17046f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
17056f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
17066f19c83bSHermès Bélusca-Maïto 
17076f19c83bSHermès Bélusca-Maïto     /* Release disk and partition info */
17086f19c83bSHermès Bélusca-Maïto     while (!IsListEmpty(&List->DiskListHead))
17096f19c83bSHermès Bélusca-Maïto     {
17106f19c83bSHermès Bélusca-Maïto         Entry = RemoveHeadList(&List->DiskListHead);
17116f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
17126f19c83bSHermès Bélusca-Maïto 
17136f19c83bSHermès Bélusca-Maïto         /* Release driver name */
17146f19c83bSHermès Bélusca-Maïto         RtlFreeUnicodeString(&DiskEntry->DriverName);
17156f19c83bSHermès Bélusca-Maïto 
17166f19c83bSHermès Bélusca-Maïto         /* Release primary partition list */
17176f19c83bSHermès Bélusca-Maïto         while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
17186f19c83bSHermès Bélusca-Maïto         {
17196f19c83bSHermès Bélusca-Maïto             Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
17206f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
17216f19c83bSHermès Bélusca-Maïto 
17226f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, PartEntry);
17236f19c83bSHermès Bélusca-Maïto         }
17246f19c83bSHermès Bélusca-Maïto 
17256f19c83bSHermès Bélusca-Maïto         /* Release logical partition list */
17266f19c83bSHermès Bélusca-Maïto         while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
17276f19c83bSHermès Bélusca-Maïto         {
17286f19c83bSHermès Bélusca-Maïto             Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
17296f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
17306f19c83bSHermès Bélusca-Maïto 
17316f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, PartEntry);
17326f19c83bSHermès Bélusca-Maïto         }
17336f19c83bSHermès Bélusca-Maïto 
17346f19c83bSHermès Bélusca-Maïto         /* Release layout buffer */
17356f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer != NULL)
17366f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
17376f19c83bSHermès Bélusca-Maïto 
17386f19c83bSHermès Bélusca-Maïto         /* Release disk entry */
17396f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, DiskEntry);
17406f19c83bSHermès Bélusca-Maïto     }
17416f19c83bSHermès Bélusca-Maïto 
17426f19c83bSHermès Bélusca-Maïto     /* Release the bios disk info */
17436f19c83bSHermès Bélusca-Maïto     while (!IsListEmpty(&List->BiosDiskListHead))
17446f19c83bSHermès Bélusca-Maïto     {
17456f19c83bSHermès Bélusca-Maïto         Entry = RemoveHeadList(&List->BiosDiskListHead);
17466f19c83bSHermès Bélusca-Maïto         BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
17476f19c83bSHermès Bélusca-Maïto 
17486f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
17496f19c83bSHermès Bélusca-Maïto     }
17506f19c83bSHermès Bélusca-Maïto 
17516f19c83bSHermès Bélusca-Maïto     /* Release list head */
17526f19c83bSHermès Bélusca-Maïto     RtlFreeHeap(ProcessHeap, 0, List);
17536f19c83bSHermès Bélusca-Maïto }
17546f19c83bSHermès Bélusca-Maïto 
17556f19c83bSHermès Bélusca-Maïto PDISKENTRY
17566f19c83bSHermès Bélusca-Maïto GetDiskByBiosNumber(
17576f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
17586f19c83bSHermès Bélusca-Maïto     IN ULONG BiosDiskNumber)
17596f19c83bSHermès Bélusca-Maïto {
17606f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
17616f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
17626f19c83bSHermès Bélusca-Maïto 
17636f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
17646f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
17656f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
17666f19c83bSHermès Bélusca-Maïto     {
17676f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
17686f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
17696f19c83bSHermès Bélusca-Maïto 
17706f19c83bSHermès Bélusca-Maïto         if (DiskEntry->BiosDiskNumber == BiosDiskNumber)
17716f19c83bSHermès Bélusca-Maïto         {
17726f19c83bSHermès Bélusca-Maïto             /* Disk found */
17736f19c83bSHermès Bélusca-Maïto             return DiskEntry;
17746f19c83bSHermès Bélusca-Maïto         }
17756f19c83bSHermès Bélusca-Maïto     }
17766f19c83bSHermès Bélusca-Maïto 
17776f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
17786f19c83bSHermès Bélusca-Maïto     return NULL;
17796f19c83bSHermès Bélusca-Maïto }
17806f19c83bSHermès Bélusca-Maïto 
17816f19c83bSHermès Bélusca-Maïto PDISKENTRY
17826f19c83bSHermès Bélusca-Maïto GetDiskByNumber(
17836f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
17846f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber)
17856f19c83bSHermès Bélusca-Maïto {
17866f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
17876f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
17886f19c83bSHermès Bélusca-Maïto 
17896f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
17906f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
17916f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
17926f19c83bSHermès Bélusca-Maïto     {
17936f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
17946f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
17956f19c83bSHermès Bélusca-Maïto 
17966f19c83bSHermès Bélusca-Maïto         if (DiskEntry->DiskNumber == DiskNumber)
17976f19c83bSHermès Bélusca-Maïto         {
17986f19c83bSHermès Bélusca-Maïto             /* Disk found */
17996f19c83bSHermès Bélusca-Maïto             return DiskEntry;
18006f19c83bSHermès Bélusca-Maïto         }
18016f19c83bSHermès Bélusca-Maïto     }
18026f19c83bSHermès Bélusca-Maïto 
18036f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
18046f19c83bSHermès Bélusca-Maïto     return NULL;
18056f19c83bSHermès Bélusca-Maïto }
18066f19c83bSHermès Bélusca-Maïto 
18076f19c83bSHermès Bélusca-Maïto PDISKENTRY
18086f19c83bSHermès Bélusca-Maïto GetDiskBySCSI(
18096f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
18106f19c83bSHermès Bélusca-Maïto     IN USHORT Port,
18116f19c83bSHermès Bélusca-Maïto     IN USHORT Bus,
18126f19c83bSHermès Bélusca-Maïto     IN USHORT Id)
18136f19c83bSHermès Bélusca-Maïto {
18146f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
18156f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
18166f19c83bSHermès Bélusca-Maïto 
18176f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
18186f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
18196f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
18206f19c83bSHermès Bélusca-Maïto     {
18216f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
18226f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
18236f19c83bSHermès Bélusca-Maïto 
18246f19c83bSHermès Bélusca-Maïto         if (DiskEntry->Port == Port &&
18256f19c83bSHermès Bélusca-Maïto             DiskEntry->Bus  == Bus  &&
18266f19c83bSHermès Bélusca-Maïto             DiskEntry->Id   == Id)
18276f19c83bSHermès Bélusca-Maïto         {
18286f19c83bSHermès Bélusca-Maïto             /* Disk found */
18296f19c83bSHermès Bélusca-Maïto             return DiskEntry;
18306f19c83bSHermès Bélusca-Maïto         }
18316f19c83bSHermès Bélusca-Maïto     }
18326f19c83bSHermès Bélusca-Maïto 
18336f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
18346f19c83bSHermès Bélusca-Maïto     return NULL;
18356f19c83bSHermès Bélusca-Maïto }
18366f19c83bSHermès Bélusca-Maïto 
18376f19c83bSHermès Bélusca-Maïto PDISKENTRY
18386f19c83bSHermès Bélusca-Maïto GetDiskBySignature(
18396f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
18406f19c83bSHermès Bélusca-Maïto     IN ULONG Signature)
18416f19c83bSHermès Bélusca-Maïto {
18426f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
18436f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
18446f19c83bSHermès Bélusca-Maïto 
18456f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
18466f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
18476f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
18486f19c83bSHermès Bélusca-Maïto     {
18496f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
18506f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
18516f19c83bSHermès Bélusca-Maïto 
18526f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer->Signature == Signature)
18536f19c83bSHermès Bélusca-Maïto         {
18546f19c83bSHermès Bélusca-Maïto             /* Disk found */
18556f19c83bSHermès Bélusca-Maïto             return DiskEntry;
18566f19c83bSHermès Bélusca-Maïto         }
18576f19c83bSHermès Bélusca-Maïto     }
18586f19c83bSHermès Bélusca-Maïto 
18596f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
18606f19c83bSHermès Bélusca-Maïto     return NULL;
18616f19c83bSHermès Bélusca-Maïto }
18626f19c83bSHermès Bélusca-Maïto 
18636f19c83bSHermès Bélusca-Maïto PPARTENTRY
18646f19c83bSHermès Bélusca-Maïto GetPartition(
18656f19c83bSHermès Bélusca-Maïto     // IN PPARTLIST List,
18666f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
18676f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionNumber)
18686f19c83bSHermès Bélusca-Maïto {
18696f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
18706f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
18716f19c83bSHermès Bélusca-Maïto 
18726f19c83bSHermès Bélusca-Maïto     /* Disk found, loop over the primary partitions first... */
18736f19c83bSHermès Bélusca-Maïto     Entry = DiskEntry->PrimaryPartListHead.Flink;
18746f19c83bSHermès Bélusca-Maïto     while (Entry != &DiskEntry->PrimaryPartListHead)
18756f19c83bSHermès Bélusca-Maïto     {
18766f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
18776f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
18786f19c83bSHermès Bélusca-Maïto 
18796f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionNumber == PartitionNumber)
18806f19c83bSHermès Bélusca-Maïto         {
18816f19c83bSHermès Bélusca-Maïto             /* Partition found */
18826f19c83bSHermès Bélusca-Maïto             return PartEntry;
18836f19c83bSHermès Bélusca-Maïto         }
18846f19c83bSHermès Bélusca-Maïto     }
18856f19c83bSHermès Bélusca-Maïto 
18866f19c83bSHermès Bélusca-Maïto     /* ... then over the logical partitions if needed */
18876f19c83bSHermès Bélusca-Maïto     Entry = DiskEntry->LogicalPartListHead.Flink;
18886f19c83bSHermès Bélusca-Maïto     while (Entry != &DiskEntry->LogicalPartListHead)
18896f19c83bSHermès Bélusca-Maïto     {
18906f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
18916f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
18926f19c83bSHermès Bélusca-Maïto 
18936f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionNumber == PartitionNumber)
18946f19c83bSHermès Bélusca-Maïto         {
18956f19c83bSHermès Bélusca-Maïto             /* Partition found */
18966f19c83bSHermès Bélusca-Maïto             return PartEntry;
18976f19c83bSHermès Bélusca-Maïto         }
18986f19c83bSHermès Bélusca-Maïto     }
18996f19c83bSHermès Bélusca-Maïto 
19006f19c83bSHermès Bélusca-Maïto     /* The partition was not found on the disk, stop there */
19016f19c83bSHermès Bélusca-Maïto     return NULL;
19026f19c83bSHermès Bélusca-Maïto }
19036f19c83bSHermès Bélusca-Maïto 
19046f19c83bSHermès Bélusca-Maïto BOOLEAN
19056f19c83bSHermès Bélusca-Maïto GetDiskOrPartition(
19066f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
19076f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
19086f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionNumber OPTIONAL,
19096f19c83bSHermès Bélusca-Maïto     OUT PDISKENTRY* pDiskEntry,
19106f19c83bSHermès Bélusca-Maïto     OUT PPARTENTRY* pPartEntry OPTIONAL)
19116f19c83bSHermès Bélusca-Maïto {
19126f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
19136f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry = NULL;
19146f19c83bSHermès Bélusca-Maïto 
19156f19c83bSHermès Bélusca-Maïto     /* Find the disk */
19166f19c83bSHermès Bélusca-Maïto     DiskEntry = GetDiskByNumber(List, DiskNumber);
19176f19c83bSHermès Bélusca-Maïto     if (!DiskEntry)
19186f19c83bSHermès Bélusca-Maïto         return FALSE;
19196f19c83bSHermès Bélusca-Maïto 
19206f19c83bSHermès Bélusca-Maïto     /* If we have a partition (PartitionNumber != 0), find it */
19216f19c83bSHermès Bélusca-Maïto     if (PartitionNumber != 0)
19226f19c83bSHermès Bélusca-Maïto     {
19236f19c83bSHermès Bélusca-Maïto         PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
19246f19c83bSHermès Bélusca-Maïto         if (!PartEntry)
19256f19c83bSHermès Bélusca-Maïto             return FALSE;
19266f19c83bSHermès Bélusca-Maïto         ASSERT(PartEntry->DiskEntry == DiskEntry);
19276f19c83bSHermès Bélusca-Maïto     }
19286f19c83bSHermès Bélusca-Maïto 
19296f19c83bSHermès Bélusca-Maïto     /* Return the disk (and optionally the partition) */
19306f19c83bSHermès Bélusca-Maïto     *pDiskEntry = DiskEntry;
19316f19c83bSHermès Bélusca-Maïto     if (pPartEntry) *pPartEntry = PartEntry;
19326f19c83bSHermès Bélusca-Maïto     return TRUE;
19336f19c83bSHermès Bélusca-Maïto }
19346f19c83bSHermès Bélusca-Maïto 
19356f19c83bSHermès Bélusca-Maïto //
19366f19c83bSHermès Bélusca-Maïto // NOTE: Was introduced broken in r6258 by Casper
19376f19c83bSHermès Bélusca-Maïto //
19386f19c83bSHermès Bélusca-Maïto BOOLEAN
19396f19c83bSHermès Bélusca-Maïto SelectPartition(
19406f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
19416f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
19426f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionNumber)
19436f19c83bSHermès Bélusca-Maïto {
19446f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
19456f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
19466f19c83bSHermès Bélusca-Maïto 
19476f19c83bSHermès Bélusca-Maïto     DiskEntry = GetDiskByNumber(List, DiskNumber);
19486f19c83bSHermès Bélusca-Maïto     if (!DiskEntry)
19496f19c83bSHermès Bélusca-Maïto         return FALSE;
19506f19c83bSHermès Bélusca-Maïto 
19516f19c83bSHermès Bélusca-Maïto     PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
19526f19c83bSHermès Bélusca-Maïto     if (!PartEntry)
19536f19c83bSHermès Bélusca-Maïto         return FALSE;
19546f19c83bSHermès Bélusca-Maïto 
19556f19c83bSHermès Bélusca-Maïto     ASSERT(PartEntry->DiskEntry == DiskEntry);
19566f19c83bSHermès Bélusca-Maïto     ASSERT(DiskEntry->DiskNumber == DiskNumber);
19576f19c83bSHermès Bélusca-Maïto     ASSERT(PartEntry->PartitionNumber == PartitionNumber);
19586f19c83bSHermès Bélusca-Maïto 
19596f19c83bSHermès Bélusca-Maïto     List->CurrentDisk = DiskEntry;
19606f19c83bSHermès Bélusca-Maïto     List->CurrentPartition = PartEntry;
19616f19c83bSHermès Bélusca-Maïto     return TRUE;
19626f19c83bSHermès Bélusca-Maïto }
19636f19c83bSHermès Bélusca-Maïto 
19646f19c83bSHermès Bélusca-Maïto PPARTENTRY
19656f19c83bSHermès Bélusca-Maïto GetNextPartition(
19666f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
19676f19c83bSHermès Bélusca-Maïto {
19686f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY DiskListEntry;
19696f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY PartListEntry;
19706f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
19716f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
19726f19c83bSHermès Bélusca-Maïto 
19736f19c83bSHermès Bélusca-Maïto     /* Fail if no disks are available */
19746f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
19756f19c83bSHermès Bélusca-Maïto         return NULL;
19766f19c83bSHermès Bélusca-Maïto 
19776f19c83bSHermès Bélusca-Maïto     /* Check for next usable entry on current disk */
19786f19c83bSHermès Bélusca-Maïto     if (List->CurrentPartition != NULL)
19796f19c83bSHermès Bélusca-Maïto     {
19806f19c83bSHermès Bélusca-Maïto         if (List->CurrentPartition->LogicalPartition)
19816f19c83bSHermès Bélusca-Maïto         {
19826f19c83bSHermès Bélusca-Maïto             /* Logical partition */
19836f19c83bSHermès Bélusca-Maïto 
19846f19c83bSHermès Bélusca-Maïto             PartListEntry = List->CurrentPartition->ListEntry.Flink;
19856f19c83bSHermès Bélusca-Maïto             if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
19866f19c83bSHermès Bélusca-Maïto             {
19876f19c83bSHermès Bélusca-Maïto                 /* Next logical partition */
19886f19c83bSHermès Bélusca-Maïto                 PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
19896f19c83bSHermès Bélusca-Maïto 
19906f19c83bSHermès Bélusca-Maïto                 List->CurrentPartition = PartEntry;
19916f19c83bSHermès Bélusca-Maïto                 return List->CurrentPartition;
19926f19c83bSHermès Bélusca-Maïto             }
19936f19c83bSHermès Bélusca-Maïto             else
19946f19c83bSHermès Bélusca-Maïto             {
19956f19c83bSHermès Bélusca-Maïto                 PartListEntry = List->CurrentDisk->ExtendedPartition->ListEntry.Flink;
19966f19c83bSHermès Bélusca-Maïto                 if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
19976f19c83bSHermès Bélusca-Maïto                 {
19986f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
19996f19c83bSHermès Bélusca-Maïto 
20006f19c83bSHermès Bélusca-Maïto                     List->CurrentPartition = PartEntry;
20016f19c83bSHermès Bélusca-Maïto                     return List->CurrentPartition;
20026f19c83bSHermès Bélusca-Maïto                 }
20036f19c83bSHermès Bélusca-Maïto             }
20046f19c83bSHermès Bélusca-Maïto         }
20056f19c83bSHermès Bélusca-Maïto         else
20066f19c83bSHermès Bélusca-Maïto         {
20076f19c83bSHermès Bélusca-Maïto             /* Primary or extended partition */
20086f19c83bSHermès Bélusca-Maïto 
2009*7df92966SHermès Bélusca-Maïto             if (List->CurrentPartition->IsPartitioned &&
20106f19c83bSHermès Bélusca-Maïto                 IsContainerPartition(List->CurrentPartition->PartitionType))
20116f19c83bSHermès Bélusca-Maïto             {
20126f19c83bSHermès Bélusca-Maïto                 /* First logical partition */
20136f19c83bSHermès Bélusca-Maïto                 PartListEntry = List->CurrentDisk->LogicalPartListHead.Flink;
20146f19c83bSHermès Bélusca-Maïto                 if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
20156f19c83bSHermès Bélusca-Maïto                 {
20166f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
20176f19c83bSHermès Bélusca-Maïto 
20186f19c83bSHermès Bélusca-Maïto                     List->CurrentPartition = PartEntry;
20196f19c83bSHermès Bélusca-Maïto                     return List->CurrentPartition;
20206f19c83bSHermès Bélusca-Maïto                 }
20216f19c83bSHermès Bélusca-Maïto             }
20226f19c83bSHermès Bélusca-Maïto             else
20236f19c83bSHermès Bélusca-Maïto             {
20246f19c83bSHermès Bélusca-Maïto                 /* Next primary partition */
20256f19c83bSHermès Bélusca-Maïto                 PartListEntry = List->CurrentPartition->ListEntry.Flink;
20266f19c83bSHermès Bélusca-Maïto                 if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
20276f19c83bSHermès Bélusca-Maïto                 {
20286f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
20296f19c83bSHermès Bélusca-Maïto 
20306f19c83bSHermès Bélusca-Maïto                     List->CurrentPartition = PartEntry;
20316f19c83bSHermès Bélusca-Maïto                     return List->CurrentPartition;
20326f19c83bSHermès Bélusca-Maïto                 }
20336f19c83bSHermès Bélusca-Maïto             }
20346f19c83bSHermès Bélusca-Maïto         }
20356f19c83bSHermès Bélusca-Maïto     }
20366f19c83bSHermès Bélusca-Maïto 
20376f19c83bSHermès Bélusca-Maïto     /* Search for the first partition entry on the next disk */
20386f19c83bSHermès Bélusca-Maïto     DiskListEntry = List->CurrentDisk->ListEntry.Flink;
20396f19c83bSHermès Bélusca-Maïto     while (DiskListEntry != &List->DiskListHead)
20406f19c83bSHermès Bélusca-Maïto     {
20416f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
20426f19c83bSHermès Bélusca-Maïto 
20436f19c83bSHermès Bélusca-Maïto         PartListEntry = DiskEntry->PrimaryPartListHead.Flink;
20446f19c83bSHermès Bélusca-Maïto         if (PartListEntry != &DiskEntry->PrimaryPartListHead)
20456f19c83bSHermès Bélusca-Maïto         {
20466f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
20476f19c83bSHermès Bélusca-Maïto 
20486f19c83bSHermès Bélusca-Maïto             List->CurrentDisk = DiskEntry;
20496f19c83bSHermès Bélusca-Maïto             List->CurrentPartition = PartEntry;
20506f19c83bSHermès Bélusca-Maïto             return List->CurrentPartition;
20516f19c83bSHermès Bélusca-Maïto         }
20526f19c83bSHermès Bélusca-Maïto 
20536f19c83bSHermès Bélusca-Maïto         DiskListEntry = DiskListEntry->Flink;
20546f19c83bSHermès Bélusca-Maïto     }
20556f19c83bSHermès Bélusca-Maïto 
20566f19c83bSHermès Bélusca-Maïto     return NULL;
20576f19c83bSHermès Bélusca-Maïto }
20586f19c83bSHermès Bélusca-Maïto 
20596f19c83bSHermès Bélusca-Maïto PPARTENTRY
20606f19c83bSHermès Bélusca-Maïto GetPrevPartition(
20616f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
20626f19c83bSHermès Bélusca-Maïto {
20636f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY DiskListEntry;
20646f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY PartListEntry;
20656f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
20666f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
20676f19c83bSHermès Bélusca-Maïto 
20686f19c83bSHermès Bélusca-Maïto     /* Fail if no disks are available */
20696f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
20706f19c83bSHermès Bélusca-Maïto         return NULL;
20716f19c83bSHermès Bélusca-Maïto 
20726f19c83bSHermès Bélusca-Maïto     /* Check for previous usable entry on current disk */
20736f19c83bSHermès Bélusca-Maïto     if (List->CurrentPartition != NULL)
20746f19c83bSHermès Bélusca-Maïto     {
20756f19c83bSHermès Bélusca-Maïto         if (List->CurrentPartition->LogicalPartition)
20766f19c83bSHermès Bélusca-Maïto         {
20776f19c83bSHermès Bélusca-Maïto             /* Logical partition */
20786f19c83bSHermès Bélusca-Maïto             PartListEntry = List->CurrentPartition->ListEntry.Blink;
20796f19c83bSHermès Bélusca-Maïto             if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
20806f19c83bSHermès Bélusca-Maïto             {
20816f19c83bSHermès Bélusca-Maïto                 /* Previous logical partition */
20826f19c83bSHermès Bélusca-Maïto                 PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
20836f19c83bSHermès Bélusca-Maïto             }
20846f19c83bSHermès Bélusca-Maïto             else
20856f19c83bSHermès Bélusca-Maïto             {
20866f19c83bSHermès Bélusca-Maïto                 /* Extended partition */
20876f19c83bSHermès Bélusca-Maïto                 PartEntry = List->CurrentDisk->ExtendedPartition;
20886f19c83bSHermès Bélusca-Maïto             }
20896f19c83bSHermès Bélusca-Maïto 
20906f19c83bSHermès Bélusca-Maïto             List->CurrentPartition = PartEntry;
20916f19c83bSHermès Bélusca-Maïto             return List->CurrentPartition;
20926f19c83bSHermès Bélusca-Maïto         }
20936f19c83bSHermès Bélusca-Maïto         else
20946f19c83bSHermès Bélusca-Maïto         {
20956f19c83bSHermès Bélusca-Maïto             /* Primary or extended partition */
20966f19c83bSHermès Bélusca-Maïto 
20976f19c83bSHermès Bélusca-Maïto             PartListEntry = List->CurrentPartition->ListEntry.Blink;
20986f19c83bSHermès Bélusca-Maïto             if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
20996f19c83bSHermès Bélusca-Maïto             {
21006f19c83bSHermès Bélusca-Maïto                 PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
21016f19c83bSHermès Bélusca-Maïto 
2102*7df92966SHermès Bélusca-Maïto                 if (PartEntry->IsPartitioned &&
21036f19c83bSHermès Bélusca-Maïto                     IsContainerPartition(PartEntry->PartitionType))
21046f19c83bSHermès Bélusca-Maïto                 {
21056f19c83bSHermès Bélusca-Maïto                     PartListEntry = List->CurrentDisk->LogicalPartListHead.Blink;
21066f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
21076f19c83bSHermès Bélusca-Maïto                 }
21086f19c83bSHermès Bélusca-Maïto 
21096f19c83bSHermès Bélusca-Maïto                 List->CurrentPartition = PartEntry;
21106f19c83bSHermès Bélusca-Maïto                 return List->CurrentPartition;
21116f19c83bSHermès Bélusca-Maïto             }
21126f19c83bSHermès Bélusca-Maïto         }
21136f19c83bSHermès Bélusca-Maïto     }
21146f19c83bSHermès Bélusca-Maïto 
21156f19c83bSHermès Bélusca-Maïto     /* Search for the last partition entry on the previous disk */
21166f19c83bSHermès Bélusca-Maïto     DiskListEntry = List->CurrentDisk->ListEntry.Blink;
21176f19c83bSHermès Bélusca-Maïto     while (DiskListEntry != &List->DiskListHead)
21186f19c83bSHermès Bélusca-Maïto     {
21196f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
21206f19c83bSHermès Bélusca-Maïto 
21216f19c83bSHermès Bélusca-Maïto         PartListEntry = DiskEntry->PrimaryPartListHead.Blink;
21226f19c83bSHermès Bélusca-Maïto         if (PartListEntry != &DiskEntry->PrimaryPartListHead)
21236f19c83bSHermès Bélusca-Maïto         {
21246f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
21256f19c83bSHermès Bélusca-Maïto 
2126*7df92966SHermès Bélusca-Maïto             if (PartEntry->IsPartitioned &&
21276f19c83bSHermès Bélusca-Maïto                 IsContainerPartition(PartEntry->PartitionType))
21286f19c83bSHermès Bélusca-Maïto             {
21296f19c83bSHermès Bélusca-Maïto                 PartListEntry = DiskEntry->LogicalPartListHead.Blink;
21306f19c83bSHermès Bélusca-Maïto                 if (PartListEntry != &DiskEntry->LogicalPartListHead)
21316f19c83bSHermès Bélusca-Maïto                 {
21326f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
21336f19c83bSHermès Bélusca-Maïto 
21346f19c83bSHermès Bélusca-Maïto                     List->CurrentDisk = DiskEntry;
21356f19c83bSHermès Bélusca-Maïto                     List->CurrentPartition = PartEntry;
21366f19c83bSHermès Bélusca-Maïto                     return List->CurrentPartition;
21376f19c83bSHermès Bélusca-Maïto                 }
21386f19c83bSHermès Bélusca-Maïto             }
21396f19c83bSHermès Bélusca-Maïto             else
21406f19c83bSHermès Bélusca-Maïto             {
21416f19c83bSHermès Bélusca-Maïto                 List->CurrentDisk = DiskEntry;
21426f19c83bSHermès Bélusca-Maïto                 List->CurrentPartition = PartEntry;
21436f19c83bSHermès Bélusca-Maïto                 return List->CurrentPartition;
21446f19c83bSHermès Bélusca-Maïto             }
21456f19c83bSHermès Bélusca-Maïto         }
21466f19c83bSHermès Bélusca-Maïto 
21476f19c83bSHermès Bélusca-Maïto         DiskListEntry = DiskListEntry->Blink;
21486f19c83bSHermès Bélusca-Maïto     }
21496f19c83bSHermès Bélusca-Maïto 
21506f19c83bSHermès Bélusca-Maïto     return NULL;
21516f19c83bSHermès Bélusca-Maïto }
21526f19c83bSHermès Bélusca-Maïto 
21536f19c83bSHermès Bélusca-Maïto // static
21546f19c83bSHermès Bélusca-Maïto FORCEINLINE
21556f19c83bSHermès Bélusca-Maïto BOOLEAN
21566f19c83bSHermès Bélusca-Maïto IsEmptyLayoutEntry(
21576f19c83bSHermès Bélusca-Maïto     IN PPARTITION_INFORMATION PartitionInfo)
21586f19c83bSHermès Bélusca-Maïto {
21596f19c83bSHermès Bélusca-Maïto     if (PartitionInfo->StartingOffset.QuadPart == 0 &&
21606f19c83bSHermès Bélusca-Maïto         PartitionInfo->PartitionLength.QuadPart == 0)
21616f19c83bSHermès Bélusca-Maïto     {
21626f19c83bSHermès Bélusca-Maïto         return TRUE;
21636f19c83bSHermès Bélusca-Maïto     }
21646f19c83bSHermès Bélusca-Maïto 
21656f19c83bSHermès Bélusca-Maïto     return FALSE;
21666f19c83bSHermès Bélusca-Maïto }
21676f19c83bSHermès Bélusca-Maïto 
21686f19c83bSHermès Bélusca-Maïto // static
21696f19c83bSHermès Bélusca-Maïto FORCEINLINE
21706f19c83bSHermès Bélusca-Maïto BOOLEAN
21716f19c83bSHermès Bélusca-Maïto IsSamePrimaryLayoutEntry(
21726f19c83bSHermès Bélusca-Maïto     IN PPARTITION_INFORMATION PartitionInfo,
21736f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
21746f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
21756f19c83bSHermès Bélusca-Maïto {
21766f19c83bSHermès Bélusca-Maïto     if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector &&
21776f19c83bSHermès Bélusca-Maïto         PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector)
21786f19c83bSHermès Bélusca-Maïto //        PartitionInfo->PartitionType == PartEntry->PartitionType
21796f19c83bSHermès Bélusca-Maïto     {
21806f19c83bSHermès Bélusca-Maïto         return TRUE;
21816f19c83bSHermès Bélusca-Maïto     }
21826f19c83bSHermès Bélusca-Maïto 
21836f19c83bSHermès Bélusca-Maïto     return FALSE;
21846f19c83bSHermès Bélusca-Maïto }
21856f19c83bSHermès Bélusca-Maïto 
21866f19c83bSHermès Bélusca-Maïto static
21876f19c83bSHermès Bélusca-Maïto ULONG
21886f19c83bSHermès Bélusca-Maïto GetPrimaryPartitionCount(
21896f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
21906f19c83bSHermès Bélusca-Maïto {
21916f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
21926f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
21936f19c83bSHermès Bélusca-Maïto     ULONG Count = 0;
21946f19c83bSHermès Bélusca-Maïto 
21956f19c83bSHermès Bélusca-Maïto     Entry = DiskEntry->PrimaryPartListHead.Flink;
21966f19c83bSHermès Bélusca-Maïto     while (Entry != &DiskEntry->PrimaryPartListHead)
21976f19c83bSHermès Bélusca-Maïto     {
21986f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
21996f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
22006f19c83bSHermès Bélusca-Maïto             Count++;
22016f19c83bSHermès Bélusca-Maïto 
22026f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
22036f19c83bSHermès Bélusca-Maïto     }
22046f19c83bSHermès Bélusca-Maïto 
22056f19c83bSHermès Bélusca-Maïto     return Count;
22066f19c83bSHermès Bélusca-Maïto }
22076f19c83bSHermès Bélusca-Maïto 
22086f19c83bSHermès Bélusca-Maïto static
22096f19c83bSHermès Bélusca-Maïto ULONG
22106f19c83bSHermès Bélusca-Maïto GetLogicalPartitionCount(
22116f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
22126f19c83bSHermès Bélusca-Maïto {
22136f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
22146f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
22156f19c83bSHermès Bélusca-Maïto     ULONG Count = 0;
22166f19c83bSHermès Bélusca-Maïto 
22176f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->LogicalPartListHead.Flink;
22186f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->LogicalPartListHead)
22196f19c83bSHermès Bélusca-Maïto     {
22206f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
22216f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
22226f19c83bSHermès Bélusca-Maïto             Count++;
22236f19c83bSHermès Bélusca-Maïto 
22246f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
22256f19c83bSHermès Bélusca-Maïto     }
22266f19c83bSHermès Bélusca-Maïto 
22276f19c83bSHermès Bélusca-Maïto     return Count;
22286f19c83bSHermès Bélusca-Maïto }
22296f19c83bSHermès Bélusca-Maïto 
22306f19c83bSHermès Bélusca-Maïto static
22316f19c83bSHermès Bélusca-Maïto BOOLEAN
22326f19c83bSHermès Bélusca-Maïto ReAllocateLayoutBuffer(
22336f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
22346f19c83bSHermès Bélusca-Maïto {
22356f19c83bSHermès Bélusca-Maïto     PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
22366f19c83bSHermès Bélusca-Maïto     ULONG NewPartitionCount;
22376f19c83bSHermès Bélusca-Maïto     ULONG CurrentPartitionCount = 0;
22386f19c83bSHermès Bélusca-Maïto     ULONG LayoutBufferSize;
22396f19c83bSHermès Bélusca-Maïto     ULONG i;
22406f19c83bSHermès Bélusca-Maïto 
22416f19c83bSHermès Bélusca-Maïto     DPRINT1("ReAllocateLayoutBuffer()\n");
22426f19c83bSHermès Bélusca-Maïto 
22436f19c83bSHermès Bélusca-Maïto     NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
22446f19c83bSHermès Bélusca-Maïto 
22456f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer)
22466f19c83bSHermès Bélusca-Maïto         CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
22476f19c83bSHermès Bélusca-Maïto 
2248*7df92966SHermès Bélusca-Maïto     DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
22496f19c83bSHermès Bélusca-Maïto             CurrentPartitionCount, NewPartitionCount);
22506f19c83bSHermès Bélusca-Maïto 
22516f19c83bSHermès Bélusca-Maïto     if (CurrentPartitionCount == NewPartitionCount)
22526f19c83bSHermès Bélusca-Maïto         return TRUE;
22536f19c83bSHermès Bélusca-Maïto 
22546f19c83bSHermès Bélusca-Maïto     LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
22556f19c83bSHermès Bélusca-Maïto                        ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
22566f19c83bSHermès Bélusca-Maïto     NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
22576f19c83bSHermès Bélusca-Maïto                                         HEAP_ZERO_MEMORY,
22586f19c83bSHermès Bélusca-Maïto                                         DiskEntry->LayoutBuffer,
22596f19c83bSHermès Bélusca-Maïto                                         LayoutBufferSize);
22606f19c83bSHermès Bélusca-Maïto     if (NewLayoutBuffer == NULL)
22616f19c83bSHermès Bélusca-Maïto     {
22626f19c83bSHermès Bélusca-Maïto         DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
22636f19c83bSHermès Bélusca-Maïto         return FALSE;
22646f19c83bSHermès Bélusca-Maïto     }
22656f19c83bSHermès Bélusca-Maïto 
2266*7df92966SHermès Bélusca-Maïto     NewLayoutBuffer->PartitionCount = NewPartitionCount;
2267*7df92966SHermès Bélusca-Maïto 
22686f19c83bSHermès Bélusca-Maïto     /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
22696f19c83bSHermès Bélusca-Maïto     if (NewPartitionCount > CurrentPartitionCount)
22706f19c83bSHermès Bélusca-Maïto     {
22716f19c83bSHermès Bélusca-Maïto         for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
2272*7df92966SHermès Bélusca-Maïto         {
22736f19c83bSHermès Bélusca-Maïto             NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
22746f19c83bSHermès Bélusca-Maïto         }
2275*7df92966SHermès Bélusca-Maïto     }
22766f19c83bSHermès Bélusca-Maïto 
22776f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer = NewLayoutBuffer;
22786f19c83bSHermès Bélusca-Maïto 
22796f19c83bSHermès Bélusca-Maïto     return TRUE;
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 VOID
22846f19c83bSHermès Bélusca-Maïto UpdateDiskLayout(
22856f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
22866f19c83bSHermès Bélusca-Maïto {
22876f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
22886f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION LinkInfo = NULL;
22896f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
22906f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
22916f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER HiddenSectors64;
22926f19c83bSHermès Bélusca-Maïto     ULONG Index;
22936f19c83bSHermès Bélusca-Maïto     ULONG PartitionNumber = 1;
22946f19c83bSHermès Bélusca-Maïto 
22956f19c83bSHermès Bélusca-Maïto     DPRINT1("UpdateDiskLayout()\n");
22966f19c83bSHermès Bélusca-Maïto 
22976f19c83bSHermès Bélusca-Maïto     /* Resize the layout buffer if necessary */
22986f19c83bSHermès Bélusca-Maïto     if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
22996f19c83bSHermès Bélusca-Maïto     {
23006f19c83bSHermès Bélusca-Maïto         DPRINT("ReAllocateLayoutBuffer() failed.\n");
23016f19c83bSHermès Bélusca-Maïto         return;
23026f19c83bSHermès Bélusca-Maïto     }
23036f19c83bSHermès Bélusca-Maïto 
23046f19c83bSHermès Bélusca-Maïto     /* Update the primary partition table */
23056f19c83bSHermès Bélusca-Maïto     Index = 0;
23066f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->PrimaryPartListHead.Flink;
23076f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->PrimaryPartListHead)
23086f19c83bSHermès Bélusca-Maïto     {
23096f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
23106f19c83bSHermès Bélusca-Maïto 
2311*7df92966SHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
23126f19c83bSHermès Bélusca-Maïto         {
23136f19c83bSHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2314*7df92966SHermès Bélusca-Maïto             PartEntry->PartitionIndex = Index;
2315*7df92966SHermès Bélusca-Maïto 
2316*7df92966SHermès Bélusca-Maïto             /* Reset the current partition number only for newly-created partitions */
2317*7df92966SHermès Bélusca-Maïto             if (PartEntry->New)
2318*7df92966SHermès Bélusca-Maïto                 PartEntry->PartitionNumber = 0;
2319*7df92966SHermès Bélusca-Maïto 
2320*7df92966SHermès Bélusca-Maïto             PartEntry->OnDiskPartitionNumber = (!IsContainerPartition(PartEntry->PartitionType)) ? PartitionNumber : 0;
23216f19c83bSHermès Bélusca-Maïto 
23226f19c83bSHermès Bélusca-Maïto             if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
23236f19c83bSHermès Bélusca-Maïto             {
23246f19c83bSHermès Bélusca-Maïto                 DPRINT1("Updating primary partition entry %lu\n", Index);
23256f19c83bSHermès Bélusca-Maïto 
23266f19c83bSHermès Bélusca-Maïto                 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
23276f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
23286f19c83bSHermès Bélusca-Maïto                 PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart;
2329*7df92966SHermès Bélusca-Maïto                 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
23306f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionType = PartEntry->PartitionType;
23316f19c83bSHermès Bélusca-Maïto                 PartitionInfo->BootIndicator = PartEntry->BootIndicator;
2332*7df92966SHermès Bélusca-Maïto                 PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
23336f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RewritePartition = TRUE;
23346f19c83bSHermès Bélusca-Maïto             }
23356f19c83bSHermès Bélusca-Maïto 
23366f19c83bSHermès Bélusca-Maïto             if (!IsContainerPartition(PartEntry->PartitionType))
23376f19c83bSHermès Bélusca-Maïto                 PartitionNumber++;
23386f19c83bSHermès Bélusca-Maïto 
23396f19c83bSHermès Bélusca-Maïto             Index++;
23406f19c83bSHermès Bélusca-Maïto         }
23416f19c83bSHermès Bélusca-Maïto 
23426f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
23436f19c83bSHermès Bélusca-Maïto     }
23446f19c83bSHermès Bélusca-Maïto 
234570fa2e2eSHermès Bélusca-Maïto     ASSERT(Index <= 4);
234670fa2e2eSHermès Bélusca-Maïto 
23476f19c83bSHermès Bélusca-Maïto     /* Update the logical partition table */
23486f19c83bSHermès Bélusca-Maïto     Index = 4;
23496f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->LogicalPartListHead.Flink;
23506f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->LogicalPartListHead)
23516f19c83bSHermès Bélusca-Maïto     {
23526f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
23536f19c83bSHermès Bélusca-Maïto 
23546f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
23556f19c83bSHermès Bélusca-Maïto         {
23566f19c83bSHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
2357*7df92966SHermès Bélusca-Maïto             PartEntry->PartitionIndex = Index;
23586f19c83bSHermès Bélusca-Maïto 
23596f19c83bSHermès Bélusca-Maïto             DPRINT1("Updating logical partition entry %lu\n", Index);
23606f19c83bSHermès Bélusca-Maïto 
2361*7df92966SHermès Bélusca-Maïto             /* Reset the current partition number only for newly-created partitions */
2362*7df92966SHermès Bélusca-Maïto             if (PartEntry->New)
2363*7df92966SHermès Bélusca-Maïto                 PartEntry->PartitionNumber = 0;
2364*7df92966SHermès Bélusca-Maïto 
2365*7df92966SHermès Bélusca-Maïto             PartEntry->OnDiskPartitionNumber = PartitionNumber;
2366*7df92966SHermès Bélusca-Maïto 
23676f19c83bSHermès Bélusca-Maïto             PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
23686f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
23696f19c83bSHermès Bélusca-Maïto             PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment;
2370*7df92966SHermès Bélusca-Maïto             PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
23716f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionType = PartEntry->PartitionType;
23726f19c83bSHermès Bélusca-Maïto             PartitionInfo->BootIndicator = FALSE;
2373*7df92966SHermès Bélusca-Maïto             PartitionInfo->RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
23746f19c83bSHermès Bélusca-Maïto             PartitionInfo->RewritePartition = TRUE;
23756f19c83bSHermès Bélusca-Maïto 
23766f19c83bSHermès Bélusca-Maïto             /* Fill the link entry of the previous partition entry */
23776f19c83bSHermès Bélusca-Maïto             if (LinkInfo != NULL)
23786f19c83bSHermès Bélusca-Maïto             {
23796f19c83bSHermès Bélusca-Maïto                 LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
23806f19c83bSHermès Bélusca-Maïto                 LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
23816f19c83bSHermès Bélusca-Maïto                 HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
23826f19c83bSHermès Bélusca-Maïto                 LinkInfo->HiddenSectors = HiddenSectors64.LowPart;
23836f19c83bSHermès Bélusca-Maïto                 LinkInfo->PartitionNumber = 0;
23846f19c83bSHermès Bélusca-Maïto                 LinkInfo->PartitionType = PARTITION_EXTENDED;
23856f19c83bSHermès Bélusca-Maïto                 LinkInfo->BootIndicator = FALSE;
23866f19c83bSHermès Bélusca-Maïto                 LinkInfo->RecognizedPartition = FALSE;
23876f19c83bSHermès Bélusca-Maïto                 LinkInfo->RewritePartition = TRUE;
23886f19c83bSHermès Bélusca-Maïto             }
23896f19c83bSHermès Bélusca-Maïto 
23906f19c83bSHermès Bélusca-Maïto             /* Save a pointer to the link entry of the current partition entry */
23916f19c83bSHermès Bélusca-Maïto             LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
23926f19c83bSHermès Bélusca-Maïto 
23936f19c83bSHermès Bélusca-Maïto             PartitionNumber++;
23946f19c83bSHermès Bélusca-Maïto             Index += 4;
23956f19c83bSHermès Bélusca-Maïto         }
23966f19c83bSHermès Bélusca-Maïto 
23976f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
23986f19c83bSHermès Bélusca-Maïto     }
23996f19c83bSHermès Bélusca-Maïto 
24006f19c83bSHermès Bélusca-Maïto     /* Wipe unused primary partition entries */
24016f19c83bSHermès Bélusca-Maïto     for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
24026f19c83bSHermès Bélusca-Maïto     {
24036f19c83bSHermès Bélusca-Maïto         DPRINT1("Primary partition entry %lu\n", Index);
24046f19c83bSHermès Bélusca-Maïto 
24056f19c83bSHermès Bélusca-Maïto         PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
24066f19c83bSHermès Bélusca-Maïto 
24076f19c83bSHermès Bélusca-Maïto         if (!IsEmptyLayoutEntry(PartitionInfo))
24086f19c83bSHermès Bélusca-Maïto         {
24096f19c83bSHermès Bélusca-Maïto             DPRINT1("Wiping primary partition entry %lu\n", Index);
24106f19c83bSHermès Bélusca-Maïto 
24116f19c83bSHermès Bélusca-Maïto             PartitionInfo->StartingOffset.QuadPart = 0;
24126f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionLength.QuadPart = 0;
24136f19c83bSHermès Bélusca-Maïto             PartitionInfo->HiddenSectors = 0;
24146f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionNumber = 0;
24156f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
24166f19c83bSHermès Bélusca-Maïto             PartitionInfo->BootIndicator = FALSE;
24176f19c83bSHermès Bélusca-Maïto             PartitionInfo->RecognizedPartition = FALSE;
24186f19c83bSHermès Bélusca-Maïto             PartitionInfo->RewritePartition = TRUE;
24196f19c83bSHermès Bélusca-Maïto         }
24206f19c83bSHermès Bélusca-Maïto     }
24216f19c83bSHermès Bélusca-Maïto 
24226f19c83bSHermès Bélusca-Maïto     /* Wipe unused logical partition entries */
24236f19c83bSHermès Bélusca-Maïto     for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
24246f19c83bSHermès Bélusca-Maïto     {
24256f19c83bSHermès Bélusca-Maïto         if (Index % 4 >= 2)
24266f19c83bSHermès Bélusca-Maïto         {
24276f19c83bSHermès Bélusca-Maïto             DPRINT1("Logical partition entry %lu\n", Index);
24286f19c83bSHermès Bélusca-Maïto 
24296f19c83bSHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
24306f19c83bSHermès Bélusca-Maïto 
24316f19c83bSHermès Bélusca-Maïto             if (!IsEmptyLayoutEntry(PartitionInfo))
24326f19c83bSHermès Bélusca-Maïto             {
24336f19c83bSHermès Bélusca-Maïto                 DPRINT1("Wiping partition entry %lu\n", Index);
24346f19c83bSHermès Bélusca-Maïto 
24356f19c83bSHermès Bélusca-Maïto                 PartitionInfo->StartingOffset.QuadPart = 0;
24366f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionLength.QuadPart = 0;
24376f19c83bSHermès Bélusca-Maïto                 PartitionInfo->HiddenSectors = 0;
24386f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionNumber = 0;
24396f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
24406f19c83bSHermès Bélusca-Maïto                 PartitionInfo->BootIndicator = FALSE;
24416f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RecognizedPartition = FALSE;
24426f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RewritePartition = TRUE;
24436f19c83bSHermès Bélusca-Maïto             }
24446f19c83bSHermès Bélusca-Maïto         }
24456f19c83bSHermès Bélusca-Maïto     }
24466f19c83bSHermès Bélusca-Maïto 
2447*7df92966SHermès Bélusca-Maïto     DiskEntry->Dirty = TRUE;
2448*7df92966SHermès Bélusca-Maïto 
24496f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
24506f19c83bSHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
24516f19c83bSHermès Bélusca-Maïto #endif
24526f19c83bSHermès Bélusca-Maïto }
24536f19c83bSHermès Bélusca-Maïto 
24546f19c83bSHermès Bélusca-Maïto static
24556f19c83bSHermès Bélusca-Maïto PPARTENTRY
24566f19c83bSHermès Bélusca-Maïto GetPrevUnpartitionedEntry(
24576f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
24586f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
24596f19c83bSHermès Bélusca-Maïto {
24606f19c83bSHermès Bélusca-Maïto     PPARTENTRY PrevPartEntry;
24616f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListHead;
24626f19c83bSHermès Bélusca-Maïto 
24636f19c83bSHermès Bélusca-Maïto     if (PartEntry->LogicalPartition)
24646f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->LogicalPartListHead;
24656f19c83bSHermès Bélusca-Maïto     else
24666f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->PrimaryPartListHead;
24676f19c83bSHermès Bélusca-Maïto 
24686f19c83bSHermès Bélusca-Maïto     if (PartEntry->ListEntry.Blink != ListHead)
24696f19c83bSHermès Bélusca-Maïto     {
24706f19c83bSHermès Bélusca-Maïto         PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
24716f19c83bSHermès Bélusca-Maïto                                           PARTENTRY,
24726f19c83bSHermès Bélusca-Maïto                                           ListEntry);
24736f19c83bSHermès Bélusca-Maïto         if (PrevPartEntry->IsPartitioned == FALSE)
24746f19c83bSHermès Bélusca-Maïto             return PrevPartEntry;
24756f19c83bSHermès Bélusca-Maïto     }
24766f19c83bSHermès Bélusca-Maïto 
24776f19c83bSHermès Bélusca-Maïto     return NULL;
24786f19c83bSHermès Bélusca-Maïto }
24796f19c83bSHermès Bélusca-Maïto 
24806f19c83bSHermès Bélusca-Maïto static
24816f19c83bSHermès Bélusca-Maïto PPARTENTRY
24826f19c83bSHermès Bélusca-Maïto GetNextUnpartitionedEntry(
24836f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
24846f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
24856f19c83bSHermès Bélusca-Maïto {
24866f19c83bSHermès Bélusca-Maïto     PPARTENTRY NextPartEntry;
24876f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListHead;
24886f19c83bSHermès Bélusca-Maïto 
24896f19c83bSHermès Bélusca-Maïto     if (PartEntry->LogicalPartition)
24906f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->LogicalPartListHead;
24916f19c83bSHermès Bélusca-Maïto     else
24926f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->PrimaryPartListHead;
24936f19c83bSHermès Bélusca-Maïto 
24946f19c83bSHermès Bélusca-Maïto     if (PartEntry->ListEntry.Flink != ListHead)
24956f19c83bSHermès Bélusca-Maïto     {
24966f19c83bSHermès Bélusca-Maïto         NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
24976f19c83bSHermès Bélusca-Maïto                                           PARTENTRY,
24986f19c83bSHermès Bélusca-Maïto                                           ListEntry);
24996f19c83bSHermès Bélusca-Maïto         if (NextPartEntry->IsPartitioned == FALSE)
25006f19c83bSHermès Bélusca-Maïto             return NextPartEntry;
25016f19c83bSHermès Bélusca-Maïto     }
25026f19c83bSHermès Bélusca-Maïto 
25036f19c83bSHermès Bélusca-Maïto     return NULL;
25046f19c83bSHermès Bélusca-Maïto }
25056f19c83bSHermès Bélusca-Maïto 
250670fa2e2eSHermès Bélusca-Maïto BOOLEAN
25076f19c83bSHermès Bélusca-Maïto CreatePrimaryPartition(
25086f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
25096f19c83bSHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
25106f19c83bSHermès Bélusca-Maïto     IN BOOLEAN AutoCreate)
25116f19c83bSHermès Bélusca-Maïto {
251270fa2e2eSHermès Bélusca-Maïto     ERROR_NUMBER Error;
25136f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
25146f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
25156f19c83bSHermès Bélusca-Maïto 
25166f19c83bSHermès Bélusca-Maïto     DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
25176f19c83bSHermès Bélusca-Maïto 
25186f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
25196f19c83bSHermès Bélusca-Maïto         List->CurrentDisk == NULL ||
25206f19c83bSHermès Bélusca-Maïto         List->CurrentPartition == NULL ||
252170fa2e2eSHermès Bélusca-Maïto         List->CurrentPartition->IsPartitioned)
25226f19c83bSHermès Bélusca-Maïto     {
252370fa2e2eSHermès Bélusca-Maïto         return FALSE;
252470fa2e2eSHermès Bélusca-Maïto     }
252570fa2e2eSHermès Bélusca-Maïto 
252670fa2e2eSHermès Bélusca-Maïto     Error = PrimaryPartitionCreationChecks(List);
252770fa2e2eSHermès Bélusca-Maïto     if (Error != NOT_AN_ERROR)
252870fa2e2eSHermès Bélusca-Maïto     {
252970fa2e2eSHermès Bélusca-Maïto         DPRINT1("PrimaryPartitionCreationChecks() failed with error %lu\n", Error);
253070fa2e2eSHermès Bélusca-Maïto         return FALSE;
25316f19c83bSHermès Bélusca-Maïto     }
25326f19c83bSHermès Bélusca-Maïto 
25336f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
25346f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
25356f19c83bSHermès Bélusca-Maïto 
2536*7df92966SHermès Bélusca-Maïto     /* Convert the current entry, or insert and initialize a new partition entry */
2537*7df92966SHermès Bélusca-Maïto     PartEntry = InitializePartitionEntry(DiskEntry, PartEntry, SectorCount, AutoCreate);
2538*7df92966SHermès Bélusca-Maïto     if (PartEntry == NULL)
253970fa2e2eSHermès Bélusca-Maïto         return FALSE;
25406f19c83bSHermès Bélusca-Maïto 
25416f19c83bSHermès Bélusca-Maïto     UpdateDiskLayout(DiskEntry);
25426f19c83bSHermès Bélusca-Maïto 
25436f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
254470fa2e2eSHermès Bélusca-Maïto 
254570fa2e2eSHermès Bélusca-Maïto     return TRUE;
25466f19c83bSHermès Bélusca-Maïto }
25476f19c83bSHermès Bélusca-Maïto 
25486f19c83bSHermès Bélusca-Maïto static
25496f19c83bSHermès Bélusca-Maïto VOID
25506f19c83bSHermès Bélusca-Maïto AddLogicalDiskSpace(
25516f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
25526f19c83bSHermès Bélusca-Maïto {
2553*7df92966SHermès Bélusca-Maïto     ULONGLONG StartSector;
2554*7df92966SHermès Bélusca-Maïto     ULONGLONG SectorCount;
25556f19c83bSHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
25566f19c83bSHermès Bélusca-Maïto 
25576f19c83bSHermès Bélusca-Maïto     DPRINT1("AddLogicalDiskSpace()\n");
25586f19c83bSHermès Bélusca-Maïto 
25596f19c83bSHermès Bélusca-Maïto     /* Create a partition entry that represents the empty space in the container partition */
2560*7df92966SHermès Bélusca-Maïto 
2561*7df92966SHermès Bélusca-Maïto     StartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
2562*7df92966SHermès Bélusca-Maïto     SectorCount = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
2563*7df92966SHermès Bélusca-Maïto 
2564*7df92966SHermès Bélusca-Maïto     NewPartEntry = CreateInsertBlankRegion(DiskEntry,
2565*7df92966SHermès Bélusca-Maïto                                            &DiskEntry->LogicalPartListHead,
2566*7df92966SHermès Bélusca-Maïto                                            StartSector,
2567*7df92966SHermès Bélusca-Maïto                                            SectorCount,
2568*7df92966SHermès Bélusca-Maïto                                            TRUE);
25696f19c83bSHermès Bélusca-Maïto     if (NewPartEntry == NULL)
2570*7df92966SHermès Bélusca-Maïto     {
2571*7df92966SHermès Bélusca-Maïto         DPRINT1("Failed to create a new empty region for extended partition space!\n");
25726f19c83bSHermès Bélusca-Maïto         return;
2573*7df92966SHermès Bélusca-Maïto     }
25746f19c83bSHermès Bélusca-Maïto     NewPartEntry->LogicalPartition = TRUE;
25756f19c83bSHermès Bélusca-Maïto }
25766f19c83bSHermès Bélusca-Maïto 
257770fa2e2eSHermès Bélusca-Maïto BOOLEAN
25786f19c83bSHermès Bélusca-Maïto CreateExtendedPartition(
25796f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
25806f19c83bSHermès Bélusca-Maïto     IN ULONGLONG SectorCount)
25816f19c83bSHermès Bélusca-Maïto {
258270fa2e2eSHermès Bélusca-Maïto     ERROR_NUMBER Error;
25836f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
25846f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
25856f19c83bSHermès Bélusca-Maïto 
25866f19c83bSHermès Bélusca-Maïto     DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
25876f19c83bSHermès Bélusca-Maïto 
25886f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
25896f19c83bSHermès Bélusca-Maïto         List->CurrentDisk == NULL ||
25906f19c83bSHermès Bélusca-Maïto         List->CurrentPartition == NULL ||
259170fa2e2eSHermès Bélusca-Maïto         List->CurrentPartition->IsPartitioned)
25926f19c83bSHermès Bélusca-Maïto     {
259370fa2e2eSHermès Bélusca-Maïto         return FALSE;
259470fa2e2eSHermès Bélusca-Maïto     }
259570fa2e2eSHermès Bélusca-Maïto 
259670fa2e2eSHermès Bélusca-Maïto     Error = ExtendedPartitionCreationChecks(List);
259770fa2e2eSHermès Bélusca-Maïto     if (Error != NOT_AN_ERROR)
259870fa2e2eSHermès Bélusca-Maïto     {
259970fa2e2eSHermès Bélusca-Maïto         DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
260070fa2e2eSHermès Bélusca-Maïto         return FALSE;
26016f19c83bSHermès Bélusca-Maïto     }
26026f19c83bSHermès Bélusca-Maïto 
26036f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
26046f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
26056f19c83bSHermès Bélusca-Maïto 
2606*7df92966SHermès Bélusca-Maïto     /* Convert the current entry, or insert and initialize a new partition entry */
2607*7df92966SHermès Bélusca-Maïto     PartEntry = InitializePartitionEntry(DiskEntry, PartEntry, SectorCount, FALSE);
2608*7df92966SHermès Bélusca-Maïto     if (PartEntry == NULL)
2609*7df92966SHermès Bélusca-Maïto         return FALSE;
26106f19c83bSHermès Bélusca-Maïto 
26116f19c83bSHermès Bélusca-Maïto     if (PartEntry->StartSector.QuadPart < 1450560)
26126f19c83bSHermès Bélusca-Maïto     {
26136f19c83bSHermès Bélusca-Maïto         /* Partition starts below the 8.4GB boundary ==> CHS partition */
26146f19c83bSHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_EXTENDED;
26156f19c83bSHermès Bélusca-Maïto     }
26166f19c83bSHermès Bélusca-Maïto     else
26176f19c83bSHermès Bélusca-Maïto     {
26186f19c83bSHermès Bélusca-Maïto         /* Partition starts above the 8.4GB boundary ==> LBA partition */
26196f19c83bSHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
26206f19c83bSHermès Bélusca-Maïto     }
26216f19c83bSHermès Bélusca-Maïto 
2622*7df92966SHermès Bélusca-Maïto     // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
2623*7df92966SHermès Bélusca-Maïto     PartEntry->New = FALSE;
2624*7df92966SHermès Bélusca-Maïto     PartEntry->FormatState = Formatted;
2625*7df92966SHermès Bélusca-Maïto 
26266f19c83bSHermès Bélusca-Maïto     DiskEntry->ExtendedPartition = PartEntry;
26276f19c83bSHermès Bélusca-Maïto 
26286f19c83bSHermès Bélusca-Maïto     AddLogicalDiskSpace(DiskEntry);
26296f19c83bSHermès Bélusca-Maïto 
26306f19c83bSHermès Bélusca-Maïto     UpdateDiskLayout(DiskEntry);
26316f19c83bSHermès Bélusca-Maïto 
26326f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
263370fa2e2eSHermès Bélusca-Maïto 
263470fa2e2eSHermès Bélusca-Maïto     return TRUE;
26356f19c83bSHermès Bélusca-Maïto }
26366f19c83bSHermès Bélusca-Maïto 
263770fa2e2eSHermès Bélusca-Maïto BOOLEAN
26386f19c83bSHermès Bélusca-Maïto CreateLogicalPartition(
26396f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
26406f19c83bSHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
26416f19c83bSHermès Bélusca-Maïto     IN BOOLEAN AutoCreate)
26426f19c83bSHermès Bélusca-Maïto {
264370fa2e2eSHermès Bélusca-Maïto     ERROR_NUMBER Error;
26446f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
26456f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
26466f19c83bSHermès Bélusca-Maïto 
26476f19c83bSHermès Bélusca-Maïto     DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
26486f19c83bSHermès Bélusca-Maïto 
26496f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
26506f19c83bSHermès Bélusca-Maïto         List->CurrentDisk == NULL ||
26516f19c83bSHermès Bélusca-Maïto         List->CurrentPartition == NULL ||
265270fa2e2eSHermès Bélusca-Maïto         List->CurrentPartition->IsPartitioned)
26536f19c83bSHermès Bélusca-Maïto     {
265470fa2e2eSHermès Bélusca-Maïto         return FALSE;
265570fa2e2eSHermès Bélusca-Maïto     }
265670fa2e2eSHermès Bélusca-Maïto 
265770fa2e2eSHermès Bélusca-Maïto     Error = LogicalPartitionCreationChecks(List);
265870fa2e2eSHermès Bélusca-Maïto     if (Error != NOT_AN_ERROR)
265970fa2e2eSHermès Bélusca-Maïto     {
266070fa2e2eSHermès Bélusca-Maïto         DPRINT1("LogicalPartitionCreationChecks() failed with error %lu\n", Error);
266170fa2e2eSHermès Bélusca-Maïto         return FALSE;
26626f19c83bSHermès Bélusca-Maïto     }
26636f19c83bSHermès Bélusca-Maïto 
26646f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
26656f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
26666f19c83bSHermès Bélusca-Maïto 
2667*7df92966SHermès Bélusca-Maïto     /* Convert the current entry, or insert and initialize a new partition entry */
2668*7df92966SHermès Bélusca-Maïto     PartEntry = InitializePartitionEntry(DiskEntry, PartEntry, SectorCount, AutoCreate);
2669*7df92966SHermès Bélusca-Maïto     if (PartEntry == NULL)
267070fa2e2eSHermès Bélusca-Maïto         return FALSE;
26716f19c83bSHermès Bélusca-Maïto 
2672*7df92966SHermès Bélusca-Maïto     PartEntry->LogicalPartition = TRUE;
26736f19c83bSHermès Bélusca-Maïto 
26746f19c83bSHermès Bélusca-Maïto     UpdateDiskLayout(DiskEntry);
26756f19c83bSHermès Bélusca-Maïto 
26766f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
267770fa2e2eSHermès Bélusca-Maïto 
267870fa2e2eSHermès Bélusca-Maïto     return TRUE;
26796f19c83bSHermès Bélusca-Maïto }
26806f19c83bSHermès Bélusca-Maïto 
26819504a38fSHermès Bélusca-Maïto static
26829504a38fSHermès Bélusca-Maïto NTSTATUS
26839504a38fSHermès Bélusca-Maïto DismountVolume(
26849504a38fSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
26859504a38fSHermès Bélusca-Maïto {
26869504a38fSHermès Bélusca-Maïto     NTSTATUS Status;
26879504a38fSHermès Bélusca-Maïto     NTSTATUS LockStatus;
26889504a38fSHermès Bélusca-Maïto     UNICODE_STRING Name;
26899504a38fSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
26909504a38fSHermès Bélusca-Maïto     IO_STATUS_BLOCK IoStatusBlock;
26919504a38fSHermès Bélusca-Maïto     HANDLE PartitionHandle;
26929504a38fSHermès Bélusca-Maïto     WCHAR Buffer[MAX_PATH];
26939504a38fSHermès Bélusca-Maïto 
26949504a38fSHermès Bélusca-Maïto     /* Check whether the partition is valid and may have been mounted in the system */
26959504a38fSHermès Bélusca-Maïto     if (!PartEntry->IsPartitioned ||
26969504a38fSHermès Bélusca-Maïto         PartEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
26979504a38fSHermès Bélusca-Maïto         IsContainerPartition(PartEntry->PartitionType)     ||
26989504a38fSHermès Bélusca-Maïto         !IsRecognizedPartition(PartEntry->PartitionType)   ||
26999504a38fSHermès Bélusca-Maïto         PartEntry->FormatState == Unformatted /* || PartEntry->FormatState == UnknownFormat */ ||
27009504a38fSHermès Bélusca-Maïto         PartEntry->FileSystem == NULL ||
27019504a38fSHermès Bélusca-Maïto         PartEntry->PartitionNumber == 0)
27029504a38fSHermès Bélusca-Maïto     {
27039504a38fSHermès Bélusca-Maïto         /* The partition is not mounted, so just return success */
27049504a38fSHermès Bélusca-Maïto         return STATUS_SUCCESS;
27059504a38fSHermès Bélusca-Maïto     }
27069504a38fSHermès Bélusca-Maïto 
27079504a38fSHermès Bélusca-Maïto     /* Open the volume */
27089504a38fSHermès Bélusca-Maïto     RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
27099504a38fSHermès Bélusca-Maïto                         L"\\Device\\Harddisk%lu\\Partition%lu",
27109504a38fSHermès Bélusca-Maïto                         PartEntry->DiskEntry->DiskNumber,
27119504a38fSHermès Bélusca-Maïto                         PartEntry->PartitionNumber);
27129504a38fSHermès Bélusca-Maïto     RtlInitUnicodeString(&Name, Buffer);
27139504a38fSHermès Bélusca-Maïto 
27149504a38fSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
27159504a38fSHermès Bélusca-Maïto                                &Name,
27169504a38fSHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
27179504a38fSHermès Bélusca-Maïto                                NULL,
27189504a38fSHermès Bélusca-Maïto                                NULL);
27199504a38fSHermès Bélusca-Maïto 
27209504a38fSHermès Bélusca-Maïto     Status = NtOpenFile(&PartitionHandle,
27219504a38fSHermès Bélusca-Maïto                         GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
27229504a38fSHermès Bélusca-Maïto                         &ObjectAttributes,
27239504a38fSHermès Bélusca-Maïto                         &IoStatusBlock,
27249504a38fSHermès Bélusca-Maïto                         FILE_SHARE_READ | FILE_SHARE_WRITE,
27259504a38fSHermès Bélusca-Maïto                         FILE_SYNCHRONOUS_IO_NONALERT);
27269504a38fSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
27279504a38fSHermès Bélusca-Maïto     {
27289504a38fSHermès Bélusca-Maïto         DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
27299504a38fSHermès Bélusca-Maïto         return Status;
27309504a38fSHermès Bélusca-Maïto     }
27319504a38fSHermès Bélusca-Maïto 
27329504a38fSHermès Bélusca-Maïto     /* Lock the volume */
27339504a38fSHermès Bélusca-Maïto     LockStatus = NtFsControlFile(PartitionHandle,
27349504a38fSHermès Bélusca-Maïto                                  NULL,
27359504a38fSHermès Bélusca-Maïto                                  NULL,
27369504a38fSHermès Bélusca-Maïto                                  NULL,
27379504a38fSHermès Bélusca-Maïto                                  &IoStatusBlock,
27389504a38fSHermès Bélusca-Maïto                                  FSCTL_LOCK_VOLUME,
27399504a38fSHermès Bélusca-Maïto                                  NULL,
27409504a38fSHermès Bélusca-Maïto                                  0,
27419504a38fSHermès Bélusca-Maïto                                  NULL,
27429504a38fSHermès Bélusca-Maïto                                  0);
27439504a38fSHermès Bélusca-Maïto     if (!NT_SUCCESS(LockStatus))
27449504a38fSHermès Bélusca-Maïto     {
27459504a38fSHermès Bélusca-Maïto         DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
27469504a38fSHermès Bélusca-Maïto     }
27479504a38fSHermès Bélusca-Maïto 
27489504a38fSHermès Bélusca-Maïto     /* Dismount the volume */
27499504a38fSHermès Bélusca-Maïto     Status = NtFsControlFile(PartitionHandle,
27509504a38fSHermès Bélusca-Maïto                              NULL,
27519504a38fSHermès Bélusca-Maïto                              NULL,
27529504a38fSHermès Bélusca-Maïto                              NULL,
27539504a38fSHermès Bélusca-Maïto                              &IoStatusBlock,
27549504a38fSHermès Bélusca-Maïto                              FSCTL_DISMOUNT_VOLUME,
27559504a38fSHermès Bélusca-Maïto                              NULL,
27569504a38fSHermès Bélusca-Maïto                              0,
27579504a38fSHermès Bélusca-Maïto                              NULL,
27589504a38fSHermès Bélusca-Maïto                              0);
27599504a38fSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
27609504a38fSHermès Bélusca-Maïto     {
27619504a38fSHermès Bélusca-Maïto         DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
27629504a38fSHermès Bélusca-Maïto     }
27639504a38fSHermès Bélusca-Maïto 
27649504a38fSHermès Bélusca-Maïto     /* Unlock the volume */
27659504a38fSHermès Bélusca-Maïto     LockStatus = NtFsControlFile(PartitionHandle,
27669504a38fSHermès Bélusca-Maïto                                  NULL,
27679504a38fSHermès Bélusca-Maïto                                  NULL,
27689504a38fSHermès Bélusca-Maïto                                  NULL,
27699504a38fSHermès Bélusca-Maïto                                  &IoStatusBlock,
27709504a38fSHermès Bélusca-Maïto                                  FSCTL_UNLOCK_VOLUME,
27719504a38fSHermès Bélusca-Maïto                                  NULL,
27729504a38fSHermès Bélusca-Maïto                                  0,
27739504a38fSHermès Bélusca-Maïto                                  NULL,
27749504a38fSHermès Bélusca-Maïto                                  0);
27759504a38fSHermès Bélusca-Maïto     if (!NT_SUCCESS(LockStatus))
27769504a38fSHermès Bélusca-Maïto     {
27779504a38fSHermès Bélusca-Maïto         DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
27789504a38fSHermès Bélusca-Maïto     }
27799504a38fSHermès Bélusca-Maïto 
27809504a38fSHermès Bélusca-Maïto     /* Close the volume */
27819504a38fSHermès Bélusca-Maïto     NtClose(PartitionHandle);
27829504a38fSHermès Bélusca-Maïto 
27839504a38fSHermès Bélusca-Maïto     return Status;
27849504a38fSHermès Bélusca-Maïto }
27859504a38fSHermès Bélusca-Maïto 
27866f19c83bSHermès Bélusca-Maïto VOID
27876f19c83bSHermès Bélusca-Maïto DeleteCurrentPartition(
27886f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
27896f19c83bSHermès Bélusca-Maïto {
27906f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
27916f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
27926f19c83bSHermès Bélusca-Maïto     PPARTENTRY PrevPartEntry;
27936f19c83bSHermès Bélusca-Maïto     PPARTENTRY NextPartEntry;
27946f19c83bSHermès Bélusca-Maïto     PPARTENTRY LogicalPartEntry;
27956f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
27966f19c83bSHermès Bélusca-Maïto 
27976f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
27986f19c83bSHermès Bélusca-Maïto         List->CurrentDisk == NULL ||
27996f19c83bSHermès Bélusca-Maïto         List->CurrentPartition == NULL ||
28006f19c83bSHermès Bélusca-Maïto         List->CurrentPartition->IsPartitioned == FALSE)
28016f19c83bSHermès Bélusca-Maïto     {
28026f19c83bSHermès Bélusca-Maïto         return;
28036f19c83bSHermès Bélusca-Maïto     }
28046f19c83bSHermès Bélusca-Maïto 
28056f19c83bSHermès Bélusca-Maïto     /* Clear the system disk and partition pointers if the system partition is being deleted */
28066f19c83bSHermès Bélusca-Maïto     if (List->SystemPartition == List->CurrentPartition)
28076f19c83bSHermès Bélusca-Maïto     {
28086f19c83bSHermès Bélusca-Maïto         List->SystemPartition = NULL;
28096f19c83bSHermès Bélusca-Maïto     }
28106f19c83bSHermès Bélusca-Maïto 
28116f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
28126f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
28136f19c83bSHermès Bélusca-Maïto 
28149504a38fSHermès Bélusca-Maïto     /* Check which type of partition (primary/logical or extended) is being deleted */
28156f19c83bSHermès Bélusca-Maïto     if (DiskEntry->ExtendedPartition == PartEntry)
28166f19c83bSHermès Bélusca-Maïto     {
28179504a38fSHermès Bélusca-Maïto         /* An extended partition is being deleted: delete all logical partition entries */
28186f19c83bSHermès Bélusca-Maïto         while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
28196f19c83bSHermès Bélusca-Maïto         {
28206f19c83bSHermès Bélusca-Maïto             Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
28216f19c83bSHermès Bélusca-Maïto             LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
28226f19c83bSHermès Bélusca-Maïto 
28239504a38fSHermès Bélusca-Maïto             /* Dismount the logical partition */
28249504a38fSHermès Bélusca-Maïto             DismountVolume(LogicalPartEntry);
28259504a38fSHermès Bélusca-Maïto 
28269504a38fSHermès Bélusca-Maïto             /* Delete it */
28276f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
28286f19c83bSHermès Bélusca-Maïto         }
28296f19c83bSHermès Bélusca-Maïto 
28306f19c83bSHermès Bélusca-Maïto         DiskEntry->ExtendedPartition = NULL;
28316f19c83bSHermès Bélusca-Maïto     }
28329504a38fSHermès Bélusca-Maïto     else
28339504a38fSHermès Bélusca-Maïto     {
28349504a38fSHermès Bélusca-Maïto         /* A primary partition is being deleted: dismount it */
28359504a38fSHermès Bélusca-Maïto         DismountVolume(PartEntry);
28369504a38fSHermès Bélusca-Maïto     }
28376f19c83bSHermès Bélusca-Maïto 
28386f19c83bSHermès Bélusca-Maïto     /* Adjust unpartitioned disk space entries */
28396f19c83bSHermès Bélusca-Maïto 
28406f19c83bSHermès Bélusca-Maïto     /* Get pointer to previous and next unpartitioned entries */
28416f19c83bSHermès Bélusca-Maïto     PrevPartEntry = GetPrevUnpartitionedEntry(DiskEntry, PartEntry);
28426f19c83bSHermès Bélusca-Maïto     NextPartEntry = GetNextUnpartitionedEntry(DiskEntry, PartEntry);
28436f19c83bSHermès Bélusca-Maïto 
28446f19c83bSHermès Bélusca-Maïto     if (PrevPartEntry != NULL && NextPartEntry != NULL)
28456f19c83bSHermès Bélusca-Maïto     {
28466f19c83bSHermès Bélusca-Maïto         /* Merge previous, current and next unpartitioned entry */
28476f19c83bSHermès Bélusca-Maïto 
28486f19c83bSHermès Bélusca-Maïto         /* Adjust the previous entries length */
28496f19c83bSHermès Bélusca-Maïto         PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
28506f19c83bSHermès Bélusca-Maïto 
28516f19c83bSHermès Bélusca-Maïto         /* Remove the current entry */
28526f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&PartEntry->ListEntry);
28536f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, PartEntry);
28546f19c83bSHermès Bélusca-Maïto 
28556f19c83bSHermès Bélusca-Maïto         /* Remove the next entry */
28566f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&NextPartEntry->ListEntry);
28576f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
28586f19c83bSHermès Bélusca-Maïto 
28596f19c83bSHermès Bélusca-Maïto         /* Update current partition */
28606f19c83bSHermès Bélusca-Maïto         List->CurrentPartition = PrevPartEntry;
28616f19c83bSHermès Bélusca-Maïto     }
28626f19c83bSHermès Bélusca-Maïto     else if (PrevPartEntry != NULL && NextPartEntry == NULL)
28636f19c83bSHermès Bélusca-Maïto     {
28646f19c83bSHermès Bélusca-Maïto         /* Merge current and previous unpartitioned entry */
28656f19c83bSHermès Bélusca-Maïto 
28666f19c83bSHermès Bélusca-Maïto         /* Adjust the previous entries length */
28676f19c83bSHermès Bélusca-Maïto         PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
28686f19c83bSHermès Bélusca-Maïto 
28696f19c83bSHermès Bélusca-Maïto         /* Remove the current entry */
28706f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&PartEntry->ListEntry);
28716f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, PartEntry);
28726f19c83bSHermès Bélusca-Maïto 
28736f19c83bSHermès Bélusca-Maïto         /* Update current partition */
28746f19c83bSHermès Bélusca-Maïto         List->CurrentPartition = PrevPartEntry;
28756f19c83bSHermès Bélusca-Maïto     }
28766f19c83bSHermès Bélusca-Maïto     else if (PrevPartEntry == NULL && NextPartEntry != NULL)
28776f19c83bSHermès Bélusca-Maïto     {
28786f19c83bSHermès Bélusca-Maïto         /* Merge current and next unpartitioned entry */
28796f19c83bSHermès Bélusca-Maïto 
28806f19c83bSHermès Bélusca-Maïto         /* Adjust the next entries offset and length */
28816f19c83bSHermès Bélusca-Maïto         NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
28826f19c83bSHermès Bélusca-Maïto         NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
28836f19c83bSHermès Bélusca-Maïto 
28846f19c83bSHermès Bélusca-Maïto         /* Remove the current entry */
28856f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&PartEntry->ListEntry);
28866f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, PartEntry);
28876f19c83bSHermès Bélusca-Maïto 
28886f19c83bSHermès Bélusca-Maïto         /* Update current partition */
28896f19c83bSHermès Bélusca-Maïto         List->CurrentPartition = NextPartEntry;
28906f19c83bSHermès Bélusca-Maïto     }
28916f19c83bSHermès Bélusca-Maïto     else
28926f19c83bSHermès Bélusca-Maïto     {
28936f19c83bSHermès Bélusca-Maïto         /* Nothing to merge but change current entry */
28946f19c83bSHermès Bélusca-Maïto         PartEntry->IsPartitioned = FALSE;
28956f19c83bSHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
28966f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = Unformatted;
28976f19c83bSHermès Bélusca-Maïto         PartEntry->FileSystem  = NULL;
28986f19c83bSHermès Bélusca-Maïto         PartEntry->DriveLetter = 0;
2899*7df92966SHermès Bélusca-Maïto         PartEntry->OnDiskPartitionNumber = 0;
2900*7df92966SHermès Bélusca-Maïto         PartEntry->PartitionNumber = 0;
2901*7df92966SHermès Bélusca-Maïto         // PartEntry->PartitionIndex = 0;
29026f19c83bSHermès Bélusca-Maïto     }
29036f19c83bSHermès Bélusca-Maïto 
29046f19c83bSHermès Bélusca-Maïto     UpdateDiskLayout(DiskEntry);
29056f19c83bSHermès Bélusca-Maïto 
29066f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
29076f19c83bSHermès Bélusca-Maïto }
29086f19c83bSHermès Bélusca-Maïto 
29096f19c83bSHermès Bélusca-Maïto VOID
29106f19c83bSHermès Bélusca-Maïto CheckActiveSystemPartition(
29116f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
29126f19c83bSHermès Bélusca-Maïto {
29136f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
29146f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
29156f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
29166f19c83bSHermès Bélusca-Maïto 
29176f19c83bSHermès Bélusca-Maïto     PFILE_SYSTEM FileSystem;
29186f19c83bSHermès Bélusca-Maïto 
29196f19c83bSHermès Bélusca-Maïto     /* Check for empty disk list */
29206f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
29216f19c83bSHermès Bélusca-Maïto     {
29226f19c83bSHermès Bélusca-Maïto         List->SystemPartition = NULL;
29236f19c83bSHermès Bélusca-Maïto         List->OriginalSystemPartition = NULL;
29246f19c83bSHermès Bélusca-Maïto         return;
29256f19c83bSHermès Bélusca-Maïto     }
29266f19c83bSHermès Bélusca-Maïto 
29276f19c83bSHermès Bélusca-Maïto     /* Choose the currently selected disk */
29286f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
29296f19c83bSHermès Bélusca-Maïto 
29306f19c83bSHermès Bélusca-Maïto     /* Check for empty partition list */
29316f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
29326f19c83bSHermès Bélusca-Maïto     {
29336f19c83bSHermès Bélusca-Maïto         List->SystemPartition = NULL;
29346f19c83bSHermès Bélusca-Maïto         List->OriginalSystemPartition = NULL;
29356f19c83bSHermès Bélusca-Maïto         return;
29366f19c83bSHermès Bélusca-Maïto     }
29376f19c83bSHermès Bélusca-Maïto 
29386f19c83bSHermès Bélusca-Maïto     if (List->SystemPartition != NULL)
29396f19c83bSHermès Bélusca-Maïto     {
29406f19c83bSHermès Bélusca-Maïto         /* We already have an active system partition */
2941f41750abSHermès Bélusca-Maïto         DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n",
29426f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->PartitionNumber,
29436f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->DiskEntry->DiskNumber,
2944f41750abSHermès Bélusca-Maïto                 (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
29456f19c83bSHermès Bélusca-Maïto         return;
29466f19c83bSHermès Bélusca-Maïto     }
29476f19c83bSHermès Bélusca-Maïto 
29486f19c83bSHermès Bélusca-Maïto     DPRINT1("We are here (1)!\n");
29496f19c83bSHermès Bélusca-Maïto 
29506f19c83bSHermès Bélusca-Maïto     List->SystemPartition = NULL;
29516f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = NULL;
29526f19c83bSHermès Bélusca-Maïto 
29536f19c83bSHermès Bélusca-Maïto     /* Retrieve the first partition of the disk */
29546f19c83bSHermès Bélusca-Maïto     PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
29556f19c83bSHermès Bélusca-Maïto                                   PARTENTRY,
29566f19c83bSHermès Bélusca-Maïto                                   ListEntry);
29576f19c83bSHermès Bélusca-Maïto     ASSERT(DiskEntry == PartEntry->DiskEntry);
29586f19c83bSHermès Bélusca-Maïto     List->SystemPartition = PartEntry;
29596f19c83bSHermès Bélusca-Maïto 
29606f19c83bSHermès Bélusca-Maïto     //
29616f19c83bSHermè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
29626f19c83bSHermès Bélusca-Maïto     //
29636f19c83bSHermès Bélusca-Maïto 
29646f19c83bSHermès Bélusca-Maïto     /* Check if the disk is new and if so, use its first partition as the active system partition */
29656f19c83bSHermès Bélusca-Maïto     if (DiskEntry->NewDisk)
29666f19c83bSHermès Bélusca-Maïto     {
29676f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator == FALSE)
29686f19c83bSHermès Bélusca-Maïto         {
29696f19c83bSHermès Bélusca-Maïto             ASSERT(DiskEntry == PartEntry->DiskEntry);
29706f19c83bSHermès Bélusca-Maïto             List->SystemPartition = PartEntry;
29716f19c83bSHermès Bélusca-Maïto 
29726f19c83bSHermès Bélusca-Maïto             List->OriginalSystemPartition = List->SystemPartition;
29736f19c83bSHermès Bélusca-Maïto 
2974f41750abSHermès Bélusca-Maïto             DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
29756f19c83bSHermès Bélusca-Maïto                     List->SystemPartition->PartitionNumber,
29766f19c83bSHermès Bélusca-Maïto                     List->SystemPartition->DiskEntry->DiskNumber,
2977f41750abSHermès Bélusca-Maïto                     (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
29786f19c83bSHermès Bélusca-Maïto 
29796f19c83bSHermès Bélusca-Maïto             goto SetSystemPartition;
29806f19c83bSHermès Bélusca-Maïto         }
29816f19c83bSHermès Bélusca-Maïto 
29826f19c83bSHermès Bélusca-Maïto         // FIXME: What to do??
29836f19c83bSHermès Bélusca-Maïto         DPRINT1("NewDisk TRUE but first partition is used?\n");
29846f19c83bSHermès Bélusca-Maïto     }
29856f19c83bSHermès Bélusca-Maïto 
29866f19c83bSHermès Bélusca-Maïto     DPRINT1("We are here (2)!\n");
29876f19c83bSHermès Bélusca-Maïto 
29886f19c83bSHermès Bélusca-Maïto     /*
29896f19c83bSHermès Bélusca-Maïto      * The disk is not new, check if any partition is initialized;
29906f19c83bSHermès Bélusca-Maïto      * if not, the first one becomes the system partition.
29916f19c83bSHermès Bélusca-Maïto      */
29926f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->PrimaryPartListHead.Flink;
29936f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->PrimaryPartListHead)
29946f19c83bSHermès Bélusca-Maïto     {
29956f19c83bSHermès Bélusca-Maïto         /* Retrieve the partition and go to the next one */
29966f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry,
29976f19c83bSHermès Bélusca-Maïto                                       PARTENTRY,
29986f19c83bSHermès Bélusca-Maïto                                       ListEntry);
29996f19c83bSHermès Bélusca-Maïto 
30006f19c83bSHermès Bélusca-Maïto         /* Check if the partition is partitioned and is used */
30016f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator != FALSE)
30026f19c83bSHermès Bélusca-Maïto         {
30036f19c83bSHermès Bélusca-Maïto             break;
30046f19c83bSHermès Bélusca-Maïto         }
30056f19c83bSHermès Bélusca-Maïto 
30066f19c83bSHermès Bélusca-Maïto         /* Go to the next one */
30076f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
30086f19c83bSHermès Bélusca-Maïto     }
30096f19c83bSHermès Bélusca-Maïto     if (ListEntry == &DiskEntry->PrimaryPartListHead)
30106f19c83bSHermès Bélusca-Maïto     {
30116f19c83bSHermès Bélusca-Maïto         /*
30126f19c83bSHermès Bélusca-Maïto          * OK we haven't encountered any used and active partition,
30136f19c83bSHermès Bélusca-Maïto          * so use the first one as the system partition.
30146f19c83bSHermès Bélusca-Maïto          */
30156f19c83bSHermès Bélusca-Maïto         ASSERT(DiskEntry == List->SystemPartition->DiskEntry);
30166f19c83bSHermès Bélusca-Maïto         List->OriginalSystemPartition = List->SystemPartition; // First PartEntry
30176f19c83bSHermès Bélusca-Maïto 
3018f41750abSHermès Bélusca-Maïto         DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
30196f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->PartitionNumber,
30206f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->DiskEntry->DiskNumber,
3021f41750abSHermès Bélusca-Maïto                 (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
30226f19c83bSHermès Bélusca-Maïto 
30236f19c83bSHermès Bélusca-Maïto         goto SetSystemPartition;
30246f19c83bSHermès Bélusca-Maïto     }
30256f19c83bSHermès Bélusca-Maïto 
30266f19c83bSHermès Bélusca-Maïto     List->SystemPartition = NULL;
30276f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = NULL;
30286f19c83bSHermès Bélusca-Maïto 
30296f19c83bSHermès Bélusca-Maïto     DPRINT1("We are here (3)!\n");
30306f19c83bSHermès Bélusca-Maïto 
30316f19c83bSHermès Bélusca-Maïto     /* The disk is not new, scan all partitions to find the (active) system partition */
30326f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->PrimaryPartListHead.Flink;
30336f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->PrimaryPartListHead)
30346f19c83bSHermès Bélusca-Maïto     {
30356f19c83bSHermès Bélusca-Maïto         /* Retrieve the partition and go to the next one */
30366f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry,
30376f19c83bSHermès Bélusca-Maïto                                       PARTENTRY,
30386f19c83bSHermès Bélusca-Maïto                                       ListEntry);
30396f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
30406f19c83bSHermès Bélusca-Maïto 
30416f19c83bSHermès Bélusca-Maïto         /* Check if the partition is partitioned and used */
30426f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned &&
30436f19c83bSHermès Bélusca-Maïto             PartEntry->PartitionType != PARTITION_ENTRY_UNUSED)
30446f19c83bSHermès Bélusca-Maïto         {
30456f19c83bSHermès Bélusca-Maïto             /* Check if the partition is active */
30466f19c83bSHermès Bélusca-Maïto             if (PartEntry->BootIndicator)
30476f19c83bSHermès Bélusca-Maïto             {
30486f19c83bSHermès Bélusca-Maïto                 /* Yes, we found it */
30496f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
30506f19c83bSHermès Bélusca-Maïto                 List->SystemPartition = PartEntry;
30516f19c83bSHermès Bélusca-Maïto 
3052f41750abSHermès Bélusca-Maïto                 DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
30536f19c83bSHermès Bélusca-Maïto                         PartEntry->PartitionNumber,
30546f19c83bSHermès Bélusca-Maïto                         DiskEntry->DiskNumber,
3055f41750abSHermès Bélusca-Maïto                         (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
30566f19c83bSHermès Bélusca-Maïto                 break;
30576f19c83bSHermès Bélusca-Maïto             }
30586f19c83bSHermès Bélusca-Maïto         }
30596f19c83bSHermès Bélusca-Maïto     }
30606f19c83bSHermès Bélusca-Maïto 
30616f19c83bSHermès Bélusca-Maïto     /* Check if we have found the system partition */
30626f19c83bSHermès Bélusca-Maïto     if (List->SystemPartition == NULL)
30636f19c83bSHermès Bélusca-Maïto     {
30646f19c83bSHermès Bélusca-Maïto         /* Nothing, use the alternative system partition */
30656f19c83bSHermès Bélusca-Maïto         DPRINT1("No system partition found, use the alternative partition!\n");
30666f19c83bSHermès Bélusca-Maïto         goto UseAlternativeSystemPartition;
30676f19c83bSHermès Bélusca-Maïto     }
30686f19c83bSHermès Bélusca-Maïto 
30696f19c83bSHermès Bélusca-Maïto     /* Save it */
30706f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = List->SystemPartition;
30716f19c83bSHermès Bélusca-Maïto 
30726f19c83bSHermès Bélusca-Maïto     /*
30736f19c83bSHermès Bélusca-Maïto      * ADDITIONAL CHECKS / BIG HACK:
30746f19c83bSHermès Bélusca-Maïto      *
30756f19c83bSHermès Bélusca-Maïto      * Retrieve its file system and check whether we have
30766f19c83bSHermès Bélusca-Maïto      * write support for it. If that is the case we are fine
30776f19c83bSHermès Bélusca-Maïto      * and we can use it directly. However if we don't have
30786f19c83bSHermès Bélusca-Maïto      * write support we will need to change the active system
30796f19c83bSHermès Bélusca-Maïto      * partition.
30806f19c83bSHermès Bélusca-Maïto      *
30816f19c83bSHermès Bélusca-Maïto      * NOTE that this is completely useless on architectures
30826f19c83bSHermès Bélusca-Maïto      * where a real system partition is required, as on these
30836f19c83bSHermès Bélusca-Maïto      * architectures the partition uses the FAT FS, for which
30846f19c83bSHermès Bélusca-Maïto      * we do have write support.
30856f19c83bSHermès Bélusca-Maïto      * NOTE also that for those architectures looking for a
30866f19c83bSHermès Bélusca-Maïto      * partition boot indicator is insufficient.
30876f19c83bSHermès Bélusca-Maïto      */
30886f19c83bSHermès Bélusca-Maïto     FileSystem = GetFileSystem(List->OriginalSystemPartition);
30896f19c83bSHermès Bélusca-Maïto     if (FileSystem == NULL)
30906f19c83bSHermès Bélusca-Maïto     {
30916f19c83bSHermès Bélusca-Maïto         DPRINT1("System partition %lu in disk %lu with no FS?!\n",
30926f19c83bSHermès Bélusca-Maïto                 List->OriginalSystemPartition->PartitionNumber,
30936f19c83bSHermès Bélusca-Maïto                 List->OriginalSystemPartition->DiskEntry->DiskNumber);
30946f19c83bSHermès Bélusca-Maïto         goto FindAndUseAlternativeSystemPartition;
30956f19c83bSHermès Bélusca-Maïto     }
30966f19c83bSHermès Bélusca-Maïto     // HACK: WARNING: We cannot write on this FS yet!
30976f19c83bSHermès Bélusca-Maïto     // See fsutil.c:GetFileSystem()
30984c6370deSBișoc George     if (List->OriginalSystemPartition->PartitionType == PARTITION_IFS)
30996f19c83bSHermès Bélusca-Maïto     {
31006f19c83bSHermès Bélusca-Maïto         DPRINT1("Recognized file system %S that doesn't support write support yet!\n",
31016f19c83bSHermès Bélusca-Maïto                 FileSystem->FileSystemName);
31026f19c83bSHermès Bélusca-Maïto         goto FindAndUseAlternativeSystemPartition;
31036f19c83bSHermès Bélusca-Maïto     }
31046f19c83bSHermès Bélusca-Maïto 
3105f41750abSHermès Bélusca-Maïto     DPRINT1("Use existing active system partition %lu in disk %lu, drive letter %C\n",
31066f19c83bSHermès Bélusca-Maïto             List->SystemPartition->PartitionNumber,
31076f19c83bSHermès Bélusca-Maïto             List->SystemPartition->DiskEntry->DiskNumber,
3108f41750abSHermès Bélusca-Maïto             (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
31096f19c83bSHermès Bélusca-Maïto 
31106f19c83bSHermès Bélusca-Maïto     return;
31116f19c83bSHermès Bélusca-Maïto 
31126f19c83bSHermès Bélusca-Maïto FindAndUseAlternativeSystemPartition:
31136f19c83bSHermès Bélusca-Maïto     /*
31146f19c83bSHermès Bélusca-Maïto      * We are here because we have not found any (active) candidate
31156f19c83bSHermès Bélusca-Maïto      * system partition that we know how to support. What we are going
31166f19c83bSHermès Bélusca-Maïto      * to do is to change the existing system partition and use the
31176f19c83bSHermès Bélusca-Maïto      * partition on which we install ReactOS as the new system partition,
31186f19c83bSHermès Bélusca-Maïto      * and then we will need to add in FreeLdr's entry a boot entry to boot
31196f19c83bSHermès Bélusca-Maïto      * from the original system partition.
31206f19c83bSHermès Bélusca-Maïto      */
31216f19c83bSHermès Bélusca-Maïto 
31226f19c83bSHermès Bélusca-Maïto     /* Unset the old system partition */
31236f19c83bSHermès Bélusca-Maïto     List->SystemPartition->BootIndicator = FALSE;
31246f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = FALSE;
31256f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
31266f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->Dirty = TRUE;
31276f19c83bSHermès Bélusca-Maïto 
31286f19c83bSHermès Bélusca-Maïto UseAlternativeSystemPartition:
31296f19c83bSHermès Bélusca-Maïto     List->SystemPartition = List->CurrentPartition;
31306f19c83bSHermès Bélusca-Maïto 
3131f41750abSHermès Bélusca-Maïto     DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
31326f19c83bSHermès Bélusca-Maïto             List->SystemPartition->PartitionNumber,
31336f19c83bSHermès Bélusca-Maïto             List->SystemPartition->DiskEntry->DiskNumber,
3134f41750abSHermès Bélusca-Maïto             (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
31356f19c83bSHermès Bélusca-Maïto 
31366f19c83bSHermès Bélusca-Maïto SetSystemPartition:
31376f19c83bSHermès Bélusca-Maïto     /* Set the new active system partition */
31386f19c83bSHermès Bélusca-Maïto     List->SystemPartition->BootIndicator = TRUE;
31396f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = TRUE;
31406f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
31416f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->Dirty = TRUE;
31426f19c83bSHermès Bélusca-Maïto }
31436f19c83bSHermès Bélusca-Maïto 
31446f19c83bSHermès Bélusca-Maïto static
31456f19c83bSHermès Bélusca-Maïto NTSTATUS
31466f19c83bSHermès Bélusca-Maïto WritePartitions(
31476f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
31486f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
31496f19c83bSHermès Bélusca-Maïto {
31506f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
3151*7df92966SHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
3152*7df92966SHermès Bélusca-Maïto     UNICODE_STRING Name;
3153*7df92966SHermès Bélusca-Maïto     HANDLE FileHandle;
3154*7df92966SHermès Bélusca-Maïto     IO_STATUS_BLOCK Iosb;
3155*7df92966SHermès Bélusca-Maïto     ULONG BufferSize;
3156*7df92966SHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
3157*7df92966SHermès Bélusca-Maïto     ULONG PartitionCount;
3158*7df92966SHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
3159*7df92966SHermès Bélusca-Maïto     PPARTENTRY PartEntry;
3160*7df92966SHermès Bélusca-Maïto     WCHAR DstPath[MAX_PATH];
31616f19c83bSHermès Bélusca-Maïto 
31626f19c83bSHermès Bélusca-Maïto     DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
31636f19c83bSHermès Bélusca-Maïto 
31646f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
31656f19c83bSHermès Bélusca-Maïto                         L"\\Device\\Harddisk%lu\\Partition0",
31666f19c83bSHermès Bélusca-Maïto                         DiskEntry->DiskNumber);
31676f19c83bSHermès Bélusca-Maïto     RtlInitUnicodeString(&Name, DstPath);
3168765994c9SHermès Bélusca-Maïto 
31696f19c83bSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
31706f19c83bSHermès Bélusca-Maïto                                &Name,
3171765994c9SHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
31726f19c83bSHermès Bélusca-Maïto                                NULL,
31736f19c83bSHermès Bélusca-Maïto                                NULL);
31746f19c83bSHermès Bélusca-Maïto 
31756f19c83bSHermès Bélusca-Maïto     Status = NtOpenFile(&FileHandle,
31766f19c83bSHermès Bélusca-Maïto                         GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
31776f19c83bSHermès Bélusca-Maïto                         &ObjectAttributes,
31786f19c83bSHermès Bélusca-Maïto                         &Iosb,
31796f19c83bSHermès Bélusca-Maïto                         0,
31806f19c83bSHermès Bélusca-Maïto                         FILE_SYNCHRONOUS_IO_NONALERT);
31816f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
31826f19c83bSHermès Bélusca-Maïto     {
31836f19c83bSHermès Bélusca-Maïto         DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
31846f19c83bSHermès Bélusca-Maïto         return Status;
31856f19c83bSHermès Bélusca-Maïto     }
31866f19c83bSHermès Bélusca-Maïto 
31876f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
31886f19c83bSHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
31896f19c83bSHermès Bélusca-Maïto #endif
31906f19c83bSHermès Bélusca-Maïto 
3191f41750abSHermès Bélusca-Maïto     //
3192f41750abSHermès Bélusca-Maïto     // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3193f41750abSHermès Bélusca-Maïto     // the disk in MBR or GPT format in case the disk was not initialized!!
3194f41750abSHermès Bélusca-Maïto     // For this we must ask the user which format to use.
3195f41750abSHermès Bélusca-Maïto     //
3196f41750abSHermès Bélusca-Maïto 
3197*7df92966SHermès Bélusca-Maïto     /* Save the original partition count to be restored later (see comment below) */
3198*7df92966SHermès Bélusca-Maïto     PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
3199*7df92966SHermès Bélusca-Maïto 
3200*7df92966SHermès Bélusca-Maïto     /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
32016f19c83bSHermès Bélusca-Maïto     BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
3202*7df92966SHermès Bélusca-Maïto                  ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
32036f19c83bSHermès Bélusca-Maïto     Status = NtDeviceIoControlFile(FileHandle,
32046f19c83bSHermès Bélusca-Maïto                                    NULL,
32056f19c83bSHermès Bélusca-Maïto                                    NULL,
32066f19c83bSHermès Bélusca-Maïto                                    NULL,
32076f19c83bSHermès Bélusca-Maïto                                    &Iosb,
32086f19c83bSHermès Bélusca-Maïto                                    IOCTL_DISK_SET_DRIVE_LAYOUT,
32096f19c83bSHermès Bélusca-Maïto                                    DiskEntry->LayoutBuffer,
32106f19c83bSHermès Bélusca-Maïto                                    BufferSize,
3211*7df92966SHermès Bélusca-Maïto                                    DiskEntry->LayoutBuffer,
3212*7df92966SHermès Bélusca-Maïto                                    BufferSize);
3213*7df92966SHermès Bélusca-Maïto     NtClose(FileHandle);
3214*7df92966SHermès Bélusca-Maïto 
3215*7df92966SHermès Bélusca-Maïto     /*
3216*7df92966SHermès Bélusca-Maïto      * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
3217*7df92966SHermès Bélusca-Maïto      * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
3218*7df92966SHermès Bélusca-Maïto      * where such a table is expected to enumerate up to 4 partitions:
3219*7df92966SHermès Bélusca-Maïto      * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
3220*7df92966SHermès Bélusca-Maïto      * Due to this we need to restore the original PartitionCount number.
3221*7df92966SHermès Bélusca-Maïto      */
3222*7df92966SHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
3223*7df92966SHermès Bélusca-Maïto 
3224*7df92966SHermès Bélusca-Maïto     /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
32256f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
32266f19c83bSHermès Bélusca-Maïto     {
32276f19c83bSHermès Bélusca-Maïto         DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
3228*7df92966SHermès Bélusca-Maïto         return Status;
32296f19c83bSHermès Bélusca-Maïto     }
32306f19c83bSHermès Bélusca-Maïto 
3231*7df92966SHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
3232*7df92966SHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
3233*7df92966SHermès Bélusca-Maïto #endif
3234*7df92966SHermès Bélusca-Maïto 
3235*7df92966SHermès Bélusca-Maïto     /* Update the partition numbers */
3236*7df92966SHermès Bélusca-Maïto 
3237*7df92966SHermès Bélusca-Maïto     /* Update the primary partition table */
3238*7df92966SHermès Bélusca-Maïto     ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3239*7df92966SHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->PrimaryPartListHead)
3240*7df92966SHermès Bélusca-Maïto     {
3241*7df92966SHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3242*7df92966SHermès Bélusca-Maïto 
3243*7df92966SHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
3244*7df92966SHermès Bélusca-Maïto         {
3245*7df92966SHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3246*7df92966SHermès Bélusca-Maïto             PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3247*7df92966SHermès Bélusca-Maïto         }
3248*7df92966SHermès Bélusca-Maïto 
3249*7df92966SHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
3250*7df92966SHermès Bélusca-Maïto     }
3251*7df92966SHermès Bélusca-Maïto 
3252*7df92966SHermès Bélusca-Maïto     /* Update the logical partition table */
3253*7df92966SHermès Bélusca-Maïto     ListEntry = DiskEntry->LogicalPartListHead.Flink;
3254*7df92966SHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->LogicalPartListHead)
3255*7df92966SHermès Bélusca-Maïto     {
3256*7df92966SHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3257*7df92966SHermès Bélusca-Maïto 
3258*7df92966SHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
3259*7df92966SHermès Bélusca-Maïto         {
3260*7df92966SHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3261*7df92966SHermès Bélusca-Maïto             PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3262*7df92966SHermès Bélusca-Maïto         }
3263*7df92966SHermès Bélusca-Maïto 
3264*7df92966SHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
3265*7df92966SHermès Bélusca-Maïto     }
32666f19c83bSHermès Bélusca-Maïto 
32676f19c83bSHermès Bélusca-Maïto     //
32686f19c83bSHermès Bélusca-Maïto     // NOTE: Originally (see r40437), we used to install here also a new MBR
32696f19c83bSHermès Bélusca-Maïto     // for this disk (by calling InstallMbrBootCodeToDisk), only if:
32706f19c83bSHermès Bélusca-Maïto     // DiskEntry->NewDisk == TRUE and DiskEntry->BiosDiskNumber == 0.
32716f19c83bSHermès Bélusca-Maïto     // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
32726f19c83bSHermès Bélusca-Maïto     // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
32736f19c83bSHermès Bélusca-Maïto     // was called too, the installation test was modified by checking whether
32746f19c83bSHermès Bélusca-Maïto     // DiskEntry->NoMbr was TRUE (instead of NewDisk).
32756f19c83bSHermès Bélusca-Maïto     //
32766f19c83bSHermès Bélusca-Maïto 
3277*7df92966SHermès Bélusca-Maïto     // DiskEntry->Dirty = FALSE;
3278*7df92966SHermès Bélusca-Maïto 
32796f19c83bSHermès Bélusca-Maïto     return Status;
32806f19c83bSHermès Bélusca-Maïto }
32816f19c83bSHermès Bélusca-Maïto 
32826f19c83bSHermès Bélusca-Maïto BOOLEAN
32836f19c83bSHermès Bélusca-Maïto WritePartitionsToDisk(
32846f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
32856f19c83bSHermès Bélusca-Maïto {
32866f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
32876f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
32886f19c83bSHermès Bélusca-Maïto 
32896f19c83bSHermès Bélusca-Maïto     if (List == NULL)
32906f19c83bSHermès Bélusca-Maïto         return TRUE;
32916f19c83bSHermès Bélusca-Maïto 
32926f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
32936f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
32946f19c83bSHermès Bélusca-Maïto     {
32956f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
32966f19c83bSHermès Bélusca-Maïto 
32976f19c83bSHermès Bélusca-Maïto         if (DiskEntry->Dirty != FALSE)
32986f19c83bSHermès Bélusca-Maïto         {
32996f19c83bSHermès Bélusca-Maïto             WritePartitions(List, DiskEntry);
33006f19c83bSHermès Bélusca-Maïto             DiskEntry->Dirty = FALSE;
33016f19c83bSHermès Bélusca-Maïto         }
33026f19c83bSHermès Bélusca-Maïto 
33036f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
33046f19c83bSHermès Bélusca-Maïto     }
33056f19c83bSHermès Bélusca-Maïto 
33066f19c83bSHermès Bélusca-Maïto     return TRUE;
33076f19c83bSHermès Bélusca-Maïto }
33086f19c83bSHermès Bélusca-Maïto 
33096f19c83bSHermès Bélusca-Maïto BOOLEAN
33106f19c83bSHermès Bélusca-Maïto SetMountedDeviceValue(
3311f41750abSHermès Bélusca-Maïto     IN WCHAR Letter,
33126f19c83bSHermès Bélusca-Maïto     IN ULONG Signature,
33136f19c83bSHermès Bélusca-Maïto     IN LARGE_INTEGER StartingOffset)
33146f19c83bSHermès Bélusca-Maïto {
33156f19c83bSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
33166f19c83bSHermès Bélusca-Maïto     WCHAR ValueNameBuffer[16];
33176f19c83bSHermès Bélusca-Maïto     UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\MountedDevices");
33186f19c83bSHermès Bélusca-Maïto     UNICODE_STRING ValueName;
33196f19c83bSHermès Bélusca-Maïto     REG_DISK_MOUNT_INFO MountInfo;
33206f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
33216f19c83bSHermès Bélusca-Maïto     HANDLE KeyHandle;
33226f19c83bSHermès Bélusca-Maïto 
33236f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(ValueNameBuffer, ARRAYSIZE(ValueNameBuffer),
3324f41750abSHermès Bélusca-Maïto                         L"\\DosDevices\\%c:", Letter);
33256f19c83bSHermès Bélusca-Maïto     RtlInitUnicodeString(&ValueName, ValueNameBuffer);
33266f19c83bSHermès Bélusca-Maïto 
33276f19c83bSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
33286f19c83bSHermès Bélusca-Maïto                                &KeyName,
33296f19c83bSHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
33306f19c83bSHermès Bélusca-Maïto                                NULL,
33316f19c83bSHermès Bélusca-Maïto                                NULL);
3332765994c9SHermès Bélusca-Maïto 
33336f19c83bSHermès Bélusca-Maïto     Status =  NtOpenKey(&KeyHandle,
33346f19c83bSHermès Bélusca-Maïto                         KEY_ALL_ACCESS,
33356f19c83bSHermès Bélusca-Maïto                         &ObjectAttributes);
33366f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
33376f19c83bSHermès Bélusca-Maïto     {
33386f19c83bSHermès Bélusca-Maïto         Status = NtCreateKey(&KeyHandle,
33396f19c83bSHermès Bélusca-Maïto                              KEY_ALL_ACCESS,
33406f19c83bSHermès Bélusca-Maïto                              &ObjectAttributes,
33416f19c83bSHermès Bélusca-Maïto                              0,
33426f19c83bSHermès Bélusca-Maïto                              NULL,
33436f19c83bSHermès Bélusca-Maïto                              REG_OPTION_NON_VOLATILE,
33446f19c83bSHermès Bélusca-Maïto                              NULL);
33456f19c83bSHermès Bélusca-Maïto     }
33466f19c83bSHermès Bélusca-Maïto 
33476f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
33486f19c83bSHermès Bélusca-Maïto     {
33496f19c83bSHermès Bélusca-Maïto         DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
33506f19c83bSHermès Bélusca-Maïto         return FALSE;
33516f19c83bSHermès Bélusca-Maïto     }
33526f19c83bSHermès Bélusca-Maïto 
33536f19c83bSHermès Bélusca-Maïto     MountInfo.Signature = Signature;
33546f19c83bSHermès Bélusca-Maïto     MountInfo.StartingOffset = StartingOffset;
33556f19c83bSHermès Bélusca-Maïto     Status = NtSetValueKey(KeyHandle,
33566f19c83bSHermès Bélusca-Maïto                            &ValueName,
33576f19c83bSHermès Bélusca-Maïto                            0,
33586f19c83bSHermès Bélusca-Maïto                            REG_BINARY,
33596f19c83bSHermès Bélusca-Maïto                            (PVOID)&MountInfo,
33606f19c83bSHermès Bélusca-Maïto                            sizeof(MountInfo));
33616f19c83bSHermès Bélusca-Maïto     NtClose(KeyHandle);
33626f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
33636f19c83bSHermès Bélusca-Maïto     {
33646f19c83bSHermès Bélusca-Maïto         DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
33656f19c83bSHermès Bélusca-Maïto         return FALSE;
33666f19c83bSHermès Bélusca-Maïto     }
33676f19c83bSHermès Bélusca-Maïto 
33686f19c83bSHermès Bélusca-Maïto     return TRUE;
33696f19c83bSHermès Bélusca-Maïto }
33706f19c83bSHermès Bélusca-Maïto 
33716f19c83bSHermès Bélusca-Maïto BOOLEAN
33726f19c83bSHermès Bélusca-Maïto SetMountedDeviceValues(
33736f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
33746f19c83bSHermès Bélusca-Maïto {
33756f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1, Entry2;
33766f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
33776f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
33786f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER StartingOffset;
33796f19c83bSHermès Bélusca-Maïto 
33806f19c83bSHermès Bélusca-Maïto     if (List == NULL)
33816f19c83bSHermès Bélusca-Maïto         return FALSE;
33826f19c83bSHermès Bélusca-Maïto 
33836f19c83bSHermès Bélusca-Maïto     Entry1 = List->DiskListHead.Flink;
33846f19c83bSHermès Bélusca-Maïto     while (Entry1 != &List->DiskListHead)
33856f19c83bSHermès Bélusca-Maïto     {
33866f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1,
33876f19c83bSHermès Bélusca-Maïto                                       DISKENTRY,
33886f19c83bSHermès Bélusca-Maïto                                       ListEntry);
33896f19c83bSHermès Bélusca-Maïto 
33906f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->PrimaryPartListHead.Flink;
33916f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->PrimaryPartListHead)
33926f19c83bSHermès Bélusca-Maïto         {
33936f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
33946f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned)
33956f19c83bSHermès Bélusca-Maïto             {
33966f19c83bSHermès Bélusca-Maïto                 /* Assign a "\DosDevices\#:" mount point to this partition */
33976f19c83bSHermès Bélusca-Maïto                 if (PartEntry->DriveLetter)
33986f19c83bSHermès Bélusca-Maïto                 {
33996f19c83bSHermès Bélusca-Maïto                     StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
34006f19c83bSHermès Bélusca-Maïto                     if (!SetMountedDeviceValue(PartEntry->DriveLetter,
34016f19c83bSHermès Bélusca-Maïto                                                DiskEntry->LayoutBuffer->Signature,
34026f19c83bSHermès Bélusca-Maïto                                                StartingOffset))
34036f19c83bSHermès Bélusca-Maïto                     {
34046f19c83bSHermès Bélusca-Maïto                         return FALSE;
34056f19c83bSHermès Bélusca-Maïto                     }
34066f19c83bSHermès Bélusca-Maïto                 }
34076f19c83bSHermès Bélusca-Maïto             }
34086f19c83bSHermès Bélusca-Maïto 
34096f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
34106f19c83bSHermès Bélusca-Maïto         }
34116f19c83bSHermès Bélusca-Maïto 
34126f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->LogicalPartListHead.Flink;
34136f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->LogicalPartListHead)
34146f19c83bSHermès Bélusca-Maïto         {
34156f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
34166f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned)
34176f19c83bSHermès Bélusca-Maïto             {
34186f19c83bSHermès Bélusca-Maïto                 /* Assign a "\DosDevices\#:" mount point to this partition */
34196f19c83bSHermès Bélusca-Maïto                 if (PartEntry->DriveLetter)
34206f19c83bSHermès Bélusca-Maïto                 {
34216f19c83bSHermès Bélusca-Maïto                     StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
34226f19c83bSHermès Bélusca-Maïto                     if (!SetMountedDeviceValue(PartEntry->DriveLetter,
34236f19c83bSHermès Bélusca-Maïto                                                DiskEntry->LayoutBuffer->Signature,
34246f19c83bSHermès Bélusca-Maïto                                                StartingOffset))
34256f19c83bSHermès Bélusca-Maïto                     {
34266f19c83bSHermès Bélusca-Maïto                         return FALSE;
34276f19c83bSHermès Bélusca-Maïto                     }
34286f19c83bSHermès Bélusca-Maïto                 }
34296f19c83bSHermès Bélusca-Maïto             }
34306f19c83bSHermès Bélusca-Maïto 
34316f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
34326f19c83bSHermès Bélusca-Maïto         }
34336f19c83bSHermès Bélusca-Maïto 
34346f19c83bSHermès Bélusca-Maïto         Entry1 = Entry1->Flink;
34356f19c83bSHermès Bélusca-Maïto     }
34366f19c83bSHermès Bélusca-Maïto 
34376f19c83bSHermès Bélusca-Maïto     return TRUE;
34386f19c83bSHermès Bélusca-Maïto }
34396f19c83bSHermès Bélusca-Maïto 
34406f19c83bSHermès Bélusca-Maïto VOID
34416f19c83bSHermès Bélusca-Maïto SetPartitionType(
34426f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry,
34436f19c83bSHermès Bélusca-Maïto     IN UCHAR PartitionType)
34446f19c83bSHermès Bélusca-Maïto {
34456f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
34466f19c83bSHermès Bélusca-Maïto 
34476f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionType = PartitionType;
34486f19c83bSHermès Bélusca-Maïto 
34496f19c83bSHermès Bélusca-Maïto     DiskEntry->Dirty = TRUE;
34506f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
3451*7df92966SHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
34526f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
34536f19c83bSHermès Bélusca-Maïto }
34546f19c83bSHermès Bélusca-Maïto 
34556f19c83bSHermès Bélusca-Maïto ERROR_NUMBER
34566f19c83bSHermès Bélusca-Maïto PrimaryPartitionCreationChecks(
34576f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
34586f19c83bSHermès Bélusca-Maïto {
34596f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
34606f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
34616f19c83bSHermès Bélusca-Maïto 
34626f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
34636f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
34646f19c83bSHermès Bélusca-Maïto 
34656f19c83bSHermès Bélusca-Maïto     /* Fail if the partition is already in use */
346670fa2e2eSHermès Bélusca-Maïto     if (PartEntry->IsPartitioned)
34676f19c83bSHermès Bélusca-Maïto         return ERROR_NEW_PARTITION;
34686f19c83bSHermès Bélusca-Maïto 
34696f19c83bSHermès Bélusca-Maïto     /* Fail if there are already 4 primary partitions in the list */
34706f19c83bSHermès Bélusca-Maïto     if (GetPrimaryPartitionCount(DiskEntry) >= 4)
34716f19c83bSHermès Bélusca-Maïto         return ERROR_PARTITION_TABLE_FULL;
34726f19c83bSHermès Bélusca-Maïto 
34736f19c83bSHermès Bélusca-Maïto     return ERROR_SUCCESS;
34746f19c83bSHermès Bélusca-Maïto }
34756f19c83bSHermès Bélusca-Maïto 
34766f19c83bSHermès Bélusca-Maïto ERROR_NUMBER
34776f19c83bSHermès Bélusca-Maïto ExtendedPartitionCreationChecks(
34786f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
34796f19c83bSHermès Bélusca-Maïto {
34806f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
34816f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
34826f19c83bSHermès Bélusca-Maïto 
34836f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
34846f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
34856f19c83bSHermès Bélusca-Maïto 
34866f19c83bSHermès Bélusca-Maïto     /* Fail if the partition is already in use */
348770fa2e2eSHermès Bélusca-Maïto     if (PartEntry->IsPartitioned)
34886f19c83bSHermès Bélusca-Maïto         return ERROR_NEW_PARTITION;
34896f19c83bSHermès Bélusca-Maïto 
34906f19c83bSHermès Bélusca-Maïto     /* Fail if there are already 4 primary partitions in the list */
34916f19c83bSHermès Bélusca-Maïto     if (GetPrimaryPartitionCount(DiskEntry) >= 4)
34926f19c83bSHermès Bélusca-Maïto         return ERROR_PARTITION_TABLE_FULL;
34936f19c83bSHermès Bélusca-Maïto 
34946f19c83bSHermès Bélusca-Maïto     /* Fail if there is another extended partition in the list */
34956f19c83bSHermès Bélusca-Maïto     if (DiskEntry->ExtendedPartition != NULL)
34966f19c83bSHermès Bélusca-Maïto         return ERROR_ONLY_ONE_EXTENDED;
34976f19c83bSHermès Bélusca-Maïto 
34986f19c83bSHermès Bélusca-Maïto     return ERROR_SUCCESS;
34996f19c83bSHermès Bélusca-Maïto }
35006f19c83bSHermès Bélusca-Maïto 
35016f19c83bSHermès Bélusca-Maïto ERROR_NUMBER
35026f19c83bSHermès Bélusca-Maïto LogicalPartitionCreationChecks(
35036f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
35046f19c83bSHermès Bélusca-Maïto {
35056f19c83bSHermès Bélusca-Maïto //    PDISKENTRY DiskEntry;
35066f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
35076f19c83bSHermès Bélusca-Maïto 
35086f19c83bSHermès Bélusca-Maïto //    DiskEntry = List->CurrentDisk;
35096f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
35106f19c83bSHermès Bélusca-Maïto 
35116f19c83bSHermès Bélusca-Maïto     /* Fail if the partition is already in use */
351270fa2e2eSHermès Bélusca-Maïto     if (PartEntry->IsPartitioned)
35136f19c83bSHermès Bélusca-Maïto         return ERROR_NEW_PARTITION;
35146f19c83bSHermès Bélusca-Maïto 
35156f19c83bSHermès Bélusca-Maïto     return ERROR_SUCCESS;
35166f19c83bSHermès Bélusca-Maïto }
35176f19c83bSHermès Bélusca-Maïto 
35186f19c83bSHermès Bélusca-Maïto BOOLEAN
35196f19c83bSHermès Bélusca-Maïto GetNextUnformattedPartition(
35206f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
35216f19c83bSHermès Bélusca-Maïto     OUT PDISKENTRY *pDiskEntry OPTIONAL,
35226f19c83bSHermès Bélusca-Maïto     OUT PPARTENTRY *pPartEntry)
35236f19c83bSHermès Bélusca-Maïto {
35246f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1, Entry2;
35256f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
35266f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
35276f19c83bSHermès Bélusca-Maïto 
35286f19c83bSHermès Bélusca-Maïto     Entry1 = List->DiskListHead.Flink;
35296f19c83bSHermès Bélusca-Maïto     while (Entry1 != &List->DiskListHead)
35306f19c83bSHermès Bélusca-Maïto     {
35316f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1,
35326f19c83bSHermès Bélusca-Maïto                                       DISKENTRY,
35336f19c83bSHermès Bélusca-Maïto                                       ListEntry);
35346f19c83bSHermès Bélusca-Maïto 
35356f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->PrimaryPartListHead.Flink;
35366f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->PrimaryPartListHead)
35376f19c83bSHermès Bélusca-Maïto         {
35386f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
35396f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned && PartEntry->New)
35406f19c83bSHermès Bélusca-Maïto             {
35416f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
35426f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
35436f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
35446f19c83bSHermès Bélusca-Maïto                 return TRUE;
35456f19c83bSHermès Bélusca-Maïto             }
35466f19c83bSHermès Bélusca-Maïto 
35476f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
35486f19c83bSHermès Bélusca-Maïto         }
35496f19c83bSHermès Bélusca-Maïto 
35506f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->LogicalPartListHead.Flink;
35516f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->LogicalPartListHead)
35526f19c83bSHermès Bélusca-Maïto         {
35536f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
35546f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned && PartEntry->New)
35556f19c83bSHermès Bélusca-Maïto             {
35566f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
35576f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
35586f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
35596f19c83bSHermès Bélusca-Maïto                 return TRUE;
35606f19c83bSHermès Bélusca-Maïto             }
35616f19c83bSHermès Bélusca-Maïto 
35626f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
35636f19c83bSHermès Bélusca-Maïto         }
35646f19c83bSHermès Bélusca-Maïto 
35656f19c83bSHermès Bélusca-Maïto         Entry1 = Entry1->Flink;
35666f19c83bSHermès Bélusca-Maïto     }
35676f19c83bSHermès Bélusca-Maïto 
35686f19c83bSHermès Bélusca-Maïto     if (pDiskEntry) *pDiskEntry = NULL;
35696f19c83bSHermès Bélusca-Maïto     *pPartEntry = NULL;
35706f19c83bSHermès Bélusca-Maïto 
35716f19c83bSHermès Bélusca-Maïto     return FALSE;
35726f19c83bSHermès Bélusca-Maïto }
35736f19c83bSHermès Bélusca-Maïto 
35746f19c83bSHermès Bélusca-Maïto BOOLEAN
35756f19c83bSHermès Bélusca-Maïto GetNextUncheckedPartition(
35766f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
35776f19c83bSHermès Bélusca-Maïto     OUT PDISKENTRY *pDiskEntry OPTIONAL,
35786f19c83bSHermès Bélusca-Maïto     OUT PPARTENTRY *pPartEntry)
35796f19c83bSHermès Bélusca-Maïto {
35806f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1, Entry2;
35816f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
35826f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
35836f19c83bSHermès Bélusca-Maïto 
35846f19c83bSHermès Bélusca-Maïto     Entry1 = List->DiskListHead.Flink;
35856f19c83bSHermès Bélusca-Maïto     while (Entry1 != &List->DiskListHead)
35866f19c83bSHermès Bélusca-Maïto     {
35876f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1,
35886f19c83bSHermès Bélusca-Maïto                                       DISKENTRY,
35896f19c83bSHermès Bélusca-Maïto                                       ListEntry);
35906f19c83bSHermès Bélusca-Maïto 
35916f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->PrimaryPartListHead.Flink;
35926f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->PrimaryPartListHead)
35936f19c83bSHermès Bélusca-Maïto         {
35946f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
35956f19c83bSHermès Bélusca-Maïto             if (PartEntry->NeedsCheck == TRUE)
35966f19c83bSHermès Bélusca-Maïto             {
35976f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
35986f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
35996f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
36006f19c83bSHermès Bélusca-Maïto                 return TRUE;
36016f19c83bSHermès Bélusca-Maïto             }
36026f19c83bSHermès Bélusca-Maïto 
36036f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
36046f19c83bSHermès Bélusca-Maïto         }
36056f19c83bSHermès Bélusca-Maïto 
36066f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->LogicalPartListHead.Flink;
36076f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->LogicalPartListHead)
36086f19c83bSHermès Bélusca-Maïto         {
36096f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
36106f19c83bSHermès Bélusca-Maïto             if (PartEntry->NeedsCheck == TRUE)
36116f19c83bSHermès Bélusca-Maïto             {
36126f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
36136f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
36146f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
36156f19c83bSHermès Bélusca-Maïto                 return TRUE;
36166f19c83bSHermès Bélusca-Maïto             }
36176f19c83bSHermès Bélusca-Maïto 
36186f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
36196f19c83bSHermès Bélusca-Maïto         }
36206f19c83bSHermès Bélusca-Maïto 
36216f19c83bSHermès Bélusca-Maïto         Entry1 = Entry1->Flink;
36226f19c83bSHermès Bélusca-Maïto     }
36236f19c83bSHermès Bélusca-Maïto 
36246f19c83bSHermès Bélusca-Maïto     if (pDiskEntry) *pDiskEntry = NULL;
36256f19c83bSHermès Bélusca-Maïto     *pPartEntry = NULL;
36266f19c83bSHermès Bélusca-Maïto 
36276f19c83bSHermès Bélusca-Maïto     return FALSE;
36286f19c83bSHermès Bélusca-Maïto }
36296f19c83bSHermès Bélusca-Maïto 
36306f19c83bSHermès Bélusca-Maïto /* EOF */
3631