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