Beispiel #1
0
        /// <summary>
        /// <see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365194(v=vs.85).aspx" />
        /// </summary>
        public VOLUME_DISK_EXTENTS VolumeGetVolumeDiskExtents()
        {
            // Fetch in increments of 32 bytes, as one extent (the most common case) is one extent pr. volume.
            byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.VolumeGetVolumeDiskExtents, 32);

            // Build the VOLUME_DISK_EXTENTS structure
            VOLUME_DISK_EXTENTS res = new VOLUME_DISK_EXTENTS();

            res.NumberOfDiskExtents = BitConverter.ToUInt32(data, 0);
            res.Extents             = new DISK_EXTENT[res.NumberOfDiskExtents];

            using (UnmanagedMemory dataPtr = new UnmanagedMemory(data))
            {
                // TODO: This code needs to be tested for volumes with more than one extent.
                for (int i = 0; i < res.NumberOfDiskExtents; i++)
                {
                    IntPtr      currentDataPtr = new IntPtr(dataPtr.Handle.ToInt64() + 8 + i * MarshalHelper.SizeOf <DISK_EXTENT>());
                    DISK_EXTENT extent         = currentDataPtr.ToStructure <DISK_EXTENT>();

                    res.Extents[i] = extent;
                }
            }

            return(res);
        }
Beispiel #2
0
        public DISK_EXTENT[] ToStructure()
        {
            bool success = false;

            DangerousAddRef(ref success);
            if (!success)
            {
                throw new InvalidOperationException();
            }

            try {
                int           length     = Marshal.ReadInt32(handle);
                DISK_EXTENT[] extents    = new DISK_EXTENT[length];
                int           arrayElem  = Marshal.SizeOf(typeof(DISK_EXTENT));
                IntPtr        arrayStart = handle + 8;
                for (int i = 0; i < length; i++)
                {
                    extents[i]  = (DISK_EXTENT)Marshal.PtrToStructure(arrayStart, typeof(DISK_EXTENT));
                    arrayStart += arrayElem;
                }
                return(extents);
            } finally {
                DangerousRelease();
            }
        }
Beispiel #3
0
        /// <summary>
        /// Get volume disk extents for volumes that may or may not span more than one physical drive.
        /// </summary>
        /// <param name="devicePath">The device path of the volume.</param>
        /// <returns>An array of DiskExtent structures.</returns>
        /// <remarks></remarks>
        public static DiskExtent[] GetDiskExtentsFor(string devicePath)
        {
            DiskExtent[] deOut  = null;
            MemPtr       inBuff = new MemPtr();
            int          inSize;
            IntPtr       file;
            int          h  = 0;
            var          de = new DISK_EXTENT();
            var          ve = new VOLUME_DISK_EXTENTS();
            bool         r;

            file = IO.CreateFile(devicePath, IO.GENERIC_READ, IO.FILE_SHARE_READ | IO.FILE_SHARE_WRITE, IntPtr.Zero, IO.OPEN_EXISTING, IO.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            if (file == DevProp.INVALID_HANDLE_VALUE)
            {
                return(null);
            }

            uint arb = 0;

            inSize        = Marshal.SizeOf(de) + Marshal.SizeOf(ve);
            inBuff.Length = inSize;
            r             = DeviceIoControl(file, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, inBuff, (uint)inSize, ref arb, IntPtr.Zero);

            if (!r && User32.GetLastError() == ERROR_MORE_DATA)
            {
                inBuff.Length = inSize * inBuff.IntAt(0L);
                r             = DeviceIoControl(file, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, inBuff, (uint)inSize, ref arb, IntPtr.Zero);
            }

            if (!r)
            {
                inBuff.Free();
                User32.CloseHandle(file);
                return(null);
            }

            User32.CloseHandle(file);
            ve = VOLUME_DISK_EXTENTS.FromPtr(inBuff);
            inBuff.Free();
            h     = 0;
            deOut = new DiskExtent[ve.Extents.Length];
            foreach (var currentDe in ve.Extents)
            {
                de = currentDe;
                deOut[h].PhysicalDevice = de.DiskNumber;
                deOut[h].Space          = de.Space;
                deOut[h].Size           = de.ExtentLength;
                deOut[h].Offset         = de.StartingOffset;
                h += 1;
            }

            return(deOut);
        }
            public Extents(string name)
            {
                // Remove trailing '/' character from path
                string newname = name.Substring(0, name.Length - 1);

                IntPtr volhandle = CreateFile(newname, EFileAccess.Any, EFileShare.Read | EFileShare.Write, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.Normal, 0);

                if (volhandle.ToInt32() == INVALID_HANDLE_VALUE)
                {
                    return;
                }

                try
                {
                    VOLUME_DISK_EXTENTS vextents = new VOLUME_DISK_EXTENTS();
                    DISK_EXTENT         dextent  = new DISK_EXTENT();
                    uint   numextents            = 1;
                    int    allocsize             = (int)Marshal.SizeOf(vextents) + (int)numextents * (int)Marshal.SizeOf(dextent);
                    IntPtr memblock = IntPtr.Zero;
                    IntPtr alloced;
                    memblock = Marshal.AllocHGlobal((int)allocsize);
                    alloced  = memblock;
                    try {
                        int returned = 0;

                        VOLUME_DISK_EXTENTS diskExtents = new VOLUME_DISK_EXTENTS();
                        while (true)
                        {
                            if (!DeviceIoControl(volhandle, IoctlControlCodes.IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, memblock, allocsize, out returned, 0))
                            {
                                int err = Marshal.GetLastWin32Error();
                                if ((err == ERROR_INSUFFICIENT_BUFFER) || (err == ERROR_MORE_DATA))
                                {
                                    Marshal.PtrToStructure(memblock, diskExtents);
                                    numextents = diskExtents.NumberOfDiskExtents;
                                    allocsize  = (int)Marshal.SizeOf(vextents) + (int)numextents * (int)Marshal.SizeOf(dextent);
                                    memblock   = Marshal.ReAllocHGlobal(memblock, new IntPtr(allocsize));
                                    alloced    = memblock;
                                    continue;
                                }
                                else
                                {
                                    return;
                                }
                            }
                            break;
                        }
                        Marshal.PtrToStructure(memblock, diskExtents);
                        memblock = new IntPtr(memblock.ToInt64() + Marshal.SizeOf(diskExtents));
                        for (int i = 0; i < diskExtents.NumberOfDiskExtents; i++)
                        {
                            Marshal.PtrToStructure(memblock, dextent);
                            Extent extent = new Extent {
                                DiskNumber = dextent.DiskNumber, ExtentLength = dextent.ExtentLength, StartingOffset = dextent.StartingOffset
                            };
                            this.Add(extent);
                            memblock = new IntPtr(memblock.ToInt64() + Marshal.SizeOf(dextent));
                        }
                    }
                    finally {
                        Marshal.FreeHGlobal(alloced);
                    }
                }
                catch (Exception e)
                {
                    WmiBase.Singleton.DebugMsg("Extent listing exception : " + e.ToString());
                    throw;
                }
                finally
                {
                    CloseHandle(volhandle);
                }
            }