From a2aaa28436e47180ffb72397571fac02d8f61a08 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 13 Mar 2022 14:20:47 +0100 Subject: [PATCH] [DISKPART] Add dump command to dump a sector of a disk or partition Select a disk and run "dump disk 0" to dump the MBR of the disk. --- base/system/diskpart/dump.c | 278 ++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 base/system/diskpart/dump.c diff --git a/base/system/diskpart/dump.c b/base/system/diskpart/dump.c new file mode 100644 index 00000000000..6e2e46a8733 --- /dev/null +++ b/base/system/diskpart/dump.c @@ -0,0 +1,278 @@ +/* + * PROJECT: ReactOS DiskPart + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/system/diskpart/dump.c + * PURPOSE: Manages all the partitions of the OS in an interactive way. + * PROGRAMMERS: Eric Kohl + */ + +#include "diskpart.h" + +#define NDEBUG +#include + +/* FUNCTIONS ******************************************************************/ + +static +VOID +HexDump( + _In_ UCHAR *addr, + _In_ int len) +{ + WCHAR Buffer[17]; + UCHAR *pc; + int i; + + Buffer[16] = L'\0'; + + pc = addr; + for (i = 0; i < len; i++) + { + if ((i % 16) == 0) + ConPrintf(StdOut, L" %04x ", i); + + ConPrintf(StdOut, L" %02x", pc[i]); + + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) + Buffer[i % 16] = L'.'; + else + Buffer[i % 16] = (WCHAR)(USHORT)pc[i]; + + if ((i % 16) == (16 - 1)) + ConPrintf(StdOut, L" %s\n", Buffer); + } +} + + +static +VOID +DumpDisk( + _In_ INT argc, + _In_ LPWSTR *argv) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + WCHAR Buffer[MAX_PATH]; + UNICODE_STRING Name; + HANDLE FileHandle = NULL; + PUCHAR pSectorBuffer = NULL; + LARGE_INTEGER FileOffset; + LONGLONG Sector; + LPWSTR endptr = NULL; + +#if 0 + if (argc == 2) + { + ConResPuts(StdOut, IDS_HELP_CMD_DUMP_DISK); + return TRUE; + } +#endif + + if (CurrentDisk == NULL) + { + ConResPuts(StdOut, IDS_SELECT_NO_DISK); + return; + } + + Sector = _wcstoi64(argv[2], &endptr, 0); + if (((Sector == 0) && (endptr == argv[2])) || + (Sector < 0)) + { + ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); + return; + } + + pSectorBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CurrentDisk->BytesPerSector); + if (pSectorBuffer == NULL) + { + DPRINT1("\n"); + /* Error message */ + goto done; + } + + swprintf(Buffer, + L"\\Device\\Harddisk%d\\Partition0", + CurrentDisk->DiskNumber); + RtlInitUnicodeString(&Name, + Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &Iosb, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("\n"); + goto done; + } + + FileOffset.QuadPart = Sector * CurrentDisk->BytesPerSector; + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + (PVOID)pSectorBuffer, + CurrentDisk->BytesPerSector, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtReadFile failed, status=%x\n", Status); + goto done; + } + + HexDump(pSectorBuffer, CurrentDisk->BytesPerSector); + +done: + if (FileHandle) + NtClose(FileHandle); + + RtlFreeHeap(RtlGetProcessHeap(), 0, pSectorBuffer); + + return; +} + + +static +VOID +DumpPartition( + _In_ INT argc, + _In_ LPWSTR *argv) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + WCHAR Buffer[MAX_PATH]; + UNICODE_STRING Name; + HANDLE FileHandle = NULL; + PUCHAR pSectorBuffer = NULL; + LARGE_INTEGER FileOffset; + LONGLONG Sector; + LPWSTR endptr = NULL; + + +#if 0 + if (argc == 2) + { + ConResPuts(StdOut, IDS_HELP_CMD_DUMP_DISK); + return TRUE; + } +#endif + + if (CurrentDisk == NULL) + { + ConResPuts(StdOut, IDS_SELECT_NO_DISK); + return; + } + + if (CurrentPartition == NULL) + { + ConResPuts(StdOut, IDS_SELECT_NO_PARTITION); + return; + } + + Sector = _wcstoi64(argv[2], &endptr, 0); + if (((Sector == 0) && (endptr == argv[2])) || + (Sector < 0)) + { + ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); + return; + } + + pSectorBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CurrentDisk->BytesPerSector); + if (pSectorBuffer == NULL) + { + DPRINT1("\n"); + /* Error message */ + goto done; + } + + swprintf(Buffer, + L"\\Device\\Harddisk%d\\Partition%d", + CurrentDisk->DiskNumber, + CurrentPartition->PartitionNumber); + RtlInitUnicodeString(&Name, + Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &Iosb, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("\n"); + goto done; + } + + FileOffset.QuadPart = Sector * CurrentDisk->BytesPerSector; + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + (PVOID)pSectorBuffer, + CurrentDisk->BytesPerSector, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtReadFile failed, status=%x\n", Status); + goto done; + } + + HexDump(pSectorBuffer, CurrentDisk->BytesPerSector); + +done: + if (FileHandle) + NtClose(FileHandle); + + RtlFreeHeap(RtlGetProcessHeap(), 0, pSectorBuffer); + + return; +} + + +BOOL +dump_main( + _In_ INT argc, + _In_ LPWSTR *argv) +{ + /* gets the first word from the string */ +#if 0 + if (argc == 1) + { + ConResPuts(StdOut, IDS_HELP_CMD_LIST); + return TRUE; + } +#endif + + /* determines which to list (disk, partition, etc.) */ + if (!wcsicmp(argv[1], L"disk")) + DumpDisk(argc, argv); + else if (!wcsicmp(argv[1], L"partition")) + DumpPartition(argc, argv); +#if 0 + else + ConResPuts(StdOut, IDS_HELP_CMD_LIST); +#endif + + return TRUE; +}