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);
        }
        //StorageCheckVerify
        //StorageCheckVerify2
        //StorageMediaRemoval

        public STORAGE_DEVICE_DESCRIPTOR_PARSED StorageGetDeviceProperty()
        {
            STORAGE_PROPERTY_QUERY query = new STORAGE_PROPERTY_QUERY();

            query.QueryType  = STORAGE_QUERY_TYPE.PropertyStandardQuery;
            query.PropertyId = STORAGE_PROPERTY_ID.StorageDeviceProperty;

            byte[] res = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.StorageQueryProperty, query);
            STORAGE_DEVICE_DESCRIPTOR descriptor = Utils.ByteArrayToStruct <STORAGE_DEVICE_DESCRIPTOR>(res, 0);

            STORAGE_DEVICE_DESCRIPTOR_PARSED returnValue = new STORAGE_DEVICE_DESCRIPTOR_PARSED();

            returnValue.Version               = descriptor.Version;
            returnValue.Size                  = descriptor.Size;
            returnValue.DeviceType            = descriptor.DeviceType;
            returnValue.DeviceTypeModifier    = descriptor.DeviceTypeModifier;
            returnValue.RemovableMedia        = descriptor.RemovableMedia;
            returnValue.CommandQueueing       = descriptor.CommandQueueing;
            returnValue.VendorIdOffset        = descriptor.VendorIdOffset;
            returnValue.ProductIdOffset       = descriptor.ProductIdOffset;
            returnValue.ProductRevisionOffset = descriptor.ProductRevisionOffset;
            returnValue.SerialNumberOffset    = descriptor.SerialNumberOffset;
            returnValue.BusType               = descriptor.BusType;
            returnValue.RawPropertiesLength   = descriptor.RawPropertiesLength;
            returnValue.RawDeviceProperties   = descriptor.RawDeviceProperties;
            returnValue.SerialNumber          = Utils.ReadNullTerminatedAsciiString(res, (int)descriptor.SerialNumberOffset);

            return(returnValue);
        }
Beispiel #3
0
        //FsctlAllowExtendedDasdIo
        //FsctlCreateOrGetObjectId
        //FsctlDeleteObjectId
        //FsctlDeleteReparsePoint
        //FsctlDismountVolume
        //FsctlDumpPropertyData
        //FsctlEnableUpgrade
        //FsctlEncryptionFsctlIo

        //FsctlExtendVolume

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364565(v=vs.85).aspx"/></summary>
        public FileSystemStats[] FileSystemGetStatistics()
        {
            byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.FsctlFileSystemGetStatistics, 512);

            FileSystemStats[] res;

            using (UnmanagedMemory mem = new UnmanagedMemory(data))
            {
                IntPtr currentDataPtr = mem;

                FILESYSTEM_STATISTICS firstStats = (FILESYSTEM_STATISTICS)Marshal.PtrToStructure(currentDataPtr, typeof(FILESYSTEM_STATISTICS));

                int fsStatsSize = Marshal.SizeOf(typeof(FILESYSTEM_STATISTICS));

                int elementSize = (int)firstStats.SizeOfCompleteStructure;
                int procCount   = data.Length / elementSize;

                res = new FileSystemStats[procCount];

                for (int i = 0; i < procCount; i++)
                {
                    res[i]       = new FileSystemStats();
                    res[i].Stats = (FILESYSTEM_STATISTICS)Marshal.PtrToStructure(currentDataPtr, typeof(FILESYSTEM_STATISTICS));

                    switch (res[i].Stats.FileSystemType)
                    {
                    case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_NTFS:
                        NTFS_STATISTICS ntfsStats = (NTFS_STATISTICS)Marshal.PtrToStructure(currentDataPtr + fsStatsSize, typeof(NTFS_STATISTICS));

                        res[i].FSStats = ntfsStats;

                        break;

                    case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_FAT:
                        FAT_STATISTICS fatStats = (FAT_STATISTICS)Marshal.PtrToStructure(currentDataPtr + fsStatsSize, typeof(FAT_STATISTICS));

                        res[i].FSStats = fatStats;
                        break;

                    case FILESYSTEM_STATISTICS_TYPE.FILESYSTEM_STATISTICS_TYPE_EXFAT:
                        EXFAT_STATISTICS exFatStats = (EXFAT_STATISTICS)Marshal.PtrToStructure(currentDataPtr + fsStatsSize, typeof(EXFAT_STATISTICS));

                        res[i].FSStats = exFatStats;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    currentDataPtr += elementSize;
                }
            }

            return(res);
        }
        /// <summary>
        /// No reference
        /// </summary>
        public List <string> QueryDosVolumePaths(string deviceName)
        {
            int byteCount = Encoding.Unicode.GetByteCount(deviceName);

            byte[] tmp = new byte[sizeof(ushort) + byteCount];

            tmp[0] = (byte)(byteCount & 0xFF);
            tmp[1] = (byte)((byteCount >> 8) & 0xFF);

            Encoding.Unicode.GetBytes(deviceName, 0, deviceName.Length, tmp, 2);

            byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.MountmgrQueryDosVolumePaths, tmp, 64, (uint)tmp.Length);

            return(new List <string>(Utils.ReadUnicodeStringArray(data, sizeof(uint))));
        }
        //FsctlGetHfsInformation

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/aa364568(v=vs.85).aspx"/></summary>
        public NTFS_FILE_RECORD_OUTPUT_BUFFER FileSystemGetNtfsFileRecord(ulong fileId)
        {
            NTFS_FILE_RECORD_INPUT_BUFFER input = new NTFS_FILE_RECORD_INPUT_BUFFER();

            input.FileReferenceNumber = fileId;

            byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.FsctlGetNtfsFileRecord, input, 1024);    // NTFS File records are in 1K chunks

            NTFS_FILE_RECORD_OUTPUT_BUFFER res = new NTFS_FILE_RECORD_OUTPUT_BUFFER();

            res.FileReferenceNumber = BitConverter.ToUInt64(data, 0);
            res.FileRecordLength    = BitConverter.ToUInt32(data, 8);

            res.FileRecordBuffer = new byte[res.FileRecordLength];
            Array.Copy(data, 8 + 4, res.FileRecordBuffer, 0, (int)res.FileRecordLength);

            return(res);
        }
        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365171(v=vs.85).aspx"/></summary>
        public DISK_GEOMETRY_EX DiskGetDriveGeometryEx()
        {
            byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.DiskGetDriveGeometryEx, 256);

            DISK_GEOMETRY_EX res;

            using (UnmanagedMemory mem = new UnmanagedMemory(data))
            {
                res.Geometry = (DISK_GEOMETRY)Marshal.PtrToStructure(mem, typeof(DISK_GEOMETRY));
                res.DiskSize = BitConverter.ToInt64(data, Marshal.SizeOf(typeof(DISK_GEOMETRY)));

                IntPtr tmpPtr = mem.Handle + Marshal.SizeOf(typeof(DISK_GEOMETRY)) + sizeof(long);
                res.PartitionInformation = (DISK_PARTITION_INFO)Marshal.PtrToStructure(tmpPtr, typeof(DISK_PARTITION_INFO));

                tmpPtr           += res.PartitionInformation.SizeOfPartitionInfo;
                res.DiskInt13Info = (DISK_EX_INT13_INFO)Marshal.PtrToStructure(tmpPtr, typeof(DISK_EX_INT13_INFO));
            }

            return(res);
        }
Beispiel #7
0
        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365171(v=vs.85).aspx"/></summary>
        public DISK_GEOMETRY_EX DiskGetDriveGeometryEx()
        {
            byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.DiskGetDriveGeometryEx, 256);

            DISK_GEOMETRY_EX res;

            using (UnmanagedMemory mem = new UnmanagedMemory(data))
            {
                res.Geometry = mem.Handle.ToStructure <DISK_GEOMETRY>();
                res.DiskSize = BitConverter.ToInt64(data, (int)MarshalHelper.SizeOf <DISK_GEOMETRY>());

                IntPtr tmpPtr = new IntPtr(mem.Handle.ToInt64() + MarshalHelper.SizeOf <DISK_GEOMETRY>() + sizeof(long));
                res.PartitionInformation = tmpPtr.ToStructure <DISK_PARTITION_INFO>();

                tmpPtr            = new IntPtr(tmpPtr.ToInt64() + res.PartitionInformation.SizeOfPartitionInfo);
                res.DiskInt13Info = tmpPtr.ToStructure <DISK_EX_INT13_INFO>();
            }

            return(res);
        }
        //FsctlNssControl
        //FsctlNssRcontrol
        //FsctlOpBatchAckClosePending
        //FsctlOplockBreakAckNo2
        //FsctlOplockBreakAcknowledge
        //FsctlOplockBreakNotify

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364582(v=vs.85).aspx"/></summary>
        public FILE_ALLOCATED_RANGE_BUFFER[] FileSystemQueryAllocatedRanges(long offset, long length)
        {
            FILE_ALLOCATED_RANGE_BUFFER input = new FILE_ALLOCATED_RANGE_BUFFER();

            input.FileOffset = offset;
            input.Length     = offset + length;

            byte[] res = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.FsctlQueryAllocatedRanges, input, 512);

            int singleSize = (int)MarshalHelper.SizeOf <FILE_ALLOCATED_RANGE_BUFFER>();
            List <FILE_ALLOCATED_RANGE_BUFFER> ranges = new List <FILE_ALLOCATED_RANGE_BUFFER>();

            for (int i = 0; i < res.Length; i += singleSize)
            {
                FILE_ALLOCATED_RANGE_BUFFER single = new FILE_ALLOCATED_RANGE_BUFFER();
                single.FileOffset = BitConverter.ToInt64(res, i);
                single.Length     = BitConverter.ToInt64(res, i + 8);

                ranges.Add(single);
            }

            return(ranges.ToArray());
        }
        /// <summary>
        /// <see cref="http://msdn.microsoft.com/en-us/library/windows/hardware/ff560474(v=vs.85).aspx" />
        /// </summary>
        public List <MountPoint> MountQueryPoints()
        {
            MOUNTMGR_MOUNT_POINT input = new MOUNTMGR_MOUNT_POINT();

            byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.MountmgrQueryPoints, input, 512);

            uint mountPoints            = BitConverter.ToUInt32(data, sizeof(uint));
            uint sizeOfMountPointStruct = MarshalHelper.SizeOf <MOUNTMGR_MOUNT_POINT>();

            List <MountPoint> result = new List <MountPoint>();

            using (UnmanagedMemory mem = new UnmanagedMemory(data))
            {
                IntPtr offset = new IntPtr(mem.Handle.ToInt64() + sizeof(uint) * 2);

                for (int i = 0; i < mountPoints; i++)
                {
                    MOUNTMGR_MOUNT_POINT strct = offset.ToStructure <MOUNTMGR_MOUNT_POINT>();

                    MountPoint point = new MountPoint();

                    point.SymbolicLinkName = Encoding.Unicode.GetString(data, (int)strct.SymbolicLinkNameOffset, strct.SymbolicLinkNameLength);
                    point.DeviceName       = Encoding.Unicode.GetString(data, (int)strct.DeviceNameOffset, strct.DeviceNameLength);

                    byte[] idBytes = new byte[strct.UniqueIdLength];
                    Array.Copy(data, (int)strct.UniqueIdOffset, idBytes, 0, idBytes.Length);
                    point.UniqueId = idBytes;

                    result.Add(point);

                    // Advance one
                    offset = new IntPtr(offset.ToInt64() + sizeOfMountPointStruct);
                }
            }

            return(result);
        }