2016-09-20 60 views
1

DiskPartまたはWMIを使用せずに、ディスクを初期化してDeviceIOControlを使用してNTFSパーティションを作成しようとしています。DeviceIoControlを使用してNTFSパーティションを初期化して作成する

次のコードを使用して、ディスクを初期化してRAWパーティションを作成できますが、新しいパーティションがNTFSになるようにパラメータを調整することはできません。

アイデア?

//Returns true if drive Index is successfully created 
//Returns false if not created successfully 
public static bool CreatePartition(int driveIndex, string physicalName) 
{ 
    IntPtr handle = GetHandle(driveIndex, physicalName); 

    if (handle == INVALID_HANDLE_VALUE) 
    { 
     return false; 
    } 

    //Step 2: IOCTL_DISK_GET_DRIVE_GEOMETRY_EX to get the physical disk's geometry (we need some information in it to fill partition data) 
    //The number of surfaces (or heads, which is the same thing), cylinders, and sectors vary a lot; the specification of the number of each is called the geometry of a hard disk. 
    //The geometry is usually stored in a special, battery-powered memory location called the CMOS RAM , from where the operating system can fetch it during bootup or driver initialization. 
    int size = 0; 
    DISK_GEOMETRY_EX geometry = new DISK_GEOMETRY_EX(); 
    IntPtr lpOutBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DISK_GEOMETRY_EX))); 
    Marshal.StructureToPtr(geometry, lpOutBuffer, false); 
    int result = DeviceIoControl(handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, IntPtr.Zero, 0, lpOutBuffer, Marshal.SizeOf(typeof(DISK_GEOMETRY_EX)), ref size, IntPtr.Zero); 
    geometry = (DISK_GEOMETRY_EX)Marshal.PtrToStructure(lpOutBuffer, typeof(DISK_GEOMETRY_EX)); 


    //Step 3: IOCTL_DISK_CREATE_DISK is used to initialize a disk with an empty partition table. 
    CREATE_DISK createDisk = new CREATE_DISK(); 
    createDisk.PartitionStyle = PARTITION_STYLE.PARTITION_STYLE_MBR; 
    createDisk.Mbr.Signature = 1; 

    IntPtr createDiskBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CREATE_DISK))); 
    Marshal.StructureToPtr(createDisk, createDiskBuffer, false); 

    byte[] arr1 = new byte[Marshal.SizeOf(typeof(CREATE_DISK))]; 
    Marshal.Copy(createDiskBuffer, arr1, 0, Marshal.SizeOf(typeof(CREATE_DISK))); 

    result = DeviceIoControl(handle, IOCTL_DISK_CREATE_DISK, createDiskBuffer, Marshal.SizeOf(typeof(CREATE_DISK)), 
           IntPtr.Zero, 0, ref size, IntPtr.Zero); 

    result = DeviceIoControl(handle, IOCTL_DISK_UPDATE_PROPERTIES, IntPtr.Zero, 0, IntPtr.Zero, 0, ref size, IntPtr.Zero); 


    //Step 4: IOCTL_DISK_SET_DRIVE_LAYOUT_EX to repartition a disk as specified. 
    //Note: use IOCTL_DISK_UPDATE_PROPERTIES to synchronize system view after IOCTL_DISK_CREATE_DISK and IOCTL_DISK_SET_DRIVE_LAYOUT_EX 
    /* DWORD driveLayoutSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + sizeof(PARTITION_INFORMATION_EX) * 4 * 25; 
     DRIVE_LAYOUT_INFORMATION_EX *DriveLayoutEx = (DRIVE_LAYOUT_INFORMATION_EX *) new BYTE[driveLayoutSize];*/ 



    IntPtr driveLayoutbuffer = Marshal.AllocHGlobal(192); 
    FillMemory(driveLayoutbuffer, 192, 0); 
    DRIVE_LAYOUT_INFORMATION_EX driveLayoutEx = new DRIVE_LAYOUT_INFORMATION_EX(); 
    driveLayoutEx.PartitionEntry = new PARTITION_INFORMATION_EX[1]; 


    mediaType = (int)geometry.Geometry.MediaType; 
    Int64 bytes_per_track = (geometry.Geometry.SectorsPerTrack) * (geometry.Geometry.BytesPerSector); 

    driveLayoutEx.PartitionEntry[0].StartingOffset = 0x0; 

    Int64 main_part_size_in_sectors, extra_part_size_in_sectors = 0; 
    main_part_size_in_sectors = (geometry.DiskSize - driveLayoutEx.PartitionEntry[0].StartingOffset)/geometry.Geometry.BytesPerSector; 

    if (main_part_size_in_sectors <= 0) 
    { 
     return false; 
    } 

    extra_part_size_in_sectors = (MIN_EXTRA_PART_SIZE + bytes_per_track - 1)/bytes_per_track; 
    main_part_size_in_sectors = ((main_part_size_in_sectors/geometry.Geometry.SectorsPerTrack) - 
            extra_part_size_in_sectors) * geometry.Geometry.SectorsPerTrack; 
    if (main_part_size_in_sectors <= 0) 
    { 
     return false; 
    } 

    driveLayoutEx.PartitionEntry[0].PartitionLength = 1024 * 1024 * 1024 * (long)20; 
    driveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE.PARTITION_STYLE_MBR; 
    driveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x80; 
    driveLayoutEx.PartitionEntry[0].Mbr.BootIndicator = true; 
    driveLayoutEx.PartitionEntry[0].PartitionNumber = 1; 
    driveLayoutEx.PartitionEntry[0].RewritePartition = true; 
    driveLayoutEx.PartitionEntry[0].Mbr.RecognizedPartition = true; 


    driveLayoutEx.PartitionStyle = PARTITION_STYLE.PARTITION_STYLE_MBR; 
    driveLayoutEx.PartitionCount = 1; //It should be a multiple of 4 
    driveLayoutEx.Mbr.Mbr.Signature = createDisk.Mbr.Signature; 
    Marshal.StructureToPtr(driveLayoutEx, driveLayoutbuffer, false); 

    result = DeviceIoControl(handle, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, driveLayoutbuffer, 192, IntPtr.Zero, 0, ref size, IntPtr.Zero); 
    result = DeviceIoControl(handle, IOCTL_DISK_UPDATE_PROPERTIES, IntPtr.Zero, 0, IntPtr.Zero, 0, ref size, IntPtr.Zero); 

    Marshal.FreeHGlobal(driveLayoutbuffer); 
    Marshal.FreeHGlobal(createDiskBuffer); 

    Marshal.FreeHGlobal(lpOutBuffer); 

    return true; 
} 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, 
    uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, 
    uint dwFlagsAndAttributes, IntPtr hTemplateFile); 

[DllImport("kernel32")] 
static extern int CloseHandle(IntPtr handle); 


[DllImport("kernel32")] 
private static extern int DeviceIoControl 
    (IntPtr deviceHandle, uint ioControlCode, 
     IntPtr inBuffer, int inBufferSize, 
     IntPtr outBuffer, int outBufferSize, 
     ref int bytesReturned, IntPtr overlapped); 

public const uint GENERIC_READ = 0x80000000; 
public const uint GENERIC_WRITE = 0x40000000; 
public const uint FILE_SHARE_READ = 0x00000001; 
public const uint FILE_SHARE_WRITE = 0x00000002; 
public const uint OPEN_EXISTING = 0x00000003; 
public const uint FILE_ATTRIBUTE_NORMAL = 0x80; 
public const uint FSCTL_ALLOW_EXTENDED_DASD_IO = 0x90083; 
public const int DRIVE_ACCESS_RETRIES = 10; 
public const int DRIVE_ACCESS_TIMEOUT = 15000; 
public const uint FSCTL_LOCK_VOLUME = 0x00090018; 
static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); 
public const uint IOCTL_DISK_GET_DRIVE_LAYOUT_EX = 0x00070050; 
public const uint IOCTL_DISK_GET_DRIVE_GEOMETRY_EX = 0x000700A0; 
public const uint IOCTL_DISK_CREATE_DISK = 0x0007C058; 
public const uint IOCTL_DISK_UPDATE_PROPERTIES = 0x00070140; 
public const uint IOCTL_DISK_SET_DRIVE_LAYOUT_EX = 0x0007C054; 
public const int MIN_EXTRA_PART_SIZE = 1024 * 1024; 
public static int mediaType = 0; 
[DllImport("kernel32.dll", EntryPoint = "RtlFillMemory", SetLastError = false)] 
public static extern void FillMemory(IntPtr destination, uint length, byte fill); 

/// <summary> 
/// Describes the geometry of disk devices and media. 
/// </summary> 
[StructLayout(LayoutKind.Explicit)] 
public struct DISK_GEOMETRY 
{ 
    /// <summary> 
    /// The number of cylinders. 
    /// </summary> 
    [FieldOffset(0)] 
    public Int64 Cylinders; 

    /// <summary> 
    /// The type of media. For a list of values, see MEDIA_TYPE. 
    /// </summary> 
    [FieldOffset(8)] 
    public MEDIA_TYPE MediaType; 

    /// <summary> 
    /// The number of tracks per cylinder. 
    /// </summary> 
    [FieldOffset(12)] 
    public uint TracksPerCylinder; 

    /// <summary> 
    /// The number of sectors per track. 
    /// </summary> 
    [FieldOffset(16)] 
    public uint SectorsPerTrack; 

    /// <summary> 
    /// The number of bytes per sector. 
    /// </summary> 
    [FieldOffset(20)] 
    public uint BytesPerSector; 
} 


public enum MEDIA_TYPE 
{ 
    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 
} 

/// <summary> 
/// Describes the extended geometry of disk devices and media. 
/// </summary> 
    [StructLayout(LayoutKind.Explicit)] 
private struct DISK_GEOMETRY_EX 
{ 
    /// <summary> 
    /// A DISK_GEOMETRY structure. 
    /// </summary> 
    [FieldOffset(0)] 
    public DISK_GEOMETRY Geometry; 

    /// <summary> 
    /// The disk size, in bytes. 
    /// </summary> 
    [FieldOffset(24)] 
    public Int64 DiskSize; 

    /// <summary> 
    /// Any additional data. 
    /// </summary> 
    [FieldOffset(32)] 
    public Byte Data; 
} 



/// <summary> 
/// Represents the format of a partition. 
/// </summary> 
public enum PARTITION_STYLE : uint 
{ 
    /// <summary> 
    /// Master boot record (MBR) format. 
    /// </summary> 
    PARTITION_STYLE_MBR = 0, 

    /// <summary> 
    /// GUID Partition Table (GPT) format. 
    /// </summary> 
    PARTITION_STYLE_GPT = 1, 

    /// <summary> 
    /// Partition not formatted in either of the recognized formats—MBR or GPT. 
    /// </summary> 
    PARTITION_STYLE_RAW = 2 
} 

/// <summary> 
/// Contains partition information specific to master boot record (MBR) disks. 
/// </summary> 
[StructLayout(LayoutKind.Explicit)] 
public struct PARTITION_INFORMATION_MBR 
{ 
    #region Constants 
    /// <summary> 
    /// An unused entry partition. 
    /// </summary> 
    public const byte PARTITION_ENTRY_UNUSED = 0x00; 

    /// <summary> 
    /// A FAT12 file system partition. 
    /// </summary> 
    public const byte PARTITION_FAT_12 = 0x01; 

    /// <summary> 
    /// A FAT16 file system partition. 
    /// </summary> 
    public const byte PARTITION_FAT_16 = 0x04; 

    /// <summary> 
    /// An extended partition. 
    /// </summary> 
    public const byte PARTITION_EXTENDED = 0x05; 

    /// <summary> 
    /// An IFS partition. 
    /// </summary> 
    public const byte PARTITION_IFS = 0x07; 

    /// <summary> 
    /// A FAT32 file system partition. 
    /// </summary> 
    public const byte PARTITION_FAT32 = 0x0B; 

    /// <summary> 
    /// A logical disk manager (LDM) partition. 
    /// </summary> 
    public const byte PARTITION_LDM = 0x42; 

    /// <summary> 
    /// An NTFT partition. 
    /// </summary> 
    public const byte PARTITION_NTFT = 0x80; 

    /// <summary> 
    /// A valid NTFT partition. 
    /// 
    /// The high bit of a partition type code indicates that a partition is part of an NTFT mirror or striped array. 
    /// </summary> 
    public const byte PARTITION_VALID_NTFT = 0xC0; 
    #endregion 

    /// <summary> 
    /// The type of partition. For a list of values, see Disk Partition Types. 
    /// </summary> 
    [FieldOffset(0)] 
    [MarshalAs(UnmanagedType.U1)] 
    public byte PartitionType; 

    /// <summary> 
    /// If this member is TRUE, the partition is bootable. 
    /// </summary> 
    [FieldOffset(1)] 
    [MarshalAs(UnmanagedType.I1)] 
    public bool BootIndicator; 

    /// <summary> 
    /// If this member is TRUE, the partition is of a recognized type. 
    /// </summary> 
    [FieldOffset(2)] 
    [MarshalAs(UnmanagedType.I1)] 
    public bool RecognizedPartition; 

    /// <summary> 
    /// The number of hidden sectors in the partition. 
    /// </summary> 
    [FieldOffset(4)] 
    public uint HiddenSectors; 
} 

/// <summary> 
/// Contains GUID partition table (GPT) partition information. 
/// </summary> 
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)] 
public struct PARTITION_INFORMATION_GPT 
{ 
    /// <summary> 
    /// A GUID that identifies the partition type. 
    /// 
    /// Each partition type that the EFI specification supports is identified by its own GUID, which is 
    /// published by the developer of the partition. 
    /// </summary> 
    [FieldOffset(0)] 
    public Guid PartitionType; 

    /// <summary> 
    /// The GUID of the partition. 
    /// </summary> 
    [FieldOffset(16)] 
    public Guid PartitionId; 

    /// <summary> 
    /// The Extensible Firmware Interface (EFI) attributes of the partition. 
    /// 
    /// </summary> 
    [FieldOffset(32)] 
    public UInt64 Attributes; 

    /// <summary> 
    /// A wide-character string that describes the partition. 
    /// </summary> 
    [FieldOffset(40)] 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 36)] 
    public string Name; 
} 
/// <summary> 
/// Provides information about a drive's master boot record (MBR) partitions. 
/// </summary> 
[StructLayout(LayoutKind.Explicit)] 
private struct DRIVE_LAYOUT_INFORMATION_MBR 
{ 
    /// <summary> 
    /// The signature of the drive. 
    /// </summary> 
    [FieldOffset(0)] 
    public uint Signature; 
} 

/// <summary> 
/// Contains information about a drive's GUID partition table (GPT) partitions. 
/// </summary> 
[StructLayout(LayoutKind.Explicit)] 
private struct DRIVE_LAYOUT_INFORMATION_GPT 
{ 
    /// <summary> 
    /// The GUID of the disk. 
    /// </summary> 
    [FieldOffset(0)] 
    public Guid DiskId; 

    /// <summary> 
    /// The starting byte offset of the first usable block. 
    /// </summary> 
    [FieldOffset(16)] 
    public Int64 StartingUsableOffset; 

    /// <summary> 
    /// The size of the usable blocks on the disk, in bytes. 
    /// </summary> 
    [FieldOffset(24)] 
    public Int64 UsableLength; 

    /// <summary> 
    /// The maximum number of partitions that can be defined in the usable block. 
    /// </summary> 
    [FieldOffset(32)] 
    public uint MaxPartitionCount; 
} 


/// <summary> 
/// Contains information about a disk partition. 
/// </summary> 
[StructLayout(LayoutKind.Explicit)] 
public struct PARTITION_INFORMATION_EX 
{ 
    /// <summary> 
    /// The format of the partition. For a list of values, see PARTITION_STYLE. 
    /// </summary> 
    [FieldOffset(0)] 
    public PARTITION_STYLE PartitionStyle; 

    /// <summary> 
    /// The starting offset of the partition. 
    /// </summary> 
    [FieldOffset(8)] 
    public Int64 StartingOffset; 

    /// <summary> 
    /// The length of the partition, in bytes. 
    /// </summary> 
    [FieldOffset(16)] 
    public Int64 PartitionLength; 

    /// <summary> 
    /// The number of the partition (1-based). 
    /// </summary> 
    [FieldOffset(24)] 
    public uint PartitionNumber; 

    /// <summary> 
    /// If this member is TRUE, the partition information has changed. When you change a partition (with 
    /// IOCTL_DISK_SET_DRIVE_LAYOUT), the system uses this member to determine which partitions have changed 
    /// and need their information rewritten. 
    /// </summary> 
    [FieldOffset(28)] 
    [MarshalAs(UnmanagedType.I1)] 
    public bool RewritePartition; 

    /// <summary> 
    /// A PARTITION_INFORMATION_MBR structure that specifies partition information specific to master boot 
    /// record (MBR) disks. The MBR partition format is the standard AT-style format. 
    /// </summary> 
    [FieldOffset(32)] 
    public PARTITION_INFORMATION_MBR Mbr; 

    /// <summary> 
    /// A PARTITION_INFORMATION_GPT structure that specifies partition information specific to GUID partition 
    /// table (GPT) disks. The GPT format corresponds to the EFI partition format. 
    /// </summary> 
    [FieldOffset(32)] 
    public PARTITION_INFORMATION_GPT Gpt; 
} 


[StructLayout(LayoutKind.Explicit)] 
private struct DRIVE_LAYOUT_INFORMATION_UNION 
{ 
    [FieldOffset(0)] 
    public DRIVE_LAYOUT_INFORMATION_MBR Mbr; 

    [FieldOffset(0)] 
    public DRIVE_LAYOUT_INFORMATION_GPT Gpt; 
} 

/// <summary> 
/// Contains extended information about a drive's partitions. 
/// </summary> 
[StructLayout(LayoutKind.Explicit)] 
private struct DRIVE_LAYOUT_INFORMATION_EX 
{ 
    /// <summary> 
    /// The style of the partitions on the drive enumerated by the PARTITION_STYLE enumeration. 
    /// </summary> 
    [FieldOffset(0)] 
    public PARTITION_STYLE PartitionStyle; 

    /// <summary> 
    /// The number of partitions on a drive. 
    /// 
    /// On disks with the MBR layout, this value is always a multiple of 4. Any partitions that are unused have 
    /// a partition type of PARTITION_ENTRY_UNUSED. 
    /// </summary> 
    [FieldOffset(4)] 
    public uint PartitionCount; 

    /// <summary> 
    /// A DRIVE_LAYOUT_INFORMATION_MBR structure containing information about the master boot record type 
    /// partitioning on the drive. 
    /// </summary> 
    [FieldOffset(8)] 
    public DRIVE_LAYOUT_INFORMATION_UNION Mbr; 

    /// <summary> 
    /// A DRIVE_LAYOUT_INFORMATION_GPT structure containing information about the GUID disk partition type 
    /// partitioning on the drive. 
    /// </summary> 
    // [FieldOffset(8)] 
    //public DRIVE_LAYOUT_INFORMATION_GPT Gpt; 

    /// <summary> 
    /// A variable-sized array of PARTITION_INFORMATION_EX structures, one structure for each partition on the 
    /// drive. 
    /// </summary> 
    [FieldOffset(48)] 
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)] 
    public PARTITION_INFORMATION_EX[] PartitionEntry; 

} 

[StructLayout(LayoutKind.Explicit)] 
private struct CREATE_DISK_MBR 
{ 
    [FieldOffset(0)] 
    public uint Signature; 
} 

[StructLayout(LayoutKind.Explicit)] 
private struct CREATE_DISK_GPT 
{ 
    [FieldOffset(0)] 
    public Guid DiskId; 

    [FieldOffset(16)] 
    public uint MaxPartitionCount; 
} 

[StructLayout(LayoutKind.Explicit)] 
private struct CREATE_DISK 
{ 
    [FieldOffset(0)] 
    public PARTITION_STYLE PartitionStyle; 

    [FieldOffset(4)] 
    public CREATE_DISK_MBR Mbr; 

    [FieldOffset(4)] 
    public CREATE_DISK_GPT Gpt; 
} 


static IntPtr GetHandle(int driveIndex, string physicalName) 
{ 
    IntPtr handle; 
    //bool locked = false; 

    Console.WriteLine(physicalName); 

    handle = CreateFile(physicalName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 
       IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); 

    if (handle == INVALID_HANDLE_VALUE) 
    { 
     Console.WriteLine(Marshal.GetLastWin32Error()); 
     return IntPtr.Zero; 
    } 
    return handle; 
} 

答えて

0

パーティションは任意のFSでフォーマットできます。以下のためのこれはあなたがfmifs.dllを使用することができない - 彼エクスポート機能あなたはフォーマットのためにそれを使用することができます

VOID WINAPI FormatEx(PWSTR DriveRoot, 
        FMIFS_MEDIA_TYPE MediaType, 
        PWSTR FileSystemName, // L"NTFS" 
        PWSTR VolumeLabel, // OPTIONAL 
        BOOL QuickFormat, 
        DWORD ClusterSize, // 0 - default cluster size 
        PFMIFSCALLBACK Callback); 

。 C++のコード例:

// 
// Callback command types 
// 
enum CALLBACKCOMMAND { 
    PROGRESS, 
    DONEWITHSTRUCTURE, 
    UNKNOWN2, 
    UNKNOWN3, 
    UNKNOWN4, 
    UNKNOWN5, 
    INSUFFICIENTRIGHTS, 
    UNKNOWN7, 
    UNKNOWN8, 
    UNKNOWN9, 
    UNKNOWNA, 
    DONE, // format OK! 
    UNKNOWNC, 
    UNKNOWND, 
    OUTPUT, 
    STRUCTUREPROGRESS 
}; 

// 
// FMIFS callback definition 
// 
typedef BOOLEAN (WINAPI *PFMIFSCALLBACK)(CALLBACKCOMMAND Command, DWORD SubAction, PVOID ActionInfo); 

enum FMIFS_MEDIA_TYPE { 
    Unknown = MEDIA_TYPE::Unknown,     // Format is unknown 
    RemovableMedia = MEDIA_TYPE::RemovableMedia,  // Removable media other than floppy 
    FixedMedia = MEDIA_TYPE::FixedMedia,    // Fixed hard disk media 
}; 

ULONG g_dwTlsIndex; 

struct FORMAT_DATA 
{ 
    BOOLEAN fOk; 
}; 

BOOLEAN FormatCb(CALLBACKCOMMAND Command, DWORD SubAction, PVOID ActionInfo) 
{ 
    DbgPrint("FormatCb(%u, %x, %p)\n", Command, SubAction, ActionInfo); 
    FORMAT_DATA* fd = (FORMAT_DATA*)TlsGetValue(g_dwTlsIndex); 
    if (Command == DONE) 
    { 
     fd->fOk = TRUE; 
    } 
    return TRUE; 
} 

BOOL TryFormat() 
{ 
    FORMAT_DATA fd; 
    fd.fOk = FALSE; 

    if ((g_dwTlsIndex = TlsAlloc()) != TLS_OUT_OF_INDEXES) 
    { 
     if (HMODULE hmod = LoadLibrary(L"fmifs")) 
     { 
      VOID (WINAPI * FormatEx)(PWSTR DriveRoot, 
       FMIFS_MEDIA_TYPE MediaType, 
       PWSTR FileSystemName, 
       PWSTR VolumeLabel, 
       BOOL QuickFormat, 
       DWORD ClusterSize, 
       PFMIFSCALLBACK Callback); 

      *(void**)&FormatEx = GetProcAddress(hmod, "FormatEx"); 

      if (FormatEx) 
      { 
       TlsSetValue(g_dwTlsIndex, &fd); 
       FormatEx(L"e:", RemovableMedia, L"NTFS", L"SomeLabel", TRUE, 512, FormatCb); 
      } 

      FreeLibrary(hmod); 
     } 

     TlsFree(g_dwTlsIndex); 
    } 

    return fd.fOk; 
} 
0

あなたがサポートAPIを使用したいと仮定すると、私は、WindowsのバージョンによってVirtual Disk ServiceまたはWindows Storage Management Providerのいずれかが必要であると考えています。

私の知る限り、パーティションをフォーマットするためのI/O制御コードはありません。これは、フォーマットコードがファイルシステムドライバの一部である必要があるため、常に(仮想)メモリに格納されるため、非常に頻繁に使用される機能には非効率です。

+0

も参照してください。http://stackoverflow.com/a/39624261/886887 –

関連する問題