示例#1
0
        internal VolumeData(IntPtr hDrive)
        {
            // Create a byte array the size of the NTFS_VOLUME_DATA_BUFFER struct
            byte[] ntfsVolData = new byte[96];

            // Instatiate an integer to accept the amount of bytes read
            int buf = new int();

            // Return the NTFS_VOLUME_DATA_BUFFER struct
            var status = NativeMethods.DeviceIoControl(
                hDevice: hDrive,
                dwIoControlCode: WinIoCtl.FSCTL_GET_NTFS_VOLUME_DATA,
                InBuffer: null,
                nInBufferSize: 0,
                OutBuffer: ntfsVolData,
                nOutBufferSize: ntfsVolData.Length,
                lpBytesReturned: ref buf,
                lpOverlapped: IntPtr.Zero);

            NTFS_VOLUME_DATA_BUFFER ntfsVD = new NTFS_VOLUME_DATA_BUFFER(ntfsVolData);

            TotalSectors         = ntfsVD.NumberSectors;
            TotalClusters        = ntfsVD.TotalClusters;
            FreeClusters         = ntfsVD.FreeClusters;
            BytesPerSector       = ntfsVD.BytesPerSector;
            BytesPerCluster      = ntfsVD.BytesPerCluster;
            BytesPerMFTRecord    = ntfsVD.BytesPerFileRecordSegment;
            ClustersPerMFTRecord = ntfsVD.ClustersPerFileRecordSegment;
            MFTSize               = ntfsVD.MftValidDataLength;
            MFTStartCluster       = ntfsVD.MftStartLcn;
            MFTZoneStartCluster   = ntfsVD.MftZoneStart;
            MFTZoneEndCluster     = ntfsVD.MftZoneEnd;
            MFTZoneSize           = (ntfsVD.MftZoneEnd - ntfsVD.MftZoneStart) * (ulong)ntfsVD.BytesPerCluster;
            MFTMirrorStartCluster = ntfsVD.Mft2StartLcn;
        }
示例#2
0
 public static extern bool DeviceIoControl(
     IntPtr hDevice,
     UInt32 dwIoControlCode,
     IntPtr lpInBuffer,
     Int32 nInBufferSize,
     out NTFS_VOLUME_DATA_BUFFER lpOutBuffer,
     Int32 nOutBufferSize,
     out uint lpBytesReturned,
     IntPtr lpOverlapped);
        private void FileInfo_Query_FileIdInformation(FileType fileType)
        {
            BaseTestSite.Assume.AreNotEqual(FileSystem.FAT32, fsaAdapter.FileSystem, "File system should not be FAT32.");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Test case steps:");
            MessageStatus status;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "1. Create a file.");
            status = this.fsaAdapter.CreateFile(fileType);
            BaseTestSite.Assert.AreEqual(MessageStatus.SUCCESS, status, "Create should succeed.");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "2. Query FileIdInformation.");
            byte[] outputBuffer;
            long   byteCount;

            status = this.fsaAdapter.QueryFileInformation(FileInfoClass.FileIdInformation, this.fsaAdapter.transBufferSize, out byteCount, out outputBuffer);
            BaseTestSite.Assert.AreEqual(MessageStatus.SUCCESS, status, "Query FileIdInformation should succeed.");

            FileIdInformation fileIdInfo = TypeMarshal.ToStruct <FileIdInformation>(outputBuffer);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "3. Get FileId by sending FSCTL_READ_FILE_USN_DATA to server.");
            status = this.fsaAdapter.FsCtlReadFileUSNData(3, 3, out outputBuffer); // Only version 3 USN record contains 128 bit FileReferenceNumber;
            BaseTestSite.Assert.AreEqual(MessageStatus.SUCCESS, status, "FSCTL_READ_FILE_USN_DATA should succeed.");
            USN_RECORD_V3 record = TypeMarshal.ToStruct <USN_RECORD_V3>(outputBuffer);

            System.Guid fileId = record.FileReferenceNumber;
            BaseTestSite.Assert.AreEqual(fileId, fileIdInfo.FileId, "FileId when querying FileIdInformation should be the same with FileReferenceNumber when sending FSCTL_READ_FILE_USN_DATA.");

            // We can get the 64-bit VolumeSerialNumber only by sending FSCTL_GET_NTFS_VOLUME_DATA or FSCTL_GET_REFS_VOLUME_DATA.
            // For other file system, just ignore this check.
            if (this.fsaAdapter.FileSystem == FileSystem.NTFS)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "4. Get VolumeSerialNumber by sending FSCTL_GET_NTFS_VOLUME_DATA to server.");
                status = this.fsaAdapter.FsCtlForEasyRequest(FsControlCommand.FSCTL_GET_NTFS_VOLUME_DATA, out outputBuffer);
                BaseTestSite.Assert.AreEqual(MessageStatus.SUCCESS, status, "FSCTL_GET_NTFS_VOLUME_DATA should succeed.");
                NTFS_VOLUME_DATA_BUFFER ntfsVolumeData = TypeMarshal.ToStruct <NTFS_VOLUME_DATA_BUFFER>(outputBuffer);
                long volumeId = ntfsVolumeData.VolumeSerialNumber;
                BaseTestSite.Assert.AreEqual(volumeId, fileIdInfo.VolumeSerialNumber,
                                             "VolumeSerialNumber when querying FileIdInformation should be the same with VolumeSerialNumber when sending FSCTL_GET_NTFS_VOLUME_DATA.");
            }
            else if (this.fsaAdapter.FileSystem == FileSystem.REFS)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "4. Get VolumeSerialNumber by sending FSCTL_GET_REFS_VOLUME_DATA to server.");
                status = this.fsaAdapter.FsCtlForEasyRequest(FsControlCommand.FSCTL_GET_REFS_VOLUME_DATA, out outputBuffer);
                BaseTestSite.Assert.AreEqual(MessageStatus.SUCCESS, status, "FSCTL_GET_REFS_VOLUME_DATA should succeed.");
                REFS_VOLUME_DATA_BUFFER refsVolumeData = TypeMarshal.ToStruct <REFS_VOLUME_DATA_BUFFER>(outputBuffer);
                long volumeId = refsVolumeData.VolumeSerialNumber;
                BaseTestSite.Assert.AreEqual(volumeId, fileIdInfo.VolumeSerialNumber,
                                             "VolumeSerialNumber when querying FileIdInformation should be the same with VolumeSerialNumber when sending FSCTL_GET_REFS_VOLUME_DATA.");
            }
        }
示例#4
0
      public static extern bool DeviceIoControl(SafeFileHandle hDevice,
 uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize,
 out NTFS_VOLUME_DATA_BUFFER lpOutBuffer, uint nOutBufferSize,
 out uint lpBytesReturned, IntPtr lpOverlapped);
        private void FsCtl_Get_Volume_Data(FileType fileType, FileSystem fileSystem)
        {
            if (fileSystem != FileSystem.REFS && fileSystem != FileSystem.NTFS)
            {
                throw new InvalidOperationException("Unexpected fileSystem!");
            }

            BaseTestSite.Assume.AreEqual(fileSystem, this.fsaAdapter.FileSystem, "The case is only applicable for {0} file system.", fileSystem);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Test case steps:");
            MessageStatus status;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "1. Create a file.");
            status = this.fsaAdapter.CreateFile(fileType);
            BaseTestSite.Assert.AreEqual(MessageStatus.SUCCESS, status, "Create should succeed.");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "2. Query FileIdInformation.");
            long byteCount;

            byte[] outputBuffer;
            status = this.fsaAdapter.QueryFileInformation(FileInfoClass.FileIdInformation, this.fsaAdapter.transBufferSize, out byteCount, out outputBuffer);
            BaseTestSite.Assert.AreEqual(MessageStatus.SUCCESS, status, "Query FileIdInformation should succeed.");
            FileIdInformation fileIdInfo = TypeMarshal.ToStruct <FileIdInformation>(outputBuffer);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "3. Query FileFsFullSizeInformation.");
            status = this.fsaAdapter.QueryFileSystemInformation(FileSystemInfoClass.File_FsFullSize_Information, this.fsaAdapter.transBufferSize, out byteCount, out outputBuffer);
            BaseTestSite.Assert.AreEqual(MessageStatus.SUCCESS, status, "Query FileFsFullSizeInformation should succeed.");
            FileFsFullSizeInformation fileFsFullSizeInfo = TypeMarshal.ToStruct <FileFsFullSizeInformation>(outputBuffer);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "4. FSCTL request with FSCTL_GET_{0}_VOLUME_DATA.", fileSystem);
            status = this.fsaAdapter.FsCtlForEasyRequest(fileSystem == FileSystem.REFS ? FsControlCommand.FSCTL_GET_REFS_VOLUME_DATA : FsControlCommand.FSCTL_GET_NTFS_VOLUME_DATA, out outputBuffer);
            BaseTestSite.Assert.AreEqual(MessageStatus.SUCCESS, status, "FSCTL_GET_{0}_VOLUME_DATA should succeed.", fileSystem);

            long volumeSerialNumber;
            long totalClusters;
            uint bytesPerSector;

            if (fileSystem == FileSystem.REFS)
            {
                REFS_VOLUME_DATA_BUFFER refsVolumeData = TypeMarshal.ToStruct <REFS_VOLUME_DATA_BUFFER>(outputBuffer);
                volumeSerialNumber = refsVolumeData.VolumeSerialNumber;
                totalClusters      = refsVolumeData.TotalClusters;
                bytesPerSector     = refsVolumeData.BytesPerSector;
            }
            else
            {
                NTFS_VOLUME_DATA_BUFFER ntfsVolumeData = TypeMarshal.ToStruct <NTFS_VOLUME_DATA_BUFFER>(outputBuffer);
                volumeSerialNumber = ntfsVolumeData.VolumeSerialNumber;
                totalClusters      = ntfsVolumeData.TotalClusters;
                bytesPerSector     = ntfsVolumeData.BytesPerSector;
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "5. Verify returned {0}_VOLUME_DATA_BUFFER.", fileSystem);

            BaseTestSite.Assert.AreEqual(fileIdInfo.VolumeSerialNumber, volumeSerialNumber,
                                         "VolumeSerialNumber of {0}_VOLUME_DATA_BUFFER should be the same with VolumeSerialNumber of FileIdInformation.", fileSystem);
            BaseTestSite.Assert.AreEqual(fileFsFullSizeInfo.TotalAllocationUnits, totalClusters,
                                         "TotalClusters of {0}_VOLUME_DATA_BUFFER should be the same with TotalAllocationUnits of FileFsFullSizeInformation", fileSystem);
            BaseTestSite.Assert.AreEqual(fileFsFullSizeInfo.BytesPerSector, bytesPerSector,
                                         "BytesPerSector of {0}_VOLUME_DATA_BUFFER should be the same with BytesPerSector of FileFsFullSizeInformation", fileSystem);
        }
示例#6
0
 public static NTFS_VOLUME_DATA_BUFFER GetNtfsVolumeData(VolumeInfo volume)
 {
     using (SafeFileHandle volumeHandle = KernelApi.NativeMethods.CreateFile(
      volume.VolumeId.Remove(volume.VolumeId.Length - 1),
      KernelApi.NativeMethods.GENERIC_READ, KernelApi.NativeMethods.FILE_SHARE_READ |
      KernelApi.NativeMethods.FILE_SHARE_WRITE, IntPtr.Zero,
      KernelApi.NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero))
     {
      uint resultSize = 0;
      NTFS_VOLUME_DATA_BUFFER volumeData = new NTFS_VOLUME_DATA_BUFFER();
      if (DeviceIoControl(volumeHandle, FSCTL_GET_NTFS_VOLUME_DATA,
       IntPtr.Zero, 0, out volumeData, (uint)Marshal.SizeOf(volumeData),
       out resultSize, IntPtr.Zero))
      {
       return volumeData;
      }
      throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
     }
 }