Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpartlist.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2002, 2003, 2004, 2005 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* COPYRIGHT: See COPYING in the top level directory 00020 * PROJECT: ReactOS text-mode setup 00021 * FILE: subsys/system/usetup/partlist.c 00022 * PURPOSE: Partition list functions 00023 * PROGRAMMER: Eric Kohl 00024 * Casper S. Hornstrup (chorns@users.sourceforge.net) 00025 */ 00026 00027 #include "usetup.h" 00028 00029 #define NDEBUG 00030 #include <debug.h> 00031 00032 /* FUNCTIONS ****************************************************************/ 00033 00034 static VOID 00035 GetDriverName (PDISKENTRY DiskEntry) 00036 { 00037 RTL_QUERY_REGISTRY_TABLE QueryTable[2]; 00038 WCHAR KeyName[32]; 00039 NTSTATUS Status; 00040 00041 RtlInitUnicodeString (&DiskEntry->DriverName, 00042 NULL); 00043 00044 swprintf (KeyName, 00045 L"\\Scsi\\Scsi Port %lu", 00046 DiskEntry->Port); 00047 00048 RtlZeroMemory (&QueryTable, 00049 sizeof(QueryTable)); 00050 00051 QueryTable[0].Name = L"Driver"; 00052 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; 00053 QueryTable[0].EntryContext = &DiskEntry->DriverName; 00054 00055 Status = RtlQueryRegistryValues (RTL_REGISTRY_DEVICEMAP, 00056 KeyName, 00057 QueryTable, 00058 NULL, 00059 NULL); 00060 if (!NT_SUCCESS (Status)) 00061 { 00062 DPRINT1 ("RtlQueryRegistryValues() failed (Status %lx)\n", Status); 00063 } 00064 } 00065 00066 00067 static VOID 00068 AssignDriverLetters (PPARTLIST List) 00069 { 00070 PDISKENTRY DiskEntry; 00071 PPARTENTRY PartEntry; 00072 PLIST_ENTRY Entry1; 00073 //PLIST_ENTRY Entry2; 00074 CHAR Letter; 00075 UCHAR i; 00076 00077 Letter = 'C'; 00078 00079 /* Assign drive letters to primary partitions */ 00080 Entry1 = List->DiskListHead.Flink; 00081 while (Entry1 != &List->DiskListHead) 00082 { 00083 DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); 00084 00085 if (!IsListEmpty (&DiskEntry->PartListHead)) 00086 { 00087 PartEntry = CONTAINING_RECORD (DiskEntry->PartListHead.Flink, 00088 PARTENTRY, 00089 ListEntry); 00090 00091 for (i=0; i<4; i++) 00092 PartEntry->DriveLetter[i] = 0; 00093 00094 if (PartEntry->Unpartitioned == FALSE) 00095 { 00096 for (i=0; i<4; i++) 00097 { 00098 if (IsContainerPartition (PartEntry->PartInfo[i].PartitionType)) 00099 continue; 00100 00101 if (IsRecognizedPartition (PartEntry->PartInfo[i].PartitionType) || 00102 (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED && 00103 PartEntry->PartInfo[i].PartitionLength.QuadPart != 0LL)) 00104 { 00105 if (Letter <= 'Z') 00106 { 00107 PartEntry->DriveLetter[i] = Letter; 00108 Letter++; 00109 } 00110 } 00111 } 00112 } 00113 } 00114 00115 Entry1 = Entry1->Flink; 00116 } 00117 00118 /* Assign drive letters to logical drives */ 00119 #if 0 00120 Entry1 = List->DiskListHead.Flink; 00121 while (Entry1 != &List->DiskListHead) 00122 { 00123 DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); 00124 00125 Entry2 = DiskEntry->PartListHead.Flink; 00126 if (Entry2 != &DiskEntry->PartListHead) 00127 { 00128 Entry2 = Entry2->Flink; 00129 while (Entry2 != &DiskEntry->PartListHead) 00130 { 00131 PartEntry = CONTAINING_RECORD (Entry2, 00132 PARTENTRY, 00133 ListEntry); 00134 00135 PartEntry->DriveLetter = 0; 00136 00137 if (PartEntry->Unpartitioned == FALSE && 00138 !IsContainerPartition (PartEntry->PartInfo[0].PartitionType)) 00139 { 00140 if (IsRecognizedPartition (PartEntry->PartInfo[0].PartitionType) || 00141 (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED && 00142 PartEntry->PartInfo[0].PartitionLength.QuadPart != 0LL)) 00143 { 00144 if (Letter <= 'Z') 00145 { 00146 PartEntry->DriveLetter = Letter; 00147 Letter++; 00148 } 00149 } 00150 } 00151 00152 Entry2 = Entry2->Flink; 00153 } 00154 } 00155 00156 Entry1 = Entry1->Flink; 00157 } 00158 #endif 00159 } 00160 00161 00162 static VOID 00163 UpdatePartitionNumbers (PDISKENTRY DiskEntry) 00164 { 00165 PPARTENTRY PartEntry; 00166 PLIST_ENTRY Entry; 00167 ULONG PartNumber; 00168 ULONG i; 00169 00170 PartNumber = 1; 00171 Entry = DiskEntry->PartListHead.Flink; 00172 while (Entry != &DiskEntry->PartListHead) 00173 { 00174 PartEntry = CONTAINING_RECORD (Entry, 00175 PARTENTRY, 00176 ListEntry); 00177 00178 if (PartEntry->Unpartitioned == TRUE) 00179 { 00180 for (i = 0; i < 4; i++) 00181 { 00182 PartEntry->PartInfo[i].PartitionNumber = 0; 00183 } 00184 } 00185 else 00186 { 00187 for (i = 0; i < 4; i++) 00188 { 00189 if (IsContainerPartition (PartEntry->PartInfo[i].PartitionType)) 00190 { 00191 PartEntry->PartInfo[i].PartitionNumber = 0; 00192 } 00193 else if (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED && 00194 PartEntry->PartInfo[i].PartitionLength.QuadPart == 0ULL) 00195 { 00196 PartEntry->PartInfo[i].PartitionNumber = 0; 00197 } 00198 else 00199 { 00200 PartEntry->PartInfo[i].PartitionNumber = PartNumber; 00201 PartNumber++; 00202 } 00203 } 00204 } 00205 00206 Entry = Entry->Flink; 00207 } 00208 } 00209 00210 00211 static VOID 00212 AddPartitionToList (ULONG DiskNumber, 00213 PDISKENTRY DiskEntry, 00214 DRIVE_LAYOUT_INFORMATION *LayoutBuffer) 00215 { 00216 PPARTENTRY PartEntry; 00217 ULONG i; 00218 ULONG j; 00219 00220 for (i = 0; i < LayoutBuffer->PartitionCount; i += 4) 00221 { 00222 for (j = 0; j < 4; j++) 00223 { 00224 if (LayoutBuffer->PartitionEntry[i+j].PartitionType != PARTITION_ENTRY_UNUSED || 00225 LayoutBuffer->PartitionEntry[i+j].PartitionLength.QuadPart != 0ULL) 00226 { 00227 break; 00228 } 00229 } 00230 if (j >= 4) 00231 { 00232 continue; 00233 } 00234 00235 PartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, 00236 0, 00237 sizeof(PARTENTRY)); 00238 if (PartEntry == NULL) 00239 { 00240 return; 00241 } 00242 00243 RtlZeroMemory (PartEntry, 00244 sizeof(PARTENTRY)); 00245 00246 PartEntry->Unpartitioned = FALSE; 00247 00248 for (j = 0; j < 4; j++) 00249 { 00250 RtlCopyMemory (&PartEntry->PartInfo[j], 00251 &LayoutBuffer->PartitionEntry[i+j], 00252 sizeof(PARTITION_INFORMATION)); 00253 } 00254 00255 if (IsContainerPartition(PartEntry->PartInfo[0].PartitionType)) 00256 { 00257 PartEntry->FormatState = Unformatted; 00258 } 00259 else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) || 00260 (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) || 00261 (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) || 00262 (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13) || 00263 (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) || 00264 (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13)) 00265 { 00266 #if 0 00267 if (CheckFatFormat()) 00268 { 00269 PartEntry->FormatState = Preformatted; 00270 } 00271 else 00272 { 00273 PartEntry->FormatState = Unformatted; 00274 } 00275 #endif 00276 PartEntry->FormatState = Preformatted; 00277 } 00278 else if (PartEntry->PartInfo[0].PartitionType == PARTITION_EXT2) 00279 { 00280 #if 0 00281 if (CheckExt2Format()) 00282 { 00283 PartEntry->FormatState = Preformatted; 00284 } 00285 else 00286 { 00287 PartEntry->FormatState = Unformatted; 00288 } 00289 #endif 00290 PartEntry->FormatState = Preformatted; 00291 } 00292 else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS) 00293 { 00294 #if 0 00295 if (CheckNtfsFormat()) 00296 { 00297 PartEntry->FormatState = Preformatted; 00298 } 00299 else if (CheckHpfsFormat()) 00300 { 00301 PartEntry->FormatState = Preformatted; 00302 } 00303 else 00304 { 00305 PartEntry->FormatState = Unformatted; 00306 } 00307 #endif 00308 PartEntry->FormatState = Preformatted; 00309 } 00310 else 00311 { 00312 PartEntry->FormatState = UnknownFormat; 00313 } 00314 00315 InsertTailList (&DiskEntry->PartListHead, 00316 &PartEntry->ListEntry); 00317 } 00318 } 00319 00320 00321 static VOID 00322 ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry) 00323 { 00324 ULONGLONG LastStartingOffset; 00325 ULONGLONG LastPartitionLength; 00326 ULONGLONG LastUnusedPartitionLength; 00327 PPARTENTRY PartEntry; 00328 PPARTENTRY NewPartEntry; 00329 PLIST_ENTRY Entry; 00330 ULONG i; 00331 ULONG j; 00332 00333 if (IsListEmpty (&DiskEntry->PartListHead)) 00334 { 00335 /* Create a partition table that represents the empty disk */ 00336 PartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, 00337 0, 00338 sizeof(PARTENTRY)); 00339 if (PartEntry == NULL) 00340 return; 00341 00342 RtlZeroMemory (PartEntry, 00343 sizeof(PARTENTRY)); 00344 00345 PartEntry->Unpartitioned = TRUE; 00346 PartEntry->UnpartitionedOffset = 0ULL; 00347 PartEntry->UnpartitionedLength = DiskEntry->DiskSize; 00348 00349 PartEntry->FormatState = Unformatted; 00350 00351 InsertTailList (&DiskEntry->PartListHead, 00352 &PartEntry->ListEntry); 00353 } 00354 else 00355 { 00356 /* Start partition at head 1, cylinder 0 */ 00357 LastStartingOffset = DiskEntry->TrackSize; 00358 LastPartitionLength = 0ULL; 00359 LastUnusedPartitionLength = 0ULL; 00360 00361 i = 0; 00362 Entry = DiskEntry->PartListHead.Flink; 00363 while (Entry != &DiskEntry->PartListHead) 00364 { 00365 PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry); 00366 00367 for (j = 0; j < 4; j++) 00368 { 00369 if ((!IsContainerPartition (PartEntry->PartInfo[j].PartitionType)) && 00370 (PartEntry->PartInfo[j].PartitionType != PARTITION_ENTRY_UNUSED || 00371 PartEntry->PartInfo[j].PartitionLength.QuadPart != 0LL)) 00372 { 00373 LastUnusedPartitionLength = 00374 PartEntry->PartInfo[j].StartingOffset.QuadPart - 00375 (LastStartingOffset + LastPartitionLength); 00376 00377 if (PartEntry->PartInfo[j].StartingOffset.QuadPart > (LastStartingOffset + LastPartitionLength) && 00378 LastUnusedPartitionLength >= DiskEntry->CylinderSize) 00379 { 00380 DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength); 00381 00382 NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, 00383 0, 00384 sizeof(PARTENTRY)); 00385 if (NewPartEntry == NULL) 00386 return; 00387 00388 RtlZeroMemory (NewPartEntry, 00389 sizeof(PARTENTRY)); 00390 00391 NewPartEntry->Unpartitioned = TRUE; 00392 NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength; 00393 NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength; 00394 if (j == 0) 00395 NewPartEntry->UnpartitionedLength -= DiskEntry->TrackSize; 00396 00397 NewPartEntry->FormatState = Unformatted; 00398 00399 /* Insert the table into the list */ 00400 InsertTailList (&PartEntry->ListEntry, 00401 &NewPartEntry->ListEntry); 00402 } 00403 00404 LastStartingOffset = PartEntry->PartInfo[j].StartingOffset.QuadPart; 00405 LastPartitionLength = PartEntry->PartInfo[j].PartitionLength.QuadPart; 00406 } 00407 } 00408 00409 i += 4; 00410 Entry = Entry->Flink; 00411 } 00412 00413 /* Check for trailing unpartitioned disk space */ 00414 if (DiskEntry->DiskSize > (LastStartingOffset + LastPartitionLength)) 00415 { 00416 /* Round-down to cylinder size */ 00417 LastUnusedPartitionLength = 00418 (DiskEntry->DiskSize - (LastStartingOffset + LastPartitionLength)) 00419 & ~(DiskEntry->CylinderSize - 1); 00420 00421 if (LastUnusedPartitionLength >= DiskEntry->CylinderSize) 00422 { 00423 DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength); 00424 00425 NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, 00426 0, 00427 sizeof(PARTENTRY)); 00428 if (NewPartEntry == NULL) 00429 return; 00430 00431 RtlZeroMemory (NewPartEntry, 00432 sizeof(PARTENTRY)); 00433 00434 NewPartEntry->Unpartitioned = TRUE; 00435 NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength; 00436 NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength; 00437 00438 /* Append the table to the list */ 00439 InsertTailList (&DiskEntry->PartListHead, 00440 &NewPartEntry->ListEntry); 00441 } 00442 } 00443 } 00444 } 00445 00446 NTSTATUS 00447 NTAPI 00448 DiskIdentifierQueryRoutine(PWSTR ValueName, 00449 ULONG ValueType, 00450 PVOID ValueData, 00451 ULONG ValueLength, 00452 PVOID Context, 00453 PVOID EntryContext) 00454 { 00455 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; 00456 UNICODE_STRING NameU; 00457 00458 if (ValueType == REG_SZ && 00459 ValueLength == 20 * sizeof(WCHAR)) 00460 { 00461 NameU.Buffer = (PWCHAR)ValueData; 00462 NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR); 00463 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum); 00464 00465 NameU.Buffer = (PWCHAR)ValueData + 9; 00466 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature); 00467 00468 return STATUS_SUCCESS; 00469 } 00470 return STATUS_UNSUCCESSFUL; 00471 } 00472 00473 NTSTATUS 00474 NTAPI 00475 DiskConfigurationDataQueryRoutine(PWSTR ValueName, 00476 ULONG ValueType, 00477 PVOID ValueData, 00478 ULONG ValueLength, 00479 PVOID Context, 00480 PVOID EntryContext) 00481 { 00482 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; 00483 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; 00484 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; 00485 ULONG i; 00486 00487 if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || 00488 ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) 00489 return STATUS_UNSUCCESSFUL; 00490 00491 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; 00492 /* Hm. Version and Revision are not set on Microsoft Windows XP... */ 00493 /*if (FullResourceDescriptor->PartialResourceList.Version != 1 || 00494 FullResourceDescriptor->PartialResourceList.Revision != 1) 00495 return STATUS_UNSUCCESSFUL;*/ 00496 00497 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++) 00498 { 00499 if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific || 00500 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)) 00501 continue; 00502 00503 DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1]; 00504 BiosDiskEntry->DiskGeometry = *DiskGeometry; 00505 00506 return STATUS_SUCCESS; 00507 } 00508 return STATUS_UNSUCCESSFUL; 00509 } 00510 00511 NTSTATUS 00512 NTAPI 00513 SystemConfigurationDataQueryRoutine(PWSTR ValueName, 00514 ULONG ValueType, 00515 PVOID ValueData, 00516 ULONG ValueLength, 00517 PVOID Context, 00518 PVOID EntryContext) 00519 { 00520 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; 00521 PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context; 00522 ULONG i; 00523 00524 if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || 00525 ValueLength < sizeof (CM_FULL_RESOURCE_DESCRIPTOR)) 00526 return STATUS_UNSUCCESSFUL; 00527 00528 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; 00529 /* Hm. Version and Revision are not set on Microsoft Windows XP... */ 00530 /*if (FullResourceDescriptor->PartialResourceList.Version != 1 || 00531 FullResourceDescriptor->PartialResourceList.Revision != 1) 00532 return STATUS_UNSUCCESSFUL;*/ 00533 00534 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++) 00535 { 00536 if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific || 00537 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0) 00538 continue; 00539 00540 *Int13Drives = (CM_INT13_DRIVE_PARAMETER*) RtlAllocateHeap(ProcessHeap, 0, FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize); 00541 if (*Int13Drives == NULL) 00542 return STATUS_NO_MEMORY; 00543 memcpy(*Int13Drives, 00544 &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1], 00545 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize); 00546 return STATUS_SUCCESS; 00547 } 00548 return STATUS_UNSUCCESSFUL; 00549 } 00550 #define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter" 00551 00552 static VOID 00553 EnumerateBiosDiskEntries(PPARTLIST PartList) 00554 { 00555 RTL_QUERY_REGISTRY_TABLE QueryTable[3]; 00556 WCHAR Name[120]; 00557 ULONG AdapterCount; 00558 ULONG DiskCount; 00559 NTSTATUS Status; 00560 PCM_INT13_DRIVE_PARAMETER Int13Drives; 00561 PBIOSDISKENTRY BiosDiskEntry; 00562 00563 memset(QueryTable, 0, sizeof(QueryTable)); 00564 00565 QueryTable[1].Name = L"Configuration Data"; 00566 QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine; 00567 Int13Drives = NULL; 00568 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 00569 L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System", 00570 &QueryTable[1], 00571 (PVOID)&Int13Drives, 00572 NULL); 00573 if (!NT_SUCCESS(Status)) 00574 { 00575 DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status); 00576 return; 00577 } 00578 00579 AdapterCount = 0; 00580 while (1) 00581 { 00582 swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount); 00583 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 00584 Name, 00585 &QueryTable[2], 00586 NULL, 00587 NULL); 00588 if (!NT_SUCCESS(Status)) 00589 { 00590 break; 00591 } 00592 00593 swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount); 00594 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 00595 Name, 00596 &QueryTable[2], 00597 NULL, 00598 NULL); 00599 if (NT_SUCCESS(Status)) 00600 { 00601 while (1) 00602 { 00603 swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount); 00604 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 00605 Name, 00606 &QueryTable[2], 00607 NULL, 00608 NULL); 00609 if (!NT_SUCCESS(Status)) 00610 { 00611 RtlFreeHeap(ProcessHeap, 0, Int13Drives); 00612 return; 00613 } 00614 00615 swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount); 00616 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 00617 Name, 00618 &QueryTable[2], 00619 NULL, 00620 NULL); 00621 if (NT_SUCCESS(Status)) 00622 { 00623 QueryTable[0].Name = L"Identifier"; 00624 QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine; 00625 QueryTable[1].Name = L"Configuration Data"; 00626 QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine; 00627 DiskCount = 0; 00628 while (1) 00629 { 00630 BiosDiskEntry = (BIOSDISKENTRY*) RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY)); 00631 if (BiosDiskEntry == NULL) 00632 { 00633 break; 00634 } 00635 swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount); 00636 Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, 00637 Name, 00638 QueryTable, 00639 (PVOID)BiosDiskEntry, 00640 NULL); 00641 if (!NT_SUCCESS(Status)) 00642 { 00643 RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry); 00644 break; 00645 } 00646 BiosDiskEntry->DiskNumber = DiskCount; 00647 BiosDiskEntry->Recognized = FALSE; 00648 00649 if (DiskCount < Int13Drives[0].NumberDrives) 00650 { 00651 BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount]; 00652 } 00653 else 00654 { 00655 DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount); 00656 } 00657 00658 00659 InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry); 00660 00661 DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber); 00662 DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature); 00663 DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum); 00664 DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector); 00665 DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders); 00666 DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads); 00667 DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect); 00668 DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders); 00669 DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack); 00670 DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads); 00671 DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives); 00672 00673 DiskCount++; 00674 } 00675 } 00676 RtlFreeHeap(ProcessHeap, 0, Int13Drives); 00677 return; 00678 } 00679 } 00680 AdapterCount++; 00681 } 00682 RtlFreeHeap(ProcessHeap, 0, Int13Drives); 00683 } 00684 00685 static VOID 00686 AddDiskToList (HANDLE FileHandle, 00687 ULONG DiskNumber, 00688 PPARTLIST List) 00689 { 00690 DRIVE_LAYOUT_INFORMATION *LayoutBuffer; 00691 DISK_GEOMETRY DiskGeometry; 00692 SCSI_ADDRESS ScsiAddress; 00693 PDISKENTRY DiskEntry; 00694 IO_STATUS_BLOCK Iosb; 00695 NTSTATUS Status; 00696 PPARTITION_SECTOR Mbr; 00697 PULONG Buffer; 00698 LARGE_INTEGER FileOffset; 00699 WCHAR Identifier[20]; 00700 ULONG Checksum; 00701 ULONG Signature; 00702 ULONG i; 00703 PLIST_ENTRY ListEntry; 00704 PBIOSDISKENTRY BiosDiskEntry; 00705 ULONG LayoutBufferSize; 00706 00707 Status = NtDeviceIoControlFile (FileHandle, 00708 NULL, 00709 NULL, 00710 NULL, 00711 &Iosb, 00712 IOCTL_DISK_GET_DRIVE_GEOMETRY, 00713 NULL, 00714 0, 00715 &DiskGeometry, 00716 sizeof(DISK_GEOMETRY)); 00717 if (!NT_SUCCESS (Status)) 00718 { 00719 return; 00720 } 00721 00722 if (DiskGeometry.MediaType != FixedMedia && 00723 DiskGeometry.MediaType != RemovableMedia) 00724 { 00725 return; 00726 } 00727 00728 Status = NtDeviceIoControlFile (FileHandle, 00729 NULL, 00730 NULL, 00731 NULL, 00732 &Iosb, 00733 IOCTL_SCSI_GET_ADDRESS, 00734 NULL, 00735 0, 00736 &ScsiAddress, 00737 sizeof(SCSI_ADDRESS)); 00738 if (!NT_SUCCESS(Status)) 00739 { 00740 return; 00741 } 00742 00743 Mbr = (PARTITION_SECTOR*) RtlAllocateHeap(ProcessHeap, 00744 0, 00745 DiskGeometry.BytesPerSector); 00746 00747 if (Mbr == NULL) 00748 { 00749 return; 00750 } 00751 00752 FileOffset.QuadPart = 0; 00753 Status = NtReadFile(FileHandle, 00754 NULL, 00755 NULL, 00756 NULL, 00757 &Iosb, 00758 (PVOID)Mbr, 00759 DiskGeometry.BytesPerSector, 00760 &FileOffset, 00761 NULL); 00762 if (!NT_SUCCESS(Status)) 00763 { 00764 RtlFreeHeap(ProcessHeap, 00765 0, 00766 Mbr); 00767 DPRINT1("NtReadFile failed, status=%x\n", Status); 00768 return; 00769 } 00770 Signature = Mbr->Signature; 00771 00772 /* Calculate the MBR checksum */ 00773 Checksum = 0; 00774 Buffer = (PULONG)Mbr; 00775 for (i = 0; i < 128; i++) 00776 { 00777 Checksum += Buffer[i]; 00778 } 00779 Checksum = ~Checksum + 1; 00780 00781 swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature); 00782 DPRINT("Identifier: %S\n", Identifier); 00783 00784 DiskEntry = (PDISKENTRY)RtlAllocateHeap (ProcessHeap, 00785 0, 00786 sizeof(DISKENTRY)); 00787 if (DiskEntry == NULL) 00788 { 00789 return; 00790 } 00791 00792 DiskEntry->Checksum = Checksum; 00793 DiskEntry->Signature = Signature; 00794 if (Signature == 0) 00795 { 00796 /* If we have no signature, set the disk to dirty. WritePartitionsToDisk creates a new signature */ 00797 DiskEntry->Modified = TRUE; 00798 } 00799 DiskEntry->BiosFound = FALSE; 00800 00801 /* Check if this disk has a valid MBR */ 00802 if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0) 00803 DiskEntry->NoMbr = TRUE; 00804 else 00805 DiskEntry->NoMbr = FALSE; 00806 00807 /* Free Mbr sector buffer */ 00808 RtlFreeHeap (ProcessHeap, 00809 0, 00810 Mbr); 00811 00812 ListEntry = List->BiosDiskListHead.Flink; 00813 while(ListEntry != &List->BiosDiskListHead) 00814 { 00815 BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry); 00816 /* FIXME: 00817 * Compare the size from bios and the reported size from driver. 00818 * If we have more than one disk with a zero or with the same signatur 00819 * we must create new signatures and reboot. After the reboot, 00820 * it is possible to identify the disks. 00821 */ 00822 if (BiosDiskEntry->Signature == Signature && 00823 BiosDiskEntry->Checksum == Checksum && 00824 !BiosDiskEntry->Recognized) 00825 { 00826 if (!DiskEntry->BiosFound) 00827 { 00828 DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber; 00829 DiskEntry->BiosFound = TRUE; 00830 BiosDiskEntry->Recognized = TRUE; 00831 } 00832 else 00833 { 00834 } 00835 } 00836 ListEntry = ListEntry->Flink; 00837 } 00838 00839 if (!DiskEntry->BiosFound) 00840 { 00841 #if 0 00842 RtlFreeHeap(ProcessHeap, 0, DiskEntry); 00843 return; 00844 #else 00845 DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber); 00846 #endif 00847 } 00848 00849 InitializeListHead (&DiskEntry->PartListHead); 00850 00851 DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart; 00852 DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder; 00853 DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack; 00854 DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector; 00855 00856 DPRINT ("Cylinders %I64u\n", DiskEntry->Cylinders); 00857 DPRINT ("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder); 00858 DPRINT ("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack); 00859 DPRINT ("BytesPerSector %I64u\n", DiskEntry->BytesPerSector); 00860 00861 DiskEntry->TrackSize = 00862 (ULONGLONG)DiskGeometry.SectorsPerTrack * 00863 (ULONGLONG)DiskGeometry.BytesPerSector; 00864 DiskEntry->CylinderSize = 00865 (ULONGLONG)DiskGeometry.TracksPerCylinder * 00866 DiskEntry->TrackSize; 00867 DiskEntry->DiskSize = 00868 DiskGeometry.Cylinders.QuadPart * 00869 DiskEntry->CylinderSize; 00870 00871 DiskEntry->DiskNumber = DiskNumber; 00872 DiskEntry->Port = ScsiAddress.PortNumber; 00873 DiskEntry->Bus = ScsiAddress.PathId; 00874 DiskEntry->Id = ScsiAddress.TargetId; 00875 00876 GetDriverName (DiskEntry); 00877 00878 InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber); 00879 00880 /* 00881 * Allocate a buffer for 26 logical drives (2 entries each == 52) 00882 * plus the main partiton table (4 entries). Total 56 entries. 00883 */ 00884 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + 00885 ((56 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); 00886 LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap (ProcessHeap, 00887 0, 00888 LayoutBufferSize); 00889 if (LayoutBuffer == NULL) 00890 { 00891 return; 00892 } 00893 00894 Status = NtDeviceIoControlFile (FileHandle, 00895 NULL, 00896 NULL, 00897 NULL, 00898 &Iosb, 00899 IOCTL_DISK_GET_DRIVE_LAYOUT, 00900 NULL, 00901 0, 00902 LayoutBuffer, 00903 LayoutBufferSize); 00904 if (NT_SUCCESS (Status)) 00905 { 00906 if (LayoutBuffer->PartitionCount == 0) 00907 { 00908 DiskEntry->NewDisk = TRUE; 00909 } 00910 00911 AddPartitionToList (DiskNumber, 00912 DiskEntry, 00913 LayoutBuffer); 00914 00915 ScanForUnpartitionedDiskSpace (DiskEntry); 00916 } 00917 00918 RtlFreeHeap (ProcessHeap, 00919 0, 00920 LayoutBuffer); 00921 } 00922 00923 00924 PPARTLIST 00925 CreatePartitionList (SHORT Left, 00926 SHORT Top, 00927 SHORT Right, 00928 SHORT Bottom) 00929 { 00930 PPARTLIST List; 00931 OBJECT_ATTRIBUTES ObjectAttributes; 00932 SYSTEM_DEVICE_INFORMATION Sdi; 00933 IO_STATUS_BLOCK Iosb; 00934 ULONG ReturnSize; 00935 NTSTATUS Status; 00936 ULONG DiskNumber; 00937 WCHAR Buffer[MAX_PATH]; 00938 UNICODE_STRING Name; 00939 HANDLE FileHandle; 00940 00941 List = (PPARTLIST)RtlAllocateHeap (ProcessHeap, 00942 0, 00943 sizeof (PARTLIST)); 00944 if (List == NULL) 00945 return NULL; 00946 00947 List->Left = Left; 00948 List->Top = Top; 00949 List->Right = Right; 00950 List->Bottom = Bottom; 00951 00952 List->Line = 0; 00953 List->Offset = 0; 00954 00955 List->TopDisk = (ULONG)-1; 00956 List->TopPartition = (ULONG)-1; 00957 00958 List->CurrentDisk = NULL; 00959 List->CurrentPartition = NULL; 00960 List->CurrentPartitionNumber = 0; 00961 00962 InitializeListHead (&List->DiskListHead); 00963 InitializeListHead (&List->BiosDiskListHead); 00964 00965 EnumerateBiosDiskEntries(List); 00966 00967 Status = NtQuerySystemInformation (SystemDeviceInformation, 00968 &Sdi, 00969 sizeof(SYSTEM_DEVICE_INFORMATION), 00970 &ReturnSize); 00971 if (!NT_SUCCESS (Status)) 00972 { 00973 RtlFreeHeap (ProcessHeap, 0, List); 00974 return NULL; 00975 } 00976 00977 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++) 00978 { 00979 swprintf (Buffer, 00980 L"\\Device\\Harddisk%d\\Partition0", 00981 DiskNumber); 00982 RtlInitUnicodeString (&Name, 00983 Buffer); 00984 00985 InitializeObjectAttributes (&ObjectAttributes, 00986 &Name, 00987 0, 00988 NULL, 00989 NULL); 00990 00991 Status = NtOpenFile (&FileHandle, 00992 FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, 00993 &ObjectAttributes, 00994 &Iosb, 00995 FILE_SHARE_READ, 00996 FILE_SYNCHRONOUS_IO_NONALERT); 00997 if (NT_SUCCESS(Status)) 00998 { 00999 AddDiskToList (FileHandle, 01000 DiskNumber, 01001 List); 01002 01003 NtClose(FileHandle); 01004 } 01005 } 01006 01007 AssignDriverLetters (List); 01008 01009 List->TopDisk = 0; 01010 List->TopPartition = 0; 01011 01012 /* Search for first usable disk and partition */ 01013 if (IsListEmpty (&List->DiskListHead)) 01014 { 01015 List->CurrentDisk = NULL; 01016 List->CurrentPartition = NULL; 01017 List->CurrentPartitionNumber = 0; 01018 } 01019 else 01020 { 01021 List->CurrentDisk = 01022 CONTAINING_RECORD (List->DiskListHead.Flink, 01023 DISKENTRY, 01024 ListEntry); 01025 01026 if (IsListEmpty (&List->CurrentDisk->PartListHead)) 01027 { 01028 List->CurrentPartition = 0; 01029 List->CurrentPartitionNumber = 0; 01030 } 01031 else 01032 { 01033 List->CurrentPartition = 01034 CONTAINING_RECORD (List->CurrentDisk->PartListHead.Flink, 01035 PARTENTRY, 01036 ListEntry); 01037 List->CurrentPartitionNumber = 0; 01038 } 01039 } 01040 01041 return List; 01042 } 01043 01044 01045 VOID 01046 DestroyPartitionList (PPARTLIST List) 01047 { 01048 PDISKENTRY DiskEntry; 01049 PBIOSDISKENTRY BiosDiskEntry; 01050 PPARTENTRY PartEntry; 01051 PLIST_ENTRY Entry; 01052 01053 /* Release disk and partition info */ 01054 while (!IsListEmpty (&List->DiskListHead)) 01055 { 01056 Entry = RemoveHeadList (&List->DiskListHead); 01057 DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); 01058 01059 /* Release driver name */ 01060 RtlFreeUnicodeString(&DiskEntry->DriverName); 01061 01062 /* Release partition array */ 01063 while (!IsListEmpty (&DiskEntry->PartListHead)) 01064 { 01065 Entry = RemoveHeadList (&DiskEntry->PartListHead); 01066 PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry); 01067 01068 RtlFreeHeap (ProcessHeap, 01069 0, 01070 PartEntry); 01071 } 01072 01073 /* Release disk entry */ 01074 RtlFreeHeap (ProcessHeap, 0, DiskEntry); 01075 } 01076 01077 /* release the bios disk info */ 01078 while(!IsListEmpty(&List->BiosDiskListHead)) 01079 { 01080 Entry = RemoveHeadList(&List->BiosDiskListHead); 01081 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry); 01082 01083 RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry); 01084 } 01085 01086 /* Release list head */ 01087 RtlFreeHeap (ProcessHeap, 0, List); 01088 } 01089 01090 01091 static VOID 01092 PrintEmptyLine (PPARTLIST List) 01093 { 01094 COORD coPos; 01095 DWORD Written; 01096 USHORT Width; 01097 USHORT Height; 01098 01099 Width = List->Right - List->Left - 1; 01100 Height = List->Bottom - List->Top - 2; 01101 01102 01103 coPos.X = List->Left + 1; 01104 coPos.Y = List->Top + 1 + List->Line; 01105 01106 if (List->Line >= 0 && List->Line <= Height) 01107 { 01108 FillConsoleOutputAttribute (StdOutput, 01109 FOREGROUND_WHITE | BACKGROUND_BLUE, 01110 Width, 01111 coPos, 01112 &Written); 01113 01114 FillConsoleOutputCharacterA (StdOutput, 01115 ' ', 01116 Width, 01117 coPos, 01118 &Written); 01119 } 01120 List->Line++; 01121 } 01122 01123 01124 static VOID 01125 PrintPartitionData (PPARTLIST List, 01126 PDISKENTRY DiskEntry, 01127 PPARTENTRY PartEntry, 01128 ULONG PartNumber) 01129 { 01130 CHAR LineBuffer[128]; 01131 COORD coPos; 01132 DWORD Written; 01133 USHORT Width; 01134 USHORT Height; 01135 01136 LARGE_INTEGER PartSize; 01137 PCHAR Unit; 01138 UCHAR Attribute; 01139 PCHAR PartType; 01140 01141 Width = List->Right - List->Left - 1; 01142 Height = List->Bottom - List->Top - 2; 01143 01144 01145 coPos.X = List->Left + 1; 01146 coPos.Y = List->Top + 1 + List->Line; 01147 01148 if (PartEntry->Unpartitioned == TRUE) 01149 { 01150 #if 0 01151 if (PartEntry->UnpartitionledLength >= 0x280000000ULL) /* 10 GB */ 01152 { 01153 PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 29)) >> 30; 01154 Unit = MUIGetString(STRING_GB); 01155 } 01156 else 01157 #endif 01158 if (PartEntry->UnpartitionedLength >= 0xA00000ULL) /* 10 MB */ 01159 { 01160 PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; 01161 Unit = MUIGetString(STRING_MB); 01162 } 01163 else 01164 { 01165 PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 9)) >> 10; 01166 Unit = MUIGetString(STRING_KB); 01167 } 01168 01169 sprintf (LineBuffer, 01170 MUIGetString(STRING_UNPSPACE), 01171 PartSize.u.LowPart, 01172 Unit); 01173 } 01174 else 01175 { 01176 /* Determine partition type */ 01177 PartType = NULL; 01178 if (PartEntry->New == TRUE) 01179 { 01180 PartType = MUIGetString(STRING_UNFORMATTED); 01181 } 01182 else if (PartEntry->Unpartitioned == FALSE) 01183 { 01184 if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_12) || 01185 (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_16) || 01186 (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_HUGE) || 01187 (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_XINT13)) 01188 { 01189 PartType = "FAT"; 01190 } 01191 else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) || 01192 (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13)) 01193 { 01194 PartType = "FAT32"; 01195 } 01196 else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2) 01197 { 01198 PartType = "EXT2"; 01199 } 01200 else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS) 01201 { 01202 PartType = "NTFS"; /* FIXME: Not quite correct! */ 01203 } 01204 } 01205 01206 #if 0 01207 if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */ 01208 { 01209 PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30; 01210 Unit = MUIGetString(STRING_GB); 01211 } 01212 else 01213 #endif 01214 if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */ 01215 { 01216 PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20; 01217 Unit = MUIGetString(STRING_MB); 01218 } 01219 else 01220 { 01221 PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 9)) >> 10; 01222 Unit = MUIGetString(STRING_KB); 01223 } 01224 01225 if (PartType == NULL) 01226 { 01227 sprintf (LineBuffer, 01228 MUIGetString(STRING_HDDINFOUNK5), 01229 (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], 01230 (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', 01231 PartEntry->PartInfo[PartNumber].PartitionType, 01232 PartSize.u.LowPart, 01233 Unit); 01234 } 01235 else 01236 { 01237 sprintf (LineBuffer, 01238 "%c%c %-24s %6lu %s", 01239 (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], 01240 (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', 01241 PartType, 01242 PartSize.u.LowPart, 01243 Unit); 01244 } 01245 } 01246 01247 Attribute = (List->CurrentDisk == DiskEntry && 01248 List->CurrentPartition == PartEntry && 01249 List->CurrentPartitionNumber == PartNumber) ? 01250 FOREGROUND_BLUE | BACKGROUND_WHITE : 01251 FOREGROUND_WHITE | BACKGROUND_BLUE; 01252 01253 if (List->Line >= 0 && List->Line <= Height) 01254 { 01255 FillConsoleOutputCharacterA (StdOutput, 01256 ' ', 01257 Width, 01258 coPos, 01259 &Written); 01260 } 01261 coPos.X += 4; 01262 Width -= 8; 01263 if (List->Line >= 0 && List->Line <= Height) 01264 { 01265 FillConsoleOutputAttribute (StdOutput, 01266 Attribute, 01267 Width, 01268 coPos, 01269 &Written); 01270 } 01271 coPos.X++; 01272 Width -= 2; 01273 if (List->Line >= 0 && List->Line <= Height) 01274 { 01275 WriteConsoleOutputCharacterA (StdOutput, 01276 LineBuffer, 01277 min (strlen (LineBuffer), Width), 01278 coPos, 01279 &Written); 01280 } 01281 List->Line++; 01282 } 01283 01284 01285 static VOID 01286 PrintDiskData (PPARTLIST List, 01287 PDISKENTRY DiskEntry) 01288 { 01289 PPARTENTRY PartEntry; 01290 PLIST_ENTRY Entry; 01291 CHAR LineBuffer[128]; 01292 COORD coPos; 01293 DWORD Written; 01294 USHORT Width; 01295 USHORT Height; 01296 ULARGE_INTEGER DiskSize; 01297 PCHAR Unit; 01298 ULONG i; 01299 01300 Width = List->Right - List->Left - 1; 01301 Height = List->Bottom - List->Top - 2; 01302 01303 01304 coPos.X = List->Left + 1; 01305 coPos.Y = List->Top + 1 + List->Line; 01306 01307 #if 0 01308 if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */ 01309 { 01310 DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 29)) >> 30; 01311 Unit = MUIGetString(STRING_GB); 01312 } 01313 else 01314 #endif 01315 { 01316 DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 19)) >> 20; 01317 if (DiskSize.QuadPart == 0) 01318 DiskSize.QuadPart = 1; 01319 Unit = MUIGetString(STRING_MB); 01320 } 01321 01322 if (DiskEntry->DriverName.Length > 0) 01323 { 01324 sprintf (LineBuffer, 01325 MUIGetString(STRING_HDINFOPARTSELECT), 01326 DiskSize.u.LowPart, 01327 Unit, 01328 DiskEntry->DiskNumber, 01329 DiskEntry->Port, 01330 DiskEntry->Bus, 01331 DiskEntry->Id, 01332 DiskEntry->DriverName.Buffer); 01333 } 01334 else 01335 { 01336 sprintf (LineBuffer, 01337 MUIGetString(STRING_HDDINFOUNK6), 01338 DiskSize.u.LowPart, 01339 Unit, 01340 DiskEntry->DiskNumber, 01341 DiskEntry->Port, 01342 DiskEntry->Bus, 01343 DiskEntry->Id); 01344 } 01345 if (List->Line >= 0 && List->Line <= Height) 01346 { 01347 FillConsoleOutputAttribute (StdOutput, 01348 FOREGROUND_WHITE | BACKGROUND_BLUE, 01349 Width, 01350 coPos, 01351 &Written); 01352 01353 FillConsoleOutputCharacterA (StdOutput, 01354 ' ', 01355 Width, 01356 coPos, 01357 &Written); 01358 } 01359 01360 coPos.X++; 01361 if (List->Line >= 0 && List->Line <= Height) 01362 { 01363 WriteConsoleOutputCharacterA (StdOutput, 01364 LineBuffer, 01365 min ((USHORT)strlen (LineBuffer), Width - 2), 01366 coPos, 01367 &Written); 01368 } 01369 List->Line++; 01370 01371 /* Print separator line */ 01372 PrintEmptyLine (List); 01373 01374 /* Print partition lines*/ 01375 Entry = DiskEntry->PartListHead.Flink; 01376 while (Entry != &DiskEntry->PartListHead) 01377 { 01378 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); 01379 01380 /* Print disk entry */ 01381 for (i=0; i<4; i++) 01382 { 01383 if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED || 01384 PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL) 01385 { 01386 PrintPartitionData (List, 01387 DiskEntry, 01388 PartEntry, 01389 i); 01390 } 01391 } 01392 01393 /* Print unpartitioned entry */ 01394 if (PartEntry->Unpartitioned) 01395 { 01396 PrintPartitionData (List, 01397 DiskEntry, 01398 PartEntry, 01399 0); 01400 } 01401 01402 Entry = Entry->Flink; 01403 } 01404 01405 /* Print separator line */ 01406 PrintEmptyLine (List); 01407 } 01408 01409 01410 VOID 01411 DrawPartitionList (PPARTLIST List) 01412 { 01413 PLIST_ENTRY Entry, Entry2; 01414 PDISKENTRY DiskEntry; 01415 PPARTENTRY PartEntry = NULL; 01416 COORD coPos; 01417 DWORD Written; 01418 SHORT i; 01419 SHORT CurrentDiskLine; 01420 SHORT CurrentPartLine; 01421 SHORT LastLine; 01422 BOOL CurrentPartLineFound = FALSE; 01423 BOOL CurrentDiskLineFound = FALSE; 01424 01425 /* Calculate the line of the current disk and partition */ 01426 CurrentDiskLine = 0; 01427 CurrentPartLine = 0; 01428 LastLine = 0; 01429 Entry = List->DiskListHead.Flink; 01430 while (Entry != &List->DiskListHead) 01431 { 01432 DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); 01433 LastLine += 2; 01434 if (CurrentPartLineFound == FALSE) 01435 { 01436 CurrentPartLine += 2; 01437 } 01438 Entry2 = DiskEntry->PartListHead.Flink; 01439 while (Entry2 != &DiskEntry->PartListHead) 01440 { 01441 PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); 01442 if (PartEntry == List->CurrentPartition) 01443 { 01444 CurrentPartLineFound = TRUE; 01445 } 01446 Entry2 = Entry2->Flink; 01447 if (CurrentPartLineFound == FALSE) 01448 { 01449 CurrentPartLine++; 01450 } 01451 LastLine++; 01452 } 01453 if (DiskEntry == List->CurrentDisk) 01454 { 01455 CurrentDiskLineFound = TRUE; 01456 } 01457 Entry = Entry->Flink; 01458 if (Entry != &List->DiskListHead) 01459 { 01460 if (CurrentDiskLineFound == FALSE) 01461 { 01462 CurrentPartLine ++; 01463 CurrentDiskLine = CurrentPartLine; 01464 } 01465 LastLine++; 01466 } 01467 else 01468 { 01469 LastLine--; 01470 } 01471 } 01472 01473 /* If it possible, make the disk name visible */ 01474 if (CurrentPartLine < List->Offset) 01475 { 01476 List->Offset = CurrentPartLine; 01477 } 01478 else if (CurrentPartLine - List->Offset > List->Bottom - List->Top - 2) 01479 { 01480 List->Offset = CurrentPartLine - (List->Bottom - List->Top - 2); 01481 } 01482 if (CurrentDiskLine < List->Offset && CurrentPartLine - CurrentDiskLine < List->Bottom - List->Top - 2) 01483 { 01484 List->Offset = CurrentDiskLine; 01485 } 01486 01487 01488 /* draw upper left corner */ 01489 coPos.X = List->Left; 01490 coPos.Y = List->Top; 01491 FillConsoleOutputCharacterA (StdOutput, 01492 0xDA, // '+', 01493 1, 01494 coPos, 01495 &Written); 01496 01497 /* draw upper edge */ 01498 coPos.X = List->Left + 1; 01499 coPos.Y = List->Top; 01500 if (List->Offset == 0) 01501 { 01502 FillConsoleOutputCharacterA (StdOutput, 01503 0xC4, // '-', 01504 List->Right - List->Left - 1, 01505 coPos, 01506 &Written); 01507 } 01508 else 01509 { 01510 FillConsoleOutputCharacterA (StdOutput, 01511 0xC4, // '-', 01512 List->Right - List->Left - 5, 01513 coPos, 01514 &Written); 01515 coPos.X = List->Right - 5; 01516 WriteConsoleOutputCharacterA (StdOutput, 01517 "(\x18)", // "(up)" 01518 3, 01519 coPos, 01520 &Written); 01521 coPos.X = List->Right - 2; 01522 FillConsoleOutputCharacterA (StdOutput, 01523 0xC4, // '-', 01524 2, 01525 coPos, 01526 &Written); 01527 } 01528 01529 /* draw upper right corner */ 01530 coPos.X = List->Right; 01531 coPos.Y = List->Top; 01532 FillConsoleOutputCharacterA (StdOutput, 01533 0xBF, // '+', 01534 1, 01535 coPos, 01536 &Written); 01537 01538 /* draw left and right edge */ 01539 for (i = List->Top + 1; i < List->Bottom; i++) 01540 { 01541 coPos.X = List->Left; 01542 coPos.Y = i; 01543 FillConsoleOutputCharacterA (StdOutput, 01544 0xB3, // '|', 01545 1, 01546 coPos, 01547 &Written); 01548 01549 coPos.X = List->Right; 01550 FillConsoleOutputCharacterA (StdOutput, 01551 0xB3, //'|', 01552 1, 01553 coPos, 01554 &Written); 01555 } 01556 01557 /* draw lower left corner */ 01558 coPos.X = List->Left; 01559 coPos.Y = List->Bottom; 01560 FillConsoleOutputCharacterA (StdOutput, 01561 0xC0, // '+', 01562 1, 01563 coPos, 01564 &Written); 01565 01566 /* draw lower edge */ 01567 coPos.X = List->Left + 1; 01568 coPos.Y = List->Bottom; 01569 if (LastLine - List->Offset <= List->Bottom - List->Top - 2) 01570 { 01571 FillConsoleOutputCharacterA (StdOutput, 01572 0xC4, // '-', 01573 List->Right - List->Left - 1, 01574 coPos, 01575 &Written); 01576 } 01577 else 01578 { 01579 FillConsoleOutputCharacterA (StdOutput, 01580 0xC4, // '-', 01581 List->Right - List->Left - 5, 01582 coPos, 01583 &Written); 01584 coPos.X = List->Right - 5; 01585 WriteConsoleOutputCharacterA (StdOutput, 01586 "(\x19)", // "(down)" 01587 3, 01588 coPos, 01589 &Written); 01590 coPos.X = List->Right - 2; 01591 FillConsoleOutputCharacterA (StdOutput, 01592 0xC4, // '-', 01593 2, 01594 coPos, 01595 &Written); 01596 } 01597 01598 /* draw lower right corner */ 01599 coPos.X = List->Right; 01600 coPos.Y = List->Bottom; 01601 FillConsoleOutputCharacterA (StdOutput, 01602 0xD9, // '+', 01603 1, 01604 coPos, 01605 &Written); 01606 01607 /* print list entries */ 01608 List->Line = - List->Offset; 01609 01610 Entry = List->DiskListHead.Flink; 01611 while (Entry != &List->DiskListHead) 01612 { 01613 DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); 01614 01615 /* Print disk entry */ 01616 PrintDiskData (List, 01617 DiskEntry); 01618 01619 Entry = Entry->Flink; 01620 } 01621 } 01622 01623 01624 DWORD 01625 SelectPartition(PPARTLIST List, ULONG DiskNumber, ULONG PartitionNumber) 01626 { 01627 PDISKENTRY DiskEntry; 01628 PPARTENTRY PartEntry; 01629 PLIST_ENTRY Entry1; 01630 PLIST_ENTRY Entry2; 01631 UCHAR i; 01632 01633 /* Check for empty disks */ 01634 if (IsListEmpty (&List->DiskListHead)) 01635 return FALSE; 01636 01637 /* Check for first usable entry on next disk */ 01638 Entry1 = List->CurrentDisk->ListEntry.Flink; 01639 while (Entry1 != &List->DiskListHead) 01640 { 01641 DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); 01642 01643 if (DiskEntry->DiskNumber == DiskNumber) 01644 { 01645 Entry2 = DiskEntry->PartListHead.Flink; 01646 while (Entry2 != &DiskEntry->PartListHead) 01647 { 01648 PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); 01649 01650 for (i = 0; i < 4; i++) 01651 { 01652 if (PartEntry->PartInfo[i].PartitionNumber == PartitionNumber) 01653 { 01654 List->CurrentDisk = DiskEntry; 01655 List->CurrentPartition = PartEntry; 01656 List->CurrentPartitionNumber = i; 01657 DrawPartitionList (List); 01658 return TRUE; 01659 } 01660 } 01661 Entry2 = Entry2->Flink; 01662 } 01663 return FALSE; 01664 } 01665 Entry1 = Entry1->Flink; 01666 } 01667 return FALSE; 01668 } 01669 01670 01671 VOID 01672 ScrollDownPartitionList (PPARTLIST List) 01673 { 01674 PDISKENTRY DiskEntry; 01675 PPARTENTRY PartEntry; 01676 PLIST_ENTRY Entry1; 01677 PLIST_ENTRY Entry2; 01678 UCHAR i; 01679 01680 /* Check for empty disks */ 01681 if (IsListEmpty (&List->DiskListHead)) 01682 return; 01683 01684 /* Check for next usable entry on current disk */ 01685 if (List->CurrentPartition != NULL) 01686 { 01687 Entry2 = &List->CurrentPartition->ListEntry; 01688 PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); 01689 01690 /* Check if we can move inside primary partitions */ 01691 for (i = List->CurrentPartitionNumber + 1; i < 4; i++) 01692 { 01693 if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) 01694 break; 01695 } 01696 01697 if (i == 4) 01698 { 01699 /* We're out of partitions in the current partition table. 01700 Try to move to the next one if possible. */ 01701 Entry2 = Entry2->Flink; 01702 } 01703 else 01704 { 01705 /* Just advance to the next partition */ 01706 List->CurrentPartitionNumber = i; 01707 DrawPartitionList (List); 01708 return; 01709 } 01710 01711 while (Entry2 != &List->CurrentDisk->PartListHead) 01712 { 01713 PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); 01714 01715 // if (PartEntry->HidePartEntry == FALSE) 01716 { 01717 List->CurrentPartition = PartEntry; 01718 List->CurrentPartitionNumber = 0; 01719 DrawPartitionList (List); 01720 return; 01721 } 01722 Entry2 = Entry2->Flink; 01723 } 01724 } 01725 01726 /* Check for first usable entry on next disk */ 01727 if (List->CurrentDisk != NULL) 01728 { 01729 Entry1 = List->CurrentDisk->ListEntry.Flink; 01730 while (Entry1 != &List->DiskListHead) 01731 { 01732 DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); 01733 01734 Entry2 = DiskEntry->PartListHead.Flink; 01735 while (Entry2 != &DiskEntry->PartListHead) 01736 { 01737 PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); 01738 01739 // if (PartEntry->HidePartEntry == FALSE) 01740 { 01741 List->CurrentDisk = DiskEntry; 01742 List->CurrentPartition = PartEntry; 01743 List->CurrentPartitionNumber = 0; 01744 DrawPartitionList (List); 01745 return; 01746 } 01747 01748 Entry2 = Entry2->Flink; 01749 } 01750 01751 Entry1 = Entry1->Flink; 01752 } 01753 } 01754 } 01755 01756 01757 VOID 01758 ScrollUpPartitionList (PPARTLIST List) 01759 { 01760 PDISKENTRY DiskEntry; 01761 PPARTENTRY PartEntry; 01762 PLIST_ENTRY Entry1; 01763 PLIST_ENTRY Entry2; 01764 UCHAR i; 01765 01766 /* Check for empty disks */ 01767 if (IsListEmpty (&List->DiskListHead)) 01768 return; 01769 01770 /* check for previous usable entry on current disk */ 01771 if (List->CurrentPartition != NULL) 01772 { 01773 Entry2 = &List->CurrentPartition->ListEntry; 01774 PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); 01775 01776 /* Check if we can move inside primary partitions */ 01777 if (List->CurrentPartitionNumber > 0) 01778 { 01779 /* Find a previous partition */ 01780 for (i = List->CurrentPartitionNumber - 1; i > 0; i--) 01781 { 01782 if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) 01783 break; 01784 } 01785 01786 /* Move to it and return */ 01787 List->CurrentPartitionNumber = i; 01788 DrawPartitionList (List); 01789 return; 01790 } 01791 01792 /* Move to the previous entry */ 01793 Entry2 = Entry2->Blink; 01794 01795 while (Entry2 != &List->CurrentDisk->PartListHead) 01796 { 01797 PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); 01798 01799 // if (PartEntry->HidePartEntry == FALSE) 01800 { 01801 List->CurrentPartition = PartEntry; 01802 01803 /* Find last existing partition in the table */ 01804 for (i = 3; i > 0; i--) 01805 { 01806 if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) 01807 break; 01808 } 01809 01810 /* Move to it */ 01811 List->CurrentPartitionNumber = i; 01812 01813 /* Draw partition list and return */ 01814 DrawPartitionList (List); 01815 return; 01816 } 01817 Entry2 = Entry2->Blink; 01818 } 01819 } 01820 01821 01822 /* check for last usable entry on previous disk */ 01823 if (List->CurrentDisk != NULL) 01824 { 01825 Entry1 = List->CurrentDisk->ListEntry.Blink; 01826 while (Entry1 != &List->DiskListHead) 01827 { 01828 DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); 01829 01830 Entry2 = DiskEntry->PartListHead.Blink; 01831 while (Entry2 != &DiskEntry->PartListHead) 01832 { 01833 PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); 01834 01835 // if (PartEntry->HidePartEntry == FALSE) 01836 { 01837 List->CurrentDisk = DiskEntry; 01838 List->CurrentPartition = PartEntry; 01839 01840 /* Find last existing partition in the table */ 01841 for (i = 3; i > 0; i--) 01842 { 01843 if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) 01844 break; 01845 } 01846 01847 /* Move to it */ 01848 List->CurrentPartitionNumber = i; 01849 01850 /* Draw partition list and return */ 01851 DrawPartitionList (List); 01852 return; 01853 } 01854 01855 Entry2 = Entry2->Blink; 01856 } 01857 01858 Entry1 = Entry1->Blink; 01859 } 01860 } 01861 } 01862 01863 01864 static PPARTENTRY 01865 GetPrevPartitionedEntry (PDISKENTRY DiskEntry, 01866 PPARTENTRY CurrentEntry) 01867 { 01868 PPARTENTRY PrevEntry; 01869 PLIST_ENTRY Entry; 01870 01871 if (CurrentEntry->ListEntry.Blink == &DiskEntry->PartListHead) 01872 return NULL; 01873 01874 Entry = CurrentEntry->ListEntry.Blink; 01875 while (Entry != &DiskEntry->PartListHead) 01876 { 01877 PrevEntry = CONTAINING_RECORD (Entry, 01878 PARTENTRY, 01879 ListEntry); 01880 if (PrevEntry->Unpartitioned == FALSE) 01881 return PrevEntry; 01882 01883 Entry = Entry->Blink; 01884 } 01885 01886 return NULL; 01887 } 01888 01889 01890 static PPARTENTRY 01891 GetNextPartitionedEntry (PDISKENTRY DiskEntry, 01892 PPARTENTRY CurrentEntry) 01893 { 01894 PPARTENTRY NextEntry; 01895 PLIST_ENTRY Entry; 01896 01897 if (CurrentEntry->ListEntry.Flink == &DiskEntry->PartListHead) 01898 return NULL; 01899 01900 Entry = CurrentEntry->ListEntry.Flink; 01901 while (Entry != &DiskEntry->PartListHead) 01902 { 01903 NextEntry = CONTAINING_RECORD (Entry, 01904 PARTENTRY, 01905 ListEntry); 01906 if (NextEntry->Unpartitioned == FALSE) 01907 return NextEntry; 01908 01909 Entry = Entry->Flink; 01910 } 01911 01912 return NULL; 01913 } 01914 01915 01916 static PPARTENTRY 01917 GetPrevUnpartitionedEntry (PDISKENTRY DiskEntry, 01918 PPARTENTRY PartEntry) 01919 { 01920 PPARTENTRY PrevPartEntry; 01921 01922 if (PartEntry->ListEntry.Blink != &DiskEntry->PartListHead) 01923 { 01924 PrevPartEntry = CONTAINING_RECORD (PartEntry->ListEntry.Blink, 01925 PARTENTRY, 01926 ListEntry); 01927 if (PrevPartEntry->Unpartitioned == TRUE) 01928 return PrevPartEntry; 01929 } 01930 01931 return NULL; 01932 } 01933 01934 01935 static PPARTENTRY 01936 GetNextUnpartitionedEntry (PDISKENTRY DiskEntry, 01937 PPARTENTRY PartEntry) 01938 { 01939 PPARTENTRY NextPartEntry; 01940 01941 if (PartEntry->ListEntry.Flink != &DiskEntry->PartListHead) 01942 { 01943 NextPartEntry = CONTAINING_RECORD (PartEntry->ListEntry.Flink, 01944 PARTENTRY, 01945 ListEntry); 01946 if (NextPartEntry->Unpartitioned == TRUE) 01947 return NextPartEntry; 01948 } 01949 01950 return NULL; 01951 } 01952 01953 01954 VOID 01955 CreateNewPartition (PPARTLIST List, 01956 ULONGLONG PartitionSize, 01957 BOOLEAN AutoCreate) 01958 { 01959 PDISKENTRY DiskEntry; 01960 PPARTENTRY PartEntry; 01961 PPARTENTRY PrevPartEntry; 01962 PPARTENTRY NextPartEntry; 01963 PPARTENTRY NewPartEntry; 01964 01965 if (List == NULL || 01966 List->CurrentDisk == NULL || 01967 List->CurrentPartition == NULL || 01968 List->CurrentPartition->Unpartitioned == FALSE) 01969 { 01970 return; 01971 } 01972 01973 DiskEntry = List->CurrentDisk; 01974 PartEntry = List->CurrentPartition; 01975 01976 if (AutoCreate == TRUE || 01977 PartitionSize == PartEntry->UnpartitionedLength) 01978 { 01979 /* Convert current entry to 'new (unformatted)' */ 01980 PartEntry->FormatState = Unformatted; 01981 PartEntry->PartInfo[0].StartingOffset.QuadPart = 01982 PartEntry->UnpartitionedOffset + DiskEntry->TrackSize; 01983 PartEntry->PartInfo[0].HiddenSectors = 01984 (ULONG)(PartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector); 01985 PartEntry->PartInfo[0].PartitionLength.QuadPart = 01986 PartEntry->UnpartitionedLength - DiskEntry->TrackSize; 01987 PartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED; 01988 PartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */ 01989 PartEntry->PartInfo[0].RewritePartition = TRUE; 01990 PartEntry->PartInfo[1].RewritePartition = TRUE; 01991 PartEntry->PartInfo[2].RewritePartition = TRUE; 01992 PartEntry->PartInfo[3].RewritePartition = TRUE; 01993 01994 /* Get previous and next partition entries */ 01995 PrevPartEntry = GetPrevPartitionedEntry (DiskEntry, 01996 PartEntry); 01997 NextPartEntry = GetNextPartitionedEntry (DiskEntry, 01998 PartEntry); 01999 02000 if (PrevPartEntry != NULL && NextPartEntry != NULL) 02001 { 02002 /* Current entry is in the middle of the list */ 02003 02004 /* Copy previous container partition data to current entry */ 02005 RtlCopyMemory (&PartEntry->PartInfo[1], 02006 &PrevPartEntry->PartInfo[1], 02007 sizeof(PARTITION_INFORMATION)); 02008 PartEntry->PartInfo[1].RewritePartition = TRUE; 02009 02010 /* Update previous container partition data */ 02011 02012 PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = 02013 PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; 02014 PrevPartEntry->PartInfo[1].HiddenSectors = 02015 (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); 02016 02017 if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) 02018 { 02019 /* Special case - previous partition is first partition */ 02020 PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = 02021 DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; 02022 } 02023 else 02024 { 02025 PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = 02026 PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; 02027 } 02028 02029 PrevPartEntry->PartInfo[1].RewritePartition = TRUE; 02030 } 02031 else if (PrevPartEntry == NULL && NextPartEntry != NULL) 02032 { 02033 /* Current entry is the first entry */ 02034 return; 02035 } 02036 else if (PrevPartEntry != NULL && NextPartEntry == NULL) 02037 { 02038 /* Current entry is the last entry */ 02039 02040 PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = 02041 PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; 02042 PrevPartEntry->PartInfo[1].HiddenSectors = 02043 (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); 02044 02045 if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) 02046 { 02047 /* Special case - previous partition is first partition */ 02048 PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = 02049 DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; 02050 } 02051 else 02052 { 02053 PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = 02054 PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; 02055 } 02056 02057 if ((PartEntry->PartInfo[1].StartingOffset.QuadPart + 02058 PartEntry->PartInfo[1].PartitionLength.QuadPart) < 02059 (1024LL * 255LL * 63LL * 512LL)) 02060 { 02061 PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED; 02062 } 02063 else 02064 { 02065 PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED; 02066 } 02067 02068 PrevPartEntry->PartInfo[1].BootIndicator = FALSE; 02069 PrevPartEntry->PartInfo[1].RewritePartition = TRUE; 02070 } 02071 02072 PartEntry->AutoCreate = AutoCreate; 02073 PartEntry->New = TRUE; 02074 PartEntry->Unpartitioned = FALSE; 02075 PartEntry->UnpartitionedOffset = 0ULL; 02076 PartEntry->UnpartitionedLength = 0ULL; 02077 } 02078 else 02079 { 02080 /* Insert an initialize a new partition entry */ 02081 NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, 02082 0, 02083 sizeof(PARTENTRY)); 02084 if (NewPartEntry == NULL) 02085 return; 02086 02087 RtlZeroMemory (NewPartEntry, 02088 sizeof(PARTENTRY)); 02089 02090 /* Insert the new entry into the list */ 02091 InsertTailList (&PartEntry->ListEntry, 02092 &NewPartEntry->ListEntry); 02093 02094 NewPartEntry->New = TRUE; 02095 02096 NewPartEntry->FormatState = Unformatted; 02097 NewPartEntry->PartInfo[0].StartingOffset.QuadPart = 02098 PartEntry->UnpartitionedOffset + DiskEntry->TrackSize; 02099 NewPartEntry->PartInfo[0].HiddenSectors = 02100 (ULONG)(NewPartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector); 02101 NewPartEntry->PartInfo[0].PartitionLength.QuadPart = 02102 PartitionSize - DiskEntry->TrackSize; 02103 NewPartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED; 02104 NewPartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */ 02105 NewPartEntry->PartInfo[0].RewritePartition = TRUE; 02106 NewPartEntry->PartInfo[1].RewritePartition = TRUE; 02107 NewPartEntry->PartInfo[2].RewritePartition = TRUE; 02108 NewPartEntry->PartInfo[3].RewritePartition = TRUE; 02109 02110 /* Get previous and next partition entries */ 02111 PrevPartEntry = GetPrevPartitionedEntry (DiskEntry, 02112 NewPartEntry); 02113 NextPartEntry = GetNextPartitionedEntry (DiskEntry, 02114 NewPartEntry); 02115 02116 if (PrevPartEntry != NULL && NextPartEntry != NULL) 02117 { 02118 /* Current entry is in the middle of the list */ 02119 02120 /* Copy previous container partition data to current entry */ 02121 RtlCopyMemory (&NewPartEntry->PartInfo[1], 02122 &PrevPartEntry->PartInfo[1], 02123 sizeof(PARTITION_INFORMATION)); 02124 NewPartEntry->PartInfo[1].RewritePartition = TRUE; 02125 02126 /* Update previous container partition data */ 02127 02128 PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = 02129 NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; 02130 PrevPartEntry->PartInfo[1].HiddenSectors = 02131 (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); 02132 02133 if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) 02134 { 02135 /* Special case - previous partition is first partition */ 02136 PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = 02137 DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; 02138 } 02139 else 02140 { 02141 PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = 02142 NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; 02143 } 02144 02145 PrevPartEntry->PartInfo[1].RewritePartition = TRUE; 02146 } 02147 else if (PrevPartEntry == NULL && NextPartEntry != NULL) 02148 { 02149 /* Current entry is the first entry */ 02150 return; 02151 } 02152 else if (PrevPartEntry != NULL && NextPartEntry == NULL) 02153 { 02154 /* Current entry is the last entry */ 02155 02156 PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = 02157 NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; 02158 PrevPartEntry->PartInfo[1].HiddenSectors = 02159 (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); 02160 02161 if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) 02162 { 02163 /* Special case - previous partition is first partition */ 02164 PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = 02165 DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; 02166 } 02167 else 02168 { 02169 PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = 02170 NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; 02171 } 02172 02173 if ((PartEntry->PartInfo[1].StartingOffset.QuadPart + 02174 PartEntry->PartInfo[1].PartitionLength.QuadPart) < 02175 (1024LL * 255LL * 63LL * 512LL)) 02176 { 02177 PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED; 02178 } 02179 else 02180 { 02181 PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED; 02182 } 02183 02184 PrevPartEntry->PartInfo[1].BootIndicator = FALSE; 02185 PrevPartEntry->PartInfo[1].RewritePartition = TRUE; 02186 } 02187 02188 /* Update offset and size of the remaining unpartitioned disk space */ 02189 PartEntry->UnpartitionedOffset += PartitionSize; 02190 PartEntry->UnpartitionedLength -= PartitionSize; 02191 } 02192 02193 DiskEntry->Modified = TRUE; 02194 02195 UpdatePartitionNumbers (DiskEntry); 02196 02197 AssignDriverLetters (List); 02198 } 02199 02200 02201 VOID 02202 DeleteCurrentPartition (PPARTLIST List) 02203 { 02204 PDISKENTRY DiskEntry; 02205 PPARTENTRY PartEntry; 02206 PPARTENTRY PrevPartEntry; 02207 PPARTENTRY NextPartEntry; 02208 02209 if (List == NULL || 02210 List->CurrentDisk == NULL || 02211 List->CurrentPartition == NULL || 02212 List->CurrentPartition->Unpartitioned == TRUE) 02213 { 02214 return; 02215 } 02216 02217 DiskEntry = List->CurrentDisk; 02218 PartEntry = List->CurrentPartition; 02219 02220 /* Adjust container partition entries */ 02221 02222 /* Get previous and next partition entries */ 02223 PrevPartEntry = GetPrevPartitionedEntry (DiskEntry, 02224 PartEntry); 02225 NextPartEntry = GetNextPartitionedEntry (DiskEntry, 02226 PartEntry); 02227 02228 if (PrevPartEntry != NULL && NextPartEntry != NULL) 02229 { 02230 /* Current entry is in the middle of the list */ 02231 02232 /* 02233 * The first extended partition can not be deleted 02234 * as long as other extended partitions are present. 02235 */ 02236 if (PrevPartEntry->ListEntry.Blink == &DiskEntry->PartListHead) 02237 return; 02238 02239 /* Copy previous container partition data to current entry */ 02240 RtlCopyMemory (&PrevPartEntry->PartInfo[1], 02241 &PartEntry->PartInfo[1], 02242 sizeof(PARTITION_INFORMATION)); 02243 PrevPartEntry->PartInfo[1].RewritePartition = TRUE; 02244 } 02245 else if (PrevPartEntry == NULL && NextPartEntry != NULL) 02246 { 02247 /* 02248 * A primary partition can not be deleted as long as 02249 * extended partitions are present. 02250 */ 02251 return; 02252 } 02253 else if (PrevPartEntry != NULL && NextPartEntry == NULL) 02254 { 02255 /* Current entry is the last entry */ 02256 RtlZeroMemory (&PrevPartEntry->PartInfo[1], 02257 sizeof(PARTITION_INFORMATION)); 02258 PrevPartEntry->PartInfo[1].RewritePartition = TRUE; 02259 } 02260 02261 02262 /* Adjust unpartitioned disk space entries */ 02263 02264 /* Get pointer to previous and next unpartitioned entries */ 02265 PrevPartEntry = GetPrevUnpartitionedEntry (DiskEntry, 02266 PartEntry); 02267 02268 NextPartEntry = GetNextUnpartitionedEntry (DiskEntry, 02269 PartEntry); 02270 02271 if (PrevPartEntry != NULL && NextPartEntry != NULL) 02272 { 02273 /* Merge previous, current and next unpartitioned entry */ 02274 02275 /* Adjust the previous entries length */ 02276 PrevPartEntry->UnpartitionedLength += 02277 (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize + 02278 NextPartEntry->UnpartitionedLength); 02279 02280 /* Remove the current entry */ 02281 RemoveEntryList (&PartEntry->ListEntry); 02282 RtlFreeHeap (ProcessHeap, 02283 0, 02284 PartEntry); 02285 02286 /* Remove the next entry */ 02287 RemoveEntryList (&NextPartEntry->ListEntry); 02288 RtlFreeHeap (ProcessHeap, 02289 0, 02290 NextPartEntry); 02291 02292 /* Update current partition */ 02293 List->CurrentPartition = PrevPartEntry; 02294 } 02295 else if (PrevPartEntry != NULL && NextPartEntry == NULL) 02296 { 02297 /* Merge current and previous unpartitioned entry */ 02298 02299 /* Adjust the previous entries length */ 02300 PrevPartEntry->UnpartitionedLength += 02301 (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize); 02302 02303 /* Remove the current entry */ 02304 RemoveEntryList (&PartEntry->ListEntry); 02305 RtlFreeHeap (ProcessHeap, 02306 0, 02307 PartEntry); 02308 02309 /* Update current partition */ 02310 List->CurrentPartition = PrevPartEntry; 02311 } 02312 else if (PrevPartEntry == NULL && NextPartEntry != NULL) 02313 { 02314 /* Merge current and next unpartitioned entry */ 02315 02316 /* Adjust the next entries offset and length */ 02317 NextPartEntry->UnpartitionedOffset = 02318 PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; 02319 NextPartEntry->UnpartitionedLength += 02320 (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize); 02321 02322 /* Remove the current entry */ 02323 RemoveEntryList (&PartEntry->ListEntry); 02324 RtlFreeHeap (ProcessHeap, 02325 0, 02326 PartEntry); 02327 02328 /* Update current partition */ 02329 List->CurrentPartition = NextPartEntry; 02330 } 02331 else 02332 { 02333 /* Nothing to merge but change current entry */ 02334 PartEntry->New = FALSE; 02335 PartEntry->Unpartitioned = TRUE; 02336 PartEntry->UnpartitionedOffset = 02337 PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; 02338 PartEntry->UnpartitionedLength = 02339 PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; 02340 02341 /* Wipe the partition table */ 02342 RtlZeroMemory (&PartEntry->PartInfo, 02343 sizeof(PartEntry->PartInfo)); 02344 } 02345 02346 DiskEntry->Modified = TRUE; 02347 02348 UpdatePartitionNumbers (DiskEntry); 02349 02350 AssignDriverLetters (List); 02351 } 02352 02353 02354 VOID 02355 CheckActiveBootPartition (PPARTLIST List) 02356 { 02357 PDISKENTRY DiskEntry; 02358 PPARTENTRY PartEntry; 02359 PLIST_ENTRY ListEntry; 02360 UCHAR i; 02361 02362 /* Check for empty disk list */ 02363 if (IsListEmpty (&List->DiskListHead)) 02364 { 02365 List->ActiveBootDisk = NULL; 02366 List->ActiveBootPartition = NULL; 02367 List->ActiveBootPartitionNumber = 0; 02368 return; 02369 } 02370 02371 #if 0 02372 if (List->ActiveBootDisk != NULL && 02373 List->ActiveBootPartition != NULL) 02374 { 02375 /* We already have an active boot partition */ 02376 return; 02377 } 02378 #endif 02379 02380 /* Choose the currently selected disk */ 02381 DiskEntry = List->CurrentDisk; 02382 02383 /* Check for empty partition list */ 02384 if (IsListEmpty (&DiskEntry->PartListHead)) 02385 { 02386 List->ActiveBootDisk = NULL; 02387 List->ActiveBootPartition = NULL; 02388 List->ActiveBootPartitionNumber = 0; 02389 return; 02390 } 02391 02392 PartEntry = CONTAINING_RECORD (DiskEntry->PartListHead.Flink, 02393 PARTENTRY, 02394 ListEntry); 02395 02396 /* Set active boot partition */ 02397 if ((DiskEntry->NewDisk == TRUE) || 02398 (PartEntry->PartInfo[0].BootIndicator == FALSE && 02399 PartEntry->PartInfo[1].BootIndicator == FALSE && 02400 PartEntry->PartInfo[2].BootIndicator == FALSE && 02401 PartEntry->PartInfo[3].BootIndicator == FALSE)) 02402 { 02403 PartEntry->PartInfo[0].BootIndicator = TRUE; 02404 PartEntry->PartInfo[0].RewritePartition = TRUE; 02405 DiskEntry->Modified = TRUE; 02406 02407 /* FIXME: Might be incorrect if partitions were created by Linux FDISK */ 02408 List->ActiveBootDisk = DiskEntry; 02409 List->ActiveBootPartition = PartEntry; 02410 List->ActiveBootPartitionNumber = 0; 02411 02412 return; 02413 } 02414 02415 /* Disk is not new, scan all partitions to find a bootable one */ 02416 List->ActiveBootDisk = NULL; 02417 List->ActiveBootPartition = NULL; 02418 List->ActiveBootPartitionNumber = 0; 02419 02420 ListEntry = DiskEntry->PartListHead.Flink; 02421 while (ListEntry != &DiskEntry->PartListHead) 02422 { 02423 PartEntry = CONTAINING_RECORD(ListEntry, 02424 PARTENTRY, 02425 ListEntry); 02426 02427 /* Check if it's partitioned */ 02428 if (!PartEntry->Unpartitioned) 02429 { 02430 /* Go through all of its 4 partitions */ 02431 for (i=0; i<4; i++) 02432 { 02433 if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED && 02434 PartEntry->PartInfo[i].BootIndicator) 02435 { 02436 /* Yes, we found it */ 02437 List->ActiveBootDisk = DiskEntry; 02438 List->ActiveBootPartition = PartEntry; 02439 List->ActiveBootPartitionNumber = i; 02440 02441 DPRINT("Found bootable partition disk %d, drive letter %c\n", 02442 DiskEntry->DiskNumber, PartEntry->DriveLetter[i]); 02443 02444 break; 02445 } 02446 } 02447 } 02448 /* Go to the next one */ 02449 ListEntry = ListEntry->Flink; 02450 } 02451 } 02452 02453 02454 BOOLEAN 02455 CheckForLinuxFdiskPartitions (PPARTLIST List) 02456 { 02457 PDISKENTRY DiskEntry; 02458 PPARTENTRY PartEntry; 02459 PLIST_ENTRY Entry1; 02460 PLIST_ENTRY Entry2; 02461 ULONG PartitionCount; 02462 ULONG i; 02463 02464 Entry1 = List->DiskListHead.Flink; 02465 while (Entry1 != &List->DiskListHead) 02466 { 02467 DiskEntry = CONTAINING_RECORD (Entry1, 02468 DISKENTRY, 02469 ListEntry); 02470 02471 Entry2 = DiskEntry->PartListHead.Flink; 02472 while (Entry2 != &DiskEntry->PartListHead) 02473 { 02474 PartEntry = CONTAINING_RECORD (Entry2, 02475 PARTENTRY, 02476 ListEntry); 02477 02478 if (PartEntry->Unpartitioned == FALSE) 02479 { 02480 PartitionCount = 0; 02481 02482 for (i = 0; i < 4; i++) 02483 { 02484 if (!IsContainerPartition (PartEntry->PartInfo[i].PartitionType) && 02485 PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL) 02486 { 02487 PartitionCount++; 02488 } 02489 } 02490 02491 if (PartitionCount > 1) 02492 { 02493 return TRUE; 02494 } 02495 } 02496 02497 Entry2 = Entry2->Flink; 02498 } 02499 02500 Entry1 = Entry1->Flink; 02501 } 02502 02503 return FALSE; 02504 } 02505 02506 02507 BOOLEAN 02508 WritePartitionsToDisk (PPARTLIST List) 02509 { 02510 PDRIVE_LAYOUT_INFORMATION DriveLayout; 02511 OBJECT_ATTRIBUTES ObjectAttributes; 02512 IO_STATUS_BLOCK Iosb; 02513 WCHAR DstPath[MAX_PATH]; 02514 UNICODE_STRING Name; 02515 HANDLE FileHandle; 02516 PDISKENTRY DiskEntry1; 02517 PDISKENTRY DiskEntry2; 02518 PPARTENTRY PartEntry; 02519 PLIST_ENTRY Entry1; 02520 PLIST_ENTRY Entry2; 02521 ULONG PartitionCount; 02522 ULONG DriveLayoutSize; 02523 ULONG Index; 02524 NTSTATUS Status; 02525 02526 if (List == NULL) 02527 { 02528 return TRUE; 02529 } 02530 02531 Entry1 = List->DiskListHead.Flink; 02532 while (Entry1 != &List->DiskListHead) 02533 { 02534 DiskEntry1 = CONTAINING_RECORD (Entry1, 02535 DISKENTRY, 02536 ListEntry); 02537 02538 if (DiskEntry1->Modified == TRUE) 02539 { 02540 /* Count partitioned entries */ 02541 PartitionCount = 0; 02542 Entry2 = DiskEntry1->PartListHead.Flink; 02543 while (Entry2 != &DiskEntry1->PartListHead) 02544 { 02545 PartEntry = CONTAINING_RECORD (Entry2, 02546 PARTENTRY, 02547 ListEntry); 02548 if (PartEntry->Unpartitioned == FALSE) 02549 { 02550 PartitionCount += 4; 02551 } 02552 02553 Entry2 = Entry2->Flink; 02554 } 02555 if (PartitionCount == 0) 02556 { 02557 DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + 02558 ((4 - 1) * sizeof (PARTITION_INFORMATION)); 02559 } 02560 else 02561 { 02562 DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + 02563 ((PartitionCount - 1) * sizeof (PARTITION_INFORMATION)); 02564 } 02565 DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap (ProcessHeap, 02566 0, 02567 DriveLayoutSize); 02568 if (DriveLayout == NULL) 02569 { 02570 DPRINT1 ("RtlAllocateHeap() failed\n"); 02571 return FALSE; 02572 } 02573 02574 RtlZeroMemory (DriveLayout, 02575 DriveLayoutSize); 02576 02577 if (PartitionCount == 0) 02578 { 02579 /* delete all partitions in the mbr */ 02580 DriveLayout->PartitionCount = 4; 02581 for (Index = 0; Index < 4; Index++) 02582 { 02583 DriveLayout->PartitionEntry[Index].RewritePartition = TRUE; 02584 } 02585 } 02586 else 02587 { 02588 DriveLayout->PartitionCount = PartitionCount; 02589 02590 Index = 0; 02591 Entry2 = DiskEntry1->PartListHead.Flink; 02592 while (Entry2 != &DiskEntry1->PartListHead) 02593 { 02594 PartEntry = CONTAINING_RECORD (Entry2, 02595 PARTENTRY, 02596 ListEntry); 02597 if (PartEntry->Unpartitioned == FALSE) 02598 { 02599 RtlCopyMemory (&DriveLayout->PartitionEntry[Index], 02600 &PartEntry->PartInfo[0], 02601 4 * sizeof (PARTITION_INFORMATION)); 02602 Index += 4; 02603 } 02604 02605 Entry2 = Entry2->Flink; 02606 } 02607 } 02608 if (DiskEntry1->Signature == 0) 02609 { 02610 LARGE_INTEGER SystemTime; 02611 TIME_FIELDS TimeFields; 02612 PUCHAR Buffer; 02613 Buffer = (PUCHAR)&DiskEntry1->Signature; 02614 02615 while (1) 02616 { 02617 NtQuerySystemTime (&SystemTime); 02618 RtlTimeToTimeFields (&SystemTime, &TimeFields); 02619 02620 Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF); 02621 Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF); 02622 Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF); 02623 Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF); 02624 02625 if (DiskEntry1->Signature == 0) 02626 { 02627 continue; 02628 } 02629 02630 /* check if the signature already exist */ 02631 /* FIXME: 02632 * Check also signatures from disks, which are 02633 * not visible (bootable) by the bios. 02634 */ 02635 Entry2 = List->DiskListHead.Flink; 02636 while (Entry2 != &List->DiskListHead) 02637 { 02638 DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry); 02639 if (DiskEntry1 != DiskEntry2 && 02640 DiskEntry1->Signature == DiskEntry2->Signature) 02641 { 02642 break; 02643 } 02644 Entry2 = Entry2->Flink; 02645 } 02646 if (Entry2 == &List->DiskListHead) 02647 { 02648 break; 02649 } 02650 } 02651 02652 /* set one partition entry to dirty, this will update the signature */ 02653 DriveLayout->PartitionEntry[0].RewritePartition = TRUE; 02654 02655 } 02656 02657 DriveLayout->Signature = DiskEntry1->Signature; 02658 02659 02660 swprintf (DstPath, 02661 L"\\Device\\Harddisk%d\\Partition0", 02662 DiskEntry1->DiskNumber); 02663 RtlInitUnicodeString (&Name, 02664 DstPath); 02665 InitializeObjectAttributes (&ObjectAttributes, 02666 &Name, 02667 0, 02668 NULL, 02669 NULL); 02670 02671 Status = NtOpenFile (&FileHandle, 02672 FILE_ALL_ACCESS, 02673 &ObjectAttributes, 02674 &Iosb, 02675 0, 02676 FILE_SYNCHRONOUS_IO_NONALERT); 02677 02678 if (!NT_SUCCESS (Status)) 02679 { 02680 DPRINT1 ("NtOpenFile() failed (Status %lx)\n", Status); 02681 return FALSE; 02682 } 02683 02684 Status = NtDeviceIoControlFile (FileHandle, 02685 NULL, 02686 NULL, 02687 NULL, 02688 &Iosb, 02689 IOCTL_DISK_SET_DRIVE_LAYOUT, 02690 DriveLayout, 02691 DriveLayoutSize, 02692 NULL, 02693 0); 02694 if (!NT_SUCCESS (Status)) 02695 { 02696 DPRINT1 ("NtDeviceIoControlFile() failed (Status %lx)\n", Status); 02697 NtClose (FileHandle); 02698 return FALSE; 02699 } 02700 02701 RtlFreeHeap (ProcessHeap, 02702 0, 02703 DriveLayout); 02704 02705 NtClose (FileHandle); 02706 } 02707 02708 Entry1 = Entry1->Flink; 02709 } 02710 02711 return TRUE; 02712 } 02713 02714 BOOL SetMountedDeviceValues(PPARTLIST List) 02715 { 02716 PLIST_ENTRY Entry1, Entry2; 02717 PDISKENTRY DiskEntry; 02718 PPARTENTRY PartEntry; 02719 UCHAR i; 02720 02721 if (List == NULL) 02722 { 02723 return FALSE; 02724 } 02725 02726 Entry1 = List->DiskListHead.Flink; 02727 while (Entry1 != &List->DiskListHead) 02728 { 02729 DiskEntry = CONTAINING_RECORD (Entry1, 02730 DISKENTRY, 02731 ListEntry); 02732 02733 Entry2 = DiskEntry->PartListHead.Flink; 02734 while (Entry2 != &DiskEntry->PartListHead) 02735 { 02736 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); 02737 if (!PartEntry->Unpartitioned) 02738 { 02739 for (i=0; i<4; i++) 02740 { 02741 if (PartEntry->DriveLetter[i]) 02742 { 02743 if (!SetMountedDeviceValue(PartEntry->DriveLetter[i], DiskEntry->Signature, PartEntry->PartInfo[i].StartingOffset)) 02744 { 02745 return FALSE; 02746 } 02747 } 02748 } 02749 } 02750 Entry2 = Entry2->Flink; 02751 } 02752 Entry1 = Entry1->Flink; 02753 } 02754 return TRUE; 02755 } 02756 02757 02758 02759 /* EOF */ Generated on Fri May 25 2012 04:16:26 for ReactOS by
1.7.6.1
|