CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Dec 2014
    Posts
    8

    Not able to create More than 1 Partition in USB Drive using kernel32 and DeviceIoCont

    I have successfully created 2 or more partitions in USB drive using DeviceIoControl in C++. Now I am trying to convert this code into C# using kernel32 and DeviceIoControl. But I am not getting more than 1 partition. Can anybody tell me what is wrong with this code?

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    namespace PartitionWrapper
    {
       
    
        public class IOWrapper
        {
            public static bool CreatePartitions(string selectedDrive)
            {
                bool RetCode = false;
    
                try
                {
                    bool bSuccess = false;
                    uint dwBytesReturned = 0;
    
                    IntPtr hDisk = OpenVolume(selectedDrive);
                    if (hDisk == null || hDisk == FSConstants.INVALID_HANDLE_VALUE)
                    {
                        RetCode = false;
                        goto FINAL;
                    }
    
                    bSuccess = FSStructures.DeviceIoControl(hDisk, FSConstants.IOCTL_DISK_DELETE_DRIVE_LAYOUT, IntPtr.Zero, 0, default(IntPtr), default(uint), ref dwBytesReturned);
    
                    // Get the partition information
                    uint PartitionInfomations = (uint)(Marshal.SizeOf(typeof(FSStructures.DRIVE_LAYOUT_INFORMATION_EX)) + 3 * Marshal.SizeOf(typeof(FSStructures.PARTITION_INFORMATION_EX)));
                    byte[] DBuffer = new byte[PartitionInfomations];
    
                    GCHandle handle = GCHandle.Alloc(DBuffer, GCHandleType.Pinned);
    
                    FSStructures.DRIVE_LAYOUT_INFORMATION_EX pDriveLayout = (FSStructures.DRIVE_LAYOUT_INFORMATION_EX)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FSStructures.DRIVE_LAYOUT_INFORMATION_EX));
    
                    IntPtr pDriveLayoutPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pDriveLayout));
    
                    Marshal.StructureToPtr(pDriveLayout, pDriveLayoutPtr, false);
    
                    // bSuccess = FSStructures.DeviceIoControl(hDisk, FSConstants.IOCTL_DISK_GET_DRIVE_LAYOUT_EX, default(IntPtr), default(uint), pDriveLayoutPtr, PartitionInfomations, ref dwBytesReturned);
    
                    pDriveLayout = (FSStructures.DRIVE_LAYOUT_INFORMATION_EX)Marshal.PtrToStructure(pDriveLayoutPtr, typeof(FSStructures.DRIVE_LAYOUT_INFORMATION_EX));
    
                    if (bSuccess || dwBytesReturned != PartitionInfomations)
                    {
                        RetCode = true;
                    }
                    else { RetCode = false; goto FINAL; }
                    pDriveLayout.PartitionEntry = new FSStructures.PARTITION_INFORMATION_EX[0x16];
                    pDriveLayout.PartitionStyle = FSStructures.PARTITION_STYLE.MasterBootRecord;
                    pDriveLayout.PartitionCount = 4;
                    pDriveLayout.DriveLayoutInformatiton.Mbr.Signature = 0xA4B57300;
    
    
    
                    pDriveLayout.PartitionEntry[0] = new FSStructures.PARTITION_INFORMATION_EX();
                    pDriveLayout.PartitionEntry[0].PartitionStyle = FSStructures.PARTITION_STYLE.MasterBootRecord;
                    pDriveLayout.PartitionEntry[0].Mbr.BootIndicator = true;
                    pDriveLayout.PartitionEntry[0].Mbr.RecognizedPartition = true;
                    pDriveLayout.PartitionEntry[0].Mbr.PartitionType = 0x0B;
    
                    pDriveLayout.PartitionEntry[0].PartitionNumber = 1;
                    pDriveLayout.PartitionEntry[0].StartingOffset = 32256;
                    pDriveLayout.PartitionEntry[0].PartitionLength = 3221225472;
                    pDriveLayout.PartitionEntry[0].RewritePartition = true;
                    pDriveLayout.PartitionEntry[0].Mbr.HiddenSectors = 32256 / 512;
    
                    pDriveLayout.PartitionEntry[1] = new FSStructures.PARTITION_INFORMATION_EX();
                    pDriveLayout.PartitionEntry[1].PartitionStyle = FSStructures.PARTITION_STYLE.MasterBootRecord;
                    pDriveLayout.PartitionEntry[1].Mbr.BootIndicator = false;
                    pDriveLayout.PartitionEntry[1].Mbr.RecognizedPartition = true;
                    pDriveLayout.PartitionEntry[1].Mbr.PartitionType = 0x0B;
    
                    pDriveLayout.PartitionEntry[1].PartitionNumber = 2;
                    pDriveLayout.PartitionEntry[1].StartingOffset = 32256 + 3221225472;
                    pDriveLayout.PartitionEntry[1].PartitionLength = 2147483648; //2147483648;//3221225472;
                    pDriveLayout.PartitionEntry[1].RewritePartition = true;
                    pDriveLayout.PartitionEntry[1].Mbr.HiddenSectors = 32256 / 512;
    
    
                    for (int i = 0; i < pDriveLayout.PartitionEntry.Length; i++)
                    {
                        pDriveLayout.PartitionEntry[i].RewritePartition = true;
                    }
    
                    try
                    {
                        bSuccess = FSStructures.DeviceIoControl(hDisk, FSConstants.IOCTL_DISK_SET_DRIVE_LAYOUT_EX, ref pDriveLayout, PartitionInfomations, default(IntPtr), default(uint), ref dwBytesReturned);
                    }
                    catch (Exception ex)
                    {
    
                    }
    
                    if (bSuccess)
                    {
                        RetCode = true;
                    }
                    else { RetCode = false; }
    
                    bSuccess = FSStructures.DeviceIoControl(hDisk, FSConstants.IOCTL_DISK_UPDATE_PROPERTIES, IntPtr.Zero, 0, default(IntPtr), default(uint), ref dwBytesReturned);
                    if (bSuccess)
                    {
                        RetCode = true;
                    }
                    else { RetCode = false; }
    
                    //}
    
                FINAL:
    
                    // Close the disk handle.
                    if (hDisk != null && hDisk != FSConstants.INVALID_HANDLE_VALUE)
                    {
                        FSStructures.CloseHandle(hDisk);
                    }
                }
                catch { return false; }
    
                return RetCode;
            }
    
            private static IntPtr OpenVolume(string DeviceName)
            {
                try
                {
                    IntPtr hDevice;
                    hDevice = FSStructures.CreateFile(
                        @"\\.\" + DeviceName,
                        FSConstants.GENERIC_EXECUTE | FSConstants.GENERIC_READ | FSConstants.GENERIC_WRITE | FSConstants.FILE_SHARE_READ | FSConstants.FILE_SHARE_WRITE,
                        FSConstants.FILE_SHARE_WRITE,
                        IntPtr.Zero,
                        FSConstants.OPEN_EXISTING,
                        0,
                        IntPtr.Zero);
    
    
                    if ((int)hDevice == -1)
                    {
                        throw new Exception(Marshal.GetLastWin32Error().ToString());
                    }
    
                    return hDevice;
                }
                catch { return FSConstants.INVALID_HANDLE_VALUE; }
            }
    
            internal static class FSConstants
            {
    
                public const uint FILE_SHARE_READ = 0x00000001;
                public const uint FILE_SHARE_WRITE = 0x00000002;
                public const uint OPEN_EXISTING = 3;
                public const int GENERIC_EXECUTE = 0x10000000;
    
                public const uint GENERIC_READ = (0x80000000);
                public const uint GENERIC_WRITE = (0x40000000);
    
                public static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
    
                public const uint IOCTL_DISK_GET_DRIVE_LAYOUT_EX = 0x00070050;
    
                public const uint IOCTL_DISK_SET_DRIVE_LAYOUT_EX = 0x7C054;
    
                public const int IOCTL_DISK_UPDATE_PROPERTIES = 0x70140;
                public const int IOCTL_DISK_DELETE_DRIVE_LAYOUT = 0x0007c010;
                public const int IOCTL_DISK_CREATE_DISK = 0x7C058;
    
            }
    
            internal static class FSStructures
            {
    
                [DllImport("kernel32.dll", EntryPoint = "CreateFile", SetLastError = true)]
                public static extern IntPtr CreateFile(
                    string lpFileName,
                    uint dwDesiredAccess,
                    uint dwShareMode,
                    IntPtr lpSecurityAttributes,
                    uint dwCreationDisposition,
                    uint dwFlagsAndAttributes,
                    IntPtr hTemplateFile);
    
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern int CloseHandle(IntPtr hObject);
    
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern bool DeviceIoControl(
                    IntPtr hDevice,
                    uint dwIoControlCode,
                     [Optional]ref DRIVE_LAYOUT_INFORMATION_EX lpInBuffer,
                    uint nInBufferSize,
                    [Optional] [Out] IntPtr lpOutBuffer,
                    uint nOutBufferSize,
                    [Optional] ref uint lpBytesReturned,
                    [Optional] IntPtr lpOverlapped);
    
    
                [DllImport("kernel32.dll", SetLastError = true)]
                public static extern bool DeviceIoControl(
                    IntPtr hDevice,
                    uint dwIoControlCode,
                     IntPtr lpInBuffer,
                    uint nInBufferSize,
                    [Optional] [Out] IntPtr lpOutBuffer,
                    uint nOutBufferSize,
                    [Optional] ref uint lpBytesReturned,
                    [Optional] IntPtr lpOverlapped);
    
                
                [StructLayout(LayoutKind.Sequential)]
                public struct DRIVE_LAYOUT_INFORMATION_EX
                {
                    public PARTITION_STYLE PartitionStyle;
                    public int PartitionCount;
                    public DRIVE_LAYOUT_INFORMATION_UNION DriveLayoutInformatiton;
                    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 0x16)]
                    public PARTITION_INFORMATION_EX[] PartitionEntry;
                }
    
                [StructLayout(LayoutKind.Sequential)]
                public struct PARTITION_INFORMATION_EX
                {
                    [MarshalAs(UnmanagedType.U4)]
                    public PARTITION_STYLE PartitionStyle;
                    public long StartingOffset;
                    public long PartitionLength;
                    public int PartitionNumber;
                    public bool RewritePartition;
                    public PARTITION_INFORMATION_MBR Mbr;
                    public PARTITION_INFORMATION_GPT Gpt;
                }
    
                [StructLayout(LayoutKind.Sequential)]
                public struct PARTITION_INFORMATION_MBR
                {
                    public byte PartitionType;
                    [MarshalAs(UnmanagedType.U1)]
                    public bool BootIndicator;
                    [MarshalAs(UnmanagedType.U1)]
                    public bool RecognizedPartition;
                    public uint HiddenSectors;
                }
    
    
                [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
                public struct PARTITION_INFORMATION_GPT
                {
                    public Guid PartitionType;
                    public Guid PartitionId;
                    [MarshalAs(UnmanagedType.U8)]
                    public EFIPartitionAttributes Attributes;
    
                    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 36)]
                    public string Name;
                }
    
                [Flags]
                public enum EFIPartitionAttributes : ulong
                {
                    GPT_ATTRIBUTE_PLATFORM_REQUIRED = 0x0000000000000001,
                    LegacyBIOSBootable = 0x0000000000000004,
                    GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER = 0x8000000000000000,
                    GPT_BASIC_DATA_ATTRIBUTE_HIDDEN = 0x4000000000000000,
                    GPT_BASIC_DATA_ATTRIBUTE_SHADOW_COPY = 0x2000000000000000,
                    GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY = 0x1000000000000000
                }
    
    
                [StructLayout(LayoutKind.Explicit)]
                public struct DRIVE_LAYOUT_INFORMATION_UNION
                {
                    [FieldOffset(0)]
                    public DRIVE_LAYOUT_INFORMATION_MBR Mbr;
    
                    [FieldOffset(0)]
                    public DRIVE_LAYOUT_INFORMATION_GPT Gpt;
                }
    
                [StructLayout(LayoutKind.Sequential)]
                public struct DRIVE_LAYOUT_INFORMATION_GPT
                {
    
                    public Guid DiskId;
    
                    public long StartingUsableOffset;
    
                    public long UsableLength;
    
                    public int MaxPartitionCount;
                }
    
                [StructLayout(LayoutKind.Sequential)]
                public struct DRIVE_LAYOUT_INFORMATION_MBR
                {
                    public uint Signature;
                }
    
                public enum PARTITION_STYLE : int
                {
                    MasterBootRecord = 0,
                    GuidPartitionTable = 1,
                    Raw = 2
                }
            }
        }
    }

  2. #2
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,283

    Re: Not able to create More than 1 Partition in USB Drive using kernel32 and DeviceIo

    What Operating system is this supposed to run on?

  3. #3
    Join Date
    Dec 2014
    Posts
    8

    Re: Not able to create More than 1 Partition in USB Drive using kernel32 and DeviceIo

    Quote Originally Posted by HanneSThEGreaT View Post
    What Operating system is this supposed to run on?
    I am using windows 8.1 Pro 64-bit and Visual Studio 2013

  4. #4
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,283

    Re: Not able to create More than 1 Partition in USB Drive using kernel32 and DeviceIo

    Does this work with C++ on WIndows 8.1? The reason I ask is I know there has been a lot of changes made on how to communicate with USB devices since Windows 7

  5. #5
    Join Date
    Dec 2014
    Posts
    8

    Re: Not able to create More than 1 Partition in USB Drive using kernel32 and DeviceIo

    Quote Originally Posted by HanneSThEGreaT View Post
    Does this work with C++ on WIndows 8.1? The reason I ask is I know there has been a lot of changes made on how to communicate with USB devices since Windows 7
    Yes, It is working. I am able to do up to four partitions in a USB. But the application is targeted to x86 platform

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured