xref: /reactos/base/setup/lib/utils/partlist.c (revision 26408b02)
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 
6676f19c83bSHermès Bélusca-Maïto static
6686f19c83bSHermès Bélusca-Maïto VOID
6696f19c83bSHermès Bélusca-Maïto AddPartitionToDisk(
6706f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
6716f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
6726f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionIndex,
6736f19c83bSHermès Bélusca-Maïto     IN BOOLEAN LogicalPartition)
6746f19c83bSHermès Bélusca-Maïto {
675f41750abSHermès Bélusca-Maïto     NTSTATUS Status;
6766f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
6776f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
678f41750abSHermès Bélusca-Maïto     HANDLE FileHandle;
679f41750abSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
680f41750abSHermès Bélusca-Maïto     IO_STATUS_BLOCK IoStatusBlock;
681f41750abSHermès Bélusca-Maïto     WCHAR Buffer[MAX_PATH];
682f41750abSHermès Bélusca-Maïto     UNICODE_STRING Name;
683f41750abSHermès Bélusca-Maïto     UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)];
684f41750abSHermès Bélusca-Maïto     PFILE_FS_VOLUME_INFORMATION LabelInfo = (PFILE_FS_VOLUME_INFORMATION)LabelBuffer;
6856f19c83bSHermès Bélusca-Maïto 
6866f19c83bSHermès Bélusca-Maïto     PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
6876f19c83bSHermès Bélusca-Maïto 
6886f19c83bSHermès Bélusca-Maïto     if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED ||
6896f19c83bSHermès Bélusca-Maïto         ((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType)))
6906f19c83bSHermès Bélusca-Maïto     {
6916f19c83bSHermès Bélusca-Maïto         return;
6926f19c83bSHermès Bélusca-Maïto     }
6936f19c83bSHermès Bélusca-Maïto 
6946f19c83bSHermès Bélusca-Maïto     PartEntry = RtlAllocateHeap(ProcessHeap,
6956f19c83bSHermès Bélusca-Maïto                                 HEAP_ZERO_MEMORY,
6966f19c83bSHermès Bélusca-Maïto                                 sizeof(PARTENTRY));
6976f19c83bSHermès Bélusca-Maïto     if (PartEntry == NULL)
6986f19c83bSHermès Bélusca-Maïto         return;
6996f19c83bSHermès Bélusca-Maïto 
7006f19c83bSHermès Bélusca-Maïto     PartEntry->DiskEntry = DiskEntry;
7016f19c83bSHermès Bélusca-Maïto 
7026f19c83bSHermès Bélusca-Maïto     PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
7036f19c83bSHermès Bélusca-Maïto     PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
7046f19c83bSHermès Bélusca-Maïto 
7056f19c83bSHermès Bélusca-Maïto     PartEntry->BootIndicator = PartitionInfo->BootIndicator;
7066f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionType = PartitionInfo->PartitionType;
7076f19c83bSHermès Bélusca-Maïto     PartEntry->HiddenSectors = PartitionInfo->HiddenSectors;
7086f19c83bSHermès Bélusca-Maïto 
7096f19c83bSHermès Bélusca-Maïto     PartEntry->LogicalPartition = LogicalPartition;
7106f19c83bSHermès Bélusca-Maïto     PartEntry->IsPartitioned = TRUE;
7116f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
7126f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionIndex = PartitionIndex;
7136f19c83bSHermès Bélusca-Maïto 
7146f19c83bSHermès Bélusca-Maïto     if (IsContainerPartition(PartEntry->PartitionType))
7156f19c83bSHermès Bélusca-Maïto     {
7166f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = Unformatted;
7176f19c83bSHermès Bélusca-Maïto         PartEntry->FileSystem  = NULL;
7186f19c83bSHermès Bélusca-Maïto 
7196f19c83bSHermès Bélusca-Maïto         if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
7206f19c83bSHermès Bélusca-Maïto             DiskEntry->ExtendedPartition = PartEntry;
7216f19c83bSHermès Bélusca-Maïto     }
7226f19c83bSHermès Bélusca-Maïto     else if (IsRecognizedPartition(PartEntry->PartitionType))
7236f19c83bSHermès Bélusca-Maïto     {
7246f19c83bSHermès Bélusca-Maïto         PartEntry->FileSystem = GetFileSystem(PartEntry);
7256f19c83bSHermès Bélusca-Maïto         if (PartEntry->FileSystem)
7266f19c83bSHermès Bélusca-Maïto             PartEntry->FormatState = Preformatted;
7276f19c83bSHermès Bélusca-Maïto         else
7286f19c83bSHermès Bélusca-Maïto             PartEntry->FormatState = Unformatted;
7296f19c83bSHermès Bélusca-Maïto         // PartEntry->FormatState = UnknownFormat;
7306f19c83bSHermès Bélusca-Maïto     }
7316f19c83bSHermès Bélusca-Maïto     else
7326f19c83bSHermès Bélusca-Maïto     {
7336f19c83bSHermès Bélusca-Maïto         /* Unknown partition, hence unknown partition format (may or may not be actually formatted) */
7346f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = UnknownFormat;
7356f19c83bSHermès Bélusca-Maïto     }
7366f19c83bSHermès Bélusca-Maïto 
737f41750abSHermès Bélusca-Maïto     /* Initialize the partition volume label */
738f41750abSHermès Bélusca-Maïto     RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
739f41750abSHermès Bélusca-Maïto 
740f41750abSHermès Bélusca-Maïto     /* Open the volume, ignore any errors */
741f41750abSHermès Bélusca-Maïto     RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
742f41750abSHermès Bélusca-Maïto                         L"\\Device\\Harddisk%lu\\Partition%lu",
743f41750abSHermès Bélusca-Maïto                         DiskEntry->DiskNumber, PartEntry->PartitionNumber);
744f41750abSHermès Bélusca-Maïto     RtlInitUnicodeString(&Name, Buffer);
745f41750abSHermès Bélusca-Maïto 
746f41750abSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
747f41750abSHermès Bélusca-Maïto                                &Name,
748f41750abSHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
749f41750abSHermès Bélusca-Maïto                                NULL,
750f41750abSHermès Bélusca-Maïto                                NULL);
751f41750abSHermès Bélusca-Maïto 
752f41750abSHermès Bélusca-Maïto     Status = NtOpenFile(&FileHandle,
753f41750abSHermès Bélusca-Maïto                         FILE_READ_DATA | SYNCHRONIZE,
754f41750abSHermès Bélusca-Maïto                         &ObjectAttributes,
755f41750abSHermès Bélusca-Maïto                         &IoStatusBlock,
756f41750abSHermès Bélusca-Maïto                         FILE_SHARE_READ | FILE_SHARE_WRITE,
757f41750abSHermès Bélusca-Maïto                         FILE_SYNCHRONOUS_IO_NONALERT);
758f41750abSHermès Bélusca-Maïto     if (NT_SUCCESS(Status))
759f41750abSHermès Bélusca-Maïto     {
760f41750abSHermès Bélusca-Maïto         /* Retrieve the partition volume label */
761f41750abSHermès Bélusca-Maïto         Status = NtQueryVolumeInformationFile(FileHandle,
762f41750abSHermès Bélusca-Maïto                                               &IoStatusBlock,
763f41750abSHermès Bélusca-Maïto                                               &LabelBuffer,
764f41750abSHermès Bélusca-Maïto                                               sizeof(LabelBuffer),
765f41750abSHermès Bélusca-Maïto                                               FileFsVolumeInformation);
766f41750abSHermès Bélusca-Maïto         /* Close the handle */
767f41750abSHermès Bélusca-Maïto         NtClose(FileHandle);
768f41750abSHermès Bélusca-Maïto 
769f41750abSHermès Bélusca-Maïto         /* Check for success */
770f41750abSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
771f41750abSHermès Bélusca-Maïto         {
772f41750abSHermès Bélusca-Maïto             /* Copy the (possibly truncated) volume label and NULL-terminate it */
773f41750abSHermès Bélusca-Maïto             RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel),
774f41750abSHermès Bélusca-Maïto                               LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength);
775f41750abSHermès Bélusca-Maïto         }
776f41750abSHermès Bélusca-Maïto         else
777f41750abSHermès Bélusca-Maïto         {
778f41750abSHermès Bélusca-Maïto             DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
779f41750abSHermès Bélusca-Maïto         }
780f41750abSHermès Bélusca-Maïto     }
781f41750abSHermès Bélusca-Maïto     else
782f41750abSHermès Bélusca-Maïto     {
783f41750abSHermès Bélusca-Maïto         DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status);
784f41750abSHermès Bélusca-Maïto     }
785f41750abSHermès Bélusca-Maïto 
7866f19c83bSHermès Bélusca-Maïto     if (LogicalPartition)
7876f19c83bSHermès Bélusca-Maïto         InsertTailList(&DiskEntry->LogicalPartListHead,
7886f19c83bSHermès Bélusca-Maïto                        &PartEntry->ListEntry);
7896f19c83bSHermès Bélusca-Maïto     else
7906f19c83bSHermès Bélusca-Maïto         InsertTailList(&DiskEntry->PrimaryPartListHead,
7916f19c83bSHermès Bélusca-Maïto                        &PartEntry->ListEntry);
7926f19c83bSHermès Bélusca-Maïto }
7936f19c83bSHermès Bélusca-Maïto 
7946f19c83bSHermès Bélusca-Maïto static
7956f19c83bSHermès Bélusca-Maïto VOID
7966f19c83bSHermès Bélusca-Maïto ScanForUnpartitionedDiskSpace(
7976f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
7986f19c83bSHermès Bélusca-Maïto {
7996f19c83bSHermès Bélusca-Maïto     ULONGLONG LastStartSector;
8006f19c83bSHermès Bélusca-Maïto     ULONGLONG LastSectorCount;
8016f19c83bSHermès Bélusca-Maïto     ULONGLONG LastUnusedSectorCount;
8026f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
8036f19c83bSHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
8046f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
8056f19c83bSHermès Bélusca-Maïto 
8066f19c83bSHermès Bélusca-Maïto     DPRINT("ScanForUnpartitionedDiskSpace()\n");
8076f19c83bSHermès Bélusca-Maïto 
8086f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
8096f19c83bSHermès Bélusca-Maïto     {
8106f19c83bSHermès Bélusca-Maïto         DPRINT1("No primary partition!\n");
8116f19c83bSHermès Bélusca-Maïto 
8126f19c83bSHermès Bélusca-Maïto         /* Create a partition entry that represents the empty disk */
8136f19c83bSHermès Bélusca-Maïto         NewPartEntry = RtlAllocateHeap(ProcessHeap,
8146f19c83bSHermès Bélusca-Maïto                                        HEAP_ZERO_MEMORY,
8156f19c83bSHermès Bélusca-Maïto                                        sizeof(PARTENTRY));
8166f19c83bSHermès Bélusca-Maïto         if (NewPartEntry == NULL)
8176f19c83bSHermès Bélusca-Maïto             return;
8186f19c83bSHermès Bélusca-Maïto 
8196f19c83bSHermès Bélusca-Maïto         NewPartEntry->DiskEntry = DiskEntry;
8206f19c83bSHermès Bélusca-Maïto 
8216f19c83bSHermès Bélusca-Maïto         NewPartEntry->IsPartitioned = FALSE;
822*26408b02SPierre Schweitzer         if (DiskEntry->SectorAlignment < 2048)
823*26408b02SPierre Schweitzer             NewPartEntry->StartSector.QuadPart = 2048ULL;
824*26408b02SPierre Schweitzer         else
8256f19c83bSHermès Bélusca-Maïto             NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
8266f19c83bSHermès Bélusca-Maïto         NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) -
8276f19c83bSHermès Bélusca-Maïto                                              NewPartEntry->StartSector.QuadPart;
8286f19c83bSHermès Bélusca-Maïto 
8296f19c83bSHermès Bélusca-Maïto         DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
8306f19c83bSHermès Bélusca-Maïto         DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
8316f19c83bSHermès Bélusca-Maïto         DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
8326f19c83bSHermès Bélusca-Maïto 
8336f19c83bSHermès Bélusca-Maïto         NewPartEntry->FormatState = Unformatted;
8346f19c83bSHermès Bélusca-Maïto         NewPartEntry->FileSystem  = NULL;
8356f19c83bSHermès Bélusca-Maïto 
8366f19c83bSHermès Bélusca-Maïto         InsertTailList(&DiskEntry->PrimaryPartListHead,
8376f19c83bSHermès Bélusca-Maïto                        &NewPartEntry->ListEntry);
8386f19c83bSHermès Bélusca-Maïto 
8396f19c83bSHermès Bélusca-Maïto         return;
8406f19c83bSHermès Bélusca-Maïto     }
8416f19c83bSHermès Bélusca-Maïto 
8426f19c83bSHermès Bélusca-Maïto     /* Start partition at head 1, cylinder 0 */
843*26408b02SPierre Schweitzer     if (DiskEntry->SectorAlignment < 2048)
844*26408b02SPierre Schweitzer         LastStartSector = 2048ULL;
845*26408b02SPierre Schweitzer     else
8466f19c83bSHermès Bélusca-Maïto         LastStartSector = DiskEntry->SectorAlignment;
8476f19c83bSHermès Bélusca-Maïto     LastSectorCount = 0ULL;
8486f19c83bSHermès Bélusca-Maïto     LastUnusedSectorCount = 0ULL;
8496f19c83bSHermès Bélusca-Maïto 
8506f19c83bSHermès Bélusca-Maïto     Entry = DiskEntry->PrimaryPartListHead.Flink;
8516f19c83bSHermès Bélusca-Maïto     while (Entry != &DiskEntry->PrimaryPartListHead)
8526f19c83bSHermès Bélusca-Maïto     {
8536f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
8546f19c83bSHermès Bélusca-Maïto 
8556f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
8566f19c83bSHermès Bélusca-Maïto             PartEntry->SectorCount.QuadPart != 0ULL)
8576f19c83bSHermès Bélusca-Maïto         {
8586f19c83bSHermès Bélusca-Maïto             LastUnusedSectorCount =
8596f19c83bSHermès Bélusca-Maïto                 PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
8606f19c83bSHermès Bélusca-Maïto 
8616f19c83bSHermès Bélusca-Maïto             if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
8626f19c83bSHermès Bélusca-Maïto                 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
8636f19c83bSHermès Bélusca-Maïto             {
8646f19c83bSHermès Bélusca-Maïto                 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
8656f19c83bSHermès Bélusca-Maïto 
8666f19c83bSHermès Bélusca-Maïto                 NewPartEntry = RtlAllocateHeap(ProcessHeap,
8676f19c83bSHermès Bélusca-Maïto                                                HEAP_ZERO_MEMORY,
8686f19c83bSHermès Bélusca-Maïto                                                sizeof(PARTENTRY));
8696f19c83bSHermès Bélusca-Maïto                 if (NewPartEntry == NULL)
8706f19c83bSHermès Bélusca-Maïto                     return;
8716f19c83bSHermès Bélusca-Maïto 
8726f19c83bSHermès Bélusca-Maïto                 NewPartEntry->DiskEntry = DiskEntry;
8736f19c83bSHermès Bélusca-Maïto 
8746f19c83bSHermès Bélusca-Maïto                 NewPartEntry->IsPartitioned = FALSE;
8756f19c83bSHermès Bélusca-Maïto                 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
8766f19c83bSHermès Bélusca-Maïto                 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
8776f19c83bSHermès Bélusca-Maïto                                                      NewPartEntry->StartSector.QuadPart;
8786f19c83bSHermès Bélusca-Maïto 
8796f19c83bSHermès Bélusca-Maïto                 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
8806f19c83bSHermès Bélusca-Maïto                 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
8816f19c83bSHermès Bélusca-Maïto                 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
8826f19c83bSHermès Bélusca-Maïto 
8836f19c83bSHermès Bélusca-Maïto                 NewPartEntry->FormatState = Unformatted;
8846f19c83bSHermès Bélusca-Maïto                 NewPartEntry->FileSystem  = NULL;
8856f19c83bSHermès Bélusca-Maïto 
8866f19c83bSHermès Bélusca-Maïto                 /* Insert the table into the list */
8876f19c83bSHermès Bélusca-Maïto                 InsertTailList(&PartEntry->ListEntry,
8886f19c83bSHermès Bélusca-Maïto                                &NewPartEntry->ListEntry);
8896f19c83bSHermès Bélusca-Maïto             }
8906f19c83bSHermès Bélusca-Maïto 
8916f19c83bSHermès Bélusca-Maïto             LastStartSector = PartEntry->StartSector.QuadPart;
8926f19c83bSHermès Bélusca-Maïto             LastSectorCount = PartEntry->SectorCount.QuadPart;
8936f19c83bSHermès Bélusca-Maïto         }
8946f19c83bSHermès Bélusca-Maïto 
8956f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
8966f19c83bSHermès Bélusca-Maïto     }
8976f19c83bSHermès Bélusca-Maïto 
8986f19c83bSHermès Bélusca-Maïto     /* Check for trailing unpartitioned disk space */
8996f19c83bSHermès Bélusca-Maïto     if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
9006f19c83bSHermès Bélusca-Maïto     {
9016f19c83bSHermès Bélusca-Maïto         LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
9026f19c83bSHermès Bélusca-Maïto 
9036f19c83bSHermès Bélusca-Maïto         if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
9046f19c83bSHermès Bélusca-Maïto         {
9056f19c83bSHermès Bélusca-Maïto             DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
9066f19c83bSHermès Bélusca-Maïto 
9076f19c83bSHermès Bélusca-Maïto             NewPartEntry = RtlAllocateHeap(ProcessHeap,
9086f19c83bSHermès Bélusca-Maïto                                            HEAP_ZERO_MEMORY,
9096f19c83bSHermès Bélusca-Maïto                                            sizeof(PARTENTRY));
9106f19c83bSHermès Bélusca-Maïto             if (NewPartEntry == NULL)
9116f19c83bSHermès Bélusca-Maïto                 return;
9126f19c83bSHermès Bélusca-Maïto 
9136f19c83bSHermès Bélusca-Maïto             NewPartEntry->DiskEntry = DiskEntry;
9146f19c83bSHermès Bélusca-Maïto 
9156f19c83bSHermès Bélusca-Maïto             NewPartEntry->IsPartitioned = FALSE;
9166f19c83bSHermès Bélusca-Maïto             NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
9176f19c83bSHermès Bélusca-Maïto             NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
9186f19c83bSHermès Bélusca-Maïto                                                  NewPartEntry->StartSector.QuadPart;
9196f19c83bSHermès Bélusca-Maïto 
9206f19c83bSHermès Bélusca-Maïto             DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
9216f19c83bSHermès Bélusca-Maïto             DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
9226f19c83bSHermès Bélusca-Maïto             DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
9236f19c83bSHermès Bélusca-Maïto 
9246f19c83bSHermès Bélusca-Maïto             NewPartEntry->FormatState = Unformatted;
9256f19c83bSHermès Bélusca-Maïto             NewPartEntry->FileSystem  = NULL;
9266f19c83bSHermès Bélusca-Maïto 
9276f19c83bSHermès Bélusca-Maïto             /* Append the table to the list */
9286f19c83bSHermès Bélusca-Maïto             InsertTailList(&DiskEntry->PrimaryPartListHead,
9296f19c83bSHermès Bélusca-Maïto                            &NewPartEntry->ListEntry);
9306f19c83bSHermès Bélusca-Maïto         }
9316f19c83bSHermès Bélusca-Maïto     }
9326f19c83bSHermès Bélusca-Maïto 
9336f19c83bSHermès Bélusca-Maïto     if (DiskEntry->ExtendedPartition != NULL)
9346f19c83bSHermès Bélusca-Maïto     {
9356f19c83bSHermès Bélusca-Maïto         if (IsListEmpty(&DiskEntry->LogicalPartListHead))
9366f19c83bSHermès Bélusca-Maïto         {
9376f19c83bSHermès Bélusca-Maïto             DPRINT1("No logical partition!\n");
9386f19c83bSHermès Bélusca-Maïto 
9396f19c83bSHermès Bélusca-Maïto             /* Create a partition entry that represents the empty extended partition */
9406f19c83bSHermès Bélusca-Maïto             NewPartEntry = RtlAllocateHeap(ProcessHeap,
9416f19c83bSHermès Bélusca-Maïto                                            HEAP_ZERO_MEMORY,
9426f19c83bSHermès Bélusca-Maïto                                            sizeof(PARTENTRY));
9436f19c83bSHermès Bélusca-Maïto             if (NewPartEntry == NULL)
9446f19c83bSHermès Bélusca-Maïto                 return;
9456f19c83bSHermès Bélusca-Maïto 
9466f19c83bSHermès Bélusca-Maïto             NewPartEntry->DiskEntry = DiskEntry;
9476f19c83bSHermès Bélusca-Maïto             NewPartEntry->LogicalPartition = TRUE;
9486f19c83bSHermès Bélusca-Maïto 
9496f19c83bSHermès Bélusca-Maïto             NewPartEntry->IsPartitioned = FALSE;
9506f19c83bSHermès Bélusca-Maïto             NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
9516f19c83bSHermès Bélusca-Maïto             NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
9526f19c83bSHermès Bélusca-Maïto 
9536f19c83bSHermès Bélusca-Maïto             DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
9546f19c83bSHermès Bélusca-Maïto             DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
9556f19c83bSHermès Bélusca-Maïto             DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
9566f19c83bSHermès Bélusca-Maïto 
9576f19c83bSHermès Bélusca-Maïto             NewPartEntry->FormatState = Unformatted;
9586f19c83bSHermès Bélusca-Maïto             NewPartEntry->FileSystem  = NULL;
9596f19c83bSHermès Bélusca-Maïto 
9606f19c83bSHermès Bélusca-Maïto             InsertTailList(&DiskEntry->LogicalPartListHead,
9616f19c83bSHermès Bélusca-Maïto                            &NewPartEntry->ListEntry);
9626f19c83bSHermès Bélusca-Maïto 
9636f19c83bSHermès Bélusca-Maïto             return;
9646f19c83bSHermès Bélusca-Maïto         }
9656f19c83bSHermès Bélusca-Maïto 
9666f19c83bSHermès Bélusca-Maïto         /* Start partition at head 1, cylinder 0 */
9676f19c83bSHermès Bélusca-Maïto         LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
9686f19c83bSHermès Bélusca-Maïto         LastSectorCount = 0ULL;
9696f19c83bSHermès Bélusca-Maïto         LastUnusedSectorCount = 0ULL;
9706f19c83bSHermès Bélusca-Maïto 
9716f19c83bSHermès Bélusca-Maïto         Entry = DiskEntry->LogicalPartListHead.Flink;
9726f19c83bSHermès Bélusca-Maïto         while (Entry != &DiskEntry->LogicalPartListHead)
9736f19c83bSHermès Bélusca-Maïto         {
9746f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
9756f19c83bSHermès Bélusca-Maïto 
9766f19c83bSHermès Bélusca-Maïto             if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
9776f19c83bSHermès Bélusca-Maïto                 PartEntry->SectorCount.QuadPart != 0ULL)
9786f19c83bSHermès Bélusca-Maïto             {
9796f19c83bSHermès Bélusca-Maïto                 LastUnusedSectorCount =
9806f19c83bSHermès Bélusca-Maïto                     PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
9816f19c83bSHermès Bélusca-Maïto 
9826f19c83bSHermès Bélusca-Maïto                 if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
9836f19c83bSHermès Bélusca-Maïto                     LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
9846f19c83bSHermès Bélusca-Maïto                 {
9856f19c83bSHermès Bélusca-Maïto                     DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
9866f19c83bSHermès Bélusca-Maïto 
9876f19c83bSHermès Bélusca-Maïto                     NewPartEntry = RtlAllocateHeap(ProcessHeap,
9886f19c83bSHermès Bélusca-Maïto                                                    HEAP_ZERO_MEMORY,
9896f19c83bSHermès Bélusca-Maïto                                                    sizeof(PARTENTRY));
9906f19c83bSHermès Bélusca-Maïto                     if (NewPartEntry == NULL)
9916f19c83bSHermès Bélusca-Maïto                         return;
9926f19c83bSHermès Bélusca-Maïto 
9936f19c83bSHermès Bélusca-Maïto                     NewPartEntry->DiskEntry = DiskEntry;
9946f19c83bSHermès Bélusca-Maïto                     NewPartEntry->LogicalPartition = TRUE;
9956f19c83bSHermès Bélusca-Maïto 
9966f19c83bSHermès Bélusca-Maïto                     NewPartEntry->IsPartitioned = FALSE;
9976f19c83bSHermès Bélusca-Maïto                     NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
9986f19c83bSHermès Bélusca-Maïto                     NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
9996f19c83bSHermès Bélusca-Maïto                                                          NewPartEntry->StartSector.QuadPart;
10006f19c83bSHermès Bélusca-Maïto 
10016f19c83bSHermès Bélusca-Maïto                     DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
10026f19c83bSHermès Bélusca-Maïto                     DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
10036f19c83bSHermès Bélusca-Maïto                     DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
10046f19c83bSHermès Bélusca-Maïto 
10056f19c83bSHermès Bélusca-Maïto                     NewPartEntry->FormatState = Unformatted;
10066f19c83bSHermès Bélusca-Maïto                     NewPartEntry->FileSystem  = NULL;
10076f19c83bSHermès Bélusca-Maïto 
10086f19c83bSHermès Bélusca-Maïto                     /* Insert the table into the list */
10096f19c83bSHermès Bélusca-Maïto                     InsertTailList(&PartEntry->ListEntry,
10106f19c83bSHermès Bélusca-Maïto                                    &NewPartEntry->ListEntry);
10116f19c83bSHermès Bélusca-Maïto                 }
10126f19c83bSHermès Bélusca-Maïto 
10136f19c83bSHermès Bélusca-Maïto                 LastStartSector = PartEntry->StartSector.QuadPart;
10146f19c83bSHermès Bélusca-Maïto                 LastSectorCount = PartEntry->SectorCount.QuadPart;
10156f19c83bSHermès Bélusca-Maïto             }
10166f19c83bSHermès Bélusca-Maïto 
10176f19c83bSHermès Bélusca-Maïto             Entry = Entry->Flink;
10186f19c83bSHermès Bélusca-Maïto         }
10196f19c83bSHermès Bélusca-Maïto 
10206f19c83bSHermès Bélusca-Maïto         /* Check for trailing unpartitioned disk space */
10216f19c83bSHermès Bélusca-Maïto         if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
10226f19c83bSHermès Bélusca-Maïto         {
10236f19c83bSHermès Bélusca-Maïto             LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
10246f19c83bSHermès Bélusca-Maïto 
10256f19c83bSHermès Bélusca-Maïto             if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
10266f19c83bSHermès Bélusca-Maïto             {
10276f19c83bSHermès Bélusca-Maïto                 DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
10286f19c83bSHermès Bélusca-Maïto 
10296f19c83bSHermès Bélusca-Maïto                 NewPartEntry = RtlAllocateHeap(ProcessHeap,
10306f19c83bSHermès Bélusca-Maïto                                                HEAP_ZERO_MEMORY,
10316f19c83bSHermès Bélusca-Maïto                                                sizeof(PARTENTRY));
10326f19c83bSHermès Bélusca-Maïto                 if (NewPartEntry == NULL)
10336f19c83bSHermès Bélusca-Maïto                     return;
10346f19c83bSHermès Bélusca-Maïto 
10356f19c83bSHermès Bélusca-Maïto                 NewPartEntry->DiskEntry = DiskEntry;
10366f19c83bSHermès Bélusca-Maïto                 NewPartEntry->LogicalPartition = TRUE;
10376f19c83bSHermès Bélusca-Maïto 
10386f19c83bSHermès Bélusca-Maïto                 NewPartEntry->IsPartitioned = FALSE;
10396f19c83bSHermès Bélusca-Maïto                 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
10406f19c83bSHermès Bélusca-Maïto                 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
10416f19c83bSHermès Bélusca-Maïto                                                      NewPartEntry->StartSector.QuadPart;
10426f19c83bSHermès Bélusca-Maïto 
10436f19c83bSHermès Bélusca-Maïto                 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
10446f19c83bSHermès Bélusca-Maïto                 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
10456f19c83bSHermès Bélusca-Maïto                 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
10466f19c83bSHermès Bélusca-Maïto 
10476f19c83bSHermès Bélusca-Maïto                 NewPartEntry->FormatState = Unformatted;
10486f19c83bSHermès Bélusca-Maïto                 NewPartEntry->FileSystem  = NULL;
10496f19c83bSHermès Bélusca-Maïto 
10506f19c83bSHermès Bélusca-Maïto                 /* Append the table to the list */
10516f19c83bSHermès Bélusca-Maïto                 InsertTailList(&DiskEntry->LogicalPartListHead,
10526f19c83bSHermès Bélusca-Maïto                                &NewPartEntry->ListEntry);
10536f19c83bSHermès Bélusca-Maïto             }
10546f19c83bSHermès Bélusca-Maïto         }
10556f19c83bSHermès Bélusca-Maïto     }
10566f19c83bSHermès Bélusca-Maïto 
10576f19c83bSHermès Bélusca-Maïto     DPRINT("ScanForUnpartitionedDiskSpace() done\n");
10586f19c83bSHermès Bélusca-Maïto }
10596f19c83bSHermès Bélusca-Maïto 
10606f19c83bSHermès Bélusca-Maïto static
10616f19c83bSHermès Bélusca-Maïto VOID
10626f19c83bSHermès Bélusca-Maïto SetDiskSignature(
10636f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
10646f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
10656f19c83bSHermès Bélusca-Maïto {
10666f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER SystemTime;
10676f19c83bSHermès Bélusca-Maïto     TIME_FIELDS TimeFields;
10686f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry2;
10696f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry2;
10706f19c83bSHermès Bélusca-Maïto     PUCHAR Buffer;
10716f19c83bSHermès Bélusca-Maïto 
10726f19c83bSHermès Bélusca-Maïto     Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature;
10736f19c83bSHermès Bélusca-Maïto 
10746f19c83bSHermès Bélusca-Maïto     while (TRUE)
10756f19c83bSHermès Bélusca-Maïto     {
10766f19c83bSHermès Bélusca-Maïto         NtQuerySystemTime(&SystemTime);
10776f19c83bSHermès Bélusca-Maïto         RtlTimeToTimeFields(&SystemTime, &TimeFields);
10786f19c83bSHermès Bélusca-Maïto 
10796f19c83bSHermès Bélusca-Maïto         Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
10806f19c83bSHermès Bélusca-Maïto         Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
10816f19c83bSHermès Bélusca-Maïto         Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
10826f19c83bSHermès Bélusca-Maïto         Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
10836f19c83bSHermès Bélusca-Maïto 
10846f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer->Signature == 0)
10856f19c83bSHermès Bélusca-Maïto         {
10866f19c83bSHermès Bélusca-Maïto             continue;
10876f19c83bSHermès Bélusca-Maïto         }
10886f19c83bSHermès Bélusca-Maïto 
10896f19c83bSHermès Bélusca-Maïto         /* Check if the signature already exist */
10906f19c83bSHermès Bélusca-Maïto         /* FIXME:
10916f19c83bSHermès Bélusca-Maïto          *   Check also signatures from disks, which are
10926f19c83bSHermès Bélusca-Maïto          *   not visible (bootable) by the bios.
10936f19c83bSHermès Bélusca-Maïto          */
10946f19c83bSHermès Bélusca-Maïto         Entry2 = List->DiskListHead.Flink;
10956f19c83bSHermès Bélusca-Maïto         while (Entry2 != &List->DiskListHead)
10966f19c83bSHermès Bélusca-Maïto         {
10976f19c83bSHermès Bélusca-Maïto             DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry);
10986f19c83bSHermès Bélusca-Maïto 
10996f19c83bSHermès Bélusca-Maïto             if (DiskEntry != DiskEntry2 &&
11006f19c83bSHermès Bélusca-Maïto                 DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature)
11016f19c83bSHermès Bélusca-Maïto                 break;
11026f19c83bSHermès Bélusca-Maïto 
11036f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
11046f19c83bSHermès Bélusca-Maïto         }
11056f19c83bSHermès Bélusca-Maïto 
11066f19c83bSHermès Bélusca-Maïto         if (Entry2 == &List->DiskListHead)
11076f19c83bSHermès Bélusca-Maïto             break;
11086f19c83bSHermès Bélusca-Maïto     }
11096f19c83bSHermès Bélusca-Maïto }
11106f19c83bSHermès Bélusca-Maïto 
11116f19c83bSHermès Bélusca-Maïto static
11126f19c83bSHermès Bélusca-Maïto VOID
11136f19c83bSHermès Bélusca-Maïto UpdateDiskSignatures(
11146f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
11156f19c83bSHermès Bélusca-Maïto {
11166f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
11176f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
11186f19c83bSHermès Bélusca-Maïto 
11196f19c83bSHermès Bélusca-Maïto     /* Print partition lines */
11206f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
11216f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
11226f19c83bSHermès Bélusca-Maïto     {
11236f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
11246f19c83bSHermès Bélusca-Maïto 
11256f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer &&
11266f19c83bSHermès Bélusca-Maïto             DiskEntry->LayoutBuffer->Signature == 0)
11276f19c83bSHermès Bélusca-Maïto         {
11286f19c83bSHermès Bélusca-Maïto             SetDiskSignature(List, DiskEntry);
11296f19c83bSHermès Bélusca-Maïto             DiskEntry->LayoutBuffer->PartitionEntry[0].RewritePartition = TRUE;
11306f19c83bSHermès Bélusca-Maïto         }
11316f19c83bSHermès Bélusca-Maïto 
11326f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
11336f19c83bSHermès Bélusca-Maïto     }
11346f19c83bSHermès Bélusca-Maïto }
11356f19c83bSHermès Bélusca-Maïto 
11366f19c83bSHermès Bélusca-Maïto static
11376f19c83bSHermès Bélusca-Maïto VOID
11386f19c83bSHermès Bélusca-Maïto AddDiskToList(
11396f19c83bSHermès Bélusca-Maïto     IN HANDLE FileHandle,
11406f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
11416f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
11426f19c83bSHermès Bélusca-Maïto {
11436f19c83bSHermès Bélusca-Maïto     DISK_GEOMETRY DiskGeometry;
11446f19c83bSHermès Bélusca-Maïto     SCSI_ADDRESS ScsiAddress;
11456f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
11466f19c83bSHermès Bélusca-Maïto     IO_STATUS_BLOCK Iosb;
11476f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
11486f19c83bSHermès Bélusca-Maïto     PPARTITION_SECTOR Mbr;
11496f19c83bSHermès Bélusca-Maïto     PULONG Buffer;
11506f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER FileOffset;
11516f19c83bSHermès Bélusca-Maïto     WCHAR Identifier[20];
11526f19c83bSHermès Bélusca-Maïto     ULONG Checksum;
11536f19c83bSHermès Bélusca-Maïto     ULONG Signature;
11546f19c83bSHermès Bélusca-Maïto     ULONG i;
11556f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
11566f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry;
11576f19c83bSHermès Bélusca-Maïto     ULONG LayoutBufferSize;
11586f19c83bSHermès Bélusca-Maïto     PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
11596f19c83bSHermès Bélusca-Maïto 
1160f41750abSHermès Bélusca-Maïto     /* Retrieve the drive geometry */
11616f19c83bSHermès Bélusca-Maïto     Status = NtDeviceIoControlFile(FileHandle,
11626f19c83bSHermès Bélusca-Maïto                                    NULL,
11636f19c83bSHermès Bélusca-Maïto                                    NULL,
11646f19c83bSHermès Bélusca-Maïto                                    NULL,
11656f19c83bSHermès Bélusca-Maïto                                    &Iosb,
11666f19c83bSHermès Bélusca-Maïto                                    IOCTL_DISK_GET_DRIVE_GEOMETRY,
11676f19c83bSHermès Bélusca-Maïto                                    NULL,
11686f19c83bSHermès Bélusca-Maïto                                    0,
11696f19c83bSHermès Bélusca-Maïto                                    &DiskGeometry,
1170f41750abSHermès Bélusca-Maïto                                    sizeof(DiskGeometry));
11716f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
11726f19c83bSHermès Bélusca-Maïto         return;
11736f19c83bSHermès Bélusca-Maïto 
11746f19c83bSHermès Bélusca-Maïto     if (DiskGeometry.MediaType != FixedMedia &&
11756f19c83bSHermès Bélusca-Maïto         DiskGeometry.MediaType != RemovableMedia)
11766f19c83bSHermès Bélusca-Maïto     {
11776f19c83bSHermès Bélusca-Maïto         return;
11786f19c83bSHermès Bélusca-Maïto     }
11796f19c83bSHermès Bélusca-Maïto 
1180f41750abSHermès Bélusca-Maïto     /*
1181f41750abSHermès Bélusca-Maïto      * FIXME: Here we suppose the disk is always SCSI. What if it is
1182f41750abSHermès Bélusca-Maïto      * of another type? To check this we need to retrieve the name of
1183f41750abSHermès Bélusca-Maïto      * the driver the disk device belongs to.
1184f41750abSHermès Bélusca-Maïto      */
11856f19c83bSHermès Bélusca-Maïto     Status = NtDeviceIoControlFile(FileHandle,
11866f19c83bSHermès Bélusca-Maïto                                    NULL,
11876f19c83bSHermès Bélusca-Maïto                                    NULL,
11886f19c83bSHermès Bélusca-Maïto                                    NULL,
11896f19c83bSHermès Bélusca-Maïto                                    &Iosb,
11906f19c83bSHermès Bélusca-Maïto                                    IOCTL_SCSI_GET_ADDRESS,
11916f19c83bSHermès Bélusca-Maïto                                    NULL,
11926f19c83bSHermès Bélusca-Maïto                                    0,
11936f19c83bSHermès Bélusca-Maïto                                    &ScsiAddress,
1194f41750abSHermès Bélusca-Maïto                                    sizeof(ScsiAddress));
11956f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
11966f19c83bSHermès Bélusca-Maïto         return;
11976f19c83bSHermès Bélusca-Maïto 
11986f19c83bSHermès Bélusca-Maïto     /*
11996f19c83bSHermès Bélusca-Maïto      * Check whether the disk is initialized, by looking at its MBR.
12006f19c83bSHermès Bélusca-Maïto      * NOTE that this must be generalized to GPT disks as well!
12016f19c83bSHermès Bélusca-Maïto      */
12026f19c83bSHermès Bélusca-Maïto 
12036f19c83bSHermès Bélusca-Maïto     Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap,
12046f19c83bSHermès Bélusca-Maïto                                              0,
12056f19c83bSHermès Bélusca-Maïto                                              DiskGeometry.BytesPerSector);
12066f19c83bSHermès Bélusca-Maïto     if (Mbr == NULL)
12076f19c83bSHermès Bélusca-Maïto         return;
12086f19c83bSHermès Bélusca-Maïto 
12096f19c83bSHermès Bélusca-Maïto     FileOffset.QuadPart = 0;
12106f19c83bSHermès Bélusca-Maïto     Status = NtReadFile(FileHandle,
12116f19c83bSHermès Bélusca-Maïto                         NULL,
12126f19c83bSHermès Bélusca-Maïto                         NULL,
12136f19c83bSHermès Bélusca-Maïto                         NULL,
12146f19c83bSHermès Bélusca-Maïto                         &Iosb,
12156f19c83bSHermès Bélusca-Maïto                         (PVOID)Mbr,
12166f19c83bSHermès Bélusca-Maïto                         DiskGeometry.BytesPerSector,
12176f19c83bSHermès Bélusca-Maïto                         &FileOffset,
12186f19c83bSHermès Bélusca-Maïto                         NULL);
12196f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
12206f19c83bSHermès Bélusca-Maïto     {
12216f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, Mbr);
12226f19c83bSHermès Bélusca-Maïto         DPRINT1("NtReadFile failed, status=%x\n", Status);
12236f19c83bSHermès Bélusca-Maïto         return;
12246f19c83bSHermès Bélusca-Maïto     }
12256f19c83bSHermès Bélusca-Maïto     Signature = Mbr->Signature;
12266f19c83bSHermès Bélusca-Maïto 
12276f19c83bSHermès Bélusca-Maïto     /* Calculate the MBR checksum */
12286f19c83bSHermès Bélusca-Maïto     Checksum = 0;
12296f19c83bSHermès Bélusca-Maïto     Buffer = (PULONG)Mbr;
12306f19c83bSHermès Bélusca-Maïto     for (i = 0; i < 128; i++)
12316f19c83bSHermès Bélusca-Maïto     {
12326f19c83bSHermès Bélusca-Maïto         Checksum += Buffer[i];
12336f19c83bSHermès Bélusca-Maïto     }
12346f19c83bSHermès Bélusca-Maïto     Checksum = ~Checksum + 1;
12356f19c83bSHermès Bélusca-Maïto 
12366f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier),
12376f19c83bSHermès Bélusca-Maïto                         L"%08x-%08x-A", Checksum, Signature);
12386f19c83bSHermès Bélusca-Maïto     DPRINT("Identifier: %S\n", Identifier);
12396f19c83bSHermès Bélusca-Maïto 
12406f19c83bSHermès Bélusca-Maïto     DiskEntry = RtlAllocateHeap(ProcessHeap,
12416f19c83bSHermès Bélusca-Maïto                                 HEAP_ZERO_MEMORY,
12426f19c83bSHermès Bélusca-Maïto                                 sizeof(DISKENTRY));
12436f19c83bSHermès Bélusca-Maïto     if (DiskEntry == NULL)
12446f19c83bSHermès Bélusca-Maïto     {
1245f41750abSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, Mbr);
1246f41750abSHermès Bélusca-Maïto         DPRINT1("Failed to allocate a new disk entry.\n");
12476f19c83bSHermès Bélusca-Maïto         return;
12486f19c83bSHermès Bélusca-Maïto     }
12496f19c83bSHermès Bélusca-Maïto 
12506f19c83bSHermès Bélusca-Maïto //    DiskEntry->Checksum = Checksum;
12516f19c83bSHermès Bélusca-Maïto //    DiskEntry->Signature = Signature;
12526f19c83bSHermès Bélusca-Maïto     DiskEntry->BiosFound = FALSE;
12536f19c83bSHermès Bélusca-Maïto 
12546f19c83bSHermès Bélusca-Maïto     /*
12556f19c83bSHermès Bélusca-Maïto      * Check if this disk has a valid MBR: verify its signature,
12566f19c83bSHermès Bélusca-Maïto      * and whether its two first bytes are a valid instruction
12576f19c83bSHermès Bélusca-Maïto      * (related to this, see IsThereAValidBootSector() in partlist.c).
12586f19c83bSHermès Bélusca-Maïto      */
12596f19c83bSHermès Bélusca-Maïto     if (Mbr->Magic != 0xaa55 || (*(PUSHORT)Mbr->BootCode) == 0x0000)
12606f19c83bSHermès Bélusca-Maïto         DiskEntry->NoMbr = TRUE;
12616f19c83bSHermès Bélusca-Maïto     else
12626f19c83bSHermès Bélusca-Maïto         DiskEntry->NoMbr = FALSE;
12636f19c83bSHermès Bélusca-Maïto 
12646f19c83bSHermès Bélusca-Maïto     /* Free the MBR sector buffer */
12656f19c83bSHermès Bélusca-Maïto     RtlFreeHeap(ProcessHeap, 0, Mbr);
12666f19c83bSHermès Bélusca-Maïto 
12676f19c83bSHermès Bélusca-Maïto 
12686f19c83bSHermès Bélusca-Maïto     ListEntry = List->BiosDiskListHead.Flink;
12696f19c83bSHermès Bélusca-Maïto     while (ListEntry != &List->BiosDiskListHead)
12706f19c83bSHermès Bélusca-Maïto     {
12716f19c83bSHermès Bélusca-Maïto         BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
12726f19c83bSHermès Bélusca-Maïto         /* FIXME:
12736f19c83bSHermès Bélusca-Maïto          *   Compare the size from bios and the reported size from driver.
12746f19c83bSHermès Bélusca-Maïto          *   If we have more than one disk with a zero or with the same signature
12756f19c83bSHermès Bélusca-Maïto          *   we must create new signatures and reboot. After the reboot,
12766f19c83bSHermès Bélusca-Maïto          *   it is possible to identify the disks.
12776f19c83bSHermès Bélusca-Maïto          */
12786f19c83bSHermès Bélusca-Maïto         if (BiosDiskEntry->Signature == Signature &&
12796f19c83bSHermès Bélusca-Maïto             BiosDiskEntry->Checksum == Checksum &&
12806f19c83bSHermès Bélusca-Maïto             !BiosDiskEntry->Recognized)
12816f19c83bSHermès Bélusca-Maïto         {
12826f19c83bSHermès Bélusca-Maïto             if (!DiskEntry->BiosFound)
12836f19c83bSHermès Bélusca-Maïto             {
12846f19c83bSHermès Bélusca-Maïto                 DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
12856f19c83bSHermès Bélusca-Maïto                 DiskEntry->BiosFound = TRUE;
12866f19c83bSHermès Bélusca-Maïto                 BiosDiskEntry->Recognized = TRUE;
12876f19c83bSHermès Bélusca-Maïto             }
12886f19c83bSHermès Bélusca-Maïto             else
12896f19c83bSHermès Bélusca-Maïto             {
1290f41750abSHermès Bélusca-Maïto                 // FIXME: What to do?
12916f19c83bSHermès Bélusca-Maïto             }
12926f19c83bSHermès Bélusca-Maïto         }
12936f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
12946f19c83bSHermès Bélusca-Maïto     }
12956f19c83bSHermès Bélusca-Maïto 
12966f19c83bSHermès Bélusca-Maïto     if (!DiskEntry->BiosFound)
12976f19c83bSHermès Bélusca-Maïto     {
12986f19c83bSHermès Bélusca-Maïto #if 0
12996f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, DiskEntry);
13006f19c83bSHermès Bélusca-Maïto         return;
13016f19c83bSHermès Bélusca-Maïto #else
13026f19c83bSHermè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);
13036f19c83bSHermès Bélusca-Maïto #endif
13046f19c83bSHermès Bélusca-Maïto     }
13056f19c83bSHermès Bélusca-Maïto 
13066f19c83bSHermès Bélusca-Maïto     InitializeListHead(&DiskEntry->PrimaryPartListHead);
13076f19c83bSHermès Bélusca-Maïto     InitializeListHead(&DiskEntry->LogicalPartListHead);
13086f19c83bSHermès Bélusca-Maïto 
13096f19c83bSHermès Bélusca-Maïto     DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
13106f19c83bSHermès Bélusca-Maïto     DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
13116f19c83bSHermès Bélusca-Maïto     DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
13126f19c83bSHermès Bélusca-Maïto     DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
13136f19c83bSHermès Bélusca-Maïto 
13146f19c83bSHermès Bélusca-Maïto     DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
13156f19c83bSHermès Bélusca-Maïto     DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder);
13166f19c83bSHermès Bélusca-Maïto     DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack);
13176f19c83bSHermès Bélusca-Maïto     DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector);
13186f19c83bSHermès Bélusca-Maïto 
13196f19c83bSHermès Bélusca-Maïto     DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
13206f19c83bSHermès Bélusca-Maïto                                       (ULONGLONG)DiskGeometry.TracksPerCylinder *
13216f19c83bSHermès Bélusca-Maïto                                       (ULONGLONG)DiskGeometry.SectorsPerTrack;
13226f19c83bSHermès Bélusca-Maïto 
13236f19c83bSHermès Bélusca-Maïto     DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
13246f19c83bSHermès Bélusca-Maïto     DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder *
13256f19c83bSHermès Bélusca-Maïto                                    DiskGeometry.SectorsPerTrack;
13266f19c83bSHermès Bélusca-Maïto 
13276f19c83bSHermès Bélusca-Maïto     DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart);
13286f19c83bSHermès Bélusca-Maïto     DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment);
13296f19c83bSHermès Bélusca-Maïto 
13306f19c83bSHermès Bélusca-Maïto     DiskEntry->DiskNumber = DiskNumber;
13316f19c83bSHermès Bélusca-Maïto     DiskEntry->Port = ScsiAddress.PortNumber;
13326f19c83bSHermès Bélusca-Maïto     DiskEntry->Bus = ScsiAddress.PathId;
13336f19c83bSHermès Bélusca-Maïto     DiskEntry->Id = ScsiAddress.TargetId;
13346f19c83bSHermès Bélusca-Maïto 
13356f19c83bSHermès Bélusca-Maïto     GetDriverName(DiskEntry);
13366f19c83bSHermès Bélusca-Maïto     /*
13376f19c83bSHermès Bélusca-Maïto      * Actually it would be more correct somehow to use:
13386f19c83bSHermès Bélusca-Maïto      *
13396f19c83bSHermès Bélusca-Maïto      * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo;
13406f19c83bSHermès Bélusca-Maïto      * ULONG ReturnedLength;
13416f19c83bSHermès Bélusca-Maïto      *
13426f19c83bSHermès Bélusca-Maïto      * Status = NtQueryObject(SomeHandleToTheDisk,
13436f19c83bSHermès Bélusca-Maïto      *                        ObjectNameInformation,
13446f19c83bSHermès Bélusca-Maïto      *                        &NameInfo,
13456f19c83bSHermès Bélusca-Maïto      *                        sizeof(NameInfo),
13466f19c83bSHermès Bélusca-Maïto      *                        &ReturnedLength);
13476f19c83bSHermès Bélusca-Maïto      * etc...
13486f19c83bSHermès Bélusca-Maïto      *
13496f19c83bSHermè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
13506f19c83bSHermès Bélusca-Maïto      */
13516f19c83bSHermès Bélusca-Maïto 
13526f19c83bSHermès Bélusca-Maïto     InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
13536f19c83bSHermès Bélusca-Maïto 
1354f41750abSHermès Bélusca-Maïto 
1355f41750abSHermès Bélusca-Maïto     /*
1356f41750abSHermès Bélusca-Maïto      * We now retrieve the disk partition layout
1357f41750abSHermès Bélusca-Maïto      */
1358f41750abSHermès Bélusca-Maïto 
13596f19c83bSHermès Bélusca-Maïto     /* Allocate a layout buffer with 4 partition entries first */
13606f19c83bSHermès Bélusca-Maïto     LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
13616f19c83bSHermès Bélusca-Maïto                        ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
13626f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer = RtlAllocateHeap(ProcessHeap,
13636f19c83bSHermès Bélusca-Maïto                                               HEAP_ZERO_MEMORY,
13646f19c83bSHermès Bélusca-Maïto                                               LayoutBufferSize);
13656f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer == NULL)
13666f19c83bSHermès Bélusca-Maïto     {
13676f19c83bSHermès Bélusca-Maïto         DPRINT1("Failed to allocate the disk layout buffer!\n");
13686f19c83bSHermès Bélusca-Maïto         return;
13696f19c83bSHermès Bélusca-Maïto     }
13706f19c83bSHermès Bélusca-Maïto 
1371f41750abSHermès Bélusca-Maïto     /* Keep looping while the drive layout buffer is too small */
13726f19c83bSHermès Bélusca-Maïto     for (;;)
13736f19c83bSHermès Bélusca-Maïto     {
13746f19c83bSHermès Bélusca-Maïto         DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
13756f19c83bSHermès Bélusca-Maïto         Status = NtDeviceIoControlFile(FileHandle,
13766f19c83bSHermès Bélusca-Maïto                                        NULL,
13776f19c83bSHermès Bélusca-Maïto                                        NULL,
13786f19c83bSHermès Bélusca-Maïto                                        NULL,
13796f19c83bSHermès Bélusca-Maïto                                        &Iosb,
13806f19c83bSHermès Bélusca-Maïto                                        IOCTL_DISK_GET_DRIVE_LAYOUT,
13816f19c83bSHermès Bélusca-Maïto                                        NULL,
13826f19c83bSHermès Bélusca-Maïto                                        0,
13836f19c83bSHermès Bélusca-Maïto                                        DiskEntry->LayoutBuffer,
13846f19c83bSHermès Bélusca-Maïto                                        LayoutBufferSize);
13856f19c83bSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
13866f19c83bSHermès Bélusca-Maïto             break;
13876f19c83bSHermès Bélusca-Maïto 
13886f19c83bSHermès Bélusca-Maïto         if (Status != STATUS_BUFFER_TOO_SMALL)
13896f19c83bSHermès Bélusca-Maïto         {
13906f19c83bSHermès Bélusca-Maïto             DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
13916f19c83bSHermès Bélusca-Maïto             return;
13926f19c83bSHermès Bélusca-Maïto         }
13936f19c83bSHermès Bélusca-Maïto 
13946f19c83bSHermès Bélusca-Maïto         LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
13956f19c83bSHermès Bélusca-Maïto         NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
13966f19c83bSHermès Bélusca-Maïto                                             HEAP_ZERO_MEMORY,
13976f19c83bSHermès Bélusca-Maïto                                             DiskEntry->LayoutBuffer,
13986f19c83bSHermès Bélusca-Maïto                                             LayoutBufferSize);
13996f19c83bSHermès Bélusca-Maïto         if (NewLayoutBuffer == NULL)
14006f19c83bSHermès Bélusca-Maïto         {
14016f19c83bSHermès Bélusca-Maïto             DPRINT1("Failed to reallocate the disk layout buffer!\n");
14026f19c83bSHermès Bélusca-Maïto             return;
14036f19c83bSHermès Bélusca-Maïto         }
14046f19c83bSHermès Bélusca-Maïto 
14056f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer = NewLayoutBuffer;
14066f19c83bSHermès Bélusca-Maïto     }
14076f19c83bSHermès Bélusca-Maïto 
14086f19c83bSHermès Bélusca-Maïto     DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
14096f19c83bSHermès Bélusca-Maïto 
14106f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
14116f19c83bSHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
14126f19c83bSHermès Bélusca-Maïto #endif
14136f19c83bSHermès Bélusca-Maïto 
14146f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
14156f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 &&
14166f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != PARTITION_ENTRY_UNUSED)
14176f19c83bSHermès Bélusca-Maïto     {
14186f19c83bSHermès Bélusca-Maïto         if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
14196f19c83bSHermès Bélusca-Maïto         {
14206f19c83bSHermès Bélusca-Maïto             DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
14216f19c83bSHermès Bélusca-Maïto         }
14226f19c83bSHermès Bélusca-Maïto         else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
14236f19c83bSHermès Bélusca-Maïto         {
14246f19c83bSHermès Bélusca-Maïto             DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
14256f19c83bSHermès Bélusca-Maïto         }
14266f19c83bSHermès Bélusca-Maïto         else
14276f19c83bSHermès Bélusca-Maïto         {
14286f19c83bSHermès Bélusca-Maïto             DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
14296f19c83bSHermès Bélusca-Maïto         }
14306f19c83bSHermès Bélusca-Maïto     }
14316f19c83bSHermès Bélusca-Maïto     else
14326f19c83bSHermès Bélusca-Maïto     {
14336f19c83bSHermès Bélusca-Maïto         DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
14346f19c83bSHermès Bélusca-Maïto     }
14356f19c83bSHermès Bélusca-Maïto 
14366f19c83bSHermès Bélusca-Maïto 
14376f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer->PartitionCount == 0)
14386f19c83bSHermès Bélusca-Maïto     {
14396f19c83bSHermès Bélusca-Maïto         DiskEntry->NewDisk = TRUE;
14406f19c83bSHermès Bélusca-Maïto         DiskEntry->LayoutBuffer->PartitionCount = 4;
14416f19c83bSHermès Bélusca-Maïto 
14426f19c83bSHermès Bélusca-Maïto         for (i = 0; i < 4; i++)
14436f19c83bSHermès Bélusca-Maïto             DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
14446f19c83bSHermès Bélusca-Maïto     }
14456f19c83bSHermès Bélusca-Maïto     else
14466f19c83bSHermès Bélusca-Maïto     {
14476f19c83bSHermès Bélusca-Maïto         for (i = 0; i < 4; i++)
14486f19c83bSHermès Bélusca-Maïto         {
14496f19c83bSHermès Bélusca-Maïto             AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
14506f19c83bSHermès Bélusca-Maïto         }
14516f19c83bSHermès Bélusca-Maïto 
14526f19c83bSHermès Bélusca-Maïto         for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
14536f19c83bSHermès Bélusca-Maïto         {
14546f19c83bSHermès Bélusca-Maïto             AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
14556f19c83bSHermès Bélusca-Maïto         }
14566f19c83bSHermès Bélusca-Maïto     }
14576f19c83bSHermès Bélusca-Maïto 
14586f19c83bSHermès Bélusca-Maïto     ScanForUnpartitionedDiskSpace(DiskEntry);
14596f19c83bSHermès Bélusca-Maïto }
14606f19c83bSHermès Bélusca-Maïto 
14616f19c83bSHermès Bélusca-Maïto PPARTLIST
14626f19c83bSHermès Bélusca-Maïto CreatePartitionList(VOID)
14636f19c83bSHermès Bélusca-Maïto {
14646f19c83bSHermès Bélusca-Maïto     PPARTLIST List;
14656f19c83bSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
14666f19c83bSHermès Bélusca-Maïto     SYSTEM_DEVICE_INFORMATION Sdi;
14676f19c83bSHermès Bélusca-Maïto     IO_STATUS_BLOCK Iosb;
14686f19c83bSHermès Bélusca-Maïto     ULONG ReturnSize;
14696f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
14706f19c83bSHermès Bélusca-Maïto     ULONG DiskNumber;
14716f19c83bSHermès Bélusca-Maïto     WCHAR Buffer[MAX_PATH];
14726f19c83bSHermès Bélusca-Maïto     UNICODE_STRING Name;
14736f19c83bSHermès Bélusca-Maïto     HANDLE FileHandle;
14746f19c83bSHermès Bélusca-Maïto 
14756f19c83bSHermès Bélusca-Maïto     List = (PPARTLIST)RtlAllocateHeap(ProcessHeap,
14766f19c83bSHermès Bélusca-Maïto                                       0,
14776f19c83bSHermès Bélusca-Maïto                                       sizeof(PARTLIST));
14786f19c83bSHermès Bélusca-Maïto     if (List == NULL)
14796f19c83bSHermès Bélusca-Maïto         return NULL;
14806f19c83bSHermès Bélusca-Maïto 
14816f19c83bSHermès Bélusca-Maïto     List->CurrentDisk = NULL;
14826f19c83bSHermès Bélusca-Maïto     List->CurrentPartition = NULL;
14836f19c83bSHermès Bélusca-Maïto 
14846f19c83bSHermès Bélusca-Maïto     List->SystemPartition = NULL;
14856f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = NULL;
14866f19c83bSHermès Bélusca-Maïto 
14876f19c83bSHermès Bélusca-Maïto     InitializeListHead(&List->DiskListHead);
14886f19c83bSHermès Bélusca-Maïto     InitializeListHead(&List->BiosDiskListHead);
14896f19c83bSHermès Bélusca-Maïto 
1490f41750abSHermès Bélusca-Maïto     /*
1491f41750abSHermès Bélusca-Maïto      * Enumerate the disks seen by the BIOS; this will be used later
1492f41750abSHermès Bélusca-Maïto      * to map drives seen by NTOS with their corresponding BIOS names.
1493f41750abSHermès Bélusca-Maïto      */
14946f19c83bSHermès Bélusca-Maïto     EnumerateBiosDiskEntries(List);
14956f19c83bSHermès Bélusca-Maïto 
1496f41750abSHermès Bélusca-Maïto     /* Enumerate disks seen by NTOS */
14976f19c83bSHermès Bélusca-Maïto     Status = NtQuerySystemInformation(SystemDeviceInformation,
14986f19c83bSHermès Bélusca-Maïto                                       &Sdi,
14996f19c83bSHermès Bélusca-Maïto                                       sizeof(Sdi),
15006f19c83bSHermès Bélusca-Maïto                                       &ReturnSize);
15016f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
15026f19c83bSHermès Bélusca-Maïto     {
15036f19c83bSHermès Bélusca-Maïto         DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status);
15046f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, List);
15056f19c83bSHermès Bélusca-Maïto         return NULL;
15066f19c83bSHermès Bélusca-Maïto     }
15076f19c83bSHermès Bélusca-Maïto 
15086f19c83bSHermès Bélusca-Maïto     for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
15096f19c83bSHermès Bélusca-Maïto     {
15106f19c83bSHermès Bélusca-Maïto         RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer),
15116f19c83bSHermès Bélusca-Maïto                             L"\\Device\\Harddisk%lu\\Partition0",
15126f19c83bSHermès Bélusca-Maïto                             DiskNumber);
15136f19c83bSHermès Bélusca-Maïto         RtlInitUnicodeString(&Name, Buffer);
15146f19c83bSHermès Bélusca-Maïto 
15156f19c83bSHermès Bélusca-Maïto         InitializeObjectAttributes(&ObjectAttributes,
15166f19c83bSHermès Bélusca-Maïto                                    &Name,
1517765994c9SHermès Bélusca-Maïto                                    OBJ_CASE_INSENSITIVE,
15186f19c83bSHermès Bélusca-Maïto                                    NULL,
15196f19c83bSHermès Bélusca-Maïto                                    NULL);
15206f19c83bSHermès Bélusca-Maïto 
15216f19c83bSHermès Bélusca-Maïto         Status = NtOpenFile(&FileHandle,
15226f19c83bSHermès Bélusca-Maïto                             FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
15236f19c83bSHermès Bélusca-Maïto                             &ObjectAttributes,
15246f19c83bSHermès Bélusca-Maïto                             &Iosb,
1525f41750abSHermès Bélusca-Maïto                             FILE_SHARE_READ | FILE_SHARE_WRITE,
15266f19c83bSHermès Bélusca-Maïto                             FILE_SYNCHRONOUS_IO_NONALERT);
15276f19c83bSHermès Bélusca-Maïto         if (NT_SUCCESS(Status))
15286f19c83bSHermès Bélusca-Maïto         {
15296f19c83bSHermès Bélusca-Maïto             AddDiskToList(FileHandle, DiskNumber, List);
15306f19c83bSHermès Bélusca-Maïto             NtClose(FileHandle);
15316f19c83bSHermès Bélusca-Maïto         }
15326f19c83bSHermès Bélusca-Maïto     }
15336f19c83bSHermès Bélusca-Maïto 
15346f19c83bSHermès Bélusca-Maïto     UpdateDiskSignatures(List);
15356f19c83bSHermès Bélusca-Maïto 
15366f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
15376f19c83bSHermès Bélusca-Maïto 
15386f19c83bSHermès Bélusca-Maïto     /* Search for first usable disk and partition */
15396f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
15406f19c83bSHermès Bélusca-Maïto     {
15416f19c83bSHermès Bélusca-Maïto         List->CurrentDisk = NULL;
15426f19c83bSHermès Bélusca-Maïto         List->CurrentPartition = NULL;
15436f19c83bSHermès Bélusca-Maïto     }
15446f19c83bSHermès Bélusca-Maïto     else
15456f19c83bSHermès Bélusca-Maïto     {
15466f19c83bSHermès Bélusca-Maïto         List->CurrentDisk = CONTAINING_RECORD(List->DiskListHead.Flink,
15476f19c83bSHermès Bélusca-Maïto                                               DISKENTRY,
15486f19c83bSHermès Bélusca-Maïto                                               ListEntry);
15496f19c83bSHermès Bélusca-Maïto 
15506f19c83bSHermès Bélusca-Maïto         if (IsListEmpty(&List->CurrentDisk->PrimaryPartListHead))
15516f19c83bSHermès Bélusca-Maïto         {
15526f19c83bSHermès Bélusca-Maïto             List->CurrentPartition = NULL;
15536f19c83bSHermès Bélusca-Maïto         }
15546f19c83bSHermès Bélusca-Maïto         else
15556f19c83bSHermès Bélusca-Maïto         {
15566f19c83bSHermès Bélusca-Maïto             List->CurrentPartition = CONTAINING_RECORD(List->CurrentDisk->PrimaryPartListHead.Flink,
15576f19c83bSHermès Bélusca-Maïto                                                        PARTENTRY,
15586f19c83bSHermès Bélusca-Maïto                                                        ListEntry);
15596f19c83bSHermès Bélusca-Maïto         }
15606f19c83bSHermès Bélusca-Maïto     }
15616f19c83bSHermès Bélusca-Maïto 
15626f19c83bSHermès Bélusca-Maïto     return List;
15636f19c83bSHermès Bélusca-Maïto }
15646f19c83bSHermès Bélusca-Maïto 
15656f19c83bSHermès Bélusca-Maïto VOID
15666f19c83bSHermès Bélusca-Maïto DestroyPartitionList(
15676f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
15686f19c83bSHermès Bélusca-Maïto {
15696f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
15706f19c83bSHermès Bélusca-Maïto     PBIOSDISKENTRY BiosDiskEntry;
15716f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
15726f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
15736f19c83bSHermès Bélusca-Maïto 
15746f19c83bSHermès Bélusca-Maïto     /* Release disk and partition info */
15756f19c83bSHermès Bélusca-Maïto     while (!IsListEmpty(&List->DiskListHead))
15766f19c83bSHermès Bélusca-Maïto     {
15776f19c83bSHermès Bélusca-Maïto         Entry = RemoveHeadList(&List->DiskListHead);
15786f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
15796f19c83bSHermès Bélusca-Maïto 
15806f19c83bSHermès Bélusca-Maïto         /* Release driver name */
15816f19c83bSHermès Bélusca-Maïto         RtlFreeUnicodeString(&DiskEntry->DriverName);
15826f19c83bSHermès Bélusca-Maïto 
15836f19c83bSHermès Bélusca-Maïto         /* Release primary partition list */
15846f19c83bSHermès Bélusca-Maïto         while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
15856f19c83bSHermès Bélusca-Maïto         {
15866f19c83bSHermès Bélusca-Maïto             Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
15876f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
15886f19c83bSHermès Bélusca-Maïto 
15896f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, PartEntry);
15906f19c83bSHermès Bélusca-Maïto         }
15916f19c83bSHermès Bélusca-Maïto 
15926f19c83bSHermès Bélusca-Maïto         /* Release logical partition list */
15936f19c83bSHermès Bélusca-Maïto         while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
15946f19c83bSHermès Bélusca-Maïto         {
15956f19c83bSHermès Bélusca-Maïto             Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
15966f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
15976f19c83bSHermès Bélusca-Maïto 
15986f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, PartEntry);
15996f19c83bSHermès Bélusca-Maïto         }
16006f19c83bSHermès Bélusca-Maïto 
16016f19c83bSHermès Bélusca-Maïto         /* Release layout buffer */
16026f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer != NULL)
16036f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
16046f19c83bSHermès Bélusca-Maïto 
16056f19c83bSHermès Bélusca-Maïto         /* Release disk entry */
16066f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, DiskEntry);
16076f19c83bSHermès Bélusca-Maïto     }
16086f19c83bSHermès Bélusca-Maïto 
16096f19c83bSHermès Bélusca-Maïto     /* Release the bios disk info */
16106f19c83bSHermès Bélusca-Maïto     while (!IsListEmpty(&List->BiosDiskListHead))
16116f19c83bSHermès Bélusca-Maïto     {
16126f19c83bSHermès Bélusca-Maïto         Entry = RemoveHeadList(&List->BiosDiskListHead);
16136f19c83bSHermès Bélusca-Maïto         BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
16146f19c83bSHermès Bélusca-Maïto 
16156f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
16166f19c83bSHermès Bélusca-Maïto     }
16176f19c83bSHermès Bélusca-Maïto 
16186f19c83bSHermès Bélusca-Maïto     /* Release list head */
16196f19c83bSHermès Bélusca-Maïto     RtlFreeHeap(ProcessHeap, 0, List);
16206f19c83bSHermès Bélusca-Maïto }
16216f19c83bSHermès Bélusca-Maïto 
16226f19c83bSHermès Bélusca-Maïto PDISKENTRY
16236f19c83bSHermès Bélusca-Maïto GetDiskByBiosNumber(
16246f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
16256f19c83bSHermès Bélusca-Maïto     IN ULONG BiosDiskNumber)
16266f19c83bSHermès Bélusca-Maïto {
16276f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
16286f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
16296f19c83bSHermès Bélusca-Maïto 
16306f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
16316f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
16326f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
16336f19c83bSHermès Bélusca-Maïto     {
16346f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
16356f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
16366f19c83bSHermès Bélusca-Maïto 
16376f19c83bSHermès Bélusca-Maïto         if (DiskEntry->BiosDiskNumber == BiosDiskNumber)
16386f19c83bSHermès Bélusca-Maïto         {
16396f19c83bSHermès Bélusca-Maïto             /* Disk found */
16406f19c83bSHermès Bélusca-Maïto             return DiskEntry;
16416f19c83bSHermès Bélusca-Maïto         }
16426f19c83bSHermès Bélusca-Maïto     }
16436f19c83bSHermès Bélusca-Maïto 
16446f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
16456f19c83bSHermès Bélusca-Maïto     return NULL;
16466f19c83bSHermès Bélusca-Maïto }
16476f19c83bSHermès Bélusca-Maïto 
16486f19c83bSHermès Bélusca-Maïto PDISKENTRY
16496f19c83bSHermès Bélusca-Maïto GetDiskByNumber(
16506f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
16516f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber)
16526f19c83bSHermès Bélusca-Maïto {
16536f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
16546f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
16556f19c83bSHermès Bélusca-Maïto 
16566f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
16576f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
16586f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
16596f19c83bSHermès Bélusca-Maïto     {
16606f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
16616f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
16626f19c83bSHermès Bélusca-Maïto 
16636f19c83bSHermès Bélusca-Maïto         if (DiskEntry->DiskNumber == DiskNumber)
16646f19c83bSHermès Bélusca-Maïto         {
16656f19c83bSHermès Bélusca-Maïto             /* Disk found */
16666f19c83bSHermès Bélusca-Maïto             return DiskEntry;
16676f19c83bSHermès Bélusca-Maïto         }
16686f19c83bSHermès Bélusca-Maïto     }
16696f19c83bSHermès Bélusca-Maïto 
16706f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
16716f19c83bSHermès Bélusca-Maïto     return NULL;
16726f19c83bSHermès Bélusca-Maïto }
16736f19c83bSHermès Bélusca-Maïto 
16746f19c83bSHermès Bélusca-Maïto PDISKENTRY
16756f19c83bSHermès Bélusca-Maïto GetDiskBySCSI(
16766f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
16776f19c83bSHermès Bélusca-Maïto     IN USHORT Port,
16786f19c83bSHermès Bélusca-Maïto     IN USHORT Bus,
16796f19c83bSHermès Bélusca-Maïto     IN USHORT Id)
16806f19c83bSHermès Bélusca-Maïto {
16816f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
16826f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
16836f19c83bSHermès Bélusca-Maïto 
16846f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
16856f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
16866f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
16876f19c83bSHermès Bélusca-Maïto     {
16886f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
16896f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
16906f19c83bSHermès Bélusca-Maïto 
16916f19c83bSHermès Bélusca-Maïto         if (DiskEntry->Port == Port &&
16926f19c83bSHermès Bélusca-Maïto             DiskEntry->Bus  == Bus  &&
16936f19c83bSHermès Bélusca-Maïto             DiskEntry->Id   == Id)
16946f19c83bSHermès Bélusca-Maïto         {
16956f19c83bSHermès Bélusca-Maïto             /* Disk found */
16966f19c83bSHermès Bélusca-Maïto             return DiskEntry;
16976f19c83bSHermès Bélusca-Maïto         }
16986f19c83bSHermès Bélusca-Maïto     }
16996f19c83bSHermès Bélusca-Maïto 
17006f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
17016f19c83bSHermès Bélusca-Maïto     return NULL;
17026f19c83bSHermès Bélusca-Maïto }
17036f19c83bSHermès Bélusca-Maïto 
17046f19c83bSHermès Bélusca-Maïto PDISKENTRY
17056f19c83bSHermès Bélusca-Maïto GetDiskBySignature(
17066f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
17076f19c83bSHermès Bélusca-Maïto     IN ULONG Signature)
17086f19c83bSHermès Bélusca-Maïto {
17096f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
17106f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
17116f19c83bSHermès Bélusca-Maïto 
17126f19c83bSHermès Bélusca-Maïto     /* Loop over the disks and find the correct one */
17136f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
17146f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
17156f19c83bSHermès Bélusca-Maïto     {
17166f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
17176f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
17186f19c83bSHermès Bélusca-Maïto 
17196f19c83bSHermès Bélusca-Maïto         if (DiskEntry->LayoutBuffer->Signature == Signature)
17206f19c83bSHermès Bélusca-Maïto         {
17216f19c83bSHermès Bélusca-Maïto             /* Disk found */
17226f19c83bSHermès Bélusca-Maïto             return DiskEntry;
17236f19c83bSHermès Bélusca-Maïto         }
17246f19c83bSHermès Bélusca-Maïto     }
17256f19c83bSHermès Bélusca-Maïto 
17266f19c83bSHermès Bélusca-Maïto     /* Disk not found, stop there */
17276f19c83bSHermès Bélusca-Maïto     return NULL;
17286f19c83bSHermès Bélusca-Maïto }
17296f19c83bSHermès Bélusca-Maïto 
17306f19c83bSHermès Bélusca-Maïto PPARTENTRY
17316f19c83bSHermès Bélusca-Maïto GetPartition(
17326f19c83bSHermès Bélusca-Maïto     // IN PPARTLIST List,
17336f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
17346f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionNumber)
17356f19c83bSHermès Bélusca-Maïto {
17366f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
17376f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
17386f19c83bSHermès Bélusca-Maïto 
17396f19c83bSHermès Bélusca-Maïto     /* Disk found, loop over the primary partitions first... */
17406f19c83bSHermès Bélusca-Maïto     Entry = DiskEntry->PrimaryPartListHead.Flink;
17416f19c83bSHermès Bélusca-Maïto     while (Entry != &DiskEntry->PrimaryPartListHead)
17426f19c83bSHermès Bélusca-Maïto     {
17436f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
17446f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
17456f19c83bSHermès Bélusca-Maïto 
17466f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionNumber == PartitionNumber)
17476f19c83bSHermès Bélusca-Maïto         {
17486f19c83bSHermès Bélusca-Maïto             /* Partition found */
17496f19c83bSHermès Bélusca-Maïto             return PartEntry;
17506f19c83bSHermès Bélusca-Maïto         }
17516f19c83bSHermès Bélusca-Maïto     }
17526f19c83bSHermès Bélusca-Maïto 
17536f19c83bSHermès Bélusca-Maïto     /* ... then over the logical partitions if needed */
17546f19c83bSHermès Bélusca-Maïto     Entry = DiskEntry->LogicalPartListHead.Flink;
17556f19c83bSHermès Bélusca-Maïto     while (Entry != &DiskEntry->LogicalPartListHead)
17566f19c83bSHermès Bélusca-Maïto     {
17576f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
17586f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
17596f19c83bSHermès Bélusca-Maïto 
17606f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionNumber == PartitionNumber)
17616f19c83bSHermès Bélusca-Maïto         {
17626f19c83bSHermès Bélusca-Maïto             /* Partition found */
17636f19c83bSHermès Bélusca-Maïto             return PartEntry;
17646f19c83bSHermès Bélusca-Maïto         }
17656f19c83bSHermès Bélusca-Maïto     }
17666f19c83bSHermès Bélusca-Maïto 
17676f19c83bSHermès Bélusca-Maïto     /* The partition was not found on the disk, stop there */
17686f19c83bSHermès Bélusca-Maïto     return NULL;
17696f19c83bSHermès Bélusca-Maïto }
17706f19c83bSHermès Bélusca-Maïto 
17716f19c83bSHermès Bélusca-Maïto BOOLEAN
17726f19c83bSHermès Bélusca-Maïto GetDiskOrPartition(
17736f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
17746f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
17756f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionNumber OPTIONAL,
17766f19c83bSHermès Bélusca-Maïto     OUT PDISKENTRY* pDiskEntry,
17776f19c83bSHermès Bélusca-Maïto     OUT PPARTENTRY* pPartEntry OPTIONAL)
17786f19c83bSHermès Bélusca-Maïto {
17796f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
17806f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry = NULL;
17816f19c83bSHermès Bélusca-Maïto 
17826f19c83bSHermès Bélusca-Maïto     /* Find the disk */
17836f19c83bSHermès Bélusca-Maïto     DiskEntry = GetDiskByNumber(List, DiskNumber);
17846f19c83bSHermès Bélusca-Maïto     if (!DiskEntry)
17856f19c83bSHermès Bélusca-Maïto         return FALSE;
17866f19c83bSHermès Bélusca-Maïto 
17876f19c83bSHermès Bélusca-Maïto     /* If we have a partition (PartitionNumber != 0), find it */
17886f19c83bSHermès Bélusca-Maïto     if (PartitionNumber != 0)
17896f19c83bSHermès Bélusca-Maïto     {
17906f19c83bSHermès Bélusca-Maïto         PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
17916f19c83bSHermès Bélusca-Maïto         if (!PartEntry)
17926f19c83bSHermès Bélusca-Maïto             return FALSE;
17936f19c83bSHermès Bélusca-Maïto         ASSERT(PartEntry->DiskEntry == DiskEntry);
17946f19c83bSHermès Bélusca-Maïto     }
17956f19c83bSHermès Bélusca-Maïto 
17966f19c83bSHermès Bélusca-Maïto     /* Return the disk (and optionally the partition) */
17976f19c83bSHermès Bélusca-Maïto     *pDiskEntry = DiskEntry;
17986f19c83bSHermès Bélusca-Maïto     if (pPartEntry) *pPartEntry = PartEntry;
17996f19c83bSHermès Bélusca-Maïto     return TRUE;
18006f19c83bSHermès Bélusca-Maïto }
18016f19c83bSHermès Bélusca-Maïto 
18026f19c83bSHermès Bélusca-Maïto //
18036f19c83bSHermès Bélusca-Maïto // NOTE: Was introduced broken in r6258 by Casper
18046f19c83bSHermès Bélusca-Maïto //
18056f19c83bSHermès Bélusca-Maïto BOOLEAN
18066f19c83bSHermès Bélusca-Maïto SelectPartition(
18076f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
18086f19c83bSHermès Bélusca-Maïto     IN ULONG DiskNumber,
18096f19c83bSHermès Bélusca-Maïto     IN ULONG PartitionNumber)
18106f19c83bSHermès Bélusca-Maïto {
18116f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
18126f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
18136f19c83bSHermès Bélusca-Maïto 
18146f19c83bSHermès Bélusca-Maïto     DiskEntry = GetDiskByNumber(List, DiskNumber);
18156f19c83bSHermès Bélusca-Maïto     if (!DiskEntry)
18166f19c83bSHermès Bélusca-Maïto         return FALSE;
18176f19c83bSHermès Bélusca-Maïto 
18186f19c83bSHermès Bélusca-Maïto     PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
18196f19c83bSHermès Bélusca-Maïto     if (!PartEntry)
18206f19c83bSHermès Bélusca-Maïto         return FALSE;
18216f19c83bSHermès Bélusca-Maïto 
18226f19c83bSHermès Bélusca-Maïto     ASSERT(PartEntry->DiskEntry == DiskEntry);
18236f19c83bSHermès Bélusca-Maïto     ASSERT(DiskEntry->DiskNumber == DiskNumber);
18246f19c83bSHermès Bélusca-Maïto     ASSERT(PartEntry->PartitionNumber == PartitionNumber);
18256f19c83bSHermès Bélusca-Maïto 
18266f19c83bSHermès Bélusca-Maïto     List->CurrentDisk = DiskEntry;
18276f19c83bSHermès Bélusca-Maïto     List->CurrentPartition = PartEntry;
18286f19c83bSHermès Bélusca-Maïto     return TRUE;
18296f19c83bSHermès Bélusca-Maïto }
18306f19c83bSHermès Bélusca-Maïto 
18316f19c83bSHermès Bélusca-Maïto PPARTENTRY
18326f19c83bSHermès Bélusca-Maïto GetNextPartition(
18336f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
18346f19c83bSHermès Bélusca-Maïto {
18356f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY DiskListEntry;
18366f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY PartListEntry;
18376f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
18386f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
18396f19c83bSHermès Bélusca-Maïto 
18406f19c83bSHermès Bélusca-Maïto     /* Fail if no disks are available */
18416f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
18426f19c83bSHermès Bélusca-Maïto         return NULL;
18436f19c83bSHermès Bélusca-Maïto 
18446f19c83bSHermès Bélusca-Maïto     /* Check for next usable entry on current disk */
18456f19c83bSHermès Bélusca-Maïto     if (List->CurrentPartition != NULL)
18466f19c83bSHermès Bélusca-Maïto     {
18476f19c83bSHermès Bélusca-Maïto         if (List->CurrentPartition->LogicalPartition)
18486f19c83bSHermès Bélusca-Maïto         {
18496f19c83bSHermès Bélusca-Maïto             /* Logical partition */
18506f19c83bSHermès Bélusca-Maïto 
18516f19c83bSHermès Bélusca-Maïto             PartListEntry = List->CurrentPartition->ListEntry.Flink;
18526f19c83bSHermès Bélusca-Maïto             if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
18536f19c83bSHermès Bélusca-Maïto             {
18546f19c83bSHermès Bélusca-Maïto                 /* Next logical partition */
18556f19c83bSHermès Bélusca-Maïto                 PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
18566f19c83bSHermès Bélusca-Maïto 
18576f19c83bSHermès Bélusca-Maïto                 List->CurrentPartition = PartEntry;
18586f19c83bSHermès Bélusca-Maïto                 return List->CurrentPartition;
18596f19c83bSHermès Bélusca-Maïto             }
18606f19c83bSHermès Bélusca-Maïto             else
18616f19c83bSHermès Bélusca-Maïto             {
18626f19c83bSHermès Bélusca-Maïto                 PartListEntry = List->CurrentDisk->ExtendedPartition->ListEntry.Flink;
18636f19c83bSHermès Bélusca-Maïto                 if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
18646f19c83bSHermès Bélusca-Maïto                 {
18656f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
18666f19c83bSHermès Bélusca-Maïto 
18676f19c83bSHermès Bélusca-Maïto                     List->CurrentPartition = PartEntry;
18686f19c83bSHermès Bélusca-Maïto                     return List->CurrentPartition;
18696f19c83bSHermès Bélusca-Maïto                 }
18706f19c83bSHermès Bélusca-Maïto             }
18716f19c83bSHermès Bélusca-Maïto         }
18726f19c83bSHermès Bélusca-Maïto         else
18736f19c83bSHermès Bélusca-Maïto         {
18746f19c83bSHermès Bélusca-Maïto             /* Primary or extended partition */
18756f19c83bSHermès Bélusca-Maïto 
18766f19c83bSHermès Bélusca-Maïto             if ((List->CurrentPartition->IsPartitioned != FALSE) &&
18776f19c83bSHermès Bélusca-Maïto                 IsContainerPartition(List->CurrentPartition->PartitionType))
18786f19c83bSHermès Bélusca-Maïto             {
18796f19c83bSHermès Bélusca-Maïto                 /* First logical partition */
18806f19c83bSHermès Bélusca-Maïto                 PartListEntry = List->CurrentDisk->LogicalPartListHead.Flink;
18816f19c83bSHermès Bélusca-Maïto                 if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
18826f19c83bSHermès Bélusca-Maïto                 {
18836f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
18846f19c83bSHermès Bélusca-Maïto 
18856f19c83bSHermès Bélusca-Maïto                     List->CurrentPartition = PartEntry;
18866f19c83bSHermès Bélusca-Maïto                     return List->CurrentPartition;
18876f19c83bSHermès Bélusca-Maïto                 }
18886f19c83bSHermès Bélusca-Maïto             }
18896f19c83bSHermès Bélusca-Maïto             else
18906f19c83bSHermès Bélusca-Maïto             {
18916f19c83bSHermès Bélusca-Maïto                 /* Next primary partition */
18926f19c83bSHermès Bélusca-Maïto                 PartListEntry = List->CurrentPartition->ListEntry.Flink;
18936f19c83bSHermès Bélusca-Maïto                 if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
18946f19c83bSHermès Bélusca-Maïto                 {
18956f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
18966f19c83bSHermès Bélusca-Maïto 
18976f19c83bSHermès Bélusca-Maïto                     List->CurrentPartition = PartEntry;
18986f19c83bSHermès Bélusca-Maïto                     return List->CurrentPartition;
18996f19c83bSHermès Bélusca-Maïto                 }
19006f19c83bSHermès Bélusca-Maïto             }
19016f19c83bSHermès Bélusca-Maïto         }
19026f19c83bSHermès Bélusca-Maïto     }
19036f19c83bSHermès Bélusca-Maïto 
19046f19c83bSHermès Bélusca-Maïto     /* Search for the first partition entry on the next disk */
19056f19c83bSHermès Bélusca-Maïto     DiskListEntry = List->CurrentDisk->ListEntry.Flink;
19066f19c83bSHermès Bélusca-Maïto     while (DiskListEntry != &List->DiskListHead)
19076f19c83bSHermès Bélusca-Maïto     {
19086f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
19096f19c83bSHermès Bélusca-Maïto 
19106f19c83bSHermès Bélusca-Maïto         PartListEntry = DiskEntry->PrimaryPartListHead.Flink;
19116f19c83bSHermès Bélusca-Maïto         if (PartListEntry != &DiskEntry->PrimaryPartListHead)
19126f19c83bSHermès Bélusca-Maïto         {
19136f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
19146f19c83bSHermès Bélusca-Maïto 
19156f19c83bSHermès Bélusca-Maïto             List->CurrentDisk = DiskEntry;
19166f19c83bSHermès Bélusca-Maïto             List->CurrentPartition = PartEntry;
19176f19c83bSHermès Bélusca-Maïto             return List->CurrentPartition;
19186f19c83bSHermès Bélusca-Maïto         }
19196f19c83bSHermès Bélusca-Maïto 
19206f19c83bSHermès Bélusca-Maïto         DiskListEntry = DiskListEntry->Flink;
19216f19c83bSHermès Bélusca-Maïto     }
19226f19c83bSHermès Bélusca-Maïto 
19236f19c83bSHermès Bélusca-Maïto     return NULL;
19246f19c83bSHermès Bélusca-Maïto }
19256f19c83bSHermès Bélusca-Maïto 
19266f19c83bSHermès Bélusca-Maïto PPARTENTRY
19276f19c83bSHermès Bélusca-Maïto GetPrevPartition(
19286f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
19296f19c83bSHermès Bélusca-Maïto {
19306f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY DiskListEntry;
19316f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY PartListEntry;
19326f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
19336f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
19346f19c83bSHermès Bélusca-Maïto 
19356f19c83bSHermès Bélusca-Maïto     /* Fail if no disks are available */
19366f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
19376f19c83bSHermès Bélusca-Maïto         return NULL;
19386f19c83bSHermès Bélusca-Maïto 
19396f19c83bSHermès Bélusca-Maïto     /* Check for previous usable entry on current disk */
19406f19c83bSHermès Bélusca-Maïto     if (List->CurrentPartition != NULL)
19416f19c83bSHermès Bélusca-Maïto     {
19426f19c83bSHermès Bélusca-Maïto         if (List->CurrentPartition->LogicalPartition)
19436f19c83bSHermès Bélusca-Maïto         {
19446f19c83bSHermès Bélusca-Maïto             /* Logical partition */
19456f19c83bSHermès Bélusca-Maïto             PartListEntry = List->CurrentPartition->ListEntry.Blink;
19466f19c83bSHermès Bélusca-Maïto             if (PartListEntry != &List->CurrentDisk->LogicalPartListHead)
19476f19c83bSHermès Bélusca-Maïto             {
19486f19c83bSHermès Bélusca-Maïto                 /* Previous logical partition */
19496f19c83bSHermès Bélusca-Maïto                 PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
19506f19c83bSHermès Bélusca-Maïto             }
19516f19c83bSHermès Bélusca-Maïto             else
19526f19c83bSHermès Bélusca-Maïto             {
19536f19c83bSHermès Bélusca-Maïto                 /* Extended partition */
19546f19c83bSHermès Bélusca-Maïto                 PartEntry = List->CurrentDisk->ExtendedPartition;
19556f19c83bSHermès Bélusca-Maïto             }
19566f19c83bSHermès Bélusca-Maïto 
19576f19c83bSHermès Bélusca-Maïto             List->CurrentPartition = PartEntry;
19586f19c83bSHermès Bélusca-Maïto             return List->CurrentPartition;
19596f19c83bSHermès Bélusca-Maïto         }
19606f19c83bSHermès Bélusca-Maïto         else
19616f19c83bSHermès Bélusca-Maïto         {
19626f19c83bSHermès Bélusca-Maïto             /* Primary or extended partition */
19636f19c83bSHermès Bélusca-Maïto 
19646f19c83bSHermès Bélusca-Maïto             PartListEntry = List->CurrentPartition->ListEntry.Blink;
19656f19c83bSHermès Bélusca-Maïto             if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead)
19666f19c83bSHermès Bélusca-Maïto             {
19676f19c83bSHermès Bélusca-Maïto                 PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
19686f19c83bSHermès Bélusca-Maïto 
19696f19c83bSHermès Bélusca-Maïto                 if ((PartEntry->IsPartitioned != FALSE) &&
19706f19c83bSHermès Bélusca-Maïto                     IsContainerPartition(PartEntry->PartitionType))
19716f19c83bSHermès Bélusca-Maïto                 {
19726f19c83bSHermès Bélusca-Maïto                     PartListEntry = List->CurrentDisk->LogicalPartListHead.Blink;
19736f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
19746f19c83bSHermès Bélusca-Maïto                 }
19756f19c83bSHermès Bélusca-Maïto 
19766f19c83bSHermès Bélusca-Maïto                 List->CurrentPartition = PartEntry;
19776f19c83bSHermès Bélusca-Maïto                 return List->CurrentPartition;
19786f19c83bSHermès Bélusca-Maïto             }
19796f19c83bSHermès Bélusca-Maïto         }
19806f19c83bSHermès Bélusca-Maïto     }
19816f19c83bSHermès Bélusca-Maïto 
19826f19c83bSHermès Bélusca-Maïto     /* Search for the last partition entry on the previous disk */
19836f19c83bSHermès Bélusca-Maïto     DiskListEntry = List->CurrentDisk->ListEntry.Blink;
19846f19c83bSHermès Bélusca-Maïto     while (DiskListEntry != &List->DiskListHead)
19856f19c83bSHermès Bélusca-Maïto     {
19866f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
19876f19c83bSHermès Bélusca-Maïto 
19886f19c83bSHermès Bélusca-Maïto         PartListEntry = DiskEntry->PrimaryPartListHead.Blink;
19896f19c83bSHermès Bélusca-Maïto         if (PartListEntry != &DiskEntry->PrimaryPartListHead)
19906f19c83bSHermès Bélusca-Maïto         {
19916f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
19926f19c83bSHermès Bélusca-Maïto 
19936f19c83bSHermès Bélusca-Maïto             if ((PartEntry->IsPartitioned != FALSE) &&
19946f19c83bSHermès Bélusca-Maïto                 IsContainerPartition(PartEntry->PartitionType))
19956f19c83bSHermès Bélusca-Maïto             {
19966f19c83bSHermès Bélusca-Maïto                 PartListEntry = DiskEntry->LogicalPartListHead.Blink;
19976f19c83bSHermès Bélusca-Maïto                 if (PartListEntry != &DiskEntry->LogicalPartListHead)
19986f19c83bSHermès Bélusca-Maïto                 {
19996f19c83bSHermès Bélusca-Maïto                     PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
20006f19c83bSHermès Bélusca-Maïto 
20016f19c83bSHermès Bélusca-Maïto                     List->CurrentDisk = DiskEntry;
20026f19c83bSHermès Bélusca-Maïto                     List->CurrentPartition = PartEntry;
20036f19c83bSHermès Bélusca-Maïto                     return List->CurrentPartition;
20046f19c83bSHermès Bélusca-Maïto                 }
20056f19c83bSHermès Bélusca-Maïto             }
20066f19c83bSHermès Bélusca-Maïto             else
20076f19c83bSHermès Bélusca-Maïto             {
20086f19c83bSHermès Bélusca-Maïto                 List->CurrentDisk = DiskEntry;
20096f19c83bSHermès Bélusca-Maïto                 List->CurrentPartition = PartEntry;
20106f19c83bSHermès Bélusca-Maïto                 return List->CurrentPartition;
20116f19c83bSHermès Bélusca-Maïto             }
20126f19c83bSHermès Bélusca-Maïto         }
20136f19c83bSHermès Bélusca-Maïto 
20146f19c83bSHermès Bélusca-Maïto         DiskListEntry = DiskListEntry->Blink;
20156f19c83bSHermès Bélusca-Maïto     }
20166f19c83bSHermès Bélusca-Maïto 
20176f19c83bSHermès Bélusca-Maïto     return NULL;
20186f19c83bSHermès Bélusca-Maïto }
20196f19c83bSHermès Bélusca-Maïto 
20206f19c83bSHermès Bélusca-Maïto // static
20216f19c83bSHermès Bélusca-Maïto FORCEINLINE
20226f19c83bSHermès Bélusca-Maïto BOOLEAN
20236f19c83bSHermès Bélusca-Maïto IsEmptyLayoutEntry(
20246f19c83bSHermès Bélusca-Maïto     IN PPARTITION_INFORMATION PartitionInfo)
20256f19c83bSHermès Bélusca-Maïto {
20266f19c83bSHermès Bélusca-Maïto     if (PartitionInfo->StartingOffset.QuadPart == 0 &&
20276f19c83bSHermès Bélusca-Maïto         PartitionInfo->PartitionLength.QuadPart == 0)
20286f19c83bSHermès Bélusca-Maïto     {
20296f19c83bSHermès Bélusca-Maïto         return TRUE;
20306f19c83bSHermès Bélusca-Maïto     }
20316f19c83bSHermès Bélusca-Maïto 
20326f19c83bSHermès Bélusca-Maïto     return FALSE;
20336f19c83bSHermès Bélusca-Maïto }
20346f19c83bSHermès Bélusca-Maïto 
20356f19c83bSHermès Bélusca-Maïto // static
20366f19c83bSHermès Bélusca-Maïto FORCEINLINE
20376f19c83bSHermès Bélusca-Maïto BOOLEAN
20386f19c83bSHermès Bélusca-Maïto IsSamePrimaryLayoutEntry(
20396f19c83bSHermès Bélusca-Maïto     IN PPARTITION_INFORMATION PartitionInfo,
20406f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
20416f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
20426f19c83bSHermès Bélusca-Maïto {
20436f19c83bSHermès Bélusca-Maïto     if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector &&
20446f19c83bSHermès Bélusca-Maïto         PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector)
20456f19c83bSHermès Bélusca-Maïto //        PartitionInfo->PartitionNumber = PartEntry->PartitionNumber &&
20466f19c83bSHermès Bélusca-Maïto //        PartitionInfo->PartitionType == PartEntry->PartitionType
20476f19c83bSHermès Bélusca-Maïto     {
20486f19c83bSHermès Bélusca-Maïto         return TRUE;
20496f19c83bSHermès Bélusca-Maïto     }
20506f19c83bSHermès Bélusca-Maïto 
20516f19c83bSHermès Bélusca-Maïto     return FALSE;
20526f19c83bSHermès Bélusca-Maïto }
20536f19c83bSHermès Bélusca-Maïto 
20546f19c83bSHermès Bélusca-Maïto static
20556f19c83bSHermès Bélusca-Maïto ULONG
20566f19c83bSHermès Bélusca-Maïto GetPrimaryPartitionCount(
20576f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
20586f19c83bSHermès Bélusca-Maïto {
20596f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
20606f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
20616f19c83bSHermès Bélusca-Maïto     ULONG Count = 0;
20626f19c83bSHermès Bélusca-Maïto 
20636f19c83bSHermès Bélusca-Maïto     Entry = DiskEntry->PrimaryPartListHead.Flink;
20646f19c83bSHermès Bélusca-Maïto     while (Entry != &DiskEntry->PrimaryPartListHead)
20656f19c83bSHermès Bélusca-Maïto     {
20666f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
20676f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
20686f19c83bSHermès Bélusca-Maïto             Count++;
20696f19c83bSHermès Bélusca-Maïto 
20706f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
20716f19c83bSHermès Bélusca-Maïto     }
20726f19c83bSHermès Bélusca-Maïto 
20736f19c83bSHermès Bélusca-Maïto     return Count;
20746f19c83bSHermès Bélusca-Maïto }
20756f19c83bSHermès Bélusca-Maïto 
20766f19c83bSHermès Bélusca-Maïto static
20776f19c83bSHermès Bélusca-Maïto ULONG
20786f19c83bSHermès Bélusca-Maïto GetLogicalPartitionCount(
20796f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
20806f19c83bSHermès Bélusca-Maïto {
20816f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
20826f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
20836f19c83bSHermès Bélusca-Maïto     ULONG Count = 0;
20846f19c83bSHermès Bélusca-Maïto 
20856f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->LogicalPartListHead.Flink;
20866f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->LogicalPartListHead)
20876f19c83bSHermès Bélusca-Maïto     {
20886f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
20896f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
20906f19c83bSHermès Bélusca-Maïto             Count++;
20916f19c83bSHermès Bélusca-Maïto 
20926f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
20936f19c83bSHermès Bélusca-Maïto     }
20946f19c83bSHermès Bélusca-Maïto 
20956f19c83bSHermès Bélusca-Maïto     return Count;
20966f19c83bSHermès Bélusca-Maïto }
20976f19c83bSHermès Bélusca-Maïto 
20986f19c83bSHermès Bélusca-Maïto static
20996f19c83bSHermès Bélusca-Maïto BOOLEAN
21006f19c83bSHermès Bélusca-Maïto ReAllocateLayoutBuffer(
21016f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
21026f19c83bSHermès Bélusca-Maïto {
21036f19c83bSHermès Bélusca-Maïto     PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
21046f19c83bSHermès Bélusca-Maïto     ULONG NewPartitionCount;
21056f19c83bSHermès Bélusca-Maïto     ULONG CurrentPartitionCount = 0;
21066f19c83bSHermès Bélusca-Maïto     ULONG LayoutBufferSize;
21076f19c83bSHermès Bélusca-Maïto     ULONG i;
21086f19c83bSHermès Bélusca-Maïto 
21096f19c83bSHermès Bélusca-Maïto     DPRINT1("ReAllocateLayoutBuffer()\n");
21106f19c83bSHermès Bélusca-Maïto 
21116f19c83bSHermès Bélusca-Maïto     NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
21126f19c83bSHermès Bélusca-Maïto 
21136f19c83bSHermès Bélusca-Maïto     if (DiskEntry->LayoutBuffer)
21146f19c83bSHermès Bélusca-Maïto         CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
21156f19c83bSHermès Bélusca-Maïto 
21166f19c83bSHermès Bélusca-Maïto     DPRINT1("CurrentPartitionCount: %lu    NewPartitionCount: %lu\n",
21176f19c83bSHermès Bélusca-Maïto             CurrentPartitionCount, NewPartitionCount);
21186f19c83bSHermès Bélusca-Maïto 
21196f19c83bSHermès Bélusca-Maïto     if (CurrentPartitionCount == NewPartitionCount)
21206f19c83bSHermès Bélusca-Maïto         return TRUE;
21216f19c83bSHermès Bélusca-Maïto 
21226f19c83bSHermès Bélusca-Maïto     LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
21236f19c83bSHermès Bélusca-Maïto                        ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
21246f19c83bSHermès Bélusca-Maïto     NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap,
21256f19c83bSHermès Bélusca-Maïto                                         HEAP_ZERO_MEMORY,
21266f19c83bSHermès Bélusca-Maïto                                         DiskEntry->LayoutBuffer,
21276f19c83bSHermès Bélusca-Maïto                                         LayoutBufferSize);
21286f19c83bSHermès Bélusca-Maïto     if (NewLayoutBuffer == NULL)
21296f19c83bSHermès Bélusca-Maïto     {
21306f19c83bSHermès Bélusca-Maïto         DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
21316f19c83bSHermès Bélusca-Maïto         return FALSE;
21326f19c83bSHermès Bélusca-Maïto     }
21336f19c83bSHermès Bélusca-Maïto 
21346f19c83bSHermès Bélusca-Maïto     /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
21356f19c83bSHermès Bélusca-Maïto     if (NewPartitionCount > CurrentPartitionCount)
21366f19c83bSHermès Bélusca-Maïto     {
21376f19c83bSHermès Bélusca-Maïto         for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
21386f19c83bSHermès Bélusca-Maïto             NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
21396f19c83bSHermès Bélusca-Maïto     }
21406f19c83bSHermès Bélusca-Maïto 
21416f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer = NewLayoutBuffer;
21426f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionCount = NewPartitionCount;
21436f19c83bSHermès Bélusca-Maïto 
21446f19c83bSHermès Bélusca-Maïto     return TRUE;
21456f19c83bSHermès Bélusca-Maïto }
21466f19c83bSHermès Bélusca-Maïto 
21476f19c83bSHermès Bélusca-Maïto static
21486f19c83bSHermès Bélusca-Maïto VOID
21496f19c83bSHermès Bélusca-Maïto UpdateDiskLayout(
21506f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
21516f19c83bSHermès Bélusca-Maïto {
21526f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION PartitionInfo;
21536f19c83bSHermès Bélusca-Maïto     PPARTITION_INFORMATION LinkInfo = NULL;
21546f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
21556f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
21566f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER HiddenSectors64;
21576f19c83bSHermès Bélusca-Maïto     ULONG Index;
21586f19c83bSHermès Bélusca-Maïto     ULONG PartitionNumber = 1;
21596f19c83bSHermès Bélusca-Maïto 
21606f19c83bSHermès Bélusca-Maïto     DPRINT1("UpdateDiskLayout()\n");
21616f19c83bSHermès Bélusca-Maïto 
21626f19c83bSHermès Bélusca-Maïto     /* Resize the layout buffer if necessary */
21636f19c83bSHermès Bélusca-Maïto     if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
21646f19c83bSHermès Bélusca-Maïto     {
21656f19c83bSHermès Bélusca-Maïto         DPRINT("ReAllocateLayoutBuffer() failed.\n");
21666f19c83bSHermès Bélusca-Maïto         return;
21676f19c83bSHermès Bélusca-Maïto     }
21686f19c83bSHermès Bélusca-Maïto 
21696f19c83bSHermès Bélusca-Maïto     /* Update the primary partition table */
21706f19c83bSHermès Bélusca-Maïto     Index = 0;
21716f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->PrimaryPartListHead.Flink;
21726f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->PrimaryPartListHead)
21736f19c83bSHermès Bélusca-Maïto     {
21746f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
21756f19c83bSHermès Bélusca-Maïto 
21766f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned != FALSE)
21776f19c83bSHermès Bélusca-Maïto         {
21786f19c83bSHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
21796f19c83bSHermès Bélusca-Maïto 
21806f19c83bSHermès Bélusca-Maïto             if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
21816f19c83bSHermès Bélusca-Maïto             {
21826f19c83bSHermès Bélusca-Maïto                 DPRINT1("Updating primary partition entry %lu\n", Index);
21836f19c83bSHermès Bélusca-Maïto 
21846f19c83bSHermès Bélusca-Maïto                 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
21856f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
21866f19c83bSHermès Bélusca-Maïto                 PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart;
21876f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionNumber = (!IsContainerPartition(PartEntry->PartitionType)) ? PartitionNumber : 0;
21886f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionType = PartEntry->PartitionType;
21896f19c83bSHermès Bélusca-Maïto                 PartitionInfo->BootIndicator = PartEntry->BootIndicator;
21906f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RecognizedPartition = FALSE;
21916f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RewritePartition = TRUE;
21926f19c83bSHermès Bélusca-Maïto             }
21936f19c83bSHermès Bélusca-Maïto 
21946f19c83bSHermès Bélusca-Maïto             PartEntry->PartitionNumber = (!IsContainerPartition(PartEntry->PartitionType)) ? PartitionNumber : 0;
21956f19c83bSHermès Bélusca-Maïto             PartEntry->PartitionIndex = Index;
21966f19c83bSHermès Bélusca-Maïto 
21976f19c83bSHermès Bélusca-Maïto             if (!IsContainerPartition(PartEntry->PartitionType))
21986f19c83bSHermès Bélusca-Maïto                 PartitionNumber++;
21996f19c83bSHermès Bélusca-Maïto 
22006f19c83bSHermès Bélusca-Maïto             Index++;
22016f19c83bSHermès Bélusca-Maïto         }
22026f19c83bSHermès Bélusca-Maïto 
22036f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
22046f19c83bSHermès Bélusca-Maïto     }
22056f19c83bSHermès Bélusca-Maïto 
22066f19c83bSHermès Bélusca-Maïto     /* Update the logical partition table */
22076f19c83bSHermès Bélusca-Maïto     Index = 4;
22086f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->LogicalPartListHead.Flink;
22096f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->LogicalPartListHead)
22106f19c83bSHermès Bélusca-Maïto     {
22116f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
22126f19c83bSHermès Bélusca-Maïto 
22136f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned)
22146f19c83bSHermès Bélusca-Maïto         {
22156f19c83bSHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
22166f19c83bSHermès Bélusca-Maïto 
22176f19c83bSHermès Bélusca-Maïto             DPRINT1("Updating logical partition entry %lu\n", Index);
22186f19c83bSHermès Bélusca-Maïto 
22196f19c83bSHermès Bélusca-Maïto             PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
22206f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
22216f19c83bSHermès Bélusca-Maïto             PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment;
22226f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionNumber = PartitionNumber;
22236f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionType = PartEntry->PartitionType;
22246f19c83bSHermès Bélusca-Maïto             PartitionInfo->BootIndicator = FALSE;
22256f19c83bSHermès Bélusca-Maïto             PartitionInfo->RecognizedPartition = FALSE;
22266f19c83bSHermès Bélusca-Maïto             PartitionInfo->RewritePartition = TRUE;
22276f19c83bSHermès Bélusca-Maïto 
22286f19c83bSHermès Bélusca-Maïto             PartEntry->PartitionNumber = PartitionNumber;
22296f19c83bSHermès Bélusca-Maïto             PartEntry->PartitionIndex = Index;
22306f19c83bSHermès Bélusca-Maïto 
22316f19c83bSHermès Bélusca-Maïto             /* Fill the link entry of the previous partition entry */
22326f19c83bSHermès Bélusca-Maïto             if (LinkInfo != NULL)
22336f19c83bSHermès Bélusca-Maïto             {
22346f19c83bSHermès Bélusca-Maïto                 LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
22356f19c83bSHermès Bélusca-Maïto                 LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
22366f19c83bSHermès Bélusca-Maïto                 HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
22376f19c83bSHermès Bélusca-Maïto                 LinkInfo->HiddenSectors = HiddenSectors64.LowPart;
22386f19c83bSHermès Bélusca-Maïto                 LinkInfo->PartitionNumber = 0;
22396f19c83bSHermès Bélusca-Maïto                 LinkInfo->PartitionType = PARTITION_EXTENDED;
22406f19c83bSHermès Bélusca-Maïto                 LinkInfo->BootIndicator = FALSE;
22416f19c83bSHermès Bélusca-Maïto                 LinkInfo->RecognizedPartition = FALSE;
22426f19c83bSHermès Bélusca-Maïto                 LinkInfo->RewritePartition = TRUE;
22436f19c83bSHermès Bélusca-Maïto             }
22446f19c83bSHermès Bélusca-Maïto 
22456f19c83bSHermès Bélusca-Maïto             /* Save a pointer to the link entry of the current partition entry */
22466f19c83bSHermès Bélusca-Maïto             LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
22476f19c83bSHermès Bélusca-Maïto 
22486f19c83bSHermès Bélusca-Maïto             PartitionNumber++;
22496f19c83bSHermès Bélusca-Maïto             Index += 4;
22506f19c83bSHermès Bélusca-Maïto         }
22516f19c83bSHermès Bélusca-Maïto 
22526f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
22536f19c83bSHermès Bélusca-Maïto     }
22546f19c83bSHermès Bélusca-Maïto 
22556f19c83bSHermès Bélusca-Maïto     /* Wipe unused primary partition entries */
22566f19c83bSHermès Bélusca-Maïto     for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
22576f19c83bSHermès Bélusca-Maïto     {
22586f19c83bSHermès Bélusca-Maïto         DPRINT1("Primary partition entry %lu\n", Index);
22596f19c83bSHermès Bélusca-Maïto 
22606f19c83bSHermès Bélusca-Maïto         PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
22616f19c83bSHermès Bélusca-Maïto 
22626f19c83bSHermès Bélusca-Maïto         if (!IsEmptyLayoutEntry(PartitionInfo))
22636f19c83bSHermès Bélusca-Maïto         {
22646f19c83bSHermès Bélusca-Maïto             DPRINT1("Wiping primary partition entry %lu\n", Index);
22656f19c83bSHermès Bélusca-Maïto 
22666f19c83bSHermès Bélusca-Maïto             PartitionInfo->StartingOffset.QuadPart = 0;
22676f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionLength.QuadPart = 0;
22686f19c83bSHermès Bélusca-Maïto             PartitionInfo->HiddenSectors = 0;
22696f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionNumber = 0;
22706f19c83bSHermès Bélusca-Maïto             PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
22716f19c83bSHermès Bélusca-Maïto             PartitionInfo->BootIndicator = FALSE;
22726f19c83bSHermès Bélusca-Maïto             PartitionInfo->RecognizedPartition = FALSE;
22736f19c83bSHermès Bélusca-Maïto             PartitionInfo->RewritePartition = TRUE;
22746f19c83bSHermès Bélusca-Maïto         }
22756f19c83bSHermès Bélusca-Maïto     }
22766f19c83bSHermès Bélusca-Maïto 
22776f19c83bSHermès Bélusca-Maïto     /* Wipe unused logical partition entries */
22786f19c83bSHermès Bélusca-Maïto     for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
22796f19c83bSHermès Bélusca-Maïto     {
22806f19c83bSHermès Bélusca-Maïto         if (Index % 4 >= 2)
22816f19c83bSHermès Bélusca-Maïto         {
22826f19c83bSHermès Bélusca-Maïto             DPRINT1("Logical partition entry %lu\n", Index);
22836f19c83bSHermès Bélusca-Maïto 
22846f19c83bSHermès Bélusca-Maïto             PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
22856f19c83bSHermès Bélusca-Maïto 
22866f19c83bSHermès Bélusca-Maïto             if (!IsEmptyLayoutEntry(PartitionInfo))
22876f19c83bSHermès Bélusca-Maïto             {
22886f19c83bSHermès Bélusca-Maïto                 DPRINT1("Wiping partition entry %lu\n", Index);
22896f19c83bSHermès Bélusca-Maïto 
22906f19c83bSHermès Bélusca-Maïto                 PartitionInfo->StartingOffset.QuadPart = 0;
22916f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionLength.QuadPart = 0;
22926f19c83bSHermès Bélusca-Maïto                 PartitionInfo->HiddenSectors = 0;
22936f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionNumber = 0;
22946f19c83bSHermès Bélusca-Maïto                 PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED;
22956f19c83bSHermès Bélusca-Maïto                 PartitionInfo->BootIndicator = FALSE;
22966f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RecognizedPartition = FALSE;
22976f19c83bSHermès Bélusca-Maïto                 PartitionInfo->RewritePartition = TRUE;
22986f19c83bSHermès Bélusca-Maïto             }
22996f19c83bSHermès Bélusca-Maïto         }
23006f19c83bSHermès Bélusca-Maïto     }
23016f19c83bSHermès Bélusca-Maïto 
23026f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
23036f19c83bSHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
23046f19c83bSHermès Bélusca-Maïto #endif
23056f19c83bSHermès Bélusca-Maïto }
23066f19c83bSHermès Bélusca-Maïto 
23076f19c83bSHermès Bélusca-Maïto static
23086f19c83bSHermès Bélusca-Maïto PPARTENTRY
23096f19c83bSHermès Bélusca-Maïto GetPrevUnpartitionedEntry(
23106f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
23116f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
23126f19c83bSHermès Bélusca-Maïto {
23136f19c83bSHermès Bélusca-Maïto     PPARTENTRY PrevPartEntry;
23146f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListHead;
23156f19c83bSHermès Bélusca-Maïto 
23166f19c83bSHermès Bélusca-Maïto     if (PartEntry->LogicalPartition)
23176f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->LogicalPartListHead;
23186f19c83bSHermès Bélusca-Maïto     else
23196f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->PrimaryPartListHead;
23206f19c83bSHermès Bélusca-Maïto 
23216f19c83bSHermès Bélusca-Maïto     if (PartEntry->ListEntry.Blink != ListHead)
23226f19c83bSHermès Bélusca-Maïto     {
23236f19c83bSHermès Bélusca-Maïto         PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
23246f19c83bSHermès Bélusca-Maïto                                           PARTENTRY,
23256f19c83bSHermès Bélusca-Maïto                                           ListEntry);
23266f19c83bSHermès Bélusca-Maïto         if (PrevPartEntry->IsPartitioned == FALSE)
23276f19c83bSHermès Bélusca-Maïto             return PrevPartEntry;
23286f19c83bSHermès Bélusca-Maïto     }
23296f19c83bSHermès Bélusca-Maïto 
23306f19c83bSHermès Bélusca-Maïto     return NULL;
23316f19c83bSHermès Bélusca-Maïto }
23326f19c83bSHermès Bélusca-Maïto 
23336f19c83bSHermès Bélusca-Maïto static
23346f19c83bSHermès Bélusca-Maïto PPARTENTRY
23356f19c83bSHermès Bélusca-Maïto GetNextUnpartitionedEntry(
23366f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry,
23376f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry)
23386f19c83bSHermès Bélusca-Maïto {
23396f19c83bSHermès Bélusca-Maïto     PPARTENTRY NextPartEntry;
23406f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListHead;
23416f19c83bSHermès Bélusca-Maïto 
23426f19c83bSHermès Bélusca-Maïto     if (PartEntry->LogicalPartition)
23436f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->LogicalPartListHead;
23446f19c83bSHermès Bélusca-Maïto     else
23456f19c83bSHermès Bélusca-Maïto         ListHead = &DiskEntry->PrimaryPartListHead;
23466f19c83bSHermès Bélusca-Maïto 
23476f19c83bSHermès Bélusca-Maïto     if (PartEntry->ListEntry.Flink != ListHead)
23486f19c83bSHermès Bélusca-Maïto     {
23496f19c83bSHermès Bélusca-Maïto         NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
23506f19c83bSHermès Bélusca-Maïto                                           PARTENTRY,
23516f19c83bSHermès Bélusca-Maïto                                           ListEntry);
23526f19c83bSHermès Bélusca-Maïto         if (NextPartEntry->IsPartitioned == FALSE)
23536f19c83bSHermès Bélusca-Maïto             return NextPartEntry;
23546f19c83bSHermès Bélusca-Maïto     }
23556f19c83bSHermès Bélusca-Maïto 
23566f19c83bSHermès Bélusca-Maïto     return NULL;
23576f19c83bSHermès Bélusca-Maïto }
23586f19c83bSHermès Bélusca-Maïto 
23596f19c83bSHermès Bélusca-Maïto VOID
23606f19c83bSHermès Bélusca-Maïto CreatePrimaryPartition(
23616f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
23626f19c83bSHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
23636f19c83bSHermès Bélusca-Maïto     IN BOOLEAN AutoCreate)
23646f19c83bSHermès Bélusca-Maïto {
23656f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
23666f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
23676f19c83bSHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
23686f19c83bSHermès Bélusca-Maïto 
23696f19c83bSHermès Bélusca-Maïto     DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
23706f19c83bSHermès Bélusca-Maïto 
23716f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
23726f19c83bSHermès Bélusca-Maïto         List->CurrentDisk == NULL ||
23736f19c83bSHermès Bélusca-Maïto         List->CurrentPartition == NULL ||
23746f19c83bSHermès Bélusca-Maïto         List->CurrentPartition->IsPartitioned != FALSE)
23756f19c83bSHermès Bélusca-Maïto     {
23766f19c83bSHermès Bélusca-Maïto         return;
23776f19c83bSHermès Bélusca-Maïto     }
23786f19c83bSHermès Bélusca-Maïto 
23796f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
23806f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
23816f19c83bSHermès Bélusca-Maïto 
23826f19c83bSHermès Bélusca-Maïto     DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
23836f19c83bSHermès Bélusca-Maïto 
23846f19c83bSHermès Bélusca-Maïto     if ((AutoCreate != FALSE) ||
23856f19c83bSHermès Bélusca-Maïto         (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
23866f19c83bSHermès Bélusca-Maïto     {
23876f19c83bSHermès Bélusca-Maïto         DPRINT1("Convert existing partition entry\n");
23886f19c83bSHermès Bélusca-Maïto 
23896f19c83bSHermès Bélusca-Maïto         /* Convert current entry to 'new (unformatted)' */
23906f19c83bSHermès Bélusca-Maïto         PartEntry->IsPartitioned = TRUE;
23916f19c83bSHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
23926f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = Unformatted;
23936f19c83bSHermès Bélusca-Maïto         PartEntry->FileSystem  = NULL;
23946f19c83bSHermès Bélusca-Maïto         PartEntry->AutoCreate = AutoCreate;
23956f19c83bSHermès Bélusca-Maïto         PartEntry->New = TRUE;
23966f19c83bSHermès Bélusca-Maïto         PartEntry->BootIndicator = FALSE;
23976f19c83bSHermès Bélusca-Maïto 
23986f19c83bSHermès Bélusca-Maïto         DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart);
23996f19c83bSHermès Bélusca-Maïto         DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
24006f19c83bSHermès Bélusca-Maïto         DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
24016f19c83bSHermès Bélusca-Maïto     }
24026f19c83bSHermès Bélusca-Maïto     else
24036f19c83bSHermès Bélusca-Maïto     {
24046f19c83bSHermès Bélusca-Maïto         DPRINT1("Add new partition entry\n");
24056f19c83bSHermès Bélusca-Maïto 
24066f19c83bSHermès Bélusca-Maïto         /* Insert and initialize a new partition entry */
24076f19c83bSHermès Bélusca-Maïto         NewPartEntry = RtlAllocateHeap(ProcessHeap,
24086f19c83bSHermès Bélusca-Maïto                                        HEAP_ZERO_MEMORY,
24096f19c83bSHermès Bélusca-Maïto                                        sizeof(PARTENTRY));
24106f19c83bSHermès Bélusca-Maïto         if (NewPartEntry == NULL)
24116f19c83bSHermès Bélusca-Maïto             return;
24126f19c83bSHermès Bélusca-Maïto 
24136f19c83bSHermès Bélusca-Maïto         /* Insert the new entry into the list */
24146f19c83bSHermès Bélusca-Maïto         InsertTailList(&PartEntry->ListEntry,
24156f19c83bSHermès Bélusca-Maïto                        &NewPartEntry->ListEntry);
24166f19c83bSHermès Bélusca-Maïto 
24176f19c83bSHermès Bélusca-Maïto         NewPartEntry->DiskEntry = DiskEntry;
24186f19c83bSHermès Bélusca-Maïto 
24196f19c83bSHermès Bélusca-Maïto         NewPartEntry->IsPartitioned = TRUE;
24206f19c83bSHermès Bélusca-Maïto         NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
24216f19c83bSHermès Bélusca-Maïto         NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
24226f19c83bSHermès Bélusca-Maïto                                              NewPartEntry->StartSector.QuadPart;
24236f19c83bSHermès Bélusca-Maïto         NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
24246f19c83bSHermès Bélusca-Maïto 
24256f19c83bSHermès Bélusca-Maïto         DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
24266f19c83bSHermès Bélusca-Maïto         DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
24276f19c83bSHermès Bélusca-Maïto         DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
24286f19c83bSHermès Bélusca-Maïto 
24296f19c83bSHermès Bélusca-Maïto         NewPartEntry->New = TRUE;
24306f19c83bSHermès Bélusca-Maïto         NewPartEntry->FormatState = Unformatted;
24316f19c83bSHermès Bélusca-Maïto         NewPartEntry->FileSystem  = NULL;
24326f19c83bSHermès Bélusca-Maïto         NewPartEntry->BootIndicator = FALSE;
24336f19c83bSHermès Bélusca-Maïto 
24346f19c83bSHermès Bélusca-Maïto         PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
24356f19c83bSHermès Bélusca-Maïto         PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
24366f19c83bSHermès Bélusca-Maïto     }
24376f19c83bSHermès Bélusca-Maïto 
24386f19c83bSHermès Bélusca-Maïto     UpdateDiskLayout(DiskEntry);
24396f19c83bSHermès Bélusca-Maïto 
24406f19c83bSHermès Bélusca-Maïto     DiskEntry->Dirty = TRUE;
24416f19c83bSHermès Bélusca-Maïto 
24426f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
24436f19c83bSHermès Bélusca-Maïto }
24446f19c83bSHermès Bélusca-Maïto 
24456f19c83bSHermès Bélusca-Maïto static
24466f19c83bSHermès Bélusca-Maïto VOID
24476f19c83bSHermès Bélusca-Maïto AddLogicalDiskSpace(
24486f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
24496f19c83bSHermès Bélusca-Maïto {
24506f19c83bSHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
24516f19c83bSHermès Bélusca-Maïto 
24526f19c83bSHermès Bélusca-Maïto     DPRINT1("AddLogicalDiskSpace()\n");
24536f19c83bSHermès Bélusca-Maïto 
24546f19c83bSHermès Bélusca-Maïto     /* Create a partition entry that represents the empty space in the container partition */
24556f19c83bSHermès Bélusca-Maïto     NewPartEntry = RtlAllocateHeap(ProcessHeap,
24566f19c83bSHermès Bélusca-Maïto                                    HEAP_ZERO_MEMORY,
24576f19c83bSHermès Bélusca-Maïto                                    sizeof(PARTENTRY));
24586f19c83bSHermès Bélusca-Maïto     if (NewPartEntry == NULL)
24596f19c83bSHermès Bélusca-Maïto         return;
24606f19c83bSHermès Bélusca-Maïto 
24616f19c83bSHermès Bélusca-Maïto     NewPartEntry->DiskEntry = DiskEntry;
24626f19c83bSHermès Bélusca-Maïto     NewPartEntry->LogicalPartition = TRUE;
24636f19c83bSHermès Bélusca-Maïto 
24646f19c83bSHermès Bélusca-Maïto     NewPartEntry->IsPartitioned = FALSE;
24656f19c83bSHermès Bélusca-Maïto     NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
24666f19c83bSHermès Bélusca-Maïto     NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
24676f19c83bSHermès Bélusca-Maïto 
24686f19c83bSHermès Bélusca-Maïto     DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
24696f19c83bSHermès Bélusca-Maïto     DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
24706f19c83bSHermès Bélusca-Maïto     DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
24716f19c83bSHermès Bélusca-Maïto 
24726f19c83bSHermès Bélusca-Maïto     NewPartEntry->FormatState = Unformatted;
24736f19c83bSHermès Bélusca-Maïto     NewPartEntry->FileSystem  = NULL;
24746f19c83bSHermès Bélusca-Maïto 
24756f19c83bSHermès Bélusca-Maïto     InsertTailList(&DiskEntry->LogicalPartListHead,
24766f19c83bSHermès Bélusca-Maïto                    &NewPartEntry->ListEntry);
24776f19c83bSHermès Bélusca-Maïto }
24786f19c83bSHermès Bélusca-Maïto 
24796f19c83bSHermès Bélusca-Maïto VOID
24806f19c83bSHermès Bélusca-Maïto CreateExtendedPartition(
24816f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
24826f19c83bSHermès Bélusca-Maïto     IN ULONGLONG SectorCount)
24836f19c83bSHermès Bélusca-Maïto {
24846f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
24856f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
24866f19c83bSHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
24876f19c83bSHermès Bélusca-Maïto 
24886f19c83bSHermès Bélusca-Maïto     DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
24896f19c83bSHermès Bélusca-Maïto 
24906f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
24916f19c83bSHermès Bélusca-Maïto         List->CurrentDisk == NULL ||
24926f19c83bSHermès Bélusca-Maïto         List->CurrentPartition == NULL ||
24936f19c83bSHermès Bélusca-Maïto         List->CurrentPartition->IsPartitioned != FALSE)
24946f19c83bSHermès Bélusca-Maïto     {
24956f19c83bSHermès Bélusca-Maïto         return;
24966f19c83bSHermès Bélusca-Maïto     }
24976f19c83bSHermès Bélusca-Maïto 
24986f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
24996f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
25006f19c83bSHermès Bélusca-Maïto 
25016f19c83bSHermès Bélusca-Maïto     DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
25026f19c83bSHermès Bélusca-Maïto 
25036f19c83bSHermès Bélusca-Maïto     if (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart)
25046f19c83bSHermès Bélusca-Maïto     {
25056f19c83bSHermès Bélusca-Maïto         DPRINT1("Convert existing partition entry\n");
25066f19c83bSHermès Bélusca-Maïto 
25076f19c83bSHermès Bélusca-Maïto         /* Convert current entry to 'new (unformatted)' */
25086f19c83bSHermès Bélusca-Maïto         PartEntry->IsPartitioned = TRUE;
25096f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = Formatted;     // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
25106f19c83bSHermès Bélusca-Maïto         PartEntry->FileSystem  = NULL;
25116f19c83bSHermès Bélusca-Maïto         PartEntry->AutoCreate = FALSE;
25126f19c83bSHermès Bélusca-Maïto         PartEntry->New = FALSE;
25136f19c83bSHermès Bélusca-Maïto         PartEntry->BootIndicator = FALSE;
25146f19c83bSHermès Bélusca-Maïto 
25156f19c83bSHermès Bélusca-Maïto         if (PartEntry->StartSector.QuadPart < 1450560)
25166f19c83bSHermès Bélusca-Maïto         {
25176f19c83bSHermès Bélusca-Maïto             /* Partition starts below the 8.4GB boundary ==> CHS partition */
25186f19c83bSHermès Bélusca-Maïto             PartEntry->PartitionType = PARTITION_EXTENDED;
25196f19c83bSHermès Bélusca-Maïto         }
25206f19c83bSHermès Bélusca-Maïto         else
25216f19c83bSHermès Bélusca-Maïto         {
25226f19c83bSHermès Bélusca-Maïto             /* Partition starts above the 8.4GB boundary ==> LBA partition */
25236f19c83bSHermès Bélusca-Maïto             PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
25246f19c83bSHermès Bélusca-Maïto         }
25256f19c83bSHermès Bélusca-Maïto 
25266f19c83bSHermès Bélusca-Maïto         DiskEntry->ExtendedPartition = PartEntry;
25276f19c83bSHermès Bélusca-Maïto 
25286f19c83bSHermès Bélusca-Maïto         DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart);
25296f19c83bSHermès Bélusca-Maïto         DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
25306f19c83bSHermès Bélusca-Maïto         DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
25316f19c83bSHermès Bélusca-Maïto     }
25326f19c83bSHermès Bélusca-Maïto     else
25336f19c83bSHermès Bélusca-Maïto     {
25346f19c83bSHermès Bélusca-Maïto         DPRINT1("Add new partition entry\n");
25356f19c83bSHermès Bélusca-Maïto 
25366f19c83bSHermès Bélusca-Maïto         /* Insert and initialize a new partition entry */
25376f19c83bSHermès Bélusca-Maïto         NewPartEntry = RtlAllocateHeap(ProcessHeap,
25386f19c83bSHermès Bélusca-Maïto                                        HEAP_ZERO_MEMORY,
25396f19c83bSHermès Bélusca-Maïto                                        sizeof(PARTENTRY));
25406f19c83bSHermès Bélusca-Maïto         if (NewPartEntry == NULL)
25416f19c83bSHermès Bélusca-Maïto             return;
25426f19c83bSHermès Bélusca-Maïto 
25436f19c83bSHermès Bélusca-Maïto         /* Insert the new entry into the list */
25446f19c83bSHermès Bélusca-Maïto         InsertTailList(&PartEntry->ListEntry,
25456f19c83bSHermès Bélusca-Maïto                        &NewPartEntry->ListEntry);
25466f19c83bSHermès Bélusca-Maïto 
25476f19c83bSHermès Bélusca-Maïto         NewPartEntry->DiskEntry = DiskEntry;
25486f19c83bSHermès Bélusca-Maïto 
25496f19c83bSHermès Bélusca-Maïto         NewPartEntry->IsPartitioned = TRUE;
25506f19c83bSHermès Bélusca-Maïto         NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
25516f19c83bSHermès Bélusca-Maïto         NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
25526f19c83bSHermès Bélusca-Maïto                                              NewPartEntry->StartSector.QuadPart;
25536f19c83bSHermès Bélusca-Maïto 
25546f19c83bSHermès Bélusca-Maïto         NewPartEntry->New = FALSE;
25556f19c83bSHermès Bélusca-Maïto         NewPartEntry->FormatState = Formatted;     // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
25566f19c83bSHermès Bélusca-Maïto         NewPartEntry->FileSystem  = NULL;
25576f19c83bSHermès Bélusca-Maïto         NewPartEntry->BootIndicator = FALSE;
25586f19c83bSHermès Bélusca-Maïto 
25596f19c83bSHermès Bélusca-Maïto         if (NewPartEntry->StartSector.QuadPart < 1450560)
25606f19c83bSHermès Bélusca-Maïto         {
25616f19c83bSHermès Bélusca-Maïto             /* Partition starts below the 8.4GB boundary ==> CHS partition */
25626f19c83bSHermès Bélusca-Maïto             NewPartEntry->PartitionType = PARTITION_EXTENDED;
25636f19c83bSHermès Bélusca-Maïto         }
25646f19c83bSHermès Bélusca-Maïto         else
25656f19c83bSHermès Bélusca-Maïto         {
25666f19c83bSHermès Bélusca-Maïto             /* Partition starts above the 8.4GB boundary ==> LBA partition */
25676f19c83bSHermès Bélusca-Maïto             NewPartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
25686f19c83bSHermès Bélusca-Maïto         }
25696f19c83bSHermès Bélusca-Maïto 
25706f19c83bSHermès Bélusca-Maïto         DiskEntry->ExtendedPartition = NewPartEntry;
25716f19c83bSHermès Bélusca-Maïto 
25726f19c83bSHermès Bélusca-Maïto         PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
25736f19c83bSHermès Bélusca-Maïto         PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
25746f19c83bSHermès Bélusca-Maïto 
25756f19c83bSHermès Bélusca-Maïto         DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
25766f19c83bSHermès Bélusca-Maïto         DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
25776f19c83bSHermès Bélusca-Maïto         DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
25786f19c83bSHermès Bélusca-Maïto     }
25796f19c83bSHermès Bélusca-Maïto 
25806f19c83bSHermès Bélusca-Maïto     AddLogicalDiskSpace(DiskEntry);
25816f19c83bSHermès Bélusca-Maïto 
25826f19c83bSHermès Bélusca-Maïto     UpdateDiskLayout(DiskEntry);
25836f19c83bSHermès Bélusca-Maïto 
25846f19c83bSHermès Bélusca-Maïto     DiskEntry->Dirty = TRUE;
25856f19c83bSHermès Bélusca-Maïto 
25866f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
25876f19c83bSHermès Bélusca-Maïto }
25886f19c83bSHermès Bélusca-Maïto 
25896f19c83bSHermès Bélusca-Maïto VOID
25906f19c83bSHermès Bélusca-Maïto CreateLogicalPartition(
25916f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
25926f19c83bSHermès Bélusca-Maïto     IN ULONGLONG SectorCount,
25936f19c83bSHermès Bélusca-Maïto     IN BOOLEAN AutoCreate)
25946f19c83bSHermès Bélusca-Maïto {
25956f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
25966f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
25976f19c83bSHermès Bélusca-Maïto     PPARTENTRY NewPartEntry;
25986f19c83bSHermès Bélusca-Maïto 
25996f19c83bSHermès Bélusca-Maïto     DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
26006f19c83bSHermès Bélusca-Maïto 
26016f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
26026f19c83bSHermès Bélusca-Maïto         List->CurrentDisk == NULL ||
26036f19c83bSHermès Bélusca-Maïto         List->CurrentPartition == NULL ||
26046f19c83bSHermès Bélusca-Maïto         List->CurrentPartition->IsPartitioned != FALSE)
26056f19c83bSHermès Bélusca-Maïto     {
26066f19c83bSHermès Bélusca-Maïto         return;
26076f19c83bSHermès Bélusca-Maïto     }
26086f19c83bSHermès Bélusca-Maïto 
26096f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
26106f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
26116f19c83bSHermès Bélusca-Maïto 
26126f19c83bSHermès Bélusca-Maïto     DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart);
26136f19c83bSHermès Bélusca-Maïto 
26146f19c83bSHermès Bélusca-Maïto     if ((AutoCreate != FALSE) ||
26156f19c83bSHermès Bélusca-Maïto         (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart))
26166f19c83bSHermès Bélusca-Maïto     {
26176f19c83bSHermès Bélusca-Maïto         DPRINT1("Convert existing partition entry\n");
26186f19c83bSHermès Bélusca-Maïto 
26196f19c83bSHermès Bélusca-Maïto         /* Convert current entry to 'new (unformatted)' */
26206f19c83bSHermès Bélusca-Maïto         PartEntry->IsPartitioned = TRUE;
26216f19c83bSHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
26226f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = Unformatted;
26236f19c83bSHermès Bélusca-Maïto         PartEntry->FileSystem  = NULL;
26246f19c83bSHermès Bélusca-Maïto         PartEntry->AutoCreate = FALSE;
26256f19c83bSHermès Bélusca-Maïto         PartEntry->New = TRUE;
26266f19c83bSHermès Bélusca-Maïto         PartEntry->BootIndicator = FALSE;
26276f19c83bSHermès Bélusca-Maïto         PartEntry->LogicalPartition = TRUE;
26286f19c83bSHermès Bélusca-Maïto 
26296f19c83bSHermès Bélusca-Maïto         DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart);
26306f19c83bSHermès Bélusca-Maïto         DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1);
26316f19c83bSHermès Bélusca-Maïto         DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart);
26326f19c83bSHermès Bélusca-Maïto     }
26336f19c83bSHermès Bélusca-Maïto     else
26346f19c83bSHermès Bélusca-Maïto     {
26356f19c83bSHermès Bélusca-Maïto         DPRINT1("Add new partition entry\n");
26366f19c83bSHermès Bélusca-Maïto 
26376f19c83bSHermès Bélusca-Maïto         /* Insert and initialize a new partition entry */
26386f19c83bSHermès Bélusca-Maïto         NewPartEntry = RtlAllocateHeap(ProcessHeap,
26396f19c83bSHermès Bélusca-Maïto                                        HEAP_ZERO_MEMORY,
26406f19c83bSHermès Bélusca-Maïto                                        sizeof(PARTENTRY));
26416f19c83bSHermès Bélusca-Maïto         if (NewPartEntry == NULL)
26426f19c83bSHermès Bélusca-Maïto             return;
26436f19c83bSHermès Bélusca-Maïto 
26446f19c83bSHermès Bélusca-Maïto         /* Insert the new entry into the list */
26456f19c83bSHermès Bélusca-Maïto         InsertTailList(&PartEntry->ListEntry,
26466f19c83bSHermès Bélusca-Maïto                        &NewPartEntry->ListEntry);
26476f19c83bSHermès Bélusca-Maïto 
26486f19c83bSHermès Bélusca-Maïto         NewPartEntry->DiskEntry = DiskEntry;
26496f19c83bSHermès Bélusca-Maïto 
26506f19c83bSHermès Bélusca-Maïto         NewPartEntry->IsPartitioned = TRUE;
26516f19c83bSHermès Bélusca-Maïto         NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
26526f19c83bSHermès Bélusca-Maïto         NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) -
26536f19c83bSHermès Bélusca-Maïto                                              NewPartEntry->StartSector.QuadPart;
26546f19c83bSHermès Bélusca-Maïto         NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
26556f19c83bSHermès Bélusca-Maïto 
26566f19c83bSHermès Bélusca-Maïto         DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
26576f19c83bSHermès Bélusca-Maïto         DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
26586f19c83bSHermès Bélusca-Maïto         DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
26596f19c83bSHermès Bélusca-Maïto 
26606f19c83bSHermès Bélusca-Maïto         NewPartEntry->New = TRUE;
26616f19c83bSHermès Bélusca-Maïto         NewPartEntry->FormatState = Unformatted;
26626f19c83bSHermès Bélusca-Maïto         NewPartEntry->FileSystem  = NULL;
26636f19c83bSHermès Bélusca-Maïto         NewPartEntry->BootIndicator = FALSE;
26646f19c83bSHermès Bélusca-Maïto         NewPartEntry->LogicalPartition = TRUE;
26656f19c83bSHermès Bélusca-Maïto 
26666f19c83bSHermès Bélusca-Maïto         PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart;
26676f19c83bSHermès Bélusca-Maïto         PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart);
26686f19c83bSHermès Bélusca-Maïto     }
26696f19c83bSHermès Bélusca-Maïto 
26706f19c83bSHermès Bélusca-Maïto     UpdateDiskLayout(DiskEntry);
26716f19c83bSHermès Bélusca-Maïto 
26726f19c83bSHermès Bélusca-Maïto     DiskEntry->Dirty = TRUE;
26736f19c83bSHermès Bélusca-Maïto 
26746f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
26756f19c83bSHermès Bélusca-Maïto }
26766f19c83bSHermès Bélusca-Maïto 
26776f19c83bSHermès Bélusca-Maïto VOID
26786f19c83bSHermès Bélusca-Maïto DeleteCurrentPartition(
26796f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
26806f19c83bSHermès Bélusca-Maïto {
26816f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
26826f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
26836f19c83bSHermès Bélusca-Maïto     PPARTENTRY PrevPartEntry;
26846f19c83bSHermès Bélusca-Maïto     PPARTENTRY NextPartEntry;
26856f19c83bSHermès Bélusca-Maïto     PPARTENTRY LogicalPartEntry;
26866f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
26876f19c83bSHermès Bélusca-Maïto 
26886f19c83bSHermès Bélusca-Maïto     if (List == NULL ||
26896f19c83bSHermès Bélusca-Maïto         List->CurrentDisk == NULL ||
26906f19c83bSHermès Bélusca-Maïto         List->CurrentPartition == NULL ||
26916f19c83bSHermès Bélusca-Maïto         List->CurrentPartition->IsPartitioned == FALSE)
26926f19c83bSHermès Bélusca-Maïto     {
26936f19c83bSHermès Bélusca-Maïto         return;
26946f19c83bSHermès Bélusca-Maïto     }
26956f19c83bSHermès Bélusca-Maïto 
26966f19c83bSHermès Bélusca-Maïto     /* Clear the system disk and partition pointers if the system partition is being deleted */
26976f19c83bSHermès Bélusca-Maïto     if (List->SystemPartition == List->CurrentPartition)
26986f19c83bSHermès Bélusca-Maïto     {
26996f19c83bSHermès Bélusca-Maïto         List->SystemPartition = NULL;
27006f19c83bSHermès Bélusca-Maïto     }
27016f19c83bSHermès Bélusca-Maïto 
27026f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
27036f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
27046f19c83bSHermès Bélusca-Maïto 
27056f19c83bSHermès Bélusca-Maïto     /* Delete all logical partition entries if an extended partition will be deleted */
27066f19c83bSHermès Bélusca-Maïto     if (DiskEntry->ExtendedPartition == PartEntry)
27076f19c83bSHermès Bélusca-Maïto     {
27086f19c83bSHermès Bélusca-Maïto         while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
27096f19c83bSHermès Bélusca-Maïto         {
27106f19c83bSHermès Bélusca-Maïto             Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
27116f19c83bSHermès Bélusca-Maïto             LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
27126f19c83bSHermès Bélusca-Maïto 
27136f19c83bSHermès Bélusca-Maïto             RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
27146f19c83bSHermès Bélusca-Maïto         }
27156f19c83bSHermès Bélusca-Maïto 
27166f19c83bSHermès Bélusca-Maïto         DiskEntry->ExtendedPartition = NULL;
27176f19c83bSHermès Bélusca-Maïto     }
27186f19c83bSHermès Bélusca-Maïto 
27196f19c83bSHermès Bélusca-Maïto     /* Adjust unpartitioned disk space entries */
27206f19c83bSHermès Bélusca-Maïto 
27216f19c83bSHermès Bélusca-Maïto     /* Get pointer to previous and next unpartitioned entries */
27226f19c83bSHermès Bélusca-Maïto     PrevPartEntry = GetPrevUnpartitionedEntry(DiskEntry, PartEntry);
27236f19c83bSHermès Bélusca-Maïto     NextPartEntry = GetNextUnpartitionedEntry(DiskEntry, PartEntry);
27246f19c83bSHermès Bélusca-Maïto 
27256f19c83bSHermès Bélusca-Maïto     if (PrevPartEntry != NULL && NextPartEntry != NULL)
27266f19c83bSHermès Bélusca-Maïto     {
27276f19c83bSHermès Bélusca-Maïto         /* Merge previous, current and next unpartitioned entry */
27286f19c83bSHermès Bélusca-Maïto 
27296f19c83bSHermès Bélusca-Maïto         /* Adjust the previous entries length */
27306f19c83bSHermès Bélusca-Maïto         PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
27316f19c83bSHermès Bélusca-Maïto 
27326f19c83bSHermès Bélusca-Maïto         /* Remove the current entry */
27336f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&PartEntry->ListEntry);
27346f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, PartEntry);
27356f19c83bSHermès Bélusca-Maïto 
27366f19c83bSHermès Bélusca-Maïto         /* Remove the next entry */
27376f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&NextPartEntry->ListEntry);
27386f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
27396f19c83bSHermès Bélusca-Maïto 
27406f19c83bSHermès Bélusca-Maïto         /* Update current partition */
27416f19c83bSHermès Bélusca-Maïto         List->CurrentPartition = PrevPartEntry;
27426f19c83bSHermès Bélusca-Maïto     }
27436f19c83bSHermès Bélusca-Maïto     else if (PrevPartEntry != NULL && NextPartEntry == NULL)
27446f19c83bSHermès Bélusca-Maïto     {
27456f19c83bSHermès Bélusca-Maïto         /* Merge current and previous unpartitioned entry */
27466f19c83bSHermès Bélusca-Maïto 
27476f19c83bSHermès Bélusca-Maïto         /* Adjust the previous entries length */
27486f19c83bSHermès Bélusca-Maïto         PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
27496f19c83bSHermès Bélusca-Maïto 
27506f19c83bSHermès Bélusca-Maïto         /* Remove the current entry */
27516f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&PartEntry->ListEntry);
27526f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, PartEntry);
27536f19c83bSHermès Bélusca-Maïto 
27546f19c83bSHermès Bélusca-Maïto         /* Update current partition */
27556f19c83bSHermès Bélusca-Maïto         List->CurrentPartition = PrevPartEntry;
27566f19c83bSHermès Bélusca-Maïto     }
27576f19c83bSHermès Bélusca-Maïto     else if (PrevPartEntry == NULL && NextPartEntry != NULL)
27586f19c83bSHermès Bélusca-Maïto     {
27596f19c83bSHermès Bélusca-Maïto         /* Merge current and next unpartitioned entry */
27606f19c83bSHermès Bélusca-Maïto 
27616f19c83bSHermès Bélusca-Maïto         /* Adjust the next entries offset and length */
27626f19c83bSHermès Bélusca-Maïto         NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
27636f19c83bSHermès Bélusca-Maïto         NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
27646f19c83bSHermès Bélusca-Maïto 
27656f19c83bSHermès Bélusca-Maïto         /* Remove the current entry */
27666f19c83bSHermès Bélusca-Maïto         RemoveEntryList(&PartEntry->ListEntry);
27676f19c83bSHermès Bélusca-Maïto         RtlFreeHeap(ProcessHeap, 0, PartEntry);
27686f19c83bSHermès Bélusca-Maïto 
27696f19c83bSHermès Bélusca-Maïto         /* Update current partition */
27706f19c83bSHermès Bélusca-Maïto         List->CurrentPartition = NextPartEntry;
27716f19c83bSHermès Bélusca-Maïto     }
27726f19c83bSHermès Bélusca-Maïto     else
27736f19c83bSHermès Bélusca-Maïto     {
27746f19c83bSHermès Bélusca-Maïto         /* Nothing to merge but change current entry */
27756f19c83bSHermès Bélusca-Maïto         PartEntry->IsPartitioned = FALSE;
27766f19c83bSHermès Bélusca-Maïto         PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
27776f19c83bSHermès Bélusca-Maïto         PartEntry->FormatState = Unformatted;
27786f19c83bSHermès Bélusca-Maïto         PartEntry->FileSystem  = NULL;
27796f19c83bSHermès Bélusca-Maïto         PartEntry->DriveLetter = 0;
27806f19c83bSHermès Bélusca-Maïto     }
27816f19c83bSHermès Bélusca-Maïto 
27826f19c83bSHermès Bélusca-Maïto     UpdateDiskLayout(DiskEntry);
27836f19c83bSHermès Bélusca-Maïto 
27846f19c83bSHermès Bélusca-Maïto     DiskEntry->Dirty = TRUE;
27856f19c83bSHermès Bélusca-Maïto 
27866f19c83bSHermès Bélusca-Maïto     AssignDriveLetters(List);
27876f19c83bSHermès Bélusca-Maïto }
27886f19c83bSHermès Bélusca-Maïto 
27896f19c83bSHermès Bélusca-Maïto VOID
27906f19c83bSHermès Bélusca-Maïto CheckActiveSystemPartition(
27916f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
27926f19c83bSHermès Bélusca-Maïto {
27936f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
27946f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
27956f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY ListEntry;
27966f19c83bSHermès Bélusca-Maïto 
27976f19c83bSHermès Bélusca-Maïto     PFILE_SYSTEM FileSystem;
27986f19c83bSHermès Bélusca-Maïto 
27996f19c83bSHermès Bélusca-Maïto     /* Check for empty disk list */
28006f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&List->DiskListHead))
28016f19c83bSHermès Bélusca-Maïto     {
28026f19c83bSHermès Bélusca-Maïto         List->SystemPartition = NULL;
28036f19c83bSHermès Bélusca-Maïto         List->OriginalSystemPartition = NULL;
28046f19c83bSHermès Bélusca-Maïto         return;
28056f19c83bSHermès Bélusca-Maïto     }
28066f19c83bSHermès Bélusca-Maïto 
28076f19c83bSHermès Bélusca-Maïto     /* Choose the currently selected disk */
28086f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
28096f19c83bSHermès Bélusca-Maïto 
28106f19c83bSHermès Bélusca-Maïto     /* Check for empty partition list */
28116f19c83bSHermès Bélusca-Maïto     if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
28126f19c83bSHermès Bélusca-Maïto     {
28136f19c83bSHermès Bélusca-Maïto         List->SystemPartition = NULL;
28146f19c83bSHermès Bélusca-Maïto         List->OriginalSystemPartition = NULL;
28156f19c83bSHermès Bélusca-Maïto         return;
28166f19c83bSHermès Bélusca-Maïto     }
28176f19c83bSHermès Bélusca-Maïto 
28186f19c83bSHermès Bélusca-Maïto     if (List->SystemPartition != NULL)
28196f19c83bSHermès Bélusca-Maïto     {
28206f19c83bSHermès Bélusca-Maïto         /* We already have an active system partition */
2821f41750abSHermès Bélusca-Maïto         DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n",
28226f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->PartitionNumber,
28236f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->DiskEntry->DiskNumber,
2824f41750abSHermès Bélusca-Maïto                 (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
28256f19c83bSHermès Bélusca-Maïto         return;
28266f19c83bSHermès Bélusca-Maïto     }
28276f19c83bSHermès Bélusca-Maïto 
28286f19c83bSHermès Bélusca-Maïto     DPRINT1("We are here (1)!\n");
28296f19c83bSHermès Bélusca-Maïto 
28306f19c83bSHermès Bélusca-Maïto     List->SystemPartition = NULL;
28316f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = NULL;
28326f19c83bSHermès Bélusca-Maïto 
28336f19c83bSHermès Bélusca-Maïto     /* Retrieve the first partition of the disk */
28346f19c83bSHermès Bélusca-Maïto     PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
28356f19c83bSHermès Bélusca-Maïto                                   PARTENTRY,
28366f19c83bSHermès Bélusca-Maïto                                   ListEntry);
28376f19c83bSHermès Bélusca-Maïto     ASSERT(DiskEntry == PartEntry->DiskEntry);
28386f19c83bSHermès Bélusca-Maïto     List->SystemPartition = PartEntry;
28396f19c83bSHermès Bélusca-Maïto 
28406f19c83bSHermès Bélusca-Maïto     //
28416f19c83bSHermè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
28426f19c83bSHermès Bélusca-Maïto     //
28436f19c83bSHermès Bélusca-Maïto 
28446f19c83bSHermès Bélusca-Maïto     /* Check if the disk is new and if so, use its first partition as the active system partition */
28456f19c83bSHermès Bélusca-Maïto     if (DiskEntry->NewDisk)
28466f19c83bSHermès Bélusca-Maïto     {
28476f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator == FALSE)
28486f19c83bSHermès Bélusca-Maïto         {
28496f19c83bSHermès Bélusca-Maïto             ASSERT(DiskEntry == PartEntry->DiskEntry);
28506f19c83bSHermès Bélusca-Maïto             List->SystemPartition = PartEntry;
28516f19c83bSHermès Bélusca-Maïto 
28526f19c83bSHermès Bélusca-Maïto             List->OriginalSystemPartition = List->SystemPartition;
28536f19c83bSHermès Bélusca-Maïto 
2854f41750abSHermès Bélusca-Maïto             DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
28556f19c83bSHermès Bélusca-Maïto                     List->SystemPartition->PartitionNumber,
28566f19c83bSHermès Bélusca-Maïto                     List->SystemPartition->DiskEntry->DiskNumber,
2857f41750abSHermès Bélusca-Maïto                     (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
28586f19c83bSHermès Bélusca-Maïto 
28596f19c83bSHermès Bélusca-Maïto             goto SetSystemPartition;
28606f19c83bSHermès Bélusca-Maïto         }
28616f19c83bSHermès Bélusca-Maïto 
28626f19c83bSHermès Bélusca-Maïto         // FIXME: What to do??
28636f19c83bSHermès Bélusca-Maïto         DPRINT1("NewDisk TRUE but first partition is used?\n");
28646f19c83bSHermès Bélusca-Maïto     }
28656f19c83bSHermès Bélusca-Maïto 
28666f19c83bSHermès Bélusca-Maïto     DPRINT1("We are here (2)!\n");
28676f19c83bSHermès Bélusca-Maïto 
28686f19c83bSHermès Bélusca-Maïto     /*
28696f19c83bSHermès Bélusca-Maïto      * The disk is not new, check if any partition is initialized;
28706f19c83bSHermès Bélusca-Maïto      * if not, the first one becomes the system partition.
28716f19c83bSHermès Bélusca-Maïto      */
28726f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->PrimaryPartListHead.Flink;
28736f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->PrimaryPartListHead)
28746f19c83bSHermès Bélusca-Maïto     {
28756f19c83bSHermès Bélusca-Maïto         /* Retrieve the partition and go to the next one */
28766f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry,
28776f19c83bSHermès Bélusca-Maïto                                       PARTENTRY,
28786f19c83bSHermès Bélusca-Maïto                                       ListEntry);
28796f19c83bSHermès Bélusca-Maïto 
28806f19c83bSHermès Bélusca-Maïto         /* Check if the partition is partitioned and is used */
28816f19c83bSHermès Bélusca-Maïto         if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator != FALSE)
28826f19c83bSHermès Bélusca-Maïto         {
28836f19c83bSHermès Bélusca-Maïto             break;
28846f19c83bSHermès Bélusca-Maïto         }
28856f19c83bSHermès Bélusca-Maïto 
28866f19c83bSHermès Bélusca-Maïto         /* Go to the next one */
28876f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
28886f19c83bSHermès Bélusca-Maïto     }
28896f19c83bSHermès Bélusca-Maïto     if (ListEntry == &DiskEntry->PrimaryPartListHead)
28906f19c83bSHermès Bélusca-Maïto     {
28916f19c83bSHermès Bélusca-Maïto         /*
28926f19c83bSHermès Bélusca-Maïto          * OK we haven't encountered any used and active partition,
28936f19c83bSHermès Bélusca-Maïto          * so use the first one as the system partition.
28946f19c83bSHermès Bélusca-Maïto          */
28956f19c83bSHermès Bélusca-Maïto         ASSERT(DiskEntry == List->SystemPartition->DiskEntry);
28966f19c83bSHermès Bélusca-Maïto         List->OriginalSystemPartition = List->SystemPartition; // First PartEntry
28976f19c83bSHermès Bélusca-Maïto 
2898f41750abSHermès Bélusca-Maïto         DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
28996f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->PartitionNumber,
29006f19c83bSHermès Bélusca-Maïto                 List->SystemPartition->DiskEntry->DiskNumber,
2901f41750abSHermès Bélusca-Maïto                 (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
29026f19c83bSHermès Bélusca-Maïto 
29036f19c83bSHermès Bélusca-Maïto         goto SetSystemPartition;
29046f19c83bSHermès Bélusca-Maïto     }
29056f19c83bSHermès Bélusca-Maïto 
29066f19c83bSHermès Bélusca-Maïto     List->SystemPartition = NULL;
29076f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = NULL;
29086f19c83bSHermès Bélusca-Maïto 
29096f19c83bSHermès Bélusca-Maïto     DPRINT1("We are here (3)!\n");
29106f19c83bSHermès Bélusca-Maïto 
29116f19c83bSHermès Bélusca-Maïto     /* The disk is not new, scan all partitions to find the (active) system partition */
29126f19c83bSHermès Bélusca-Maïto     ListEntry = DiskEntry->PrimaryPartListHead.Flink;
29136f19c83bSHermès Bélusca-Maïto     while (ListEntry != &DiskEntry->PrimaryPartListHead)
29146f19c83bSHermès Bélusca-Maïto     {
29156f19c83bSHermès Bélusca-Maïto         /* Retrieve the partition and go to the next one */
29166f19c83bSHermès Bélusca-Maïto         PartEntry = CONTAINING_RECORD(ListEntry,
29176f19c83bSHermès Bélusca-Maïto                                       PARTENTRY,
29186f19c83bSHermès Bélusca-Maïto                                       ListEntry);
29196f19c83bSHermès Bélusca-Maïto         ListEntry = ListEntry->Flink;
29206f19c83bSHermès Bélusca-Maïto 
29216f19c83bSHermès Bélusca-Maïto         /* Check if the partition is partitioned and used */
29226f19c83bSHermès Bélusca-Maïto         if (PartEntry->IsPartitioned &&
29236f19c83bSHermès Bélusca-Maïto             PartEntry->PartitionType != PARTITION_ENTRY_UNUSED)
29246f19c83bSHermès Bélusca-Maïto         {
29256f19c83bSHermès Bélusca-Maïto             /* Check if the partition is active */
29266f19c83bSHermès Bélusca-Maïto             if (PartEntry->BootIndicator)
29276f19c83bSHermès Bélusca-Maïto             {
29286f19c83bSHermès Bélusca-Maïto                 /* Yes, we found it */
29296f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
29306f19c83bSHermès Bélusca-Maïto                 List->SystemPartition = PartEntry;
29316f19c83bSHermès Bélusca-Maïto 
2932f41750abSHermès Bélusca-Maïto                 DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n",
29336f19c83bSHermès Bélusca-Maïto                         PartEntry->PartitionNumber,
29346f19c83bSHermès Bélusca-Maïto                         DiskEntry->DiskNumber,
2935f41750abSHermès Bélusca-Maïto                         (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter);
29366f19c83bSHermès Bélusca-Maïto                 break;
29376f19c83bSHermès Bélusca-Maïto             }
29386f19c83bSHermès Bélusca-Maïto         }
29396f19c83bSHermès Bélusca-Maïto     }
29406f19c83bSHermès Bélusca-Maïto 
29416f19c83bSHermès Bélusca-Maïto     /* Check if we have found the system partition */
29426f19c83bSHermès Bélusca-Maïto     if (List->SystemPartition == NULL)
29436f19c83bSHermès Bélusca-Maïto     {
29446f19c83bSHermès Bélusca-Maïto         /* Nothing, use the alternative system partition */
29456f19c83bSHermès Bélusca-Maïto         DPRINT1("No system partition found, use the alternative partition!\n");
29466f19c83bSHermès Bélusca-Maïto         goto UseAlternativeSystemPartition;
29476f19c83bSHermès Bélusca-Maïto     }
29486f19c83bSHermès Bélusca-Maïto 
29496f19c83bSHermès Bélusca-Maïto     /* Save it */
29506f19c83bSHermès Bélusca-Maïto     List->OriginalSystemPartition = List->SystemPartition;
29516f19c83bSHermès Bélusca-Maïto 
29526f19c83bSHermès Bélusca-Maïto     /*
29536f19c83bSHermès Bélusca-Maïto      * ADDITIONAL CHECKS / BIG HACK:
29546f19c83bSHermès Bélusca-Maïto      *
29556f19c83bSHermès Bélusca-Maïto      * Retrieve its file system and check whether we have
29566f19c83bSHermès Bélusca-Maïto      * write support for it. If that is the case we are fine
29576f19c83bSHermès Bélusca-Maïto      * and we can use it directly. However if we don't have
29586f19c83bSHermès Bélusca-Maïto      * write support we will need to change the active system
29596f19c83bSHermès Bélusca-Maïto      * partition.
29606f19c83bSHermès Bélusca-Maïto      *
29616f19c83bSHermès Bélusca-Maïto      * NOTE that this is completely useless on architectures
29626f19c83bSHermès Bélusca-Maïto      * where a real system partition is required, as on these
29636f19c83bSHermès Bélusca-Maïto      * architectures the partition uses the FAT FS, for which
29646f19c83bSHermès Bélusca-Maïto      * we do have write support.
29656f19c83bSHermès Bélusca-Maïto      * NOTE also that for those architectures looking for a
29666f19c83bSHermès Bélusca-Maïto      * partition boot indicator is insufficient.
29676f19c83bSHermès Bélusca-Maïto      */
29686f19c83bSHermès Bélusca-Maïto     FileSystem = GetFileSystem(List->OriginalSystemPartition);
29696f19c83bSHermès Bélusca-Maïto     if (FileSystem == NULL)
29706f19c83bSHermès Bélusca-Maïto     {
29716f19c83bSHermès Bélusca-Maïto         DPRINT1("System partition %lu in disk %lu with no FS?!\n",
29726f19c83bSHermès Bélusca-Maïto                 List->OriginalSystemPartition->PartitionNumber,
29736f19c83bSHermès Bélusca-Maïto                 List->OriginalSystemPartition->DiskEntry->DiskNumber);
29746f19c83bSHermès Bélusca-Maïto         goto FindAndUseAlternativeSystemPartition;
29756f19c83bSHermès Bélusca-Maïto     }
29766f19c83bSHermès Bélusca-Maïto     // HACK: WARNING: We cannot write on this FS yet!
29776f19c83bSHermès Bélusca-Maïto     // See fsutil.c:GetFileSystem()
29784c6370deSBișoc George     if (List->OriginalSystemPartition->PartitionType == PARTITION_IFS)
29796f19c83bSHermès Bélusca-Maïto     {
29806f19c83bSHermès Bélusca-Maïto         DPRINT1("Recognized file system %S that doesn't support write support yet!\n",
29816f19c83bSHermès Bélusca-Maïto                 FileSystem->FileSystemName);
29826f19c83bSHermès Bélusca-Maïto         goto FindAndUseAlternativeSystemPartition;
29836f19c83bSHermès Bélusca-Maïto     }
29846f19c83bSHermès Bélusca-Maïto 
2985f41750abSHermès Bélusca-Maïto     DPRINT1("Use existing active system partition %lu in disk %lu, drive letter %C\n",
29866f19c83bSHermès Bélusca-Maïto             List->SystemPartition->PartitionNumber,
29876f19c83bSHermès Bélusca-Maïto             List->SystemPartition->DiskEntry->DiskNumber,
2988f41750abSHermès Bélusca-Maïto             (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
29896f19c83bSHermès Bélusca-Maïto 
29906f19c83bSHermès Bélusca-Maïto     return;
29916f19c83bSHermès Bélusca-Maïto 
29926f19c83bSHermès Bélusca-Maïto FindAndUseAlternativeSystemPartition:
29936f19c83bSHermès Bélusca-Maïto     /*
29946f19c83bSHermès Bélusca-Maïto      * We are here because we have not found any (active) candidate
29956f19c83bSHermès Bélusca-Maïto      * system partition that we know how to support. What we are going
29966f19c83bSHermès Bélusca-Maïto      * to do is to change the existing system partition and use the
29976f19c83bSHermès Bélusca-Maïto      * partition on which we install ReactOS as the new system partition,
29986f19c83bSHermès Bélusca-Maïto      * and then we will need to add in FreeLdr's entry a boot entry to boot
29996f19c83bSHermès Bélusca-Maïto      * from the original system partition.
30006f19c83bSHermès Bélusca-Maïto      */
30016f19c83bSHermès Bélusca-Maïto 
30026f19c83bSHermès Bélusca-Maïto     /* Unset the old system partition */
30036f19c83bSHermès Bélusca-Maïto     List->SystemPartition->BootIndicator = FALSE;
30046f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = FALSE;
30056f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
30066f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->Dirty = TRUE;
30076f19c83bSHermès Bélusca-Maïto 
30086f19c83bSHermès Bélusca-Maïto UseAlternativeSystemPartition:
30096f19c83bSHermès Bélusca-Maïto     List->SystemPartition = List->CurrentPartition;
30106f19c83bSHermès Bélusca-Maïto 
3011f41750abSHermès Bélusca-Maïto     DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
30126f19c83bSHermès Bélusca-Maïto             List->SystemPartition->PartitionNumber,
30136f19c83bSHermès Bélusca-Maïto             List->SystemPartition->DiskEntry->DiskNumber,
3014f41750abSHermès Bélusca-Maïto             (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter);
30156f19c83bSHermès Bélusca-Maïto 
30166f19c83bSHermès Bélusca-Maïto SetSystemPartition:
30176f19c83bSHermès Bélusca-Maïto     /* Set the new active system partition */
30186f19c83bSHermès Bélusca-Maïto     List->SystemPartition->BootIndicator = TRUE;
30196f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = TRUE;
30206f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE;
30216f19c83bSHermès Bélusca-Maïto     List->SystemPartition->DiskEntry->Dirty = TRUE;
30226f19c83bSHermès Bélusca-Maïto }
30236f19c83bSHermès Bélusca-Maïto 
30246f19c83bSHermès Bélusca-Maïto static
30256f19c83bSHermès Bélusca-Maïto NTSTATUS
30266f19c83bSHermès Bélusca-Maïto WritePartitions(
30276f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
30286f19c83bSHermès Bélusca-Maïto     IN PDISKENTRY DiskEntry)
30296f19c83bSHermès Bélusca-Maïto {
30306f19c83bSHermès Bélusca-Maïto     WCHAR DstPath[MAX_PATH];
30316f19c83bSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
30326f19c83bSHermès Bélusca-Maïto     IO_STATUS_BLOCK Iosb;
30336f19c83bSHermès Bélusca-Maïto     UNICODE_STRING Name;
30346f19c83bSHermès Bélusca-Maïto     ULONG BufferSize;
30356f19c83bSHermès Bélusca-Maïto     HANDLE FileHandle = NULL;
30366f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
30376f19c83bSHermès Bélusca-Maïto 
30386f19c83bSHermès Bélusca-Maïto     DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
30396f19c83bSHermès Bélusca-Maïto 
30406f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(DstPath, ARRAYSIZE(DstPath),
30416f19c83bSHermès Bélusca-Maïto                         L"\\Device\\Harddisk%lu\\Partition0",
30426f19c83bSHermès Bélusca-Maïto                         DiskEntry->DiskNumber);
30436f19c83bSHermès Bélusca-Maïto     RtlInitUnicodeString(&Name, DstPath);
3044765994c9SHermès Bélusca-Maïto 
30456f19c83bSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
30466f19c83bSHermès Bélusca-Maïto                                &Name,
3047765994c9SHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
30486f19c83bSHermès Bélusca-Maïto                                NULL,
30496f19c83bSHermès Bélusca-Maïto                                NULL);
30506f19c83bSHermès Bélusca-Maïto 
30516f19c83bSHermès Bélusca-Maïto     Status = NtOpenFile(&FileHandle,
30526f19c83bSHermès Bélusca-Maïto                         GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
30536f19c83bSHermès Bélusca-Maïto                         &ObjectAttributes,
30546f19c83bSHermès Bélusca-Maïto                         &Iosb,
30556f19c83bSHermès Bélusca-Maïto                         0,
30566f19c83bSHermès Bélusca-Maïto                         FILE_SYNCHRONOUS_IO_NONALERT);
30576f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
30586f19c83bSHermès Bélusca-Maïto     {
30596f19c83bSHermès Bélusca-Maïto         DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
30606f19c83bSHermès Bélusca-Maïto         return Status;
30616f19c83bSHermès Bélusca-Maïto     }
30626f19c83bSHermès Bélusca-Maïto 
30636f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE
30646f19c83bSHermès Bélusca-Maïto     DumpPartitionTable(DiskEntry);
30656f19c83bSHermès Bélusca-Maïto #endif
30666f19c83bSHermès Bélusca-Maïto 
3067f41750abSHermès Bélusca-Maïto     //
3068f41750abSHermès Bélusca-Maïto     // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3069f41750abSHermès Bélusca-Maïto     // the disk in MBR or GPT format in case the disk was not initialized!!
3070f41750abSHermès Bélusca-Maïto     // For this we must ask the user which format to use.
3071f41750abSHermès Bélusca-Maïto     //
3072f41750abSHermès Bélusca-Maïto 
30736f19c83bSHermès Bélusca-Maïto     BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
30746f19c83bSHermès Bélusca-Maïto                  ((DiskEntry->LayoutBuffer->PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
30756f19c83bSHermès Bélusca-Maïto     Status = NtDeviceIoControlFile(FileHandle,
30766f19c83bSHermès Bélusca-Maïto                                    NULL,
30776f19c83bSHermès Bélusca-Maïto                                    NULL,
30786f19c83bSHermès Bélusca-Maïto                                    NULL,
30796f19c83bSHermès Bélusca-Maïto                                    &Iosb,
30806f19c83bSHermès Bélusca-Maïto                                    IOCTL_DISK_SET_DRIVE_LAYOUT,
30816f19c83bSHermès Bélusca-Maïto                                    DiskEntry->LayoutBuffer,
30826f19c83bSHermès Bélusca-Maïto                                    BufferSize,
30836f19c83bSHermès Bélusca-Maïto                                    NULL,
30846f19c83bSHermès Bélusca-Maïto                                    0);
30856f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
30866f19c83bSHermès Bélusca-Maïto     {
30876f19c83bSHermès Bélusca-Maïto         DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
30886f19c83bSHermès Bélusca-Maïto     }
30896f19c83bSHermès Bélusca-Maïto 
30906f19c83bSHermès Bélusca-Maïto     if (FileHandle != NULL)
30916f19c83bSHermès Bélusca-Maïto         NtClose(FileHandle);
30926f19c83bSHermès Bélusca-Maïto 
30936f19c83bSHermès Bélusca-Maïto     //
30946f19c83bSHermès Bélusca-Maïto     // NOTE: Originally (see r40437), we used to install here also a new MBR
30956f19c83bSHermès Bélusca-Maïto     // for this disk (by calling InstallMbrBootCodeToDisk), only if:
30966f19c83bSHermès Bélusca-Maïto     // DiskEntry->NewDisk == TRUE and DiskEntry->BiosDiskNumber == 0.
30976f19c83bSHermès Bélusca-Maïto     // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
30986f19c83bSHermès Bélusca-Maïto     // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
30996f19c83bSHermès Bélusca-Maïto     // was called too, the installation test was modified by checking whether
31006f19c83bSHermès Bélusca-Maïto     // DiskEntry->NoMbr was TRUE (instead of NewDisk).
31016f19c83bSHermès Bélusca-Maïto     //
31026f19c83bSHermès Bélusca-Maïto 
31036f19c83bSHermès Bélusca-Maïto     return Status;
31046f19c83bSHermès Bélusca-Maïto }
31056f19c83bSHermès Bélusca-Maïto 
31066f19c83bSHermès Bélusca-Maïto BOOLEAN
31076f19c83bSHermès Bélusca-Maïto WritePartitionsToDisk(
31086f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
31096f19c83bSHermès Bélusca-Maïto {
31106f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry;
31116f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
31126f19c83bSHermès Bélusca-Maïto 
31136f19c83bSHermès Bélusca-Maïto     if (List == NULL)
31146f19c83bSHermès Bélusca-Maïto         return TRUE;
31156f19c83bSHermès Bélusca-Maïto 
31166f19c83bSHermès Bélusca-Maïto     Entry = List->DiskListHead.Flink;
31176f19c83bSHermès Bélusca-Maïto     while (Entry != &List->DiskListHead)
31186f19c83bSHermès Bélusca-Maïto     {
31196f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
31206f19c83bSHermès Bélusca-Maïto 
31216f19c83bSHermès Bélusca-Maïto         if (DiskEntry->Dirty != FALSE)
31226f19c83bSHermès Bélusca-Maïto         {
31236f19c83bSHermès Bélusca-Maïto             WritePartitions(List, DiskEntry);
31246f19c83bSHermès Bélusca-Maïto             DiskEntry->Dirty = FALSE;
31256f19c83bSHermès Bélusca-Maïto         }
31266f19c83bSHermès Bélusca-Maïto 
31276f19c83bSHermès Bélusca-Maïto         Entry = Entry->Flink;
31286f19c83bSHermès Bélusca-Maïto     }
31296f19c83bSHermès Bélusca-Maïto 
31306f19c83bSHermès Bélusca-Maïto     return TRUE;
31316f19c83bSHermès Bélusca-Maïto }
31326f19c83bSHermès Bélusca-Maïto 
31336f19c83bSHermès Bélusca-Maïto BOOLEAN
31346f19c83bSHermès Bélusca-Maïto SetMountedDeviceValue(
3135f41750abSHermès Bélusca-Maïto     IN WCHAR Letter,
31366f19c83bSHermès Bélusca-Maïto     IN ULONG Signature,
31376f19c83bSHermès Bélusca-Maïto     IN LARGE_INTEGER StartingOffset)
31386f19c83bSHermès Bélusca-Maïto {
31396f19c83bSHermès Bélusca-Maïto     OBJECT_ATTRIBUTES ObjectAttributes;
31406f19c83bSHermès Bélusca-Maïto     WCHAR ValueNameBuffer[16];
31416f19c83bSHermès Bélusca-Maïto     UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\MountedDevices");
31426f19c83bSHermès Bélusca-Maïto     UNICODE_STRING ValueName;
31436f19c83bSHermès Bélusca-Maïto     REG_DISK_MOUNT_INFO MountInfo;
31446f19c83bSHermès Bélusca-Maïto     NTSTATUS Status;
31456f19c83bSHermès Bélusca-Maïto     HANDLE KeyHandle;
31466f19c83bSHermès Bélusca-Maïto 
31476f19c83bSHermès Bélusca-Maïto     RtlStringCchPrintfW(ValueNameBuffer, ARRAYSIZE(ValueNameBuffer),
3148f41750abSHermès Bélusca-Maïto                         L"\\DosDevices\\%c:", Letter);
31496f19c83bSHermès Bélusca-Maïto     RtlInitUnicodeString(&ValueName, ValueNameBuffer);
31506f19c83bSHermès Bélusca-Maïto 
31516f19c83bSHermès Bélusca-Maïto     InitializeObjectAttributes(&ObjectAttributes,
31526f19c83bSHermès Bélusca-Maïto                                &KeyName,
31536f19c83bSHermès Bélusca-Maïto                                OBJ_CASE_INSENSITIVE,
31546f19c83bSHermès Bélusca-Maïto                                NULL,
31556f19c83bSHermès Bélusca-Maïto                                NULL);
3156765994c9SHermès Bélusca-Maïto 
31576f19c83bSHermès Bélusca-Maïto     Status =  NtOpenKey(&KeyHandle,
31586f19c83bSHermès Bélusca-Maïto                         KEY_ALL_ACCESS,
31596f19c83bSHermès Bélusca-Maïto                         &ObjectAttributes);
31606f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
31616f19c83bSHermès Bélusca-Maïto     {
31626f19c83bSHermès Bélusca-Maïto         Status = NtCreateKey(&KeyHandle,
31636f19c83bSHermès Bélusca-Maïto                              KEY_ALL_ACCESS,
31646f19c83bSHermès Bélusca-Maïto                              &ObjectAttributes,
31656f19c83bSHermès Bélusca-Maïto                              0,
31666f19c83bSHermès Bélusca-Maïto                              NULL,
31676f19c83bSHermès Bélusca-Maïto                              REG_OPTION_NON_VOLATILE,
31686f19c83bSHermès Bélusca-Maïto                              NULL);
31696f19c83bSHermès Bélusca-Maïto     }
31706f19c83bSHermès Bélusca-Maïto 
31716f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
31726f19c83bSHermès Bélusca-Maïto     {
31736f19c83bSHermès Bélusca-Maïto         DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
31746f19c83bSHermès Bélusca-Maïto         return FALSE;
31756f19c83bSHermès Bélusca-Maïto     }
31766f19c83bSHermès Bélusca-Maïto 
31776f19c83bSHermès Bélusca-Maïto     MountInfo.Signature = Signature;
31786f19c83bSHermès Bélusca-Maïto     MountInfo.StartingOffset = StartingOffset;
31796f19c83bSHermès Bélusca-Maïto     Status = NtSetValueKey(KeyHandle,
31806f19c83bSHermès Bélusca-Maïto                            &ValueName,
31816f19c83bSHermès Bélusca-Maïto                            0,
31826f19c83bSHermès Bélusca-Maïto                            REG_BINARY,
31836f19c83bSHermès Bélusca-Maïto                            (PVOID)&MountInfo,
31846f19c83bSHermès Bélusca-Maïto                            sizeof(MountInfo));
31856f19c83bSHermès Bélusca-Maïto     NtClose(KeyHandle);
31866f19c83bSHermès Bélusca-Maïto     if (!NT_SUCCESS(Status))
31876f19c83bSHermès Bélusca-Maïto     {
31886f19c83bSHermès Bélusca-Maïto         DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
31896f19c83bSHermès Bélusca-Maïto         return FALSE;
31906f19c83bSHermès Bélusca-Maïto     }
31916f19c83bSHermès Bélusca-Maïto 
31926f19c83bSHermès Bélusca-Maïto     return TRUE;
31936f19c83bSHermès Bélusca-Maïto }
31946f19c83bSHermès Bélusca-Maïto 
31956f19c83bSHermès Bélusca-Maïto BOOLEAN
31966f19c83bSHermès Bélusca-Maïto SetMountedDeviceValues(
31976f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
31986f19c83bSHermès Bélusca-Maïto {
31996f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1, Entry2;
32006f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
32016f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
32026f19c83bSHermès Bélusca-Maïto     LARGE_INTEGER StartingOffset;
32036f19c83bSHermès Bélusca-Maïto 
32046f19c83bSHermès Bélusca-Maïto     if (List == NULL)
32056f19c83bSHermès Bélusca-Maïto         return FALSE;
32066f19c83bSHermès Bélusca-Maïto 
32076f19c83bSHermès Bélusca-Maïto     Entry1 = List->DiskListHead.Flink;
32086f19c83bSHermès Bélusca-Maïto     while (Entry1 != &List->DiskListHead)
32096f19c83bSHermès Bélusca-Maïto     {
32106f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1,
32116f19c83bSHermès Bélusca-Maïto                                       DISKENTRY,
32126f19c83bSHermès Bélusca-Maïto                                       ListEntry);
32136f19c83bSHermès Bélusca-Maïto 
32146f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->PrimaryPartListHead.Flink;
32156f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->PrimaryPartListHead)
32166f19c83bSHermès Bélusca-Maïto         {
32176f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
32186f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned)
32196f19c83bSHermès Bélusca-Maïto             {
32206f19c83bSHermès Bélusca-Maïto                 /* Assign a "\DosDevices\#:" mount point to this partition */
32216f19c83bSHermès Bélusca-Maïto                 if (PartEntry->DriveLetter)
32226f19c83bSHermès Bélusca-Maïto                 {
32236f19c83bSHermès Bélusca-Maïto                     StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
32246f19c83bSHermès Bélusca-Maïto                     if (!SetMountedDeviceValue(PartEntry->DriveLetter,
32256f19c83bSHermès Bélusca-Maïto                                                DiskEntry->LayoutBuffer->Signature,
32266f19c83bSHermès Bélusca-Maïto                                                StartingOffset))
32276f19c83bSHermès Bélusca-Maïto                     {
32286f19c83bSHermès Bélusca-Maïto                         return FALSE;
32296f19c83bSHermès Bélusca-Maïto                     }
32306f19c83bSHermès Bélusca-Maïto                 }
32316f19c83bSHermès Bélusca-Maïto             }
32326f19c83bSHermès Bélusca-Maïto 
32336f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
32346f19c83bSHermès Bélusca-Maïto         }
32356f19c83bSHermès Bélusca-Maïto 
32366f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->LogicalPartListHead.Flink;
32376f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->LogicalPartListHead)
32386f19c83bSHermès Bélusca-Maïto         {
32396f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
32406f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned)
32416f19c83bSHermès Bélusca-Maïto             {
32426f19c83bSHermès Bélusca-Maïto                 /* Assign a "\DosDevices\#:" mount point to this partition */
32436f19c83bSHermès Bélusca-Maïto                 if (PartEntry->DriveLetter)
32446f19c83bSHermès Bélusca-Maïto                 {
32456f19c83bSHermès Bélusca-Maïto                     StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
32466f19c83bSHermès Bélusca-Maïto                     if (!SetMountedDeviceValue(PartEntry->DriveLetter,
32476f19c83bSHermès Bélusca-Maïto                                                DiskEntry->LayoutBuffer->Signature,
32486f19c83bSHermès Bélusca-Maïto                                                StartingOffset))
32496f19c83bSHermès Bélusca-Maïto                     {
32506f19c83bSHermès Bélusca-Maïto                         return FALSE;
32516f19c83bSHermès Bélusca-Maïto                     }
32526f19c83bSHermès Bélusca-Maïto                 }
32536f19c83bSHermès Bélusca-Maïto             }
32546f19c83bSHermès Bélusca-Maïto 
32556f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
32566f19c83bSHermès Bélusca-Maïto         }
32576f19c83bSHermès Bélusca-Maïto 
32586f19c83bSHermès Bélusca-Maïto         Entry1 = Entry1->Flink;
32596f19c83bSHermès Bélusca-Maïto     }
32606f19c83bSHermès Bélusca-Maïto 
32616f19c83bSHermès Bélusca-Maïto     return TRUE;
32626f19c83bSHermès Bélusca-Maïto }
32636f19c83bSHermès Bélusca-Maïto 
32646f19c83bSHermès Bélusca-Maïto VOID
32656f19c83bSHermès Bélusca-Maïto SetPartitionType(
32666f19c83bSHermès Bélusca-Maïto     IN PPARTENTRY PartEntry,
32676f19c83bSHermès Bélusca-Maïto     IN UCHAR PartitionType)
32686f19c83bSHermès Bélusca-Maïto {
32696f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry = PartEntry->DiskEntry;
32706f19c83bSHermès Bélusca-Maïto 
32716f19c83bSHermès Bélusca-Maïto     PartEntry->PartitionType = PartitionType;
32726f19c83bSHermès Bélusca-Maïto 
32736f19c83bSHermès Bélusca-Maïto     DiskEntry->Dirty = TRUE;
32746f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
32756f19c83bSHermès Bélusca-Maïto     DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
32766f19c83bSHermès Bélusca-Maïto }
32776f19c83bSHermès Bélusca-Maïto 
32786f19c83bSHermès Bélusca-Maïto ERROR_NUMBER
32796f19c83bSHermès Bélusca-Maïto PrimaryPartitionCreationChecks(
32806f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
32816f19c83bSHermès Bélusca-Maïto {
32826f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
32836f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
32846f19c83bSHermès Bélusca-Maïto 
32856f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
32866f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
32876f19c83bSHermès Bélusca-Maïto 
32886f19c83bSHermès Bélusca-Maïto     /* Fail if the partition is already in use */
32896f19c83bSHermès Bélusca-Maïto     if (PartEntry->IsPartitioned != FALSE)
32906f19c83bSHermès Bélusca-Maïto         return ERROR_NEW_PARTITION;
32916f19c83bSHermès Bélusca-Maïto 
32926f19c83bSHermès Bélusca-Maïto     /* Fail if there are already 4 primary partitions in the list */
32936f19c83bSHermès Bélusca-Maïto     if (GetPrimaryPartitionCount(DiskEntry) >= 4)
32946f19c83bSHermès Bélusca-Maïto         return ERROR_PARTITION_TABLE_FULL;
32956f19c83bSHermès Bélusca-Maïto 
32966f19c83bSHermès Bélusca-Maïto     return ERROR_SUCCESS;
32976f19c83bSHermès Bélusca-Maïto }
32986f19c83bSHermès Bélusca-Maïto 
32996f19c83bSHermès Bélusca-Maïto ERROR_NUMBER
33006f19c83bSHermès Bélusca-Maïto ExtendedPartitionCreationChecks(
33016f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
33026f19c83bSHermès Bélusca-Maïto {
33036f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
33046f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
33056f19c83bSHermès Bélusca-Maïto 
33066f19c83bSHermès Bélusca-Maïto     DiskEntry = List->CurrentDisk;
33076f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
33086f19c83bSHermès Bélusca-Maïto 
33096f19c83bSHermès Bélusca-Maïto     /* Fail if the partition is already in use */
33106f19c83bSHermès Bélusca-Maïto     if (PartEntry->IsPartitioned != FALSE)
33116f19c83bSHermès Bélusca-Maïto         return ERROR_NEW_PARTITION;
33126f19c83bSHermès Bélusca-Maïto 
33136f19c83bSHermès Bélusca-Maïto     /* Fail if there are already 4 primary partitions in the list */
33146f19c83bSHermès Bélusca-Maïto     if (GetPrimaryPartitionCount(DiskEntry) >= 4)
33156f19c83bSHermès Bélusca-Maïto         return ERROR_PARTITION_TABLE_FULL;
33166f19c83bSHermès Bélusca-Maïto 
33176f19c83bSHermès Bélusca-Maïto     /* Fail if there is another extended partition in the list */
33186f19c83bSHermès Bélusca-Maïto     if (DiskEntry->ExtendedPartition != NULL)
33196f19c83bSHermès Bélusca-Maïto         return ERROR_ONLY_ONE_EXTENDED;
33206f19c83bSHermès Bélusca-Maïto 
33216f19c83bSHermès Bélusca-Maïto     return ERROR_SUCCESS;
33226f19c83bSHermès Bélusca-Maïto }
33236f19c83bSHermès Bélusca-Maïto 
33246f19c83bSHermès Bélusca-Maïto ERROR_NUMBER
33256f19c83bSHermès Bélusca-Maïto LogicalPartitionCreationChecks(
33266f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List)
33276f19c83bSHermès Bélusca-Maïto {
33286f19c83bSHermès Bélusca-Maïto //    PDISKENTRY DiskEntry;
33296f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
33306f19c83bSHermès Bélusca-Maïto 
33316f19c83bSHermès Bélusca-Maïto //    DiskEntry = List->CurrentDisk;
33326f19c83bSHermès Bélusca-Maïto     PartEntry = List->CurrentPartition;
33336f19c83bSHermès Bélusca-Maïto 
33346f19c83bSHermès Bélusca-Maïto     /* Fail if the partition is already in use */
33356f19c83bSHermès Bélusca-Maïto     if (PartEntry->IsPartitioned != FALSE)
33366f19c83bSHermès Bélusca-Maïto         return ERROR_NEW_PARTITION;
33376f19c83bSHermès Bélusca-Maïto 
33386f19c83bSHermès Bélusca-Maïto     return ERROR_SUCCESS;
33396f19c83bSHermès Bélusca-Maïto }
33406f19c83bSHermès Bélusca-Maïto 
33416f19c83bSHermès Bélusca-Maïto BOOLEAN
33426f19c83bSHermès Bélusca-Maïto GetNextUnformattedPartition(
33436f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
33446f19c83bSHermès Bélusca-Maïto     OUT PDISKENTRY *pDiskEntry OPTIONAL,
33456f19c83bSHermès Bélusca-Maïto     OUT PPARTENTRY *pPartEntry)
33466f19c83bSHermès Bélusca-Maïto {
33476f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1, Entry2;
33486f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
33496f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
33506f19c83bSHermès Bélusca-Maïto 
33516f19c83bSHermès Bélusca-Maïto     Entry1 = List->DiskListHead.Flink;
33526f19c83bSHermès Bélusca-Maïto     while (Entry1 != &List->DiskListHead)
33536f19c83bSHermès Bélusca-Maïto     {
33546f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1,
33556f19c83bSHermès Bélusca-Maïto                                       DISKENTRY,
33566f19c83bSHermès Bélusca-Maïto                                       ListEntry);
33576f19c83bSHermès Bélusca-Maïto 
33586f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->PrimaryPartListHead.Flink;
33596f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->PrimaryPartListHead)
33606f19c83bSHermès Bélusca-Maïto         {
33616f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
33626f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned && PartEntry->New)
33636f19c83bSHermès Bélusca-Maïto             {
33646f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
33656f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
33666f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
33676f19c83bSHermès Bélusca-Maïto                 return TRUE;
33686f19c83bSHermès Bélusca-Maïto             }
33696f19c83bSHermès Bélusca-Maïto 
33706f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
33716f19c83bSHermès Bélusca-Maïto         }
33726f19c83bSHermès Bélusca-Maïto 
33736f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->LogicalPartListHead.Flink;
33746f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->LogicalPartListHead)
33756f19c83bSHermès Bélusca-Maïto         {
33766f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
33776f19c83bSHermès Bélusca-Maïto             if (PartEntry->IsPartitioned && PartEntry->New)
33786f19c83bSHermès Bélusca-Maïto             {
33796f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
33806f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
33816f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
33826f19c83bSHermès Bélusca-Maïto                 return TRUE;
33836f19c83bSHermès Bélusca-Maïto             }
33846f19c83bSHermès Bélusca-Maïto 
33856f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
33866f19c83bSHermès Bélusca-Maïto         }
33876f19c83bSHermès Bélusca-Maïto 
33886f19c83bSHermès Bélusca-Maïto         Entry1 = Entry1->Flink;
33896f19c83bSHermès Bélusca-Maïto     }
33906f19c83bSHermès Bélusca-Maïto 
33916f19c83bSHermès Bélusca-Maïto     if (pDiskEntry) *pDiskEntry = NULL;
33926f19c83bSHermès Bélusca-Maïto     *pPartEntry = NULL;
33936f19c83bSHermès Bélusca-Maïto 
33946f19c83bSHermès Bélusca-Maïto     return FALSE;
33956f19c83bSHermès Bélusca-Maïto }
33966f19c83bSHermès Bélusca-Maïto 
33976f19c83bSHermès Bélusca-Maïto BOOLEAN
33986f19c83bSHermès Bélusca-Maïto GetNextUncheckedPartition(
33996f19c83bSHermès Bélusca-Maïto     IN PPARTLIST List,
34006f19c83bSHermès Bélusca-Maïto     OUT PDISKENTRY *pDiskEntry OPTIONAL,
34016f19c83bSHermès Bélusca-Maïto     OUT PPARTENTRY *pPartEntry)
34026f19c83bSHermès Bélusca-Maïto {
34036f19c83bSHermès Bélusca-Maïto     PLIST_ENTRY Entry1, Entry2;
34046f19c83bSHermès Bélusca-Maïto     PDISKENTRY DiskEntry;
34056f19c83bSHermès Bélusca-Maïto     PPARTENTRY PartEntry;
34066f19c83bSHermès Bélusca-Maïto 
34076f19c83bSHermès Bélusca-Maïto     Entry1 = List->DiskListHead.Flink;
34086f19c83bSHermès Bélusca-Maïto     while (Entry1 != &List->DiskListHead)
34096f19c83bSHermès Bélusca-Maïto     {
34106f19c83bSHermès Bélusca-Maïto         DiskEntry = CONTAINING_RECORD(Entry1,
34116f19c83bSHermès Bélusca-Maïto                                       DISKENTRY,
34126f19c83bSHermès Bélusca-Maïto                                       ListEntry);
34136f19c83bSHermès Bélusca-Maïto 
34146f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->PrimaryPartListHead.Flink;
34156f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->PrimaryPartListHead)
34166f19c83bSHermès Bélusca-Maïto         {
34176f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
34186f19c83bSHermès Bélusca-Maïto             if (PartEntry->NeedsCheck == TRUE)
34196f19c83bSHermès Bélusca-Maïto             {
34206f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
34216f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
34226f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
34236f19c83bSHermès Bélusca-Maïto                 return TRUE;
34246f19c83bSHermès Bélusca-Maïto             }
34256f19c83bSHermès Bélusca-Maïto 
34266f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
34276f19c83bSHermès Bélusca-Maïto         }
34286f19c83bSHermès Bélusca-Maïto 
34296f19c83bSHermès Bélusca-Maïto         Entry2 = DiskEntry->LogicalPartListHead.Flink;
34306f19c83bSHermès Bélusca-Maïto         while (Entry2 != &DiskEntry->LogicalPartListHead)
34316f19c83bSHermès Bélusca-Maïto         {
34326f19c83bSHermès Bélusca-Maïto             PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
34336f19c83bSHermès Bélusca-Maïto             if (PartEntry->NeedsCheck == TRUE)
34346f19c83bSHermès Bélusca-Maïto             {
34356f19c83bSHermès Bélusca-Maïto                 ASSERT(DiskEntry == PartEntry->DiskEntry);
34366f19c83bSHermès Bélusca-Maïto                 if (pDiskEntry) *pDiskEntry = DiskEntry;
34376f19c83bSHermès Bélusca-Maïto                 *pPartEntry = PartEntry;
34386f19c83bSHermès Bélusca-Maïto                 return TRUE;
34396f19c83bSHermès Bélusca-Maïto             }
34406f19c83bSHermès Bélusca-Maïto 
34416f19c83bSHermès Bélusca-Maïto             Entry2 = Entry2->Flink;
34426f19c83bSHermès Bélusca-Maïto         }
34436f19c83bSHermès Bélusca-Maïto 
34446f19c83bSHermès Bélusca-Maïto         Entry1 = Entry1->Flink;
34456f19c83bSHermès Bélusca-Maïto     }
34466f19c83bSHermès Bélusca-Maïto 
34476f19c83bSHermès Bélusca-Maïto     if (pDiskEntry) *pDiskEntry = NULL;
34486f19c83bSHermès Bélusca-Maïto     *pPartEntry = NULL;
34496f19c83bSHermès Bélusca-Maïto 
34506f19c83bSHermès Bélusca-Maïto     return FALSE;
34516f19c83bSHermès Bélusca-Maïto }
34526f19c83bSHermès Bélusca-Maïto 
34536f19c83bSHermès Bélusca-Maïto /* EOF */
3454