Well, I now need to make the partition as 'Active' for finish the boot module from the WinUSB Maker. The problem is: I need to support Windows XP, and the most obviously way was use the DISKPART, but Windows XP does not want to recognize USB Drives around that... I was looking around and we can do it using DeviceIoControl P/invoke around IoWrapper.dll from Win7 USB Tool from Microsoft. This DLL is unmanaged and I understand ZERO from Visual C++. I need of help now. I want to do it natively from C#. Can anyone understand these C++ code and able to convert to C# method? The source of the IoWrapper.dll are above, some that solve the problem here from : SOLVED: ******************************************************************************************** http://forums.mydigitallife.net/thr...tion-as-active?p=765292&viewfull=1#post765411 ******************************************************************************************** .....
Maybe you can work from this? Code: private int SetActivePartition(string selectedDrive) { int hr = S_OK; int bSuccess = 0; uint dwBytesReturned = 0; System.IntPtr hDisk = OpenDiskHandle(selectedDrive); if (hDisk == null || INVALID_HANDLE_VALUE == hDisk) { hr = GetLastError(); ExitOnFailure(hr, "Unable to get handle to disk."); } // Get the partition information byte[] Buffer = new byte[sizeof(DRIVE_LAYOUT_INFORMATION_EX) + 3 * sizeof(PARTITION_INFORMATION_EX)]; bSuccess = DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, null, 0, Buffer, sizeof(byte), dwBytesReturned, null); if (bSuccess == 0 || dwBytesReturned != sizeof(byte)) { hr = GetLastError(); ExitOnFailure(hr, "Unable to read partition information."); } // Set bootable flag and rewrite the partition if needed. DRIVE_LAYOUT_INFORMATION_EX pDriveLayout = (DRIVE_LAYOUT_INFORMATION_EX)Buffer; if (!pDriveLayout.PartitionEntry[0].Mbr.BootIndicator) { pDriveLayout.PartitionEntry[0].Mbr.BootIndicator = 1; pDriveLayout.PartitionEntry[0].RewritePartition = 1; bSuccess = DeviceIoControl(hDisk, IOCTL_DISK_SET_DRIVE_LAYOUT_EX, pDriveLayout, sizeof(DRIVE_LAYOUT_INFORMATION_EX) + 3 * sizeof(PARTITION_INFORMATION_EX), null, 0, dwBytesReturned, null); if (bSuccess == 0) { hr = GetLastError(); ExitOnFailure(hr, "Unable to write partition information."); } } LExit: if (null != hDisk && INVALID_HANDLE_VALUE != hDisk) { CloseHandle(hDisk); } return hr; Code: private System.IntPtr OpenDiskHandle(string rootPath) { int hr; System.IntPtr hDisk = INVALID_HANDLE_VALUE; string drivePath = null; // CreateFile requires a file name in the format '\\.\X:' instead of 'X:\' hr = StrAllocString(drivePath, "\\\\.\\", 6); ExitOnFailure(hr, "Unable to allocate drive path string."); hr = StrAllocConcat(drivePath, rootPath, 2); ExitOnFailure(hr, "Unable to concatenate drive path string."); // Open handle to disk hDisk = CreateFile(drivePath, GENERIC_EXECUTE | GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, null); LExit: ReleaseNullStr(drivePath); if (hr != S_OK) { SetLastError(hr); } return hDisk; }
@The Dev I also have converted some code to C# using a tool but I can not understand some hard things that has many structs, enums.....
I have found this class around MSDN blog: SOLVED: ******************************************************************************************** http://forums.mydigitallife.net/thr...tion-as-active?p=765292&viewfull=1#post765411 ******************************************************************************************** It now are looking a bit easier, I will try to pass the correct flags and see if it will work...
I have worked a bit but still it is not working: SOLVED: ************************************************** ****************************************** http://forums.mydigitallife.net/thr...tion-as-active?p=765411&viewfull=1#post765411 ************************************************** ****************************************** It runs fine but no change around the partition (is not setting up to Active).... Any ideas?
Ok guys, I have worked some hours today and here is the method working as well: Code: /* * IOWrapper C# class by Michel Oliveira. * 2013/06/18 * www.joshcellsoftwares.com GPL License. */ namespace PartitionWrapper { using System; using System.Diagnostics; using System.Windows.Forms; using System.Runtime.InteropServices; public class IOWrapper { public static bool SetActivePartition(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; } // 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; } if (!pDriveLayout.PartitionEntry[0].Mbr.BootIndicator) { pDriveLayout.PartitionEntry[0].PartitionStyle = FSStructures.PARTITION_STYLE.MasterBootRecord; pDriveLayout.PartitionEntry[0].Mbr.BootIndicator = true; pDriveLayout.PartitionEntry[0].RewritePartition = true; { pDriveLayoutPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pDriveLayout)); Marshal.StructureToPtr(pDriveLayout, pDriveLayoutPtr, false); } bSuccess = FSStructures.DeviceIoControl(hDisk, FSConstants.IOCTL_DISK_SET_DRIVE_LAYOUT_EX, pDriveLayoutPtr, PartitionInfomations, 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; } internal static class FSStructures { [DllImport("kernel32.dll", 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] 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 } } } } USAGE: Code: PartitionWrapper.IOWrapper.SetActivePartition("K:"); //Where K: is your partition to make as active. I hope it will solve that. There is no solid method like that around the internet for .NET languages... See you soon.