1 /* 2 * PROJECT: ReactOS DiskPart 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/system/diskpart/dump.c 5 * PURPOSE: Manages all the partitions of the OS in an interactive way. 6 * PROGRAMMERS: Eric Kohl 7 */ 8 9 #include "diskpart.h" 10 11 #define NDEBUG 12 #include <debug.h> 13 14 /* FUNCTIONS ******************************************************************/ 15 16 static 17 VOID 18 HexDump( 19 _In_ UCHAR *addr, 20 _In_ int len) 21 { 22 WCHAR Buffer[17]; 23 UCHAR *pc; 24 int i; 25 26 Buffer[16] = L'\0'; 27 28 pc = addr; 29 for (i = 0; i < len; i++) 30 { 31 if ((i % 16) == 0) 32 ConPrintf(StdOut, L" %04x ", i); 33 34 ConPrintf(StdOut, L" %02x", pc[i]); 35 36 if ((pc[i] < 0x20) || (pc[i] > 0x7e)) 37 Buffer[i % 16] = L'.'; 38 else 39 Buffer[i % 16] = (WCHAR)(USHORT)pc[i]; 40 41 if ((i % 16) == (16 - 1)) 42 ConPrintf(StdOut, L" %s\n", Buffer); 43 } 44 } 45 46 47 static 48 VOID 49 DumpDisk( 50 _In_ INT argc, 51 _In_ LPWSTR *argv) 52 { 53 OBJECT_ATTRIBUTES ObjectAttributes; 54 IO_STATUS_BLOCK Iosb; 55 NTSTATUS Status; 56 WCHAR Buffer[MAX_PATH]; 57 UNICODE_STRING Name; 58 HANDLE FileHandle = NULL; 59 PUCHAR pSectorBuffer = NULL; 60 LARGE_INTEGER FileOffset; 61 LONGLONG Sector; 62 LPWSTR endptr = NULL; 63 64 #if 0 65 if (argc == 2) 66 { 67 ConResPuts(StdOut, IDS_HELP_CMD_DUMP_DISK); 68 return TRUE; 69 } 70 #endif 71 72 if (CurrentDisk == NULL) 73 { 74 ConResPuts(StdOut, IDS_SELECT_NO_DISK); 75 return; 76 } 77 78 Sector = _wcstoi64(argv[2], &endptr, 0); 79 if (((Sector == 0) && (endptr == argv[2])) || 80 (Sector < 0)) 81 { 82 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); 83 return; 84 } 85 86 pSectorBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CurrentDisk->BytesPerSector); 87 if (pSectorBuffer == NULL) 88 { 89 DPRINT1("\n"); 90 /* Error message */ 91 goto done; 92 } 93 94 swprintf(Buffer, 95 L"\\Device\\Harddisk%d\\Partition0", 96 CurrentDisk->DiskNumber); 97 RtlInitUnicodeString(&Name, 98 Buffer); 99 100 InitializeObjectAttributes(&ObjectAttributes, 101 &Name, 102 0, 103 NULL, 104 NULL); 105 106 Status = NtOpenFile(&FileHandle, 107 FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, 108 &ObjectAttributes, 109 &Iosb, 110 FILE_SHARE_READ, 111 FILE_SYNCHRONOUS_IO_NONALERT); 112 if (!NT_SUCCESS(Status)) 113 { 114 DPRINT1("\n"); 115 goto done; 116 } 117 118 FileOffset.QuadPart = Sector * CurrentDisk->BytesPerSector; 119 Status = NtReadFile(FileHandle, 120 NULL, 121 NULL, 122 NULL, 123 &Iosb, 124 (PVOID)pSectorBuffer, 125 CurrentDisk->BytesPerSector, 126 &FileOffset, 127 NULL); 128 if (!NT_SUCCESS(Status)) 129 { 130 DPRINT1("NtReadFile failed, status=%x\n", Status); 131 goto done; 132 } 133 134 HexDump(pSectorBuffer, CurrentDisk->BytesPerSector); 135 136 done: 137 if (FileHandle) 138 NtClose(FileHandle); 139 140 RtlFreeHeap(RtlGetProcessHeap(), 0, pSectorBuffer); 141 142 return; 143 } 144 145 146 static 147 VOID 148 DumpPartition( 149 _In_ INT argc, 150 _In_ LPWSTR *argv) 151 { 152 OBJECT_ATTRIBUTES ObjectAttributes; 153 IO_STATUS_BLOCK Iosb; 154 NTSTATUS Status; 155 WCHAR Buffer[MAX_PATH]; 156 UNICODE_STRING Name; 157 HANDLE FileHandle = NULL; 158 PUCHAR pSectorBuffer = NULL; 159 LARGE_INTEGER FileOffset; 160 LONGLONG Sector; 161 LPWSTR endptr = NULL; 162 163 164 #if 0 165 if (argc == 2) 166 { 167 ConResPuts(StdOut, IDS_HELP_CMD_DUMP_DISK); 168 return TRUE; 169 } 170 #endif 171 172 if (CurrentDisk == NULL) 173 { 174 ConResPuts(StdOut, IDS_SELECT_NO_DISK); 175 return; 176 } 177 178 if (CurrentPartition == NULL) 179 { 180 ConResPuts(StdOut, IDS_SELECT_NO_PARTITION); 181 return; 182 } 183 184 Sector = _wcstoi64(argv[2], &endptr, 0); 185 if (((Sector == 0) && (endptr == argv[2])) || 186 (Sector < 0)) 187 { 188 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); 189 return; 190 } 191 192 pSectorBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CurrentDisk->BytesPerSector); 193 if (pSectorBuffer == NULL) 194 { 195 DPRINT1("\n"); 196 /* Error message */ 197 goto done; 198 } 199 200 swprintf(Buffer, 201 L"\\Device\\Harddisk%d\\Partition%d", 202 CurrentDisk->DiskNumber, 203 CurrentPartition->PartitionNumber); 204 RtlInitUnicodeString(&Name, 205 Buffer); 206 207 InitializeObjectAttributes(&ObjectAttributes, 208 &Name, 209 0, 210 NULL, 211 NULL); 212 213 Status = NtOpenFile(&FileHandle, 214 FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, 215 &ObjectAttributes, 216 &Iosb, 217 FILE_SHARE_READ, 218 FILE_SYNCHRONOUS_IO_NONALERT); 219 if (!NT_SUCCESS(Status)) 220 { 221 DPRINT1("\n"); 222 goto done; 223 } 224 225 FileOffset.QuadPart = Sector * CurrentDisk->BytesPerSector; 226 Status = NtReadFile(FileHandle, 227 NULL, 228 NULL, 229 NULL, 230 &Iosb, 231 (PVOID)pSectorBuffer, 232 CurrentDisk->BytesPerSector, 233 &FileOffset, 234 NULL); 235 if (!NT_SUCCESS(Status)) 236 { 237 DPRINT1("NtReadFile failed, status=%x\n", Status); 238 goto done; 239 } 240 241 HexDump(pSectorBuffer, CurrentDisk->BytesPerSector); 242 243 done: 244 if (FileHandle) 245 NtClose(FileHandle); 246 247 RtlFreeHeap(RtlGetProcessHeap(), 0, pSectorBuffer); 248 249 return; 250 } 251 252 253 BOOL 254 dump_main( 255 _In_ INT argc, 256 _In_ LPWSTR *argv) 257 { 258 /* gets the first word from the string */ 259 #if 0 260 if (argc == 1) 261 { 262 ConResPuts(StdOut, IDS_HELP_CMD_LIST); 263 return TRUE; 264 } 265 #endif 266 267 /* determines which to list (disk, partition, etc.) */ 268 if (!wcsicmp(argv[1], L"disk")) 269 DumpDisk(argc, argv); 270 else if (!wcsicmp(argv[1], L"partition")) 271 DumpPartition(argc, argv); 272 #if 0 273 else 274 ConResPuts(StdOut, IDS_HELP_CMD_LIST); 275 #endif 276 277 return TRUE; 278 } 279