16f19c83bSHermès Bélusca-Maïto /* 26f19c83bSHermès Bélusca-Maïto * PROJECT: ReactOS Setup Library 36f19c83bSHermès Bélusca-Maïto * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 46f19c83bSHermès Bélusca-Maïto * PURPOSE: Partition list functions 56f19c83bSHermès Bélusca-Maïto * COPYRIGHT: Copyright 2003-2018 Casper S. Hornstrup (chorns@users.sourceforge.net) 66f19c83bSHermès Bélusca-Maïto */ 76f19c83bSHermès Bélusca-Maïto 86f19c83bSHermès Bélusca-Maïto #include "precomp.h" 96f19c83bSHermès Bélusca-Maïto #include <ntddscsi.h> 106f19c83bSHermès Bélusca-Maïto 116f19c83bSHermès Bélusca-Maïto #include "partlist.h" 126f19c83bSHermès Bélusca-Maïto #include "fsutil.h" 136f19c83bSHermès Bélusca-Maïto 146f19c83bSHermès Bélusca-Maïto #define NDEBUG 156f19c83bSHermès Bélusca-Maïto #include <debug.h> 166f19c83bSHermès Bélusca-Maïto 176f19c83bSHermès Bélusca-Maïto //#define DUMP_PARTITION_TABLE 186f19c83bSHermès Bélusca-Maïto 196f19c83bSHermès Bélusca-Maïto #include <pshpack1.h> 206f19c83bSHermès Bélusca-Maïto 216f19c83bSHermès Bélusca-Maïto typedef struct _REG_DISK_MOUNT_INFO 226f19c83bSHermès Bélusca-Maïto { 236f19c83bSHermès Bélusca-Maïto ULONG Signature; 246f19c83bSHermès Bélusca-Maïto LARGE_INTEGER StartingOffset; 256f19c83bSHermès Bélusca-Maïto } REG_DISK_MOUNT_INFO, *PREG_DISK_MOUNT_INFO; 266f19c83bSHermès Bélusca-Maïto 276f19c83bSHermès Bélusca-Maïto #include <poppack.h> 286f19c83bSHermès Bélusca-Maïto 296f19c83bSHermès Bélusca-Maïto 30f41750abSHermès Bélusca-Maïto /* HELPERS FOR PARTITION TYPES **********************************************/ 31f41750abSHermès Bélusca-Maïto 32f41750abSHermès Bélusca-Maïto /* 33f41750abSHermès Bélusca-Maïto * This partition type list was ripped from the kernelDisk.c module of 34f41750abSHermès Bélusca-Maïto * the Visopsys Operating System (see license below), and completed with 35f41750abSHermès Bélusca-Maïto * information from Paragon Hard-Disk Manager, and the following websites: 36f41750abSHermès Bélusca-Maïto * http://www.win.tue.nl/~aeb/partitions/partition_types-1.html 37f41750abSHermès Bélusca-Maïto * https://en.wikipedia.org/wiki/Partition_type#List_of_partition_IDs 38f41750abSHermès Bélusca-Maïto */ 39f41750abSHermès Bélusca-Maïto /* 40f41750abSHermès Bélusca-Maïto * kernelDisk.c 41f41750abSHermès Bélusca-Maïto * 42f41750abSHermès Bélusca-Maïto * Visopsys Operating System 43f41750abSHermès Bélusca-Maïto * Copyright (C) 1998-2015 J. Andrew McLaughlin 44f41750abSHermès Bélusca-Maïto * 45f41750abSHermès Bélusca-Maïto * This program is free software; you can redistribute it and/or modify it 46f41750abSHermès Bélusca-Maïto * under the terms of the GNU General Public License as published by the Free 47f41750abSHermès Bélusca-Maïto * Software Foundation; either version 2 of the License, or (at your option) 48f41750abSHermès Bélusca-Maïto * any later version. 49f41750abSHermès Bélusca-Maïto * 50f41750abSHermès Bélusca-Maïto * This program is distributed in the hope that it will be useful, but 51f41750abSHermès Bélusca-Maïto * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 52f41750abSHermès Bélusca-Maïto * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 53f41750abSHermès Bélusca-Maïto * for more details. 54f41750abSHermès Bélusca-Maïto * 55f41750abSHermès Bélusca-Maïto * You should have received a copy of the GNU General Public License along 56f41750abSHermès Bélusca-Maïto * with this program; if not, write to the Free Software Foundation, Inc., 57f41750abSHermès Bélusca-Maïto * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 58f41750abSHermès Bélusca-Maïto */ 59f41750abSHermès Bélusca-Maïto 60f41750abSHermès Bélusca-Maïto /* This is a table for keeping known partition type codes and descriptions */ 61f41750abSHermès Bélusca-Maïto PARTITION_TYPE PartitionTypes[NUM_PARTITION_TYPE_ENTRIES] = 62f41750abSHermès Bélusca-Maïto { 63f41750abSHermès Bélusca-Maïto { 0x00, "(Empty)" }, 64f41750abSHermès Bélusca-Maïto { 0x01, "FAT12" }, 65f41750abSHermès Bélusca-Maïto { 0x02, "XENIX root" }, 66f41750abSHermès Bélusca-Maïto { 0x03, "XENIX usr" }, 67f41750abSHermès Bélusca-Maïto { 0x04, "FAT16 (< 32 MB)" }, 68f41750abSHermès Bélusca-Maïto { 0x05, "Extended" }, 69f41750abSHermès Bélusca-Maïto { 0x06, "FAT16" }, 70f41750abSHermès Bélusca-Maïto { 0x07, "NTFS/HPFS/exFAT" }, 71f41750abSHermès Bélusca-Maïto { 0x08, "OS/2 or AIX boot" }, 72f41750abSHermès Bélusca-Maïto { 0x09, "AIX data" }, 73f41750abSHermès Bélusca-Maïto { 0x0A, "OS/2 Boot Manager" }, 74f41750abSHermès Bélusca-Maïto { 0x0B, "FAT32" }, 75f41750abSHermès Bélusca-Maïto { 0x0C, "FAT32 (LBA)" }, 76f41750abSHermès Bélusca-Maïto { 0x0E, "FAT16 (LBA)" }, 77f41750abSHermès Bélusca-Maïto { 0x0F, "Extended (LBA)" }, 78f41750abSHermès Bélusca-Maïto { 0x10, "OPUS" }, 79f41750abSHermès Bélusca-Maïto { 0x11, "Hidden FAT12" }, 80f41750abSHermès Bélusca-Maïto { 0x12, "FAT diagnostic (Compaq)" }, 81f41750abSHermès Bélusca-Maïto { 0x13, "BTRON" }, 82f41750abSHermès Bélusca-Maïto { 0x14, "Hidden FAT16 (< 32 MB)" }, 83f41750abSHermès Bélusca-Maïto { 0x16, "Hidden FAT16" }, 84f41750abSHermès Bélusca-Maïto { 0x17, "Hidden HPFS or NTFS" }, 85f41750abSHermès Bélusca-Maïto { 0x18, "AST SmartSleep" }, 86f41750abSHermès Bélusca-Maïto { 0x1B, "Hidden FAT32" }, 87f41750abSHermès Bélusca-Maïto { 0x1C, "Hidden FAT32 (LBA)" }, 88f41750abSHermès Bélusca-Maïto { 0x1E, "Hidden FAT16 (LBA)" }, 89f41750abSHermès Bélusca-Maïto { 0x24, "NEC DOS 3.x" }, 90f41750abSHermès Bélusca-Maïto { 0x27, "Hidden WinRE NTFS" }, 91f41750abSHermès Bélusca-Maïto { 0x2A, "AtheOS File System (AFS)" }, 92f41750abSHermès Bélusca-Maïto { 0x2B, "SyllableSecure (SylStor)" }, 93f41750abSHermès Bélusca-Maïto { 0x32, "NOS" }, 94f41750abSHermès Bélusca-Maïto { 0x35, "JFS on OS/2 or eCS" }, 95f41750abSHermès Bélusca-Maïto { 0x38, "THEOS v3.2 2GB partition" }, 96f41750abSHermès Bélusca-Maïto { 0x39, "Plan 9" }, 97f41750abSHermès Bélusca-Maïto { 0x3A, "THEOS v4 4GB partition" }, 98f41750abSHermès Bélusca-Maïto { 0x3B, "THEOS v4 extended partition" }, 99f41750abSHermès Bélusca-Maïto { 0x3C, "PartitionMagic recovery partition" }, 100f41750abSHermès Bélusca-Maïto { 0x3D, "Hidden NetWare" }, 101f41750abSHermès Bélusca-Maïto { 0x40, "Lynx" }, 102f41750abSHermès Bélusca-Maïto { 0x41, "PowerPC PReP boot" }, 103f41750abSHermès Bélusca-Maïto { 0x42, "Win2K Dynamic Volume extended" }, 104f41750abSHermès Bélusca-Maïto { 0x43, "Old Linux" }, 105f41750abSHermès Bélusca-Maïto { 0x44, "GoBack" }, 106f41750abSHermès Bélusca-Maïto { 0x45, "Priam or Boot-US Boot Manager" }, 107f41750abSHermès Bélusca-Maïto { 0x4D, "QNX4.x" }, 108f41750abSHermès Bélusca-Maïto { 0x4E, "QNX4.x 2nd partition" }, 109f41750abSHermès Bélusca-Maïto { 0x4F, "QNX4.x 3rd partition" }, 110f41750abSHermès Bélusca-Maïto { 0x50, "OnTrack Disk Manager R/O" }, 111f41750abSHermès Bélusca-Maïto { 0x51, "OnTrack Disk Manager R/W or Novell" }, 112f41750abSHermès Bélusca-Maïto { 0x52, "CP/M" }, 113f41750abSHermès Bélusca-Maïto { 0x53, "OnTrack DM6 Aux3" }, 114f41750abSHermès Bélusca-Maïto { 0x54, "OnTrack DM6 Dynamic Drive Overlay" }, 115f41750abSHermès Bélusca-Maïto { 0x55, "EZ-Drive" }, 116f41750abSHermès Bélusca-Maïto { 0x56, "Golden Bow VFeature Partitioned Volume" }, 117f41750abSHermès Bélusca-Maïto { 0x5C, "Priam EDisk" }, 118f41750abSHermès Bélusca-Maïto { 0x61, "SpeedStor" }, 119f41750abSHermès Bélusca-Maïto { 0x62, "Pick" }, 120f41750abSHermès Bélusca-Maïto { 0x63, "GNU HURD or Unix System V (SCO, ISC Unix, UnixWare)" }, 121f41750abSHermès Bélusca-Maïto { 0x64, "Novell NetWare 286, 2.xx" }, 122f41750abSHermès Bélusca-Maïto { 0x65, "Novell NetWare 386, 3.xx or 4.xx" }, 123f41750abSHermès Bélusca-Maïto { 0x66, "Novell NetWare SMS Partition" }, 124f41750abSHermès Bélusca-Maïto { 0x67, "Novell" }, 125f41750abSHermès Bélusca-Maïto { 0x68, "Novell" }, 126f41750abSHermès Bélusca-Maïto { 0x69, "Novell NetWare 5+" }, 127f41750abSHermès Bélusca-Maïto { 0x70, "DiskSecure Multi-Boot" }, 128f41750abSHermès Bélusca-Maïto { 0x75, "IBM PC/IX" }, 129f41750abSHermès Bélusca-Maïto { 0x7E, "Veritas VxVM public" }, 130f41750abSHermès Bélusca-Maïto { 0x7F, "Veritas VxVM private" }, 131f41750abSHermès Bélusca-Maïto { 0x80, "Old MINIX" }, 132f41750abSHermès Bélusca-Maïto { 0x81, "Linux or MINIX" }, 133f41750abSHermès Bélusca-Maïto { 0x82, "Linux swap or Solaris" }, 134f41750abSHermès Bélusca-Maïto { 0x83, "Linux Native" }, 135f41750abSHermès Bélusca-Maïto { 0x84, "Hibernate" }, 136f41750abSHermès Bélusca-Maïto { 0x85, "Extended Linux" }, 137f41750abSHermès Bélusca-Maïto { 0x86, "FAT16 mirrored" }, 138f41750abSHermès Bélusca-Maïto { 0x87, "HPFS or NTFS mirrored" }, 139f41750abSHermès Bélusca-Maïto { 0x88, "Linux plaintext partition table" }, 140f41750abSHermès Bélusca-Maïto { 0x8B, "FAT32 mirrored" }, 141f41750abSHermès Bélusca-Maïto { 0x8C, "FAT32 (LBA) mirrored" }, 142f41750abSHermès Bélusca-Maïto { 0x8E, "Linux LVM" }, 143f41750abSHermès Bélusca-Maïto { 0x93, "Hidden Linux" }, 144f41750abSHermès Bélusca-Maïto { 0x94, "Amoeba BBT" }, 145f41750abSHermès Bélusca-Maïto { 0x96, "CDFS/ISO-9660" }, 146f41750abSHermès Bélusca-Maïto { 0x9F, "BSD/OS" }, 147f41750abSHermès Bélusca-Maïto { 0xA0, "Laptop Hibernate" }, 148f41750abSHermès Bélusca-Maïto { 0xA1, "Laptop Hibernate (NEC 6000H)" }, 149f41750abSHermès Bélusca-Maïto { 0xA5, "BSD, NetBSD, FreeBSD" }, 150f41750abSHermès Bélusca-Maïto { 0xA6, "OpenBSD" }, 151f41750abSHermès Bélusca-Maïto { 0xA7, "NeXTStep" }, 152f41750abSHermès Bélusca-Maïto { 0xA8, "Darwin UFS" }, // Also known as "OS-X" 153f41750abSHermès Bélusca-Maïto { 0xA9, "NetBSD" }, 154f41750abSHermès Bélusca-Maïto { 0xAB, "Darwin boot" }, 155f41750abSHermès Bélusca-Maïto { 0xAF, "Apple HFS" }, 156f41750abSHermès Bélusca-Maïto { 0xB6, "NT FAT16 corrupt mirror" }, 157f41750abSHermès Bélusca-Maïto { 0xB7, "BSDI BSD/386 FS" }, // Alternatively, "NT NTFS corrupt mirror" 158f41750abSHermès Bélusca-Maïto { 0xB8, "BSDI BSD/386 swap" }, 159f41750abSHermès Bélusca-Maïto { 0xBB, "Boot Wizard hidden" }, 160f41750abSHermès Bélusca-Maïto { 0xBC, "Paragon Backup capsule" }, 161f41750abSHermès Bélusca-Maïto { 0xBE, "Solaris 8 boot partition" }, 162f41750abSHermès Bélusca-Maïto { 0xBF, "Solaris 10 x86" }, 163f41750abSHermès Bélusca-Maïto { 0xC0, "NTFT" }, // Alternatively, "CTOS" or "REAL/32 or DR-DOS or Novell-DOS secure partition" 164f41750abSHermès Bélusca-Maïto { 0xC1, "DR-DOS FAT12" }, 165f41750abSHermès Bélusca-Maïto { 0xC2, "Hidden Linux" }, 166f41750abSHermès Bélusca-Maïto { 0xC3, "Hidden Linux swap" }, 167f41750abSHermès Bélusca-Maïto { 0xC4, "DR-DOS FAT16 (< 32 MB)" }, 168f41750abSHermès Bélusca-Maïto { 0xC5, "DR-DOS Extended" }, 169f41750abSHermès Bélusca-Maïto { 0xC6, "DR-DOS FAT16" }, 170f41750abSHermès Bélusca-Maïto { 0xC7, "HPFS mirrored" }, // Alternatively, "Syrinx boot" 171f41750abSHermès Bélusca-Maïto { 0xCB, "DR-DOS FAT32" }, 172f41750abSHermès Bélusca-Maïto { 0xCC, "DR-DOS FAT32 (LBA)" }, 173f41750abSHermès Bélusca-Maïto { 0xCE, "DR-DOS FAT16 (LBA)" }, 174f41750abSHermès Bélusca-Maïto { 0xD0, "MDOS" }, 175f41750abSHermès Bélusca-Maïto { 0xD1, "MDOS FAT12" }, 176f41750abSHermès Bélusca-Maïto { 0xD4, "MDOS FAT16 (< 32 MB)" }, 177f41750abSHermès Bélusca-Maïto { 0xD5, "MDOS Extended" }, 178f41750abSHermès Bélusca-Maïto { 0xD6, "MDOS FAT16" }, 179f41750abSHermès Bélusca-Maïto { 0xD8, "CP/M-86" }, 180f41750abSHermès Bélusca-Maïto { 0xDB, "Digital Research CP/M" }, 181f41750abSHermès Bélusca-Maïto { 0xDE, "Dell OEM" }, 182f41750abSHermès Bélusca-Maïto { 0xDF, "BootIt EMBRM (FAT16/32)" }, 183f41750abSHermès Bélusca-Maïto { 0xE1, "SpeedStor FAT12" }, 184f41750abSHermès Bélusca-Maïto { 0xE3, "SpeedStor (0xE3)" }, 185f41750abSHermès Bélusca-Maïto { 0xE4, "SpeedStor FAT16" }, 186f41750abSHermès Bélusca-Maïto { 0xE5, "Tandy MSDOS" }, 187f41750abSHermès Bélusca-Maïto { 0xE6, "SpeedStor (0xE6)" }, 188f41750abSHermès Bélusca-Maïto { 0xE8, "Linux Unified Key Setup partition" }, 189f41750abSHermès Bélusca-Maïto { 0xEA, "Rufus private partition" }, 190f41750abSHermès Bélusca-Maïto { 0xEB, "BeOS BFS" }, 191f41750abSHermès Bélusca-Maïto { 0xEC, "SkyOS SkyFS" }, 192f41750abSHermès Bélusca-Maïto { 0xEE, "EFI GPT protective" }, 193f41750abSHermès Bélusca-Maïto { 0xEF, "EFI System partition" }, 194f41750abSHermès Bélusca-Maïto { 0xF0, "Linux/PA-RISC boot loader" }, 195f41750abSHermès Bélusca-Maïto { 0xF1, "SpeedStor (0xF1)" }, 196f41750abSHermès Bélusca-Maïto { 0xF2, "DOS 3.3+ second" }, 197f41750abSHermès Bélusca-Maïto { 0xF4, "SpeedStor (0xF4)" }, 198f41750abSHermès Bélusca-Maïto { 0xF5, "SpeedStor (0xF5)" }, 199f41750abSHermès Bélusca-Maïto { 0xF6, "SpeedStor (0xF6)" }, 200f41750abSHermès Bélusca-Maïto { 0xFA, "Bochs" }, 201f41750abSHermès Bélusca-Maïto { 0xFB, "VMware FS" }, 202f41750abSHermès Bélusca-Maïto { 0xFC, "VMware swap" }, 203f41750abSHermès Bélusca-Maïto { 0xFD, "Linux RAID auto" }, 204f41750abSHermès Bélusca-Maïto { 0xFE, "NT hidden partition" }, 205f41750abSHermès Bélusca-Maïto { 0xFF, "XENIX Bad Block Table" }, 206f41750abSHermès Bélusca-Maïto }; 207f41750abSHermès Bélusca-Maïto 208f41750abSHermès Bélusca-Maïto 2096f19c83bSHermès Bélusca-Maïto /* FUNCTIONS ****************************************************************/ 2106f19c83bSHermès Bélusca-Maïto 2116f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE 2126f19c83bSHermès Bélusca-Maïto static 2136f19c83bSHermès Bélusca-Maïto VOID 2146f19c83bSHermès Bélusca-Maïto DumpPartitionTable( 2156f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry) 2166f19c83bSHermès Bélusca-Maïto { 2176f19c83bSHermès Bélusca-Maïto PPARTITION_INFORMATION PartitionInfo; 2186f19c83bSHermès Bélusca-Maïto ULONG i; 2196f19c83bSHermès Bélusca-Maïto 2206f19c83bSHermès Bélusca-Maïto DbgPrint("\n"); 2216f19c83bSHermès Bélusca-Maïto DbgPrint("Index Start Length Hidden Nr Type Boot RW\n"); 2226f19c83bSHermès Bélusca-Maïto DbgPrint("----- ------------ ------------ ---------- -- ---- ---- --\n"); 2236f19c83bSHermès Bélusca-Maïto 2246f19c83bSHermès Bélusca-Maïto for (i = 0; i < DiskEntry->LayoutBuffer->PartitionCount; i++) 2256f19c83bSHermès Bélusca-Maïto { 2266f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[i]; 2276f19c83bSHermès Bélusca-Maïto DbgPrint(" %3lu %12I64u %12I64u %10lu %2lu %2x %c %c\n", 2286f19c83bSHermès Bélusca-Maïto i, 2296f19c83bSHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector, 2306f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector, 2316f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors, 2326f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionNumber, 2336f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType, 2346f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator ? '*': ' ', 2356f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition ? 'Y': 'N'); 2366f19c83bSHermès Bélusca-Maïto } 2376f19c83bSHermès Bélusca-Maïto 2386f19c83bSHermès Bélusca-Maïto DbgPrint("\n"); 2396f19c83bSHermès Bélusca-Maïto } 2406f19c83bSHermès Bélusca-Maïto #endif 2416f19c83bSHermès Bélusca-Maïto 2426f19c83bSHermès Bélusca-Maïto 2436f19c83bSHermès Bélusca-Maïto ULONGLONG 2446f19c83bSHermès Bélusca-Maïto AlignDown( 2456f19c83bSHermès Bélusca-Maïto IN ULONGLONG Value, 2466f19c83bSHermès Bélusca-Maïto IN ULONG Alignment) 2476f19c83bSHermès Bélusca-Maïto { 2486f19c83bSHermès Bélusca-Maïto ULONGLONG Temp; 2496f19c83bSHermès Bélusca-Maïto 2506f19c83bSHermès Bélusca-Maïto Temp = Value / Alignment; 2516f19c83bSHermès Bélusca-Maïto 2526f19c83bSHermès Bélusca-Maïto return Temp * Alignment; 2536f19c83bSHermès Bélusca-Maïto } 2546f19c83bSHermès Bélusca-Maïto 2556f19c83bSHermès Bélusca-Maïto ULONGLONG 2566f19c83bSHermès Bélusca-Maïto AlignUp( 2576f19c83bSHermès Bélusca-Maïto IN ULONGLONG Value, 2586f19c83bSHermès Bélusca-Maïto IN ULONG Alignment) 2596f19c83bSHermès Bélusca-Maïto { 2606f19c83bSHermès Bélusca-Maïto ULONGLONG Temp, Result; 2616f19c83bSHermès Bélusca-Maïto 2626f19c83bSHermès Bélusca-Maïto Temp = Value / Alignment; 2636f19c83bSHermès Bélusca-Maïto 2646f19c83bSHermès Bélusca-Maïto Result = Temp * Alignment; 2656f19c83bSHermès Bélusca-Maïto if (Value % Alignment) 2666f19c83bSHermès Bélusca-Maïto Result += Alignment; 2676f19c83bSHermès Bélusca-Maïto 2686f19c83bSHermès Bélusca-Maïto return Result; 2696f19c83bSHermès Bélusca-Maïto } 2706f19c83bSHermès Bélusca-Maïto 2716f19c83bSHermès Bélusca-Maïto ULONGLONG 2726f19c83bSHermès Bélusca-Maïto RoundingDivide( 2736f19c83bSHermès Bélusca-Maïto IN ULONGLONG Dividend, 2746f19c83bSHermès Bélusca-Maïto IN ULONGLONG Divisor) 2756f19c83bSHermès Bélusca-Maïto { 2766f19c83bSHermès Bélusca-Maïto return (Dividend + Divisor / 2) / Divisor; 2776f19c83bSHermès Bélusca-Maïto } 2786f19c83bSHermès Bélusca-Maïto 2796f19c83bSHermès Bélusca-Maïto 2806f19c83bSHermès Bélusca-Maïto static 2816f19c83bSHermès Bélusca-Maïto VOID 2826f19c83bSHermès Bélusca-Maïto GetDriverName( 2836f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry) 2846f19c83bSHermès Bélusca-Maïto { 2856f19c83bSHermès Bélusca-Maïto RTL_QUERY_REGISTRY_TABLE QueryTable[2]; 2866f19c83bSHermès Bélusca-Maïto WCHAR KeyName[32]; 2876f19c83bSHermès Bélusca-Maïto NTSTATUS Status; 2886f19c83bSHermès Bélusca-Maïto 2896f19c83bSHermès Bélusca-Maïto RtlInitUnicodeString(&DiskEntry->DriverName, NULL); 2906f19c83bSHermès Bélusca-Maïto 2916f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(KeyName, ARRAYSIZE(KeyName), 2926f19c83bSHermès Bélusca-Maïto L"\\Scsi\\Scsi Port %hu", 2936f19c83bSHermès Bélusca-Maïto DiskEntry->Port); 2946f19c83bSHermès Bélusca-Maïto 2956f19c83bSHermès Bélusca-Maïto RtlZeroMemory(&QueryTable, sizeof(QueryTable)); 2966f19c83bSHermès Bélusca-Maïto 2976f19c83bSHermès Bélusca-Maïto QueryTable[0].Name = L"Driver"; 2986f19c83bSHermès Bélusca-Maïto QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; 2996f19c83bSHermès Bélusca-Maïto QueryTable[0].EntryContext = &DiskEntry->DriverName; 3006f19c83bSHermès Bélusca-Maïto 301f41750abSHermès Bélusca-Maïto /* This will allocate DiskEntry->DriverName if needed */ 3026f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP, 3036f19c83bSHermès Bélusca-Maïto KeyName, 3046f19c83bSHermès Bélusca-Maïto QueryTable, 3056f19c83bSHermès Bélusca-Maïto NULL, 3066f19c83bSHermès Bélusca-Maïto NULL); 3076f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 3086f19c83bSHermès Bélusca-Maïto { 3096f19c83bSHermès Bélusca-Maïto DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status); 3106f19c83bSHermès Bélusca-Maïto } 3116f19c83bSHermès Bélusca-Maïto } 3126f19c83bSHermès Bélusca-Maïto 3136f19c83bSHermès Bélusca-Maïto static 3146f19c83bSHermès Bélusca-Maïto VOID 3156f19c83bSHermès Bélusca-Maïto AssignDriveLetters( 3166f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 3176f19c83bSHermès Bélusca-Maïto { 3186f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 3196f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 3206f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry1; 3216f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry2; 322f41750abSHermès Bélusca-Maïto WCHAR Letter; 3236f19c83bSHermès Bélusca-Maïto 324f41750abSHermès Bélusca-Maïto Letter = L'C'; 3256f19c83bSHermès Bélusca-Maïto 3266f19c83bSHermès Bélusca-Maïto /* Assign drive letters to primary partitions */ 3276f19c83bSHermès Bélusca-Maïto Entry1 = List->DiskListHead.Flink; 3286f19c83bSHermès Bélusca-Maïto while (Entry1 != &List->DiskListHead) 3296f19c83bSHermès Bélusca-Maïto { 3306f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); 3316f19c83bSHermès Bélusca-Maïto 3326f19c83bSHermès Bélusca-Maïto Entry2 = DiskEntry->PrimaryPartListHead.Flink; 3336f19c83bSHermès Bélusca-Maïto while (Entry2 != &DiskEntry->PrimaryPartListHead) 3346f19c83bSHermès Bélusca-Maïto { 3356f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); 3366f19c83bSHermès Bélusca-Maïto 3376f19c83bSHermès Bélusca-Maïto PartEntry->DriveLetter = 0; 3386f19c83bSHermès Bélusca-Maïto 3396f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned && 3406f19c83bSHermès Bélusca-Maïto !IsContainerPartition(PartEntry->PartitionType)) 3416f19c83bSHermès Bélusca-Maïto { 3426f19c83bSHermès Bélusca-Maïto if (IsRecognizedPartition(PartEntry->PartitionType) || 3436f19c83bSHermès Bélusca-Maïto (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED && 3446f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart != 0LL)) 3456f19c83bSHermès Bélusca-Maïto { 346f41750abSHermès Bélusca-Maïto if (Letter <= L'Z') 3476f19c83bSHermès Bélusca-Maïto { 3486f19c83bSHermès Bélusca-Maïto PartEntry->DriveLetter = Letter; 3496f19c83bSHermès Bélusca-Maïto Letter++; 3506f19c83bSHermès Bélusca-Maïto } 3516f19c83bSHermès Bélusca-Maïto } 3526f19c83bSHermès Bélusca-Maïto } 3536f19c83bSHermès Bélusca-Maïto 3546f19c83bSHermès Bélusca-Maïto Entry2 = Entry2->Flink; 3556f19c83bSHermès Bélusca-Maïto } 3566f19c83bSHermès Bélusca-Maïto 3576f19c83bSHermès Bélusca-Maïto Entry1 = Entry1->Flink; 3586f19c83bSHermès Bélusca-Maïto } 3596f19c83bSHermès Bélusca-Maïto 3606f19c83bSHermès Bélusca-Maïto /* Assign drive letters to logical drives */ 3616f19c83bSHermès Bélusca-Maïto Entry1 = List->DiskListHead.Flink; 3626f19c83bSHermès Bélusca-Maïto while (Entry1 != &List->DiskListHead) 3636f19c83bSHermès Bélusca-Maïto { 3646f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); 3656f19c83bSHermès Bélusca-Maïto 3666f19c83bSHermès Bélusca-Maïto Entry2 = DiskEntry->LogicalPartListHead.Flink; 3676f19c83bSHermès Bélusca-Maïto while (Entry2 != &DiskEntry->LogicalPartListHead) 3686f19c83bSHermès Bélusca-Maïto { 3696f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); 3706f19c83bSHermès Bélusca-Maïto 3716f19c83bSHermès Bélusca-Maïto PartEntry->DriveLetter = 0; 3726f19c83bSHermès Bélusca-Maïto 3736f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned) 3746f19c83bSHermès Bélusca-Maïto { 3756f19c83bSHermès Bélusca-Maïto if (IsRecognizedPartition(PartEntry->PartitionType) || 3766f19c83bSHermès Bélusca-Maïto (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED && 3776f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart != 0LL)) 3786f19c83bSHermès Bélusca-Maïto { 379f41750abSHermès Bélusca-Maïto if (Letter <= L'Z') 3806f19c83bSHermès Bélusca-Maïto { 3816f19c83bSHermès Bélusca-Maïto PartEntry->DriveLetter = Letter; 3826f19c83bSHermès Bélusca-Maïto Letter++; 3836f19c83bSHermès Bélusca-Maïto } 3846f19c83bSHermès Bélusca-Maïto } 3856f19c83bSHermès Bélusca-Maïto } 3866f19c83bSHermès Bélusca-Maïto 3876f19c83bSHermès Bélusca-Maïto Entry2 = Entry2->Flink; 3886f19c83bSHermès Bélusca-Maïto } 3896f19c83bSHermès Bélusca-Maïto 3906f19c83bSHermès Bélusca-Maïto Entry1 = Entry1->Flink; 3916f19c83bSHermès Bélusca-Maïto } 3926f19c83bSHermès Bélusca-Maïto } 3936f19c83bSHermès Bélusca-Maïto 3946f19c83bSHermès Bélusca-Maïto static NTSTATUS 3956f19c83bSHermès Bélusca-Maïto NTAPI 3966f19c83bSHermès Bélusca-Maïto DiskIdentifierQueryRoutine( 3976f19c83bSHermès Bélusca-Maïto PWSTR ValueName, 3986f19c83bSHermès Bélusca-Maïto ULONG ValueType, 3996f19c83bSHermès Bélusca-Maïto PVOID ValueData, 4006f19c83bSHermès Bélusca-Maïto ULONG ValueLength, 4016f19c83bSHermès Bélusca-Maïto PVOID Context, 4026f19c83bSHermès Bélusca-Maïto PVOID EntryContext) 4036f19c83bSHermès Bélusca-Maïto { 4046f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; 4056f19c83bSHermès Bélusca-Maïto UNICODE_STRING NameU; 4066f19c83bSHermès Bélusca-Maïto 4076f19c83bSHermès Bélusca-Maïto if (ValueType == REG_SZ && 4086f19c83bSHermès Bélusca-Maïto ValueLength == 20 * sizeof(WCHAR)) 4096f19c83bSHermès Bélusca-Maïto { 4106f19c83bSHermès Bélusca-Maïto NameU.Buffer = (PWCHAR)ValueData; 4116f19c83bSHermès Bélusca-Maïto NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR); 4126f19c83bSHermès Bélusca-Maïto RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum); 4136f19c83bSHermès Bélusca-Maïto 4146f19c83bSHermès Bélusca-Maïto NameU.Buffer = (PWCHAR)ValueData + 9; 4156f19c83bSHermès Bélusca-Maïto RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature); 4166f19c83bSHermès Bélusca-Maïto 4176f19c83bSHermès Bélusca-Maïto return STATUS_SUCCESS; 4186f19c83bSHermès Bélusca-Maïto } 4196f19c83bSHermès Bélusca-Maïto 4206f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL; 4216f19c83bSHermès Bélusca-Maïto } 4226f19c83bSHermès Bélusca-Maïto 4236f19c83bSHermès Bélusca-Maïto static NTSTATUS 4246f19c83bSHermès Bélusca-Maïto NTAPI 4256f19c83bSHermès Bélusca-Maïto DiskConfigurationDataQueryRoutine( 4266f19c83bSHermès Bélusca-Maïto PWSTR ValueName, 4276f19c83bSHermès Bélusca-Maïto ULONG ValueType, 4286f19c83bSHermès Bélusca-Maïto PVOID ValueData, 4296f19c83bSHermès Bélusca-Maïto ULONG ValueLength, 4306f19c83bSHermès Bélusca-Maïto PVOID Context, 4316f19c83bSHermès Bélusca-Maïto PVOID EntryContext) 4326f19c83bSHermès Bélusca-Maïto { 4336f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; 4346f19c83bSHermès Bélusca-Maïto PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; 4356f19c83bSHermès Bélusca-Maïto PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; 4366f19c83bSHermès Bélusca-Maïto ULONG i; 4376f19c83bSHermès Bélusca-Maïto 4386f19c83bSHermès Bélusca-Maïto if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || 4396f19c83bSHermès Bélusca-Maïto ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) 4406f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL; 4416f19c83bSHermès Bélusca-Maïto 4426f19c83bSHermès Bélusca-Maïto FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; 4436f19c83bSHermès Bélusca-Maïto 4446f19c83bSHermès Bélusca-Maïto /* Hm. Version and Revision are not set on Microsoft Windows XP... */ 4456f19c83bSHermès Bélusca-Maïto #if 0 4466f19c83bSHermès Bélusca-Maïto if (FullResourceDescriptor->PartialResourceList.Version != 1 || 4476f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.Revision != 1) 4486f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL; 4496f19c83bSHermès Bélusca-Maïto #endif 4506f19c83bSHermès Bélusca-Maïto 4516f19c83bSHermès Bélusca-Maïto for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++) 4526f19c83bSHermès Bélusca-Maïto { 4536f19c83bSHermès Bélusca-Maïto if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific || 4546f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)) 4556f19c83bSHermès Bélusca-Maïto continue; 4566f19c83bSHermès Bélusca-Maïto 4576f19c83bSHermès Bélusca-Maïto DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1]; 4586f19c83bSHermès Bélusca-Maïto BiosDiskEntry->DiskGeometry = *DiskGeometry; 4596f19c83bSHermès Bélusca-Maïto 4606f19c83bSHermès Bélusca-Maïto return STATUS_SUCCESS; 4616f19c83bSHermès Bélusca-Maïto } 4626f19c83bSHermès Bélusca-Maïto 4636f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL; 4646f19c83bSHermès Bélusca-Maïto } 4656f19c83bSHermès Bélusca-Maïto 4666f19c83bSHermès Bélusca-Maïto static NTSTATUS 4676f19c83bSHermès Bélusca-Maïto NTAPI 4686f19c83bSHermès Bélusca-Maïto SystemConfigurationDataQueryRoutine( 4696f19c83bSHermès Bélusca-Maïto PWSTR ValueName, 4706f19c83bSHermès Bélusca-Maïto ULONG ValueType, 4716f19c83bSHermès Bélusca-Maïto PVOID ValueData, 4726f19c83bSHermès Bélusca-Maïto ULONG ValueLength, 4736f19c83bSHermès Bélusca-Maïto PVOID Context, 4746f19c83bSHermès Bélusca-Maïto PVOID EntryContext) 4756f19c83bSHermès Bélusca-Maïto { 4766f19c83bSHermès Bélusca-Maïto PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; 4776f19c83bSHermès Bélusca-Maïto PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context; 4786f19c83bSHermès Bélusca-Maïto ULONG i; 4796f19c83bSHermès Bélusca-Maïto 4806f19c83bSHermès Bélusca-Maïto if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || 4816f19c83bSHermès Bélusca-Maïto ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) 4826f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL; 4836f19c83bSHermès Bélusca-Maïto 4846f19c83bSHermès Bélusca-Maïto FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; 4856f19c83bSHermès Bélusca-Maïto 4866f19c83bSHermès Bélusca-Maïto /* Hm. Version and Revision are not set on Microsoft Windows XP... */ 4876f19c83bSHermès Bélusca-Maïto #if 0 4886f19c83bSHermès Bélusca-Maïto if (FullResourceDescriptor->PartialResourceList.Version != 1 || 4896f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.Revision != 1) 4906f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL; 4916f19c83bSHermès Bélusca-Maïto #endif 4926f19c83bSHermès Bélusca-Maïto 4936f19c83bSHermès Bélusca-Maïto for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++) 4946f19c83bSHermès Bélusca-Maïto { 4956f19c83bSHermès Bélusca-Maïto if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific || 4966f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0) 4976f19c83bSHermès Bélusca-Maïto continue; 4986f19c83bSHermès Bélusca-Maïto 4996f19c83bSHermès Bélusca-Maïto *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(ProcessHeap, 0, 5006f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize); 5016f19c83bSHermès Bélusca-Maïto if (*Int13Drives == NULL) 5026f19c83bSHermès Bélusca-Maïto return STATUS_NO_MEMORY; 5036f19c83bSHermès Bélusca-Maïto 5046f19c83bSHermès Bélusca-Maïto memcpy(*Int13Drives, 5056f19c83bSHermès Bélusca-Maïto &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1], 5066f19c83bSHermès Bélusca-Maïto FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize); 5076f19c83bSHermès Bélusca-Maïto return STATUS_SUCCESS; 5086f19c83bSHermès Bélusca-Maïto } 5096f19c83bSHermès Bélusca-Maïto 5106f19c83bSHermès Bélusca-Maïto return STATUS_UNSUCCESSFUL; 5116f19c83bSHermès Bélusca-Maïto } 5126f19c83bSHermès Bélusca-Maïto 5136f19c83bSHermès Bélusca-Maïto 5146f19c83bSHermès Bélusca-Maïto static VOID 5156f19c83bSHermès Bélusca-Maïto EnumerateBiosDiskEntries( 5166f19c83bSHermès Bélusca-Maïto IN PPARTLIST PartList) 5176f19c83bSHermès Bélusca-Maïto { 5186f19c83bSHermès Bélusca-Maïto RTL_QUERY_REGISTRY_TABLE QueryTable[3]; 5196f19c83bSHermès Bélusca-Maïto WCHAR Name[120]; 5206f19c83bSHermès Bélusca-Maïto ULONG AdapterCount; 5216f19c83bSHermès Bélusca-Maïto ULONG DiskCount; 5226f19c83bSHermès Bélusca-Maïto NTSTATUS Status; 5236f19c83bSHermès Bélusca-Maïto PCM_INT13_DRIVE_PARAMETER Int13Drives; 5246f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry; 5256f19c83bSHermès Bélusca-Maïto 526f41750abSHermès Bélusca-Maïto #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter" 527f41750abSHermès Bélusca-Maïto 5286f19c83bSHermès Bélusca-Maïto memset(QueryTable, 0, sizeof(QueryTable)); 5296f19c83bSHermès Bélusca-Maïto 5306f19c83bSHermès Bélusca-Maïto QueryTable[1].Name = L"Configuration Data"; 5316f19c83bSHermès Bélusca-Maïto QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine; 5326f19c83bSHermès Bélusca-Maïto Int13Drives = NULL; 5336f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 5346f19c83bSHermès Bélusca-Maïto L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System", 5356f19c83bSHermès Bélusca-Maïto &QueryTable[1], 5366f19c83bSHermès Bélusca-Maïto (PVOID)&Int13Drives, 5376f19c83bSHermès Bélusca-Maïto NULL); 5386f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 5396f19c83bSHermès Bélusca-Maïto { 5406f19c83bSHermès Bélusca-Maïto DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status); 5416f19c83bSHermès Bélusca-Maïto return; 5426f19c83bSHermès Bélusca-Maïto } 5436f19c83bSHermès Bélusca-Maïto 5446f19c83bSHermès Bélusca-Maïto AdapterCount = 0; 5456f19c83bSHermès Bélusca-Maïto while (TRUE) 5466f19c83bSHermès Bélusca-Maïto { 5476f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name), 5486f19c83bSHermès Bélusca-Maïto L"%s\\%lu", 5496f19c83bSHermès Bélusca-Maïto ROOT_NAME, AdapterCount); 5506f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 5516f19c83bSHermès Bélusca-Maïto Name, 5526f19c83bSHermès Bélusca-Maïto &QueryTable[2], 5536f19c83bSHermès Bélusca-Maïto NULL, 5546f19c83bSHermès Bélusca-Maïto NULL); 5556f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 5566f19c83bSHermès Bélusca-Maïto { 5576f19c83bSHermès Bélusca-Maïto break; 5586f19c83bSHermès Bélusca-Maïto } 5596f19c83bSHermès Bélusca-Maïto 5606f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name), 5616f19c83bSHermès Bélusca-Maïto L"%s\\%lu\\DiskController", 5626f19c83bSHermès Bélusca-Maïto ROOT_NAME, AdapterCount); 5636f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 5646f19c83bSHermès Bélusca-Maïto Name, 5656f19c83bSHermès Bélusca-Maïto &QueryTable[2], 5666f19c83bSHermès Bélusca-Maïto NULL, 5676f19c83bSHermès Bélusca-Maïto NULL); 5686f19c83bSHermès Bélusca-Maïto if (NT_SUCCESS(Status)) 5696f19c83bSHermès Bélusca-Maïto { 5706f19c83bSHermès Bélusca-Maïto while (TRUE) 5716f19c83bSHermès Bélusca-Maïto { 5726f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name), 5736f19c83bSHermès Bélusca-Maïto L"%s\\%lu\\DiskController\\0", 5746f19c83bSHermès Bélusca-Maïto ROOT_NAME, AdapterCount); 5756f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 5766f19c83bSHermès Bélusca-Maïto Name, 5776f19c83bSHermès Bélusca-Maïto &QueryTable[2], 5786f19c83bSHermès Bélusca-Maïto NULL, 5796f19c83bSHermès Bélusca-Maïto NULL); 5806f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 5816f19c83bSHermès Bélusca-Maïto { 5826f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Int13Drives); 5836f19c83bSHermès Bélusca-Maïto return; 5846f19c83bSHermès Bélusca-Maïto } 5856f19c83bSHermès Bélusca-Maïto 5866f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name), 5876f19c83bSHermès Bélusca-Maïto L"%s\\%lu\\DiskController\\0\\DiskPeripheral", 5886f19c83bSHermès Bélusca-Maïto ROOT_NAME, AdapterCount); 5896f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 5906f19c83bSHermès Bélusca-Maïto Name, 5916f19c83bSHermès Bélusca-Maïto &QueryTable[2], 5926f19c83bSHermès Bélusca-Maïto NULL, 5936f19c83bSHermès Bélusca-Maïto NULL); 5946f19c83bSHermès Bélusca-Maïto if (NT_SUCCESS(Status)) 5956f19c83bSHermès Bélusca-Maïto { 5966f19c83bSHermès Bélusca-Maïto QueryTable[0].Name = L"Identifier"; 5976f19c83bSHermès Bélusca-Maïto QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine; 5986f19c83bSHermès Bélusca-Maïto QueryTable[1].Name = L"Configuration Data"; 5996f19c83bSHermès Bélusca-Maïto QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine; 6006f19c83bSHermès Bélusca-Maïto 6016f19c83bSHermès Bélusca-Maïto DiskCount = 0; 6026f19c83bSHermès Bélusca-Maïto while (TRUE) 6036f19c83bSHermès Bélusca-Maïto { 6046f19c83bSHermès Bélusca-Maïto BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY)); 6056f19c83bSHermès Bélusca-Maïto if (BiosDiskEntry == NULL) 6066f19c83bSHermès Bélusca-Maïto { 6076f19c83bSHermès Bélusca-Maïto break; 6086f19c83bSHermès Bélusca-Maïto } 6096f19c83bSHermès Bélusca-Maïto 6106f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Name, ARRAYSIZE(Name), 6116f19c83bSHermès Bélusca-Maïto L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", 6126f19c83bSHermès Bélusca-Maïto ROOT_NAME, AdapterCount, DiskCount); 6136f19c83bSHermès Bélusca-Maïto Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 6146f19c83bSHermès Bélusca-Maïto Name, 6156f19c83bSHermès Bélusca-Maïto QueryTable, 6166f19c83bSHermès Bélusca-Maïto (PVOID)BiosDiskEntry, 6176f19c83bSHermès Bélusca-Maïto NULL); 6186f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 6196f19c83bSHermès Bélusca-Maïto { 6206f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry); 6216f19c83bSHermès Bélusca-Maïto break; 6226f19c83bSHermès Bélusca-Maïto } 6236f19c83bSHermès Bélusca-Maïto 6246f19c83bSHermès Bélusca-Maïto BiosDiskEntry->DiskNumber = DiskCount; 6256f19c83bSHermès Bélusca-Maïto BiosDiskEntry->Recognized = FALSE; 6266f19c83bSHermès Bélusca-Maïto 6276f19c83bSHermès Bélusca-Maïto if (DiskCount < Int13Drives[0].NumberDrives) 6286f19c83bSHermès Bélusca-Maïto { 6296f19c83bSHermès Bélusca-Maïto BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount]; 6306f19c83bSHermès Bélusca-Maïto } 6316f19c83bSHermès Bélusca-Maïto else 6326f19c83bSHermès Bélusca-Maïto { 6336f19c83bSHermès Bélusca-Maïto DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount); 6346f19c83bSHermès Bélusca-Maïto } 6356f19c83bSHermès Bélusca-Maïto 6366f19c83bSHermès Bélusca-Maïto InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry); 6376f19c83bSHermès Bélusca-Maïto 6386f19c83bSHermès Bélusca-Maïto DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber); 6396f19c83bSHermès Bélusca-Maïto DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature); 6406f19c83bSHermès Bélusca-Maïto DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum); 6416f19c83bSHermès Bélusca-Maïto DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector); 6426f19c83bSHermès Bélusca-Maïto DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders); 6436f19c83bSHermès Bélusca-Maïto DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads); 6446f19c83bSHermès Bélusca-Maïto DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect); 6456f19c83bSHermès Bélusca-Maïto DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders); 6466f19c83bSHermès Bélusca-Maïto DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack); 6476f19c83bSHermès Bélusca-Maïto DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads); 6486f19c83bSHermès Bélusca-Maïto DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives); 6496f19c83bSHermès Bélusca-Maïto 6506f19c83bSHermès Bélusca-Maïto DiskCount++; 6516f19c83bSHermès Bélusca-Maïto } 6526f19c83bSHermès Bélusca-Maïto } 6536f19c83bSHermès Bélusca-Maïto 6546f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Int13Drives); 6556f19c83bSHermès Bélusca-Maïto return; 6566f19c83bSHermès Bélusca-Maïto } 6576f19c83bSHermès Bélusca-Maïto } 6586f19c83bSHermès Bélusca-Maïto 6596f19c83bSHermès Bélusca-Maïto AdapterCount++; 6606f19c83bSHermès Bélusca-Maïto } 6616f19c83bSHermès Bélusca-Maïto 6626f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Int13Drives); 663f41750abSHermès Bélusca-Maïto 664f41750abSHermès Bélusca-Maïto #undef ROOT_NAME 6656f19c83bSHermès Bélusca-Maïto } 6666f19c83bSHermès Bélusca-Maïto 6676f19c83bSHermès Bélusca-Maïto static 6686f19c83bSHermès Bélusca-Maïto VOID 6696f19c83bSHermès Bélusca-Maïto AddPartitionToDisk( 6706f19c83bSHermès Bélusca-Maïto IN ULONG DiskNumber, 6716f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry, 6726f19c83bSHermès Bélusca-Maïto IN ULONG PartitionIndex, 6736f19c83bSHermès Bélusca-Maïto IN BOOLEAN LogicalPartition) 6746f19c83bSHermès Bélusca-Maïto { 675f41750abSHermès Bélusca-Maïto NTSTATUS Status; 6766f19c83bSHermès Bélusca-Maïto PPARTITION_INFORMATION PartitionInfo; 6776f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 678f41750abSHermès Bélusca-Maïto HANDLE FileHandle; 679f41750abSHermès Bélusca-Maïto OBJECT_ATTRIBUTES ObjectAttributes; 680f41750abSHermès Bélusca-Maïto IO_STATUS_BLOCK IoStatusBlock; 681f41750abSHermès Bélusca-Maïto WCHAR Buffer[MAX_PATH]; 682f41750abSHermès Bélusca-Maïto UNICODE_STRING Name; 683f41750abSHermès Bélusca-Maïto UCHAR LabelBuffer[sizeof(FILE_FS_VOLUME_INFORMATION) + 256 * sizeof(WCHAR)]; 684f41750abSHermès Bélusca-Maïto PFILE_FS_VOLUME_INFORMATION LabelInfo = (PFILE_FS_VOLUME_INFORMATION)LabelBuffer; 6856f19c83bSHermès Bélusca-Maïto 6866f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex]; 6876f19c83bSHermès Bélusca-Maïto 6886f19c83bSHermès Bélusca-Maïto if (PartitionInfo->PartitionType == PARTITION_ENTRY_UNUSED || 6896f19c83bSHermès Bélusca-Maïto ((LogicalPartition != FALSE) && IsContainerPartition(PartitionInfo->PartitionType))) 6906f19c83bSHermès Bélusca-Maïto { 6916f19c83bSHermès Bélusca-Maïto return; 6926f19c83bSHermès Bélusca-Maïto } 6936f19c83bSHermès Bélusca-Maïto 6946f19c83bSHermès Bélusca-Maïto PartEntry = RtlAllocateHeap(ProcessHeap, 6956f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 6966f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 6976f19c83bSHermès Bélusca-Maïto if (PartEntry == NULL) 6986f19c83bSHermès Bélusca-Maïto return; 6996f19c83bSHermès Bélusca-Maïto 7006f19c83bSHermès Bélusca-Maïto PartEntry->DiskEntry = DiskEntry; 7016f19c83bSHermès Bélusca-Maïto 7026f19c83bSHermès Bélusca-Maïto PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector; 7036f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector; 7046f19c83bSHermès Bélusca-Maïto 7056f19c83bSHermès Bélusca-Maïto PartEntry->BootIndicator = PartitionInfo->BootIndicator; 7066f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType = PartitionInfo->PartitionType; 7076f19c83bSHermès Bélusca-Maïto PartEntry->HiddenSectors = PartitionInfo->HiddenSectors; 7086f19c83bSHermès Bélusca-Maïto 7096f19c83bSHermès Bélusca-Maïto PartEntry->LogicalPartition = LogicalPartition; 7106f19c83bSHermès Bélusca-Maïto PartEntry->IsPartitioned = TRUE; 7116f19c83bSHermès Bélusca-Maïto PartEntry->PartitionNumber = PartitionInfo->PartitionNumber; 7126f19c83bSHermès Bélusca-Maïto PartEntry->PartitionIndex = PartitionIndex; 7136f19c83bSHermès Bélusca-Maïto 7146f19c83bSHermès Bélusca-Maïto if (IsContainerPartition(PartEntry->PartitionType)) 7156f19c83bSHermès Bélusca-Maïto { 7166f19c83bSHermès Bélusca-Maïto PartEntry->FormatState = Unformatted; 7176f19c83bSHermès Bélusca-Maïto PartEntry->FileSystem = NULL; 7186f19c83bSHermès Bélusca-Maïto 7196f19c83bSHermès Bélusca-Maïto if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL) 7206f19c83bSHermès Bélusca-Maïto DiskEntry->ExtendedPartition = PartEntry; 7216f19c83bSHermès Bélusca-Maïto } 7226f19c83bSHermès Bélusca-Maïto else if (IsRecognizedPartition(PartEntry->PartitionType)) 7236f19c83bSHermès Bélusca-Maïto { 7246f19c83bSHermès Bélusca-Maïto PartEntry->FileSystem = GetFileSystem(PartEntry); 7256f19c83bSHermès Bélusca-Maïto if (PartEntry->FileSystem) 7266f19c83bSHermès Bélusca-Maïto PartEntry->FormatState = Preformatted; 7276f19c83bSHermès Bélusca-Maïto else 7286f19c83bSHermès Bélusca-Maïto PartEntry->FormatState = Unformatted; 7296f19c83bSHermès Bélusca-Maïto // PartEntry->FormatState = UnknownFormat; 7306f19c83bSHermès Bélusca-Maïto } 7316f19c83bSHermès Bélusca-Maïto else 7326f19c83bSHermès Bélusca-Maïto { 7336f19c83bSHermès Bélusca-Maïto /* Unknown partition, hence unknown partition format (may or may not be actually formatted) */ 7346f19c83bSHermès Bélusca-Maïto PartEntry->FormatState = UnknownFormat; 7356f19c83bSHermès Bélusca-Maïto } 7366f19c83bSHermès Bélusca-Maïto 737f41750abSHermès Bélusca-Maïto /* Initialize the partition volume label */ 738f41750abSHermès Bélusca-Maïto RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel)); 739f41750abSHermès Bélusca-Maïto 740f41750abSHermès Bélusca-Maïto /* Open the volume, ignore any errors */ 741f41750abSHermès Bélusca-Maïto RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer), 742f41750abSHermès Bélusca-Maïto L"\\Device\\Harddisk%lu\\Partition%lu", 743f41750abSHermès Bélusca-Maïto DiskEntry->DiskNumber, PartEntry->PartitionNumber); 744f41750abSHermès Bélusca-Maïto RtlInitUnicodeString(&Name, Buffer); 745f41750abSHermès Bélusca-Maïto 746f41750abSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes, 747f41750abSHermès Bélusca-Maïto &Name, 748f41750abSHermès Bélusca-Maïto OBJ_CASE_INSENSITIVE, 749f41750abSHermès Bélusca-Maïto NULL, 750f41750abSHermès Bélusca-Maïto NULL); 751f41750abSHermès Bélusca-Maïto 752f41750abSHermès Bélusca-Maïto Status = NtOpenFile(&FileHandle, 753f41750abSHermès Bélusca-Maïto FILE_READ_DATA | SYNCHRONIZE, 754f41750abSHermès Bélusca-Maïto &ObjectAttributes, 755f41750abSHermès Bélusca-Maïto &IoStatusBlock, 756f41750abSHermès Bélusca-Maïto FILE_SHARE_READ | FILE_SHARE_WRITE, 757f41750abSHermès Bélusca-Maïto FILE_SYNCHRONOUS_IO_NONALERT); 758f41750abSHermès Bélusca-Maïto if (NT_SUCCESS(Status)) 759f41750abSHermès Bélusca-Maïto { 760f41750abSHermès Bélusca-Maïto /* Retrieve the partition volume label */ 761f41750abSHermès Bélusca-Maïto Status = NtQueryVolumeInformationFile(FileHandle, 762f41750abSHermès Bélusca-Maïto &IoStatusBlock, 763f41750abSHermès Bélusca-Maïto &LabelBuffer, 764f41750abSHermès Bélusca-Maïto sizeof(LabelBuffer), 765f41750abSHermès Bélusca-Maïto FileFsVolumeInformation); 766f41750abSHermès Bélusca-Maïto /* Close the handle */ 767f41750abSHermès Bélusca-Maïto NtClose(FileHandle); 768f41750abSHermès Bélusca-Maïto 769f41750abSHermès Bélusca-Maïto /* Check for success */ 770f41750abSHermès Bélusca-Maïto if (NT_SUCCESS(Status)) 771f41750abSHermès Bélusca-Maïto { 772f41750abSHermès Bélusca-Maïto /* Copy the (possibly truncated) volume label and NULL-terminate it */ 773f41750abSHermès Bélusca-Maïto RtlStringCbCopyNW(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel), 774f41750abSHermès Bélusca-Maïto LabelInfo->VolumeLabel, LabelInfo->VolumeLabelLength); 775f41750abSHermès Bélusca-Maïto } 776f41750abSHermès Bélusca-Maïto else 777f41750abSHermès Bélusca-Maïto { 778f41750abSHermès Bélusca-Maïto DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status); 779f41750abSHermès Bélusca-Maïto } 780f41750abSHermès Bélusca-Maïto } 781f41750abSHermès Bélusca-Maïto else 782f41750abSHermès Bélusca-Maïto { 783f41750abSHermès Bélusca-Maïto DPRINT1("NtOpenFile() failed, Status 0x%08lx\n", Status); 784f41750abSHermès Bélusca-Maïto } 785f41750abSHermès Bélusca-Maïto 7866f19c83bSHermès Bélusca-Maïto if (LogicalPartition) 7876f19c83bSHermès Bélusca-Maïto InsertTailList(&DiskEntry->LogicalPartListHead, 7886f19c83bSHermès Bélusca-Maïto &PartEntry->ListEntry); 7896f19c83bSHermès Bélusca-Maïto else 7906f19c83bSHermès Bélusca-Maïto InsertTailList(&DiskEntry->PrimaryPartListHead, 7916f19c83bSHermès Bélusca-Maïto &PartEntry->ListEntry); 7926f19c83bSHermès Bélusca-Maïto } 7936f19c83bSHermès Bélusca-Maïto 7946f19c83bSHermès Bélusca-Maïto static 7956f19c83bSHermès Bélusca-Maïto VOID 7966f19c83bSHermès Bélusca-Maïto ScanForUnpartitionedDiskSpace( 7976f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry) 7986f19c83bSHermès Bélusca-Maïto { 7996f19c83bSHermès Bélusca-Maïto ULONGLONG LastStartSector; 8006f19c83bSHermès Bélusca-Maïto ULONGLONG LastSectorCount; 8016f19c83bSHermès Bélusca-Maïto ULONGLONG LastUnusedSectorCount; 8026f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 8036f19c83bSHermès Bélusca-Maïto PPARTENTRY NewPartEntry; 8046f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 8056f19c83bSHermès Bélusca-Maïto 8066f19c83bSHermès Bélusca-Maïto DPRINT("ScanForUnpartitionedDiskSpace()\n"); 8076f19c83bSHermès Bélusca-Maïto 8086f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&DiskEntry->PrimaryPartListHead)) 8096f19c83bSHermès Bélusca-Maïto { 8106f19c83bSHermès Bélusca-Maïto DPRINT1("No primary partition!\n"); 8116f19c83bSHermès Bélusca-Maïto 8126f19c83bSHermès Bélusca-Maïto /* Create a partition entry that represents the empty disk */ 8136f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 8146f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 8156f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 8166f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 8176f19c83bSHermès Bélusca-Maïto return; 8186f19c83bSHermès Bélusca-Maïto 8196f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 8206f19c83bSHermès Bélusca-Maïto 8216f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = FALSE; 822*26408b02SPierre Schweitzer if (DiskEntry->SectorAlignment < 2048) 823*26408b02SPierre Schweitzer NewPartEntry->StartSector.QuadPart = 2048ULL; 824*26408b02SPierre Schweitzer else 8256f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment; 8266f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) - 8276f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart; 8286f19c83bSHermès Bélusca-Maïto 8296f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 8306f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 8316f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 8326f19c83bSHermès Bélusca-Maïto 8336f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Unformatted; 8346f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 8356f19c83bSHermès Bélusca-Maïto 8366f19c83bSHermès Bélusca-Maïto InsertTailList(&DiskEntry->PrimaryPartListHead, 8376f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 8386f19c83bSHermès Bélusca-Maïto 8396f19c83bSHermès Bélusca-Maïto return; 8406f19c83bSHermès Bélusca-Maïto } 8416f19c83bSHermès Bélusca-Maïto 8426f19c83bSHermès Bélusca-Maïto /* Start partition at head 1, cylinder 0 */ 843*26408b02SPierre Schweitzer if (DiskEntry->SectorAlignment < 2048) 844*26408b02SPierre Schweitzer LastStartSector = 2048ULL; 845*26408b02SPierre Schweitzer else 8466f19c83bSHermès Bélusca-Maïto LastStartSector = DiskEntry->SectorAlignment; 8476f19c83bSHermès Bélusca-Maïto LastSectorCount = 0ULL; 8486f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount = 0ULL; 8496f19c83bSHermès Bélusca-Maïto 8506f19c83bSHermès Bélusca-Maïto Entry = DiskEntry->PrimaryPartListHead.Flink; 8516f19c83bSHermès Bélusca-Maïto while (Entry != &DiskEntry->PrimaryPartListHead) 8526f19c83bSHermès Bélusca-Maïto { 8536f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 8546f19c83bSHermès Bélusca-Maïto 8556f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || 8566f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart != 0ULL) 8576f19c83bSHermès Bélusca-Maïto { 8586f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount = 8596f19c83bSHermès Bélusca-Maïto PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount); 8606f19c83bSHermès Bélusca-Maïto 8616f19c83bSHermès Bélusca-Maïto if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) && 8626f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) 8636f19c83bSHermès Bélusca-Maïto { 8646f19c83bSHermès Bélusca-Maïto DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount); 8656f19c83bSHermès Bélusca-Maïto 8666f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 8676f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 8686f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 8696f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 8706f19c83bSHermès Bélusca-Maïto return; 8716f19c83bSHermès Bélusca-Maïto 8726f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 8736f19c83bSHermès Bélusca-Maïto 8746f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = FALSE; 8756f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; 8766f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - 8776f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart; 8786f19c83bSHermès Bélusca-Maïto 8796f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 8806f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 8816f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 8826f19c83bSHermès Bélusca-Maïto 8836f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Unformatted; 8846f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 8856f19c83bSHermès Bélusca-Maïto 8866f19c83bSHermès Bélusca-Maïto /* Insert the table into the list */ 8876f19c83bSHermès Bélusca-Maïto InsertTailList(&PartEntry->ListEntry, 8886f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 8896f19c83bSHermès Bélusca-Maïto } 8906f19c83bSHermès Bélusca-Maïto 8916f19c83bSHermès Bélusca-Maïto LastStartSector = PartEntry->StartSector.QuadPart; 8926f19c83bSHermès Bélusca-Maïto LastSectorCount = PartEntry->SectorCount.QuadPart; 8936f19c83bSHermès Bélusca-Maïto } 8946f19c83bSHermès Bélusca-Maïto 8956f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 8966f19c83bSHermès Bélusca-Maïto } 8976f19c83bSHermès Bélusca-Maïto 8986f19c83bSHermès Bélusca-Maïto /* Check for trailing unpartitioned disk space */ 8996f19c83bSHermès Bélusca-Maïto if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart) 9006f19c83bSHermès Bélusca-Maïto { 9016f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment); 9026f19c83bSHermès Bélusca-Maïto 9036f19c83bSHermès Bélusca-Maïto if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) 9046f19c83bSHermès Bélusca-Maïto { 9056f19c83bSHermès Bélusca-Maïto DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount); 9066f19c83bSHermès Bélusca-Maïto 9076f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 9086f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 9096f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 9106f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 9116f19c83bSHermès Bélusca-Maïto return; 9126f19c83bSHermès Bélusca-Maïto 9136f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 9146f19c83bSHermès Bélusca-Maïto 9156f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = FALSE; 9166f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; 9176f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - 9186f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart; 9196f19c83bSHermès Bélusca-Maïto 9206f19c83bSHermès Bélusca-Maïto DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 9216f19c83bSHermès Bélusca-Maïto DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 9226f19c83bSHermès Bélusca-Maïto DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 9236f19c83bSHermès Bélusca-Maïto 9246f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Unformatted; 9256f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 9266f19c83bSHermès Bélusca-Maïto 9276f19c83bSHermès Bélusca-Maïto /* Append the table to the list */ 9286f19c83bSHermès Bélusca-Maïto InsertTailList(&DiskEntry->PrimaryPartListHead, 9296f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 9306f19c83bSHermès Bélusca-Maïto } 9316f19c83bSHermès Bélusca-Maïto } 9326f19c83bSHermès Bélusca-Maïto 9336f19c83bSHermès Bélusca-Maïto if (DiskEntry->ExtendedPartition != NULL) 9346f19c83bSHermès Bélusca-Maïto { 9356f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&DiskEntry->LogicalPartListHead)) 9366f19c83bSHermès Bélusca-Maïto { 9376f19c83bSHermès Bélusca-Maïto DPRINT1("No logical partition!\n"); 9386f19c83bSHermès Bélusca-Maïto 9396f19c83bSHermès Bélusca-Maïto /* Create a partition entry that represents the empty extended partition */ 9406f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 9416f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 9426f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 9436f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 9446f19c83bSHermès Bélusca-Maïto return; 9456f19c83bSHermès Bélusca-Maïto 9466f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 9476f19c83bSHermès Bélusca-Maïto NewPartEntry->LogicalPartition = TRUE; 9486f19c83bSHermès Bélusca-Maïto 9496f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = FALSE; 9506f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment; 9516f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment; 9526f19c83bSHermès Bélusca-Maïto 9536f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 9546f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 9556f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 9566f19c83bSHermès Bélusca-Maïto 9576f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Unformatted; 9586f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 9596f19c83bSHermès Bélusca-Maïto 9606f19c83bSHermès Bélusca-Maïto InsertTailList(&DiskEntry->LogicalPartListHead, 9616f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 9626f19c83bSHermès Bélusca-Maïto 9636f19c83bSHermès Bélusca-Maïto return; 9646f19c83bSHermès Bélusca-Maïto } 9656f19c83bSHermès Bélusca-Maïto 9666f19c83bSHermès Bélusca-Maïto /* Start partition at head 1, cylinder 0 */ 9676f19c83bSHermès Bélusca-Maïto LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment; 9686f19c83bSHermès Bélusca-Maïto LastSectorCount = 0ULL; 9696f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount = 0ULL; 9706f19c83bSHermès Bélusca-Maïto 9716f19c83bSHermès Bélusca-Maïto Entry = DiskEntry->LogicalPartListHead.Flink; 9726f19c83bSHermès Bélusca-Maïto while (Entry != &DiskEntry->LogicalPartListHead) 9736f19c83bSHermès Bélusca-Maïto { 9746f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 9756f19c83bSHermès Bélusca-Maïto 9766f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || 9776f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart != 0ULL) 9786f19c83bSHermès Bélusca-Maïto { 9796f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount = 9806f19c83bSHermès Bélusca-Maïto PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount); 9816f19c83bSHermès Bélusca-Maïto 9826f19c83bSHermès Bélusca-Maïto if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) && 9836f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) 9846f19c83bSHermès Bélusca-Maïto { 9856f19c83bSHermès Bélusca-Maïto DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount); 9866f19c83bSHermès Bélusca-Maïto 9876f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 9886f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 9896f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 9906f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 9916f19c83bSHermès Bélusca-Maïto return; 9926f19c83bSHermès Bélusca-Maïto 9936f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 9946f19c83bSHermès Bélusca-Maïto NewPartEntry->LogicalPartition = TRUE; 9956f19c83bSHermès Bélusca-Maïto 9966f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = FALSE; 9976f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; 9986f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - 9996f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart; 10006f19c83bSHermès Bélusca-Maïto 10016f19c83bSHermès Bélusca-Maïto DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 10026f19c83bSHermès Bélusca-Maïto DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 10036f19c83bSHermès Bélusca-Maïto DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 10046f19c83bSHermès Bélusca-Maïto 10056f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Unformatted; 10066f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 10076f19c83bSHermès Bélusca-Maïto 10086f19c83bSHermès Bélusca-Maïto /* Insert the table into the list */ 10096f19c83bSHermès Bélusca-Maïto InsertTailList(&PartEntry->ListEntry, 10106f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 10116f19c83bSHermès Bélusca-Maïto } 10126f19c83bSHermès Bélusca-Maïto 10136f19c83bSHermès Bélusca-Maïto LastStartSector = PartEntry->StartSector.QuadPart; 10146f19c83bSHermès Bélusca-Maïto LastSectorCount = PartEntry->SectorCount.QuadPart; 10156f19c83bSHermès Bélusca-Maïto } 10166f19c83bSHermès Bélusca-Maïto 10176f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 10186f19c83bSHermès Bélusca-Maïto } 10196f19c83bSHermès Bélusca-Maïto 10206f19c83bSHermès Bélusca-Maïto /* Check for trailing unpartitioned disk space */ 10216f19c83bSHermès Bélusca-Maïto if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart) 10226f19c83bSHermès Bélusca-Maïto { 10236f19c83bSHermès Bélusca-Maïto LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment); 10246f19c83bSHermès Bélusca-Maïto 10256f19c83bSHermès Bélusca-Maïto if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment) 10266f19c83bSHermès Bélusca-Maïto { 10276f19c83bSHermès Bélusca-Maïto DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount); 10286f19c83bSHermès Bélusca-Maïto 10296f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 10306f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 10316f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 10326f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 10336f19c83bSHermès Bélusca-Maïto return; 10346f19c83bSHermès Bélusca-Maïto 10356f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 10366f19c83bSHermès Bélusca-Maïto NewPartEntry->LogicalPartition = TRUE; 10376f19c83bSHermès Bélusca-Maïto 10386f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = FALSE; 10396f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount; 10406f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) - 10416f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart; 10426f19c83bSHermès Bélusca-Maïto 10436f19c83bSHermès Bélusca-Maïto DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 10446f19c83bSHermès Bélusca-Maïto DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 10456f19c83bSHermès Bélusca-Maïto DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 10466f19c83bSHermès Bélusca-Maïto 10476f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Unformatted; 10486f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 10496f19c83bSHermès Bélusca-Maïto 10506f19c83bSHermès Bélusca-Maïto /* Append the table to the list */ 10516f19c83bSHermès Bélusca-Maïto InsertTailList(&DiskEntry->LogicalPartListHead, 10526f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 10536f19c83bSHermès Bélusca-Maïto } 10546f19c83bSHermès Bélusca-Maïto } 10556f19c83bSHermès Bélusca-Maïto } 10566f19c83bSHermès Bélusca-Maïto 10576f19c83bSHermès Bélusca-Maïto DPRINT("ScanForUnpartitionedDiskSpace() done\n"); 10586f19c83bSHermès Bélusca-Maïto } 10596f19c83bSHermès Bélusca-Maïto 10606f19c83bSHermès Bélusca-Maïto static 10616f19c83bSHermès Bélusca-Maïto VOID 10626f19c83bSHermès Bélusca-Maïto SetDiskSignature( 10636f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 10646f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry) 10656f19c83bSHermès Bélusca-Maïto { 10666f19c83bSHermès Bélusca-Maïto LARGE_INTEGER SystemTime; 10676f19c83bSHermès Bélusca-Maïto TIME_FIELDS TimeFields; 10686f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry2; 10696f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry2; 10706f19c83bSHermès Bélusca-Maïto PUCHAR Buffer; 10716f19c83bSHermès Bélusca-Maïto 10726f19c83bSHermès Bélusca-Maïto Buffer = (PUCHAR)&DiskEntry->LayoutBuffer->Signature; 10736f19c83bSHermès Bélusca-Maïto 10746f19c83bSHermès Bélusca-Maïto while (TRUE) 10756f19c83bSHermès Bélusca-Maïto { 10766f19c83bSHermès Bélusca-Maïto NtQuerySystemTime(&SystemTime); 10776f19c83bSHermès Bélusca-Maïto RtlTimeToTimeFields(&SystemTime, &TimeFields); 10786f19c83bSHermès Bélusca-Maïto 10796f19c83bSHermès Bélusca-Maïto Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF); 10806f19c83bSHermès Bélusca-Maïto Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF); 10816f19c83bSHermès Bélusca-Maïto Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF); 10826f19c83bSHermès Bélusca-Maïto Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF); 10836f19c83bSHermès Bélusca-Maïto 10846f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer->Signature == 0) 10856f19c83bSHermès Bélusca-Maïto { 10866f19c83bSHermès Bélusca-Maïto continue; 10876f19c83bSHermès Bélusca-Maïto } 10886f19c83bSHermès Bélusca-Maïto 10896f19c83bSHermès Bélusca-Maïto /* Check if the signature already exist */ 10906f19c83bSHermès Bélusca-Maïto /* FIXME: 10916f19c83bSHermès Bélusca-Maïto * Check also signatures from disks, which are 10926f19c83bSHermès Bélusca-Maïto * not visible (bootable) by the bios. 10936f19c83bSHermès Bélusca-Maïto */ 10946f19c83bSHermès Bélusca-Maïto Entry2 = List->DiskListHead.Flink; 10956f19c83bSHermès Bélusca-Maïto while (Entry2 != &List->DiskListHead) 10966f19c83bSHermès Bélusca-Maïto { 10976f19c83bSHermès Bélusca-Maïto DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry); 10986f19c83bSHermès Bélusca-Maïto 10996f19c83bSHermès Bélusca-Maïto if (DiskEntry != DiskEntry2 && 11006f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->Signature == DiskEntry2->LayoutBuffer->Signature) 11016f19c83bSHermès Bélusca-Maïto break; 11026f19c83bSHermès Bélusca-Maïto 11036f19c83bSHermès Bélusca-Maïto Entry2 = Entry2->Flink; 11046f19c83bSHermès Bélusca-Maïto } 11056f19c83bSHermès Bélusca-Maïto 11066f19c83bSHermès Bélusca-Maïto if (Entry2 == &List->DiskListHead) 11076f19c83bSHermès Bélusca-Maïto break; 11086f19c83bSHermès Bélusca-Maïto } 11096f19c83bSHermès Bélusca-Maïto } 11106f19c83bSHermès Bélusca-Maïto 11116f19c83bSHermès Bélusca-Maïto static 11126f19c83bSHermès Bélusca-Maïto VOID 11136f19c83bSHermès Bélusca-Maïto UpdateDiskSignatures( 11146f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 11156f19c83bSHermès Bélusca-Maïto { 11166f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 11176f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 11186f19c83bSHermès Bélusca-Maïto 11196f19c83bSHermès Bélusca-Maïto /* Print partition lines */ 11206f19c83bSHermès Bélusca-Maïto Entry = List->DiskListHead.Flink; 11216f19c83bSHermès Bélusca-Maïto while (Entry != &List->DiskListHead) 11226f19c83bSHermès Bélusca-Maïto { 11236f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); 11246f19c83bSHermès Bélusca-Maïto 11256f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer && 11266f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->Signature == 0) 11276f19c83bSHermès Bélusca-Maïto { 11286f19c83bSHermès Bélusca-Maïto SetDiskSignature(List, DiskEntry); 11296f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[0].RewritePartition = TRUE; 11306f19c83bSHermès Bélusca-Maïto } 11316f19c83bSHermès Bélusca-Maïto 11326f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 11336f19c83bSHermès Bélusca-Maïto } 11346f19c83bSHermès Bélusca-Maïto } 11356f19c83bSHermès Bélusca-Maïto 11366f19c83bSHermès Bélusca-Maïto static 11376f19c83bSHermès Bélusca-Maïto VOID 11386f19c83bSHermès Bélusca-Maïto AddDiskToList( 11396f19c83bSHermès Bélusca-Maïto IN HANDLE FileHandle, 11406f19c83bSHermès Bélusca-Maïto IN ULONG DiskNumber, 11416f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 11426f19c83bSHermès Bélusca-Maïto { 11436f19c83bSHermès Bélusca-Maïto DISK_GEOMETRY DiskGeometry; 11446f19c83bSHermès Bélusca-Maïto SCSI_ADDRESS ScsiAddress; 11456f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 11466f19c83bSHermès Bélusca-Maïto IO_STATUS_BLOCK Iosb; 11476f19c83bSHermès Bélusca-Maïto NTSTATUS Status; 11486f19c83bSHermès Bélusca-Maïto PPARTITION_SECTOR Mbr; 11496f19c83bSHermès Bélusca-Maïto PULONG Buffer; 11506f19c83bSHermès Bélusca-Maïto LARGE_INTEGER FileOffset; 11516f19c83bSHermès Bélusca-Maïto WCHAR Identifier[20]; 11526f19c83bSHermès Bélusca-Maïto ULONG Checksum; 11536f19c83bSHermès Bélusca-Maïto ULONG Signature; 11546f19c83bSHermès Bélusca-Maïto ULONG i; 11556f19c83bSHermès Bélusca-Maïto PLIST_ENTRY ListEntry; 11566f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry; 11576f19c83bSHermès Bélusca-Maïto ULONG LayoutBufferSize; 11586f19c83bSHermès Bélusca-Maïto PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer; 11596f19c83bSHermès Bélusca-Maïto 1160f41750abSHermès Bélusca-Maïto /* Retrieve the drive geometry */ 11616f19c83bSHermès Bélusca-Maïto Status = NtDeviceIoControlFile(FileHandle, 11626f19c83bSHermès Bélusca-Maïto NULL, 11636f19c83bSHermès Bélusca-Maïto NULL, 11646f19c83bSHermès Bélusca-Maïto NULL, 11656f19c83bSHermès Bélusca-Maïto &Iosb, 11666f19c83bSHermès Bélusca-Maïto IOCTL_DISK_GET_DRIVE_GEOMETRY, 11676f19c83bSHermès Bélusca-Maïto NULL, 11686f19c83bSHermès Bélusca-Maïto 0, 11696f19c83bSHermès Bélusca-Maïto &DiskGeometry, 1170f41750abSHermès Bélusca-Maïto sizeof(DiskGeometry)); 11716f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 11726f19c83bSHermès Bélusca-Maïto return; 11736f19c83bSHermès Bélusca-Maïto 11746f19c83bSHermès Bélusca-Maïto if (DiskGeometry.MediaType != FixedMedia && 11756f19c83bSHermès Bélusca-Maïto DiskGeometry.MediaType != RemovableMedia) 11766f19c83bSHermès Bélusca-Maïto { 11776f19c83bSHermès Bélusca-Maïto return; 11786f19c83bSHermès Bélusca-Maïto } 11796f19c83bSHermès Bélusca-Maïto 1180f41750abSHermès Bélusca-Maïto /* 1181f41750abSHermès Bélusca-Maïto * FIXME: Here we suppose the disk is always SCSI. What if it is 1182f41750abSHermès Bélusca-Maïto * of another type? To check this we need to retrieve the name of 1183f41750abSHermès Bélusca-Maïto * the driver the disk device belongs to. 1184f41750abSHermès Bélusca-Maïto */ 11856f19c83bSHermès Bélusca-Maïto Status = NtDeviceIoControlFile(FileHandle, 11866f19c83bSHermès Bélusca-Maïto NULL, 11876f19c83bSHermès Bélusca-Maïto NULL, 11886f19c83bSHermès Bélusca-Maïto NULL, 11896f19c83bSHermès Bélusca-Maïto &Iosb, 11906f19c83bSHermès Bélusca-Maïto IOCTL_SCSI_GET_ADDRESS, 11916f19c83bSHermès Bélusca-Maïto NULL, 11926f19c83bSHermès Bélusca-Maïto 0, 11936f19c83bSHermès Bélusca-Maïto &ScsiAddress, 1194f41750abSHermès Bélusca-Maïto sizeof(ScsiAddress)); 11956f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 11966f19c83bSHermès Bélusca-Maïto return; 11976f19c83bSHermès Bélusca-Maïto 11986f19c83bSHermès Bélusca-Maïto /* 11996f19c83bSHermès Bélusca-Maïto * Check whether the disk is initialized, by looking at its MBR. 12006f19c83bSHermès Bélusca-Maïto * NOTE that this must be generalized to GPT disks as well! 12016f19c83bSHermès Bélusca-Maïto */ 12026f19c83bSHermès Bélusca-Maïto 12036f19c83bSHermès Bélusca-Maïto Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap, 12046f19c83bSHermès Bélusca-Maïto 0, 12056f19c83bSHermès Bélusca-Maïto DiskGeometry.BytesPerSector); 12066f19c83bSHermès Bélusca-Maïto if (Mbr == NULL) 12076f19c83bSHermès Bélusca-Maïto return; 12086f19c83bSHermès Bélusca-Maïto 12096f19c83bSHermès Bélusca-Maïto FileOffset.QuadPart = 0; 12106f19c83bSHermès Bélusca-Maïto Status = NtReadFile(FileHandle, 12116f19c83bSHermès Bélusca-Maïto NULL, 12126f19c83bSHermès Bélusca-Maïto NULL, 12136f19c83bSHermès Bélusca-Maïto NULL, 12146f19c83bSHermès Bélusca-Maïto &Iosb, 12156f19c83bSHermès Bélusca-Maïto (PVOID)Mbr, 12166f19c83bSHermès Bélusca-Maïto DiskGeometry.BytesPerSector, 12176f19c83bSHermès Bélusca-Maïto &FileOffset, 12186f19c83bSHermès Bélusca-Maïto NULL); 12196f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 12206f19c83bSHermès Bélusca-Maïto { 12216f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Mbr); 12226f19c83bSHermès Bélusca-Maïto DPRINT1("NtReadFile failed, status=%x\n", Status); 12236f19c83bSHermès Bélusca-Maïto return; 12246f19c83bSHermès Bélusca-Maïto } 12256f19c83bSHermès Bélusca-Maïto Signature = Mbr->Signature; 12266f19c83bSHermès Bélusca-Maïto 12276f19c83bSHermès Bélusca-Maïto /* Calculate the MBR checksum */ 12286f19c83bSHermès Bélusca-Maïto Checksum = 0; 12296f19c83bSHermès Bélusca-Maïto Buffer = (PULONG)Mbr; 12306f19c83bSHermès Bélusca-Maïto for (i = 0; i < 128; i++) 12316f19c83bSHermès Bélusca-Maïto { 12326f19c83bSHermès Bélusca-Maïto Checksum += Buffer[i]; 12336f19c83bSHermès Bélusca-Maïto } 12346f19c83bSHermès Bélusca-Maïto Checksum = ~Checksum + 1; 12356f19c83bSHermès Bélusca-Maïto 12366f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Identifier, ARRAYSIZE(Identifier), 12376f19c83bSHermès Bélusca-Maïto L"%08x-%08x-A", Checksum, Signature); 12386f19c83bSHermès Bélusca-Maïto DPRINT("Identifier: %S\n", Identifier); 12396f19c83bSHermès Bélusca-Maïto 12406f19c83bSHermès Bélusca-Maïto DiskEntry = RtlAllocateHeap(ProcessHeap, 12416f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 12426f19c83bSHermès Bélusca-Maïto sizeof(DISKENTRY)); 12436f19c83bSHermès Bélusca-Maïto if (DiskEntry == NULL) 12446f19c83bSHermès Bélusca-Maïto { 1245f41750abSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Mbr); 1246f41750abSHermès Bélusca-Maïto DPRINT1("Failed to allocate a new disk entry.\n"); 12476f19c83bSHermès Bélusca-Maïto return; 12486f19c83bSHermès Bélusca-Maïto } 12496f19c83bSHermès Bélusca-Maïto 12506f19c83bSHermès Bélusca-Maïto // DiskEntry->Checksum = Checksum; 12516f19c83bSHermès Bélusca-Maïto // DiskEntry->Signature = Signature; 12526f19c83bSHermès Bélusca-Maïto DiskEntry->BiosFound = FALSE; 12536f19c83bSHermès Bélusca-Maïto 12546f19c83bSHermès Bélusca-Maïto /* 12556f19c83bSHermès Bélusca-Maïto * Check if this disk has a valid MBR: verify its signature, 12566f19c83bSHermès Bélusca-Maïto * and whether its two first bytes are a valid instruction 12576f19c83bSHermès Bélusca-Maïto * (related to this, see IsThereAValidBootSector() in partlist.c). 12586f19c83bSHermès Bélusca-Maïto */ 12596f19c83bSHermès Bélusca-Maïto if (Mbr->Magic != 0xaa55 || (*(PUSHORT)Mbr->BootCode) == 0x0000) 12606f19c83bSHermès Bélusca-Maïto DiskEntry->NoMbr = TRUE; 12616f19c83bSHermès Bélusca-Maïto else 12626f19c83bSHermès Bélusca-Maïto DiskEntry->NoMbr = FALSE; 12636f19c83bSHermès Bélusca-Maïto 12646f19c83bSHermès Bélusca-Maïto /* Free the MBR sector buffer */ 12656f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, Mbr); 12666f19c83bSHermès Bélusca-Maïto 12676f19c83bSHermès Bélusca-Maïto 12686f19c83bSHermès Bélusca-Maïto ListEntry = List->BiosDiskListHead.Flink; 12696f19c83bSHermès Bélusca-Maïto while (ListEntry != &List->BiosDiskListHead) 12706f19c83bSHermès Bélusca-Maïto { 12716f19c83bSHermès Bélusca-Maïto BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry); 12726f19c83bSHermès Bélusca-Maïto /* FIXME: 12736f19c83bSHermès Bélusca-Maïto * Compare the size from bios and the reported size from driver. 12746f19c83bSHermès Bélusca-Maïto * If we have more than one disk with a zero or with the same signature 12756f19c83bSHermès Bélusca-Maïto * we must create new signatures and reboot. After the reboot, 12766f19c83bSHermès Bélusca-Maïto * it is possible to identify the disks. 12776f19c83bSHermès Bélusca-Maïto */ 12786f19c83bSHermès Bélusca-Maïto if (BiosDiskEntry->Signature == Signature && 12796f19c83bSHermès Bélusca-Maïto BiosDiskEntry->Checksum == Checksum && 12806f19c83bSHermès Bélusca-Maïto !BiosDiskEntry->Recognized) 12816f19c83bSHermès Bélusca-Maïto { 12826f19c83bSHermès Bélusca-Maïto if (!DiskEntry->BiosFound) 12836f19c83bSHermès Bélusca-Maïto { 12846f19c83bSHermès Bélusca-Maïto DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber; 12856f19c83bSHermès Bélusca-Maïto DiskEntry->BiosFound = TRUE; 12866f19c83bSHermès Bélusca-Maïto BiosDiskEntry->Recognized = TRUE; 12876f19c83bSHermès Bélusca-Maïto } 12886f19c83bSHermès Bélusca-Maïto else 12896f19c83bSHermès Bélusca-Maïto { 1290f41750abSHermès Bélusca-Maïto // FIXME: What to do? 12916f19c83bSHermès Bélusca-Maïto } 12926f19c83bSHermès Bélusca-Maïto } 12936f19c83bSHermès Bélusca-Maïto ListEntry = ListEntry->Flink; 12946f19c83bSHermès Bélusca-Maïto } 12956f19c83bSHermès Bélusca-Maïto 12966f19c83bSHermès Bélusca-Maïto if (!DiskEntry->BiosFound) 12976f19c83bSHermès Bélusca-Maïto { 12986f19c83bSHermès Bélusca-Maïto #if 0 12996f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, DiskEntry); 13006f19c83bSHermès Bélusca-Maïto return; 13016f19c83bSHermès Bélusca-Maïto #else 13026f19c83bSHermès Bélusca-Maïto DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber); 13036f19c83bSHermès Bélusca-Maïto #endif 13046f19c83bSHermès Bélusca-Maïto } 13056f19c83bSHermès Bélusca-Maïto 13066f19c83bSHermès Bélusca-Maïto InitializeListHead(&DiskEntry->PrimaryPartListHead); 13076f19c83bSHermès Bélusca-Maïto InitializeListHead(&DiskEntry->LogicalPartListHead); 13086f19c83bSHermès Bélusca-Maïto 13096f19c83bSHermès Bélusca-Maïto DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart; 13106f19c83bSHermès Bélusca-Maïto DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder; 13116f19c83bSHermès Bélusca-Maïto DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack; 13126f19c83bSHermès Bélusca-Maïto DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector; 13136f19c83bSHermès Bélusca-Maïto 13146f19c83bSHermès Bélusca-Maïto DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders); 13156f19c83bSHermès Bélusca-Maïto DPRINT("TracksPerCylinder %lu\n", DiskEntry->TracksPerCylinder); 13166f19c83bSHermès Bélusca-Maïto DPRINT("SectorsPerTrack %lu\n", DiskEntry->SectorsPerTrack); 13176f19c83bSHermès Bélusca-Maïto DPRINT("BytesPerSector %lu\n", DiskEntry->BytesPerSector); 13186f19c83bSHermès Bélusca-Maïto 13196f19c83bSHermès Bélusca-Maïto DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart * 13206f19c83bSHermès Bélusca-Maïto (ULONGLONG)DiskGeometry.TracksPerCylinder * 13216f19c83bSHermès Bélusca-Maïto (ULONGLONG)DiskGeometry.SectorsPerTrack; 13226f19c83bSHermès Bélusca-Maïto 13236f19c83bSHermès Bélusca-Maïto DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack; 13246f19c83bSHermès Bélusca-Maïto DiskEntry->CylinderAlignment = DiskGeometry.TracksPerCylinder * 13256f19c83bSHermès Bélusca-Maïto DiskGeometry.SectorsPerTrack; 13266f19c83bSHermès Bélusca-Maïto 13276f19c83bSHermès Bélusca-Maïto DPRINT("SectorCount %I64u\n", DiskEntry->SectorCount.QuadPart); 13286f19c83bSHermès Bélusca-Maïto DPRINT("SectorAlignment %lu\n", DiskEntry->SectorAlignment); 13296f19c83bSHermès Bélusca-Maïto 13306f19c83bSHermès Bélusca-Maïto DiskEntry->DiskNumber = DiskNumber; 13316f19c83bSHermès Bélusca-Maïto DiskEntry->Port = ScsiAddress.PortNumber; 13326f19c83bSHermès Bélusca-Maïto DiskEntry->Bus = ScsiAddress.PathId; 13336f19c83bSHermès Bélusca-Maïto DiskEntry->Id = ScsiAddress.TargetId; 13346f19c83bSHermès Bélusca-Maïto 13356f19c83bSHermès Bélusca-Maïto GetDriverName(DiskEntry); 13366f19c83bSHermès Bélusca-Maïto /* 13376f19c83bSHermès Bélusca-Maïto * Actually it would be more correct somehow to use: 13386f19c83bSHermès Bélusca-Maïto * 13396f19c83bSHermès Bélusca-Maïto * OBJECT_NAME_INFORMATION NameInfo; // ObjectNameInfo; 13406f19c83bSHermès Bélusca-Maïto * ULONG ReturnedLength; 13416f19c83bSHermès Bélusca-Maïto * 13426f19c83bSHermès Bélusca-Maïto * Status = NtQueryObject(SomeHandleToTheDisk, 13436f19c83bSHermès Bélusca-Maïto * ObjectNameInformation, 13446f19c83bSHermès Bélusca-Maïto * &NameInfo, 13456f19c83bSHermès Bélusca-Maïto * sizeof(NameInfo), 13466f19c83bSHermès Bélusca-Maïto * &ReturnedLength); 13476f19c83bSHermès Bélusca-Maïto * etc... 13486f19c83bSHermès Bélusca-Maïto * 13496f19c83bSHermès Bélusca-Maïto * See examples in https://git.reactos.org/?p=reactos.git;a=blob;f=reactos/ntoskrnl/io/iomgr/error.c;hb=2f3a93ee9cec8322a86bf74b356f1ad83fc912dc#l267 13506f19c83bSHermès Bélusca-Maïto */ 13516f19c83bSHermès Bélusca-Maïto 13526f19c83bSHermès Bélusca-Maïto InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber); 13536f19c83bSHermès Bélusca-Maïto 1354f41750abSHermès Bélusca-Maïto 1355f41750abSHermès Bélusca-Maïto /* 1356f41750abSHermès Bélusca-Maïto * We now retrieve the disk partition layout 1357f41750abSHermès Bélusca-Maïto */ 1358f41750abSHermès Bélusca-Maïto 13596f19c83bSHermès Bélusca-Maïto /* Allocate a layout buffer with 4 partition entries first */ 13606f19c83bSHermès Bélusca-Maïto LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + 13616f19c83bSHermès Bélusca-Maïto ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); 13626f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer = RtlAllocateHeap(ProcessHeap, 13636f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 13646f19c83bSHermès Bélusca-Maïto LayoutBufferSize); 13656f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer == NULL) 13666f19c83bSHermès Bélusca-Maïto { 13676f19c83bSHermès Bélusca-Maïto DPRINT1("Failed to allocate the disk layout buffer!\n"); 13686f19c83bSHermès Bélusca-Maïto return; 13696f19c83bSHermès Bélusca-Maïto } 13706f19c83bSHermès Bélusca-Maïto 1371f41750abSHermès Bélusca-Maïto /* Keep looping while the drive layout buffer is too small */ 13726f19c83bSHermès Bélusca-Maïto for (;;) 13736f19c83bSHermès Bélusca-Maïto { 13746f19c83bSHermès Bélusca-Maïto DPRINT1("Buffer size: %lu\n", LayoutBufferSize); 13756f19c83bSHermès Bélusca-Maïto Status = NtDeviceIoControlFile(FileHandle, 13766f19c83bSHermès Bélusca-Maïto NULL, 13776f19c83bSHermès Bélusca-Maïto NULL, 13786f19c83bSHermès Bélusca-Maïto NULL, 13796f19c83bSHermès Bélusca-Maïto &Iosb, 13806f19c83bSHermès Bélusca-Maïto IOCTL_DISK_GET_DRIVE_LAYOUT, 13816f19c83bSHermès Bélusca-Maïto NULL, 13826f19c83bSHermès Bélusca-Maïto 0, 13836f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer, 13846f19c83bSHermès Bélusca-Maïto LayoutBufferSize); 13856f19c83bSHermès Bélusca-Maïto if (NT_SUCCESS(Status)) 13866f19c83bSHermès Bélusca-Maïto break; 13876f19c83bSHermès Bélusca-Maïto 13886f19c83bSHermès Bélusca-Maïto if (Status != STATUS_BUFFER_TOO_SMALL) 13896f19c83bSHermès Bélusca-Maïto { 13906f19c83bSHermès Bélusca-Maïto DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status); 13916f19c83bSHermès Bélusca-Maïto return; 13926f19c83bSHermès Bélusca-Maïto } 13936f19c83bSHermès Bélusca-Maïto 13946f19c83bSHermès Bélusca-Maïto LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION); 13956f19c83bSHermès Bélusca-Maïto NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap, 13966f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 13976f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer, 13986f19c83bSHermès Bélusca-Maïto LayoutBufferSize); 13996f19c83bSHermès Bélusca-Maïto if (NewLayoutBuffer == NULL) 14006f19c83bSHermès Bélusca-Maïto { 14016f19c83bSHermès Bélusca-Maïto DPRINT1("Failed to reallocate the disk layout buffer!\n"); 14026f19c83bSHermès Bélusca-Maïto return; 14036f19c83bSHermès Bélusca-Maïto } 14046f19c83bSHermès Bélusca-Maïto 14056f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer = NewLayoutBuffer; 14066f19c83bSHermès Bélusca-Maïto } 14076f19c83bSHermès Bélusca-Maïto 14086f19c83bSHermès Bélusca-Maïto DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount); 14096f19c83bSHermès Bélusca-Maïto 14106f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE 14116f19c83bSHermès Bélusca-Maïto DumpPartitionTable(DiskEntry); 14126f19c83bSHermès Bélusca-Maïto #endif 14136f19c83bSHermès Bélusca-Maïto 14146f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 && 14156f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0 && 14166f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != PARTITION_ENTRY_UNUSED) 14176f19c83bSHermès Bélusca-Maïto { 14186f19c83bSHermès Bélusca-Maïto if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0) 14196f19c83bSHermès Bélusca-Maïto { 14206f19c83bSHermès Bélusca-Maïto DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack); 14216f19c83bSHermès Bélusca-Maïto } 14226f19c83bSHermès Bélusca-Maïto else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0) 14236f19c83bSHermès Bélusca-Maïto { 14246f19c83bSHermès Bélusca-Maïto DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector); 14256f19c83bSHermès Bélusca-Maïto } 14266f19c83bSHermès Bélusca-Maïto else 14276f19c83bSHermès Bélusca-Maïto { 14286f19c83bSHermès Bélusca-Maïto DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart); 14296f19c83bSHermès Bélusca-Maïto } 14306f19c83bSHermès Bélusca-Maïto } 14316f19c83bSHermès Bélusca-Maïto else 14326f19c83bSHermès Bélusca-Maïto { 14336f19c83bSHermès Bélusca-Maïto DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector); 14346f19c83bSHermès Bélusca-Maïto } 14356f19c83bSHermès Bélusca-Maïto 14366f19c83bSHermès Bélusca-Maïto 14376f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer->PartitionCount == 0) 14386f19c83bSHermès Bélusca-Maïto { 14396f19c83bSHermès Bélusca-Maïto DiskEntry->NewDisk = TRUE; 14406f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionCount = 4; 14416f19c83bSHermès Bélusca-Maïto 14426f19c83bSHermès Bélusca-Maïto for (i = 0; i < 4; i++) 14436f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE; 14446f19c83bSHermès Bélusca-Maïto } 14456f19c83bSHermès Bélusca-Maïto else 14466f19c83bSHermès Bélusca-Maïto { 14476f19c83bSHermès Bélusca-Maïto for (i = 0; i < 4; i++) 14486f19c83bSHermès Bélusca-Maïto { 14496f19c83bSHermès Bélusca-Maïto AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE); 14506f19c83bSHermès Bélusca-Maïto } 14516f19c83bSHermès Bélusca-Maïto 14526f19c83bSHermès Bélusca-Maïto for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4) 14536f19c83bSHermès Bélusca-Maïto { 14546f19c83bSHermès Bélusca-Maïto AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE); 14556f19c83bSHermès Bélusca-Maïto } 14566f19c83bSHermès Bélusca-Maïto } 14576f19c83bSHermès Bélusca-Maïto 14586f19c83bSHermès Bélusca-Maïto ScanForUnpartitionedDiskSpace(DiskEntry); 14596f19c83bSHermès Bélusca-Maïto } 14606f19c83bSHermès Bélusca-Maïto 14616f19c83bSHermès Bélusca-Maïto PPARTLIST 14626f19c83bSHermès Bélusca-Maïto CreatePartitionList(VOID) 14636f19c83bSHermès Bélusca-Maïto { 14646f19c83bSHermès Bélusca-Maïto PPARTLIST List; 14656f19c83bSHermès Bélusca-Maïto OBJECT_ATTRIBUTES ObjectAttributes; 14666f19c83bSHermès Bélusca-Maïto SYSTEM_DEVICE_INFORMATION Sdi; 14676f19c83bSHermès Bélusca-Maïto IO_STATUS_BLOCK Iosb; 14686f19c83bSHermès Bélusca-Maïto ULONG ReturnSize; 14696f19c83bSHermès Bélusca-Maïto NTSTATUS Status; 14706f19c83bSHermès Bélusca-Maïto ULONG DiskNumber; 14716f19c83bSHermès Bélusca-Maïto WCHAR Buffer[MAX_PATH]; 14726f19c83bSHermès Bélusca-Maïto UNICODE_STRING Name; 14736f19c83bSHermès Bélusca-Maïto HANDLE FileHandle; 14746f19c83bSHermès Bélusca-Maïto 14756f19c83bSHermès Bélusca-Maïto List = (PPARTLIST)RtlAllocateHeap(ProcessHeap, 14766f19c83bSHermès Bélusca-Maïto 0, 14776f19c83bSHermès Bélusca-Maïto sizeof(PARTLIST)); 14786f19c83bSHermès Bélusca-Maïto if (List == NULL) 14796f19c83bSHermès Bélusca-Maïto return NULL; 14806f19c83bSHermès Bélusca-Maïto 14816f19c83bSHermès Bélusca-Maïto List->CurrentDisk = NULL; 14826f19c83bSHermès Bélusca-Maïto List->CurrentPartition = NULL; 14836f19c83bSHermès Bélusca-Maïto 14846f19c83bSHermès Bélusca-Maïto List->SystemPartition = NULL; 14856f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition = NULL; 14866f19c83bSHermès Bélusca-Maïto 14876f19c83bSHermès Bélusca-Maïto InitializeListHead(&List->DiskListHead); 14886f19c83bSHermès Bélusca-Maïto InitializeListHead(&List->BiosDiskListHead); 14896f19c83bSHermès Bélusca-Maïto 1490f41750abSHermès Bélusca-Maïto /* 1491f41750abSHermès Bélusca-Maïto * Enumerate the disks seen by the BIOS; this will be used later 1492f41750abSHermès Bélusca-Maïto * to map drives seen by NTOS with their corresponding BIOS names. 1493f41750abSHermès Bélusca-Maïto */ 14946f19c83bSHermès Bélusca-Maïto EnumerateBiosDiskEntries(List); 14956f19c83bSHermès Bélusca-Maïto 1496f41750abSHermès Bélusca-Maïto /* Enumerate disks seen by NTOS */ 14976f19c83bSHermès Bélusca-Maïto Status = NtQuerySystemInformation(SystemDeviceInformation, 14986f19c83bSHermès Bélusca-Maïto &Sdi, 14996f19c83bSHermès Bélusca-Maïto sizeof(Sdi), 15006f19c83bSHermès Bélusca-Maïto &ReturnSize); 15016f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 15026f19c83bSHermès Bélusca-Maïto { 15036f19c83bSHermès Bélusca-Maïto DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status); 15046f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, List); 15056f19c83bSHermès Bélusca-Maïto return NULL; 15066f19c83bSHermès Bélusca-Maïto } 15076f19c83bSHermès Bélusca-Maïto 15086f19c83bSHermès Bélusca-Maïto for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++) 15096f19c83bSHermès Bélusca-Maïto { 15106f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(Buffer, ARRAYSIZE(Buffer), 15116f19c83bSHermès Bélusca-Maïto L"\\Device\\Harddisk%lu\\Partition0", 15126f19c83bSHermès Bélusca-Maïto DiskNumber); 15136f19c83bSHermès Bélusca-Maïto RtlInitUnicodeString(&Name, Buffer); 15146f19c83bSHermès Bélusca-Maïto 15156f19c83bSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes, 15166f19c83bSHermès Bélusca-Maïto &Name, 1517765994c9SHermès Bélusca-Maïto OBJ_CASE_INSENSITIVE, 15186f19c83bSHermès Bélusca-Maïto NULL, 15196f19c83bSHermès Bélusca-Maïto NULL); 15206f19c83bSHermès Bélusca-Maïto 15216f19c83bSHermès Bélusca-Maïto Status = NtOpenFile(&FileHandle, 15226f19c83bSHermès Bélusca-Maïto FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, 15236f19c83bSHermès Bélusca-Maïto &ObjectAttributes, 15246f19c83bSHermès Bélusca-Maïto &Iosb, 1525f41750abSHermès Bélusca-Maïto FILE_SHARE_READ | FILE_SHARE_WRITE, 15266f19c83bSHermès Bélusca-Maïto FILE_SYNCHRONOUS_IO_NONALERT); 15276f19c83bSHermès Bélusca-Maïto if (NT_SUCCESS(Status)) 15286f19c83bSHermès Bélusca-Maïto { 15296f19c83bSHermès Bélusca-Maïto AddDiskToList(FileHandle, DiskNumber, List); 15306f19c83bSHermès Bélusca-Maïto NtClose(FileHandle); 15316f19c83bSHermès Bélusca-Maïto } 15326f19c83bSHermès Bélusca-Maïto } 15336f19c83bSHermès Bélusca-Maïto 15346f19c83bSHermès Bélusca-Maïto UpdateDiskSignatures(List); 15356f19c83bSHermès Bélusca-Maïto 15366f19c83bSHermès Bélusca-Maïto AssignDriveLetters(List); 15376f19c83bSHermès Bélusca-Maïto 15386f19c83bSHermès Bélusca-Maïto /* Search for first usable disk and partition */ 15396f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&List->DiskListHead)) 15406f19c83bSHermès Bélusca-Maïto { 15416f19c83bSHermès Bélusca-Maïto List->CurrentDisk = NULL; 15426f19c83bSHermès Bélusca-Maïto List->CurrentPartition = NULL; 15436f19c83bSHermès Bélusca-Maïto } 15446f19c83bSHermès Bélusca-Maïto else 15456f19c83bSHermès Bélusca-Maïto { 15466f19c83bSHermès Bélusca-Maïto List->CurrentDisk = CONTAINING_RECORD(List->DiskListHead.Flink, 15476f19c83bSHermès Bélusca-Maïto DISKENTRY, 15486f19c83bSHermès Bélusca-Maïto ListEntry); 15496f19c83bSHermès Bélusca-Maïto 15506f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&List->CurrentDisk->PrimaryPartListHead)) 15516f19c83bSHermès Bélusca-Maïto { 15526f19c83bSHermès Bélusca-Maïto List->CurrentPartition = NULL; 15536f19c83bSHermès Bélusca-Maïto } 15546f19c83bSHermès Bélusca-Maïto else 15556f19c83bSHermès Bélusca-Maïto { 15566f19c83bSHermès Bélusca-Maïto List->CurrentPartition = CONTAINING_RECORD(List->CurrentDisk->PrimaryPartListHead.Flink, 15576f19c83bSHermès Bélusca-Maïto PARTENTRY, 15586f19c83bSHermès Bélusca-Maïto ListEntry); 15596f19c83bSHermès Bélusca-Maïto } 15606f19c83bSHermès Bélusca-Maïto } 15616f19c83bSHermès Bélusca-Maïto 15626f19c83bSHermès Bélusca-Maïto return List; 15636f19c83bSHermès Bélusca-Maïto } 15646f19c83bSHermès Bélusca-Maïto 15656f19c83bSHermès Bélusca-Maïto VOID 15666f19c83bSHermès Bélusca-Maïto DestroyPartitionList( 15676f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 15686f19c83bSHermès Bélusca-Maïto { 15696f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 15706f19c83bSHermès Bélusca-Maïto PBIOSDISKENTRY BiosDiskEntry; 15716f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 15726f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 15736f19c83bSHermès Bélusca-Maïto 15746f19c83bSHermès Bélusca-Maïto /* Release disk and partition info */ 15756f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&List->DiskListHead)) 15766f19c83bSHermès Bélusca-Maïto { 15776f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&List->DiskListHead); 15786f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); 15796f19c83bSHermès Bélusca-Maïto 15806f19c83bSHermès Bélusca-Maïto /* Release driver name */ 15816f19c83bSHermès Bélusca-Maïto RtlFreeUnicodeString(&DiskEntry->DriverName); 15826f19c83bSHermès Bélusca-Maïto 15836f19c83bSHermès Bélusca-Maïto /* Release primary partition list */ 15846f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&DiskEntry->PrimaryPartListHead)) 15856f19c83bSHermès Bélusca-Maïto { 15866f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead); 15876f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 15886f19c83bSHermès Bélusca-Maïto 15896f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, PartEntry); 15906f19c83bSHermès Bélusca-Maïto } 15916f19c83bSHermès Bélusca-Maïto 15926f19c83bSHermès Bélusca-Maïto /* Release logical partition list */ 15936f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&DiskEntry->LogicalPartListHead)) 15946f19c83bSHermès Bélusca-Maïto { 15956f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead); 15966f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 15976f19c83bSHermès Bélusca-Maïto 15986f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, PartEntry); 15996f19c83bSHermès Bélusca-Maïto } 16006f19c83bSHermès Bélusca-Maïto 16016f19c83bSHermès Bélusca-Maïto /* Release layout buffer */ 16026f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer != NULL) 16036f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer); 16046f19c83bSHermès Bélusca-Maïto 16056f19c83bSHermès Bélusca-Maïto /* Release disk entry */ 16066f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, DiskEntry); 16076f19c83bSHermès Bélusca-Maïto } 16086f19c83bSHermès Bélusca-Maïto 16096f19c83bSHermès Bélusca-Maïto /* Release the bios disk info */ 16106f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&List->BiosDiskListHead)) 16116f19c83bSHermès Bélusca-Maïto { 16126f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&List->BiosDiskListHead); 16136f19c83bSHermès Bélusca-Maïto BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry); 16146f19c83bSHermès Bélusca-Maïto 16156f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry); 16166f19c83bSHermès Bélusca-Maïto } 16176f19c83bSHermès Bélusca-Maïto 16186f19c83bSHermès Bélusca-Maïto /* Release list head */ 16196f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, List); 16206f19c83bSHermès Bélusca-Maïto } 16216f19c83bSHermès Bélusca-Maïto 16226f19c83bSHermès Bélusca-Maïto PDISKENTRY 16236f19c83bSHermès Bélusca-Maïto GetDiskByBiosNumber( 16246f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 16256f19c83bSHermès Bélusca-Maïto IN ULONG BiosDiskNumber) 16266f19c83bSHermès Bélusca-Maïto { 16276f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 16286f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 16296f19c83bSHermès Bélusca-Maïto 16306f19c83bSHermès Bélusca-Maïto /* Loop over the disks and find the correct one */ 16316f19c83bSHermès Bélusca-Maïto Entry = List->DiskListHead.Flink; 16326f19c83bSHermès Bélusca-Maïto while (Entry != &List->DiskListHead) 16336f19c83bSHermès Bélusca-Maïto { 16346f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); 16356f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 16366f19c83bSHermès Bélusca-Maïto 16376f19c83bSHermès Bélusca-Maïto if (DiskEntry->BiosDiskNumber == BiosDiskNumber) 16386f19c83bSHermès Bélusca-Maïto { 16396f19c83bSHermès Bélusca-Maïto /* Disk found */ 16406f19c83bSHermès Bélusca-Maïto return DiskEntry; 16416f19c83bSHermès Bélusca-Maïto } 16426f19c83bSHermès Bélusca-Maïto } 16436f19c83bSHermès Bélusca-Maïto 16446f19c83bSHermès Bélusca-Maïto /* Disk not found, stop there */ 16456f19c83bSHermès Bélusca-Maïto return NULL; 16466f19c83bSHermès Bélusca-Maïto } 16476f19c83bSHermès Bélusca-Maïto 16486f19c83bSHermès Bélusca-Maïto PDISKENTRY 16496f19c83bSHermès Bélusca-Maïto GetDiskByNumber( 16506f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 16516f19c83bSHermès Bélusca-Maïto IN ULONG DiskNumber) 16526f19c83bSHermès Bélusca-Maïto { 16536f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 16546f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 16556f19c83bSHermès Bélusca-Maïto 16566f19c83bSHermès Bélusca-Maïto /* Loop over the disks and find the correct one */ 16576f19c83bSHermès Bélusca-Maïto Entry = List->DiskListHead.Flink; 16586f19c83bSHermès Bélusca-Maïto while (Entry != &List->DiskListHead) 16596f19c83bSHermès Bélusca-Maïto { 16606f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); 16616f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 16626f19c83bSHermès Bélusca-Maïto 16636f19c83bSHermès Bélusca-Maïto if (DiskEntry->DiskNumber == DiskNumber) 16646f19c83bSHermès Bélusca-Maïto { 16656f19c83bSHermès Bélusca-Maïto /* Disk found */ 16666f19c83bSHermès Bélusca-Maïto return DiskEntry; 16676f19c83bSHermès Bélusca-Maïto } 16686f19c83bSHermès Bélusca-Maïto } 16696f19c83bSHermès Bélusca-Maïto 16706f19c83bSHermès Bélusca-Maïto /* Disk not found, stop there */ 16716f19c83bSHermès Bélusca-Maïto return NULL; 16726f19c83bSHermès Bélusca-Maïto } 16736f19c83bSHermès Bélusca-Maïto 16746f19c83bSHermès Bélusca-Maïto PDISKENTRY 16756f19c83bSHermès Bélusca-Maïto GetDiskBySCSI( 16766f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 16776f19c83bSHermès Bélusca-Maïto IN USHORT Port, 16786f19c83bSHermès Bélusca-Maïto IN USHORT Bus, 16796f19c83bSHermès Bélusca-Maïto IN USHORT Id) 16806f19c83bSHermès Bélusca-Maïto { 16816f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 16826f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 16836f19c83bSHermès Bélusca-Maïto 16846f19c83bSHermès Bélusca-Maïto /* Loop over the disks and find the correct one */ 16856f19c83bSHermès Bélusca-Maïto Entry = List->DiskListHead.Flink; 16866f19c83bSHermès Bélusca-Maïto while (Entry != &List->DiskListHead) 16876f19c83bSHermès Bélusca-Maïto { 16886f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); 16896f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 16906f19c83bSHermès Bélusca-Maïto 16916f19c83bSHermès Bélusca-Maïto if (DiskEntry->Port == Port && 16926f19c83bSHermès Bélusca-Maïto DiskEntry->Bus == Bus && 16936f19c83bSHermès Bélusca-Maïto DiskEntry->Id == Id) 16946f19c83bSHermès Bélusca-Maïto { 16956f19c83bSHermès Bélusca-Maïto /* Disk found */ 16966f19c83bSHermès Bélusca-Maïto return DiskEntry; 16976f19c83bSHermès Bélusca-Maïto } 16986f19c83bSHermès Bélusca-Maïto } 16996f19c83bSHermès Bélusca-Maïto 17006f19c83bSHermès Bélusca-Maïto /* Disk not found, stop there */ 17016f19c83bSHermès Bélusca-Maïto return NULL; 17026f19c83bSHermès Bélusca-Maïto } 17036f19c83bSHermès Bélusca-Maïto 17046f19c83bSHermès Bélusca-Maïto PDISKENTRY 17056f19c83bSHermès Bélusca-Maïto GetDiskBySignature( 17066f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 17076f19c83bSHermès Bélusca-Maïto IN ULONG Signature) 17086f19c83bSHermès Bélusca-Maïto { 17096f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 17106f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 17116f19c83bSHermès Bélusca-Maïto 17126f19c83bSHermès Bélusca-Maïto /* Loop over the disks and find the correct one */ 17136f19c83bSHermès Bélusca-Maïto Entry = List->DiskListHead.Flink; 17146f19c83bSHermès Bélusca-Maïto while (Entry != &List->DiskListHead) 17156f19c83bSHermès Bélusca-Maïto { 17166f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); 17176f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 17186f19c83bSHermès Bélusca-Maïto 17196f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer->Signature == Signature) 17206f19c83bSHermès Bélusca-Maïto { 17216f19c83bSHermès Bélusca-Maïto /* Disk found */ 17226f19c83bSHermès Bélusca-Maïto return DiskEntry; 17236f19c83bSHermès Bélusca-Maïto } 17246f19c83bSHermès Bélusca-Maïto } 17256f19c83bSHermès Bélusca-Maïto 17266f19c83bSHermès Bélusca-Maïto /* Disk not found, stop there */ 17276f19c83bSHermès Bélusca-Maïto return NULL; 17286f19c83bSHermès Bélusca-Maïto } 17296f19c83bSHermès Bélusca-Maïto 17306f19c83bSHermès Bélusca-Maïto PPARTENTRY 17316f19c83bSHermès Bélusca-Maïto GetPartition( 17326f19c83bSHermès Bélusca-Maïto // IN PPARTLIST List, 17336f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry, 17346f19c83bSHermès Bélusca-Maïto IN ULONG PartitionNumber) 17356f19c83bSHermès Bélusca-Maïto { 17366f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 17376f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 17386f19c83bSHermès Bélusca-Maïto 17396f19c83bSHermès Bélusca-Maïto /* Disk found, loop over the primary partitions first... */ 17406f19c83bSHermès Bélusca-Maïto Entry = DiskEntry->PrimaryPartListHead.Flink; 17416f19c83bSHermès Bélusca-Maïto while (Entry != &DiskEntry->PrimaryPartListHead) 17426f19c83bSHermès Bélusca-Maïto { 17436f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 17446f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 17456f19c83bSHermès Bélusca-Maïto 17466f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionNumber == PartitionNumber) 17476f19c83bSHermès Bélusca-Maïto { 17486f19c83bSHermès Bélusca-Maïto /* Partition found */ 17496f19c83bSHermès Bélusca-Maïto return PartEntry; 17506f19c83bSHermès Bélusca-Maïto } 17516f19c83bSHermès Bélusca-Maïto } 17526f19c83bSHermès Bélusca-Maïto 17536f19c83bSHermès Bélusca-Maïto /* ... then over the logical partitions if needed */ 17546f19c83bSHermès Bélusca-Maïto Entry = DiskEntry->LogicalPartListHead.Flink; 17556f19c83bSHermès Bélusca-Maïto while (Entry != &DiskEntry->LogicalPartListHead) 17566f19c83bSHermès Bélusca-Maïto { 17576f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 17586f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 17596f19c83bSHermès Bélusca-Maïto 17606f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionNumber == PartitionNumber) 17616f19c83bSHermès Bélusca-Maïto { 17626f19c83bSHermès Bélusca-Maïto /* Partition found */ 17636f19c83bSHermès Bélusca-Maïto return PartEntry; 17646f19c83bSHermès Bélusca-Maïto } 17656f19c83bSHermès Bélusca-Maïto } 17666f19c83bSHermès Bélusca-Maïto 17676f19c83bSHermès Bélusca-Maïto /* The partition was not found on the disk, stop there */ 17686f19c83bSHermès Bélusca-Maïto return NULL; 17696f19c83bSHermès Bélusca-Maïto } 17706f19c83bSHermès Bélusca-Maïto 17716f19c83bSHermès Bélusca-Maïto BOOLEAN 17726f19c83bSHermès Bélusca-Maïto GetDiskOrPartition( 17736f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 17746f19c83bSHermès Bélusca-Maïto IN ULONG DiskNumber, 17756f19c83bSHermès Bélusca-Maïto IN ULONG PartitionNumber OPTIONAL, 17766f19c83bSHermès Bélusca-Maïto OUT PDISKENTRY* pDiskEntry, 17776f19c83bSHermès Bélusca-Maïto OUT PPARTENTRY* pPartEntry OPTIONAL) 17786f19c83bSHermès Bélusca-Maïto { 17796f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 17806f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry = NULL; 17816f19c83bSHermès Bélusca-Maïto 17826f19c83bSHermès Bélusca-Maïto /* Find the disk */ 17836f19c83bSHermès Bélusca-Maïto DiskEntry = GetDiskByNumber(List, DiskNumber); 17846f19c83bSHermès Bélusca-Maïto if (!DiskEntry) 17856f19c83bSHermès Bélusca-Maïto return FALSE; 17866f19c83bSHermès Bélusca-Maïto 17876f19c83bSHermès Bélusca-Maïto /* If we have a partition (PartitionNumber != 0), find it */ 17886f19c83bSHermès Bélusca-Maïto if (PartitionNumber != 0) 17896f19c83bSHermès Bélusca-Maïto { 17906f19c83bSHermès Bélusca-Maïto PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber); 17916f19c83bSHermès Bélusca-Maïto if (!PartEntry) 17926f19c83bSHermès Bélusca-Maïto return FALSE; 17936f19c83bSHermès Bélusca-Maïto ASSERT(PartEntry->DiskEntry == DiskEntry); 17946f19c83bSHermès Bélusca-Maïto } 17956f19c83bSHermès Bélusca-Maïto 17966f19c83bSHermès Bélusca-Maïto /* Return the disk (and optionally the partition) */ 17976f19c83bSHermès Bélusca-Maïto *pDiskEntry = DiskEntry; 17986f19c83bSHermès Bélusca-Maïto if (pPartEntry) *pPartEntry = PartEntry; 17996f19c83bSHermès Bélusca-Maïto return TRUE; 18006f19c83bSHermès Bélusca-Maïto } 18016f19c83bSHermès Bélusca-Maïto 18026f19c83bSHermès Bélusca-Maïto // 18036f19c83bSHermès Bélusca-Maïto // NOTE: Was introduced broken in r6258 by Casper 18046f19c83bSHermès Bélusca-Maïto // 18056f19c83bSHermès Bélusca-Maïto BOOLEAN 18066f19c83bSHermès Bélusca-Maïto SelectPartition( 18076f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 18086f19c83bSHermès Bélusca-Maïto IN ULONG DiskNumber, 18096f19c83bSHermès Bélusca-Maïto IN ULONG PartitionNumber) 18106f19c83bSHermès Bélusca-Maïto { 18116f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 18126f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 18136f19c83bSHermès Bélusca-Maïto 18146f19c83bSHermès Bélusca-Maïto DiskEntry = GetDiskByNumber(List, DiskNumber); 18156f19c83bSHermès Bélusca-Maïto if (!DiskEntry) 18166f19c83bSHermès Bélusca-Maïto return FALSE; 18176f19c83bSHermès Bélusca-Maïto 18186f19c83bSHermès Bélusca-Maïto PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber); 18196f19c83bSHermès Bélusca-Maïto if (!PartEntry) 18206f19c83bSHermès Bélusca-Maïto return FALSE; 18216f19c83bSHermès Bélusca-Maïto 18226f19c83bSHermès Bélusca-Maïto ASSERT(PartEntry->DiskEntry == DiskEntry); 18236f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry->DiskNumber == DiskNumber); 18246f19c83bSHermès Bélusca-Maïto ASSERT(PartEntry->PartitionNumber == PartitionNumber); 18256f19c83bSHermès Bélusca-Maïto 18266f19c83bSHermès Bélusca-Maïto List->CurrentDisk = DiskEntry; 18276f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 18286f19c83bSHermès Bélusca-Maïto return TRUE; 18296f19c83bSHermès Bélusca-Maïto } 18306f19c83bSHermès Bélusca-Maïto 18316f19c83bSHermès Bélusca-Maïto PPARTENTRY 18326f19c83bSHermès Bélusca-Maïto GetNextPartition( 18336f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 18346f19c83bSHermès Bélusca-Maïto { 18356f19c83bSHermès Bélusca-Maïto PLIST_ENTRY DiskListEntry; 18366f19c83bSHermès Bélusca-Maïto PLIST_ENTRY PartListEntry; 18376f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 18386f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 18396f19c83bSHermès Bélusca-Maïto 18406f19c83bSHermès Bélusca-Maïto /* Fail if no disks are available */ 18416f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&List->DiskListHead)) 18426f19c83bSHermès Bélusca-Maïto return NULL; 18436f19c83bSHermès Bélusca-Maïto 18446f19c83bSHermès Bélusca-Maïto /* Check for next usable entry on current disk */ 18456f19c83bSHermès Bélusca-Maïto if (List->CurrentPartition != NULL) 18466f19c83bSHermès Bélusca-Maïto { 18476f19c83bSHermès Bélusca-Maïto if (List->CurrentPartition->LogicalPartition) 18486f19c83bSHermès Bélusca-Maïto { 18496f19c83bSHermès Bélusca-Maïto /* Logical partition */ 18506f19c83bSHermès Bélusca-Maïto 18516f19c83bSHermès Bélusca-Maïto PartListEntry = List->CurrentPartition->ListEntry.Flink; 18526f19c83bSHermès Bélusca-Maïto if (PartListEntry != &List->CurrentDisk->LogicalPartListHead) 18536f19c83bSHermès Bélusca-Maïto { 18546f19c83bSHermès Bélusca-Maïto /* Next logical partition */ 18556f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 18566f19c83bSHermès Bélusca-Maïto 18576f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 18586f19c83bSHermès Bélusca-Maïto return List->CurrentPartition; 18596f19c83bSHermès Bélusca-Maïto } 18606f19c83bSHermès Bélusca-Maïto else 18616f19c83bSHermès Bélusca-Maïto { 18626f19c83bSHermès Bélusca-Maïto PartListEntry = List->CurrentDisk->ExtendedPartition->ListEntry.Flink; 18636f19c83bSHermès Bélusca-Maïto if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead) 18646f19c83bSHermès Bélusca-Maïto { 18656f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 18666f19c83bSHermès Bélusca-Maïto 18676f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 18686f19c83bSHermès Bélusca-Maïto return List->CurrentPartition; 18696f19c83bSHermès Bélusca-Maïto } 18706f19c83bSHermès Bélusca-Maïto } 18716f19c83bSHermès Bélusca-Maïto } 18726f19c83bSHermès Bélusca-Maïto else 18736f19c83bSHermès Bélusca-Maïto { 18746f19c83bSHermès Bélusca-Maïto /* Primary or extended partition */ 18756f19c83bSHermès Bélusca-Maïto 18766f19c83bSHermès Bélusca-Maïto if ((List->CurrentPartition->IsPartitioned != FALSE) && 18776f19c83bSHermès Bélusca-Maïto IsContainerPartition(List->CurrentPartition->PartitionType)) 18786f19c83bSHermès Bélusca-Maïto { 18796f19c83bSHermès Bélusca-Maïto /* First logical partition */ 18806f19c83bSHermès Bélusca-Maïto PartListEntry = List->CurrentDisk->LogicalPartListHead.Flink; 18816f19c83bSHermès Bélusca-Maïto if (PartListEntry != &List->CurrentDisk->LogicalPartListHead) 18826f19c83bSHermès Bélusca-Maïto { 18836f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 18846f19c83bSHermès Bélusca-Maïto 18856f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 18866f19c83bSHermès Bélusca-Maïto return List->CurrentPartition; 18876f19c83bSHermès Bélusca-Maïto } 18886f19c83bSHermès Bélusca-Maïto } 18896f19c83bSHermès Bélusca-Maïto else 18906f19c83bSHermès Bélusca-Maïto { 18916f19c83bSHermès Bélusca-Maïto /* Next primary partition */ 18926f19c83bSHermès Bélusca-Maïto PartListEntry = List->CurrentPartition->ListEntry.Flink; 18936f19c83bSHermès Bélusca-Maïto if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead) 18946f19c83bSHermès Bélusca-Maïto { 18956f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 18966f19c83bSHermès Bélusca-Maïto 18976f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 18986f19c83bSHermès Bélusca-Maïto return List->CurrentPartition; 18996f19c83bSHermès Bélusca-Maïto } 19006f19c83bSHermès Bélusca-Maïto } 19016f19c83bSHermès Bélusca-Maïto } 19026f19c83bSHermès Bélusca-Maïto } 19036f19c83bSHermès Bélusca-Maïto 19046f19c83bSHermès Bélusca-Maïto /* Search for the first partition entry on the next disk */ 19056f19c83bSHermès Bélusca-Maïto DiskListEntry = List->CurrentDisk->ListEntry.Flink; 19066f19c83bSHermès Bélusca-Maïto while (DiskListEntry != &List->DiskListHead) 19076f19c83bSHermès Bélusca-Maïto { 19086f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry); 19096f19c83bSHermès Bélusca-Maïto 19106f19c83bSHermès Bélusca-Maïto PartListEntry = DiskEntry->PrimaryPartListHead.Flink; 19116f19c83bSHermès Bélusca-Maïto if (PartListEntry != &DiskEntry->PrimaryPartListHead) 19126f19c83bSHermès Bélusca-Maïto { 19136f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 19146f19c83bSHermès Bélusca-Maïto 19156f19c83bSHermès Bélusca-Maïto List->CurrentDisk = DiskEntry; 19166f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 19176f19c83bSHermès Bélusca-Maïto return List->CurrentPartition; 19186f19c83bSHermès Bélusca-Maïto } 19196f19c83bSHermès Bélusca-Maïto 19206f19c83bSHermès Bélusca-Maïto DiskListEntry = DiskListEntry->Flink; 19216f19c83bSHermès Bélusca-Maïto } 19226f19c83bSHermès Bélusca-Maïto 19236f19c83bSHermès Bélusca-Maïto return NULL; 19246f19c83bSHermès Bélusca-Maïto } 19256f19c83bSHermès Bélusca-Maïto 19266f19c83bSHermès Bélusca-Maïto PPARTENTRY 19276f19c83bSHermès Bélusca-Maïto GetPrevPartition( 19286f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 19296f19c83bSHermès Bélusca-Maïto { 19306f19c83bSHermès Bélusca-Maïto PLIST_ENTRY DiskListEntry; 19316f19c83bSHermès Bélusca-Maïto PLIST_ENTRY PartListEntry; 19326f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 19336f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 19346f19c83bSHermès Bélusca-Maïto 19356f19c83bSHermès Bélusca-Maïto /* Fail if no disks are available */ 19366f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&List->DiskListHead)) 19376f19c83bSHermès Bélusca-Maïto return NULL; 19386f19c83bSHermès Bélusca-Maïto 19396f19c83bSHermès Bélusca-Maïto /* Check for previous usable entry on current disk */ 19406f19c83bSHermès Bélusca-Maïto if (List->CurrentPartition != NULL) 19416f19c83bSHermès Bélusca-Maïto { 19426f19c83bSHermès Bélusca-Maïto if (List->CurrentPartition->LogicalPartition) 19436f19c83bSHermès Bélusca-Maïto { 19446f19c83bSHermès Bélusca-Maïto /* Logical partition */ 19456f19c83bSHermès Bélusca-Maïto PartListEntry = List->CurrentPartition->ListEntry.Blink; 19466f19c83bSHermès Bélusca-Maïto if (PartListEntry != &List->CurrentDisk->LogicalPartListHead) 19476f19c83bSHermès Bélusca-Maïto { 19486f19c83bSHermès Bélusca-Maïto /* Previous logical partition */ 19496f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 19506f19c83bSHermès Bélusca-Maïto } 19516f19c83bSHermès Bélusca-Maïto else 19526f19c83bSHermès Bélusca-Maïto { 19536f19c83bSHermès Bélusca-Maïto /* Extended partition */ 19546f19c83bSHermès Bélusca-Maïto PartEntry = List->CurrentDisk->ExtendedPartition; 19556f19c83bSHermès Bélusca-Maïto } 19566f19c83bSHermès Bélusca-Maïto 19576f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 19586f19c83bSHermès Bélusca-Maïto return List->CurrentPartition; 19596f19c83bSHermès Bélusca-Maïto } 19606f19c83bSHermès Bélusca-Maïto else 19616f19c83bSHermès Bélusca-Maïto { 19626f19c83bSHermès Bélusca-Maïto /* Primary or extended partition */ 19636f19c83bSHermès Bélusca-Maïto 19646f19c83bSHermès Bélusca-Maïto PartListEntry = List->CurrentPartition->ListEntry.Blink; 19656f19c83bSHermès Bélusca-Maïto if (PartListEntry != &List->CurrentDisk->PrimaryPartListHead) 19666f19c83bSHermès Bélusca-Maïto { 19676f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 19686f19c83bSHermès Bélusca-Maïto 19696f19c83bSHermès Bélusca-Maïto if ((PartEntry->IsPartitioned != FALSE) && 19706f19c83bSHermès Bélusca-Maïto IsContainerPartition(PartEntry->PartitionType)) 19716f19c83bSHermès Bélusca-Maïto { 19726f19c83bSHermès Bélusca-Maïto PartListEntry = List->CurrentDisk->LogicalPartListHead.Blink; 19736f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 19746f19c83bSHermès Bélusca-Maïto } 19756f19c83bSHermès Bélusca-Maïto 19766f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 19776f19c83bSHermès Bélusca-Maïto return List->CurrentPartition; 19786f19c83bSHermès Bélusca-Maïto } 19796f19c83bSHermès Bélusca-Maïto } 19806f19c83bSHermès Bélusca-Maïto } 19816f19c83bSHermès Bélusca-Maïto 19826f19c83bSHermès Bélusca-Maïto /* Search for the last partition entry on the previous disk */ 19836f19c83bSHermès Bélusca-Maïto DiskListEntry = List->CurrentDisk->ListEntry.Blink; 19846f19c83bSHermès Bélusca-Maïto while (DiskListEntry != &List->DiskListHead) 19856f19c83bSHermès Bélusca-Maïto { 19866f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry); 19876f19c83bSHermès Bélusca-Maïto 19886f19c83bSHermès Bélusca-Maïto PartListEntry = DiskEntry->PrimaryPartListHead.Blink; 19896f19c83bSHermès Bélusca-Maïto if (PartListEntry != &DiskEntry->PrimaryPartListHead) 19906f19c83bSHermès Bélusca-Maïto { 19916f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 19926f19c83bSHermès Bélusca-Maïto 19936f19c83bSHermès Bélusca-Maïto if ((PartEntry->IsPartitioned != FALSE) && 19946f19c83bSHermès Bélusca-Maïto IsContainerPartition(PartEntry->PartitionType)) 19956f19c83bSHermès Bélusca-Maïto { 19966f19c83bSHermès Bélusca-Maïto PartListEntry = DiskEntry->LogicalPartListHead.Blink; 19976f19c83bSHermès Bélusca-Maïto if (PartListEntry != &DiskEntry->LogicalPartListHead) 19986f19c83bSHermès Bélusca-Maïto { 19996f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry); 20006f19c83bSHermès Bélusca-Maïto 20016f19c83bSHermès Bélusca-Maïto List->CurrentDisk = DiskEntry; 20026f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 20036f19c83bSHermès Bélusca-Maïto return List->CurrentPartition; 20046f19c83bSHermès Bélusca-Maïto } 20056f19c83bSHermès Bélusca-Maïto } 20066f19c83bSHermès Bélusca-Maïto else 20076f19c83bSHermès Bélusca-Maïto { 20086f19c83bSHermès Bélusca-Maïto List->CurrentDisk = DiskEntry; 20096f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PartEntry; 20106f19c83bSHermès Bélusca-Maïto return List->CurrentPartition; 20116f19c83bSHermès Bélusca-Maïto } 20126f19c83bSHermès Bélusca-Maïto } 20136f19c83bSHermès Bélusca-Maïto 20146f19c83bSHermès Bélusca-Maïto DiskListEntry = DiskListEntry->Blink; 20156f19c83bSHermès Bélusca-Maïto } 20166f19c83bSHermès Bélusca-Maïto 20176f19c83bSHermès Bélusca-Maïto return NULL; 20186f19c83bSHermès Bélusca-Maïto } 20196f19c83bSHermès Bélusca-Maïto 20206f19c83bSHermès Bélusca-Maïto // static 20216f19c83bSHermès Bélusca-Maïto FORCEINLINE 20226f19c83bSHermès Bélusca-Maïto BOOLEAN 20236f19c83bSHermès Bélusca-Maïto IsEmptyLayoutEntry( 20246f19c83bSHermès Bélusca-Maïto IN PPARTITION_INFORMATION PartitionInfo) 20256f19c83bSHermès Bélusca-Maïto { 20266f19c83bSHermès Bélusca-Maïto if (PartitionInfo->StartingOffset.QuadPart == 0 && 20276f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart == 0) 20286f19c83bSHermès Bélusca-Maïto { 20296f19c83bSHermès Bélusca-Maïto return TRUE; 20306f19c83bSHermès Bélusca-Maïto } 20316f19c83bSHermès Bélusca-Maïto 20326f19c83bSHermès Bélusca-Maïto return FALSE; 20336f19c83bSHermès Bélusca-Maïto } 20346f19c83bSHermès Bélusca-Maïto 20356f19c83bSHermès Bélusca-Maïto // static 20366f19c83bSHermès Bélusca-Maïto FORCEINLINE 20376f19c83bSHermès Bélusca-Maïto BOOLEAN 20386f19c83bSHermès Bélusca-Maïto IsSamePrimaryLayoutEntry( 20396f19c83bSHermès Bélusca-Maïto IN PPARTITION_INFORMATION PartitionInfo, 20406f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry, 20416f19c83bSHermès Bélusca-Maïto IN PPARTENTRY PartEntry) 20426f19c83bSHermès Bélusca-Maïto { 20436f19c83bSHermès Bélusca-Maïto if (PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector && 20446f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) 20456f19c83bSHermès Bélusca-Maïto // PartitionInfo->PartitionNumber = PartEntry->PartitionNumber && 20466f19c83bSHermès Bélusca-Maïto // PartitionInfo->PartitionType == PartEntry->PartitionType 20476f19c83bSHermès Bélusca-Maïto { 20486f19c83bSHermès Bélusca-Maïto return TRUE; 20496f19c83bSHermès Bélusca-Maïto } 20506f19c83bSHermès Bélusca-Maïto 20516f19c83bSHermès Bélusca-Maïto return FALSE; 20526f19c83bSHermès Bélusca-Maïto } 20536f19c83bSHermès Bélusca-Maïto 20546f19c83bSHermès Bélusca-Maïto static 20556f19c83bSHermès Bélusca-Maïto ULONG 20566f19c83bSHermès Bélusca-Maïto GetPrimaryPartitionCount( 20576f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry) 20586f19c83bSHermès Bélusca-Maïto { 20596f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 20606f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 20616f19c83bSHermès Bélusca-Maïto ULONG Count = 0; 20626f19c83bSHermès Bélusca-Maïto 20636f19c83bSHermès Bélusca-Maïto Entry = DiskEntry->PrimaryPartListHead.Flink; 20646f19c83bSHermès Bélusca-Maïto while (Entry != &DiskEntry->PrimaryPartListHead) 20656f19c83bSHermès Bélusca-Maïto { 20666f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 20676f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned) 20686f19c83bSHermès Bélusca-Maïto Count++; 20696f19c83bSHermès Bélusca-Maïto 20706f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 20716f19c83bSHermès Bélusca-Maïto } 20726f19c83bSHermès Bélusca-Maïto 20736f19c83bSHermès Bélusca-Maïto return Count; 20746f19c83bSHermès Bélusca-Maïto } 20756f19c83bSHermès Bélusca-Maïto 20766f19c83bSHermès Bélusca-Maïto static 20776f19c83bSHermès Bélusca-Maïto ULONG 20786f19c83bSHermès Bélusca-Maïto GetLogicalPartitionCount( 20796f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry) 20806f19c83bSHermès Bélusca-Maïto { 20816f19c83bSHermès Bélusca-Maïto PLIST_ENTRY ListEntry; 20826f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 20836f19c83bSHermès Bélusca-Maïto ULONG Count = 0; 20846f19c83bSHermès Bélusca-Maïto 20856f19c83bSHermès Bélusca-Maïto ListEntry = DiskEntry->LogicalPartListHead.Flink; 20866f19c83bSHermès Bélusca-Maïto while (ListEntry != &DiskEntry->LogicalPartListHead) 20876f19c83bSHermès Bélusca-Maïto { 20886f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); 20896f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned) 20906f19c83bSHermès Bélusca-Maïto Count++; 20916f19c83bSHermès Bélusca-Maïto 20926f19c83bSHermès Bélusca-Maïto ListEntry = ListEntry->Flink; 20936f19c83bSHermès Bélusca-Maïto } 20946f19c83bSHermès Bélusca-Maïto 20956f19c83bSHermès Bélusca-Maïto return Count; 20966f19c83bSHermès Bélusca-Maïto } 20976f19c83bSHermès Bélusca-Maïto 20986f19c83bSHermès Bélusca-Maïto static 20996f19c83bSHermès Bélusca-Maïto BOOLEAN 21006f19c83bSHermès Bélusca-Maïto ReAllocateLayoutBuffer( 21016f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry) 21026f19c83bSHermès Bélusca-Maïto { 21036f19c83bSHermès Bélusca-Maïto PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer; 21046f19c83bSHermès Bélusca-Maïto ULONG NewPartitionCount; 21056f19c83bSHermès Bélusca-Maïto ULONG CurrentPartitionCount = 0; 21066f19c83bSHermès Bélusca-Maïto ULONG LayoutBufferSize; 21076f19c83bSHermès Bélusca-Maïto ULONG i; 21086f19c83bSHermès Bélusca-Maïto 21096f19c83bSHermès Bélusca-Maïto DPRINT1("ReAllocateLayoutBuffer()\n"); 21106f19c83bSHermès Bélusca-Maïto 21116f19c83bSHermès Bélusca-Maïto NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4; 21126f19c83bSHermès Bélusca-Maïto 21136f19c83bSHermès Bélusca-Maïto if (DiskEntry->LayoutBuffer) 21146f19c83bSHermès Bélusca-Maïto CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount; 21156f19c83bSHermès Bélusca-Maïto 21166f19c83bSHermès Bélusca-Maïto DPRINT1("CurrentPartitionCount: %lu NewPartitionCount: %lu\n", 21176f19c83bSHermès Bélusca-Maïto CurrentPartitionCount, NewPartitionCount); 21186f19c83bSHermès Bélusca-Maïto 21196f19c83bSHermès Bélusca-Maïto if (CurrentPartitionCount == NewPartitionCount) 21206f19c83bSHermès Bélusca-Maïto return TRUE; 21216f19c83bSHermès Bélusca-Maïto 21226f19c83bSHermès Bélusca-Maïto LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + 21236f19c83bSHermès Bélusca-Maïto ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); 21246f19c83bSHermès Bélusca-Maïto NewLayoutBuffer = RtlReAllocateHeap(ProcessHeap, 21256f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 21266f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer, 21276f19c83bSHermès Bélusca-Maïto LayoutBufferSize); 21286f19c83bSHermès Bélusca-Maïto if (NewLayoutBuffer == NULL) 21296f19c83bSHermès Bélusca-Maïto { 21306f19c83bSHermès Bélusca-Maïto DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize); 21316f19c83bSHermès Bélusca-Maïto return FALSE; 21326f19c83bSHermès Bélusca-Maïto } 21336f19c83bSHermès Bélusca-Maïto 21346f19c83bSHermès Bélusca-Maïto /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */ 21356f19c83bSHermès Bélusca-Maïto if (NewPartitionCount > CurrentPartitionCount) 21366f19c83bSHermès Bélusca-Maïto { 21376f19c83bSHermès Bélusca-Maïto for (i = CurrentPartitionCount; i < NewPartitionCount; i++) 21386f19c83bSHermès Bélusca-Maïto NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE; 21396f19c83bSHermès Bélusca-Maïto } 21406f19c83bSHermès Bélusca-Maïto 21416f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer = NewLayoutBuffer; 21426f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionCount = NewPartitionCount; 21436f19c83bSHermès Bélusca-Maïto 21446f19c83bSHermès Bélusca-Maïto return TRUE; 21456f19c83bSHermès Bélusca-Maïto } 21466f19c83bSHermès Bélusca-Maïto 21476f19c83bSHermès Bélusca-Maïto static 21486f19c83bSHermès Bélusca-Maïto VOID 21496f19c83bSHermès Bélusca-Maïto UpdateDiskLayout( 21506f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry) 21516f19c83bSHermès Bélusca-Maïto { 21526f19c83bSHermès Bélusca-Maïto PPARTITION_INFORMATION PartitionInfo; 21536f19c83bSHermès Bélusca-Maïto PPARTITION_INFORMATION LinkInfo = NULL; 21546f19c83bSHermès Bélusca-Maïto PLIST_ENTRY ListEntry; 21556f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 21566f19c83bSHermès Bélusca-Maïto LARGE_INTEGER HiddenSectors64; 21576f19c83bSHermès Bélusca-Maïto ULONG Index; 21586f19c83bSHermès Bélusca-Maïto ULONG PartitionNumber = 1; 21596f19c83bSHermès Bélusca-Maïto 21606f19c83bSHermès Bélusca-Maïto DPRINT1("UpdateDiskLayout()\n"); 21616f19c83bSHermès Bélusca-Maïto 21626f19c83bSHermès Bélusca-Maïto /* Resize the layout buffer if necessary */ 21636f19c83bSHermès Bélusca-Maïto if (ReAllocateLayoutBuffer(DiskEntry) == FALSE) 21646f19c83bSHermès Bélusca-Maïto { 21656f19c83bSHermès Bélusca-Maïto DPRINT("ReAllocateLayoutBuffer() failed.\n"); 21666f19c83bSHermès Bélusca-Maïto return; 21676f19c83bSHermès Bélusca-Maïto } 21686f19c83bSHermès Bélusca-Maïto 21696f19c83bSHermès Bélusca-Maïto /* Update the primary partition table */ 21706f19c83bSHermès Bélusca-Maïto Index = 0; 21716f19c83bSHermès Bélusca-Maïto ListEntry = DiskEntry->PrimaryPartListHead.Flink; 21726f19c83bSHermès Bélusca-Maïto while (ListEntry != &DiskEntry->PrimaryPartListHead) 21736f19c83bSHermès Bélusca-Maïto { 21746f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); 21756f19c83bSHermès Bélusca-Maïto 21766f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned != FALSE) 21776f19c83bSHermès Bélusca-Maïto { 21786f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; 21796f19c83bSHermès Bélusca-Maïto 21806f19c83bSHermès Bélusca-Maïto if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry)) 21816f19c83bSHermès Bélusca-Maïto { 21826f19c83bSHermès Bélusca-Maïto DPRINT1("Updating primary partition entry %lu\n", Index); 21836f19c83bSHermès Bélusca-Maïto 21846f19c83bSHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; 21856f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; 21866f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors = PartEntry->StartSector.LowPart; 21876f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionNumber = (!IsContainerPartition(PartEntry->PartitionType)) ? PartitionNumber : 0; 21886f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType = PartEntry->PartitionType; 21896f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator = PartEntry->BootIndicator; 21906f19c83bSHermès Bélusca-Maïto PartitionInfo->RecognizedPartition = FALSE; 21916f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition = TRUE; 21926f19c83bSHermès Bélusca-Maïto } 21936f19c83bSHermès Bélusca-Maïto 21946f19c83bSHermès Bélusca-Maïto PartEntry->PartitionNumber = (!IsContainerPartition(PartEntry->PartitionType)) ? PartitionNumber : 0; 21956f19c83bSHermès Bélusca-Maïto PartEntry->PartitionIndex = Index; 21966f19c83bSHermès Bélusca-Maïto 21976f19c83bSHermès Bélusca-Maïto if (!IsContainerPartition(PartEntry->PartitionType)) 21986f19c83bSHermès Bélusca-Maïto PartitionNumber++; 21996f19c83bSHermès Bélusca-Maïto 22006f19c83bSHermès Bélusca-Maïto Index++; 22016f19c83bSHermès Bélusca-Maïto } 22026f19c83bSHermès Bélusca-Maïto 22036f19c83bSHermès Bélusca-Maïto ListEntry = ListEntry->Flink; 22046f19c83bSHermès Bélusca-Maïto } 22056f19c83bSHermès Bélusca-Maïto 22066f19c83bSHermès Bélusca-Maïto /* Update the logical partition table */ 22076f19c83bSHermès Bélusca-Maïto Index = 4; 22086f19c83bSHermès Bélusca-Maïto ListEntry = DiskEntry->LogicalPartListHead.Flink; 22096f19c83bSHermès Bélusca-Maïto while (ListEntry != &DiskEntry->LogicalPartListHead) 22106f19c83bSHermès Bélusca-Maïto { 22116f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry); 22126f19c83bSHermès Bélusca-Maïto 22136f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned) 22146f19c83bSHermès Bélusca-Maïto { 22156f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; 22166f19c83bSHermès Bélusca-Maïto 22176f19c83bSHermès Bélusca-Maïto DPRINT1("Updating logical partition entry %lu\n", Index); 22186f19c83bSHermès Bélusca-Maïto 22196f19c83bSHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; 22206f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; 22216f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors = DiskEntry->SectorAlignment; 22226f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionNumber = PartitionNumber; 22236f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType = PartEntry->PartitionType; 22246f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator = FALSE; 22256f19c83bSHermès Bélusca-Maïto PartitionInfo->RecognizedPartition = FALSE; 22266f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition = TRUE; 22276f19c83bSHermès Bélusca-Maïto 22286f19c83bSHermès Bélusca-Maïto PartEntry->PartitionNumber = PartitionNumber; 22296f19c83bSHermès Bélusca-Maïto PartEntry->PartitionIndex = Index; 22306f19c83bSHermès Bélusca-Maïto 22316f19c83bSHermès Bélusca-Maïto /* Fill the link entry of the previous partition entry */ 22326f19c83bSHermès Bélusca-Maïto if (LinkInfo != NULL) 22336f19c83bSHermès Bélusca-Maïto { 22346f19c83bSHermès Bélusca-Maïto LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector; 22356f19c83bSHermès Bélusca-Maïto LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector; 22366f19c83bSHermès Bélusca-Maïto HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart; 22376f19c83bSHermès Bélusca-Maïto LinkInfo->HiddenSectors = HiddenSectors64.LowPart; 22386f19c83bSHermès Bélusca-Maïto LinkInfo->PartitionNumber = 0; 22396f19c83bSHermès Bélusca-Maïto LinkInfo->PartitionType = PARTITION_EXTENDED; 22406f19c83bSHermès Bélusca-Maïto LinkInfo->BootIndicator = FALSE; 22416f19c83bSHermès Bélusca-Maïto LinkInfo->RecognizedPartition = FALSE; 22426f19c83bSHermès Bélusca-Maïto LinkInfo->RewritePartition = TRUE; 22436f19c83bSHermès Bélusca-Maïto } 22446f19c83bSHermès Bélusca-Maïto 22456f19c83bSHermès Bélusca-Maïto /* Save a pointer to the link entry of the current partition entry */ 22466f19c83bSHermès Bélusca-Maïto LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1]; 22476f19c83bSHermès Bélusca-Maïto 22486f19c83bSHermès Bélusca-Maïto PartitionNumber++; 22496f19c83bSHermès Bélusca-Maïto Index += 4; 22506f19c83bSHermès Bélusca-Maïto } 22516f19c83bSHermès Bélusca-Maïto 22526f19c83bSHermès Bélusca-Maïto ListEntry = ListEntry->Flink; 22536f19c83bSHermès Bélusca-Maïto } 22546f19c83bSHermès Bélusca-Maïto 22556f19c83bSHermès Bélusca-Maïto /* Wipe unused primary partition entries */ 22566f19c83bSHermès Bélusca-Maïto for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++) 22576f19c83bSHermès Bélusca-Maïto { 22586f19c83bSHermès Bélusca-Maïto DPRINT1("Primary partition entry %lu\n", Index); 22596f19c83bSHermès Bélusca-Maïto 22606f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; 22616f19c83bSHermès Bélusca-Maïto 22626f19c83bSHermès Bélusca-Maïto if (!IsEmptyLayoutEntry(PartitionInfo)) 22636f19c83bSHermès Bélusca-Maïto { 22646f19c83bSHermès Bélusca-Maïto DPRINT1("Wiping primary partition entry %lu\n", Index); 22656f19c83bSHermès Bélusca-Maïto 22666f19c83bSHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart = 0; 22676f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart = 0; 22686f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors = 0; 22696f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionNumber = 0; 22706f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED; 22716f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator = FALSE; 22726f19c83bSHermès Bélusca-Maïto PartitionInfo->RecognizedPartition = FALSE; 22736f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition = TRUE; 22746f19c83bSHermès Bélusca-Maïto } 22756f19c83bSHermès Bélusca-Maïto } 22766f19c83bSHermès Bélusca-Maïto 22776f19c83bSHermès Bélusca-Maïto /* Wipe unused logical partition entries */ 22786f19c83bSHermès Bélusca-Maïto for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++) 22796f19c83bSHermès Bélusca-Maïto { 22806f19c83bSHermès Bélusca-Maïto if (Index % 4 >= 2) 22816f19c83bSHermès Bélusca-Maïto { 22826f19c83bSHermès Bélusca-Maïto DPRINT1("Logical partition entry %lu\n", Index); 22836f19c83bSHermès Bélusca-Maïto 22846f19c83bSHermès Bélusca-Maïto PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index]; 22856f19c83bSHermès Bélusca-Maïto 22866f19c83bSHermès Bélusca-Maïto if (!IsEmptyLayoutEntry(PartitionInfo)) 22876f19c83bSHermès Bélusca-Maïto { 22886f19c83bSHermès Bélusca-Maïto DPRINT1("Wiping partition entry %lu\n", Index); 22896f19c83bSHermès Bélusca-Maïto 22906f19c83bSHermès Bélusca-Maïto PartitionInfo->StartingOffset.QuadPart = 0; 22916f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionLength.QuadPart = 0; 22926f19c83bSHermès Bélusca-Maïto PartitionInfo->HiddenSectors = 0; 22936f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionNumber = 0; 22946f19c83bSHermès Bélusca-Maïto PartitionInfo->PartitionType = PARTITION_ENTRY_UNUSED; 22956f19c83bSHermès Bélusca-Maïto PartitionInfo->BootIndicator = FALSE; 22966f19c83bSHermès Bélusca-Maïto PartitionInfo->RecognizedPartition = FALSE; 22976f19c83bSHermès Bélusca-Maïto PartitionInfo->RewritePartition = TRUE; 22986f19c83bSHermès Bélusca-Maïto } 22996f19c83bSHermès Bélusca-Maïto } 23006f19c83bSHermès Bélusca-Maïto } 23016f19c83bSHermès Bélusca-Maïto 23026f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE 23036f19c83bSHermès Bélusca-Maïto DumpPartitionTable(DiskEntry); 23046f19c83bSHermès Bélusca-Maïto #endif 23056f19c83bSHermès Bélusca-Maïto } 23066f19c83bSHermès Bélusca-Maïto 23076f19c83bSHermès Bélusca-Maïto static 23086f19c83bSHermès Bélusca-Maïto PPARTENTRY 23096f19c83bSHermès Bélusca-Maïto GetPrevUnpartitionedEntry( 23106f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry, 23116f19c83bSHermès Bélusca-Maïto IN PPARTENTRY PartEntry) 23126f19c83bSHermès Bélusca-Maïto { 23136f19c83bSHermès Bélusca-Maïto PPARTENTRY PrevPartEntry; 23146f19c83bSHermès Bélusca-Maïto PLIST_ENTRY ListHead; 23156f19c83bSHermès Bélusca-Maïto 23166f19c83bSHermès Bélusca-Maïto if (PartEntry->LogicalPartition) 23176f19c83bSHermès Bélusca-Maïto ListHead = &DiskEntry->LogicalPartListHead; 23186f19c83bSHermès Bélusca-Maïto else 23196f19c83bSHermès Bélusca-Maïto ListHead = &DiskEntry->PrimaryPartListHead; 23206f19c83bSHermès Bélusca-Maïto 23216f19c83bSHermès Bélusca-Maïto if (PartEntry->ListEntry.Blink != ListHead) 23226f19c83bSHermès Bélusca-Maïto { 23236f19c83bSHermès Bélusca-Maïto PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink, 23246f19c83bSHermès Bélusca-Maïto PARTENTRY, 23256f19c83bSHermès Bélusca-Maïto ListEntry); 23266f19c83bSHermès Bélusca-Maïto if (PrevPartEntry->IsPartitioned == FALSE) 23276f19c83bSHermès Bélusca-Maïto return PrevPartEntry; 23286f19c83bSHermès Bélusca-Maïto } 23296f19c83bSHermès Bélusca-Maïto 23306f19c83bSHermès Bélusca-Maïto return NULL; 23316f19c83bSHermès Bélusca-Maïto } 23326f19c83bSHermès Bélusca-Maïto 23336f19c83bSHermès Bélusca-Maïto static 23346f19c83bSHermès Bélusca-Maïto PPARTENTRY 23356f19c83bSHermès Bélusca-Maïto GetNextUnpartitionedEntry( 23366f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry, 23376f19c83bSHermès Bélusca-Maïto IN PPARTENTRY PartEntry) 23386f19c83bSHermès Bélusca-Maïto { 23396f19c83bSHermès Bélusca-Maïto PPARTENTRY NextPartEntry; 23406f19c83bSHermès Bélusca-Maïto PLIST_ENTRY ListHead; 23416f19c83bSHermès Bélusca-Maïto 23426f19c83bSHermès Bélusca-Maïto if (PartEntry->LogicalPartition) 23436f19c83bSHermès Bélusca-Maïto ListHead = &DiskEntry->LogicalPartListHead; 23446f19c83bSHermès Bélusca-Maïto else 23456f19c83bSHermès Bélusca-Maïto ListHead = &DiskEntry->PrimaryPartListHead; 23466f19c83bSHermès Bélusca-Maïto 23476f19c83bSHermès Bélusca-Maïto if (PartEntry->ListEntry.Flink != ListHead) 23486f19c83bSHermès Bélusca-Maïto { 23496f19c83bSHermès Bélusca-Maïto NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink, 23506f19c83bSHermès Bélusca-Maïto PARTENTRY, 23516f19c83bSHermès Bélusca-Maïto ListEntry); 23526f19c83bSHermès Bélusca-Maïto if (NextPartEntry->IsPartitioned == FALSE) 23536f19c83bSHermès Bélusca-Maïto return NextPartEntry; 23546f19c83bSHermès Bélusca-Maïto } 23556f19c83bSHermès Bélusca-Maïto 23566f19c83bSHermès Bélusca-Maïto return NULL; 23576f19c83bSHermès Bélusca-Maïto } 23586f19c83bSHermès Bélusca-Maïto 23596f19c83bSHermès Bélusca-Maïto VOID 23606f19c83bSHermès Bélusca-Maïto CreatePrimaryPartition( 23616f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 23626f19c83bSHermès Bélusca-Maïto IN ULONGLONG SectorCount, 23636f19c83bSHermès Bélusca-Maïto IN BOOLEAN AutoCreate) 23646f19c83bSHermès Bélusca-Maïto { 23656f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 23666f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 23676f19c83bSHermès Bélusca-Maïto PPARTENTRY NewPartEntry; 23686f19c83bSHermès Bélusca-Maïto 23696f19c83bSHermès Bélusca-Maïto DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount); 23706f19c83bSHermès Bélusca-Maïto 23716f19c83bSHermès Bélusca-Maïto if (List == NULL || 23726f19c83bSHermès Bélusca-Maïto List->CurrentDisk == NULL || 23736f19c83bSHermès Bélusca-Maïto List->CurrentPartition == NULL || 23746f19c83bSHermès Bélusca-Maïto List->CurrentPartition->IsPartitioned != FALSE) 23756f19c83bSHermès Bélusca-Maïto { 23766f19c83bSHermès Bélusca-Maïto return; 23776f19c83bSHermès Bélusca-Maïto } 23786f19c83bSHermès Bélusca-Maïto 23796f19c83bSHermès Bélusca-Maïto DiskEntry = List->CurrentDisk; 23806f19c83bSHermès Bélusca-Maïto PartEntry = List->CurrentPartition; 23816f19c83bSHermès Bélusca-Maïto 23826f19c83bSHermès Bélusca-Maïto DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); 23836f19c83bSHermès Bélusca-Maïto 23846f19c83bSHermès Bélusca-Maïto if ((AutoCreate != FALSE) || 23856f19c83bSHermès Bélusca-Maïto (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart)) 23866f19c83bSHermès Bélusca-Maïto { 23876f19c83bSHermès Bélusca-Maïto DPRINT1("Convert existing partition entry\n"); 23886f19c83bSHermès Bélusca-Maïto 23896f19c83bSHermès Bélusca-Maïto /* Convert current entry to 'new (unformatted)' */ 23906f19c83bSHermès Bélusca-Maïto PartEntry->IsPartitioned = TRUE; 23916f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType = PARTITION_ENTRY_UNUSED; 23926f19c83bSHermès Bélusca-Maïto PartEntry->FormatState = Unformatted; 23936f19c83bSHermès Bélusca-Maïto PartEntry->FileSystem = NULL; 23946f19c83bSHermès Bélusca-Maïto PartEntry->AutoCreate = AutoCreate; 23956f19c83bSHermès Bélusca-Maïto PartEntry->New = TRUE; 23966f19c83bSHermès Bélusca-Maïto PartEntry->BootIndicator = FALSE; 23976f19c83bSHermès Bélusca-Maïto 23986f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart); 23996f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1); 24006f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart); 24016f19c83bSHermès Bélusca-Maïto } 24026f19c83bSHermès Bélusca-Maïto else 24036f19c83bSHermès Bélusca-Maïto { 24046f19c83bSHermès Bélusca-Maïto DPRINT1("Add new partition entry\n"); 24056f19c83bSHermès Bélusca-Maïto 24066f19c83bSHermès Bélusca-Maïto /* Insert and initialize a new partition entry */ 24076f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 24086f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 24096f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 24106f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 24116f19c83bSHermès Bélusca-Maïto return; 24126f19c83bSHermès Bélusca-Maïto 24136f19c83bSHermès Bélusca-Maïto /* Insert the new entry into the list */ 24146f19c83bSHermès Bélusca-Maïto InsertTailList(&PartEntry->ListEntry, 24156f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 24166f19c83bSHermès Bélusca-Maïto 24176f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 24186f19c83bSHermès Bélusca-Maïto 24196f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = TRUE; 24206f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; 24216f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - 24226f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart; 24236f19c83bSHermès Bélusca-Maïto NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED; 24246f19c83bSHermès Bélusca-Maïto 24256f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 24266f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 24276f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 24286f19c83bSHermès Bélusca-Maïto 24296f19c83bSHermès Bélusca-Maïto NewPartEntry->New = TRUE; 24306f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Unformatted; 24316f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 24326f19c83bSHermès Bélusca-Maïto NewPartEntry->BootIndicator = FALSE; 24336f19c83bSHermès Bélusca-Maïto 24346f19c83bSHermès Bélusca-Maïto PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; 24356f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart); 24366f19c83bSHermès Bélusca-Maïto } 24376f19c83bSHermès Bélusca-Maïto 24386f19c83bSHermès Bélusca-Maïto UpdateDiskLayout(DiskEntry); 24396f19c83bSHermès Bélusca-Maïto 24406f19c83bSHermès Bélusca-Maïto DiskEntry->Dirty = TRUE; 24416f19c83bSHermès Bélusca-Maïto 24426f19c83bSHermès Bélusca-Maïto AssignDriveLetters(List); 24436f19c83bSHermès Bélusca-Maïto } 24446f19c83bSHermès Bélusca-Maïto 24456f19c83bSHermès Bélusca-Maïto static 24466f19c83bSHermès Bélusca-Maïto VOID 24476f19c83bSHermès Bélusca-Maïto AddLogicalDiskSpace( 24486f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry) 24496f19c83bSHermès Bélusca-Maïto { 24506f19c83bSHermès Bélusca-Maïto PPARTENTRY NewPartEntry; 24516f19c83bSHermès Bélusca-Maïto 24526f19c83bSHermès Bélusca-Maïto DPRINT1("AddLogicalDiskSpace()\n"); 24536f19c83bSHermès Bélusca-Maïto 24546f19c83bSHermès Bélusca-Maïto /* Create a partition entry that represents the empty space in the container partition */ 24556f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 24566f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 24576f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 24586f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 24596f19c83bSHermès Bélusca-Maïto return; 24606f19c83bSHermès Bélusca-Maïto 24616f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 24626f19c83bSHermès Bélusca-Maïto NewPartEntry->LogicalPartition = TRUE; 24636f19c83bSHermès Bélusca-Maïto 24646f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = FALSE; 24656f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment; 24666f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment; 24676f19c83bSHermès Bélusca-Maïto 24686f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 24696f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 24706f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 24716f19c83bSHermès Bélusca-Maïto 24726f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Unformatted; 24736f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 24746f19c83bSHermès Bélusca-Maïto 24756f19c83bSHermès Bélusca-Maïto InsertTailList(&DiskEntry->LogicalPartListHead, 24766f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 24776f19c83bSHermès Bélusca-Maïto } 24786f19c83bSHermès Bélusca-Maïto 24796f19c83bSHermès Bélusca-Maïto VOID 24806f19c83bSHermès Bélusca-Maïto CreateExtendedPartition( 24816f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 24826f19c83bSHermès Bélusca-Maïto IN ULONGLONG SectorCount) 24836f19c83bSHermès Bélusca-Maïto { 24846f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 24856f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 24866f19c83bSHermès Bélusca-Maïto PPARTENTRY NewPartEntry; 24876f19c83bSHermès Bélusca-Maïto 24886f19c83bSHermès Bélusca-Maïto DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount); 24896f19c83bSHermès Bélusca-Maïto 24906f19c83bSHermès Bélusca-Maïto if (List == NULL || 24916f19c83bSHermès Bélusca-Maïto List->CurrentDisk == NULL || 24926f19c83bSHermès Bélusca-Maïto List->CurrentPartition == NULL || 24936f19c83bSHermès Bélusca-Maïto List->CurrentPartition->IsPartitioned != FALSE) 24946f19c83bSHermès Bélusca-Maïto { 24956f19c83bSHermès Bélusca-Maïto return; 24966f19c83bSHermès Bélusca-Maïto } 24976f19c83bSHermès Bélusca-Maïto 24986f19c83bSHermès Bélusca-Maïto DiskEntry = List->CurrentDisk; 24996f19c83bSHermès Bélusca-Maïto PartEntry = List->CurrentPartition; 25006f19c83bSHermès Bélusca-Maïto 25016f19c83bSHermès Bélusca-Maïto DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); 25026f19c83bSHermès Bélusca-Maïto 25036f19c83bSHermès Bélusca-Maïto if (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart) 25046f19c83bSHermès Bélusca-Maïto { 25056f19c83bSHermès Bélusca-Maïto DPRINT1("Convert existing partition entry\n"); 25066f19c83bSHermès Bélusca-Maïto 25076f19c83bSHermès Bélusca-Maïto /* Convert current entry to 'new (unformatted)' */ 25086f19c83bSHermès Bélusca-Maïto PartEntry->IsPartitioned = TRUE; 25096f19c83bSHermès Bélusca-Maïto PartEntry->FormatState = Formatted; // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container) 25106f19c83bSHermès Bélusca-Maïto PartEntry->FileSystem = NULL; 25116f19c83bSHermès Bélusca-Maïto PartEntry->AutoCreate = FALSE; 25126f19c83bSHermès Bélusca-Maïto PartEntry->New = FALSE; 25136f19c83bSHermès Bélusca-Maïto PartEntry->BootIndicator = FALSE; 25146f19c83bSHermès Bélusca-Maïto 25156f19c83bSHermès Bélusca-Maïto if (PartEntry->StartSector.QuadPart < 1450560) 25166f19c83bSHermès Bélusca-Maïto { 25176f19c83bSHermès Bélusca-Maïto /* Partition starts below the 8.4GB boundary ==> CHS partition */ 25186f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType = PARTITION_EXTENDED; 25196f19c83bSHermès Bélusca-Maïto } 25206f19c83bSHermès Bélusca-Maïto else 25216f19c83bSHermès Bélusca-Maïto { 25226f19c83bSHermès Bélusca-Maïto /* Partition starts above the 8.4GB boundary ==> LBA partition */ 25236f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType = PARTITION_XINT13_EXTENDED; 25246f19c83bSHermès Bélusca-Maïto } 25256f19c83bSHermès Bélusca-Maïto 25266f19c83bSHermès Bélusca-Maïto DiskEntry->ExtendedPartition = PartEntry; 25276f19c83bSHermès Bélusca-Maïto 25286f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart); 25296f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1); 25306f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart); 25316f19c83bSHermès Bélusca-Maïto } 25326f19c83bSHermès Bélusca-Maïto else 25336f19c83bSHermès Bélusca-Maïto { 25346f19c83bSHermès Bélusca-Maïto DPRINT1("Add new partition entry\n"); 25356f19c83bSHermès Bélusca-Maïto 25366f19c83bSHermès Bélusca-Maïto /* Insert and initialize a new partition entry */ 25376f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 25386f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 25396f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 25406f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 25416f19c83bSHermès Bélusca-Maïto return; 25426f19c83bSHermès Bélusca-Maïto 25436f19c83bSHermès Bélusca-Maïto /* Insert the new entry into the list */ 25446f19c83bSHermès Bélusca-Maïto InsertTailList(&PartEntry->ListEntry, 25456f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 25466f19c83bSHermès Bélusca-Maïto 25476f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 25486f19c83bSHermès Bélusca-Maïto 25496f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = TRUE; 25506f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; 25516f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - 25526f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart; 25536f19c83bSHermès Bélusca-Maïto 25546f19c83bSHermès Bélusca-Maïto NewPartEntry->New = FALSE; 25556f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Formatted; // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container) 25566f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 25576f19c83bSHermès Bélusca-Maïto NewPartEntry->BootIndicator = FALSE; 25586f19c83bSHermès Bélusca-Maïto 25596f19c83bSHermès Bélusca-Maïto if (NewPartEntry->StartSector.QuadPart < 1450560) 25606f19c83bSHermès Bélusca-Maïto { 25616f19c83bSHermès Bélusca-Maïto /* Partition starts below the 8.4GB boundary ==> CHS partition */ 25626f19c83bSHermès Bélusca-Maïto NewPartEntry->PartitionType = PARTITION_EXTENDED; 25636f19c83bSHermès Bélusca-Maïto } 25646f19c83bSHermès Bélusca-Maïto else 25656f19c83bSHermès Bélusca-Maïto { 25666f19c83bSHermès Bélusca-Maïto /* Partition starts above the 8.4GB boundary ==> LBA partition */ 25676f19c83bSHermès Bélusca-Maïto NewPartEntry->PartitionType = PARTITION_XINT13_EXTENDED; 25686f19c83bSHermès Bélusca-Maïto } 25696f19c83bSHermès Bélusca-Maïto 25706f19c83bSHermès Bélusca-Maïto DiskEntry->ExtendedPartition = NewPartEntry; 25716f19c83bSHermès Bélusca-Maïto 25726f19c83bSHermès Bélusca-Maïto PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; 25736f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart); 25746f19c83bSHermès Bélusca-Maïto 25756f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 25766f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 25776f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 25786f19c83bSHermès Bélusca-Maïto } 25796f19c83bSHermès Bélusca-Maïto 25806f19c83bSHermès Bélusca-Maïto AddLogicalDiskSpace(DiskEntry); 25816f19c83bSHermès Bélusca-Maïto 25826f19c83bSHermès Bélusca-Maïto UpdateDiskLayout(DiskEntry); 25836f19c83bSHermès Bélusca-Maïto 25846f19c83bSHermès Bélusca-Maïto DiskEntry->Dirty = TRUE; 25856f19c83bSHermès Bélusca-Maïto 25866f19c83bSHermès Bélusca-Maïto AssignDriveLetters(List); 25876f19c83bSHermès Bélusca-Maïto } 25886f19c83bSHermès Bélusca-Maïto 25896f19c83bSHermès Bélusca-Maïto VOID 25906f19c83bSHermès Bélusca-Maïto CreateLogicalPartition( 25916f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 25926f19c83bSHermès Bélusca-Maïto IN ULONGLONG SectorCount, 25936f19c83bSHermès Bélusca-Maïto IN BOOLEAN AutoCreate) 25946f19c83bSHermès Bélusca-Maïto { 25956f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 25966f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 25976f19c83bSHermès Bélusca-Maïto PPARTENTRY NewPartEntry; 25986f19c83bSHermès Bélusca-Maïto 25996f19c83bSHermès Bélusca-Maïto DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount); 26006f19c83bSHermès Bélusca-Maïto 26016f19c83bSHermès Bélusca-Maïto if (List == NULL || 26026f19c83bSHermès Bélusca-Maïto List->CurrentDisk == NULL || 26036f19c83bSHermès Bélusca-Maïto List->CurrentPartition == NULL || 26046f19c83bSHermès Bélusca-Maïto List->CurrentPartition->IsPartitioned != FALSE) 26056f19c83bSHermès Bélusca-Maïto { 26066f19c83bSHermès Bélusca-Maïto return; 26076f19c83bSHermès Bélusca-Maïto } 26086f19c83bSHermès Bélusca-Maïto 26096f19c83bSHermès Bélusca-Maïto DiskEntry = List->CurrentDisk; 26106f19c83bSHermès Bélusca-Maïto PartEntry = List->CurrentPartition; 26116f19c83bSHermès Bélusca-Maïto 26126f19c83bSHermès Bélusca-Maïto DPRINT1("Current partition sector count: %I64u\n", PartEntry->SectorCount.QuadPart); 26136f19c83bSHermès Bélusca-Maïto 26146f19c83bSHermès Bélusca-Maïto if ((AutoCreate != FALSE) || 26156f19c83bSHermès Bélusca-Maïto (AlignDown(PartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - PartEntry->StartSector.QuadPart == PartEntry->SectorCount.QuadPart)) 26166f19c83bSHermès Bélusca-Maïto { 26176f19c83bSHermès Bélusca-Maïto DPRINT1("Convert existing partition entry\n"); 26186f19c83bSHermès Bélusca-Maïto 26196f19c83bSHermès Bélusca-Maïto /* Convert current entry to 'new (unformatted)' */ 26206f19c83bSHermès Bélusca-Maïto PartEntry->IsPartitioned = TRUE; 26216f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType = PARTITION_ENTRY_UNUSED; 26226f19c83bSHermès Bélusca-Maïto PartEntry->FormatState = Unformatted; 26236f19c83bSHermès Bélusca-Maïto PartEntry->FileSystem = NULL; 26246f19c83bSHermès Bélusca-Maïto PartEntry->AutoCreate = FALSE; 26256f19c83bSHermès Bélusca-Maïto PartEntry->New = TRUE; 26266f19c83bSHermès Bélusca-Maïto PartEntry->BootIndicator = FALSE; 26276f19c83bSHermès Bélusca-Maïto PartEntry->LogicalPartition = TRUE; 26286f19c83bSHermès Bélusca-Maïto 26296f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", PartEntry->StartSector.QuadPart); 26306f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", PartEntry->StartSector.QuadPart + PartEntry->SectorCount.QuadPart - 1); 26316f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", PartEntry->SectorCount.QuadPart); 26326f19c83bSHermès Bélusca-Maïto } 26336f19c83bSHermès Bélusca-Maïto else 26346f19c83bSHermès Bélusca-Maïto { 26356f19c83bSHermès Bélusca-Maïto DPRINT1("Add new partition entry\n"); 26366f19c83bSHermès Bélusca-Maïto 26376f19c83bSHermès Bélusca-Maïto /* Insert and initialize a new partition entry */ 26386f19c83bSHermès Bélusca-Maïto NewPartEntry = RtlAllocateHeap(ProcessHeap, 26396f19c83bSHermès Bélusca-Maïto HEAP_ZERO_MEMORY, 26406f19c83bSHermès Bélusca-Maïto sizeof(PARTENTRY)); 26416f19c83bSHermès Bélusca-Maïto if (NewPartEntry == NULL) 26426f19c83bSHermès Bélusca-Maïto return; 26436f19c83bSHermès Bélusca-Maïto 26446f19c83bSHermès Bélusca-Maïto /* Insert the new entry into the list */ 26456f19c83bSHermès Bélusca-Maïto InsertTailList(&PartEntry->ListEntry, 26466f19c83bSHermès Bélusca-Maïto &NewPartEntry->ListEntry); 26476f19c83bSHermès Bélusca-Maïto 26486f19c83bSHermès Bélusca-Maïto NewPartEntry->DiskEntry = DiskEntry; 26496f19c83bSHermès Bélusca-Maïto 26506f19c83bSHermès Bélusca-Maïto NewPartEntry->IsPartitioned = TRUE; 26516f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; 26526f19c83bSHermès Bélusca-Maïto NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + SectorCount, DiskEntry->SectorAlignment) - 26536f19c83bSHermès Bélusca-Maïto NewPartEntry->StartSector.QuadPart; 26546f19c83bSHermès Bélusca-Maïto NewPartEntry->PartitionType = PARTITION_ENTRY_UNUSED; 26556f19c83bSHermès Bélusca-Maïto 26566f19c83bSHermès Bélusca-Maïto DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart); 26576f19c83bSHermès Bélusca-Maïto DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1); 26586f19c83bSHermès Bélusca-Maïto DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart); 26596f19c83bSHermès Bélusca-Maïto 26606f19c83bSHermès Bélusca-Maïto NewPartEntry->New = TRUE; 26616f19c83bSHermès Bélusca-Maïto NewPartEntry->FormatState = Unformatted; 26626f19c83bSHermès Bélusca-Maïto NewPartEntry->FileSystem = NULL; 26636f19c83bSHermès Bélusca-Maïto NewPartEntry->BootIndicator = FALSE; 26646f19c83bSHermès Bélusca-Maïto NewPartEntry->LogicalPartition = TRUE; 26656f19c83bSHermès Bélusca-Maïto 26666f19c83bSHermès Bélusca-Maïto PartEntry->StartSector.QuadPart = NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart; 26676f19c83bSHermès Bélusca-Maïto PartEntry->SectorCount.QuadPart -= (PartEntry->StartSector.QuadPart - NewPartEntry->StartSector.QuadPart); 26686f19c83bSHermès Bélusca-Maïto } 26696f19c83bSHermès Bélusca-Maïto 26706f19c83bSHermès Bélusca-Maïto UpdateDiskLayout(DiskEntry); 26716f19c83bSHermès Bélusca-Maïto 26726f19c83bSHermès Bélusca-Maïto DiskEntry->Dirty = TRUE; 26736f19c83bSHermès Bélusca-Maïto 26746f19c83bSHermès Bélusca-Maïto AssignDriveLetters(List); 26756f19c83bSHermès Bélusca-Maïto } 26766f19c83bSHermès Bélusca-Maïto 26776f19c83bSHermès Bélusca-Maïto VOID 26786f19c83bSHermès Bélusca-Maïto DeleteCurrentPartition( 26796f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 26806f19c83bSHermès Bélusca-Maïto { 26816f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 26826f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 26836f19c83bSHermès Bélusca-Maïto PPARTENTRY PrevPartEntry; 26846f19c83bSHermès Bélusca-Maïto PPARTENTRY NextPartEntry; 26856f19c83bSHermès Bélusca-Maïto PPARTENTRY LogicalPartEntry; 26866f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 26876f19c83bSHermès Bélusca-Maïto 26886f19c83bSHermès Bélusca-Maïto if (List == NULL || 26896f19c83bSHermès Bélusca-Maïto List->CurrentDisk == NULL || 26906f19c83bSHermès Bélusca-Maïto List->CurrentPartition == NULL || 26916f19c83bSHermès Bélusca-Maïto List->CurrentPartition->IsPartitioned == FALSE) 26926f19c83bSHermès Bélusca-Maïto { 26936f19c83bSHermès Bélusca-Maïto return; 26946f19c83bSHermès Bélusca-Maïto } 26956f19c83bSHermès Bélusca-Maïto 26966f19c83bSHermès Bélusca-Maïto /* Clear the system disk and partition pointers if the system partition is being deleted */ 26976f19c83bSHermès Bélusca-Maïto if (List->SystemPartition == List->CurrentPartition) 26986f19c83bSHermès Bélusca-Maïto { 26996f19c83bSHermès Bélusca-Maïto List->SystemPartition = NULL; 27006f19c83bSHermès Bélusca-Maïto } 27016f19c83bSHermès Bélusca-Maïto 27026f19c83bSHermès Bélusca-Maïto DiskEntry = List->CurrentDisk; 27036f19c83bSHermès Bélusca-Maïto PartEntry = List->CurrentPartition; 27046f19c83bSHermès Bélusca-Maïto 27056f19c83bSHermès Bélusca-Maïto /* Delete all logical partition entries if an extended partition will be deleted */ 27066f19c83bSHermès Bélusca-Maïto if (DiskEntry->ExtendedPartition == PartEntry) 27076f19c83bSHermès Bélusca-Maïto { 27086f19c83bSHermès Bélusca-Maïto while (!IsListEmpty(&DiskEntry->LogicalPartListHead)) 27096f19c83bSHermès Bélusca-Maïto { 27106f19c83bSHermès Bélusca-Maïto Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead); 27116f19c83bSHermès Bélusca-Maïto LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 27126f19c83bSHermès Bélusca-Maïto 27136f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry); 27146f19c83bSHermès Bélusca-Maïto } 27156f19c83bSHermès Bélusca-Maïto 27166f19c83bSHermès Bélusca-Maïto DiskEntry->ExtendedPartition = NULL; 27176f19c83bSHermès Bélusca-Maïto } 27186f19c83bSHermès Bélusca-Maïto 27196f19c83bSHermès Bélusca-Maïto /* Adjust unpartitioned disk space entries */ 27206f19c83bSHermès Bélusca-Maïto 27216f19c83bSHermès Bélusca-Maïto /* Get pointer to previous and next unpartitioned entries */ 27226f19c83bSHermès Bélusca-Maïto PrevPartEntry = GetPrevUnpartitionedEntry(DiskEntry, PartEntry); 27236f19c83bSHermès Bélusca-Maïto NextPartEntry = GetNextUnpartitionedEntry(DiskEntry, PartEntry); 27246f19c83bSHermès Bélusca-Maïto 27256f19c83bSHermès Bélusca-Maïto if (PrevPartEntry != NULL && NextPartEntry != NULL) 27266f19c83bSHermès Bélusca-Maïto { 27276f19c83bSHermès Bélusca-Maïto /* Merge previous, current and next unpartitioned entry */ 27286f19c83bSHermès Bélusca-Maïto 27296f19c83bSHermès Bélusca-Maïto /* Adjust the previous entries length */ 27306f19c83bSHermès Bélusca-Maïto PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart); 27316f19c83bSHermès Bélusca-Maïto 27326f19c83bSHermès Bélusca-Maïto /* Remove the current entry */ 27336f19c83bSHermès Bélusca-Maïto RemoveEntryList(&PartEntry->ListEntry); 27346f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, PartEntry); 27356f19c83bSHermès Bélusca-Maïto 27366f19c83bSHermès Bélusca-Maïto /* Remove the next entry */ 27376f19c83bSHermès Bélusca-Maïto RemoveEntryList(&NextPartEntry->ListEntry); 27386f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, NextPartEntry); 27396f19c83bSHermès Bélusca-Maïto 27406f19c83bSHermès Bélusca-Maïto /* Update current partition */ 27416f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PrevPartEntry; 27426f19c83bSHermès Bélusca-Maïto } 27436f19c83bSHermès Bélusca-Maïto else if (PrevPartEntry != NULL && NextPartEntry == NULL) 27446f19c83bSHermès Bélusca-Maïto { 27456f19c83bSHermès Bélusca-Maïto /* Merge current and previous unpartitioned entry */ 27466f19c83bSHermès Bélusca-Maïto 27476f19c83bSHermès Bélusca-Maïto /* Adjust the previous entries length */ 27486f19c83bSHermès Bélusca-Maïto PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart; 27496f19c83bSHermès Bélusca-Maïto 27506f19c83bSHermès Bélusca-Maïto /* Remove the current entry */ 27516f19c83bSHermès Bélusca-Maïto RemoveEntryList(&PartEntry->ListEntry); 27526f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, PartEntry); 27536f19c83bSHermès Bélusca-Maïto 27546f19c83bSHermès Bélusca-Maïto /* Update current partition */ 27556f19c83bSHermès Bélusca-Maïto List->CurrentPartition = PrevPartEntry; 27566f19c83bSHermès Bélusca-Maïto } 27576f19c83bSHermès Bélusca-Maïto else if (PrevPartEntry == NULL && NextPartEntry != NULL) 27586f19c83bSHermès Bélusca-Maïto { 27596f19c83bSHermès Bélusca-Maïto /* Merge current and next unpartitioned entry */ 27606f19c83bSHermès Bélusca-Maïto 27616f19c83bSHermès Bélusca-Maïto /* Adjust the next entries offset and length */ 27626f19c83bSHermès Bélusca-Maïto NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart; 27636f19c83bSHermès Bélusca-Maïto NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart; 27646f19c83bSHermès Bélusca-Maïto 27656f19c83bSHermès Bélusca-Maïto /* Remove the current entry */ 27666f19c83bSHermès Bélusca-Maïto RemoveEntryList(&PartEntry->ListEntry); 27676f19c83bSHermès Bélusca-Maïto RtlFreeHeap(ProcessHeap, 0, PartEntry); 27686f19c83bSHermès Bélusca-Maïto 27696f19c83bSHermès Bélusca-Maïto /* Update current partition */ 27706f19c83bSHermès Bélusca-Maïto List->CurrentPartition = NextPartEntry; 27716f19c83bSHermès Bélusca-Maïto } 27726f19c83bSHermès Bélusca-Maïto else 27736f19c83bSHermès Bélusca-Maïto { 27746f19c83bSHermès Bélusca-Maïto /* Nothing to merge but change current entry */ 27756f19c83bSHermès Bélusca-Maïto PartEntry->IsPartitioned = FALSE; 27766f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType = PARTITION_ENTRY_UNUSED; 27776f19c83bSHermès Bélusca-Maïto PartEntry->FormatState = Unformatted; 27786f19c83bSHermès Bélusca-Maïto PartEntry->FileSystem = NULL; 27796f19c83bSHermès Bélusca-Maïto PartEntry->DriveLetter = 0; 27806f19c83bSHermès Bélusca-Maïto } 27816f19c83bSHermès Bélusca-Maïto 27826f19c83bSHermès Bélusca-Maïto UpdateDiskLayout(DiskEntry); 27836f19c83bSHermès Bélusca-Maïto 27846f19c83bSHermès Bélusca-Maïto DiskEntry->Dirty = TRUE; 27856f19c83bSHermès Bélusca-Maïto 27866f19c83bSHermès Bélusca-Maïto AssignDriveLetters(List); 27876f19c83bSHermès Bélusca-Maïto } 27886f19c83bSHermès Bélusca-Maïto 27896f19c83bSHermès Bélusca-Maïto VOID 27906f19c83bSHermès Bélusca-Maïto CheckActiveSystemPartition( 27916f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 27926f19c83bSHermès Bélusca-Maïto { 27936f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 27946f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 27956f19c83bSHermès Bélusca-Maïto PLIST_ENTRY ListEntry; 27966f19c83bSHermès Bélusca-Maïto 27976f19c83bSHermès Bélusca-Maïto PFILE_SYSTEM FileSystem; 27986f19c83bSHermès Bélusca-Maïto 27996f19c83bSHermès Bélusca-Maïto /* Check for empty disk list */ 28006f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&List->DiskListHead)) 28016f19c83bSHermès Bélusca-Maïto { 28026f19c83bSHermès Bélusca-Maïto List->SystemPartition = NULL; 28036f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition = NULL; 28046f19c83bSHermès Bélusca-Maïto return; 28056f19c83bSHermès Bélusca-Maïto } 28066f19c83bSHermès Bélusca-Maïto 28076f19c83bSHermès Bélusca-Maïto /* Choose the currently selected disk */ 28086f19c83bSHermès Bélusca-Maïto DiskEntry = List->CurrentDisk; 28096f19c83bSHermès Bélusca-Maïto 28106f19c83bSHermès Bélusca-Maïto /* Check for empty partition list */ 28116f19c83bSHermès Bélusca-Maïto if (IsListEmpty(&DiskEntry->PrimaryPartListHead)) 28126f19c83bSHermès Bélusca-Maïto { 28136f19c83bSHermès Bélusca-Maïto List->SystemPartition = NULL; 28146f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition = NULL; 28156f19c83bSHermès Bélusca-Maïto return; 28166f19c83bSHermès Bélusca-Maïto } 28176f19c83bSHermès Bélusca-Maïto 28186f19c83bSHermès Bélusca-Maïto if (List->SystemPartition != NULL) 28196f19c83bSHermès Bélusca-Maïto { 28206f19c83bSHermès Bélusca-Maïto /* We already have an active system partition */ 2821f41750abSHermès Bélusca-Maïto DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n", 28226f19c83bSHermès Bélusca-Maïto List->SystemPartition->PartitionNumber, 28236f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->DiskNumber, 2824f41750abSHermès Bélusca-Maïto (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter); 28256f19c83bSHermès Bélusca-Maïto return; 28266f19c83bSHermès Bélusca-Maïto } 28276f19c83bSHermès Bélusca-Maïto 28286f19c83bSHermès Bélusca-Maïto DPRINT1("We are here (1)!\n"); 28296f19c83bSHermès Bélusca-Maïto 28306f19c83bSHermès Bélusca-Maïto List->SystemPartition = NULL; 28316f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition = NULL; 28326f19c83bSHermès Bélusca-Maïto 28336f19c83bSHermès Bélusca-Maïto /* Retrieve the first partition of the disk */ 28346f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink, 28356f19c83bSHermès Bélusca-Maïto PARTENTRY, 28366f19c83bSHermès Bélusca-Maïto ListEntry); 28376f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry == PartEntry->DiskEntry); 28386f19c83bSHermès Bélusca-Maïto List->SystemPartition = PartEntry; 28396f19c83bSHermès Bélusca-Maïto 28406f19c83bSHermès Bélusca-Maïto // 28416f19c83bSHermès Bélusca-Maïto // See: https://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/partlist.c?r1=63355&r2=63354&pathrev=63355#l2318 28426f19c83bSHermès Bélusca-Maïto // 28436f19c83bSHermès Bélusca-Maïto 28446f19c83bSHermès Bélusca-Maïto /* Check if the disk is new and if so, use its first partition as the active system partition */ 28456f19c83bSHermès Bélusca-Maïto if (DiskEntry->NewDisk) 28466f19c83bSHermès Bélusca-Maïto { 28476f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionType == PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator == FALSE) 28486f19c83bSHermès Bélusca-Maïto { 28496f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry == PartEntry->DiskEntry); 28506f19c83bSHermès Bélusca-Maïto List->SystemPartition = PartEntry; 28516f19c83bSHermès Bélusca-Maïto 28526f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition = List->SystemPartition; 28536f19c83bSHermès Bélusca-Maïto 2854f41750abSHermès Bélusca-Maïto DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n", 28556f19c83bSHermès Bélusca-Maïto List->SystemPartition->PartitionNumber, 28566f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->DiskNumber, 2857f41750abSHermès Bélusca-Maïto (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter); 28586f19c83bSHermès Bélusca-Maïto 28596f19c83bSHermès Bélusca-Maïto goto SetSystemPartition; 28606f19c83bSHermès Bélusca-Maïto } 28616f19c83bSHermès Bélusca-Maïto 28626f19c83bSHermès Bélusca-Maïto // FIXME: What to do?? 28636f19c83bSHermès Bélusca-Maïto DPRINT1("NewDisk TRUE but first partition is used?\n"); 28646f19c83bSHermès Bélusca-Maïto } 28656f19c83bSHermès Bélusca-Maïto 28666f19c83bSHermès Bélusca-Maïto DPRINT1("We are here (2)!\n"); 28676f19c83bSHermès Bélusca-Maïto 28686f19c83bSHermès Bélusca-Maïto /* 28696f19c83bSHermès Bélusca-Maïto * The disk is not new, check if any partition is initialized; 28706f19c83bSHermès Bélusca-Maïto * if not, the first one becomes the system partition. 28716f19c83bSHermès Bélusca-Maïto */ 28726f19c83bSHermès Bélusca-Maïto ListEntry = DiskEntry->PrimaryPartListHead.Flink; 28736f19c83bSHermès Bélusca-Maïto while (ListEntry != &DiskEntry->PrimaryPartListHead) 28746f19c83bSHermès Bélusca-Maïto { 28756f19c83bSHermès Bélusca-Maïto /* Retrieve the partition and go to the next one */ 28766f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, 28776f19c83bSHermès Bélusca-Maïto PARTENTRY, 28786f19c83bSHermès Bélusca-Maïto ListEntry); 28796f19c83bSHermès Bélusca-Maïto 28806f19c83bSHermès Bélusca-Maïto /* Check if the partition is partitioned and is used */ 28816f19c83bSHermès Bélusca-Maïto if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator != FALSE) 28826f19c83bSHermès Bélusca-Maïto { 28836f19c83bSHermès Bélusca-Maïto break; 28846f19c83bSHermès Bélusca-Maïto } 28856f19c83bSHermès Bélusca-Maïto 28866f19c83bSHermès Bélusca-Maïto /* Go to the next one */ 28876f19c83bSHermès Bélusca-Maïto ListEntry = ListEntry->Flink; 28886f19c83bSHermès Bélusca-Maïto } 28896f19c83bSHermès Bélusca-Maïto if (ListEntry == &DiskEntry->PrimaryPartListHead) 28906f19c83bSHermès Bélusca-Maïto { 28916f19c83bSHermès Bélusca-Maïto /* 28926f19c83bSHermès Bélusca-Maïto * OK we haven't encountered any used and active partition, 28936f19c83bSHermès Bélusca-Maïto * so use the first one as the system partition. 28946f19c83bSHermès Bélusca-Maïto */ 28956f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry == List->SystemPartition->DiskEntry); 28966f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition = List->SystemPartition; // First PartEntry 28976f19c83bSHermès Bélusca-Maïto 2898f41750abSHermès Bélusca-Maïto DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n", 28996f19c83bSHermès Bélusca-Maïto List->SystemPartition->PartitionNumber, 29006f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->DiskNumber, 2901f41750abSHermès Bélusca-Maïto (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter); 29026f19c83bSHermès Bélusca-Maïto 29036f19c83bSHermès Bélusca-Maïto goto SetSystemPartition; 29046f19c83bSHermès Bélusca-Maïto } 29056f19c83bSHermès Bélusca-Maïto 29066f19c83bSHermès Bélusca-Maïto List->SystemPartition = NULL; 29076f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition = NULL; 29086f19c83bSHermès Bélusca-Maïto 29096f19c83bSHermès Bélusca-Maïto DPRINT1("We are here (3)!\n"); 29106f19c83bSHermès Bélusca-Maïto 29116f19c83bSHermès Bélusca-Maïto /* The disk is not new, scan all partitions to find the (active) system partition */ 29126f19c83bSHermès Bélusca-Maïto ListEntry = DiskEntry->PrimaryPartListHead.Flink; 29136f19c83bSHermès Bélusca-Maïto while (ListEntry != &DiskEntry->PrimaryPartListHead) 29146f19c83bSHermès Bélusca-Maïto { 29156f19c83bSHermès Bélusca-Maïto /* Retrieve the partition and go to the next one */ 29166f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(ListEntry, 29176f19c83bSHermès Bélusca-Maïto PARTENTRY, 29186f19c83bSHermès Bélusca-Maïto ListEntry); 29196f19c83bSHermès Bélusca-Maïto ListEntry = ListEntry->Flink; 29206f19c83bSHermès Bélusca-Maïto 29216f19c83bSHermès Bélusca-Maïto /* Check if the partition is partitioned and used */ 29226f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned && 29236f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType != PARTITION_ENTRY_UNUSED) 29246f19c83bSHermès Bélusca-Maïto { 29256f19c83bSHermès Bélusca-Maïto /* Check if the partition is active */ 29266f19c83bSHermès Bélusca-Maïto if (PartEntry->BootIndicator) 29276f19c83bSHermès Bélusca-Maïto { 29286f19c83bSHermès Bélusca-Maïto /* Yes, we found it */ 29296f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry == PartEntry->DiskEntry); 29306f19c83bSHermès Bélusca-Maïto List->SystemPartition = PartEntry; 29316f19c83bSHermès Bélusca-Maïto 2932f41750abSHermès Bélusca-Maïto DPRINT1("Found active system partition %lu in disk %lu, drive letter %C\n", 29336f19c83bSHermès Bélusca-Maïto PartEntry->PartitionNumber, 29346f19c83bSHermès Bélusca-Maïto DiskEntry->DiskNumber, 2935f41750abSHermès Bélusca-Maïto (PartEntry->DriveLetter == 0) ? L'-' : PartEntry->DriveLetter); 29366f19c83bSHermès Bélusca-Maïto break; 29376f19c83bSHermès Bélusca-Maïto } 29386f19c83bSHermès Bélusca-Maïto } 29396f19c83bSHermès Bélusca-Maïto } 29406f19c83bSHermès Bélusca-Maïto 29416f19c83bSHermès Bélusca-Maïto /* Check if we have found the system partition */ 29426f19c83bSHermès Bélusca-Maïto if (List->SystemPartition == NULL) 29436f19c83bSHermès Bélusca-Maïto { 29446f19c83bSHermès Bélusca-Maïto /* Nothing, use the alternative system partition */ 29456f19c83bSHermès Bélusca-Maïto DPRINT1("No system partition found, use the alternative partition!\n"); 29466f19c83bSHermès Bélusca-Maïto goto UseAlternativeSystemPartition; 29476f19c83bSHermès Bélusca-Maïto } 29486f19c83bSHermès Bélusca-Maïto 29496f19c83bSHermès Bélusca-Maïto /* Save it */ 29506f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition = List->SystemPartition; 29516f19c83bSHermès Bélusca-Maïto 29526f19c83bSHermès Bélusca-Maïto /* 29536f19c83bSHermès Bélusca-Maïto * ADDITIONAL CHECKS / BIG HACK: 29546f19c83bSHermès Bélusca-Maïto * 29556f19c83bSHermès Bélusca-Maïto * Retrieve its file system and check whether we have 29566f19c83bSHermès Bélusca-Maïto * write support for it. If that is the case we are fine 29576f19c83bSHermès Bélusca-Maïto * and we can use it directly. However if we don't have 29586f19c83bSHermès Bélusca-Maïto * write support we will need to change the active system 29596f19c83bSHermès Bélusca-Maïto * partition. 29606f19c83bSHermès Bélusca-Maïto * 29616f19c83bSHermès Bélusca-Maïto * NOTE that this is completely useless on architectures 29626f19c83bSHermès Bélusca-Maïto * where a real system partition is required, as on these 29636f19c83bSHermès Bélusca-Maïto * architectures the partition uses the FAT FS, for which 29646f19c83bSHermès Bélusca-Maïto * we do have write support. 29656f19c83bSHermès Bélusca-Maïto * NOTE also that for those architectures looking for a 29666f19c83bSHermès Bélusca-Maïto * partition boot indicator is insufficient. 29676f19c83bSHermès Bélusca-Maïto */ 29686f19c83bSHermès Bélusca-Maïto FileSystem = GetFileSystem(List->OriginalSystemPartition); 29696f19c83bSHermès Bélusca-Maïto if (FileSystem == NULL) 29706f19c83bSHermès Bélusca-Maïto { 29716f19c83bSHermès Bélusca-Maïto DPRINT1("System partition %lu in disk %lu with no FS?!\n", 29726f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition->PartitionNumber, 29736f19c83bSHermès Bélusca-Maïto List->OriginalSystemPartition->DiskEntry->DiskNumber); 29746f19c83bSHermès Bélusca-Maïto goto FindAndUseAlternativeSystemPartition; 29756f19c83bSHermès Bélusca-Maïto } 29766f19c83bSHermès Bélusca-Maïto // HACK: WARNING: We cannot write on this FS yet! 29776f19c83bSHermès Bélusca-Maïto // See fsutil.c:GetFileSystem() 29784c6370deSBișoc George if (List->OriginalSystemPartition->PartitionType == PARTITION_IFS) 29796f19c83bSHermès Bélusca-Maïto { 29806f19c83bSHermès Bélusca-Maïto DPRINT1("Recognized file system %S that doesn't support write support yet!\n", 29816f19c83bSHermès Bélusca-Maïto FileSystem->FileSystemName); 29826f19c83bSHermès Bélusca-Maïto goto FindAndUseAlternativeSystemPartition; 29836f19c83bSHermès Bélusca-Maïto } 29846f19c83bSHermès Bélusca-Maïto 2985f41750abSHermès Bélusca-Maïto DPRINT1("Use existing active system partition %lu in disk %lu, drive letter %C\n", 29866f19c83bSHermès Bélusca-Maïto List->SystemPartition->PartitionNumber, 29876f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->DiskNumber, 2988f41750abSHermès Bélusca-Maïto (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter); 29896f19c83bSHermès Bélusca-Maïto 29906f19c83bSHermès Bélusca-Maïto return; 29916f19c83bSHermès Bélusca-Maïto 29926f19c83bSHermès Bélusca-Maïto FindAndUseAlternativeSystemPartition: 29936f19c83bSHermès Bélusca-Maïto /* 29946f19c83bSHermès Bélusca-Maïto * We are here because we have not found any (active) candidate 29956f19c83bSHermès Bélusca-Maïto * system partition that we know how to support. What we are going 29966f19c83bSHermès Bélusca-Maïto * to do is to change the existing system partition and use the 29976f19c83bSHermès Bélusca-Maïto * partition on which we install ReactOS as the new system partition, 29986f19c83bSHermès Bélusca-Maïto * and then we will need to add in FreeLdr's entry a boot entry to boot 29996f19c83bSHermès Bélusca-Maïto * from the original system partition. 30006f19c83bSHermès Bélusca-Maïto */ 30016f19c83bSHermès Bélusca-Maïto 30026f19c83bSHermès Bélusca-Maïto /* Unset the old system partition */ 30036f19c83bSHermès Bélusca-Maïto List->SystemPartition->BootIndicator = FALSE; 30046f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = FALSE; 30056f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE; 30066f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->Dirty = TRUE; 30076f19c83bSHermès Bélusca-Maïto 30086f19c83bSHermès Bélusca-Maïto UseAlternativeSystemPartition: 30096f19c83bSHermès Bélusca-Maïto List->SystemPartition = List->CurrentPartition; 30106f19c83bSHermès Bélusca-Maïto 3011f41750abSHermès Bélusca-Maïto DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n", 30126f19c83bSHermès Bélusca-Maïto List->SystemPartition->PartitionNumber, 30136f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->DiskNumber, 3014f41750abSHermès Bélusca-Maïto (List->SystemPartition->DriveLetter == 0) ? L'-' : List->SystemPartition->DriveLetter); 30156f19c83bSHermès Bélusca-Maïto 30166f19c83bSHermès Bélusca-Maïto SetSystemPartition: 30176f19c83bSHermès Bélusca-Maïto /* Set the new active system partition */ 30186f19c83bSHermès Bélusca-Maïto List->SystemPartition->BootIndicator = TRUE; 30196f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].BootIndicator = TRUE; 30206f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->LayoutBuffer->PartitionEntry[List->SystemPartition->PartitionIndex].RewritePartition = TRUE; 30216f19c83bSHermès Bélusca-Maïto List->SystemPartition->DiskEntry->Dirty = TRUE; 30226f19c83bSHermès Bélusca-Maïto } 30236f19c83bSHermès Bélusca-Maïto 30246f19c83bSHermès Bélusca-Maïto static 30256f19c83bSHermès Bélusca-Maïto NTSTATUS 30266f19c83bSHermès Bélusca-Maïto WritePartitions( 30276f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 30286f19c83bSHermès Bélusca-Maïto IN PDISKENTRY DiskEntry) 30296f19c83bSHermès Bélusca-Maïto { 30306f19c83bSHermès Bélusca-Maïto WCHAR DstPath[MAX_PATH]; 30316f19c83bSHermès Bélusca-Maïto OBJECT_ATTRIBUTES ObjectAttributes; 30326f19c83bSHermès Bélusca-Maïto IO_STATUS_BLOCK Iosb; 30336f19c83bSHermès Bélusca-Maïto UNICODE_STRING Name; 30346f19c83bSHermès Bélusca-Maïto ULONG BufferSize; 30356f19c83bSHermès Bélusca-Maïto HANDLE FileHandle = NULL; 30366f19c83bSHermès Bélusca-Maïto NTSTATUS Status; 30376f19c83bSHermès Bélusca-Maïto 30386f19c83bSHermès Bélusca-Maïto DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber); 30396f19c83bSHermès Bélusca-Maïto 30406f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(DstPath, ARRAYSIZE(DstPath), 30416f19c83bSHermès Bélusca-Maïto L"\\Device\\Harddisk%lu\\Partition0", 30426f19c83bSHermès Bélusca-Maïto DiskEntry->DiskNumber); 30436f19c83bSHermès Bélusca-Maïto RtlInitUnicodeString(&Name, DstPath); 3044765994c9SHermès Bélusca-Maïto 30456f19c83bSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes, 30466f19c83bSHermès Bélusca-Maïto &Name, 3047765994c9SHermès Bélusca-Maïto OBJ_CASE_INSENSITIVE, 30486f19c83bSHermès Bélusca-Maïto NULL, 30496f19c83bSHermès Bélusca-Maïto NULL); 30506f19c83bSHermès Bélusca-Maïto 30516f19c83bSHermès Bélusca-Maïto Status = NtOpenFile(&FileHandle, 30526f19c83bSHermès Bélusca-Maïto GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 30536f19c83bSHermès Bélusca-Maïto &ObjectAttributes, 30546f19c83bSHermès Bélusca-Maïto &Iosb, 30556f19c83bSHermès Bélusca-Maïto 0, 30566f19c83bSHermès Bélusca-Maïto FILE_SYNCHRONOUS_IO_NONALERT); 30576f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 30586f19c83bSHermès Bélusca-Maïto { 30596f19c83bSHermès Bélusca-Maïto DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); 30606f19c83bSHermès Bélusca-Maïto return Status; 30616f19c83bSHermès Bélusca-Maïto } 30626f19c83bSHermès Bélusca-Maïto 30636f19c83bSHermès Bélusca-Maïto #ifdef DUMP_PARTITION_TABLE 30646f19c83bSHermès Bélusca-Maïto DumpPartitionTable(DiskEntry); 30656f19c83bSHermès Bélusca-Maïto #endif 30666f19c83bSHermès Bélusca-Maïto 3067f41750abSHermès Bélusca-Maïto // 3068f41750abSHermès Bélusca-Maïto // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize 3069f41750abSHermès Bélusca-Maïto // the disk in MBR or GPT format in case the disk was not initialized!! 3070f41750abSHermès Bélusca-Maïto // For this we must ask the user which format to use. 3071f41750abSHermès Bélusca-Maïto // 3072f41750abSHermès Bélusca-Maïto 30736f19c83bSHermès Bélusca-Maïto BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + 30746f19c83bSHermès Bélusca-Maïto ((DiskEntry->LayoutBuffer->PartitionCount - 1) * sizeof(PARTITION_INFORMATION)); 30756f19c83bSHermès Bélusca-Maïto Status = NtDeviceIoControlFile(FileHandle, 30766f19c83bSHermès Bélusca-Maïto NULL, 30776f19c83bSHermès Bélusca-Maïto NULL, 30786f19c83bSHermès Bélusca-Maïto NULL, 30796f19c83bSHermès Bélusca-Maïto &Iosb, 30806f19c83bSHermès Bélusca-Maïto IOCTL_DISK_SET_DRIVE_LAYOUT, 30816f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer, 30826f19c83bSHermès Bélusca-Maïto BufferSize, 30836f19c83bSHermès Bélusca-Maïto NULL, 30846f19c83bSHermès Bélusca-Maïto 0); 30856f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 30866f19c83bSHermès Bélusca-Maïto { 30876f19c83bSHermès Bélusca-Maïto DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status); 30886f19c83bSHermès Bélusca-Maïto } 30896f19c83bSHermès Bélusca-Maïto 30906f19c83bSHermès Bélusca-Maïto if (FileHandle != NULL) 30916f19c83bSHermès Bélusca-Maïto NtClose(FileHandle); 30926f19c83bSHermès Bélusca-Maïto 30936f19c83bSHermès Bélusca-Maïto // 30946f19c83bSHermès Bélusca-Maïto // NOTE: Originally (see r40437), we used to install here also a new MBR 30956f19c83bSHermès Bélusca-Maïto // for this disk (by calling InstallMbrBootCodeToDisk), only if: 30966f19c83bSHermès Bélusca-Maïto // DiskEntry->NewDisk == TRUE and DiskEntry->BiosDiskNumber == 0. 30976f19c83bSHermès Bélusca-Maïto // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set 30986f19c83bSHermès Bélusca-Maïto // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk 30996f19c83bSHermès Bélusca-Maïto // was called too, the installation test was modified by checking whether 31006f19c83bSHermès Bélusca-Maïto // DiskEntry->NoMbr was TRUE (instead of NewDisk). 31016f19c83bSHermès Bélusca-Maïto // 31026f19c83bSHermès Bélusca-Maïto 31036f19c83bSHermès Bélusca-Maïto return Status; 31046f19c83bSHermès Bélusca-Maïto } 31056f19c83bSHermès Bélusca-Maïto 31066f19c83bSHermès Bélusca-Maïto BOOLEAN 31076f19c83bSHermès Bélusca-Maïto WritePartitionsToDisk( 31086f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 31096f19c83bSHermès Bélusca-Maïto { 31106f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry; 31116f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 31126f19c83bSHermès Bélusca-Maïto 31136f19c83bSHermès Bélusca-Maïto if (List == NULL) 31146f19c83bSHermès Bélusca-Maïto return TRUE; 31156f19c83bSHermès Bélusca-Maïto 31166f19c83bSHermès Bélusca-Maïto Entry = List->DiskListHead.Flink; 31176f19c83bSHermès Bélusca-Maïto while (Entry != &List->DiskListHead) 31186f19c83bSHermès Bélusca-Maïto { 31196f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); 31206f19c83bSHermès Bélusca-Maïto 31216f19c83bSHermès Bélusca-Maïto if (DiskEntry->Dirty != FALSE) 31226f19c83bSHermès Bélusca-Maïto { 31236f19c83bSHermès Bélusca-Maïto WritePartitions(List, DiskEntry); 31246f19c83bSHermès Bélusca-Maïto DiskEntry->Dirty = FALSE; 31256f19c83bSHermès Bélusca-Maïto } 31266f19c83bSHermès Bélusca-Maïto 31276f19c83bSHermès Bélusca-Maïto Entry = Entry->Flink; 31286f19c83bSHermès Bélusca-Maïto } 31296f19c83bSHermès Bélusca-Maïto 31306f19c83bSHermès Bélusca-Maïto return TRUE; 31316f19c83bSHermès Bélusca-Maïto } 31326f19c83bSHermès Bélusca-Maïto 31336f19c83bSHermès Bélusca-Maïto BOOLEAN 31346f19c83bSHermès Bélusca-Maïto SetMountedDeviceValue( 3135f41750abSHermès Bélusca-Maïto IN WCHAR Letter, 31366f19c83bSHermès Bélusca-Maïto IN ULONG Signature, 31376f19c83bSHermès Bélusca-Maïto IN LARGE_INTEGER StartingOffset) 31386f19c83bSHermès Bélusca-Maïto { 31396f19c83bSHermès Bélusca-Maïto OBJECT_ATTRIBUTES ObjectAttributes; 31406f19c83bSHermès Bélusca-Maïto WCHAR ValueNameBuffer[16]; 31416f19c83bSHermès Bélusca-Maïto UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\MountedDevices"); 31426f19c83bSHermès Bélusca-Maïto UNICODE_STRING ValueName; 31436f19c83bSHermès Bélusca-Maïto REG_DISK_MOUNT_INFO MountInfo; 31446f19c83bSHermès Bélusca-Maïto NTSTATUS Status; 31456f19c83bSHermès Bélusca-Maïto HANDLE KeyHandle; 31466f19c83bSHermès Bélusca-Maïto 31476f19c83bSHermès Bélusca-Maïto RtlStringCchPrintfW(ValueNameBuffer, ARRAYSIZE(ValueNameBuffer), 3148f41750abSHermès Bélusca-Maïto L"\\DosDevices\\%c:", Letter); 31496f19c83bSHermès Bélusca-Maïto RtlInitUnicodeString(&ValueName, ValueNameBuffer); 31506f19c83bSHermès Bélusca-Maïto 31516f19c83bSHermès Bélusca-Maïto InitializeObjectAttributes(&ObjectAttributes, 31526f19c83bSHermès Bélusca-Maïto &KeyName, 31536f19c83bSHermès Bélusca-Maïto OBJ_CASE_INSENSITIVE, 31546f19c83bSHermès Bélusca-Maïto NULL, 31556f19c83bSHermès Bélusca-Maïto NULL); 3156765994c9SHermès Bélusca-Maïto 31576f19c83bSHermès Bélusca-Maïto Status = NtOpenKey(&KeyHandle, 31586f19c83bSHermès Bélusca-Maïto KEY_ALL_ACCESS, 31596f19c83bSHermès Bélusca-Maïto &ObjectAttributes); 31606f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 31616f19c83bSHermès Bélusca-Maïto { 31626f19c83bSHermès Bélusca-Maïto Status = NtCreateKey(&KeyHandle, 31636f19c83bSHermès Bélusca-Maïto KEY_ALL_ACCESS, 31646f19c83bSHermès Bélusca-Maïto &ObjectAttributes, 31656f19c83bSHermès Bélusca-Maïto 0, 31666f19c83bSHermès Bélusca-Maïto NULL, 31676f19c83bSHermès Bélusca-Maïto REG_OPTION_NON_VOLATILE, 31686f19c83bSHermès Bélusca-Maïto NULL); 31696f19c83bSHermès Bélusca-Maïto } 31706f19c83bSHermès Bélusca-Maïto 31716f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 31726f19c83bSHermès Bélusca-Maïto { 31736f19c83bSHermès Bélusca-Maïto DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); 31746f19c83bSHermès Bélusca-Maïto return FALSE; 31756f19c83bSHermès Bélusca-Maïto } 31766f19c83bSHermès Bélusca-Maïto 31776f19c83bSHermès Bélusca-Maïto MountInfo.Signature = Signature; 31786f19c83bSHermès Bélusca-Maïto MountInfo.StartingOffset = StartingOffset; 31796f19c83bSHermès Bélusca-Maïto Status = NtSetValueKey(KeyHandle, 31806f19c83bSHermès Bélusca-Maïto &ValueName, 31816f19c83bSHermès Bélusca-Maïto 0, 31826f19c83bSHermès Bélusca-Maïto REG_BINARY, 31836f19c83bSHermès Bélusca-Maïto (PVOID)&MountInfo, 31846f19c83bSHermès Bélusca-Maïto sizeof(MountInfo)); 31856f19c83bSHermès Bélusca-Maïto NtClose(KeyHandle); 31866f19c83bSHermès Bélusca-Maïto if (!NT_SUCCESS(Status)) 31876f19c83bSHermès Bélusca-Maïto { 31886f19c83bSHermès Bélusca-Maïto DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); 31896f19c83bSHermès Bélusca-Maïto return FALSE; 31906f19c83bSHermès Bélusca-Maïto } 31916f19c83bSHermès Bélusca-Maïto 31926f19c83bSHermès Bélusca-Maïto return TRUE; 31936f19c83bSHermès Bélusca-Maïto } 31946f19c83bSHermès Bélusca-Maïto 31956f19c83bSHermès Bélusca-Maïto BOOLEAN 31966f19c83bSHermès Bélusca-Maïto SetMountedDeviceValues( 31976f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 31986f19c83bSHermès Bélusca-Maïto { 31996f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry1, Entry2; 32006f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 32016f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 32026f19c83bSHermès Bélusca-Maïto LARGE_INTEGER StartingOffset; 32036f19c83bSHermès Bélusca-Maïto 32046f19c83bSHermès Bélusca-Maïto if (List == NULL) 32056f19c83bSHermès Bélusca-Maïto return FALSE; 32066f19c83bSHermès Bélusca-Maïto 32076f19c83bSHermès Bélusca-Maïto Entry1 = List->DiskListHead.Flink; 32086f19c83bSHermès Bélusca-Maïto while (Entry1 != &List->DiskListHead) 32096f19c83bSHermès Bélusca-Maïto { 32106f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry1, 32116f19c83bSHermès Bélusca-Maïto DISKENTRY, 32126f19c83bSHermès Bélusca-Maïto ListEntry); 32136f19c83bSHermès Bélusca-Maïto 32146f19c83bSHermès Bélusca-Maïto Entry2 = DiskEntry->PrimaryPartListHead.Flink; 32156f19c83bSHermès Bélusca-Maïto while (Entry2 != &DiskEntry->PrimaryPartListHead) 32166f19c83bSHermès Bélusca-Maïto { 32176f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); 32186f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned) 32196f19c83bSHermès Bélusca-Maïto { 32206f19c83bSHermès Bélusca-Maïto /* Assign a "\DosDevices\#:" mount point to this partition */ 32216f19c83bSHermès Bélusca-Maïto if (PartEntry->DriveLetter) 32226f19c83bSHermès Bélusca-Maïto { 32236f19c83bSHermès Bélusca-Maïto StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; 32246f19c83bSHermès Bélusca-Maïto if (!SetMountedDeviceValue(PartEntry->DriveLetter, 32256f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->Signature, 32266f19c83bSHermès Bélusca-Maïto StartingOffset)) 32276f19c83bSHermès Bélusca-Maïto { 32286f19c83bSHermès Bélusca-Maïto return FALSE; 32296f19c83bSHermès Bélusca-Maïto } 32306f19c83bSHermès Bélusca-Maïto } 32316f19c83bSHermès Bélusca-Maïto } 32326f19c83bSHermès Bélusca-Maïto 32336f19c83bSHermès Bélusca-Maïto Entry2 = Entry2->Flink; 32346f19c83bSHermès Bélusca-Maïto } 32356f19c83bSHermès Bélusca-Maïto 32366f19c83bSHermès Bélusca-Maïto Entry2 = DiskEntry->LogicalPartListHead.Flink; 32376f19c83bSHermès Bélusca-Maïto while (Entry2 != &DiskEntry->LogicalPartListHead) 32386f19c83bSHermès Bélusca-Maïto { 32396f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); 32406f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned) 32416f19c83bSHermès Bélusca-Maïto { 32426f19c83bSHermès Bélusca-Maïto /* Assign a "\DosDevices\#:" mount point to this partition */ 32436f19c83bSHermès Bélusca-Maïto if (PartEntry->DriveLetter) 32446f19c83bSHermès Bélusca-Maïto { 32456f19c83bSHermès Bélusca-Maïto StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector; 32466f19c83bSHermès Bélusca-Maïto if (!SetMountedDeviceValue(PartEntry->DriveLetter, 32476f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->Signature, 32486f19c83bSHermès Bélusca-Maïto StartingOffset)) 32496f19c83bSHermès Bélusca-Maïto { 32506f19c83bSHermès Bélusca-Maïto return FALSE; 32516f19c83bSHermès Bélusca-Maïto } 32526f19c83bSHermès Bélusca-Maïto } 32536f19c83bSHermès Bélusca-Maïto } 32546f19c83bSHermès Bélusca-Maïto 32556f19c83bSHermès Bélusca-Maïto Entry2 = Entry2->Flink; 32566f19c83bSHermès Bélusca-Maïto } 32576f19c83bSHermès Bélusca-Maïto 32586f19c83bSHermès Bélusca-Maïto Entry1 = Entry1->Flink; 32596f19c83bSHermès Bélusca-Maïto } 32606f19c83bSHermès Bélusca-Maïto 32616f19c83bSHermès Bélusca-Maïto return TRUE; 32626f19c83bSHermès Bélusca-Maïto } 32636f19c83bSHermès Bélusca-Maïto 32646f19c83bSHermès Bélusca-Maïto VOID 32656f19c83bSHermès Bélusca-Maïto SetPartitionType( 32666f19c83bSHermès Bélusca-Maïto IN PPARTENTRY PartEntry, 32676f19c83bSHermès Bélusca-Maïto IN UCHAR PartitionType) 32686f19c83bSHermès Bélusca-Maïto { 32696f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry = PartEntry->DiskEntry; 32706f19c83bSHermès Bélusca-Maïto 32716f19c83bSHermès Bélusca-Maïto PartEntry->PartitionType = PartitionType; 32726f19c83bSHermès Bélusca-Maïto 32736f19c83bSHermès Bélusca-Maïto DiskEntry->Dirty = TRUE; 32746f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType; 32756f19c83bSHermès Bélusca-Maïto DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE; 32766f19c83bSHermès Bélusca-Maïto } 32776f19c83bSHermès Bélusca-Maïto 32786f19c83bSHermès Bélusca-Maïto ERROR_NUMBER 32796f19c83bSHermès Bélusca-Maïto PrimaryPartitionCreationChecks( 32806f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 32816f19c83bSHermès Bélusca-Maïto { 32826f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 32836f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 32846f19c83bSHermès Bélusca-Maïto 32856f19c83bSHermès Bélusca-Maïto DiskEntry = List->CurrentDisk; 32866f19c83bSHermès Bélusca-Maïto PartEntry = List->CurrentPartition; 32876f19c83bSHermès Bélusca-Maïto 32886f19c83bSHermès Bélusca-Maïto /* Fail if the partition is already in use */ 32896f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned != FALSE) 32906f19c83bSHermès Bélusca-Maïto return ERROR_NEW_PARTITION; 32916f19c83bSHermès Bélusca-Maïto 32926f19c83bSHermès Bélusca-Maïto /* Fail if there are already 4 primary partitions in the list */ 32936f19c83bSHermès Bélusca-Maïto if (GetPrimaryPartitionCount(DiskEntry) >= 4) 32946f19c83bSHermès Bélusca-Maïto return ERROR_PARTITION_TABLE_FULL; 32956f19c83bSHermès Bélusca-Maïto 32966f19c83bSHermès Bélusca-Maïto return ERROR_SUCCESS; 32976f19c83bSHermès Bélusca-Maïto } 32986f19c83bSHermès Bélusca-Maïto 32996f19c83bSHermès Bélusca-Maïto ERROR_NUMBER 33006f19c83bSHermès Bélusca-Maïto ExtendedPartitionCreationChecks( 33016f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 33026f19c83bSHermès Bélusca-Maïto { 33036f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 33046f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 33056f19c83bSHermès Bélusca-Maïto 33066f19c83bSHermès Bélusca-Maïto DiskEntry = List->CurrentDisk; 33076f19c83bSHermès Bélusca-Maïto PartEntry = List->CurrentPartition; 33086f19c83bSHermès Bélusca-Maïto 33096f19c83bSHermès Bélusca-Maïto /* Fail if the partition is already in use */ 33106f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned != FALSE) 33116f19c83bSHermès Bélusca-Maïto return ERROR_NEW_PARTITION; 33126f19c83bSHermès Bélusca-Maïto 33136f19c83bSHermès Bélusca-Maïto /* Fail if there are already 4 primary partitions in the list */ 33146f19c83bSHermès Bélusca-Maïto if (GetPrimaryPartitionCount(DiskEntry) >= 4) 33156f19c83bSHermès Bélusca-Maïto return ERROR_PARTITION_TABLE_FULL; 33166f19c83bSHermès Bélusca-Maïto 33176f19c83bSHermès Bélusca-Maïto /* Fail if there is another extended partition in the list */ 33186f19c83bSHermès Bélusca-Maïto if (DiskEntry->ExtendedPartition != NULL) 33196f19c83bSHermès Bélusca-Maïto return ERROR_ONLY_ONE_EXTENDED; 33206f19c83bSHermès Bélusca-Maïto 33216f19c83bSHermès Bélusca-Maïto return ERROR_SUCCESS; 33226f19c83bSHermès Bélusca-Maïto } 33236f19c83bSHermès Bélusca-Maïto 33246f19c83bSHermès Bélusca-Maïto ERROR_NUMBER 33256f19c83bSHermès Bélusca-Maïto LogicalPartitionCreationChecks( 33266f19c83bSHermès Bélusca-Maïto IN PPARTLIST List) 33276f19c83bSHermès Bélusca-Maïto { 33286f19c83bSHermès Bélusca-Maïto // PDISKENTRY DiskEntry; 33296f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 33306f19c83bSHermès Bélusca-Maïto 33316f19c83bSHermès Bélusca-Maïto // DiskEntry = List->CurrentDisk; 33326f19c83bSHermès Bélusca-Maïto PartEntry = List->CurrentPartition; 33336f19c83bSHermès Bélusca-Maïto 33346f19c83bSHermès Bélusca-Maïto /* Fail if the partition is already in use */ 33356f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned != FALSE) 33366f19c83bSHermès Bélusca-Maïto return ERROR_NEW_PARTITION; 33376f19c83bSHermès Bélusca-Maïto 33386f19c83bSHermès Bélusca-Maïto return ERROR_SUCCESS; 33396f19c83bSHermès Bélusca-Maïto } 33406f19c83bSHermès Bélusca-Maïto 33416f19c83bSHermès Bélusca-Maïto BOOLEAN 33426f19c83bSHermès Bélusca-Maïto GetNextUnformattedPartition( 33436f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 33446f19c83bSHermès Bélusca-Maïto OUT PDISKENTRY *pDiskEntry OPTIONAL, 33456f19c83bSHermès Bélusca-Maïto OUT PPARTENTRY *pPartEntry) 33466f19c83bSHermès Bélusca-Maïto { 33476f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry1, Entry2; 33486f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 33496f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 33506f19c83bSHermès Bélusca-Maïto 33516f19c83bSHermès Bélusca-Maïto Entry1 = List->DiskListHead.Flink; 33526f19c83bSHermès Bélusca-Maïto while (Entry1 != &List->DiskListHead) 33536f19c83bSHermès Bélusca-Maïto { 33546f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry1, 33556f19c83bSHermès Bélusca-Maïto DISKENTRY, 33566f19c83bSHermès Bélusca-Maïto ListEntry); 33576f19c83bSHermès Bélusca-Maïto 33586f19c83bSHermès Bélusca-Maïto Entry2 = DiskEntry->PrimaryPartListHead.Flink; 33596f19c83bSHermès Bélusca-Maïto while (Entry2 != &DiskEntry->PrimaryPartListHead) 33606f19c83bSHermès Bélusca-Maïto { 33616f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); 33626f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned && PartEntry->New) 33636f19c83bSHermès Bélusca-Maïto { 33646f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry == PartEntry->DiskEntry); 33656f19c83bSHermès Bélusca-Maïto if (pDiskEntry) *pDiskEntry = DiskEntry; 33666f19c83bSHermès Bélusca-Maïto *pPartEntry = PartEntry; 33676f19c83bSHermès Bélusca-Maïto return TRUE; 33686f19c83bSHermès Bélusca-Maïto } 33696f19c83bSHermès Bélusca-Maïto 33706f19c83bSHermès Bélusca-Maïto Entry2 = Entry2->Flink; 33716f19c83bSHermès Bélusca-Maïto } 33726f19c83bSHermès Bélusca-Maïto 33736f19c83bSHermès Bélusca-Maïto Entry2 = DiskEntry->LogicalPartListHead.Flink; 33746f19c83bSHermès Bélusca-Maïto while (Entry2 != &DiskEntry->LogicalPartListHead) 33756f19c83bSHermès Bélusca-Maïto { 33766f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); 33776f19c83bSHermès Bélusca-Maïto if (PartEntry->IsPartitioned && PartEntry->New) 33786f19c83bSHermès Bélusca-Maïto { 33796f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry == PartEntry->DiskEntry); 33806f19c83bSHermès Bélusca-Maïto if (pDiskEntry) *pDiskEntry = DiskEntry; 33816f19c83bSHermès Bélusca-Maïto *pPartEntry = PartEntry; 33826f19c83bSHermès Bélusca-Maïto return TRUE; 33836f19c83bSHermès Bélusca-Maïto } 33846f19c83bSHermès Bélusca-Maïto 33856f19c83bSHermès Bélusca-Maïto Entry2 = Entry2->Flink; 33866f19c83bSHermès Bélusca-Maïto } 33876f19c83bSHermès Bélusca-Maïto 33886f19c83bSHermès Bélusca-Maïto Entry1 = Entry1->Flink; 33896f19c83bSHermès Bélusca-Maïto } 33906f19c83bSHermès Bélusca-Maïto 33916f19c83bSHermès Bélusca-Maïto if (pDiskEntry) *pDiskEntry = NULL; 33926f19c83bSHermès Bélusca-Maïto *pPartEntry = NULL; 33936f19c83bSHermès Bélusca-Maïto 33946f19c83bSHermès Bélusca-Maïto return FALSE; 33956f19c83bSHermès Bélusca-Maïto } 33966f19c83bSHermès Bélusca-Maïto 33976f19c83bSHermès Bélusca-Maïto BOOLEAN 33986f19c83bSHermès Bélusca-Maïto GetNextUncheckedPartition( 33996f19c83bSHermès Bélusca-Maïto IN PPARTLIST List, 34006f19c83bSHermès Bélusca-Maïto OUT PDISKENTRY *pDiskEntry OPTIONAL, 34016f19c83bSHermès Bélusca-Maïto OUT PPARTENTRY *pPartEntry) 34026f19c83bSHermès Bélusca-Maïto { 34036f19c83bSHermès Bélusca-Maïto PLIST_ENTRY Entry1, Entry2; 34046f19c83bSHermès Bélusca-Maïto PDISKENTRY DiskEntry; 34056f19c83bSHermès Bélusca-Maïto PPARTENTRY PartEntry; 34066f19c83bSHermès Bélusca-Maïto 34076f19c83bSHermès Bélusca-Maïto Entry1 = List->DiskListHead.Flink; 34086f19c83bSHermès Bélusca-Maïto while (Entry1 != &List->DiskListHead) 34096f19c83bSHermès Bélusca-Maïto { 34106f19c83bSHermès Bélusca-Maïto DiskEntry = CONTAINING_RECORD(Entry1, 34116f19c83bSHermès Bélusca-Maïto DISKENTRY, 34126f19c83bSHermès Bélusca-Maïto ListEntry); 34136f19c83bSHermès Bélusca-Maïto 34146f19c83bSHermès Bélusca-Maïto Entry2 = DiskEntry->PrimaryPartListHead.Flink; 34156f19c83bSHermès Bélusca-Maïto while (Entry2 != &DiskEntry->PrimaryPartListHead) 34166f19c83bSHermès Bélusca-Maïto { 34176f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); 34186f19c83bSHermès Bélusca-Maïto if (PartEntry->NeedsCheck == TRUE) 34196f19c83bSHermès Bélusca-Maïto { 34206f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry == PartEntry->DiskEntry); 34216f19c83bSHermès Bélusca-Maïto if (pDiskEntry) *pDiskEntry = DiskEntry; 34226f19c83bSHermès Bélusca-Maïto *pPartEntry = PartEntry; 34236f19c83bSHermès Bélusca-Maïto return TRUE; 34246f19c83bSHermès Bélusca-Maïto } 34256f19c83bSHermès Bélusca-Maïto 34266f19c83bSHermès Bélusca-Maïto Entry2 = Entry2->Flink; 34276f19c83bSHermès Bélusca-Maïto } 34286f19c83bSHermès Bélusca-Maïto 34296f19c83bSHermès Bélusca-Maïto Entry2 = DiskEntry->LogicalPartListHead.Flink; 34306f19c83bSHermès Bélusca-Maïto while (Entry2 != &DiskEntry->LogicalPartListHead) 34316f19c83bSHermès Bélusca-Maïto { 34326f19c83bSHermès Bélusca-Maïto PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); 34336f19c83bSHermès Bélusca-Maïto if (PartEntry->NeedsCheck == TRUE) 34346f19c83bSHermès Bélusca-Maïto { 34356f19c83bSHermès Bélusca-Maïto ASSERT(DiskEntry == PartEntry->DiskEntry); 34366f19c83bSHermès Bélusca-Maïto if (pDiskEntry) *pDiskEntry = DiskEntry; 34376f19c83bSHermès Bélusca-Maïto *pPartEntry = PartEntry; 34386f19c83bSHermès Bélusca-Maïto return TRUE; 34396f19c83bSHermès Bélusca-Maïto } 34406f19c83bSHermès Bélusca-Maïto 34416f19c83bSHermès Bélusca-Maïto Entry2 = Entry2->Flink; 34426f19c83bSHermès Bélusca-Maïto } 34436f19c83bSHermès Bélusca-Maïto 34446f19c83bSHermès Bélusca-Maïto Entry1 = Entry1->Flink; 34456f19c83bSHermès Bélusca-Maïto } 34466f19c83bSHermès Bélusca-Maïto 34476f19c83bSHermès Bélusca-Maïto if (pDiskEntry) *pDiskEntry = NULL; 34486f19c83bSHermès Bélusca-Maïto *pPartEntry = NULL; 34496f19c83bSHermès Bélusca-Maïto 34506f19c83bSHermès Bélusca-Maïto return FALSE; 34516f19c83bSHermès Bélusca-Maïto } 34526f19c83bSHermès Bélusca-Maïto 34536f19c83bSHermès Bélusca-Maïto /* EOF */ 3454