Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DeviceIoControl来初始化和创建NTFS分区_C#_.net_Winapi_Deviceiocontrol - Fatal编程技术网

C# DeviceIoControl来初始化和创建NTFS分区

C# DeviceIoControl来初始化和创建NTFS分区,c#,.net,winapi,deviceiocontrol,C#,.net,Winapi,Deviceiocontrol,我正在尝试初始化磁盘并通过DeviceIOControl创建NTFS分区,而不使用DiskPart或WMI 使用下面的代码,我可以初始化磁盘并创建一个原始分区,但我无法调整参数,使新分区为NTFS 有什么想法吗 //Returns true if drive Index is successfully created //Returns false if not created successfully public static bool CreatePartition(int driveIn

我正在尝试初始化磁盘并通过DeviceIOControl创建NTFS分区,而不使用DiskPart或WMI

使用下面的代码,我可以初始化磁盘并创建一个原始分区,但我无法调整参数,使新分区为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;
}
//如果成功创建驱动器索引,则返回true
//如果未成功创建,则返回false
公共静态bool CreatePartition(int-driveIndex,string-physicalName)
{
IntPtr handle=GetHandle(driveIndex,physicalName);
if(句柄==无效的句柄值)
{
返回false;
}
//第2步:IOCTL\u DISK\u GET\u DRIVE\u GEOMETRY\u EX获取物理磁盘的几何图形(我们需要一些信息来填充分区数据)
//表面(或磁头,这是相同的东西)、圆柱体和扇区的数量变化很大;每个曲面(或磁头,这是相同的东西)、圆柱体和扇区的数量规格称为硬盘的几何图形。
//几何体通常存储在一个特殊的、电池供电的内存位置,称为CMOS RAM,在启动或驱动程序初始化期间,操作系统可以从该位置获取几何体。
int size=0;
DISK_GEOMETRY_EX GEOMETRY=新的DISK_GEOMETRY_EX();
IntPtr LPEXBUFFER=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DISK_GEOMETRY_EX));
Marshal.StructureToPtr(几何体,LPBuffer,false);
int result=DeviceIoControl(句柄、IOCTL\u磁盘\u GET\u驱动器\u几何体\u EX、IntPtr.Zero、0、lpextuffer、Marshal.SizeOf(typeof(DISK\u几何体\u EX))、ref size、IntPtr.Zero);
几何体=(DISK_geometry_EX)Marshal.PtrToStructure(lpburffer,typeof(DISK_geometry_EX));
//步骤3:IOCTL_DISK_CREATE_DISK用于初始化分区表为空的磁盘。
CREATE_DISK createDisk=新建CREATE_DISK();
createDisk.PartitionStyle=PARTITION\u STYLE.PARTITION\u STYLE\u MBR;
createDisk.Mbr.Signature=1;
IntPtr createDiskBuffer=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CREATE_DISK));
StructureToPtr(createDisk,createDiskBuffer,false);
byte[]arr1=新字节[Marshal.SizeOf(typeof(CREATE_DISK))];
Marshal.Copy(createDiskBuffer,arr1,0,Marshal.SizeOf(typeof(CREATE_DISK)));
结果=设备控制(句柄、IOCTL\U磁盘\U创建磁盘、createDiskBuffer、Marshal.SizeOf(类型(创建磁盘)),
IntPtr.Zero,0,参考大小,IntPtr.Zero);
结果=设备控制(句柄、IOCTL\u磁盘\u更新\u属性、IntPtr.Zero、0、IntPtr.Zero、0、ref size、IntPtr.Zero);
//步骤4:IOCTL\U DISK\U SET\U DRIVE\U LAYOU\U EX按照指定重新分区磁盘。
//注意:在IOCTL\u DISK\u CREATE\u DISK和IOCTL\u DISK\u SET\u DRIVE\u LAYOUT\u EX之后,使用IOCTL\u DISK\u UPDATE\u属性同步系统视图
/*DWORD driveLayoutSize=sizeof(驱动器布局信息)+sizeof(分区信息)*4*25;
驱动器布局信息驱动器布局信息新字节[driveLayoutSize]*/
IntPtr driveLayoutbuffer=Marshal.AllocHGlobal(192);
填充内存(driveLayoutbuffer,192,0);
驱动器布局信息驱动器布局信息=新驱动器布局信息驱动器布局信息;
driveLayoutEx.PartitionEntry=新分区信息[1];
mediaType=(int)geometry.geometry.mediaType;
Int64字节/U磁道=(geometry.geometry.SectorsPerTrack)*(geometry.geometry.BytesPerSector);
driveLayoutEx.PartitionEntry[0]。起始偏移量=0x0;
Int64主部分大小在扇区中,额外部分大小在扇区中=0;
主\u部分\u大小\u在\u扇区=(geometry.DiskSize-driveLayoutEx.PartitionEntry[0]。StartingOffset)/geometry.geometry.bytesperctor;

如果(主部分大小)扇区中的分区可以由任何FS格式化。为此,您可以使用导出功能

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;
}

假设您希望使用受支持的API,我相信您需要或,具体取决于Windows的版本

据我所知,没有用于格式化分区的I/O控制代码。这可能是因为这样做需要格式化代码成为文件系统驱动程序的一部分,这意味着它将始终位于(虚拟)内存中,这对于很少使用的功能来说是低效的