1 /* 2 * PROJECT: ReactOS DiskPart 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/system/diskpart/detail.c 5 * PURPOSE: Manages all the partitions of the OS in an interactive way. 6 * PROGRAMMERS: Lee Schroeder 7 */ 8 9 #include "diskpart.h" 10 11 #define NDEBUG 12 #include <debug.h> 13 14 /* FUNCTIONS ******************************************************************/ 15 16 static 17 BOOL 18 IsDiskInVolume( 19 _In_ PVOLENTRY VolumeEntry, 20 _In_ PDISKENTRY DiskEntry) 21 { 22 ULONG i; 23 24 if ((VolumeEntry == NULL) || 25 (VolumeEntry->pExtents == NULL) || 26 (DiskEntry == NULL)) 27 return FALSE; 28 29 for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++) 30 { 31 if (VolumeEntry->pExtents->Extents[i].DiskNumber == DiskEntry->DiskNumber) 32 return TRUE; 33 } 34 35 return FALSE; 36 } 37 38 39 static 40 BOOL 41 IsPartitionInVolume( 42 _In_ PVOLENTRY VolumeEntry, 43 _In_ PPARTENTRY PartEntry) 44 { 45 ULONG i; 46 47 if ((VolumeEntry == NULL) || 48 (VolumeEntry->pExtents == NULL) || 49 (PartEntry == NULL) || 50 (PartEntry->DiskEntry == NULL)) 51 return FALSE; 52 53 for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++) 54 { 55 if (VolumeEntry->pExtents->Extents[i].DiskNumber == PartEntry->DiskEntry->DiskNumber) 56 { 57 if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) && 58 (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector)) 59 return TRUE; 60 } 61 } 62 63 return FALSE; 64 } 65 66 67 BOOL 68 DetailDisk( 69 _In_ INT argc, 70 _In_ PWSTR *argv) 71 { 72 PLIST_ENTRY Entry; 73 PVOLENTRY VolumeEntry; 74 BOOL bPrintHeader = TRUE; 75 76 DPRINT("DetailDisk()\n"); 77 78 if (argc > 2) 79 { 80 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); 81 return TRUE; 82 } 83 84 if (CurrentDisk == NULL) 85 { 86 ConResPuts(StdOut, IDS_SELECT_NO_DISK); 87 return TRUE; 88 } 89 90 /* TODO: Print more disk details */ 91 ConPuts(StdOut, L"\n"); 92 ConResPrintf(StdOut, IDS_DETAIL_INFO_DISK_ID, CurrentDisk->LayoutBuffer->Signature); 93 ConResPrintf(StdOut, IDS_DETAIL_INFO_PATH, CurrentDisk->PathId); 94 ConResPrintf(StdOut, IDS_DETAIL_INFO_TARGET, CurrentDisk->TargetId); 95 ConResPrintf(StdOut, IDS_DETAIL_INFO_LUN_ID, CurrentDisk->Lun); 96 97 Entry = VolumeListHead.Flink; 98 while (Entry != &VolumeListHead) 99 { 100 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry); 101 102 if (IsDiskInVolume(VolumeEntry, CurrentDisk)) 103 { 104 if (bPrintHeader) 105 { 106 ConPuts(StdOut, L"\n"); 107 ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD); 108 ConResPuts(StdOut, IDS_LIST_VOLUME_LINE); 109 bPrintHeader = FALSE; 110 } 111 112 PrintVolume(VolumeEntry); 113 } 114 115 Entry = Entry->Flink; 116 } 117 118 ConPuts(StdOut, L"\n"); 119 120 return TRUE; 121 } 122 123 124 BOOL 125 DetailPartition( 126 _In_ INT argc, 127 _In_ PWSTR *argv) 128 { 129 PPARTENTRY PartEntry; 130 ULONGLONG PartOffset; 131 PLIST_ENTRY Entry; 132 PVOLENTRY VolumeEntry; 133 BOOL bVolumeFound = FALSE, bPrintHeader = TRUE; 134 135 DPRINT("DetailPartition()\n"); 136 137 if (argc > 2) 138 { 139 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); 140 return TRUE; 141 } 142 143 if (CurrentDisk == NULL) 144 { 145 ConResPuts(StdOut, IDS_SELECT_PARTITION_NO_DISK); 146 return TRUE; 147 } 148 149 if (CurrentPartition == NULL) 150 { 151 ConResPuts(StdOut, IDS_SELECT_NO_PARTITION); 152 return TRUE; 153 } 154 155 PartEntry = CurrentPartition; 156 PartOffset = PartEntry->StartSector.QuadPart * CurrentDisk->BytesPerSector; 157 158 /* TODO: Print more partition details */ 159 ConPuts(StdOut, L"\n"); 160 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_NUMBER, PartEntry->PartitionNumber); 161 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_TYPE, PartEntry->PartitionType); 162 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_HIDDEN, ""); 163 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_ACTIVE, PartEntry->BootIndicator ? L"Yes" : L"No"); 164 ConResPrintf(StdOut, IDS_DETAIL_PARTITION_OFFSET, PartOffset); 165 166 Entry = VolumeListHead.Flink; 167 while (Entry != &VolumeListHead) 168 { 169 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry); 170 171 if (IsPartitionInVolume(VolumeEntry, CurrentPartition)) 172 { 173 if (bPrintHeader) 174 { 175 ConPuts(StdOut, L"\n"); 176 ConResPuts(StdOut, IDS_LIST_VOLUME_HEAD); 177 ConResPuts(StdOut, IDS_LIST_VOLUME_LINE); 178 bPrintHeader = FALSE; 179 } 180 181 PrintVolume(VolumeEntry); 182 bVolumeFound = TRUE; 183 } 184 185 Entry = Entry->Flink; 186 } 187 188 if (bVolumeFound == FALSE) 189 ConResPuts(StdOut, IDS_DETAIL_NO_VOLUME); 190 191 ConPuts(StdOut, L"\n"); 192 193 return TRUE; 194 } 195 196 197 BOOL 198 DetailVolume( 199 _In_ INT argc, 200 _In_ PWSTR *argv) 201 { 202 PDISKENTRY DiskEntry; 203 PLIST_ENTRY Entry; 204 BOOL bDiskFound = FALSE, bPrintHeader = TRUE; 205 206 DPRINT("DetailVolume()\n"); 207 208 if (argc > 2) 209 { 210 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); 211 return TRUE; 212 } 213 214 if (CurrentVolume == NULL) 215 { 216 ConResPuts(StdOut, IDS_SELECT_NO_VOLUME); 217 return TRUE; 218 } 219 220 221 Entry = DiskListHead.Flink; 222 while (Entry != &DiskListHead) 223 { 224 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); 225 226 if (IsDiskInVolume(CurrentVolume, DiskEntry)) 227 { 228 if (bPrintHeader) 229 { 230 ConPuts(StdOut, L"\n"); 231 ConResPuts(StdOut, IDS_LIST_DISK_HEAD); 232 ConResPuts(StdOut, IDS_LIST_DISK_LINE); 233 bPrintHeader = FALSE; 234 } 235 236 PrintDisk(DiskEntry); 237 bDiskFound = TRUE; 238 } 239 240 Entry = Entry->Flink; 241 } 242 243 if (bDiskFound == FALSE) 244 ConResPuts(StdOut, IDS_DETAIL_NO_DISKS); 245 246 /* TODO: Print more volume details */ 247 248 ConPuts(StdOut, L"\n"); 249 250 return TRUE; 251 } 252