C#でディスクフォーマット

数年前に仕事で調べたハードディスクフォーマットの方法です。(結局使わなかったんですが。。)

WinAPIを使用します。(fmifs.dll)

相変わらず使用用途のないネタですね。

 

XPで動作確認しています。

Vista以降や64bitOSでは動作確認していません。

 

下のコードを適当なクラスに張り付けて、

Formatメソッドを呼べば動くと思います。

 

以下、コード

// コールバック
private delegate Int32 FormatCallBackDelegate(
    CallbackCommand callBackCommand,
    Int32 subActionCommand,
    IntPtr action);

// フォーマットAPI
[DllImport(
    "fmifs.dll",
    CharSet = CharSet.Auto,
    EntryPoint = "FormatEx")]
private static extern void FormatEx(
    string driveLetter,
    Int32 mediaFlag,
    string fsType,
    string label,
    Int32 quickFormat,
    Int32 clusterSize,
    FormatCallBackDelegate callBackDelegate);

// ハードディスク
private const MEDIA_HARDDISK = 0x0C;
// フロッピー
private const MEDIA_FLOPPY = 0x08;

// コールバック種別
private enum CallbackCommand
{
    PROGRESS,
    DONEWITHSTRUCTURE,
    UNKNOWN2,
    UNKNOWN3,
    UNKNOWN4,
    UNKNOWN5,
    INSUFFICIENTRIGHTS,
    UNKNOWN7,
    DISKLOCKEDFORACCESS, //UNKNOWN8,
    UNKNOWN9,
    UNKNOWNA,
    DONE,
    UNKNOWNC,
    UNKNOWND,
    OUTPUT,
    STRUCTUREPROGRESS
}

// Formatメソッドの結果
private static bool result = false;

// フォーマットメソッド
public static bool Format(
    string drive,        // 「C:」「D:」等
    string fileSystem,    // 「FAT32」または「NTFS」
    string label,        // ドライブのラベル(DriveInfo.VolumeLabel)
    int clusterSize,    // クラスタサイズ
    bool quick)
{
    /* クラスタサイズはバイト単位で指定
     * 0=デフォルトサイズ
     * 512,1024,2048,4096,8192,16384.32768,
     * 65536,1031072,262144が指定可能
     */

    FormatCallBackDelegate callback =
        new FormatCallBackDelegate(formatCallBack);

    int intQuick = quick ? 1 : 0;
    result = false;
    FormatEx(
        drive,
        MEDIA_HARDDISK,
        fileSystem,
        label,
        intQuick,
        (Int32)clusterSize,
        callback);
    return result;
}

// APIからのコールバック
// 定期的に繰り返し呼ばれる
private static Int32 formatCallBack(
    CallbackCommand callBackCommand,
    int subActionCommand,
    IntPtr action)
{
    try
    {
        switch (callBackCommand)
        {
            case CallbackCommand.DISKLOCKEDFORACCESS:
                // ディスクにアクセスしているプロセスがある
                break;
            case CallbackCommand.DONE:
                // 終了通知
                if (action != IntPtr.Zero)
                {
                    result = (Marshal.ReadByte(action) == 1);
                    // result == true ならフォーマット成功
                }
                break;
            case CallbackCommand.DONEWITHSTRUCTURE:
                // 正常終了時
                break;
            case CallbackCommand.INSUFFICIENTRIGHTS:
                // 権限不足
                break;
            case CallbackCommand.OUTPUT:
                // 不明(メッセージがセットされる?)
                // actionにメッセージがあるっぽい
                break;
            case CallbackCommand.PROGRESS:
                // 進捗報告(Marshal.ReadInt32(action)で%が取得できる)
                break;
            case CallbackCommand.STRUCTUREPROGRESS:
                // 状況取得(0を返却すると強制キャンセル出来る)
                break;
            default:
                // 不明なコマンド
                break;
        }
    }
    catch
    {
    }
    // フォーマットを続行する場合「1」を返却する
    return 1;
}

2010/09/15