diff --git a/TestSuites/FileServer/docs/MS-FSA_ServerTestDesignSpecification.md b/TestSuites/FileServer/docs/MS-FSA_ServerTestDesignSpecification.md index 483800a7a..901d996dd 100644 --- a/TestSuites/FileServer/docs/MS-FSA_ServerTestDesignSpecification.md +++ b/TestSuites/FileServer/docs/MS-FSA_ServerTestDesignSpecification.md @@ -30,6 +30,7 @@ * [FileInfo_Set_FileBasicInformation_Timestamp_MinusOne](#FileInfo_Set_FileBasicInformation_Timestamp_MinusOne) * [FileInfo_Set_FileBasicInformation_Timestamp_MinusTwo](#FileInfo_Set_FileBasicInformaiton_Timestamp_MinusTwo) * [Scenarios for FileSystemInformation](#Scenarios-for-FileSystemInformation) + * [FsInfo_FileFsVolumeInformation](#FsInfo_FileFsVolumeInformation) * [FsInfo_FileFsAttributeInformation](#FsInfo_FileFsAttributeInformation) * [FsInfo_IsObjectIdSupported](#FsInfo_IsObjectIdSupported) * [FsInfo_FileFsSizeInformation_ClusterSize](#FsInfo_FileFsSizeInformation_ClusterSize) @@ -200,6 +201,13 @@ * [FileInfo_Set_FileBasicInformation_Timestamp_Negative_File_CreationTime](#FileInfo_Set_FileBasicInformation_Timestamp_Negative_File_CreationTime) * [FileInfo_Set_FileBasicInformation_Timestamp_Negative_Dir_CreationTime](#FileInfo_Set_FileBasicInformation_Timestamp_Negative_Dir_CreationTime) * [Test cases for FileSystemInformation](#Test-cases-for-FileSystemInformation) + * [FileFsVolumeInformation](#FileFsVolumeInformation) + * [FsInfo_Query_FileFsVolumeInformation_File_OutputBufferSizeLessThanMinimum](#FsInfo_Query_FileFsVolumeInformation_File_OutputBufferSizeLessThanMinimum) + * [FsInfo_Query_FileFsVolumeInformation_Dir_OutputBufferSizeLessThanMinimum](#FsInfo_Query_FileFsVolumeInformation_Dir_OutputBufferSizeLessThanMinimum) + * [FsInfo_Query_FileFsVolumeInformation_File_OutputBufferOverflow](#FsInfo_Query_FileFsVolumeInformation_File_OutputBufferOverflow) + * [FsInfo_Query_FileFsVolumeInformation_Dir_OutputBufferOverflow](#FsInfo_Query_FileFsVolumeInformation_Dir_OutputBufferOverflow) + * [FsInfo_Query_FileFsVolumeInformation_File_OutputValues (BVT)](#FsInfo_Query_FileFsVolumeInformation_File_OutputValues-BVT) + * [FsInfo_Query_FileFsVolumeInformation_Dir_OutputValues](#FsInfo_Query_FileFsVolumeInformation_Dir_OutputValues) * [IsObjectIdSupported](#IsObjectIdSupported) * [FsInfo_Query_FileFsObjectIdInformation_File_IsObjectIdSupported (BVT)](#FsInfo_Query_FileFsObjectIdInformation_File_IsObjectIdSupported-BVT) * [FsInfo_Query_FileFsObjectIdInformation_Dir_IsObjectIdSupported](#FsInfo_Query_FileFsObjectIdInformation_Dir_IsObjectIdSupported) @@ -516,12 +524,12 @@ The following diagram shows the basic test environment for MS-FSA. The **DC01** ### Traditional Test cases Traditional Test cases are designed specific to new algorithms in Win8, ReFS file system and Alternate Data Stream. -There are 228 test cases in total: +There are 234 test cases in total: | **Category** | **Scenarios** | **Test cases (BVT)** | | ------------- | -------------- | -------------------- | | Scenarios for FileInformation | 11 | 84 (49) | -| Scenarios for FileSystemInformation | 4 | 24 (7) | +| Scenarios for FileSystemInformation | 5 | 30 (8) | | Scenarios for FsControlRequest | 13 | 101 (32) | | Scenarios for Alternate Data Stream | 9 | 41 (12) | | Scenarios for QuotaInformation | 1 | 2 (0) | @@ -805,6 +813,22 @@ There are 343 test cases in total: | | Verify timestamp attribute is set to current time| ### Scenarios for FileSystemInformation +#### FsInfo_FileFsVolumeInformation + +| | | +| -------------| ------------- | +| Description| To query FileFsVolumeInformation and validate the MS-FSA processing rules for fixed fields, the variable-length volume label, ByteCount, and status.| +| | Test environment: FAT32, NTFS, ReFS| +| | Test object: DataFile, DirectoryFile| +| | Test coverage:| +| | FsInfoClass: FileFsVolumeInformation| +| | If OutputBufferSize is smaller than BlockAlign(FieldOffset(FILE_FS_VOLUME_INFORMATION.VolumeLabel), 8), the operation returns **STATUS_INFO_LENGTH_MISMATCH**.| +| | If the buffer contains the fixed fields but cannot contain all VolumeLabel bytes, the response contains the available prefix, ByteCount equals FieldOffset(VolumeLabel) plus BytesToCopy, and the operation returns **STATUS_BUFFER_OVERFLOW**.| +| | If the buffer can contain the complete label, the response contains VolumeCreationTime, VolumeSerialNumber, VolumeLabelLength, SupportsObjects set to TRUE, Reserved set to zero, and the complete VolumeLabel; ByteCount is exact and the operation returns **STATUS_SUCCESS**.| +| Message Sequence| CreateFile.| +| | QueryInfo with FsInfoClass.FileFsVolumeInformation and boundary-sized output buffers.| +| | Verify the returned status, ByteCount, fixed fields, and VolumeLabel bytes.| + #### FsInfo_FileFsAttributeInformation | | | @@ -2976,6 +3000,78 @@ There are 343 test cases in total: ### Test cases for FileSystemInformation +#### FileFsVolumeInformation + +##### FsInfo_Query_FileFsVolumeInformation_File_OutputBufferSizeLessThanMinimum + +| | | +| -------------| ------------- | +| Description| To verify the minimum aligned output-buffer requirement for FileFsVolumeInformation queried from a data file.| +| | Category: FSA, QueryFileSystemInformation, NonSmb, Positive| +| | Test environment: FAT32, NTFS, ReFS| +| Message Sequence| CreateFile (DataFile).| +| | QueryInfo with FsInfoClass.FileFsVolumeInformation and OutputBufferSize equal to BlockAlign(FieldOffset(VolumeLabel), 8) - 1.| +| Pass Criteria| The operation returns **STATUS_INFO_LENGTH_MISMATCH**.| + +##### FsInfo_Query_FileFsVolumeInformation_Dir_OutputBufferSizeLessThanMinimum + +| | | +| -------------| ------------- | +| Description| To verify the minimum aligned output-buffer requirement for FileFsVolumeInformation queried from a directory.| +| | Category: FSA, QueryFileSystemInformation, NonSmb, Positive| +| | Test environment: FAT32, NTFS, ReFS| +| Message Sequence| CreateFile (DirectoryFile).| +| | QueryInfo with FsInfoClass.FileFsVolumeInformation and OutputBufferSize equal to BlockAlign(FieldOffset(VolumeLabel), 8) - 1.| +| Pass Criteria| The operation returns **STATUS_INFO_LENGTH_MISMATCH**.| + +##### FsInfo_Query_FileFsVolumeInformation_File_OutputBufferOverflow + +| | | +| -------------| ------------- | +| Description| To verify the partial-volume-label response for FileFsVolumeInformation queried from a data file.| +| | Category: FSA, QueryFileSystemInformation, NonSmb, Positive| +| | Test environment: FAT32, NTFS, ReFS; requires a volume label long enough to exceed the minimum aligned response buffer.| +| Message Sequence| CreateFile (DataFile).| +| | Query the complete FileFsVolumeInformation response to determine VolumeLabelLength.| +| | Query again with space for all fixed fields and all but one UTF-16 code unit of VolumeLabel.| +| Pass Criteria| The operation returns **STATUS_BUFFER_OVERFLOW**; ByteCount equals FieldOffset(VolumeLabel) plus BytesToCopy; the fixed fields match the complete response; and the returned VolumeLabel is the expected prefix.| + +##### FsInfo_Query_FileFsVolumeInformation_Dir_OutputBufferOverflow + +| | | +| -------------| ------------- | +| Description| To verify the partial-volume-label response for FileFsVolumeInformation queried from a directory.| +| | Category: FSA, QueryFileSystemInformation, NonSmb, Positive| +| | Test environment: FAT32, NTFS, ReFS; requires a volume label long enough to exceed the minimum aligned response buffer.| +| Message Sequence| CreateFile (DirectoryFile).| +| | Query the complete FileFsVolumeInformation response to determine VolumeLabelLength.| +| | Query again with space for all fixed fields and all but one UTF-16 code unit of VolumeLabel.| +| Pass Criteria| The operation returns **STATUS_BUFFER_OVERFLOW**; ByteCount equals FieldOffset(VolumeLabel) plus BytesToCopy; the fixed fields match the complete response; and the returned VolumeLabel is the expected prefix.| + +##### FsInfo_Query_FileFsVolumeInformation_File_OutputValues (BVT) + +| | | +| -------------| ------------- | +| Description| To verify a complete FileFsVolumeInformation response queried from a data file.| +| | Category: BVT, FSA, QueryFileSystemInformation, NonSmb| +| | Test environment: FAT32, NTFS, ReFS| +| Message Sequence| CreateFile (DataFile).| +| | Query the complete FileFsVolumeInformation response.| +| | Query again with the minimum buffer that can contain the complete response.| +| Pass Criteria| Both queries return **STATUS_SUCCESS**; VolumeCreationTime is nonnegative; VolumeLabelLength matches the Unicode label bytes; SupportsObjects is TRUE; Reserved is zero; ByteCount is exact; and all volume fields are stable across both responses.| + +##### FsInfo_Query_FileFsVolumeInformation_Dir_OutputValues + +| | | +| -------------| ------------- | +| Description| To verify a complete FileFsVolumeInformation response queried from a directory.| +| | Category: FSA, QueryFileSystemInformation, NonSmb, Positive| +| | Test environment: FAT32, NTFS, ReFS| +| Message Sequence| CreateFile (DirectoryFile).| +| | Query the complete FileFsVolumeInformation response.| +| | Query again with the minimum buffer that can contain the complete response.| +| Pass Criteria| Both queries return **STATUS_SUCCESS**; VolumeCreationTime is nonnegative; VolumeLabelLength matches the Unicode label bytes; SupportsObjects is TRUE; Reserved is zero; ByteCount is exact; and all volume fields are stable across both responses.| + #### IsObjectIdSupported ##### FsInfo_Query_FileFsObjectIdInformation_File_IsObjectIdSupported (BVT) diff --git a/TestSuites/FileServer/src/FSA/TestSuite/FileSystemInformation/FsInfo_Query_FileFsVolumeInformation.cs b/TestSuites/FileServer/src/FSA/TestSuite/FileSystemInformation/FsInfo_Query_FileFsVolumeInformation.cs new file mode 100644 index 000000000..dc3d0c428 --- /dev/null +++ b/TestSuites/FileServer/src/FSA/TestSuite/FileSystemInformation/FsInfo_Query_FileFsVolumeInformation.cs @@ -0,0 +1,332 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using Microsoft.Protocols.TestSuites.FileSharing.Common.Adapter; +using Microsoft.Protocols.TestSuites.FileSharing.FSA.Adapter; +using Microsoft.Protocols.TestTools; +using Microsoft.Protocols.TestTools.StackSdk; +using Microsoft.Protocols.TestTools.StackSdk.FileAccessService.Fscc; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Microsoft.Protocols.TestSuites.FileSharing.FSA.TestSuite +{ + public partial class FsInfoTestCases : PtfTestClassBase + { + private const uint FileFsVolumeInformationAlignment = 8; + + #region Test Cases + + [TestMethod()] + [TestCategory(TestCategories.Fsa)] + [TestCategory(TestCategories.QueryFileSystemInformation)] + [TestCategory(TestCategories.NonSmb)] + [TestCategory(TestCategories.Positive)] + [Description("Query FileFsVolumeInformation from a file with an output buffer smaller than the aligned fixed portion.")] + public void FsInfo_Query_FileFsVolumeInformation_File_OutputBufferSizeLessThanMinimum() + { + FsInfo_Query_FileFsVolumeInformation_OutputBufferSizeLessThanMinimum(FileType.DataFile); + } + + [TestMethod()] + [TestCategory(TestCategories.Fsa)] + [TestCategory(TestCategories.QueryFileSystemInformation)] + [TestCategory(TestCategories.NonSmb)] + [TestCategory(TestCategories.Positive)] + [Description("Query FileFsVolumeInformation from a directory with an output buffer smaller than the aligned fixed portion.")] + public void FsInfo_Query_FileFsVolumeInformation_Dir_OutputBufferSizeLessThanMinimum() + { + FsInfo_Query_FileFsVolumeInformation_OutputBufferSizeLessThanMinimum(FileType.DirectoryFile); + } + + [TestMethod()] + [TestCategory(TestCategories.Fsa)] + [TestCategory(TestCategories.QueryFileSystemInformation)] + [TestCategory(TestCategories.NonSmb)] + [TestCategory(TestCategories.Positive)] + [Description("Query FileFsVolumeInformation from a file with space for only part of the volume label.")] + public void FsInfo_Query_FileFsVolumeInformation_File_OutputBufferOverflow() + { + FsInfo_Query_FileFsVolumeInformation_OutputBufferOverflow(FileType.DataFile); + } + + [TestMethod()] + [TestCategory(TestCategories.Fsa)] + [TestCategory(TestCategories.QueryFileSystemInformation)] + [TestCategory(TestCategories.NonSmb)] + [TestCategory(TestCategories.Positive)] + [Description("Query FileFsVolumeInformation from a directory with space for only part of the volume label.")] + public void FsInfo_Query_FileFsVolumeInformation_Dir_OutputBufferOverflow() + { + FsInfo_Query_FileFsVolumeInformation_OutputBufferOverflow(FileType.DirectoryFile); + } + + [TestMethod()] + [TestCategory(TestCategories.Bvt)] + [TestCategory(TestCategories.Fsa)] + [TestCategory(TestCategories.QueryFileSystemInformation)] + [TestCategory(TestCategories.NonSmb)] + [Description("Query FileFsVolumeInformation from a file and verify the complete response.")] + public void FsInfo_Query_FileFsVolumeInformation_File_OutputValues() + { + FsInfo_Query_FileFsVolumeInformation_OutputValues(FileType.DataFile); + } + + [TestMethod()] + [TestCategory(TestCategories.Fsa)] + [TestCategory(TestCategories.QueryFileSystemInformation)] + [TestCategory(TestCategories.NonSmb)] + [TestCategory(TestCategories.Positive)] + [Description("Query FileFsVolumeInformation from a directory and verify the complete response.")] + public void FsInfo_Query_FileFsVolumeInformation_Dir_OutputValues() + { + FsInfo_Query_FileFsVolumeInformation_OutputValues(FileType.DirectoryFile); + } + + #endregion + + #region Test Case Utility + + private void FsInfo_Query_FileFsVolumeInformation_OutputBufferSizeLessThanMinimum(FileType fileType) + { + BaseTestSite.Log.Add(LogEntryKind.TestStep, "Test case steps:"); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "1. Create " + fileType.ToString()); + MessageStatus status = this.fsaAdapter.CreateFile(fileType); + this.fsaAdapter.AssertAreEqual( + this.Manager, + MessageStatus.SUCCESS, + status, + "CreateFile is expected to succeed."); + + uint volumeLabelOffset = GetFileFsVolumeInformationVolumeLabelOffset(); + uint minimumOutputBufferSize = BlockAlign(volumeLabelOffset, FileFsVolumeInformationAlignment); + + BaseTestSite.Log.Add( + LogEntryKind.TestStep, + "2. Query FileFsVolumeInformation with OutputBufferSize smaller than BlockAlign(FieldOffset(VolumeLabel), 8)."); + status = this.fsaAdapter.QueryFileSystemInformation( + FileSystemInfoClass.File_FsVolumeInformation, + minimumOutputBufferSize - 1, + out _, + out _); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "3. Verify STATUS_INFO_LENGTH_MISMATCH is returned."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + MessageStatus.INFO_LENGTH_MISMATCH, + status, + "[MS-FSA 2.1.5.13.1] An OutputBufferSize smaller than BlockAlign(FieldOffset(FILE_FS_VOLUME_INFORMATION.VolumeLabel), 8) MUST fail with STATUS_INFO_LENGTH_MISMATCH."); + } + + private void FsInfo_Query_FileFsVolumeInformation_OutputBufferOverflow(FileType fileType) + { + BaseTestSite.Log.Add(LogEntryKind.TestStep, "Test case steps:"); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "1. Create " + fileType.ToString()); + MessageStatus status = this.fsaAdapter.CreateFile(fileType); + this.fsaAdapter.AssertAreEqual( + this.Manager, + MessageStatus.SUCCESS, + status, + "CreateFile is expected to succeed."); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "2. Query the complete FileFsVolumeInformation response."); + FileFsVolumeInformation completeVolumeInformation = QueryCompleteFileFsVolumeInformation( + out long completeByteCount, + out byte[] completeOutputBuffer); + + uint volumeLabelOffset = GetFileFsVolumeInformationVolumeLabelOffset(); + uint minimumOutputBufferSize = BlockAlign(volumeLabelOffset, FileFsVolumeInformationAlignment); + uint completeResponseSize = volumeLabelOffset + completeVolumeInformation.VolumeLabelLength; + + this.fsaAdapter.AssertAreEqual( + this.Manager, + (long)completeResponseSize, + completeByteCount, + "[MS-FSA 2.1.5.13.1] ByteCount MUST equal FieldOffset(FILE_FS_VOLUME_INFORMATION.VolumeLabel) plus BytesToCopy."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + 0u, + completeVolumeInformation.VolumeLabelLength % sizeof(char), + "[MS-FSCC 2.5.9] VolumeLabel is a Unicode field, so VolumeLabelLength is expected to contain complete UTF-16 code units."); + + BaseTestSite.Assume.IsTrue( + completeResponseSize > minimumOutputBufferSize, + "The configured volume label must be longer than {0} bytes to exercise STATUS_BUFFER_OVERFLOW.", + minimumOutputBufferSize - volumeLabelOffset); + + uint truncatedOutputBufferSize = completeResponseSize - sizeof(char); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "3. Query FileFsVolumeInformation with space for only part of VolumeLabel."); + status = this.fsaAdapter.QueryFileSystemInformation( + FileSystemInfoClass.File_FsVolumeInformation, + truncatedOutputBufferSize, + out long truncatedByteCount, + out byte[] truncatedOutputBuffer); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "4. Verify the partial response, ByteCount, and STATUS_BUFFER_OVERFLOW."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + MessageStatus.BUFFER_OVERFLOW, + status, + "[MS-FSA 2.1.5.13.1] The status MUST be STATUS_BUFFER_OVERFLOW when BytesToCopy is less than VolumeLabelLength."); + BaseTestSite.Assert.IsNotNull( + truncatedOutputBuffer, + "The partial FILE_FS_VOLUME_INFORMATION response must be returned with STATUS_BUFFER_OVERFLOW."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + (long)truncatedOutputBufferSize, + truncatedByteCount, + "[MS-FSA 2.1.5.13.1] ByteCount MUST equal FieldOffset(FILE_FS_VOLUME_INFORMATION.VolumeLabel) plus BytesToCopy."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + (int)truncatedOutputBufferSize, + truncatedOutputBuffer.Length, + "The returned buffer length must match ByteCount."); + + int fixedFieldLength = (int)volumeLabelOffset; + int bytesToCopy = (int)(truncatedOutputBufferSize - volumeLabelOffset); + this.fsaAdapter.AssertAreEqual( + this.Manager, + true, + completeOutputBuffer.AsSpan(0, fixedFieldLength).SequenceEqual( + truncatedOutputBuffer.AsSpan(0, fixedFieldLength)), + "[MS-FSA 2.1.5.13.1] The fixed FILE_FS_VOLUME_INFORMATION fields MUST describe the open file's volume."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + true, + completeOutputBuffer.AsSpan(fixedFieldLength, bytesToCopy).SequenceEqual( + truncatedOutputBuffer.AsSpan(fixedFieldLength, bytesToCopy)), + "[MS-FSA 2.1.5.13.1] The returned VolumeLabel MUST contain the first BytesToCopy bytes of the volume label."); + } + + private void FsInfo_Query_FileFsVolumeInformation_OutputValues(FileType fileType) + { + BaseTestSite.Log.Add(LogEntryKind.TestStep, "Test case steps:"); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "1. Create " + fileType.ToString()); + MessageStatus status = this.fsaAdapter.CreateFile(fileType); + this.fsaAdapter.AssertAreEqual( + this.Manager, + MessageStatus.SUCCESS, + status, + "CreateFile is expected to succeed."); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "2. Query the complete FileFsVolumeInformation response."); + FileFsVolumeInformation volumeInformation = QueryCompleteFileFsVolumeInformation( + out long byteCount, + out byte[] outputBuffer); + + uint volumeLabelOffset = GetFileFsVolumeInformationVolumeLabelOffset(); + int volumeLabelLength = volumeInformation.VolumeLabel == null ? 0 : volumeInformation.VolumeLabel.Length; + long expectedByteCount = volumeLabelOffset + volumeInformation.VolumeLabelLength; + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "3. Verify the FILE_FS_VOLUME_INFORMATION fields and ByteCount."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + true, + volumeInformation.VolumeCreationTime >= 0, + "[MS-FSCC 2.5.9] VolumeCreationTime MUST be greater than or equal to zero."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + (uint)volumeLabelLength, + volumeInformation.VolumeLabelLength, + "[MS-FSA 2.1.5.13.1] VolumeLabelLength MUST equal the length, in bytes, of the volume label."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + 0u, + volumeInformation.VolumeLabelLength % sizeof(char), + "[MS-FSCC 2.5.9] VolumeLabel is a Unicode field, so VolumeLabelLength is expected to contain complete UTF-16 code units."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + SupportsObjects_Values.V1, + volumeInformation.SupportsObjects, + "[MS-FSA 2.1.5.13.1] SupportsObjects MUST be set to TRUE."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + (byte)0, + volumeInformation.Reserved, + "[MS-FSCC 2.5.9] Reserved MUST be set to zero."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + expectedByteCount, + byteCount, + "[MS-FSA 2.1.5.13.1] ByteCount MUST equal FieldOffset(FILE_FS_VOLUME_INFORMATION.VolumeLabel) plus BytesToCopy."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + expectedByteCount, + (long)outputBuffer.Length, + "The returned buffer length must match ByteCount."); + + uint minimumOutputBufferSize = BlockAlign(volumeLabelOffset, FileFsVolumeInformationAlignment); + uint exactOutputBufferSize = Math.Max(minimumOutputBufferSize, (uint)expectedByteCount); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "4. Query again with exactly enough space for the complete response."); + status = this.fsaAdapter.QueryFileSystemInformation( + FileSystemInfoClass.File_FsVolumeInformation, + exactOutputBufferSize, + out long exactByteCount, + out byte[] exactOutputBuffer); + + BaseTestSite.Log.Add(LogEntryKind.TestStep, "5. Verify STATUS_SUCCESS and the complete volume information."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + MessageStatus.SUCCESS, + status, + "[MS-FSA 2.1.5.13.1] The status MUST be STATUS_SUCCESS when BytesToCopy equals VolumeLabelLength."); + BaseTestSite.Assert.IsNotNull( + exactOutputBuffer, + "The complete FILE_FS_VOLUME_INFORMATION response must be returned with STATUS_SUCCESS."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + expectedByteCount, + exactByteCount, + "[MS-FSA 2.1.5.13.1] ByteCount MUST equal FieldOffset(FILE_FS_VOLUME_INFORMATION.VolumeLabel) plus BytesToCopy."); + this.fsaAdapter.AssertAreEqual( + this.Manager, + true, + outputBuffer.AsSpan().SequenceEqual(exactOutputBuffer), + "[MS-FSA 2.1.5.13.1] VolumeCreationTime, VolumeSerialNumber, VolumeLabelLength, SupportsObjects, and VolumeLabel MUST describe the same open file volume."); + } + + private FileFsVolumeInformation QueryCompleteFileFsVolumeInformation( + out long byteCount, + out byte[] outputBuffer) + { + MessageStatus status = this.fsaAdapter.QueryFileSystemInformation( + FileSystemInfoClass.File_FsVolumeInformation, + this.fsaAdapter.transBufferSize, + out byteCount, + out outputBuffer); + + this.fsaAdapter.AssertAreEqual( + this.Manager, + MessageStatus.SUCCESS, + status, + "Querying FileFsVolumeInformation with a complete output buffer is expected to succeed."); + BaseTestSite.Assert.IsNotNull( + outputBuffer, + "The complete FILE_FS_VOLUME_INFORMATION response must not be null."); + + return TypeMarshal.ToStruct(outputBuffer); + } + + private static uint GetFileFsVolumeInformationVolumeLabelOffset() + { + FileFsVolumeInformation volumeInformation = new FileFsVolumeInformation + { + VolumeLabel = Array.Empty() + }; + + return (uint)TypeMarshal.ToBytes(volumeInformation).Length; + } + + private static uint BlockAlign(uint value, uint alignment) + { + return ((value + alignment - 1) / alignment) * alignment; + } + + #endregion + } +}