3 * Copyright (C) 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/partlist.c
23 * PURPOSE: Partition list functions
24 * PROGRAMMER: Eric Kohl
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
28 #include <ddk/ntddk.h>
29 #include <ddk/ntddscsi.h>
31 #include <ntdll/rtl.h>
33 #include <ntos/minmax.h>
41 /* FUNCTIONS ****************************************************************/
44 AddPartitionList(ULONG DiskNumber,
46 DRIVE_LAYOUT_INFORMATION *LayoutBuffer)
51 BOOLEAN LastEntryWasUnused;
52 ULONGLONG LastStartingOffset;
53 ULONGLONG LastPartitionSize;
54 ULONGLONG LastUnusedPartitionSize;
55 ULONG LastUnusedEntry;
59 * Determine required number of partiton entries.
60 * This must include entries for unused disk space.
63 /* Check for unpartitioned disk */
64 if (LayoutBuffer->PartitionCount == 0)
70 EntryCount = LayoutBuffer->PartitionCount;
74 DiskEntry->PartArray = (PPARTENTRY)RtlAllocateHeap(ProcessHeap,
76 EntryCount * sizeof(PARTENTRY));
77 DiskEntry->PartCount = EntryCount;
79 RtlZeroMemory(DiskEntry->PartArray,
80 EntryCount * sizeof(PARTENTRY));
82 if (LayoutBuffer->PartitionCount == 0)
84 /* Initialize an 'Unpartitioned space' entry */
85 PartEntry = &DiskEntry->PartArray[0];
87 PartEntry->Unpartitioned = TRUE;
88 // Start partition at head 1, cylinder 0
89 PartEntry->StartingOffset = DiskEntry->SectorsPerTrack * DiskEntry->BytesPerSector;
90 PartEntry->PartSize = DiskEntry->DiskSize - PartEntry->StartingOffset;
91 PartEntry->Used = FALSE;
92 PartEntry->HidePartEntry = FALSE;
93 PartEntry->PartNumber = 1;
97 LastEntryWasUnused = FALSE;
98 // Start partition at head 1, cylinder 0
99 LastStartingOffset = DiskEntry->SectorsPerTrack * DiskEntry->BytesPerSector;
100 LastPartitionSize = 0;
101 LastUnusedEntry = -1;
102 LastUnusedPartitionSize = 0;
103 for (i = 0; i < LayoutBuffer->PartitionCount; i++)
105 PartEntry = &DiskEntry->PartArray[i];
107 if ((LayoutBuffer->PartitionEntry[i].PartitionType != PARTITION_ENTRY_UNUSED) &&
108 (!IsContainerPartition(LayoutBuffer->PartitionEntry[i].PartitionType)))
110 LastUnusedPartitionSize = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart
111 - (LastStartingOffset + LastPartitionSize);
112 if (LastUnusedEntry != -1)
114 DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize;
115 DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize;
116 DiskEntry->PartArray[LastUnusedEntry].PartNumber = LastUnusedEntry + 1; /* FIXME: Is this always correct? */
118 LastStartingOffset = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart;
119 LastPartitionSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart;
121 PartEntry->StartingOffset = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart;
122 PartEntry->PartSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart;
123 PartEntry->PartNumber = LayoutBuffer->PartitionEntry[i].PartitionNumber,
124 PartEntry->PartType = LayoutBuffer->PartitionEntry[i].PartitionType;
125 PartEntry->Active = LayoutBuffer->PartitionEntry[i].BootIndicator;
127 PartEntry->DriveLetter = GetDriveLetter(DiskNumber,
128 LayoutBuffer->PartitionEntry[i].PartitionNumber);
130 PartEntry->Unpartitioned = FALSE;
132 PartEntry->Used = TRUE;
133 PartEntry->HidePartEntry = FALSE;
134 LastEntryWasUnused = FALSE;
135 LastUnusedEntry = -1;
139 if (LastEntryWasUnused)
141 /* Group unused entries into one unpartitioned disk space area */
142 PartEntry->HidePartEntry = TRUE;
143 PartEntry->PartSize = 0;
150 PartEntry->Unpartitioned = TRUE;
152 PartEntry->Used = FALSE;
153 LastEntryWasUnused = TRUE;
156 LastUnusedPartitionSize = DiskEntry->DiskSize
157 - (LastStartingOffset + LastPartitionSize);
158 if (LastUnusedEntry != -1)
160 DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize;
161 DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize;
162 DiskEntry->PartArray[LastUnusedEntry].PartNumber = LastUnusedEntry + 1; /* FIXME: Is this always correct? */
169 GetDriverName(PDISKENTRY DiskEntry)
171 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
175 RtlInitUnicodeString(&DiskEntry->DriverName,
179 L"\\Scsi\\Scsi Port %lu",
182 RtlZeroMemory(&QueryTable,
185 QueryTable[0].Name = L"Driver";
186 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
187 QueryTable[0].EntryContext = &DiskEntry->DriverName;
189 Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
194 if (!NT_SUCCESS(Status))
196 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
202 CreatePartitionListNoGUI()
205 OBJECT_ATTRIBUTES ObjectAttributes;
206 SYSTEM_DEVICE_INFORMATION Sdi;
207 DISK_GEOMETRY DiskGeometry;
208 IO_STATUS_BLOCK Iosb;
212 WCHAR Buffer[MAX_PATH];
215 DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
216 SCSI_ADDRESS ScsiAddress;
218 List = (PPARTLIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTLIST));
229 List->TopDisk = (ULONG)-1;
230 List->TopPartition = (ULONG)-1;
232 List->CurrentDisk = (ULONG)-1;
233 List->CurrentPartition = (ULONG)-1;
236 List->DiskArray = NULL;
239 Status = NtQuerySystemInformation(SystemDeviceInformation,
241 sizeof(SYSTEM_DEVICE_INFORMATION),
243 if (!NT_SUCCESS(Status))
245 RtlFreeHeap(ProcessHeap, 0, List);
249 List->DiskArray = (PDISKENTRY)RtlAllocateHeap(ProcessHeap,
251 Sdi.NumberOfDisks * sizeof(DISKENTRY));
252 List->DiskCount = Sdi.NumberOfDisks;
254 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
257 L"\\Device\\Harddisk%d\\Partition0",
259 RtlInitUnicodeString(&Name,
262 InitializeObjectAttributes(&ObjectAttributes,
268 Status = NtOpenFile(&FileHandle,
273 FILE_SYNCHRONOUS_IO_NONALERT);
274 if (NT_SUCCESS(Status))
276 Status = NtDeviceIoControlFile(FileHandle,
281 IOCTL_DISK_GET_DRIVE_GEOMETRY,
285 sizeof(DISK_GEOMETRY));
286 if (NT_SUCCESS(Status))
288 if (DiskGeometry.MediaType == FixedMedia)
290 Status = NtDeviceIoControlFile(FileHandle,
295 IOCTL_SCSI_GET_ADDRESS,
299 sizeof(SCSI_ADDRESS));
302 List->DiskArray[DiskNumber].Cylinders = DiskGeometry.Cylinders.QuadPart;
303 List->DiskArray[DiskNumber].TracksPerCylinder = DiskGeometry.TracksPerCylinder;
304 List->DiskArray[DiskNumber].SectorsPerTrack = DiskGeometry.SectorsPerTrack;
305 List->DiskArray[DiskNumber].BytesPerSector = DiskGeometry.BytesPerSector;
307 DPRINT("Cylinders %d\n", List->DiskArray[DiskNumber].Cylinders);
308 DPRINT("TracksPerCylinder %d\n", List->DiskArray[DiskNumber].TracksPerCylinder);
309 DPRINT("SectorsPerTrack %d\n", List->DiskArray[DiskNumber].SectorsPerTrack);
310 DPRINT("BytesPerSector %d\n", List->DiskArray[DiskNumber].BytesPerSector);
312 List->DiskArray[DiskNumber].DiskSize =
313 DiskGeometry.Cylinders.QuadPart *
314 (ULONGLONG)DiskGeometry.TracksPerCylinder *
315 (ULONGLONG)DiskGeometry.SectorsPerTrack *
316 (ULONGLONG)DiskGeometry.BytesPerSector;
317 List->DiskArray[DiskNumber].DiskNumber = DiskNumber;
318 List->DiskArray[DiskNumber].Port = ScsiAddress.PortNumber;
319 List->DiskArray[DiskNumber].Bus = ScsiAddress.PathId;
320 List->DiskArray[DiskNumber].Id = ScsiAddress.TargetId;
322 List->DiskArray[DiskNumber].FixedDisk = TRUE;
324 GetDriverName(&List->DiskArray[DiskNumber]);
326 LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192);
328 Status = NtDeviceIoControlFile(FileHandle,
333 IOCTL_DISK_GET_DRIVE_LAYOUT,
338 if (NT_SUCCESS(Status))
340 AddPartitionList(DiskNumber,
341 &List->DiskArray[DiskNumber],
345 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
349 /* mark removable disk entry */
350 List->DiskArray[DiskNumber].FixedDisk = FALSE;
351 List->DiskArray[DiskNumber].PartCount = 0;
352 List->DiskArray[DiskNumber].PartArray = NULL;
361 List->TopPartition = 0;
363 /* FIXME: search for first usable disk and partition */
364 List->CurrentDisk = 0;
365 List->CurrentPartition = 0;
371 CreatePartitionList(SHORT Left,
378 List = CreatePartitionListNoGUI();
385 List->Bottom = Bottom;
387 DrawPartitionList(List);
394 GetPartitionInformation(PPARTLIST List,
396 ULONG PartitionNumber,
397 PULONG PartEntryNumber)
399 PPARTENTRY PartEntry;
402 if (List->DiskArray == NULL)
407 if (DiskNumber >= List->DiskCount)
412 if (PartitionNumber >= List->DiskArray[DiskNumber].PartCount)
417 if (List->DiskArray[DiskNumber].FixedDisk != TRUE)
422 for (i = 0; i < List->DiskArray[DiskNumber].PartCount; i++)
424 PartEntry = &List->DiskArray[DiskNumber].PartArray[i];
425 if (PartEntry->PartNumber == PartitionNumber)
427 *PartEntryNumber = i;
435 MarkPartitionActive(ULONG DiskNumber,
436 ULONG PartitionNumber,
437 PPARTDATA ActivePartition)
440 PPARTENTRY PartEntry;
441 ULONG PartEntryNumber;
442 OBJECT_ATTRIBUTES ObjectAttributes;
443 DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
444 IO_STATUS_BLOCK Iosb;
446 WCHAR Buffer[MAX_PATH];
450 List = CreatePartitionListNoGUI();
456 PartEntry = GetPartitionInformation(List,
462 DestroyPartitionList(List);
468 L"\\Device\\Harddisk%d\\Partition0",
470 RtlInitUnicodeString(&Name, Buffer);
472 InitializeObjectAttributes(&ObjectAttributes,
478 Status = NtOpenFile(&FileHandle,
483 FILE_SYNCHRONOUS_IO_NONALERT);
484 if (NT_SUCCESS(Status))
486 LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192);
488 Status = NtDeviceIoControlFile(FileHandle,
493 IOCTL_DISK_GET_DRIVE_LAYOUT,
498 if (!NT_SUCCESS(Status))
501 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
502 DestroyPartitionList(List);
507 LayoutBuffer->PartitionEntry[PartEntryNumber].BootIndicator = TRUE;
509 Status = NtDeviceIoControlFile(FileHandle,
514 IOCTL_DISK_SET_DRIVE_LAYOUT,
519 if (!NT_SUCCESS(Status))
522 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
523 DestroyPartitionList(List);
530 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
531 DestroyPartitionList(List);
536 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
538 PartEntry->Active = TRUE;
539 if (!GetActiveBootPartition(List, ActivePartition))
541 DestroyPartitionList(List);
542 DPRINT("GetActiveBootPartition() failed\n");
546 DestroyPartitionList(List);
553 DestroyPartitionList(PPARTLIST List)
560 /* clear occupied screen area */
561 coPos.X = List->Left;
562 Width = List->Right - List->Left + 1;
563 for (coPos.Y = List->Top; coPos.Y <= List->Bottom; coPos.Y++)
565 FillConsoleOutputAttribute(0x17,
570 FillConsoleOutputCharacter(' ',
577 /* Release disk and partition info */
578 if (List->DiskArray != NULL)
580 for (i = 0; i < List->DiskCount; i++)
582 /* Release driver name */
583 RtlFreeUnicodeString(&List->DiskArray[i].DriverName);
585 /* Release partition array */
586 if (List->DiskArray[i].PartArray != NULL)
588 RtlFreeHeap(ProcessHeap, 0, List->DiskArray[i].PartArray);
589 List->DiskArray[i].PartCount = 0;
590 List->DiskArray[i].PartArray = NULL;
594 /* Release disk array */
595 RtlFreeHeap(ProcessHeap, 0, List->DiskArray);
597 List->DiskArray = NULL;
600 /* Release list head */
601 RtlFreeHeap(ProcessHeap, 0, List);
606 PrintEmptyLine(PPARTLIST List)
613 Width = List->Right - List->Left - 1;
614 Height = List->Bottom - List->Top - 1;
616 if (List->Line < 0 || List->Line > Height)
619 coPos.X = List->Left + 1;
620 coPos.Y = List->Top + 1 + List->Line;
622 FillConsoleOutputAttribute(0x17,
627 FillConsoleOutputCharacter(' ',
637 PrintPartitionData(PPARTLIST List,
641 PPARTENTRY PartEntry;
642 CHAR LineBuffer[128];
653 Width = List->Right - List->Left - 1;
654 Height = List->Bottom - List->Top - 1;
656 if (List->Line < 0 || List->Line > Height)
659 coPos.X = List->Left + 1;
660 coPos.Y = List->Top + 1 + List->Line;
662 PartEntry = &List->DiskArray[DiskIndex].PartArray[PartIndex];
664 /* Determine partition type */
666 if (PartEntry->Unpartitioned == FALSE)
668 if ((PartEntry->PartType == PARTITION_FAT_12) ||
669 (PartEntry->PartType == PARTITION_FAT_16) ||
670 (PartEntry->PartType == PARTITION_HUGE) ||
671 (PartEntry->PartType == PARTITION_XINT13))
675 else if ((PartEntry->PartType == PARTITION_FAT32) ||
676 (PartEntry->PartType == PARTITION_FAT32_XINT13))
680 else if (PartEntry->PartType == PARTITION_IFS)
682 PartType = "NTFS"; /* FIXME: Not quite correct! */
688 if (PartEntry->PartSize >= 0x280000000ULL) /* 10 GB */
690 PartSize = (PartEntry->PartSize + (1 << 29)) >> 30;
695 if (PartEntry->PartSize >= 0xA00000ULL) /* 10 MB */
697 PartSize = (PartEntry->PartSize + (1 << 19)) >> 20;
702 PartSize = (PartEntry->PartSize + (1 << 9)) >> 10;
707 if (PartEntry->Unpartitioned == TRUE)
710 " Unpartitioned space %I64u %s",
714 else if (PartEntry->DriveLetter != (CHAR)0)
716 if (PartType == NULL)
719 "%c: Type %-3lu %I64u %s",
720 PartEntry->DriveLetter,
729 PartEntry->DriveLetter,
737 "%c: %s (%d: nr: %d type: %x) %I64u %s",
738 PartEntry->DriveLetter,
741 PartEntry->PartNumber,
750 "-- %s (%d: nr: %d type: %x) %I64u %s",
751 PartEntry->FileSystemName,
753 PartEntry->PartNumber,
759 Attribute = (List->CurrentDisk == DiskIndex &&
760 List->CurrentPartition == PartIndex) ? 0x71 : 0x17;
762 FillConsoleOutputCharacter(' ',
769 FillConsoleOutputAttribute(Attribute,
776 WriteConsoleOutputCharacters(LineBuffer,
777 min(strlen(LineBuffer), Width),
785 PrintDiskData(PPARTLIST List,
788 PDISKENTRY DiskEntry;
789 CHAR LineBuffer[128];
798 DiskEntry = &List->DiskArray[DiskIndex];
800 Width = List->Right - List->Left - 1;
801 Height = List->Bottom - List->Top - 1;
803 if (List->Line < 0 || List->Line > Height)
806 coPos.X = List->Left + 1;
807 coPos.Y = List->Top + 1 + List->Line;
810 if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
812 DiskSize = (DiskEntry->DiskSize + (1 << 29)) >> 30;
818 DiskSize = (DiskEntry->DiskSize + (1 << 19)) >> 20;
824 if (DiskEntry->DriverName.Length > 0)
827 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ",
830 DiskEntry->DiskNumber,
834 &DiskEntry->DriverName);
839 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)",
842 DiskEntry->DiskNumber,
848 FillConsoleOutputAttribute(0x17,
853 FillConsoleOutputCharacter(' ',
859 WriteConsoleOutputCharacters(LineBuffer,
860 min(strlen(LineBuffer), Width - 2),
865 /* Print separator line */
866 PrintEmptyLine(List);
869 /* Print partition lines*/
870 for (PartIndex = 0; PartIndex < DiskEntry->PartCount; PartIndex++)
872 if (!DiskEntry->PartArray[PartIndex].HidePartEntry)
874 PrintPartitionData(List,
880 /* Print separator line */
881 PrintEmptyLine(List);
886 DrawPartitionList(PPARTLIST List)
888 CHAR LineBuffer[128];
894 /* draw upper left corner */
895 coPos.X = List->Left;
897 FillConsoleOutputCharacter(0xDA, // '+',
902 /* draw upper edge */
903 coPos.X = List->Left + 1;
905 FillConsoleOutputCharacter(0xC4, // '-',
906 List->Right - List->Left - 1,
910 /* draw upper right corner */
911 coPos.X = List->Right;
913 FillConsoleOutputCharacter(0xBF, // '+',
918 /* draw left and right edge */
919 for (i = List->Top + 1; i < List->Bottom; i++)
921 coPos.X = List->Left;
923 FillConsoleOutputCharacter(0xB3, // '|',
928 coPos.X = List->Right;
929 FillConsoleOutputCharacter(0xB3, //'|',
935 /* draw lower left corner */
936 coPos.X = List->Left;
937 coPos.Y = List->Bottom;
938 FillConsoleOutputCharacter(0xC0, // '+',
943 /* draw lower edge */
944 coPos.X = List->Left + 1;
945 coPos.Y = List->Bottom;
946 FillConsoleOutputCharacter(0xC4, // '-',
947 List->Right - List->Left - 1,
951 /* draw lower right corner */
952 coPos.X = List->Right;
953 coPos.Y = List->Bottom;
954 FillConsoleOutputCharacter(0xD9, // '+',
959 /* print list entries */
961 for (DiskIndex = 0; DiskIndex < List->DiskCount; DiskIndex++)
963 if (List->DiskArray[DiskIndex].FixedDisk == TRUE)
965 /* Print disk entry */
974 ScrollDownPartitionList(PPARTLIST List)
979 /* check for available disks */
980 if (List->DiskCount == 0)
983 /* check for next usable entry on current disk */
984 for (i = List->CurrentPartition + 1; i < List->DiskArray[List->CurrentDisk].PartCount; i++)
986 if (!List->DiskArray[List->CurrentDisk].PartArray[i].HidePartEntry)
988 List->CurrentPartition = i;
989 DrawPartitionList(List);
994 /* check for first usable entry on next disk */
995 for (j = List->CurrentDisk + 1; j < List->DiskCount; j++)
997 for (i = 0; i < List->DiskArray[j].PartCount; i++)
999 if (!List->DiskArray[j].PartArray[i].HidePartEntry)
1001 List->CurrentDisk = j;
1002 List->CurrentPartition = i;
1003 DrawPartitionList(List);
1012 ScrollUpPartitionList(PPARTLIST List)
1017 /* check for available disks */
1018 if (List->DiskCount == 0)
1021 /* check for previous usable entry on current disk */
1022 for (i = List->CurrentPartition - 1; i != (ULONG)-1; i--)
1024 if (!List->DiskArray[List->CurrentDisk].PartArray[i].HidePartEntry)
1026 List->CurrentPartition = i;
1027 DrawPartitionList(List);
1032 /* check for last usable entry on previous disk */
1033 for (j = List->CurrentDisk - 1; j != (ULONG)-1; j--)
1035 for (i = List->DiskArray[j].PartCount - 1; i != (ULONG)-1; i--)
1037 if (!List->DiskArray[j].PartArray[i].HidePartEntry)
1039 List->CurrentDisk = j;
1040 List->CurrentPartition = i;
1041 DrawPartitionList(List);
1050 GetSelectedPartition(PPARTLIST List,
1053 PDISKENTRY DiskEntry;
1054 PPARTENTRY PartEntry;
1056 if (List->CurrentDisk >= List->DiskCount)
1059 DiskEntry = &List->DiskArray[List->CurrentDisk];
1061 if (DiskEntry->FixedDisk == FALSE)
1064 if (List->CurrentPartition >= DiskEntry->PartCount)
1067 PartEntry = &DiskEntry->PartArray[List->CurrentPartition];
1069 if (PartEntry->Used == FALSE)
1074 /* Copy disk-specific data */
1075 Data->DiskSize = DiskEntry->DiskSize;
1076 Data->DiskNumber = DiskEntry->DiskNumber;
1077 Data->Port = DiskEntry->Port;
1078 Data->Bus = DiskEntry->Bus;
1079 Data->Id = DiskEntry->Id;
1081 /* Copy driver name */
1082 RtlInitUnicodeString(&Data->DriverName,
1084 if (DiskEntry->DriverName.Length != 0)
1086 Data->DriverName.Buffer = RtlAllocateHeap(ProcessHeap,
1088 DiskEntry->DriverName.MaximumLength);
1089 if (Data->DriverName.Buffer != NULL)
1091 Data->DriverName.MaximumLength = DiskEntry->DriverName.MaximumLength;
1092 Data->DriverName.Length = DiskEntry->DriverName.Length;
1093 RtlCopyMemory(Data->DriverName.Buffer,
1094 DiskEntry->DriverName.Buffer,
1095 DiskEntry->DriverName.MaximumLength);
1099 /* Copy partition-specific data */
1100 Data->CreatePartition = FALSE;
1101 Data->NewPartSize = 0;
1102 Data->PartSize = PartEntry->PartSize;
1103 Data->PartNumber = PartEntry->PartNumber;
1104 Data->PartType = PartEntry->PartType;
1105 Data->DriveLetter = PartEntry->DriveLetter;
1111 GetActiveBootPartition(PPARTLIST List,
1114 PDISKENTRY DiskEntry;
1115 PPARTENTRY PartEntry;
1118 if (List->CurrentDisk >= List->DiskCount)
1121 DiskEntry = &List->DiskArray[List->CurrentDisk];
1123 if (DiskEntry->FixedDisk == FALSE)
1128 for (i = 0; i < DiskEntry->PartCount; i++)
1130 if (DiskEntry->PartArray[i].Active)
1132 PartEntry = &DiskEntry->PartArray[i];
1134 if (PartEntry->Used == FALSE)
1139 /* Copy disk-specific data */
1140 Data->DiskSize = DiskEntry->DiskSize;
1141 Data->DiskNumber = DiskEntry->DiskNumber;
1142 Data->Port = DiskEntry->Port;
1143 Data->Bus = DiskEntry->Bus;
1144 Data->Id = DiskEntry->Id;
1146 /* Copy driver name */
1147 RtlInitUnicodeString(&Data->DriverName,
1149 if (DiskEntry->DriverName.Length != 0)
1151 Data->DriverName.Buffer = RtlAllocateHeap(ProcessHeap,
1153 DiskEntry->DriverName.MaximumLength);
1154 if (Data->DriverName.Buffer != NULL)
1156 Data->DriverName.MaximumLength = DiskEntry->DriverName.MaximumLength;
1157 Data->DriverName.Length = DiskEntry->DriverName.Length;
1158 RtlCopyMemory(Data->DriverName.Buffer,
1159 DiskEntry->DriverName.Buffer,
1160 DiskEntry->DriverName.MaximumLength);
1164 /* Copy partition-specific data */
1165 Data->PartSize = PartEntry->PartSize;
1166 Data->PartNumber = PartEntry->PartNumber;
1167 Data->PartType = PartEntry->PartType;
1168 Data->DriveLetter = PartEntry->DriveLetter;
1179 CreateSelectedPartition(PPARTLIST List,
1181 ULONGLONG NewPartSize)
1183 PDISKENTRY DiskEntry;
1184 PPARTENTRY PartEntry;
1185 ULONG PartEntryNumber;
1186 OBJECT_ATTRIBUTES ObjectAttributes;
1187 DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
1188 IO_STATUS_BLOCK Iosb;
1190 WCHAR Buffer[MAX_PATH];
1191 UNICODE_STRING Name;
1195 DiskEntry = &List->DiskArray[List->CurrentDisk];
1196 PartEntry = &DiskEntry->PartArray[List->CurrentPartition];
1197 PartEntry->PartType = PartType;
1198 PartEntryNumber = List->CurrentPartition;
1200 DPRINT("NewPartSize %d (%d MB)\n", NewPartSize, NewPartSize / (1024 * 1024));
1201 DPRINT("PartEntry->StartingOffset %d\n", PartEntry->StartingOffset);
1202 DPRINT("PartEntry->PartSize %d\n", PartEntry->PartSize);
1203 DPRINT("PartEntry->PartNumber %d\n", PartEntry->PartNumber);
1204 DPRINT("PartEntry->PartType 0x%x\n", PartEntry->PartType);
1205 DPRINT("PartEntry->FileSystemName %s\n", PartEntry->FileSystemName);
1208 L"\\Device\\Harddisk%d\\Partition0",
1209 DiskEntry->DiskNumber);
1210 RtlInitUnicodeString(&Name, Buffer);
1212 InitializeObjectAttributes(&ObjectAttributes,
1218 Status = NtOpenFile(&FileHandle,
1223 FILE_SYNCHRONOUS_IO_NONALERT);
1224 if (NT_SUCCESS(Status))
1226 LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192);
1228 Status = NtDeviceIoControlFile(FileHandle,
1233 IOCTL_DISK_GET_DRIVE_LAYOUT,
1238 if (!NT_SUCCESS(Status))
1240 DPRINT("IOCTL_DISK_GET_DRIVE_LAYOUT failed() 0x%.08x\n", Status);
1241 NtClose(FileHandle);
1242 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
1246 li.QuadPart = PartEntry->StartingOffset;
1247 LayoutBuffer->PartitionEntry[PartEntryNumber].StartingOffset = li;
1248 li.QuadPart = NewPartSize;
1249 LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionLength = li;
1250 LayoutBuffer->PartitionEntry[PartEntryNumber].HiddenSectors = 0; /* FIXME: ? */
1251 LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionType = PartType;
1252 LayoutBuffer->PartitionEntry[PartEntryNumber].RecognizedPartition = TRUE;
1253 LayoutBuffer->PartitionEntry[PartEntryNumber].RewritePartition = TRUE;
1255 Status = NtDeviceIoControlFile(FileHandle,
1260 IOCTL_DISK_SET_DRIVE_LAYOUT,
1265 if (!NT_SUCCESS(Status))
1267 DPRINT("IOCTL_DISK_SET_DRIVE_LAYOUT failed() 0x%.08x\n", Status);
1268 NtClose(FileHandle);
1269 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
1275 DPRINT("NtOpenFile failed() 0x%.08x\n", Status);
1276 NtClose(FileHandle);
1277 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
1281 NtClose(FileHandle);
1282 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
1289 DeleteSelectedPartition(PPARTLIST List)
1291 PDISKENTRY DiskEntry;
1292 PPARTENTRY PartEntry;
1293 ULONG PartEntryNumber;
1294 OBJECT_ATTRIBUTES ObjectAttributes;
1295 DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
1296 IO_STATUS_BLOCK Iosb;
1298 WCHAR Buffer[MAX_PATH];
1299 UNICODE_STRING Name;
1303 DiskEntry = &List->DiskArray[List->CurrentDisk];
1304 PartEntry = &DiskEntry->PartArray[List->CurrentPartition];
1305 PartEntry->PartType = PARTITION_ENTRY_UNUSED;
1306 PartEntryNumber = List->CurrentPartition;
1308 DPRINT1("DeleteSelectedPartition(PartEntryNumber = %d)\n", PartEntryNumber);
1309 DPRINT1("PartEntry->StartingOffset %d\n", PartEntry->StartingOffset);
1310 DPRINT1("PartEntry->PartSize %d\n", PartEntry->PartSize);
1311 DPRINT1("PartEntry->PartNumber %d\n", PartEntry->PartNumber);
1312 DPRINT1("PartEntry->PartType 0x%x\n", PartEntry->PartType);
1313 DPRINT1("PartEntry->FileSystemName %s\n", PartEntry->FileSystemName);
1316 L"\\Device\\Harddisk%d\\Partition0",
1317 DiskEntry->DiskNumber);
1318 RtlInitUnicodeString(&Name, Buffer);
1320 InitializeObjectAttributes(&ObjectAttributes,
1326 Status = NtOpenFile(&FileHandle,
1331 FILE_SYNCHRONOUS_IO_NONALERT);
1332 if (NT_SUCCESS(Status))
1334 LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192);
1336 Status = NtDeviceIoControlFile(FileHandle,
1341 IOCTL_DISK_GET_DRIVE_LAYOUT,
1346 if (!NT_SUCCESS(Status))
1348 DPRINT("IOCTL_DISK_GET_DRIVE_LAYOUT failed() 0x%.08x\n", Status);
1349 NtClose(FileHandle);
1350 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
1355 LayoutBuffer->PartitionEntry[PartEntryNumber].StartingOffset = li;
1357 LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionLength = li;
1358 LayoutBuffer->PartitionEntry[PartEntryNumber].HiddenSectors = 0;
1359 LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionType = 0;
1360 LayoutBuffer->PartitionEntry[PartEntryNumber].RecognizedPartition = FALSE;
1361 LayoutBuffer->PartitionEntry[PartEntryNumber].RewritePartition = TRUE;
1363 Status = NtDeviceIoControlFile(FileHandle,
1368 IOCTL_DISK_SET_DRIVE_LAYOUT,
1373 if (!NT_SUCCESS(Status))
1375 DPRINT("IOCTL_DISK_SET_DRIVE_LAYOUT failed() 0x%.08x\n", Status);
1376 NtClose(FileHandle);
1377 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
1383 DPRINT("NtOpenFile failed() 0x%.08x\n", Status);
1384 NtClose(FileHandle);
1385 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
1389 NtClose(FileHandle);
1390 RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);