Formating a Floppy or an SD Card in C# using APIs

Posted on 2009-05-11
Last Modified: 2012-05-06
I'm trying to format a drive in C#.

Before anyone of you start suggesting methods like calling the Dos format, or using SHFormatDrive... I'm not interested in those methods.

None of them gives a feedback on the progress. The Dos method opens a Dos Window and the SHFormatDrive opens windows format dialog, which basically sucks!!!

In the past, I've used FormatEx in fmifs.dll which gives me exactly what I want: Feedback on the progress (including percentage), not useless dialog etc..

It was working well in XP (it takes like 2-3 seconds to format an SD Card), but the major problem is that in Windows Vista (YUCK!!!!) it takes more than 1 minute and without any obvious reason.

This is why I'm searching for an alternate method.

I'm attaching the code I've written so far in C#.

Something (probably few things) is/are wrong with it since it doesn't format the drive that I chose... I tried \\.\F:  as the drive.
It gets to the point where it needs to fill outputBuffer with the disk geometry, but I get 0 on the number of cylinders etc, so it doesn't format the drive...

I'm not sure where exactly the problem is.

I hope someone here can help me... Thanks.
using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace Disk_Format





        public int DeviceType;

        public int DeviceNumber;

        public int PartitionNumber;





        public MEDIA_TYPE MediaType;

        public uint StartCylinderNumber;

        public uint EndCylinderNumber;

        public uint StartHeadNumber;

        public uint EndHeadNumber;



    public struct DISK_GEOMETRY


        public long Cylinders;

        public MEDIA_TYPE MediaType;

        public int TracksPerCylinder;

        public int SectorsPerTrack;

        public int BytesPerSector;

        public long DiskSize




                return Cylinders * (long)TracksPerCylinder * (long)SectorsPerTrack * (long)BytesPerSector;




    public enum MEDIA_TYPE





























    public partial class Form1 : Form


        const Int64 INVALID_HANDLE_VALUE = -1;

        const uint IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080;

        public const uint FSCTL_LOCK_VOLUME = 0x00090018;

        public const uint IOCTL_DISK_GET_DRIVE_GEOMETRY = 0x70000;

        public const uint IOCTL_DISK_FORMAT_TRACKS = 0x7C018;

        public const uint IOCTL_DISK_FORMAT_TRACKS_EX = 0x7C02C;

        public const uint FSCTL_UNLOCK_VOLUME = 0x0009001C;

        DISK_GEOMETRY outputBuffer = new DISK_GEOMETRY();



        public enum EFileAccess : uint


            /// <summary>


            /// </summary>

            GenericRead = 0x80000000,

            /// <summary>


            /// </summary>

            GenericWrite = 0x40000000,

            /// <summary>


            /// </summary>

            GenericExecute = 0x20000000,

            /// <summary>


            /// </summary>

            GenericAll = 0x10000000



        public enum EFileShare : uint


            /// <summary>


            /// </summary>

            None = 0x00000000,

            /// <summary>

            /// Enables subsequent open operations on an object to request read access. 

            /// Otherwise, other processes cannot open the object if they request read access. 

            /// If this flag is not specified, but the object has been opened for read access, the function fails.

            /// </summary>

            Read = 0x00000001,

            /// <summary>

            /// Enables subsequent open operations on an object to request write access. 

            /// Otherwise, other processes cannot open the object if they request write access. 

            /// If this flag is not specified, but the object has been opened for write access, the function fails.

            /// </summary>

            Write = 0x00000002,

            /// <summary>

            /// Enables subsequent open operations on an object to request delete access. 

            /// Otherwise, other processes cannot open the object if they request delete access.

            /// If this flag is not specified, but the object has been opened for delete access, the function fails.

            /// </summary>

            Delete = 0x00000004


        public enum ECreationDisposition : uint


            /// <summary>

            /// Creates a new file. The function fails if a specified file exists.

            /// </summary>

            New = 1,

            /// <summary>

            /// Creates a new file, always. 

            /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes, 

            /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.

            /// </summary>

            CreateAlways = 2,

            /// <summary>

            /// Opens a file. The function fails if the file does not exist. 

            /// </summary>

            OpenExisting = 3,

            /// <summary>

            /// Opens a file, always. 

            /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.

            /// </summary>

            OpenAlways = 4,

            /// <summary>

            /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.

            /// The calling process must open the file with the GENERIC_WRITE access right. 

            /// </summary>

            TruncateExisting = 5



        public enum EFileAttributes : uint


            Readonly = 0x00000001,

            Hidden = 0x00000002,

            System = 0x00000004,

            Directory = 0x00000010,

            Archive = 0x00000020,

            Device = 0x00000040,

            Normal = 0x00000080,

            Temporary = 0x00000100,

            SparseFile = 0x00000200,

            ReparsePoint = 0x00000400,

            Compressed = 0x00000800,

            Offline = 0x00001000,

            NotContentIndexed = 0x00002000,

            Encrypted = 0x00004000,

            Write_Through = 0x80000000,

            Overlapped = 0x40000000,

            NoBuffering = 0x20000000,

            RandomAccess = 0x10000000,

            SequentialScan = 0x08000000,

            DeleteOnClose = 0x04000000,

            BackupSemantics = 0x02000000,

            PosixSemantics = 0x01000000,

            OpenReparsePoint = 0x00200000,

            OpenNoRecall = 0x00100000,

            FirstPipeInstance = 0x00080000



        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern IntPtr CreateFile(

           string lpFileName,

           EFileAccess dwDesiredAccess,

           EFileShare dwShareMode,

           IntPtr lpSecurityAttributes,

           ECreationDisposition dwCreationDisposition,

           EFileAttributes dwFlagsAndAttributes,

           IntPtr hTemplateFile);

        [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]

        static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode,

        IntPtr lpInBuffer, uint nInBufferSize,

        IntPtr lpOutBuffer, uint nOutBufferSize,

        out uint lpBytesReturned, IntPtr lpOverlapped);

        [DllImport("kernel32.dll", SetLastError=true)]

        static extern bool CloseHandle(IntPtr hHandle);

        public Form1()




        // for example: \\.\C:

        private void button1_Click(object sender, EventArgs e)


            FORMAT_PARAMETERS formatParemeters = new FORMAT_PARAMETERS();

            IntPtr h = CreateFile(textBox1.Text.TrimEnd('\\'), EFileAccess.GenericRead | EFileAccess.GenericWrite,EFileShare.Read | EFileShare.Write, IntPtr.Zero, ECreationDisposition.OpenExisting, 0, IntPtr.Zero);

            uint BytesReturned;

            if (h.ToInt32() == INVALID_HANDLE_VALUE)





            bool mybool = DeviceIoControl(h, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero,0,

              out BytesReturned, IntPtr.Zero);

            IntPtr outBufferPointer = VarPtr(outputBuffer);

            mybool = DeviceIoControl(h, IOCTL_DISK_GET_DRIVE_GEOMETRY, IntPtr.Zero, 0, outBufferPointer, 24,

              out BytesReturned, IntPtr.Zero);

            formatParemeters.MediaType = outputBuffer.MediaType;

            formatParemeters.StartCylinderNumber = 0;

            formatParemeters.StartHeadNumber = 0;

            formatParemeters.EndCylinderNumber = (uint)(outputBuffer.Cylinders & 0xFFFFFFFF - 1);

            formatParemeters.EndHeadNumber = (uint)(outputBuffer.TracksPerCylinder - 1);

            uint dwBufSize;

            dwBufSize = (uint)(outputBuffer.TracksPerCylinder * 16);

            ushort[] bad_track = new ushort[outputBuffer.TracksPerCylinder];

            for (int i = 0; i < bad_track.Length; i++)


                bad_track[i] = 0;


            IntPtr formatParametersPointer = VarPtr(formatParemeters);

            IntPtr bad_trackPointer = VarPtr(bad_track);

            mybool = DeviceIoControl(h, IOCTL_DISK_FORMAT_TRACKS, formatParametersPointer, 20, bad_trackPointer, dwBufSize,

              out BytesReturned, IntPtr.Zero);

            mybool = DeviceIoControl(h, FSCTL_UNLOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0,

              out BytesReturned, IntPtr.Zero);


        static IntPtr VarPtr(object obj)


            GCHandle GC = GCHandle.Alloc(obj, GCHandleType.Pinned);

            IntPtr ret = GC.AddrOfPinnedObject();

            return ret;




Open in new window

Question by:saragani
  • 3
LVL 11

Author Comment

ID: 24371547
OK, lets start with a VB6 example, OK?

I've written an example with VB6 and it doesn't work. I've later searched the Internet for an example in VB6 and found one... and yes, It doesn't work either.

During the searches I've read somewhere that IOCTL_DISK_FORMAT_TRACKS only works with Floppy Disks... (I've read that it doesn't work on Hard Drives is I remember correctly).

So how exactly companies like Panasonic have managed to create a tool for formating an SD/USB Flash drive??
(And their tool is very good)

If you are having problems writing an example in C#, then VB6 could be a good start. (Maybe instead of using IOCTL_DISK_FORMAT_TRACKS we need to write the FAT32 by ourselves??)

Isn't there an expert here that can help me with that task?

LVL 11

Author Comment

ID: 24383159
Maybe using the UFAT.dll can help??
(I know it has format capabilities... I understand that FMIFS.dll uses it)

Anyone has an idea on how to use it in order to format a USB drive?
LVL 11

Accepted Solution

saragani earned 0 total points
ID: 24461323
Almost 2 weeks and not a single comment. I'm closing this question.

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
count7 challenge 12 101
groovy example issue 10 89
parse convert xml feed to text (python) 2 67
tvirtualstringtree freeze when load too manny images 10 52
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

912 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now