//FsctlSetEncryption
        //FsctlSetObjectId
        //FsctlSetObjectIdExtended
        //FsctlSetReparsePoint

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364596(v=vs.85).aspx"/></summary>
        public void FileSystemSetSparseFile(bool setSparse)
        {
            FILE_SET_SPARSE_BUFFER input = new FILE_SET_SPARSE_BUFFER();

            input.SetSparse = setSparse;

            DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlSetSparse, input);
        }
        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364597(v=vs.85).aspx"/></summary>
        public void FileSystemSetZeroData(long fileOffset, long length)
        {
            FILE_ZERO_DATA_INFORMATION input = new FILE_ZERO_DATA_INFORMATION();

            input.FileOffset      = fileOffset;
            input.BeyondFinalZero = fileOffset + length;

            DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlSetZeroData, input);
        }
        //FsctlHsmData
        //FsctlHsmMsg
        //FsctlInvalidateVolumes
        //FsctlIsPathnameValid
        //FsctlIsVolumeDirty
        //FsctlIsVolumeMounted
        //FsctlLockVolume
        //FsctlMarkAsSystemHive
        //FsctlMarkHandle
        //FsctlMarkVolumeDirty

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/aa364577(v=vs.85).aspx"/></summary>
        public void FileSystemMoveFile(IntPtr fileHandle, ulong startingVcn, ulong startingLcn, uint clusterCount)
        {
            MOVE_FILE_DATA input = new MOVE_FILE_DATA();

            input.FileHandle   = fileHandle;
            input.StartingVcn  = startingVcn;
            input.StartingLcn  = startingLcn;
            input.ClusterCount = clusterCount;

            DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlMoveFile, input);
        }
        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364563(v=vs.85).aspx"/></summary>
        public IUSN_RECORD[] FileSystemEnumUsnData()
        {
            ulong     nextUsn   = 0;
            const int chunkSize = 1 * 1024 * 1024;      // 1 MB chunks

            List <IUSN_RECORD> res = new List <IUSN_RECORD>();

            using (UnmanagedMemory mem = new UnmanagedMemory(chunkSize))
            {
                do
                {
                    MFT_ENUM_DATA_V0 input = new MFT_ENUM_DATA_V0();
                    input.StartFileReferenceNumber = nextUsn;
                    input.LowUsn  = long.MinValue;
                    input.HighUsn = long.MaxValue;

                    int    errorCode;
                    byte[] data = DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlEnumUsnData, chunkSize, input, out errorCode);
                    Marshal.Copy(data, 0, mem, data.Length);

                    if (errorCode != 0)
                    {
                        // Exit when theres no more to do
                        break;
                    }

                    nextUsn = BitConverter.ToUInt64(data, 0);

                    int dataOffset = 8;

                    while (dataOffset < data.Length)
                    {
                        int         length;
                        IUSN_RECORD rec = ParseUsnRecord(mem, dataOffset, out length);

                        if (length <= 0)
                        {
                            break;
                        }

                        res.Add(rec);

                        // Move to next record
                        dataOffset += length;
                    }

                    // Fetch next chunk
                } while (true);
            }

            return(res.ToArray());
        }
        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364573(v=vs.85).aspx"/></summary>
        public VOLUME_BITMAP_BUFFER FileSystemGetVolumeBitmap(ulong startingLcn = 0)
        {
            STARTING_LCN_INPUT_BUFFER startingLcnStruct = new STARTING_LCN_INPUT_BUFFER();

            startingLcnStruct.StartingLcn = startingLcn;

            // Fetch 128 bytes (this includes the size parameter of the VOLUME_BITMAP_BUFFER structure.
            int lastError;

            byte[] data = DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlGetVolumeBitmap, 128, startingLcnStruct, out lastError);

            // Is there more data? (Most often there is).
            if (lastError == 234)
            {
                // Parse length attribute (2'nd 64-bit attribute)
                uint newLength = (uint)BitConverter.ToUInt64(data, 8);

                // Length: Clusters / 8 + 2x 64 bit numbers
                newLength = (uint)Math.Ceiling(newLength / 8d) + 2 * 8;

                data = DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlGetVolumeBitmap, newLength, startingLcnStruct, out lastError);
            }

            // Ensure the last call to InvokeIoControl succeeded.
            if (lastError != 0)
            {
                throw new Win32Exception(lastError, "Couldn't invoke FileSystemGetVolumeBitmap. LastError: " + Utils.GetWin32ErrorMessage(lastError));
            }

            // Build the VOLUME_BITMAP_BUFFER structure.
            VOLUME_BITMAP_BUFFER res = new VOLUME_BITMAP_BUFFER();

            res.StartingLcn = BitConverter.ToUInt64(data, 0);
            res.BitmapSize  = BitConverter.ToUInt64(data, sizeof(UInt64));

            res.Buffer = new BitArray((int)res.BitmapSize);

            for (int i = 0; i < res.Buffer.Length; i++)
            {
                int  dataByteIndex = sizeof(UInt64) * 2 + i / 8;
                byte dataByte      = data[dataByteIndex];

                int byteIdx = i % 8;

                res.Buffer[i] = ((dataByte >> byteIdx) & 1) == 1;
            }

            return(res);
        }
        //DiskSetPartitionInfo
        //DiskSetPartitionInfoEx

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365173(v=vs.85).aspx"/></summary>
        public DRIVE_LAYOUT_INFORMATION DiskGetDriveLayout()
        {
            DRIVE_LAYOUT_INFORMATION_INTERNAL data = DeviceIoControlHelper.InvokeIoControl <DRIVE_LAYOUT_INFORMATION_INTERNAL>(Handle, IOControlCode.DiskGetDriveLayout);

            DRIVE_LAYOUT_INFORMATION res = new DRIVE_LAYOUT_INFORMATION();

            res.PartitionCount = data.PartitionCount;
            res.Signature      = data.Signature;
            res.PartitionEntry = new PARTITION_INFORMATION[res.PartitionCount];

            for (int i = 0; i < res.PartitionCount; i++)
            {
                res.PartitionEntry[i] = data.PartitionEntry[i];
            }

            return(res);
        }
        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365174(v=vs.85).aspx"/></summary>
        public DRIVE_LAYOUT_INFORMATION_EX DiskGetDriveLayoutEx()
        {
            DRIVE_LAYOUT_INFORMATION_EX_INTERNAL data = DeviceIoControlHelper.InvokeIoControl <DRIVE_LAYOUT_INFORMATION_EX_INTERNAL>(Handle, IOControlCode.DiskGetDriveLayoutEx);

            DRIVE_LAYOUT_INFORMATION_EX res = new DRIVE_LAYOUT_INFORMATION_EX();

            res.PartitionStyle         = data.PartitionStyle;
            res.PartitionCount         = data.PartitionCount;
            res.DriveLayoutInformaiton = data.DriveLayoutInformaiton;
            res.PartitionEntry         = new PARTITION_INFORMATION_EX[res.PartitionCount];

            for (int i = 0; i < res.PartitionCount; i++)
            {
                res.PartitionEntry[i] = data.PartitionEntry[i];
            }

            return(res);
        }
        /// <summary><see cref="https://msdn.microsoft.com/en-us/library/windows/desktop/aa364586(v=vs.85).aspx"/></summary>
        public IUSN_RECORD[] FileSystemReadUsnJournal(long volumeJournalId, UsnJournalReasonMask reasonMask, USN firstUsn, int bytesToWaitFor = 0, int timeout = 0)
        {
            READ_USN_JOURNAL_DATA_V0 input = new READ_USN_JOURNAL_DATA_V0();

            input.StartUsn       = firstUsn;
            input.UsnJournalId   = volumeJournalId;
            input.ReasonMask     = reasonMask;
            input.BytesToWaitFor = bytesToWaitFor;
            input.Timeout        = timeout;

            int errorCode;

            byte[] data = DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlReadUsnJournal, 1024 * 1024, input, out errorCode);

            List <IUSN_RECORD> res = new List <IUSN_RECORD>();

            using (UnmanagedMemory mem = new UnmanagedMemory(data))
            {
                int dataOffset = 8;

                while (dataOffset < data.Length)
                {
                    int         length;
                    IUSN_RECORD rec = ParseUsnRecord(mem, dataOffset, out length);

                    if (length <= 0)
                    {
                        break;
                    }

                    res.Add(rec);

                    // Move to next record
                    dataOffset += length;
                }
            }

            return(res.ToArray());
        }
        //FsctlFindFilesBySid

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364567(v=vs.85).aspx"/></summary>
        public COMPRESSION_FORMAT FileSystemGetCompression()
        {
            return((COMPRESSION_FORMAT)DeviceIoControlHelper.InvokeIoControl <ushort>(Handle, IOControlCode.FsctlGetCompression));
        }
예제 #10
0
 /// <summary>
 /// Used to f.ex. close CD Rom trays
 /// <see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa363414(v=vs.85).aspx" />
 /// </summary>
 public bool StorageLoadMedia()
 {
     return(DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.StorageLoadMedia));
 }
        //FsctlQueryFatBpb
        //FsctlQueryRetrievalPointers
        //FsctlQueryOnDiskVolumeInfo

        //FsctlReadPropertyData
        //FsctlReadRawEncrypted
        //FsctlRecallFile
        //FsctlRequestBatchOplock
        //FsctlRequestFilterOplock
        //FsctlRequestOplockLevel1
        //FsctlRequestOplockLevel2
        //FsctlSecurityIdCheck

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364592(v=vs.85).aspx"/></summary>
        public void FileSystemSetCompression(COMPRESSION_FORMAT level)
        {
            DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlSetCompression, (ushort)level);
        }
        //DiskSetDriveLayout
        //DiskSetDriveLayoutEx
        //DiskVerify
        //DiskFormatTracks
        //DiskReassignBlocks
        //DiskPerformance
        //DiskIsWritable
        //DiskLogging
        //DiskFormatTracksEx
        //DiskHistogramStructure
        //DiskHistogramData
        //DiskHistogramReset
        //DiskRequestStructure
        //DiskRequestData
        //DiskControllerNumber

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/hardware/ff566202(v=vs.85).aspx"/></summary>
        public GETVERSIONINPARAMS DiskGetSmartVersion()
        {
            return(DeviceIoControlHelper.InvokeIoControl <GETVERSIONINPARAMS>(Handle, IOControlCode.DiskSmartGetVersion));
        }
        //DiskSmartSendDriveCommand
        //DiskSmartRcvDriveData
        //DiskUpdateDriveSize
        //DiskGrowPartition

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365165(v=vs.85).aspx"/></summary>
        public DISK_CACHE_INFORMATION DiskGetCacheInformation()
        {
            return(DeviceIoControlHelper.InvokeIoControl <DISK_CACHE_INFORMATION>(Handle, IOControlCode.DiskGetCacheInformation));
        }
        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/dd405526(v=vs.85).aspx"/></summary>
        /// <remarks>
        ///     Does not correcly handle all cases of this method!. Especially regarding compressed/encrypted and/or sparse files in NTFS.
        ///     Consider yourself warned.
        /// </remarks>
        public FileExtentInfo[] FileSystemGetRetrievalPointers()
        {
            STARTING_VCN_INPUT_BUFFER input = new STARTING_VCN_INPUT_BUFFER();

            input.StartingVcn = 0;

            List <FileExtentInfo> extents = new List <FileExtentInfo>();

            uint chunkSize        = 1024;
            uint singleExtentSize = MarshalHelper.SizeOf <RETRIEVAL_POINTERS_EXTENT>();

            int lastError;

            do
            {
                byte[] data = DeviceIoControlHelper.InvokeIoControl(Handle, IOControlCode.FsctlGetRetrievalPointers, chunkSize, input, out lastError);

                RETRIEVAL_POINTERS_BUFFER output = new RETRIEVAL_POINTERS_BUFFER();
                output.ExtentCount = BitConverter.ToUInt32(data, 0);
                output.StartingVcn = BitConverter.ToUInt64(data, sizeof(ulong));

                output.Extents = new RETRIEVAL_POINTERS_EXTENT[output.ExtentCount];

                // Parse extents
                int extentsSize = (int)(output.ExtentCount * singleExtentSize);
                using (var dataPtr = new UnmanagedMemory(extentsSize))
                {
                    Marshal.Copy(data, sizeof(ulong) + sizeof(ulong), dataPtr, extentsSize);

                    for (ulong i = 0; i < output.ExtentCount; i++)
                    {
                        IntPtr currentPtr = new IntPtr(dataPtr.Handle.ToInt64() + (int)(singleExtentSize * i));
                        output.Extents[i] = currentPtr.ToStructure <RETRIEVAL_POINTERS_EXTENT>();
                    }
                }

                // Make extents more readable
                for (ulong i = 0; i < output.ExtentCount; i++)
                {
                    ulong startVcn = i == 0
                        ? output.StartingVcn
                        : output.Extents[i - 1].NextVcn;

                    ulong size = output.Extents[i].NextVcn - startVcn;

                    FileExtentInfo extent = new FileExtentInfo();
                    extent.Size = size;
                    extent.Vcn  = startVcn;
                    extent.Lcn  = output.Extents[i].Lcn;

                    extents.Add(extent);
                }

                if (lastError == 38)
                {
                    // End of file reached
                    break;
                }

                // Prep the start point for the next call
                input.StartingVcn = output.Extents[output.ExtentCount - 1].NextVcn;
            } while (lastError == 234);

            return(extents.ToArray());
        }
        //FsctlGetObjectId
        //FsctlGetReparsePoint

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/dd405526(v=vs.85).aspx"/></summary>
        public RETRIEVAL_POINTER_BASE FileSystemGetRetrievalPointerBase()
        {
            return(DeviceIoControlHelper.InvokeIoControl <RETRIEVAL_POINTER_BASE>(Handle, IOControlCode.FsctlGetRetrievalPointerBase));
        }
 /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa364569(v=vs.85).aspx"/></summary>
 public NTFS_VOLUME_DATA_BUFFER FileSystemGetNtfsVolumeData()
 {
     return(DeviceIoControlHelper.InvokeIoControl <NTFS_VOLUME_DATA_BUFFER>(Handle, IOControlCode.FsctlGetNtfsVolumeData));
 }
        /// <summary><see cref="https://msdn.microsoft.com/en-us/library/windows/desktop/aa364583(v=vs.85).aspx"/></summary>
        public USN_JOURNAL_DATA_V0 FileSystemQueryUsnJournal()
        {
            USN_JOURNAL_DATA_V0 res = DeviceIoControlHelper.InvokeIoControl <USN_JOURNAL_DATA_V0>(Handle, IOControlCode.FsctlQueryUsnJournal);

            return(res);
        }
 /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365180(v=vs.85).aspx"/></summary>
 public PARTITION_INFORMATION_EX DiskGetPartitionInfoEx()
 {
     return(DeviceIoControlHelper.InvokeIoControl <PARTITION_INFORMATION_EX>(Handle, IOControlCode.DiskGetPartitionInfoEx));
 }
 /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365169(v=vs.85).aspx"/></summary>
 public DISK_GEOMETRY DiskGetDriveGeometry()
 {
     return(DeviceIoControlHelper.InvokeIoControl <DISK_GEOMETRY>(Handle, IOControlCode.DiskGetDriveGeometry));
 }
 /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/hh706681(v=vs.85).aspx"/></summary>
 public GET_DISK_ATTRIBUTES DiskGetDiskAttributes()
 {
     return(DeviceIoControlHelper.InvokeIoControl <GET_DISK_ATTRIBUTES>(Handle, IOControlCode.DiskGetDiskAttributes));
 }
        //DiskSetCacheInformation
        //DiskDeleteDriveLayout
        //DiskFormatDrive
        //DiskSenseDevice
        //DiskCheckVerify
        //DiskMediaRemoval
        //DiskEjectMedia
        //DiskLoadMedia
        //DiskReserve
        //DiskRelease
        //DiskFindNewDevices
        //DiskCreateDisk

        /// <summary><see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365178(v=vs.85).aspx"/></summary>
        public long DiskGetLengthInfo()
        {
            return(DeviceIoControlHelper.InvokeIoControl <GET_LENGTH_INFORMATION>(Handle, IOControlCode.DiskGetLengthInfo).Length);
        }