[DISKPART] Add dump command to dump a sector of a disk or partition
authorEric Kohl <eric.kohl@reactos.org>
Sun, 13 Mar 2022 13:20:47 +0000 (14:20 +0100)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 13 Mar 2022 13:26:10 +0000 (14:26 +0100)
Select a disk and run "dump disk 0" to dump the MBR of the disk.

base/system/diskpart/dump.c [new file with mode: 0644]

diff --git a/base/system/diskpart/dump.c b/base/system/diskpart/dump.c
new file mode 100644 (file)
index 0000000..6e2e46a
--- /dev/null
@@ -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 <debug.h>
+
+/* 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;
+}