mirror of
https://github.com/reactos/reactos.git
synced 2024-11-19 21:48:10 +00:00
344 lines
8.7 KiB
C
344 lines
8.7 KiB
C
/*
|
|
* 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;
|
|
}
|