From 2a15f045bc98059ee5e8836dc5749069219485c8 Mon Sep 17 00:00:00 2001
From: Pdawg11239 <83825746+Pdawg-bytes@users.noreply.github.com>
Date: Sun, 16 Mar 2025 18:40:38 -0400
Subject: [PATCH] More work on FAT32 formatter
---
.../BadBuilder.Formatter.csproj | 1 +
BadBuilder.Formatter/Class1.cs | 9 -
BadBuilder.Formatter/Constants.cs | 9 +
BadBuilder.Formatter/DiskFormatter.cs | 114 +++++++++
BadBuilder.Formatter/FAT32BootSector.cs | 69 ++---
BadBuilder.Formatter/FAT32FsInfo.cs | 22 --
BadBuilder.Formatter/FAT32FsInfoSector.cs | 26 ++
BadBuilder.Formatter/FAT32Utilities.cs | 93 ++++++-
BadBuilder.Formatter/Win32.cs | 238 ++++++++++++++++++
BadBuilder/BadBuilder.csproj | 4 +
BadBuilder/Program.cs | 1 +
11 files changed, 524 insertions(+), 62 deletions(-)
delete mode 100644 BadBuilder.Formatter/Class1.cs
create mode 100644 BadBuilder.Formatter/Constants.cs
create mode 100644 BadBuilder.Formatter/DiskFormatter.cs
delete mode 100644 BadBuilder.Formatter/FAT32FsInfo.cs
create mode 100644 BadBuilder.Formatter/FAT32FsInfoSector.cs
create mode 100644 BadBuilder.Formatter/Win32.cs
diff --git a/BadBuilder.Formatter/BadBuilder.Formatter.csproj b/BadBuilder.Formatter/BadBuilder.Formatter.csproj
index fa71b7a..bd44ee5 100644
--- a/BadBuilder.Formatter/BadBuilder.Formatter.csproj
+++ b/BadBuilder.Formatter/BadBuilder.Formatter.csproj
@@ -4,6 +4,7 @@
net8.0
enable
enable
+ true
diff --git a/BadBuilder.Formatter/Class1.cs b/BadBuilder.Formatter/Class1.cs
deleted file mode 100644
index 7ba8ce6..0000000
--- a/BadBuilder.Formatter/Class1.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace BadBuilder.Formatter
-{
- public class DiskFormatter
- {
-
- }
-}
diff --git a/BadBuilder.Formatter/Constants.cs b/BadBuilder.Formatter/Constants.cs
new file mode 100644
index 0000000..99a3530
--- /dev/null
+++ b/BadBuilder.Formatter/Constants.cs
@@ -0,0 +1,9 @@
+namespace BadBuilder.Formatter
+{
+ static class Constants
+ {
+ internal const string ORANGE = "\u001b[38;2;255;114;0m";
+
+ internal const string ANSI_RESET = "\u001b[0m";
+ }
+}
\ No newline at end of file
diff --git a/BadBuilder.Formatter/DiskFormatter.cs b/BadBuilder.Formatter/DiskFormatter.cs
new file mode 100644
index 0000000..81b7b6a
--- /dev/null
+++ b/BadBuilder.Formatter/DiskFormatter.cs
@@ -0,0 +1,114 @@
+using static BadBuilder.Formatter.Win32;
+using static BadBuilder.Formatter.Constants;
+using static BadBuilder.Formatter.FAT32Utilities;
+using System.Runtime.InteropServices;
+
+namespace BadBuilder.Formatter
+{
+ public static class DiskFormatter
+ {
+ public static unsafe (int, string) FormatVolume(char driveLetter)
+ {
+ uint cbRet;
+
+ DISK_GEOMETRY diskGeometry;
+ PARTITION_INFORMATION diskPartInfo;
+ PARTITION_INFORMATION_EX exDiskPartInfo;
+ bool isGPT = false;
+ uint bytesPerSector = 0;
+ uint totalSectors;
+ uint fatSize;
+
+ string devicePath = $"\\\\.\\{driveLetter}:";
+ uint volumeID = GetVolumeID();
+
+
+ IntPtr driveHandle = CreateFileW(
+ devicePath,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ 0,
+ OPEN_EXISTING,
+ FILE_FLAG_NO_BUFFERING,
+ 0);
+
+ if (driveHandle == -1) return (-1, Error("Unable to open device - close all open programs or windows that may have a handle lock on the drive."));
+
+ if (!DeviceIoControl( driveHandle, FSCTL_ALLOW_EXTENDED_DASD_IO, 0, 0, 0, 0, out cbRet, 0))
+ return (-1, Error("Failed to enable extended DASD IO on the device."));
+
+ if (!DeviceIoControl(driveHandle, FSCTL_LOCK_VOLUME, 0, 0, 0, 0, out cbRet, 0))
+ return (-1, Error("Failed to lock the device."));
+
+
+ using (var pDiskGeometry = NativePointer.Allocate())
+ {
+ if (!DeviceIoControl(driveHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, 0, 0, pDiskGeometry.Pointer, pDiskGeometry.Size, out cbRet, 0))
+ return (-1, Error("Failed to get the drive geometry."));
+
+ diskGeometry = Marshal.PtrToStructure(pDiskGeometry.Pointer);
+ }
+ bytesPerSector = diskGeometry.BytesPerSector;
+
+ using (var pDrivePartInfo = NativePointer.Allocate())
+ {
+ if (!DeviceIoControl(driveHandle, IOCTL_DISK_GET_PARTITION_INFO, 0, 0, pDrivePartInfo.Pointer, pDrivePartInfo.Size, out cbRet, 0))
+ return (-1, Error("Failed to get the drive partition information."));
+
+ diskPartInfo = Marshal.PtrToStructure(pDrivePartInfo.Pointer);
+ }
+
+ using (var pDriveExPartInfo = NativePointer.Allocate())
+ {
+ if (!DeviceIoControl(driveHandle, IOCTL_DISK_GET_PARTITION_INFO_EX, 0, 0, pDriveExPartInfo.Pointer, pDriveExPartInfo.Size, out cbRet, 0))
+ return (-1, Error("Failed to get the drive extended partition information."));
+
+ exDiskPartInfo = Marshal.PtrToStructure(pDriveExPartInfo.Pointer);
+ }
+ isGPT = (exDiskPartInfo.PartitionStyle == PARTITION_STYLE.GPT);
+
+ totalSectors = (uint)(diskPartInfo.PartitionLength / diskGeometry.BytesPerSector);
+ if (totalSectors < 65536 || totalSectors >= 0xffffffff)
+ return (-1, Error("Invalid drive size for FAT32 - either too small (less than 64K clusters) or too large (greater than 2TB)."));
+
+ FAT32BootSector bootSector;
+ FAT32FsInfoSector fsInfo;
+
+ bootSector.JumpCode = [0xEB, 0x58, 0x90];
+ bootSector.OEMName = "MSWIN4.1".ToCharArray();
+ bootSector.BytesPerSector = (ushort)bytesPerSector;
+ bootSector.SectorsPerCluster = CalculateSectorsPerCluster((ulong)diskPartInfo.PartitionLength, bytesPerSector);
+ bootSector.ReservedSectorCount = 32;
+ bootSector.NumberOfFATs = 2;
+ bootSector.MaxRootEntries = 0;
+ bootSector.TotalSectors16 = 0;
+ bootSector.MediaDescriptor = 0xF8;
+ bootSector.SectorsPerFAT16 = 0;
+ bootSector.SectorsPerTrack = (ushort)diskGeometry.SectorsPerTrack;
+ bootSector.NumberOfHeads = (ushort)diskGeometry.TracksPerCylinder;
+ bootSector.HiddenSectors = diskPartInfo.HiddenSectors;
+ bootSector.TotalSectors = totalSectors;
+
+ fatSize = CalculateFATSize(bootSector.TotalSectors, bootSector.ReservedSectorCount, bootSector.SectorsPerCluster, bootSector.NumberOfFATs, bytesPerSector);
+
+ bootSector.SectorsPerFAT = fatSize;
+ bootSector.FATFlags = 0;
+ bootSector.FileSystemVersion = 0;
+ bootSector.RootCluster = 2;
+ bootSector.FSInfoSector = 1;
+ bootSector.BackupBootSector = 6;
+ bootSector.DriveNumber = 0x80;
+ bootSector.Reserved1 = 0;
+ bootSector.BootSignature = 0x29;
+ bootSector.VolumeID = volumeID;
+ bootSector.VolumeLabel = "BADUPDATE ".ToCharArray();
+ bootSector.FileSystemType = "FAT32 ".ToCharArray();
+ bootSector.Signature = 0x55AA;
+
+ if (!DeviceIoControl(driveHandle, FSCTL_UNLOCK_VOLUME, 0, 0, 0, 0, out cbRet, 0))
+ return (-1, Error("Failed to unlock the device."));
+
+ return (0, "");
+ }
+ }
+}
diff --git a/BadBuilder.Formatter/FAT32BootSector.cs b/BadBuilder.Formatter/FAT32BootSector.cs
index 0634994..ea5d3c6 100644
--- a/BadBuilder.Formatter/FAT32BootSector.cs
+++ b/BadBuilder.Formatter/FAT32BootSector.cs
@@ -2,48 +2,61 @@
namespace BadBuilder.Formatter
{
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ // Reference: https://cscie92.dce.harvard.edu/spring2024/K70F120M/bootSector.h
+
+ [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 512)]
internal struct FAT32BootSector
{
+ [FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
- public byte[] JumpCode;
+ internal byte[] JumpCode;
+ [FieldOffset(3)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public byte[] OEMName;
+ internal char[] OEMName;
- public ushort BytesPerSector;
- public byte SectorsPerCluster;
- public ushort ReservedSectorCount;
- public byte NumberOfFATs;
- public ushort MaxRootEntries; // Unused in FAT32
- public ushort TotalSectors16; // If 0, use TotalSectors
- public byte MediaDescriptor;
- public ushort SectorsPerFAT16; // Unused in FAT32
- public ushort SectorsPerTrack;
- public ushort NumberOfHeads;
- public uint HiddenSectors;
- public uint TotalSectors; // Total sectors (if TotalSectors16 is 0)
+ [FieldOffset(11)] internal ushort BytesPerSector;
+ [FieldOffset(13)] internal byte SectorsPerCluster;
+ [FieldOffset(14)] internal ushort ReservedSectorCount;
+ [FieldOffset(16)] internal byte NumberOfFATs;
+ [FieldOffset(17)] internal ushort MaxRootEntries; // Unused in FAT32
+ [FieldOffset(19)] internal ushort TotalSectors16; // If 0, use TotalSectors
+ [FieldOffset(21)] internal byte MediaDescriptor;
+ [FieldOffset(22)] internal ushort SectorsPerFAT16; // Unused in FAT32
+ [FieldOffset(24)] internal ushort SectorsPerTrack;
+ [FieldOffset(26)] internal ushort NumberOfHeads;
+ [FieldOffset(28)] internal uint HiddenSectors;
+ [FieldOffset(32)] internal uint TotalSectors; // Total sectors (if TotalSectors16 is 0)
// FAT32-specific fields
- public uint SectorsPerFAT;
- public ushort FATFlags;
- public ushort FileSystemVersion;
- public uint RootCluster;
- public ushort FSInfoSector;
- public ushort BackupBootSector;
+ [FieldOffset(36)] internal uint SectorsPerFAT;
+ [FieldOffset(40)] internal ushort FATFlags;
+ [FieldOffset(42)] internal ushort FileSystemVersion;
+ [FieldOffset(44)] internal uint RootCluster;
+ [FieldOffset(48)] internal ushort FSInfoSector;
+ [FieldOffset(50)] internal ushort BackupBootSector;
+ [FieldOffset(52)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
- public byte[] Reserved;
+ internal byte[] Reserved;
- public byte DriveNumber;
- public byte Reserved1;
- public byte BootSignature;
- public uint VolumeID;
+ [FieldOffset(64)] internal byte DriveNumber;
+ [FieldOffset(65)] internal byte Reserved1;
+ [FieldOffset(66)] internal byte BootSignature;
+ [FieldOffset(67)] internal uint VolumeID;
+ [FieldOffset(71)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
- public byte[] VolumeLabel;
+ internal char[] VolumeLabel;
+ [FieldOffset(82)]
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public byte[] FileSystemType;
+ internal char[] FileSystemType;
+
+ [FieldOffset(90)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 420)]
+ internal byte[] Reserved2;
+
+ [FieldOffset(510)] internal ushort Signature;
}
}
\ No newline at end of file
diff --git a/BadBuilder.Formatter/FAT32FsInfo.cs b/BadBuilder.Formatter/FAT32FsInfo.cs
deleted file mode 100644
index 461fe37..0000000
--- a/BadBuilder.Formatter/FAT32FsInfo.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace BadBuilder.Formatter
-{
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- internal struct FAT32FsInfo
- {
- public uint LeadSignature; // Should be 0x41615252
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 480)]
- public byte[] Reserved1; // Zeros
-
- public uint StructureSignature; // Should be 0x61417272
- public uint FreeClusterCount; // Number of free clusters (or 0xFFFFFFFF if unknown)
- public uint NextFreeCluster; // Next free cluster (or 0xFFFFFFFF if unknown)
-
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
- public byte[] Reserved2; // Zeros
-
- public uint TrailSignature; // Should be 0xAA550000
- }
-}
\ No newline at end of file
diff --git a/BadBuilder.Formatter/FAT32FsInfoSector.cs b/BadBuilder.Formatter/FAT32FsInfoSector.cs
new file mode 100644
index 0000000..bfdb1ef
--- /dev/null
+++ b/BadBuilder.Formatter/FAT32FsInfoSector.cs
@@ -0,0 +1,26 @@
+using System.Runtime.InteropServices;
+
+namespace BadBuilder.Formatter
+{
+ // Reference: https://cscie92.dce.harvard.edu/spring2024/K70F120M/fsInfo.h
+
+ [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 512)]
+ internal struct FAT32FsInfoSector
+ {
+ [FieldOffset(0)] public uint LeadSignature;
+
+ [FieldOffset(4)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 480)]
+ public byte[] Reserved1; // Zeros
+
+ [FieldOffset(484)] public uint StructureSignature;
+ [FieldOffset(488)] public uint FreeClusterCount;
+ [FieldOffset(492)] public uint NextFreeCluster;
+
+ [FieldOffset(496)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
+ public byte[] Reserved2;
+
+ [FieldOffset(508)] public uint TrailSignature;
+ }
+}
\ No newline at end of file
diff --git a/BadBuilder.Formatter/FAT32Utilities.cs b/BadBuilder.Formatter/FAT32Utilities.cs
index af7b54b..ab1c011 100644
--- a/BadBuilder.Formatter/FAT32Utilities.cs
+++ b/BadBuilder.Formatter/FAT32Utilities.cs
@@ -1,7 +1,46 @@
-namespace BadBuilder.Formatter
+using static BadBuilder.Formatter.Win32;
+using static BadBuilder.Formatter.Constants;
+using System.Runtime.InteropServices;
+
+namespace BadBuilder.Formatter
{
static class FAT32Utilities
{
+ internal struct NativePointer : IDisposable
+ {
+ internal IntPtr Pointer;
+ internal uint Size;
+
+ internal NativePointer(Type type)
+ {
+ uint size = (uint)Marshal.SizeOf(type);
+ Pointer = Marshal.AllocHGlobal((int)size);
+ Size = size;
+ }
+
+ public void Dispose()
+ {
+ if (Pointer != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(Pointer);
+ Pointer = IntPtr.Zero;
+ Size = 0;
+ }
+ }
+
+ internal static NativePointer Allocate() where T : struct
+ {
+ return new NativePointer(typeof(T));
+ }
+ }
+
+ internal static string Error(string error) => $"{ORANGE}[-]{ANSI_RESET} {error}";
+ internal static void ExitWithError(string error)
+ {
+ Console.WriteLine($"{ORANGE}[-]{ANSI_RESET} {error}");
+ Environment.Exit(-1);
+ }
+
internal static uint GetVolumeID()
{
DateTime now = DateTime.Now;
@@ -15,14 +54,62 @@
return (uint)(low | (hi << 16));
}
- internal static uint CalculateFATSize(uint diskSize, uint reservedSectorCount, uint sectorsPerCluster, uint numberOfFATs, uint bytesPerSector)
+ internal static uint CalculateFATSize(uint totalSectors, uint reservedSectors, uint sectorsPerCluster, uint numberOfFATs, uint bytesPerSector)
{
const ulong fatElementSize = 4;
- ulong numerator = fatElementSize * (diskSize - reservedSectorCount);
+ ulong numerator = fatElementSize * (totalSectors - reservedSectors);
ulong denominator = (sectorsPerCluster * bytesPerSector) + (fatElementSize * numberOfFATs);
return (uint)((numerator / denominator) + 1);
}
+
+ internal static byte CalculateSectorsPerCluster(ulong diskSizeBytes, uint bytesPerSector) => (diskSizeBytes / (1024 * 1024)) switch
+ {
+ var size when size > 512 => (byte)((4 * 1024) / bytesPerSector),
+ var size when size > 8192 => (byte)((8 * 1024) / bytesPerSector),
+ var size when size > 16384 => (byte)((16 * 1024) / bytesPerSector),
+ var size when size > 32768 => (byte)((32 * 1024) / bytesPerSector),
+ _ => 1
+ };
+
+
+ internal static void SeekTo(IntPtr hDevice, uint sector, uint bytesPerSector)
+ {
+ long offset = sector * bytesPerSector;
+
+ int lowOffset = (int)(offset & 0xFFFFFFFF);
+ int highOffset = (int)(offset >> 32);
+
+ SetFilePointer(hDevice, lowOffset, ref highOffset, FILE_BEGIN);
+ }
+
+ internal static void WriteSector(IntPtr hDevice, uint sector, uint numberOfSectors, uint bytesPerSector, byte[] data)
+ {
+ uint bytesWritten;
+
+ SeekTo(hDevice, sector, bytesPerSector);
+
+ if (!WriteFile(hDevice, data, numberOfSectors * bytesPerSector, out bytesWritten, 0))
+ ExitWithError("Unable to write to write sectors to FAT32 device, exiting.");
+ }
+
+ internal static void ZeroOutSectors(IntPtr hDevice, uint sector, uint numberOfSectors, uint bytesPerSector)
+ {
+ const uint burstSize = 128;
+ uint writeSize;
+
+ byte[] zeroBuffer = new byte[bytesPerSector * burstSize];
+ Array.Clear(zeroBuffer);
+
+ SeekTo(hDevice, sector, bytesPerSector);
+
+ while (numberOfSectors > 0)
+ {
+ writeSize = (numberOfSectors > burstSize) ? burstSize : numberOfSectors;
+ WriteSector(hDevice, sector, numberOfSectors, bytesPerSector, zeroBuffer);
+ numberOfSectors -= writeSize;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/BadBuilder.Formatter/Win32.cs b/BadBuilder.Formatter/Win32.cs
new file mode 100644
index 0000000..91154d3
--- /dev/null
+++ b/BadBuilder.Formatter/Win32.cs
@@ -0,0 +1,238 @@
+using System.Runtime.InteropServices;
+
+namespace BadBuilder.Formatter
+{
+ static partial class Win32
+ {
+ internal const uint GENERIC_READ = 0x80000000;
+ internal const uint GENERIC_WRITE = 0x40000000;
+ internal const uint OPEN_EXISTING = 3;
+ internal const uint FILE_SHARE_READ = 1;
+ internal const uint FILE_BEGIN = 0;
+ internal const uint FILE_FLAG_NO_BUFFERING = 0x20000000;
+
+ internal const uint IOCTL_DISK_GET_DRIVE_GEOMETRY = 0x00070000;
+ internal const uint IOCTL_DISK_GET_PARTITION_INFO_EX = 0x00070048;
+ internal const uint IOCTL_DISK_GET_PARTITION_INFO = 0x00074004;
+ internal const uint FSCTL_LOCK_VOLUME = 0x00090018;
+ internal const uint FSCTL_UNLOCK_VOLUME = 0x0009001C;
+ internal const uint FSCTL_QUERY_RETRIEVAL_POINTERS = 0x0009003B;
+ internal const uint FSCTL_GET_COMPRESSION = 0x0009003C;
+ internal const uint FSCTL_SET_COMPRESSION = 0x0009C040;
+ internal const uint FSCTL_SET_BOOTLOADER_ACCESSED = 0x0009004F;
+ internal const uint FSCTL_MARK_AS_SYSTEM_HIVE = 0x0009004F;
+ internal const uint FSCTL_OPLOCK_BREAK_ACK_NO_2 = 0x00090050;
+ internal const uint FSCTL_INVALIDATE_VOLUMES = 0x00090054;
+ internal const uint FSCTL_QUERY_FAT_BPB = 0x00090058;
+ internal const uint FSCTL_REQUEST_FILTER_OPLOCK = 0x0009005C;
+ internal const uint FSCTL_FILESYSTEM_GET_STATISTICS = 0x00090060;
+ internal const uint FSCTL_GET_NTFS_VOLUME_DATA = 0x00090064;
+ internal const uint FSCTL_GET_NTFS_FILE_RECORD = 0x00090068;
+ internal const uint FSCTL_GET_VOLUME_BITMAP = 0x0009006F;
+ internal const uint FSCTL_GET_RETRIEVAL_POINTERS = 0x00090073;
+ internal const uint FSCTL_MOVE_FILE = 0x00090074;
+ internal const uint FSCTL_IS_VOLUME_DIRTY = 0x00090078;
+ internal const uint FSCTL_ALLOW_EXTENDED_DASD_IO = 0x00090083;
+
+
+ private const string Kernel32 = "kernel32.dll";
+
+ [LibraryImport(Kernel32, SetLastError = true)]
+ internal static partial IntPtr CreateFileW(
+ [MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
+ uint dwDesiredAccess,
+ uint dwShareMode,
+ IntPtr lpSecurityAttributes,
+ uint dwCreationDisposition,
+ uint dwFlagsAndAttributes,
+ IntPtr hTemplateFile);
+
+
+ [LibraryImport(Kernel32, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static partial bool WriteFile(
+ IntPtr hFile,
+ byte[] lpBuffer,
+ uint nNumberOfBytesToWrite,
+ out uint lpNumberOfBytesWritten,
+ IntPtr lpOverlapped);
+
+ [LibraryImport(Kernel32, SetLastError = true)]
+ internal static partial uint SetFilePointer(
+ IntPtr hFile,
+ int lDistanceToMove,
+ ref int lpDistanceToMoveHigh,
+ uint dwMoveMethod);
+
+ [LibraryImport(Kernel32, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static partial bool DeviceIoControl(
+ IntPtr hDevice,
+ uint dwIoControlCode,
+ IntPtr lpInBuffer,
+ uint nInBufferSize,
+ IntPtr lpOutBuffer,
+ uint nOutBufferSize,
+ out uint lpBytesReturned,
+ IntPtr lpOverlapped);
+
+ [LibraryImport(Kernel32, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static partial bool CloseHandle(IntPtr hObject);
+
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ internal struct DISK_GEOMETRY
+ {
+ internal long Cylinders;
+ internal MediaType MediaType;
+ internal uint TracksPerCylinder;
+ internal uint SectorsPerTrack;
+ internal uint BytesPerSector;
+ }
+
+ internal enum MediaType // from winioctl.h
+ {
+ Unknown, // Format is unknown
+ F5_1Pt2_512, // 5.25", 1.2MB, 512 bytes/sector
+ F3_1Pt44_512, // 3.5", 1.44MB, 512 bytes/sector
+ F3_2Pt88_512, // 3.5", 2.88MB, 512 bytes/sector
+ F3_20Pt8_512, // 3.5", 20.8MB, 512 bytes/sector
+ F3_720_512, // 3.5", 720KB, 512 bytes/sector
+ F5_360_512, // 5.25", 360KB, 512 bytes/sector
+ F5_320_512, // 5.25", 320KB, 512 bytes/sector
+ F5_320_1024, // 5.25", 320KB, 1024 bytes/sector
+ F5_180_512, // 5.25", 180KB, 512 bytes/sector
+ F5_160_512, // 5.25", 160KB, 512 bytes/sector
+ RemovableMedia, // Removable media other than floppy
+ FixedMedia, // Fixed hard disk media
+ F3_120M_512, // 3.5", 120M Floppy
+ F3_640_512, // 3.5" , 640KB, 512 bytes/sector
+ F5_640_512, // 5.25", 640KB, 512 bytes/sector
+ F5_720_512, // 5.25", 720KB, 512 bytes/sector
+ F3_1Pt2_512, // 3.5" , 1.2Mb, 512 bytes/sector
+ F3_1Pt23_1024, // 3.5" , 1.23Mb, 1024 bytes/sector
+ F5_1Pt23_1024, // 5.25", 1.23MB, 1024 bytes/sector
+ F3_128Mb_512, // 3.5" MO 128Mb 512 bytes/sector
+ F3_230Mb_512, // 3.5" MO 230Mb 512 bytes/sector
+ F8_256_128, // 8", 256KB, 128 bytes/sector
+ F3_200Mb_512, // 3.5", 200M Floppy (HiFD)
+ F3_240M_512, // 3.5", 240Mb Floppy (HiFD)
+ F3_32M_512 // 3.5", 32Mb Floppy
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 16)]
+ internal struct GUID
+ {
+ internal uint Data1;
+ internal ushort Data2;
+ internal ushort Data3;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
+ internal byte[] Data4;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 32)]
+ internal struct PARTITION_INFORMATION
+ {
+ internal long StartingOffset;
+ internal long PartitionLength;
+ internal uint HiddenSectors;
+ internal uint PartitionNumber;
+ internal byte PartitionType;
+ internal byte BootIndicator;
+ internal byte RecognizedPattern;
+ internal byte RewritePartition;
+ }
+
+ [StructLayout(LayoutKind.Explicit, Size = 144)]
+ internal struct PARTITION_INFORMATION_EX
+ {
+ [FieldOffset(0)]
+ internal PARTITION_STYLE PartitionStyle;
+
+ [FieldOffset(8)]
+ internal long StartingOffset;
+
+ [FieldOffset(16)]
+ internal long PartitionLength;
+
+ [FieldOffset(24)]
+ internal uint PartitionNumber;
+
+ [FieldOffset(28)]
+ internal byte RewritePartition;
+
+ [FieldOffset(29)]
+ internal byte IsServicePartition;
+
+ [FieldOffset(32)]
+ internal unsafe fixed byte Union[112];
+
+ public unsafe PARTITION_INFORMATION_MBR Mbr
+ {
+ get
+ {
+ fixed (byte* p = Union)
+ {
+ return *(PARTITION_INFORMATION_MBR*)p;
+ }
+ }
+ set
+ {
+ fixed (byte* p = Union)
+ {
+ *(PARTITION_INFORMATION_MBR*)p = value;
+ }
+ }
+ }
+
+ public unsafe PARTITION_INFORMATION_GPT Gpt
+ {
+ get
+ {
+ fixed (byte* p = Union)
+ {
+ return *(PARTITION_INFORMATION_GPT*)p;
+ }
+ }
+ set
+ {
+ fixed (byte* p = Union)
+ {
+ *(PARTITION_INFORMATION_GPT*)p = value;
+ }
+ }
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 24)]
+ internal struct PARTITION_INFORMATION_MBR
+ {
+ internal byte PartitionType;
+ internal byte BootIndicator;
+ internal byte RecognizedPartition;
+ private byte _padding1;
+ internal uint HiddenSectors;
+ internal GUID PartitionId;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 112)]
+ internal struct PARTITION_INFORMATION_GPT
+ {
+ internal GUID PartitionType;
+ internal GUID PartitionId;
+ internal ulong Attributes;
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
+ internal ushort[] Name;
+ }
+
+ internal enum PARTITION_STYLE : uint
+ {
+ MBR = 0,
+ GPT = 1,
+ RAW = 2
+ }
+ }
+}
\ No newline at end of file
diff --git a/BadBuilder/BadBuilder.csproj b/BadBuilder/BadBuilder.csproj
index e2620de..9032e08 100644
--- a/BadBuilder/BadBuilder.csproj
+++ b/BadBuilder/BadBuilder.csproj
@@ -24,4 +24,8 @@
+
+
+
+
diff --git a/BadBuilder/Program.cs b/BadBuilder/Program.cs
index 3dca2ff..d0967cc 100644
--- a/BadBuilder/Program.cs
+++ b/BadBuilder/Program.cs
@@ -26,6 +26,7 @@ namespace BadBuilder
static void Main(string[] args)
{
+ BadBuilder.Formatter.DiskFormatter.FormatVolume('E');
ShowWelcomeMessage();
while (true)