[PARTTEST]
authorPierre Schweitzer <pierre@reactos.org>
Mon, 10 Nov 2014 18:26:34 +0000 (18:26 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 10 Nov 2014 18:26:34 +0000 (18:26 +0000)
Add a dummy application that will open first disk and check first sector for MBR and then will open first partition to check for something known (& not MBR)

svn path=/trunk/; revision=65367

rostests/tests/parttest/CMakeLists.txt [new file with mode: 0644]
rostests/tests/parttest/parttest.c [new file with mode: 0644]

diff --git a/rostests/tests/parttest/CMakeLists.txt b/rostests/tests/parttest/CMakeLists.txt
new file mode 100644 (file)
index 0000000..46f4029
--- /dev/null
@@ -0,0 +1,4 @@
+add_executable(parttest parttest.c)
+set_module_type(parttest win32cui)
+add_importlibs(parttest ntdll msvcrt kernel32)
+add_cd_file(TARGET parttest DESTINATION reactos/bin FOR all)
diff --git a/rostests/tests/parttest/parttest.c b/rostests/tests/parttest/parttest.c
new file mode 100644 (file)
index 0000000..688e125
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * PROJECT:         ReactOS partitions tests/dump
+ * LICENSE:         LGPLv2+ - See COPYING.LIB in the top level directory
+ * PURPOSE:         Open disk & partition trying to get information about volumes & MBR
+ * PROGRAMMER:      Pierre Schweitzer <pierre@reactos.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <winternl.h>
+
+#ifndef NT_SUCCESS
+# define NT_SUCCESS(_Status) (((NTSTATUS)(_Status)) >= 0)
+#endif
+
+#define SECTOR_SIZE 512
+#define BOOT_RECORD_SIGNATURE 0xAA55
+
+PCWSTR DiskFormat = L"\\Device\\Harddisk%lu\\Partition%lu";
+
+#include <pshpack1.h>
+typedef struct {
+    unsigned char  magic0, res0, magic1;
+    unsigned char  OEMName[8];
+    unsigned short BytesPerSector;
+    unsigned char  SectorsPerCluster;
+    unsigned short ReservedSectors;
+    unsigned char  FATCount;
+    unsigned short RootEntries, Sectors;
+    unsigned char  Media;
+    unsigned short FATSectors, SectorsPerTrack, Heads;
+    unsigned long  HiddenSectors, SectorsHuge;
+    unsigned long  FATSectors32;
+    unsigned short ExtFlag;
+    unsigned short FSVersion;
+    unsigned long  RootCluster;
+    unsigned short FSInfoSector;
+    unsigned short BootBackup;
+    unsigned char  Res3[12];
+    unsigned char  Drive;
+    unsigned char  Res4;
+    unsigned char  ExtBootSignature;
+    unsigned long  VolumeID;
+    unsigned char  VolumeLabel[11], SysType[8];
+    unsigned char  Res2[420];
+    unsigned short Signature1;
+} FATBootSector, *PFATBootSector;
+
+typedef struct {
+    UCHAR     Jump[3];
+    UCHAR     OEMID[8];
+    USHORT    BytesPerSector;
+    UCHAR     SectorsPerCluster;
+    UCHAR     Unused0[7];
+    UCHAR     MediaId;
+    UCHAR     Unused1[2];
+    USHORT    SectorsPerTrack;
+    USHORT    Heads;
+    UCHAR     Unused2[4];
+    UCHAR     Unused3[4];
+    USHORT    Unknown[2];
+    ULONGLONG SectorCount;
+    ULONGLONG MftLocation;
+    ULONGLONG MftMirrLocation;
+    CHAR      ClustersPerMftRecord;
+    UCHAR     Unused4[3];
+    CHAR      ClustersPerIndexRecord;
+    UCHAR     Unused5[3];
+    ULONGLONG SerialNumber;
+    UCHAR     Checksum[4];
+    UCHAR     BootStrap[426];
+    USHORT    EndSector;
+} NTFSBootSector, *PNTFSBootSector;
+
+typedef struct {
+    UCHAR BootIndicator;
+    UCHAR StartHead;
+    UCHAR StartSector;
+    UCHAR StartCylinder;
+    UCHAR SystemIndicator;
+    UCHAR EndHead;
+    UCHAR EndSector;
+    UCHAR EndCylinder;
+    ULONG SectorCountBeforePartition;
+    ULONG PartitionSectorCount;
+} PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
+
+typedef struct {
+    UCHAR MasterBootRecordCodeAndData[0x1B8];
+    ULONG Signature;
+    USHORT Reserved;
+    PARTITION_TABLE_ENTRY PartitionTable[4];
+    USHORT MasterBootRecordMagic;
+} MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
+#include <poppack.h>
+
+BOOL CheckAgainstFAT(PFATBootSector Sector)
+{
+    if (Sector->Signature1 != 0xaa55)
+    {
+        return FALSE;
+    }
+
+    if (Sector->BytesPerSector != 512 &&
+        Sector->BytesPerSector != 1024 &&
+        Sector->BytesPerSector != 2048 &&
+        Sector->BytesPerSector != 4096)
+    {
+        return FALSE;
+    }
+
+    if (Sector->FATCount != 1 &&
+        Sector->FATCount != 2)
+    {
+        return FALSE;
+    }
+
+    if (Sector->Media != 0xf0 &&
+        Sector->Media != 0xf8 &&
+        Sector->Media != 0xf9 &&
+        Sector->Media != 0xfa &&
+        Sector->Media != 0xfb &&
+        Sector->Media != 0xfc &&
+        Sector->Media != 0xfd &&
+        Sector->Media != 0xfe &&
+        Sector->Media != 0xff)
+    {
+        return FALSE;
+    }
+
+    if (Sector->SectorsPerCluster != 1 &&
+        Sector->SectorsPerCluster != 2 &&
+        Sector->SectorsPerCluster != 4 &&
+        Sector->SectorsPerCluster != 8 &&
+        Sector->SectorsPerCluster != 16 &&
+        Sector->SectorsPerCluster != 32 &&
+        Sector->SectorsPerCluster != 64 &&
+        Sector->SectorsPerCluster != 128)
+    {
+        return FALSE;
+    }
+
+    if (Sector->BytesPerSector * Sector->SectorsPerCluster > 32 * 1024)
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+BOOL CheckAgainstNTFS(PNTFSBootSector Sector)
+{
+    ULONG k;
+    ULONG ClusterSize;
+
+    /* OEMID: this field must be NTFS */
+    if (RtlCompareMemory(Sector->OEMID, "NTFS    ", 8) != 8)
+    {
+        return FALSE;
+    }
+
+    /* Unused0: this field must be COMPLETELY null */
+    for (k = 0; k < 7; k++)
+    {
+        if (Sector->Unused0[k] != 0)
+        {
+            return FALSE;
+        }
+    }
+
+    /* Unused3: this field must be COMPLETELY null */
+    for (k = 0; k < 4; k++)
+    {
+        if (Sector->Unused3[k] != 0)
+        {
+            return FALSE;
+        }
+    }
+
+    /* Check cluster size */
+    ClusterSize = Sector->BytesPerSector * Sector->SectorsPerCluster;
+    if (ClusterSize != 512 && ClusterSize != 1024 && 
+        ClusterSize != 2048 && ClusterSize != 4096 &&
+        ClusterSize != 8192 && ClusterSize != 16384 &&
+        ClusterSize != 32768 && ClusterSize != 65536)
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+BOOL CheckAgainstMBR(PMASTER_BOOT_RECORD Sector)
+{
+    if (Sector->MasterBootRecordMagic != BOOT_RECORD_SIGNATURE)
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+int main(int argc, char ** argv)
+{
+    HANDLE FileHandle;
+    NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+    WCHAR Buffer[MAX_PATH];
+    UNICODE_STRING Name;
+    PVOID Sector;
+
+    Sector = malloc(SECTOR_SIZE);
+    if (Sector == NULL)
+    {
+        fprintf(stderr, "Failed allocating memory!\n");
+        return 0;
+    }
+
+    /* We first open disk */
+    swprintf(Buffer, DiskFormat, 0, 0);
+    RtlInitUnicodeString(&Name, Buffer);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &Name,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenFile(&FileHandle,
+                        GENERIC_READ | SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        0,
+                        FILE_SYNCHRONOUS_IO_NONALERT);
+    if (!NT_SUCCESS(Status))
+    {
+        free(Sector);
+        fprintf(stderr, "Failed opening disk! %lx\n", Status);
+        return 0;
+    }
+
+    /* Read first sector of the disk */
+    Status = NtReadFile(FileHandle,
+                        NULL,
+                        NULL,
+                        NULL,
+                        &IoStatusBlock,
+                        Sector,
+                        SECTOR_SIZE,
+                        NULL,
+                        NULL);
+    NtClose(FileHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        free(Sector);
+        fprintf(stderr, "Failed reading sector 0! %lx\n", Status);
+        return 0;
+    }
+
+    /* Is it FAT? */
+    if (CheckAgainstFAT(Sector))
+    {
+        printf("Sector 0 seems to be FAT boot sector\n");
+    }
+    /* Is it NTFS? */
+    else if (CheckAgainstNTFS(Sector))
+    {
+        printf("Sector 0 seems to be NTFS boot sector\n");
+    }
+    /* Is it MBR? */
+    else if (CheckAgainstMBR(Sector))
+    {
+        printf("Sector 0 might be MBR\n");
+    }
+    /* We don't support anything else */
+    else
+    {
+        printf("Sector 0 not recognized\n");
+    }
+
+    /* Redo it with first partition */
+    swprintf(Buffer, DiskFormat, 0, 1);
+    RtlInitUnicodeString(&Name, Buffer);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &Name,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenFile(&FileHandle,
+                        GENERIC_READ | SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                        FILE_SYNCHRONOUS_IO_NONALERT);
+    if (!NT_SUCCESS(Status))
+    {
+        free(Sector);
+        fprintf(stderr, "Failed opening partition! %lx\n", Status);
+        return 0;
+    }
+
+    /* Read first sector of the partition */
+    Status = NtReadFile(FileHandle,
+                        NULL,
+                        NULL,
+                        NULL,
+                        &IoStatusBlock,
+                        Sector,
+                        SECTOR_SIZE,
+                        NULL,
+                        NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        free(Sector);
+        fprintf(stderr, "Failed reading first sector of the partition! %lx\n", Status);
+        return 0;
+    }
+
+    /* Is it FAT? */
+    if (CheckAgainstFAT(Sector))
+    {
+        printf("Seems to be a FAT partittion\n");
+    }
+    /* Is it NTFS? */
+    else if (CheckAgainstNTFS(Sector))
+    {
+        printf("Seems to be a NTFS partition\n");
+    }
+    /* Is it MBR? */
+    else if (CheckAgainstMBR(Sector))
+    {
+        printf("Seems to be MBR\n");
+    }
+    /* We don't support anything else */
+    else
+    {
+        printf("Not recognized\n");
+    }
+
+    free(Sector);
+
+    return 0;
+}