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