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."); } }
private static IUSN_RECORD ParseUsnRecord(UnmanagedMemory mem, int dataOffset, out int length) { // Get record length length = Marshal.ReadInt32(mem, dataOffset); int majorVersion = Marshal.ReadByte(mem, dataOffset + sizeof(int)) + (Marshal.ReadByte(mem, dataOffset + sizeof(int) + 1) << 8); if (length <= 0) { // No more records return(null); } // Copy out record subset switch (majorVersion) { case 2: USN_RECORD_V2 recordv2 = (USN_RECORD_V2)Marshal.PtrToStructure(mem.Handle + dataOffset, typeof(USN_RECORD_V2)); // Parse string manually, as we cannot rely on the string to be null-terminated. recordv2.FileName = Marshal.PtrToStringUni(mem.Handle + dataOffset + recordv2.FileNameOffset, recordv2.FileNameLength / 2); return(recordv2); case 3: USN_RECORD_V3 recordv3 = (USN_RECORD_V3)Marshal.PtrToStructure(mem.Handle + dataOffset, typeof(USN_RECORD_V3)); // Parse string manually, as we cannot rely on the string to be null-terminated. recordv3.FileName = Marshal.PtrToStringUni(mem.Handle + dataOffset + recordv3.FileNameOffset, recordv3.FileNameLength / 2); return(recordv3); default: // Ignore Debugger.Break(); break; } return(null); }