Пример #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DevicePartition"/> class.
        /// </summary>
        /// <param name="partititonInformation">The partititon information.</param>
        internal DevicePartition(PARTITION_INFORMATION_EX partititonInformation)
        {
            this.PartitionStyle = partititonInformation.PartitionStyle.ConvertToString();
            this.StartingOffset = partititonInformation.StartingOffset;
            this.PartitionLength = partititonInformation.PartitionLength;
            this.Number = Convert.ToInt32(partititonInformation.PartitionNumber);

            switch(partititonInformation.PartitionStyle)
            {
                case PARTITION_STYLE.PARTITION_STYLE_MBR:
                    this.BootIndicator = partititonInformation.DriveLayoutInformaiton.Mbr.BootIndicator;
                    this.PartitionType = partititonInformation.DriveLayoutInformaiton.Mbr.PartitionType.ConvertToString();
                    this.HiddenSectors = Convert.ToInt32(partititonInformation.DriveLayoutInformaiton.Mbr.HiddenSectors);
                    break;
                case PARTITION_STYLE.PARTITION_STYLE_GPT:
                    this.Name = partititonInformation.DriveLayoutInformaiton.Gpt.Name;
                    this.GptId = partititonInformation.DriveLayoutInformaiton.Gpt.PartitionId;
                    this.GptPartitionType = partititonInformation.DriveLayoutInformaiton.Gpt.PartitionType;
                    this.GptAttributes = Convert.ToInt64(partititonInformation.DriveLayoutInformaiton.Gpt.Attributes);
                    break;
                case PARTITION_STYLE.PARTITION_STYLE_RAW:
                    break;
            }
        }
Пример #2
0
        /// <summary>
        /// Gets the drive layout.
        /// This is special case DeviceIoControl call. The <see cref="DRIVE_LAYOUT_INFORMATION_EX"/> contains dynamic array
        /// </summary>
        /// <param name="device">The device to query</param>
        /// <remarks>Code was taken from: http://brianhehir.blogspot.co.il/2011/12/kernel32dll-deviceiocontrol-in-c.html </remarks>
        /// <returns><c>Tuple</c> of <see cref="DRIVE_LAYOUT_INFORMATION_EX"/> and array of <see cref="PARTITION_INFORMATION_EX"/></returns>
        internal Tuple <DRIVE_LAYOUT_INFORMATION_EX, PARTITION_INFORMATION_EX[]> GetDriveLayout(DeviceHandle device)
        {
            bool   functionResult = false;
            IntPtr ptrInputData   = IntPtr.Zero;

            int numberOfExpectedPartitions = 1;

            // 48 = the number of bytes in DRIVE_LAYOUT_INFORMATION_EX up to
            // the first PARTITION_INFORMATION_EX in the array.
            // And each PARTITION_INFORMATION_EX is 144 bytes.
            var structureSize   = 48 + (numberOfExpectedPartitions * 144);
            int lpBytesReturned = 0;
            NativeOverlapped nativeOverlapped = new NativeOverlapped();
            int win32Error = 0;

            try
            {
                // First try
                ptrInputData = Marshal.AllocHGlobal(structureSize);

                while (functionResult == false)
                {
                    lock (lockMe)
                    {
                        IntPtr handle = device.OpenDeviceHandle();

                        functionResult = UnsafeNativeMethods.DeviceIoControl(handle,
                                                                             IoControlCode.IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
                                                                             IntPtr.Zero,
                                                                             0,
                                                                             ptrInputData,
                                                                             structureSize,
                                                                             ref lpBytesReturned,
                                                                             ref nativeOverlapped);

                        win32Error = Marshal.GetLastWin32Error();

                        device.CloseDeviceHandle();
                    }

                    if (functionResult == false)
                    {
                        if (win32Error == UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
                        {
                            Marshal.FreeHGlobal(ptrInputData);
                            checked
                            {
                                numberOfExpectedPartitions++;
                                structureSize = 48 + (numberOfExpectedPartitions * 144);
                            }
                            ptrInputData = Marshal.AllocHGlobal(structureSize);
                        }
                        else
                        {
                            throw new Win32Exception("Could not acquire information from windows kernel.", new Win32Exception(win32Error));
                        }
                    }
                }

                DRIVE_LAYOUT_INFORMATION_EX driveLayoutInfo = default(DRIVE_LAYOUT_INFORMATION_EX);
                driveLayoutInfo = (DRIVE_LAYOUT_INFORMATION_EX)Marshal.PtrToStructure(ptrInputData, typeof(DRIVE_LAYOUT_INFORMATION_EX));

                PARTITION_INFORMATION_EX[] partititons = new PARTITION_INFORMATION_EX[driveLayoutInfo.PartitionCount];
                for (int iCounter = 0; iCounter < partititons.Length; iCounter++)
                {
                    IntPtr partitionOffset = new IntPtr(ptrInputData.ToInt64() + 48 + (iCounter * 144));
                    partititons[iCounter] = (PARTITION_INFORMATION_EX)Marshal.PtrToStructure(partitionOffset, typeof(PARTITION_INFORMATION_EX));
                }

                return(new Tuple <DRIVE_LAYOUT_INFORMATION_EX, PARTITION_INFORMATION_EX[]>(driveLayoutInfo, partititons));
            }
            catch (Exception exp_gen)
            {
                throw new Win32Exception("Exception occurred while trying to work with Windows kernel", exp_gen);
            }
            finally
            {
                Marshal.FreeHGlobal(ptrInputData);
            }
        }