3 * Copyright (C) 2002, 2003, 2004, 2005 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)
33 /* FUNCTIONS ****************************************************************/
36 GetDriverName (PDISKENTRY DiskEntry
)
38 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
42 RtlInitUnicodeString (&DiskEntry
->DriverName
,
46 L
"\\Scsi\\Scsi Port %lu",
49 RtlZeroMemory (&QueryTable
,
52 QueryTable
[0].Name
= L
"Driver";
53 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
;
54 QueryTable
[0].EntryContext
= &DiskEntry
->DriverName
;
56 Status
= RtlQueryRegistryValues (RTL_REGISTRY_DEVICEMAP
,
61 if (!NT_SUCCESS (Status
))
63 DPRINT1 ("RtlQueryRegistryValues() failed (Status %lx)\n", Status
);
69 AssignDriverLetters (PPARTLIST List
)
79 /* Assign drive letters to primary partitions */
80 Entry1
= List
->DiskListHead
.Flink
;
81 while (Entry1
!= &List
->DiskListHead
)
83 DiskEntry
= CONTAINING_RECORD (Entry1
, DISKENTRY
, ListEntry
);
85 if (!IsListEmpty (&DiskEntry
->PartListHead
))
87 PartEntry
= CONTAINING_RECORD (DiskEntry
->PartListHead
.Flink
,
91 PartEntry
->DriveLetter
= 0;
93 if (PartEntry
->Unpartitioned
== FALSE
&&
94 !IsContainerPartition (PartEntry
->PartInfo
[0].PartitionType
))
96 if (IsRecognizedPartition (PartEntry
->PartInfo
[0].PartitionType
) ||
97 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
&&
98 PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
!= 0LL))
102 PartEntry
->DriveLetter
= Letter
;
109 Entry1
= Entry1
->Flink
;
113 /* Assign drive letters to logical drives */
114 Entry1
= List
->DiskListHead
.Flink
;
115 while (Entry1
!= &List
->DiskListHead
)
117 DiskEntry
= CONTAINING_RECORD (Entry1
, DISKENTRY
, ListEntry
);
119 Entry2
= DiskEntry
->PartListHead
.Flink
;
120 if (Entry2
!= &DiskEntry
->PartListHead
)
122 Entry2
= Entry2
->Flink
;
123 while (Entry2
!= &DiskEntry
->PartListHead
)
125 PartEntry
= CONTAINING_RECORD (Entry2
,
129 PartEntry
->DriveLetter
= 0;
131 if (PartEntry
->Unpartitioned
== FALSE
&&
132 !IsContainerPartition (PartEntry
->PartInfo
[0].PartitionType
))
134 if (IsRecognizedPartition (PartEntry
->PartInfo
[0].PartitionType
) ||
135 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
&&
136 PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
!= 0LL))
140 PartEntry
->DriveLetter
= Letter
;
146 Entry2
= Entry2
->Flink
;
150 Entry1
= Entry1
->Flink
;
156 UpdatePartitionNumbers (PDISKENTRY DiskEntry
)
158 PPARTENTRY PartEntry
;
164 Entry
= DiskEntry
->PartListHead
.Flink
;
165 while (Entry
!= &DiskEntry
->PartListHead
)
167 PartEntry
= CONTAINING_RECORD (Entry
,
171 if (PartEntry
->Unpartitioned
== TRUE
)
173 for (i
= 0; i
< 4; i
++)
175 PartEntry
->PartInfo
[i
].PartitionNumber
= 0;
180 for (i
= 0; i
< 4; i
++)
182 if (IsContainerPartition (PartEntry
->PartInfo
[i
].PartitionType
))
184 PartEntry
->PartInfo
[i
].PartitionNumber
= 0;
186 else if (PartEntry
->PartInfo
[i
].PartitionType
== PARTITION_ENTRY_UNUSED
&&
187 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
== 0ULL)
189 PartEntry
->PartInfo
[i
].PartitionNumber
= 0;
193 PartEntry
->PartInfo
[i
].PartitionNumber
= PartNumber
;
199 Entry
= Entry
->Flink
;
205 AddPartitionToList (ULONG DiskNumber
,
206 PDISKENTRY DiskEntry
,
207 DRIVE_LAYOUT_INFORMATION
*LayoutBuffer
)
209 PPARTENTRY PartEntry
;
213 for (i
= 0; i
< LayoutBuffer
->PartitionCount
; i
+= 4)
215 for (j
= 0; j
< 4; j
++)
217 if (LayoutBuffer
->PartitionEntry
[j
].PartitionType
!= PARTITION_ENTRY_UNUSED
||
218 LayoutBuffer
->PartitionEntry
[j
].PartitionLength
.QuadPart
!= 0ULL)
228 PartEntry
= (PPARTENTRY
)RtlAllocateHeap (ProcessHeap
,
231 if (PartEntry
== NULL
)
236 RtlZeroMemory (PartEntry
,
239 PartEntry
->Unpartitioned
= FALSE
;
241 for (j
= 0; j
< 4; j
++)
243 RtlCopyMemory (&PartEntry
->PartInfo
[j
],
244 &LayoutBuffer
->PartitionEntry
[i
+j
],
245 sizeof(PARTITION_INFORMATION
));
248 if (IsContainerPartition(PartEntry
->PartInfo
[0].PartitionType
))
250 PartEntry
->FormatState
= Unformatted
;
252 else if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
253 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
254 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
255 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_XINT13
) ||
256 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
257 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
260 if (CheckFatFormat())
262 PartEntry
->FormatState
= Preformatted
;
266 PartEntry
->FormatState
= Unformatted
;
269 PartEntry
->FormatState
= Preformatted
;
271 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
274 if (CheckNtfsFormat())
276 PartEntry
->FormatState
= Preformatted
;
278 else if (CheckHpfsFormat())
280 PartEntry
->FormatState
= Preformatted
;
284 PartEntry
->FormatState
= Unformatted
;
287 PartEntry
->FormatState
= Preformatted
;
291 PartEntry
->FormatState
= Unknown
;
294 InsertTailList (&DiskEntry
->PartListHead
,
295 &PartEntry
->ListEntry
);
301 ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry
)
303 ULONGLONG LastStartingOffset
;
304 ULONGLONG LastPartitionLength
;
305 ULONGLONG LastUnusedPartitionLength
;
306 PPARTENTRY PartEntry
;
307 PPARTENTRY NewPartEntry
;
312 if (IsListEmpty (&DiskEntry
->PartListHead
))
314 /* Create a partition table that represents the empty disk */
315 PartEntry
= (PPARTENTRY
)RtlAllocateHeap (ProcessHeap
,
318 if (PartEntry
== NULL
)
321 RtlZeroMemory (PartEntry
,
324 PartEntry
->Unpartitioned
= TRUE
;
325 PartEntry
->UnpartitionedOffset
= 0ULL;
326 PartEntry
->UnpartitionedLength
= DiskEntry
->DiskSize
;
328 PartEntry
->FormatState
= Unformatted
;
330 InsertTailList (&DiskEntry
->PartListHead
,
331 &PartEntry
->ListEntry
);
335 /* Start partition at head 1, cylinder 0 */
336 LastStartingOffset
= DiskEntry
->TrackSize
;
337 LastPartitionLength
= 0ULL;
338 LastUnusedPartitionLength
= 0ULL;
341 Entry
= DiskEntry
->PartListHead
.Flink
;
342 while (Entry
!= &DiskEntry
->PartListHead
)
344 PartEntry
= CONTAINING_RECORD (Entry
, PARTENTRY
, ListEntry
);
346 for (j
= 0; j
< 4; j
++)
348 if ((!IsContainerPartition (PartEntry
->PartInfo
[j
].PartitionType
)) &&
349 (PartEntry
->PartInfo
[j
].PartitionType
!= PARTITION_ENTRY_UNUSED
||
350 PartEntry
->PartInfo
[j
].PartitionLength
.QuadPart
!= 0LL))
352 LastUnusedPartitionLength
=
353 PartEntry
->PartInfo
[j
].StartingOffset
.QuadPart
-
354 (LastStartingOffset
+ LastPartitionLength
);
356 if (LastUnusedPartitionLength
>= DiskEntry
->CylinderSize
)
358 DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength
);
360 NewPartEntry
= (PPARTENTRY
)RtlAllocateHeap (ProcessHeap
,
363 if (NewPartEntry
== NULL
)
366 RtlZeroMemory (NewPartEntry
,
369 NewPartEntry
->Unpartitioned
= TRUE
;
370 NewPartEntry
->UnpartitionedOffset
= LastStartingOffset
+ LastPartitionLength
;
371 NewPartEntry
->UnpartitionedLength
= LastUnusedPartitionLength
;
373 NewPartEntry
->UnpartitionedLength
-= DiskEntry
->TrackSize
;
375 NewPartEntry
->FormatState
= Unformatted
;
377 /* Insert the table into the list */
378 InsertTailList (&PartEntry
->ListEntry
,
379 &NewPartEntry
->ListEntry
);
382 LastStartingOffset
= PartEntry
->PartInfo
[j
].StartingOffset
.QuadPart
;
383 LastPartitionLength
= PartEntry
->PartInfo
[j
].PartitionLength
.QuadPart
;
388 Entry
= Entry
->Flink
;
391 /* Check for trailing unpartitioned disk space */
392 if (DiskEntry
->DiskSize
> (LastStartingOffset
+ LastPartitionLength
))
394 /* Round-down to cylinder size */
395 LastUnusedPartitionLength
=
396 ROUND_DOWN (DiskEntry
->DiskSize
- (LastStartingOffset
+ LastPartitionLength
),
397 DiskEntry
->CylinderSize
);
399 if (LastUnusedPartitionLength
>= DiskEntry
->CylinderSize
)
401 DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength
);
403 NewPartEntry
= (PPARTENTRY
)RtlAllocateHeap (ProcessHeap
,
406 if (NewPartEntry
== NULL
)
409 RtlZeroMemory (NewPartEntry
,
412 NewPartEntry
->Unpartitioned
= TRUE
;
413 NewPartEntry
->UnpartitionedOffset
= LastStartingOffset
+ LastPartitionLength
;
414 NewPartEntry
->UnpartitionedLength
= LastUnusedPartitionLength
;
416 /* Append the table to the list */
417 InsertTailList (&DiskEntry
->PartListHead
,
418 &NewPartEntry
->ListEntry
);
426 DiskIdentifierQueryRoutine(PWSTR ValueName
,
433 PBIOSDISKENTRY BiosDiskEntry
= (PBIOSDISKENTRY
)Context
;
434 UNICODE_STRING NameU
;
436 if (ValueType
== REG_SZ
&&
437 ValueLength
== 20 * sizeof(WCHAR
))
439 NameU
.Buffer
= (PWCHAR
)ValueData
;
440 NameU
.Length
= NameU
.MaximumLength
= 8 * sizeof(WCHAR
);
441 RtlUnicodeStringToInteger(&NameU
, 16, &BiosDiskEntry
->Checksum
);
443 NameU
.Buffer
= (PWCHAR
)ValueData
+ 9;
444 RtlUnicodeStringToInteger(&NameU
, 16, &BiosDiskEntry
->Signature
);
446 return STATUS_SUCCESS
;
448 return STATUS_UNSUCCESSFUL
;
453 DiskConfigurationDataQueryRoutine(PWSTR ValueName
,
460 PBIOSDISKENTRY BiosDiskEntry
= (PBIOSDISKENTRY
)Context
;
461 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
462 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
;
464 if (ValueType
== REG_FULL_RESOURCE_DESCRIPTOR
&&
465 ValueLength
== sizeof(CM_FULL_RESOURCE_DESCRIPTOR
) + sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
))
467 FullResourceDescriptor
= (PCM_FULL_RESOURCE_DESCRIPTOR
)ValueData
;
469 * Is this 'paranoia' check correct ?
471 if (FullResourceDescriptor
->InterfaceType
!= InterfaceTypeUndefined
||
472 FullResourceDescriptor
->BusNumber
!= 0 ||
473 FullResourceDescriptor
->PartialResourceList
.Count
!= 1 ||
474 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
!= CmResourceTypeDeviceSpecific
||
475 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].u
.DeviceSpecificData
.DataSize
!= sizeof(CM_DISK_GEOMETRY_DEVICE_DATA
))
477 return STATUS_UNSUCCESSFUL
;
479 DiskGeometry
= (PCM_DISK_GEOMETRY_DEVICE_DATA
)(FullResourceDescriptor
+ 1);
480 BiosDiskEntry
->DiskGeometry
= *DiskGeometry
;
482 return STATUS_SUCCESS
;
484 return STATUS_UNSUCCESSFUL
;
489 SystemConfigurationDataQueryRoutine(PWSTR ValueName
,
496 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor
;
497 PCM_INT13_DRIVE_PARAMETER
* Int13Drives
= (PCM_INT13_DRIVE_PARAMETER
*)Context
;
499 if (ValueType
== REG_FULL_RESOURCE_DESCRIPTOR
&&
500 ValueLength
>= sizeof (CM_FULL_RESOURCE_DESCRIPTOR
) &&
501 (ValueLength
- sizeof(CM_FULL_RESOURCE_DESCRIPTOR
)) % sizeof(CM_INT13_DRIVE_PARAMETER
) == 0)
503 FullResourceDescriptor
= (PCM_FULL_RESOURCE_DESCRIPTOR
)ValueData
;
504 if (FullResourceDescriptor
->InterfaceType
!= InterfaceTypeUndefined
||
505 FullResourceDescriptor
->BusNumber
!= -1 ||
506 FullResourceDescriptor
->PartialResourceList
.Count
!= 1 ||
507 FullResourceDescriptor
->PartialResourceList
.PartialDescriptors
[0].Type
!= CmResourceTypeDeviceSpecific
)
509 return STATUS_UNSUCCESSFUL
;
511 *Int13Drives
= RtlAllocateHeap(ProcessHeap
, 0, ValueLength
- sizeof (CM_FULL_RESOURCE_DESCRIPTOR
));
512 if (*Int13Drives
== NULL
)
514 return STATUS_NO_MEMORY
;
516 memcpy(*Int13Drives
, FullResourceDescriptor
+ 1, ValueLength
- sizeof (CM_FULL_RESOURCE_DESCRIPTOR
));
517 return STATUS_SUCCESS
;
519 return STATUS_UNSUCCESSFUL
;
522 #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
525 EnumerateBiosDiskEntries(PPARTLIST PartList
)
527 RTL_QUERY_REGISTRY_TABLE QueryTable
[3];
532 PCM_INT13_DRIVE_PARAMETER Int13Drives
;
533 PBIOSDISKENTRY BiosDiskEntry
;
535 memset(QueryTable
, 0, sizeof(QueryTable
));
537 QueryTable
[1].Name
= L
"Configuration Data";
538 QueryTable
[1].QueryRoutine
= SystemConfigurationDataQueryRoutine
;
540 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
541 L
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
545 if (!NT_SUCCESS(Status
))
547 DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status
);
554 swprintf(Name
, L
"%s\\%lu", ROOT_NAME
, AdapterCount
);
555 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
560 if (!NT_SUCCESS(Status
))
565 swprintf(Name
, L
"%s\\%lu\\DiskController", ROOT_NAME
, AdapterCount
);
566 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
571 if (NT_SUCCESS(Status
))
575 swprintf(Name
, L
"%s\\%lu\\DiskController\\0", ROOT_NAME
, AdapterCount
);
576 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
581 if (!NT_SUCCESS(Status
))
583 RtlFreeHeap(ProcessHeap
, 0, Int13Drives
);
587 swprintf(Name
, L
"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME
, AdapterCount
);
588 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
593 if (NT_SUCCESS(Status
))
595 QueryTable
[0].Name
= L
"Identifier";
596 QueryTable
[0].QueryRoutine
= DiskIdentifierQueryRoutine
;
597 QueryTable
[1].Name
= L
"Configuration Data";
598 QueryTable
[1].QueryRoutine
= DiskConfigurationDataQueryRoutine
;
602 BiosDiskEntry
= RtlAllocateHeap(ProcessHeap
, HEAP_ZERO_MEMORY
, sizeof(BIOSDISKENTRY
));
603 if (BiosDiskEntry
== NULL
)
607 swprintf(Name
, L
"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME
, AdapterCount
, DiskCount
);
608 Status
= RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE
,
611 (PVOID
)BiosDiskEntry
,
613 if (!NT_SUCCESS(Status
))
615 RtlFreeHeap(ProcessHeap
, 0, BiosDiskEntry
);
618 BiosDiskEntry
->DiskNumber
= DiskCount
;
619 BiosDiskEntry
->Recognized
= FALSE
;
621 if (DiskCount
< Int13Drives
[0].NumberDrives
)
623 BiosDiskEntry
->Int13DiskData
= Int13Drives
[DiskCount
];
627 DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount
);
631 InsertTailList(&PartList
->BiosDiskListHead
, &BiosDiskEntry
->ListEntry
);
633 DPRINT("DiskNumber: %d\n", BiosDiskEntry
->DiskNumber
);
634 DPRINT("Signature: %08x\n", BiosDiskEntry
->Signature
);
635 DPRINT("Checksum: %08x\n", BiosDiskEntry
->Checksum
);
636 DPRINT("BytesPerSector: %d\n", BiosDiskEntry
->DiskGeometry
.BytesPerSector
);
637 DPRINT("NumberOfCylinders: %d\n", BiosDiskEntry
->DiskGeometry
.NumberOfCylinders
);
638 DPRINT("NumberOfHeads: %d\n", BiosDiskEntry
->DiskGeometry
.NumberOfHeads
);
639 DPRINT("DriveSelect: %02x\n", BiosDiskEntry
->Int13DiskData
.DriveSelect
);
640 DPRINT("MaxCylinders: %d\n", BiosDiskEntry
->Int13DiskData
.MaxCylinders
);
641 DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry
->Int13DiskData
.SectorsPerTrack
);
642 DPRINT("MaxHeads: %d\n", BiosDiskEntry
->Int13DiskData
.MaxHeads
);
643 DPRINT("NumberDrives: %d\n", BiosDiskEntry
->Int13DiskData
.NumberDrives
);
648 RtlFreeHeap(ProcessHeap
, 0, Int13Drives
);
654 RtlFreeHeap(ProcessHeap
, 0, Int13Drives
);
658 AddDiskToList (HANDLE FileHandle
,
662 DRIVE_LAYOUT_INFORMATION
*LayoutBuffer
;
663 DISK_GEOMETRY DiskGeometry
;
664 SCSI_ADDRESS ScsiAddress
;
665 PDISKENTRY DiskEntry
;
666 IO_STATUS_BLOCK Iosb
;
668 PPARTITION_SECTOR Mbr
;
670 LARGE_INTEGER FileOffset
;
671 WCHAR Identifier
[20];
675 PLIST_ENTRY ListEntry
;
676 PBIOSDISKENTRY BiosDiskEntry
;
678 Status
= NtDeviceIoControlFile (FileHandle
,
683 IOCTL_DISK_GET_DRIVE_GEOMETRY
,
687 sizeof(DISK_GEOMETRY
));
688 if (!NT_SUCCESS (Status
))
693 if (DiskGeometry
.MediaType
!= FixedMedia
)
698 Status
= NtDeviceIoControlFile (FileHandle
,
703 IOCTL_SCSI_GET_ADDRESS
,
707 sizeof(SCSI_ADDRESS
));
708 if (!NT_SUCCESS(Status
))
713 Mbr
= RtlAllocateHeap(ProcessHeap
,
715 DiskGeometry
.BytesPerSector
);
722 FileOffset
.QuadPart
= 0;
723 Status
= NtReadFile(FileHandle
,
729 DiskGeometry
.BytesPerSector
,
732 if (!NT_SUCCESS(Status
))
734 RtlFreeHeap(ProcessHeap
,
737 DPRINT1("NtReadFile failed, status=%x\n", Status
);
740 Signature
= Mbr
->Signature
;
742 /* Calculate the MBR checksum */
744 Buffer
= (PULONG
)Mbr
;
745 for (i
= 0; i
< 128; i
++)
747 Checksum
+= Buffer
[i
];
749 Checksum
= ~Checksum
+ 1;
751 RtlFreeHeap (ProcessHeap
,
755 swprintf(Identifier
, L
"%08x-%08x-A", Checksum
, Signature
);
756 DPRINT("Identifier: %S\n", Identifier
);
758 DiskEntry
= (PDISKENTRY
)RtlAllocateHeap (ProcessHeap
,
761 if (DiskEntry
== NULL
)
766 DiskEntry
->Checksum
= Checksum
;
767 DiskEntry
->Signature
= Signature
;
770 /* If we have no signature, set the disk to dirty. WritePartitionsToDisk creates a new signature */
771 DiskEntry
->Modified
= TRUE
;
773 DiskEntry
->BiosFound
= FALSE
;
775 ListEntry
= List
->BiosDiskListHead
.Flink
;
776 while(ListEntry
!= &List
->BiosDiskListHead
)
778 BiosDiskEntry
= CONTAINING_RECORD(ListEntry
, BIOSDISKENTRY
, ListEntry
);
780 * Compare the size from bios and the reported size from driver.
781 * If we have more than one disk with a zero or with the same signatur
782 * we must create new signatures and reboot. After the reboot,
783 * it is possible to identify the disks.
785 if (BiosDiskEntry
->Signature
== Signature
&&
786 BiosDiskEntry
->Checksum
== Checksum
&&
787 !BiosDiskEntry
->Recognized
)
789 if (!DiskEntry
->BiosFound
)
791 DiskEntry
->BiosDiskNumber
= BiosDiskEntry
->DiskNumber
;
792 DiskEntry
->BiosFound
= TRUE
;
793 BiosDiskEntry
->Recognized
= TRUE
;
799 ListEntry
= ListEntry
->Flink
;
802 if (!DiskEntry
->BiosFound
)
804 RtlFreeHeap(ProcessHeap
, 0, DiskEntry
);
808 InitializeListHead (&DiskEntry
->PartListHead
);
810 DiskEntry
->Cylinders
= DiskGeometry
.Cylinders
.QuadPart
;
811 DiskEntry
->TracksPerCylinder
= DiskGeometry
.TracksPerCylinder
;
812 DiskEntry
->SectorsPerTrack
= DiskGeometry
.SectorsPerTrack
;
813 DiskEntry
->BytesPerSector
= DiskGeometry
.BytesPerSector
;
815 DPRINT ("Cylinders %d\n", DiskEntry
->Cylinders
);
816 DPRINT ("TracksPerCylinder %d\n", DiskEntry
->TracksPerCylinder
);
817 DPRINT ("SectorsPerTrack %d\n", DiskEntry
->SectorsPerTrack
);
818 DPRINT ("BytesPerSector %d\n", DiskEntry
->BytesPerSector
);
820 DiskEntry
->DiskSize
=
821 DiskGeometry
.Cylinders
.QuadPart
*
822 (ULONGLONG
)DiskGeometry
.TracksPerCylinder
*
823 (ULONGLONG
)DiskGeometry
.SectorsPerTrack
*
824 (ULONGLONG
)DiskGeometry
.BytesPerSector
;
825 DiskEntry
->CylinderSize
=
826 (ULONGLONG
)DiskGeometry
.TracksPerCylinder
*
827 (ULONGLONG
)DiskGeometry
.SectorsPerTrack
*
828 (ULONGLONG
)DiskGeometry
.BytesPerSector
;
829 DiskEntry
->TrackSize
=
830 (ULONGLONG
)DiskGeometry
.SectorsPerTrack
*
831 (ULONGLONG
)DiskGeometry
.BytesPerSector
;
833 DiskEntry
->DiskNumber
= DiskNumber
;
834 DiskEntry
->Port
= ScsiAddress
.PortNumber
;
835 DiskEntry
->Bus
= ScsiAddress
.PathId
;
836 DiskEntry
->Id
= ScsiAddress
.TargetId
;
838 GetDriverName (DiskEntry
);
840 InsertAscendingList(&List
->DiskListHead
, DiskEntry
, DISKENTRY
, ListEntry
, BiosDiskNumber
);
842 LayoutBuffer
= (DRIVE_LAYOUT_INFORMATION
*)RtlAllocateHeap (ProcessHeap
,
845 if (LayoutBuffer
== NULL
)
850 Status
= NtDeviceIoControlFile (FileHandle
,
855 IOCTL_DISK_GET_DRIVE_LAYOUT
,
860 if (NT_SUCCESS (Status
))
862 if (LayoutBuffer
->PartitionCount
== 0)
864 DiskEntry
->NewDisk
= TRUE
;
867 AddPartitionToList (DiskNumber
,
871 ScanForUnpartitionedDiskSpace (DiskEntry
);
874 RtlFreeHeap (ProcessHeap
,
881 CreatePartitionList (SHORT Left
,
887 OBJECT_ATTRIBUTES ObjectAttributes
;
888 SYSTEM_DEVICE_INFORMATION Sdi
;
889 IO_STATUS_BLOCK Iosb
;
893 WCHAR Buffer
[MAX_PATH
];
897 List
= (PPARTLIST
)RtlAllocateHeap (ProcessHeap
,
906 List
->Bottom
= Bottom
;
910 List
->TopDisk
= (ULONG
)-1;
911 List
->TopPartition
= (ULONG
)-1;
913 List
->CurrentDisk
= NULL
;
914 List
->CurrentPartition
= NULL
;
916 InitializeListHead (&List
->DiskListHead
);
917 InitializeListHead (&List
->BiosDiskListHead
);
919 EnumerateBiosDiskEntries(List
);
921 Status
= NtQuerySystemInformation (SystemDeviceInformation
,
923 sizeof(SYSTEM_DEVICE_INFORMATION
),
925 if (!NT_SUCCESS (Status
))
927 RtlFreeHeap (ProcessHeap
, 0, List
);
931 for (DiskNumber
= 0; DiskNumber
< Sdi
.NumberOfDisks
; DiskNumber
++)
934 L
"\\Device\\Harddisk%d\\Partition0",
936 RtlInitUnicodeString (&Name
,
939 InitializeObjectAttributes (&ObjectAttributes
,
945 Status
= NtOpenFile (&FileHandle
,
950 FILE_SYNCHRONOUS_IO_NONALERT
);
951 if (NT_SUCCESS(Status
))
953 AddDiskToList (FileHandle
,
961 AssignDriverLetters (List
);
964 List
->TopPartition
= 0;
966 /* Search for first usable disk and partition */
967 if (IsListEmpty (&List
->DiskListHead
))
969 List
->CurrentDisk
= NULL
;
970 List
->CurrentPartition
= NULL
;
975 CONTAINING_RECORD (List
->DiskListHead
.Flink
,
979 if (IsListEmpty (&List
->CurrentDisk
->PartListHead
))
981 List
->CurrentPartition
= 0;
985 List
->CurrentPartition
=
986 CONTAINING_RECORD (List
->CurrentDisk
->PartListHead
.Flink
,
997 DestroyPartitionList (PPARTLIST List
)
999 PDISKENTRY DiskEntry
;
1000 PBIOSDISKENTRY BiosDiskEntry
;
1001 PPARTENTRY PartEntry
;
1004 /* Release disk and partition info */
1005 while (!IsListEmpty (&List
->DiskListHead
))
1007 Entry
= RemoveHeadList (&List
->DiskListHead
);
1008 DiskEntry
= CONTAINING_RECORD (Entry
, DISKENTRY
, ListEntry
);
1010 /* Release driver name */
1011 RtlFreeUnicodeString(&DiskEntry
->DriverName
);
1013 /* Release partition array */
1014 while (!IsListEmpty (&DiskEntry
->PartListHead
))
1016 Entry
= RemoveHeadList (&DiskEntry
->PartListHead
);
1017 PartEntry
= CONTAINING_RECORD (Entry
, PARTENTRY
, ListEntry
);
1019 RtlFreeHeap (ProcessHeap
,
1024 /* Release disk entry */
1025 RtlFreeHeap (ProcessHeap
, 0, DiskEntry
);
1028 /* release the bios disk info */
1029 while(!IsListEmpty(&List
->BiosDiskListHead
))
1031 Entry
= RemoveHeadList(&List
->BiosDiskListHead
);
1032 BiosDiskEntry
= CONTAINING_RECORD(Entry
, BIOSDISKENTRY
, ListEntry
);
1034 RtlFreeHeap(ProcessHeap
, 0, BiosDiskEntry
);
1037 /* Release list head */
1038 RtlFreeHeap (ProcessHeap
, 0, List
);
1043 PrintEmptyLine (PPARTLIST List
)
1050 Width
= List
->Right
- List
->Left
- 1;
1051 Height
= List
->Bottom
- List
->Top
- 2;
1054 coPos
.X
= List
->Left
+ 1;
1055 coPos
.Y
= List
->Top
+ 1 + List
->Line
;
1057 if (List
->Line
>= 0 && List
->Line
<= Height
)
1059 FillConsoleOutputAttribute (StdOutput
,
1060 FOREGROUND_WHITE
| BACKGROUND_BLUE
,
1065 FillConsoleOutputCharacterA (StdOutput
,
1076 PrintPartitionData (PPARTLIST List
,
1077 PDISKENTRY DiskEntry
,
1078 PPARTENTRY PartEntry
)
1080 CHAR LineBuffer
[128];
1091 Width
= List
->Right
- List
->Left
- 1;
1092 Height
= List
->Bottom
- List
->Top
- 2;
1095 coPos
.X
= List
->Left
+ 1;
1096 coPos
.Y
= List
->Top
+ 1 + List
->Line
;
1098 if (PartEntry
->Unpartitioned
== TRUE
)
1101 if (PartEntry
->UnpartitionledLength
>= 0x280000000ULL
) /* 10 GB */
1103 PartSize
= (PartEntry
->UnpartitionedLength
+ (1 << 29)) >> 30;
1108 if (PartEntry
->UnpartitionedLength
>= 0xA00000ULL
) /* 10 MB */
1110 PartSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20;
1115 PartSize
= (PartEntry
->UnpartitionedLength
+ (1 << 9)) >> 10;
1119 sprintf (LineBuffer
,
1120 " Unpartitioned space %6I64u %s",
1126 /* Determine partition type */
1128 if (PartEntry
->New
== TRUE
)
1130 PartType
= "New (Unformatted)";
1132 else if (PartEntry
->Unpartitioned
== FALSE
)
1134 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
1135 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
1136 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
1137 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_XINT13
))
1141 else if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
1142 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
1146 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
1148 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1153 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
1155 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1160 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0xA00000LL
) /* 10 MB */
1162 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1167 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1171 if (PartType
== NULL
)
1173 sprintf (LineBuffer
,
1174 "%c%c Type %-3u %6I64u %s",
1175 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1176 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1177 PartEntry
->PartInfo
[0].PartitionType
,
1183 sprintf (LineBuffer
,
1184 "%c%c %-24s %6I64u %s",
1185 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1186 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1193 Attribute
= (List
->CurrentDisk
== DiskEntry
&&
1194 List
->CurrentPartition
== PartEntry
) ?
1195 FOREGROUND_BLUE
| BACKGROUND_WHITE
:
1196 FOREGROUND_WHITE
| BACKGROUND_BLUE
;
1198 if (List
->Line
>= 0 && List
->Line
<= Height
)
1200 FillConsoleOutputCharacterA (StdOutput
,
1208 if (List
->Line
>= 0 && List
->Line
<= Height
)
1210 FillConsoleOutputAttribute (StdOutput
,
1218 if (List
->Line
>= 0 && List
->Line
<= Height
)
1220 WriteConsoleOutputCharacterA (StdOutput
,
1222 min (strlen (LineBuffer
), Width
),
1231 PrintDiskData (PPARTLIST List
,
1232 PDISKENTRY DiskEntry
)
1234 PPARTENTRY PartEntry
;
1235 CHAR LineBuffer
[128];
1240 ULARGE_INTEGER DiskSize
;
1243 Width
= List
->Right
- List
->Left
- 1;
1244 Height
= List
->Bottom
- List
->Top
- 2;
1247 coPos
.X
= List
->Left
+ 1;
1248 coPos
.Y
= List
->Top
+ 1 + List
->Line
;
1251 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1253 DiskSize
.QuadPart
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1259 DiskSize
.QuadPart
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1260 if (DiskSize
.QuadPart
== 0)
1261 DiskSize
.QuadPart
= 1;
1265 if (DiskEntry
->DriverName
.Length
> 0)
1267 sprintf (LineBuffer
,
1268 "%6lu %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %S",
1271 DiskEntry
->DiskNumber
,
1275 DiskEntry
->DriverName
.Buffer
);
1279 sprintf (LineBuffer
,
1280 "%6lu %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu)",
1283 DiskEntry
->DiskNumber
,
1288 if (List
->Line
>= 0 && List
->Line
<= Height
)
1290 FillConsoleOutputAttribute (StdOutput
,
1291 FOREGROUND_WHITE
| BACKGROUND_BLUE
,
1296 FillConsoleOutputCharacterA (StdOutput
,
1304 if (List
->Line
>= 0 && List
->Line
<= Height
)
1306 WriteConsoleOutputCharacterA (StdOutput
,
1308 min (strlen (LineBuffer
), Width
- 2),
1314 /* Print separator line */
1315 PrintEmptyLine (List
);
1317 /* Print partition lines*/
1318 LIST_FOR_EACH(PartEntry
, &DiskEntry
->PartListHead
, PARTENTRY
, ListEntry
)
1320 /* Print disk entry */
1321 PrintPartitionData (List
,
1326 /* Print separator line */
1327 PrintEmptyLine (List
);
1332 DrawPartitionList (PPARTLIST List
)
1334 PLIST_ENTRY Entry
, Entry2
;
1335 PDISKENTRY DiskEntry
;
1336 PPARTENTRY PartEntry
= NULL
;
1340 SHORT CurrentDiskLine
;
1341 SHORT CurrentPartLine
;
1343 BOOL CurrentPartLineFound
= FALSE
;
1344 BOOL CurrentDiskLineFound
= FALSE
;
1346 /* Calculate the line of the current disk and partition */
1347 CurrentDiskLine
= 0;
1348 CurrentPartLine
= 0;
1350 Entry
= List
->DiskListHead
.Flink
;
1351 while (Entry
!= &List
->DiskListHead
)
1353 DiskEntry
= CONTAINING_RECORD (Entry
, DISKENTRY
, ListEntry
);
1355 if (CurrentPartLineFound
== FALSE
)
1357 CurrentPartLine
+= 2;
1359 Entry2
= DiskEntry
->PartListHead
.Flink
;
1360 while (Entry2
!= &DiskEntry
->PartListHead
)
1362 PartEntry
= CONTAINING_RECORD (Entry2
, PARTENTRY
, ListEntry
);
1363 if (PartEntry
== List
->CurrentPartition
)
1365 CurrentPartLineFound
= TRUE
;
1367 Entry2
= Entry2
->Flink
;
1368 if (CurrentPartLineFound
== FALSE
)
1374 if (DiskEntry
== List
->CurrentDisk
)
1376 CurrentDiskLineFound
= TRUE
;
1378 Entry
= Entry
->Flink
;
1379 if (Entry
!= &List
->DiskListHead
)
1381 if (CurrentDiskLineFound
== FALSE
)
1384 CurrentDiskLine
= CurrentPartLine
;
1394 /* If it possible, make the disk name visible */
1395 if (CurrentPartLine
< List
->Offset
)
1397 List
->Offset
= CurrentPartLine
;
1399 else if (CurrentPartLine
- List
->Offset
> List
->Bottom
- List
->Top
- 2)
1401 List
->Offset
= CurrentPartLine
- (List
->Bottom
- List
->Top
- 2);
1403 if (CurrentDiskLine
< List
->Offset
&& CurrentPartLine
- CurrentDiskLine
< List
->Bottom
- List
->Top
- 2)
1405 List
->Offset
= CurrentDiskLine
;
1409 /* draw upper left corner */
1410 coPos
.X
= List
->Left
;
1411 coPos
.Y
= List
->Top
;
1412 FillConsoleOutputCharacterA (StdOutput
,
1418 /* draw upper edge */
1419 coPos
.X
= List
->Left
+ 1;
1420 coPos
.Y
= List
->Top
;
1421 if (List
->Offset
== 0)
1423 FillConsoleOutputCharacterA (StdOutput
,
1425 List
->Right
- List
->Left
- 1,
1431 FillConsoleOutputCharacterA (StdOutput
,
1433 List
->Right
- List
->Left
- 5,
1436 coPos
.X
= List
->Right
- 5;
1437 WriteConsoleOutputCharacterA (StdOutput
,
1442 coPos
.X
= List
->Right
- 2;
1443 FillConsoleOutputCharacterA (StdOutput
,
1450 /* draw upper right corner */
1451 coPos
.X
= List
->Right
;
1452 coPos
.Y
= List
->Top
;
1453 FillConsoleOutputCharacterA (StdOutput
,
1459 /* draw left and right edge */
1460 for (i
= List
->Top
+ 1; i
< List
->Bottom
; i
++)
1462 coPos
.X
= List
->Left
;
1464 FillConsoleOutputCharacterA (StdOutput
,
1470 coPos
.X
= List
->Right
;
1471 FillConsoleOutputCharacterA (StdOutput
,
1478 /* draw lower left corner */
1479 coPos
.X
= List
->Left
;
1480 coPos
.Y
= List
->Bottom
;
1481 FillConsoleOutputCharacterA (StdOutput
,
1487 /* draw lower edge */
1488 coPos
.X
= List
->Left
+ 1;
1489 coPos
.Y
= List
->Bottom
;
1490 if (LastLine
- List
->Offset
<= List
->Bottom
- List
->Top
- 2)
1492 FillConsoleOutputCharacterA (StdOutput
,
1494 List
->Right
- List
->Left
- 1,
1500 FillConsoleOutputCharacterA (StdOutput
,
1502 List
->Right
- List
->Left
- 5,
1505 coPos
.X
= List
->Right
- 5;
1506 WriteConsoleOutputCharacterA (StdOutput
,
1507 "(\x19)", // "(down)"
1511 coPos
.X
= List
->Right
- 2;
1512 FillConsoleOutputCharacterA (StdOutput
,
1519 /* draw lower right corner */
1520 coPos
.X
= List
->Right
;
1521 coPos
.Y
= List
->Bottom
;
1522 FillConsoleOutputCharacterA (StdOutput
,
1528 /* print list entries */
1529 List
->Line
= - List
->Offset
;
1531 LIST_FOR_EACH(DiskEntry
, &List
->DiskListHead
, DISKENTRY
, ListEntry
)
1533 /* Print disk entry */
1534 PrintDiskData (List
,
1541 SelectPartition(PPARTLIST List
, ULONG DiskNumber
, ULONG PartitionNumber
)
1543 PDISKENTRY DiskEntry
;
1544 PPARTENTRY PartEntry
;
1549 /* Check for empty disks */
1550 if (IsListEmpty (&List
->DiskListHead
))
1553 /* Check for first usable entry on next disk */
1554 Entry1
= List
->CurrentDisk
->ListEntry
.Flink
;
1555 while (Entry1
!= &List
->DiskListHead
)
1557 DiskEntry
= CONTAINING_RECORD (Entry1
, DISKENTRY
, ListEntry
);
1559 if (DiskEntry
->DiskNumber
== DiskNumber
)
1561 Entry2
= DiskEntry
->PartListHead
.Flink
;
1562 while (Entry2
!= &DiskEntry
->PartListHead
)
1564 PartEntry
= CONTAINING_RECORD (Entry2
, PARTENTRY
, ListEntry
);
1566 for (i
= 0; i
< 4; i
++)
1568 if (PartEntry
->PartInfo
[i
].PartitionNumber
== PartitionNumber
)
1570 List
->CurrentDisk
= DiskEntry
;
1571 List
->CurrentPartition
= PartEntry
;
1572 DrawPartitionList (List
);
1576 Entry2
= Entry2
->Flink
;
1580 Entry1
= Entry1
->Flink
;
1586 ScrollDownPartitionList (PPARTLIST List
)
1588 PDISKENTRY DiskEntry
;
1589 PPARTENTRY PartEntry
;
1593 /* Check for empty disks */
1594 if (IsListEmpty (&List
->DiskListHead
))
1597 /* Check for next usable entry on current disk */
1598 if (List
->CurrentPartition
!= NULL
)
1600 Entry2
= List
->CurrentPartition
->ListEntry
.Flink
;
1601 while (Entry2
!= &List
->CurrentDisk
->PartListHead
)
1603 PartEntry
= CONTAINING_RECORD (Entry2
, PARTENTRY
, ListEntry
);
1605 // if (PartEntry->HidePartEntry == FALSE)
1607 List
->CurrentPartition
= PartEntry
;
1608 DrawPartitionList (List
);
1611 Entry2
= Entry2
->Flink
;
1615 /* Check for first usable entry on next disk */
1616 if (List
->CurrentDisk
!= NULL
)
1618 Entry1
= List
->CurrentDisk
->ListEntry
.Flink
;
1619 while (Entry1
!= &List
->DiskListHead
)
1621 DiskEntry
= CONTAINING_RECORD (Entry1
, DISKENTRY
, ListEntry
);
1623 Entry2
= DiskEntry
->PartListHead
.Flink
;
1624 while (Entry2
!= &DiskEntry
->PartListHead
)
1626 PartEntry
= CONTAINING_RECORD (Entry2
, PARTENTRY
, ListEntry
);
1628 // if (PartEntry->HidePartEntry == FALSE)
1630 List
->CurrentDisk
= DiskEntry
;
1631 List
->CurrentPartition
= PartEntry
;
1632 DrawPartitionList (List
);
1636 Entry2
= Entry2
->Flink
;
1639 Entry1
= Entry1
->Flink
;
1646 ScrollUpPartitionList (PPARTLIST List
)
1648 PDISKENTRY DiskEntry
;
1649 PPARTENTRY PartEntry
;
1653 /* Check for empty disks */
1654 if (IsListEmpty (&List
->DiskListHead
))
1657 /* check for previous usable entry on current disk */
1658 if (List
->CurrentPartition
!= NULL
)
1660 Entry2
= List
->CurrentPartition
->ListEntry
.Blink
;
1661 while (Entry2
!= &List
->CurrentDisk
->PartListHead
)
1663 PartEntry
= CONTAINING_RECORD (Entry2
, PARTENTRY
, ListEntry
);
1665 // if (PartEntry->HidePartEntry == FALSE)
1667 List
->CurrentPartition
= PartEntry
;
1668 DrawPartitionList (List
);
1671 Entry2
= Entry2
->Blink
;
1676 /* check for last usable entry on previous disk */
1677 if (List
->CurrentDisk
!= NULL
)
1679 Entry1
= List
->CurrentDisk
->ListEntry
.Blink
;
1680 while (Entry1
!= &List
->DiskListHead
)
1682 DiskEntry
= CONTAINING_RECORD (Entry1
, DISKENTRY
, ListEntry
);
1684 Entry2
= DiskEntry
->PartListHead
.Blink
;
1685 while (Entry2
!= &DiskEntry
->PartListHead
)
1687 PartEntry
= CONTAINING_RECORD (Entry2
, PARTENTRY
, ListEntry
);
1689 // if (PartEntry->HidePartEntry == FALSE)
1691 List
->CurrentDisk
= DiskEntry
;
1692 List
->CurrentPartition
= PartEntry
;
1693 DrawPartitionList (List
);
1697 Entry2
= Entry2
->Blink
;
1700 Entry1
= Entry1
->Blink
;
1707 GetPrevPartitionedEntry (PDISKENTRY DiskEntry
,
1708 PPARTENTRY CurrentEntry
)
1710 PPARTENTRY PrevEntry
;
1713 if (CurrentEntry
->ListEntry
.Blink
== &DiskEntry
->PartListHead
)
1716 Entry
= CurrentEntry
->ListEntry
.Blink
;
1717 while (Entry
!= &DiskEntry
->PartListHead
)
1719 PrevEntry
= CONTAINING_RECORD (Entry
,
1722 if (PrevEntry
->Unpartitioned
== FALSE
)
1725 Entry
= Entry
->Blink
;
1733 GetNextPartitionedEntry (PDISKENTRY DiskEntry
,
1734 PPARTENTRY CurrentEntry
)
1736 PPARTENTRY NextEntry
;
1739 if (CurrentEntry
->ListEntry
.Flink
== &DiskEntry
->PartListHead
)
1742 Entry
= CurrentEntry
->ListEntry
.Flink
;
1743 while (Entry
!= &DiskEntry
->PartListHead
)
1745 NextEntry
= CONTAINING_RECORD (Entry
,
1748 if (NextEntry
->Unpartitioned
== FALSE
)
1751 Entry
= Entry
->Flink
;
1759 GetPrevUnpartitionedEntry (PDISKENTRY DiskEntry
,
1760 PPARTENTRY PartEntry
)
1762 PPARTENTRY PrevPartEntry
;
1764 if (PartEntry
->ListEntry
.Blink
!= &DiskEntry
->PartListHead
)
1766 PrevPartEntry
= CONTAINING_RECORD (PartEntry
->ListEntry
.Blink
,
1769 if (PrevPartEntry
->Unpartitioned
== TRUE
)
1770 return PrevPartEntry
;
1778 GetNextUnpartitionedEntry (PDISKENTRY DiskEntry
,
1779 PPARTENTRY PartEntry
)
1781 PPARTENTRY NextPartEntry
;
1783 if (PartEntry
->ListEntry
.Flink
!= &DiskEntry
->PartListHead
)
1785 NextPartEntry
= CONTAINING_RECORD (PartEntry
->ListEntry
.Flink
,
1788 if (NextPartEntry
->Unpartitioned
== TRUE
)
1789 return NextPartEntry
;
1797 CreateNewPartition (PPARTLIST List
,
1798 ULONGLONG PartitionSize
,
1801 PDISKENTRY DiskEntry
;
1802 PPARTENTRY PartEntry
;
1803 PPARTENTRY PrevPartEntry
;
1804 PPARTENTRY NextPartEntry
;
1805 PPARTENTRY NewPartEntry
;
1808 List
->CurrentDisk
== NULL
||
1809 List
->CurrentPartition
== NULL
||
1810 List
->CurrentPartition
->Unpartitioned
== FALSE
)
1815 DiskEntry
= List
->CurrentDisk
;
1816 PartEntry
= List
->CurrentPartition
;
1818 if (AutoCreate
== TRUE
||
1819 PartitionSize
== PartEntry
->UnpartitionedLength
)
1821 /* Convert current entry to 'new (unformatted)' */
1822 PartEntry
->FormatState
= Unformatted
;
1823 PartEntry
->PartInfo
[0].StartingOffset
.QuadPart
=
1824 PartEntry
->UnpartitionedOffset
+ DiskEntry
->TrackSize
;
1825 PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
=
1826 PartEntry
->UnpartitionedLength
- DiskEntry
->TrackSize
;
1827 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_ENTRY_UNUSED
;
1828 PartEntry
->PartInfo
[0].BootIndicator
= FALSE
; /* FIXME */
1829 PartEntry
->PartInfo
[0].RewritePartition
= TRUE
;
1830 PartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
1831 PartEntry
->PartInfo
[2].RewritePartition
= TRUE
;
1832 PartEntry
->PartInfo
[3].RewritePartition
= TRUE
;
1834 /* Get previous and next partition entries */
1835 PrevPartEntry
= GetPrevPartitionedEntry (DiskEntry
,
1837 NextPartEntry
= GetNextPartitionedEntry (DiskEntry
,
1840 if (PrevPartEntry
!= NULL
&& NextPartEntry
!= NULL
)
1842 /* Current entry is in the middle of the list */
1844 /* Copy previous container partition data to current entry */
1845 RtlCopyMemory (&PartEntry
->PartInfo
[1],
1846 &PrevPartEntry
->PartInfo
[1],
1847 sizeof(PARTITION_INFORMATION
));
1848 PartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
1850 /* Update previous container partition data */
1852 PrevPartEntry
->PartInfo
[1].StartingOffset
.QuadPart
=
1853 PartEntry
->PartInfo
[0].StartingOffset
.QuadPart
- DiskEntry
->TrackSize
;
1855 if (DiskEntry
->PartListHead
.Flink
== &PrevPartEntry
->ListEntry
)
1857 /* Special case - previous partition is first partition */
1858 PrevPartEntry
->PartInfo
[1].PartitionLength
.QuadPart
=
1859 DiskEntry
->DiskSize
- PrevPartEntry
->PartInfo
[1].StartingOffset
.QuadPart
;
1863 PrevPartEntry
->PartInfo
[1].PartitionLength
.QuadPart
=
1864 PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ DiskEntry
->TrackSize
;
1867 PrevPartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
1869 else if (PrevPartEntry
== NULL
&& NextPartEntry
!= NULL
)
1871 /* Current entry is the first entry */
1874 else if (PrevPartEntry
!= NULL
&& NextPartEntry
== NULL
)
1876 /* Current entry is the last entry */
1878 PrevPartEntry
->PartInfo
[1].StartingOffset
.QuadPart
=
1879 PartEntry
->PartInfo
[0].StartingOffset
.QuadPart
- DiskEntry
->TrackSize
;
1881 if (DiskEntry
->PartListHead
.Flink
== &PrevPartEntry
->ListEntry
)
1883 /* Special case - previous partition is first partition */
1884 PrevPartEntry
->PartInfo
[1].PartitionLength
.QuadPart
=
1885 DiskEntry
->DiskSize
- PrevPartEntry
->PartInfo
[1].StartingOffset
.QuadPart
;
1889 PrevPartEntry
->PartInfo
[1].PartitionLength
.QuadPart
=
1890 PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ DiskEntry
->TrackSize
;
1893 if ((PartEntry
->PartInfo
[1].StartingOffset
.QuadPart
+
1894 PartEntry
->PartInfo
[1].PartitionLength
.QuadPart
) <
1895 (1024LL * 255LL * 63LL * 512LL))
1897 PrevPartEntry
->PartInfo
[1].PartitionType
= PARTITION_EXTENDED
;
1901 PrevPartEntry
->PartInfo
[1].PartitionType
= PARTITION_XINT13_EXTENDED
;
1904 PrevPartEntry
->PartInfo
[1].BootIndicator
= FALSE
;
1905 PrevPartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
1908 PartEntry
->AutoCreate
= AutoCreate
;
1909 PartEntry
->New
= TRUE
;
1910 PartEntry
->Unpartitioned
= FALSE
;
1911 PartEntry
->UnpartitionedOffset
= 0ULL;
1912 PartEntry
->UnpartitionedLength
= 0ULL;
1916 /* Insert an initialize a new partition entry */
1917 NewPartEntry
= (PPARTENTRY
)RtlAllocateHeap (ProcessHeap
,
1920 if (NewPartEntry
== NULL
)
1923 RtlZeroMemory (NewPartEntry
,
1926 /* Insert the new entry into the list */
1927 InsertTailList (&PartEntry
->ListEntry
,
1928 &NewPartEntry
->ListEntry
);
1930 NewPartEntry
->New
= TRUE
;
1932 NewPartEntry
->FormatState
= Unformatted
;
1933 NewPartEntry
->PartInfo
[0].StartingOffset
.QuadPart
=
1934 PartEntry
->UnpartitionedOffset
+ DiskEntry
->TrackSize
;
1935 NewPartEntry
->PartInfo
[0].PartitionLength
.QuadPart
=
1936 PartitionSize
- DiskEntry
->TrackSize
;
1937 NewPartEntry
->PartInfo
[0].PartitionType
= PARTITION_ENTRY_UNUSED
;
1938 NewPartEntry
->PartInfo
[0].BootIndicator
= FALSE
; /* FIXME */
1939 NewPartEntry
->PartInfo
[0].RewritePartition
= TRUE
;
1940 NewPartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
1941 NewPartEntry
->PartInfo
[2].RewritePartition
= TRUE
;
1942 NewPartEntry
->PartInfo
[3].RewritePartition
= TRUE
;
1944 /* Get previous and next partition entries */
1945 PrevPartEntry
= GetPrevPartitionedEntry (DiskEntry
,
1947 NextPartEntry
= GetNextPartitionedEntry (DiskEntry
,
1950 if (PrevPartEntry
!= NULL
&& NextPartEntry
!= NULL
)
1952 /* Current entry is in the middle of the list */
1954 /* Copy previous container partition data to current entry */
1955 RtlCopyMemory (&NewPartEntry
->PartInfo
[1],
1956 &PrevPartEntry
->PartInfo
[1],
1957 sizeof(PARTITION_INFORMATION
));
1958 NewPartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
1960 /* Update previous container partition data */
1962 PrevPartEntry
->PartInfo
[1].StartingOffset
.QuadPart
=
1963 NewPartEntry
->PartInfo
[0].StartingOffset
.QuadPart
- DiskEntry
->TrackSize
;
1965 if (DiskEntry
->PartListHead
.Flink
== &PrevPartEntry
->ListEntry
)
1967 /* Special case - previous partition is first partition */
1968 PrevPartEntry
->PartInfo
[1].PartitionLength
.QuadPart
=
1969 DiskEntry
->DiskSize
- PrevPartEntry
->PartInfo
[1].StartingOffset
.QuadPart
;
1973 PrevPartEntry
->PartInfo
[1].PartitionLength
.QuadPart
=
1974 NewPartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ DiskEntry
->TrackSize
;
1977 PrevPartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
1979 else if (PrevPartEntry
== NULL
&& NextPartEntry
!= NULL
)
1981 /* Current entry is the first entry */
1984 else if (PrevPartEntry
!= NULL
&& NextPartEntry
== NULL
)
1986 /* Current entry is the last entry */
1988 PrevPartEntry
->PartInfo
[1].StartingOffset
.QuadPart
=
1989 NewPartEntry
->PartInfo
[0].StartingOffset
.QuadPart
- DiskEntry
->TrackSize
;
1991 if (DiskEntry
->PartListHead
.Flink
== &PrevPartEntry
->ListEntry
)
1993 /* Special case - previous partition is first partition */
1994 PrevPartEntry
->PartInfo
[1].PartitionLength
.QuadPart
=
1995 DiskEntry
->DiskSize
- PrevPartEntry
->PartInfo
[1].StartingOffset
.QuadPart
;
1999 PrevPartEntry
->PartInfo
[1].PartitionLength
.QuadPart
=
2000 NewPartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ DiskEntry
->TrackSize
;
2003 if ((PartEntry
->PartInfo
[1].StartingOffset
.QuadPart
+
2004 PartEntry
->PartInfo
[1].PartitionLength
.QuadPart
) <
2005 (1024LL * 255LL * 63LL * 512LL))
2007 PrevPartEntry
->PartInfo
[1].PartitionType
= PARTITION_EXTENDED
;
2011 PrevPartEntry
->PartInfo
[1].PartitionType
= PARTITION_XINT13_EXTENDED
;
2014 PrevPartEntry
->PartInfo
[1].BootIndicator
= FALSE
;
2015 PrevPartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
2018 /* Update offset and size of the remaining unpartitioned disk space */
2019 PartEntry
->UnpartitionedOffset
+= PartitionSize
;
2020 PartEntry
->UnpartitionedLength
-= PartitionSize
;
2023 DiskEntry
->Modified
= TRUE
;
2025 UpdatePartitionNumbers (DiskEntry
);
2027 AssignDriverLetters (List
);
2032 DeleteCurrentPartition (PPARTLIST List
)
2034 PDISKENTRY DiskEntry
;
2035 PPARTENTRY PartEntry
;
2036 PPARTENTRY PrevPartEntry
;
2037 PPARTENTRY NextPartEntry
;
2040 List
->CurrentDisk
== NULL
||
2041 List
->CurrentPartition
== NULL
||
2042 List
->CurrentPartition
->Unpartitioned
== TRUE
)
2047 DiskEntry
= List
->CurrentDisk
;
2048 PartEntry
= List
->CurrentPartition
;
2050 /* Adjust container partition entries */
2052 /* Get previous and next partition entries */
2053 PrevPartEntry
= GetPrevPartitionedEntry (DiskEntry
,
2055 NextPartEntry
= GetNextPartitionedEntry (DiskEntry
,
2058 if (PrevPartEntry
!= NULL
&& NextPartEntry
!= NULL
)
2060 /* Current entry is in the middle of the list */
2063 * The first extended partition can not be deleted
2064 * as long as other extended partitions are present.
2066 if (PrevPartEntry
->ListEntry
.Blink
== &DiskEntry
->PartListHead
)
2069 /* Copy previous container partition data to current entry */
2070 RtlCopyMemory (&PrevPartEntry
->PartInfo
[1],
2071 &PartEntry
->PartInfo
[1],
2072 sizeof(PARTITION_INFORMATION
));
2073 PrevPartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
2075 else if (PrevPartEntry
== NULL
&& NextPartEntry
!= NULL
)
2078 * A primary partition can not be deleted as long as
2079 * extended partitions are present.
2083 else if (PrevPartEntry
!= NULL
&& NextPartEntry
== NULL
)
2085 /* Current entry is the last entry */
2086 RtlZeroMemory (&PrevPartEntry
->PartInfo
[1],
2087 sizeof(PARTITION_INFORMATION
));
2088 PrevPartEntry
->PartInfo
[1].RewritePartition
= TRUE
;
2092 /* Adjust unpartitioned disk space entries */
2094 /* Get pointer to previous and next unpartitioned entries */
2095 PrevPartEntry
= GetPrevUnpartitionedEntry (DiskEntry
,
2098 NextPartEntry
= GetNextUnpartitionedEntry (DiskEntry
,
2101 if (PrevPartEntry
!= NULL
&& NextPartEntry
!= NULL
)
2103 /* Merge previous, current and next unpartitioned entry */
2105 /* Adjust the previous entries length */
2106 PrevPartEntry
->UnpartitionedLength
+=
2107 (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ DiskEntry
->TrackSize
+
2108 NextPartEntry
->UnpartitionedLength
);
2110 /* Remove the current entry */
2111 RemoveEntryList (&PartEntry
->ListEntry
);
2112 RtlFreeHeap (ProcessHeap
,
2116 /* Remove the next entry */
2117 RemoveEntryList (&NextPartEntry
->ListEntry
);
2118 RtlFreeHeap (ProcessHeap
,
2122 /* Update current partition */
2123 List
->CurrentPartition
= PrevPartEntry
;
2125 else if (PrevPartEntry
!= NULL
&& NextPartEntry
== NULL
)
2127 /* Merge current and previous unpartitioned entry */
2129 /* Adjust the previous entries length */
2130 PrevPartEntry
->UnpartitionedLength
+=
2131 (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ DiskEntry
->TrackSize
);
2133 /* Remove the current entry */
2134 RemoveEntryList (&PartEntry
->ListEntry
);
2135 RtlFreeHeap (ProcessHeap
,
2139 /* Update current partition */
2140 List
->CurrentPartition
= PrevPartEntry
;
2142 else if (PrevPartEntry
== NULL
&& NextPartEntry
!= NULL
)
2144 /* Merge current and next unpartitioned entry */
2146 /* Adjust the next entries offset and length */
2147 NextPartEntry
->UnpartitionedOffset
=
2148 PartEntry
->PartInfo
[0].StartingOffset
.QuadPart
- DiskEntry
->TrackSize
;
2149 NextPartEntry
->UnpartitionedLength
+=
2150 (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ DiskEntry
->TrackSize
);
2152 /* Remove the current entry */
2153 RemoveEntryList (&PartEntry
->ListEntry
);
2154 RtlFreeHeap (ProcessHeap
,
2158 /* Update current partition */
2159 List
->CurrentPartition
= NextPartEntry
;
2163 /* Nothing to merge but change current entry */
2164 PartEntry
->New
= FALSE
;
2165 PartEntry
->Unpartitioned
= TRUE
;
2166 PartEntry
->UnpartitionedOffset
=
2167 PartEntry
->PartInfo
[0].StartingOffset
.QuadPart
- DiskEntry
->TrackSize
;
2168 PartEntry
->UnpartitionedLength
=
2169 PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ DiskEntry
->TrackSize
;
2171 /* Wipe the partition table */
2172 RtlZeroMemory (&PartEntry
->PartInfo
,
2173 sizeof(PartEntry
->PartInfo
));
2176 DiskEntry
->Modified
= TRUE
;
2178 UpdatePartitionNumbers (DiskEntry
);
2180 AssignDriverLetters (List
);
2185 CheckActiveBootPartition (PPARTLIST List
)
2187 PDISKENTRY DiskEntry
;
2188 PPARTENTRY PartEntry
;
2190 /* Check for empty disk list */
2191 if (IsListEmpty (&List
->DiskListHead
))
2193 List
->ActiveBootDisk
= NULL
;
2194 List
->ActiveBootPartition
= NULL
;
2199 if (List
->ActiveBootDisk
!= NULL
&&
2200 List
->ActiveBootPartition
!= NULL
)
2202 /* We already have an active boot partition */
2207 DiskEntry
= CONTAINING_RECORD (List
->DiskListHead
.Flink
,
2211 /* Check for empty partition list */
2212 if (IsListEmpty (&DiskEntry
->PartListHead
))
2214 List
->ActiveBootDisk
= NULL
;
2215 List
->ActiveBootPartition
= NULL
;
2219 PartEntry
= CONTAINING_RECORD (DiskEntry
->PartListHead
.Flink
,
2223 /* Set active boot partition */
2224 if ((DiskEntry
->NewDisk
== TRUE
) ||
2225 (PartEntry
->PartInfo
[0].BootIndicator
== FALSE
&&
2226 PartEntry
->PartInfo
[1].BootIndicator
== FALSE
&&
2227 PartEntry
->PartInfo
[2].BootIndicator
== FALSE
&&
2228 PartEntry
->PartInfo
[3].BootIndicator
== FALSE
))
2230 PartEntry
->PartInfo
[0].BootIndicator
= TRUE
;
2231 PartEntry
->PartInfo
[0].RewritePartition
= TRUE
;
2232 DiskEntry
->Modified
= TRUE
;
2235 /* FIXME: Might be incorrect if partitions were created by Linux FDISK */
2236 List
->ActiveBootDisk
= DiskEntry
;
2237 List
->ActiveBootPartition
= PartEntry
;
2242 CheckForLinuxFdiskPartitions (PPARTLIST List
)
2244 PDISKENTRY DiskEntry
;
2245 PPARTENTRY PartEntry
;
2248 ULONG PartitionCount
;
2251 Entry1
= List
->DiskListHead
.Flink
;
2252 while (Entry1
!= &List
->DiskListHead
)
2254 DiskEntry
= CONTAINING_RECORD (Entry1
,
2258 Entry2
= DiskEntry
->PartListHead
.Flink
;
2259 while (Entry2
!= &DiskEntry
->PartListHead
)
2261 PartEntry
= CONTAINING_RECORD (Entry2
,
2265 if (PartEntry
->Unpartitioned
== FALSE
)
2269 for (i
= 0; i
< 4; i
++)
2271 if (!IsContainerPartition (PartEntry
->PartInfo
[i
].PartitionType
) &&
2272 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
!= 0ULL)
2278 if (PartitionCount
> 1)
2284 Entry2
= Entry2
->Flink
;
2287 Entry1
= Entry1
->Flink
;
2295 WritePartitionsToDisk (PPARTLIST List
)
2297 PDRIVE_LAYOUT_INFORMATION DriveLayout
;
2298 OBJECT_ATTRIBUTES ObjectAttributes
;
2299 IO_STATUS_BLOCK Iosb
;
2300 WCHAR SrcPath
[MAX_PATH
];
2301 WCHAR DstPath
[MAX_PATH
];
2302 UNICODE_STRING Name
;
2304 PDISKENTRY DiskEntry1
;
2305 PDISKENTRY DiskEntry2
;
2306 PPARTENTRY PartEntry
;
2309 ULONG PartitionCount
;
2310 ULONG DriveLayoutSize
;
2319 Entry1
= List
->DiskListHead
.Flink
;
2320 while (Entry1
!= &List
->DiskListHead
)
2322 DiskEntry1
= CONTAINING_RECORD (Entry1
,
2326 if (DiskEntry1
->Modified
== TRUE
)
2328 /* Count partitioned entries */
2330 Entry2
= DiskEntry1
->PartListHead
.Flink
;
2331 while (Entry2
!= &DiskEntry1
->PartListHead
)
2333 PartEntry
= CONTAINING_RECORD (Entry2
,
2336 if (PartEntry
->Unpartitioned
== FALSE
)
2338 PartitionCount
+= 4;
2341 Entry2
= Entry2
->Flink
;
2343 if (PartitionCount
== 0)
2345 DriveLayoutSize
= sizeof (DRIVE_LAYOUT_INFORMATION
) +
2346 ((4 - 1) * sizeof (PARTITION_INFORMATION
));
2350 DriveLayoutSize
= sizeof (DRIVE_LAYOUT_INFORMATION
) +
2351 ((PartitionCount
- 1) * sizeof (PARTITION_INFORMATION
));
2353 DriveLayout
= (PDRIVE_LAYOUT_INFORMATION
)RtlAllocateHeap (ProcessHeap
,
2356 if (DriveLayout
== NULL
)
2358 DPRINT1 ("RtlAllocateHeap() failed\n");
2362 RtlZeroMemory (DriveLayout
,
2365 if (PartitionCount
== 0)
2367 /* delete all partitions in the mbr */
2368 DriveLayout
->PartitionCount
= 4;
2369 for (Index
= 0; Index
< 4; Index
++)
2371 DriveLayout
->PartitionEntry
[Index
].RewritePartition
= TRUE
;
2376 DriveLayout
->PartitionCount
= PartitionCount
;
2379 Entry2
= DiskEntry1
->PartListHead
.Flink
;
2380 while (Entry2
!= &DiskEntry1
->PartListHead
)
2382 PartEntry
= CONTAINING_RECORD (Entry2
,
2385 if (PartEntry
->Unpartitioned
== FALSE
)
2387 RtlCopyMemory (&DriveLayout
->PartitionEntry
[Index
],
2388 &PartEntry
->PartInfo
[0],
2389 4 * sizeof (PARTITION_INFORMATION
));
2393 Entry2
= Entry2
->Flink
;
2396 if (DiskEntry1
->Signature
== 0)
2398 LARGE_INTEGER SystemTime
;
2399 TIME_FIELDS TimeFields
;
2401 Buffer
= (PUCHAR
)&DiskEntry1
->Signature
;
2405 NtQuerySystemTime (&SystemTime
);
2406 RtlTimeToTimeFields (&SystemTime
, &TimeFields
);
2408 Buffer
[0] = (UCHAR
)(TimeFields
.Year
& 0xFF) + (UCHAR
)(TimeFields
.Hour
& 0xFF);
2409 Buffer
[1] = (UCHAR
)(TimeFields
.Year
>> 8) + (UCHAR
)(TimeFields
.Minute
& 0xFF);
2410 Buffer
[2] = (UCHAR
)(TimeFields
.Month
& 0xFF) + (UCHAR
)(TimeFields
.Second
& 0xFF);
2411 Buffer
[3] = (UCHAR
)(TimeFields
.Day
& 0xFF) + (UCHAR
)(TimeFields
.Milliseconds
& 0xFF);
2413 if (DiskEntry1
->Signature
== 0)
2418 /* check if the signature already exist */
2420 * Check also signatures from disks, which are
2421 * not visible (bootable) by the bios.
2423 Entry2
= List
->DiskListHead
.Flink
;
2424 while (Entry2
!= &List
->DiskListHead
)
2426 DiskEntry2
= CONTAINING_RECORD(Entry2
, DISKENTRY
, ListEntry
);
2427 if (DiskEntry1
!= DiskEntry2
&&
2428 DiskEntry1
->Signature
== DiskEntry2
->Signature
)
2432 Entry2
= Entry2
->Flink
;
2434 if (Entry2
== &List
->DiskListHead
)
2440 /* set one partition entry to dirty, this will update the signature */
2441 DriveLayout
->PartitionEntry
[0].RewritePartition
= TRUE
;
2445 DriveLayout
->Signature
= DiskEntry1
->Signature
;
2449 L
"\\Device\\Harddisk%d\\Partition0",
2450 DiskEntry1
->DiskNumber
);
2451 RtlInitUnicodeString (&Name
,
2453 InitializeObjectAttributes (&ObjectAttributes
,
2459 Status
= NtOpenFile (&FileHandle
,
2464 FILE_SYNCHRONOUS_IO_NONALERT
);
2466 if (!NT_SUCCESS (Status
))
2468 DPRINT1 ("NtOpenFile() failed (Status %lx)\n", Status
);
2472 Status
= NtDeviceIoControlFile (FileHandle
,
2477 IOCTL_DISK_SET_DRIVE_LAYOUT
,
2482 if (!NT_SUCCESS (Status
))
2484 DPRINT1 ("NtDeviceIoControlFile() failed (Status %lx)\n", Status
);
2485 NtClose (FileHandle
);
2489 RtlFreeHeap (ProcessHeap
,
2493 NtClose (FileHandle
);
2495 /* Install MBR code if the disk is new */
2496 if (DiskEntry1
->NewDisk
== TRUE
&&
2497 DiskEntry1
->BiosDiskNumber
== 0)
2499 wcscpy (SrcPath
, SourceRootPath
.Buffer
);
2500 wcscat (SrcPath
, L
"\\loader\\dosmbr.bin");
2502 DPRINT ("Install MBR bootcode: %S ==> %S\n",
2505 /* Install MBR bootcode */
2506 Status
= InstallMbrBootCodeToDisk (SrcPath
,
2508 if (!NT_SUCCESS (Status
))
2510 DPRINT1 ("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
2515 DiskEntry1
->NewDisk
= FALSE
;
2519 Entry1
= Entry1
->Flink
;
2525 BOOL
SetMountedDeviceValues(PPARTLIST List
)
2527 PLIST_ENTRY Entry1
, Entry2
;
2528 PDISKENTRY DiskEntry
;
2529 PPARTENTRY PartEntry
;
2536 Entry1
= List
->DiskListHead
.Flink
;
2537 while (Entry1
!= &List
->DiskListHead
)
2539 DiskEntry
= CONTAINING_RECORD (Entry1
,
2543 Entry2
= DiskEntry
->PartListHead
.Flink
;
2544 while (Entry2
!= &DiskEntry
->PartListHead
)
2546 PartEntry
= CONTAINING_RECORD(Entry2
, PARTENTRY
, ListEntry
);
2547 if (!PartEntry
->Unpartitioned
&& PartEntry
->DriveLetter
)
2549 if (!SetMountedDeviceValue(PartEntry
->DriveLetter
, DiskEntry
->Signature
, PartEntry
->PartInfo
[0].StartingOffset
))
2554 Entry2
= Entry2
->Flink
;
2556 Entry1
= Entry1
->Flink
;