IFS Test

Note  This content applies to the Windows Logo Kit (WLK). For the latest information using the new Windows Hardware Certification Kit (HCK), see Windows HCK User's Guide on the Windows Hardware Dev Center.

Overview

The Installable File System (IFS) test is designed to test that installable file systems comply with the Microsoft Windows operating systems. Its intended audience includes file system developers who want to verify that their drivers comply with a standard set of expected functionality.

You can run the IFS test from the command line and specify several options. Each test returns a test status block if the test has passed or failed. You can also view the test results in NTlog.

The IFS test was written with the following design goals:

  • Subsystem independence. The tests take place in the NT Native Call API (the user-mode Ntdll.dll), which provides subsystem independence. The Microsoft Win32 API is a publicly available interface. This interface creates the Win32 subsystem, which depends heavily on the private Microsoft native call interface. The NT Native Call API interface sits below all subsystems in the operating system. By rigorously verifying the correct operation of the file system at this level, you can reasonably assume that other subsystems are working properly.

  • Synthetic operation distinction. Several Win32 file system operations rely on a sequence of NT native call APIs being run. These APIs are identified to be the first type of synthetic file system operations. The testing approach is to observe the use and expectations of the NT Native Call API by the Type I Synthetic Operations, track these usages and expectations, and verify that an existing test (or combination of tests) exercises these operations. Some examples of this approach include the Win32 Backup APIs (BackupRead, BackupWrite, BackupSeek), CopyFile, and MoveFile.

    The second type of synthetic operation is a file system-related operation at the Win32 level or NT Native Call API level that is satisfied by the Win32 or kernel code. A good example is the NtSetInformationFile call with the FilePositionInformation class specified. The file pointer is updated in the file object by the I/O manager and the call is completed.

    There are several reasons to not include synthetic operation testing directly in the Compliance test. First, you would be testing a lot of the Win32 user-mode code, kernel-mode I/O manager code, or object manager code. These items are key system paths that are well tested and that you do not need to retest. Second, if a synthetic operation fails because of a file system problem, there is no easy description of the failure without also a description of Win32 or NT internal calls. In addition, if unexpected results do occur in the core operating system components, you would not be able to trace them easily.

  • Separate test groups. A file system driver is usually written by modifying an existing file system or IFS code sample. You can use the IFS test to test portions of your driver before the entire file system driver (FSD) is complete. You can test portions of a driver under development by separating the IFS test into groups, which include the relevant set of individual tests. This independence permits you to test specific portions of the new FSD without the interaction from other untested or unimplemented functions.

  • Asynchronous and synchronous testingMost of the I/O operations can be performed both asynchronously and synchronously. The calling user-mode thread might block in kernel mode when it is waiting for a synchronous operation to finish. The same user-mode thread might be able to continue running while an asynchronous operation is completed by a system or worker thread in kernel mode. You must implement this functionality within the file system driver. The IFS tests are generally designed to be run in both modes of operation. Special tests are created, where applicable, to test certain cases where only asynchronous or synchronous operations are allowed.

  • Fault identification. The fault identification capability of the IFS test enables you to test different aspects of a file system and determine which operation causes a failure. You can better identify and isolate the problem if the exact point of failure is readily discernable. This capability is created by the separate IFS test groups and independent tests within those groups. Each test returns a test status block that indicates whether the test has passed or failed.

  • Coverage. The goal for the IFS test is to compare all functional aspects of a new FSD with other completed file systems. By comparing the untested driver against a group of comprehensive tests that are known to work on time-tested file systems (for example, FASTFAT or NTFS), a new driver could be considered compliant from a functional point of view. This type of testing is a "black-box" approach to the problem. Given the same input, any file system put in the box should behave in the same way. This approach, in conjunction with a stress test, results in a robust test of the new FSD.

    The native calls interact directly with the I/O manager and sometimes directly call into the FSD through these two interfaces. The level of control in the native calls enables you to test for specific operations on the file system, enabling fault identification. The native calls also make the test extensible because new calls can replace outdated calls, and you can add additional calls to support new IRPs or fast I/O paths.

    There is a relationship between the native calls and the IRPs and fast I/O paths. Not all native calls are considered in the IFS test, but you must address all IRPs and fast I/O paths for complete coverage. Note that all native calls that use the file system interface were considered.

  • Extensible. You can add to the IFS test when new capabilities are added to the file system model. The grouping of tests lends itself to this capability. You can add and remove individual tests from the groups without affecting surrounding tests. You can also check backward compatibility by applying a selection of tests that were verified on previous versions of the operating system and FSD.

  • Development guideline. The IFS test helps establish a minimum set of capabilities that a file system driver should support. You can use the tests as your guide by demonstrating the expected capabilities of their systems. Notes in the documentation of the test help describe what is expected and what capabilities the FSD must have to comply.

  • Filter testing. You can use the IFS test to verify the transparency and coexistence properties of filters and determine if a filter is negatively affecting a Windows NT system.

Details

The following list contains all of the file system test groups in the IFS test:

  • OpenCreateGeneral

  • OpenCreateParameters

  • CloseCleanupDelete

  • VolumeInformation

  • FileInformation

  • EaInformation

  • DirectoryInformation

  • FileLocking

  • OpLocks

  • ChangeNotification

  • DeviceControl

  • FileSystemControlVolume

  • FileSystemControlGeneral

  • ReadWrite

  • SectionsCaching

  • Security

  • ObjectID

  • MountPoints

  • ReparsePoints

  • SparseFiles

  • ExtendedSecurity

  • ForcedDismount

  • Encryption

  • Quotas File

  • LinkTracking

  • ChangeJournal

  • StreamEnhancements

  • DefragEnhancements

The following sections describe each group in more detail.

OpenCreateGeneral File System Test Group

The tests in this group include:

  • CreatePagingFileTest. The CreatePagingFile test creates a paging file and uses a combination of file-opens on the paging file and registry queries. The create paging file function is used to create a new paging file and verified to return a success. The create file function is called with the file open disposition on the paging file. All share access rights and a desired access of just synchronize are used in the open. This call should fail since the file open for paging does not allow even minimal access.

  • FileNameLengthTest. Each file system supports different lengths of file names. File-name length is determined by internal representations. The maximum component name length that is obtained from AttributeInformationTest is used to determine the longest file name that the file system supports. This value is used to form file names that are less than, equal to, and greater than the maximum. The create file function tests the different file names. When the file names specified go beyond the maximum length, the create file function should return an error (object name invalid). The created files are verified by calling the create file function. A successful open verifies the creation and reference of the file by names of proper length. The test is repeated for directory names. The directory file option flag is specified to the create file function.

  • HFHTest. HFHTest tests the parsing of the double backslash (\\) when it is used as a prefix for a file name or directory name. The backslash is converted to a single backslash in this case. A file is created in the root directory of the volume that is being tested. The file is opened with a call to the create file function. The double backslash is used for the open access. The open should succeed on the file.

    A directory is created in the root directory of the volume that is being tested. The directory is opened with a call to the create file function. The double backslash is used for the open access. The open should succeed on the directory.

  • UnicodeOnDiskTest. You can obtain the Unicode on disk volume attribute flag by using the query volume information function. This flag indicates that the file system will store the Unicode representation of the file name on the disk. Several files are created by using the create file function call. These file names contain Unicode characters. Several valid and invalid Unicode characters are used in the file name. The directory is then queried. The long names are checked to see if the Unicode representation has been preserved. The code page is then changed. The returned file names are checked to see if the Unicode representation has been stored. All invalid Unicode characters in the code page should be returned as question marks (?).

  • CaseSensitiveTest. You can obtain the case sensitive search volume attribute flag by using the query volume information function. This flag indicates that the file system differentiates between file names that differ only in case. That is, when two file names are identical except for case, they are considered different files. This differentiation is verified by using the create file function with several file names that differ only in case. Each file is filled with different data. The files are then opened with the file names, and the unique data they contain is verified with by reading the files. The files are then queried for the unique IDs. These IDs are verified to be different for the cases where the file names differ only by case.

  • PreserveCaseTest. You can obtain the case preserved names volume attribute flag by using the query volume information function. This flag indicates that the file system preserves the case of different file names. That is, when a file is created with a mixed-case file name, the directory contents, when queried, return file names that reflect the original mixed case. This preservation is verified by using the create file function call with several file names that have mixed case. The directory is then queried. The returned file names are checked to see if the case has been preserved from create time.

  • ShortFileNameTest. This test is performed if the file system supports long names. Short names are the MS-DOS-compatible 8.3 format (an eight-character name with a three-character file name extension). Long names are defined as any file names that do not fit in the 8.3 format but are otherwise legal names in the file system. The file system should always create an 8.3 representation for the long file name. You can create the 8.3 representation when extended characters are used in the file name. You can use this short name representation to access the file with the same way that the long file name does. This capability is verified by using the create file function with several long file names and several file names that use extended characters. The directory is then queried. The returned short and long file names are checked to see if the short names have been properly created for the files. The file is then accessed with the short name. This access should be successful.

  • ShareAccessTest. You can specify the share access of a handle at the time a file is created. This access determines if subsequent attempt to open the same file are allowed to succeed. A file is first created with read attributes desired access and no share parameters set. Creating a file in this way allows only query operations.

    The file is created with the create file function. Four subsequent attempts to open the file are made on the file. The create file function is used to open the file with the following desired access parameters: read data, write data. The two calls are made separately. These calls should both fail because sharing is not allowed for these options. A third call specifies zero for the access parameters, but it specifies the delete-on-close create option; this call should also fail with an access-denied error. The last call is made with a zero for the access parameters and read attributes for the create options. This call should succeed because queries are allowed. This test is verified by specifying the share parameters separately. The pass/fail result of the create file function verifies that the share control operates correctly. These tests are repeated for directories and DASD handles, the same results apply.

  • AlternateStreamTest. NTFS supports alternate data streams. You can open or create the alternate streams by specifying the file name as in the normal open/create tests but following the name with a colon (:) and the name of the alternate stream. A test file is created by using the create file function, and data is written to the file. The test file name is appended with the string ":stream1" and the alternate data stream is opened by using the create file function. Data is written to the alternate data stream. Two more streams are opened and written to with different data. All open file handles are closed. The alternate data streams and primary data stream are open for reading. The data is verified. An attempt is then made to open data streams that do not exist in the file. The proper status should be returned from the call to the create file function.

  • StreamShareTest. Share access of a handle of an alternate data stream should follow the same rules as opening another handle on the same file. A single stream in a file that contains multiple streams is first opened with the read attributes desired access and no share parameters set. This setting allows only query type operations.

    The stream is opened with the create file function. Four subsequent opens are attempted on the handle. The create file function is used to open a different stream with the following desired access parameters: read data, write data. The two calls are made separately. These calls should both fail since sharing is not allowed. A third call specifies zero for the access parameters, but it specifies the delete-on-close create option. This call should also fail. The last call is made with a zero for the access parameters and read attributes for the create options. This call should succeed as queries are allowed. This test is verified by specifying the share parameters separately. The pass/fail result of the create file function verifies that the share control operates correctly.

  • FileSystemDeviceOpenTest. The FSD test creates a device object in the root directory of the Microsoft Windows NT object namespace (for example, \Fat, \Ntfs). This action tests that the device object can be opened and, therefore, it verifies that the device object exists. The user supplies an object namespace path as input. The file open disposition is used with the desired access of ReadAttributes. The successful return on the operation is required to pass the test.

  • FileFullPathCreationTest. A fully qualified file name is one that consists of the full path to a file in the Windows NT object namespace. For this test, the system path to the volume is used as a prefix to the file name. The file name that is appended to this path is formed within the upper bound of the maximum component name length. The file is verified to be nonexistent by a call to the create file function with the file open disposition. This call should fail with an object name not found error. The file is then created with a call to the create file function with the file create disposition. ReadOnly volumes should return a write protection error at this point. The file handle is closed. The existence of the file is verified with a call to the create file function with the file open disposition. This call should succeed.

  • DirectoryFullPathCreationTest. A fully qualified directory name is one in which a full path (including the system root, volume root, and directory path) is supplied as a prefix to the directory name. The TESTVOL and TESTROOT strings are used as prefixes to the directory name in this test. The directory name is appended to the path and formed within the upper bound of the maximum component name length.

    The failure of the create when the temporary attribute is specified is tested. The creation of a directory in a path that exists and does not exist is tested. The directory is verified to be nonexistent by a call to the create file function with the file open disposition and the file directory option flag. This option flag instructs the file system to open a directory rather than a file. This call should fail.

    The directory is then created with a call to the create file function by using the file create disposition with the directory file option flag. Creation of the directory is also tested with the temporary attribute set in the call to the create file function. This call should fail with an access-denied error. The directory handle is then closed.

    The existence of the directory is verified by another call to the create file function with the file open disposition and the directory file option flag set. This operation should succeed. The handle to the directory is then closed. A file is then created inside of the newly created directory using the create file function and the fully qualified path and file name. The call to the create file function should have the file create disposition. The handle is then closed.

    A subsequent open on the fully qualified directory path and file name by using the create file function and the file open disposition will verify the file is created in the directory path. The handle is then closed. The above directory creation is tested with a path specified with TESTVOL\TESTROOT\faketestdir\testdir. This path should fail since faketestdir does not exist. The above directory creation is tested with a path that does exist (realtestdir instead of faketestdir). This path should succeed.

  • FileRelativePathCreationTest. You can access files by going through the handle of an open directory. This type of access is considered a relative path access because the file is created relative to a specific open directory. The handle to the test directory is used in the object attributes parameter to the create file function. The file name is created within the upper bound of the maximum component length. Only the file name is passed into the create file function because no qualifying path is necessary.

    A handle to a test directory is opened. The file is verified to be nonexistent by a call to the create file function with the file open disposition; this call should fail with an object name not found error. The existence of the file is verified by another call to the create file function with the file open disposition. This operation should succeed. The file handle and test directory handles are then closed. The preceding test file creation attempt is repeated, but the file name specified is modified to include a leading backslash. This operation should fail with an object name invalid error.

  • DirectoryRelativePathCreationTest. You can open or create directories relative to an open directory. This type of access is considered a relative access. The handle to a test directory, is used in the object attributes parameter to the create file function. The directory name is created within the upper bound of the maximum component name length. There is also a test for failure on leading backslash.

    A handle to the test directory is opened. The directory is verified to be nonexistent by a call to the create file function with the file open disposition and the directory file option flag set. This create option instructs the file system to create a directory, not a file. This instruction should fail because the operation is attempting to open a directory that does not exist. The directory is then created with a call to the create file function using the file create disposition and the directory file create option. This call should succeed. The directory handle is then closed. The existence of the directory is verified by another call to the create file function with the file open disposition and with the directory file option flag. This operation should succeed.

    A file is then created inside of the newly created directory using the create file function with the file create disposition. The handle to the recently created directory should be passed in as an object attribute for the relative path information. The handle is then closed. A subsequent open using the create file function call with the file open disposition on the created directory handle verifies the file is created in the new directory. The handles to the file, directory, and test directory are closed. The preceding attempt to create a test directory is repeated, but the directory name specified is modified to include a leading backslash. This operation should fail with an object-name-invalid error.

  • FileOpenByIDTest. You can query the unique and persistent identifier for a file. This identifier can be used to open the file on supported file systems. A test file is created in the TESTVOL\TESTROOT path. The query information file function is called to obtain the unique index value. The 8 bytes are passed into a call to the create file function in place of the file name. A handle to the test root path is passed into the call through the object attributes root directory parameter. The file open disposition is used. The contents and attributes of the opened file are compared against the test file.

  • NonDirectoryFileOpenTest. You can specify the nondirectory file option flag in a call to the create file function. The operation should fail if the object being opened is a directory and the flag is set. The directory file option flag can be specified in a call to the create file function. This operation should fail if the object being opened is a file and the flag is set.

    A test directory is created in the TESTVOL\TESTROOT path. An open is attempted on the directory with the non-directory file. This operation should fail with the not a directory error. An open is attempted on the directory without the non-directory file disposition being set. This operation should succeed. The same operation should be performed with the directory file flag set. This operation should succeed in the same way the first attempt succeeded.

    A test file is created in the TESTVOL\TESTROOT path. An open is attempted on the file with the directory file flag set. This operation should fail with object name invalid error. An open is attempted on the file without the directory file being set. This operation should succeed. The same operation should be performed with the non-directory file flag set. This should operation succeed in the same way the first attempt succeeded.

  • OpenVolumeTest. The file system driver should support volume or Direct Access to Storage Device (DASD) opening. This support allows for opening the "\DosDevices\?: volume device; where ?: is the name of the drive letter that is mapped to the volume that is being tested. When the volume device is opened, it can be written in a direct byte access method as opposed to a file and directory hierarchy. Automatic volume locking is also tested.

    First a new file is created on the volume. The desired access is not a concern. This test is intended to maintain an open handle. Next an attempt is made to open the volume. Because the share access is 0, no open handles can exist on the volume. The test checks to see that the sharing violation error came back. Next the test tries to open the volume for reading. Even though there is only one handle open and that is a read-only handle, the operation should fail with a sharing violation error. Next, the test tries to open the volume with the file share read disposition on the share access. Because only one, read-only handle is open, this operation should succeed. Next, two DASD opens are attempted, the first should succeed and the second should fail with an access-denied error.

OpenCreateParameters File System Test Group

The tests in this group include:

  • OverwriteFileTest. When the file create function is used with the file overwrite disposition, an existing file is required. The existing file is truncated so the end-of-file pointer is set to the beginning of the file. The system and hidden attributes that are specified in the call to the file create function must match the attributes that are currently set on the existing file. New attributes are joined with the OR operator into the existing attributes; that is, existing attributes cannot be cleared, but additional attributes can be specified.

    The file create function is used with the file overwrite function on a file name that does not exist. This operation should succeed. Next, the file create function is used with the file overwrite function on a file name that does exist. This operation should return a file-overwritten status. The file is then read and should be empty.

  • OverwriteFileAllocTest. When you use the file create function with the file overwrite disposition, an existing file is required. The existing file is truncated so the end-of-file pointer is set to the beginning of the file.

    The test is performed with an allocation size specified to the file create function. The allocation size is queried and verified to be a multiple of the minimum allocation size.

  • OverwriteFileAttrTest. When you use the file create function with the file overwrite disposition, an existing file is required. The system and hidden attributes specified in the call to the file create function must match the attributes that are currently set on the existing file. New attributes are joined with the OR operator into the existing attributes; that is, existing attributes cannot be cleared, but additional attributes can be specified.

    The file create function is used with the file overwrite function on a file name that does not exist; this operation should succeed. Next the file create function is used with the file overwrite function on a file name that does exist; this operation should return a file overwritten status. The file is then read and should be empty.

    The test is repeated again on a hidden system test file. This time when the file create function is called the status returned is a media-write-protected error. The test is repeated on a read-only file; now when the file create function is called, the test should fail with an access-denied error.

  • SupersedeFileTest. When the file create function is specified with the file supersede disposition, an existing file is required. The existing file is truncated so the end-of-file pointer is set to the beginning of the file. The system and hidden attributes that are specified in the call to the file create function must match the attributes that are currently set on the existing file. New attributes become the attributes of the file; that is existing attributes are replaced with the new attributes.

    The file create function is called with the file supersede disposition and a file name that does not exist; this call should succeed. Next the file create function is called with the file supersede disposition on a file name that does exist; this call should return a file supersede status.

  • SupersedeFileAllocTest. When the file create function is specified with the file supersede disposition, an existing file is required. The existing file is truncated so the end-of-file pointer is set to the beginning of the file.

    The test is performed with an allocation size specified to the file create function, the allocation size is then queried, and it is verified to be a multiple of the minimum allocation size.

  • SupersedeFileAttrTest. When the file create function is specified with the file supersede disposition, an existing file is required. The system and hidden attributes that are specified in the call to the file create function must match the attributes that are currently set on the existing file. New attributes become the attributes of the file; that is, existing attributes are replaced with the new attributes.

    The test is performed on a hidden system file, when the file create function is called with the file supersede disposition, the-media-write-protected error is returned. The test is repeated on a file that is read-only; the call to the file create function with the file supersede disposition should succeed since it is overwriting the file anyway.

  • ReadOnlyAttributeTest. You can set the attributes of a file when the file is created. If the read-only attribute is set on a file, you can open the file for reading but not writing. The file cannot subsequently be opened with the delete-on-close option set. The delete-on-close option and read-only attribute are mutually exclusive. A test file with the read-only attribute is opened and a write is attempted. This write attempt should fail with an invalid-user-buffer error. Next a read is attempted on the test file; this read attempt should pass without any errors. The file handle is then closed. The file create function with the delete-on-close option set is used to open a test file; this attempt should fail with an access-denied error. Next, this test is performed on a test file with the delete-on-close and read-only option set when the file was created; this test should fail with an access-denied error.

  • SystemAttributeTest. You can set The attributes of a file can be set when the file is created. If the system attribute is set on a file, the file reflects this attribute information with the query directory file function. A file is created with the system attribute set. The query directory file function is then called to verify the existence of the flag in the returned information on the file.

  • OpenFileTest. An attempt is made to open a file that does not exist; this attempt should return an object-not-found error. Next, an attempt is made to open a file that does exist. This operation should succeed.

  • OpenFileDirTest. An attempt is made to open a directory that does not exist. This attempt should return an object-not-found error. Next, an attempt is made to open a directory that does exist. This operation should succeed.

  • CreateFileTest. The file create disposition does not allow an existing file to be opened. This disposition creates a new file if the file does not exist and returns an error if the file already exists.

    The file create disposition is used to create a file that does not exist. This operation should succeed. Next, the file create disposition is used to create a file that does exist; this operation should fail with an access-denied error.

  • OpenAlwaysFileTest. The file open if disposition allows the opening of an existing or nonexistent file. If the file does not exist, the file is created. The create file function is used with the file open if disposition for a file name that does not exist; this operation should return a created status. Next, the create file function is used with the file open if disposition for a file name that does exist. This operation should return an open status.

  • OpenAlwaysFileDirTest. The file open if disposition allows the opening of an existing or nonexistent directory. If the directory does not exist, the directory is created. The create file function is used with the file open if disposition for a directory name that does not exist; this operation should return a created status. Next the create file function is used with the file open if disposition for a directory name that does exist. This operation should return an open status.

  • OverwriteAlwaysFileTest. The file overwrite if disposition does not require an existing file. If the file is created, the end-of-file pointer is already at the beginning of the file so no overwriting is done. If the file already exists, the file is truncated. The end-of-file pointer is set to the beginning of the file. The system and hidden attributes that are specified in the call to the file create function must match the attributes that are currently set on the existing file. New attributes are combined with a bitwise OR into the existing attributes; that is, existing attributes cannot be cleared, but additional attributes can be specified.

    The file create function is used with the file overwrite if disposition on a file name that does not exist. The status returned should be a file created success. Next the file create function is used with the file overwrite if disposition on a file name that exists and contains data, this should return a success message, and a file overwritten status. A read is done on the file and there should be no data in it.

  • OverwriteAlwaysAllocTest. The file overwrite if disposition does not require an existing file. The file create function is used with the file overwrite if disposition on a file name that does not exist. The status that is returned should be a file-created success. Next, the file create function is used with the file overwrite if disposition on a file name that exists and contains data, this should return a success message and a file overwritten status. The file is read and no data should be found in it.

    The test is repeated with an allocation size that is specified in the file create function. The allocation size is then queried, and it is verified to be a multiple of the minimum allocation size.

    The test is repeated on a hidden system file, when the file create function is called with the file overwrite if disposition, the media write protected error is returned. The test is repeated, this time on a file that is read only; the call to the file create function with the file overwrite if disposition should fail with an access-denied error.

  • OverwriteAlwaysAttrTest. The file overwrite if disposition does not require an existing file. The file create function is used with the file overwrite if disposition on a file name that does not exist. The status that is returned should be a file-created success. Next the file create function is used with the file overwrite if disposition on a file name that exists and contains data; this test should return a success message and a file overwritten status. The file is read and there should be no data in it.

    The test is repeated on a hidden system file, when the file create function is called with the overwrite if disposition, the media write protected error is returned. The test is repeated, and this time on a file that is read-only. The call to the file create function with the overwrite if disposition should fail with an access-denied error.

  • FileAllocationSizeTest. The allocation size of the file can be specified at creation time. The allocation size is the amount of space the file takes up on the storage device. The actual size of the file is marked by the end-of-file pointer. The minimum allocation size varies based on the file system and volume. The file create function is used with a specified allocation size to reserve the storage for several files. Each file requests a different allocation size. Each file is then queried and verified for its allocation size. The size should be consistent with the specified allocation size, rounded up to the minimum allocation size allowed for the volume. Then a file is created with no allocation size specified. The default allocation size should be zero, and this result is verified.

  • ExecuteAccessTest. The file execute disposition causes the file system driver to update the last-accessed-time on a handle close. The last access time is read from the file and recorded. The file create function is used to open a sample executable file with the file execute disposition. The handle is then closed. The last access time is then checked and verified to be updated.

  • HiddenAttributeTest. The attributes of a file can be set at file creation time. If the hidden attribute is set on a file, the file reflects this attribute information with the query directory file function. A test file is created with the hidden attribute set. The query directory file is used to verify the existence of the flag in the returned information on the file.

  • NormalAttributeTest. The attributes of a file can be set when the file is created. If the normal attribute is set on a file, the file reflects this attribute information with the query directory file. Normal file attributes are not read- only, hidden, system, directory, or archive. A file is created with the normal attribute set. The file is then closed. The query directory file is then called to verify the absence of the following attributes: read-only, hidden, system, directory, or archive.

  • DirectoryAttributeTest. The directory attribute designates a file as a directory. The file system should set the attribute when a new directory is created. If the directory attribute is set on a file, the file reflects this attribute information with the query directory file. A test directory is created and the query directory function is called on the directory that contains this test directory to verify the existence of the flag in the returned information on the directory. A new file is then created, and the query directory file function is called to verify the cleared directory attribute flag in the returned information on the file.

  • CreateFileDirTest. The file create disposition does not allow an open on an existing directory. This disposition will create a new directory if the directory does not exist, and it returns an error if the directory already exists.

    The file create disposition is used to create a directory that does not exist. This operation should succeed. Next, the file create disposition is used to create a directory that does exist. This operation should fail with an access-denied error.

  • ArchiveAttributeTest. The attributes of a file can be set when the file is created. If the archive attribute is set on a file, the file will reflect this attribute information with the query directory file. The archive attribute should be set any time a file is created or modified without the archive attribute specified in the call to the file create file function. A file is created with the archive attribute set. The query directory file is used to verify the existence of the flag in the returned information on the file.

    The test is repeated on a file without the archive attribute set. The attribute should be set after the handle to the file is closed. The test is repeated with four permutations of cached/no buffering and synchronous/asynchronous. The test file is again opened, and the archive bit is cleared. The handle to the file is then closed. The file is then queried, and it is verified that the archive bit is not set. The file is again opened, and a few bytes are written to the file. The handle to the file is then closed. The query directory file is called again to verify that the archive bit is set.

CloseCleanupDelete File System Test Group

The following tests are included in this group:

  • VolumeUnlockOnCloseTest. The volume can be opened directly for Direct Access to Storage Device (DASD) access. Input/output (I/O) buffers must subsequently be sector-aligned direct or buffered. The volume is auto-locked as a result of a DASD open. The semantics for the DASD open are tested in OpenVolumeTest. No additional files can be opened on the locked volume (even with minimal or no desired access).

    The test opens the volume with auto-lock and attempts to open a file. The operation is verified to fail as a result of the locked volume. The handle to the open volume is then closed. When the DASD handle is closed, the volume should release the volume lock. This result is tested by attempting to open a file again. This time, the file open should succeed.

  • UpdateOnCloseTest. A directory handle can be used to find a file that is contained in that directory and obtain the file times, attributes, end-of-file pointer, and allocation size. If handles on the file are open, changes that have been made to the file time, attribute, end-of-file pointer, and allocation size information might differ from the information that is read through the open directory handle. The information is updated when the last open handle to the file object is closed. This action sends out IRP_MJ_CLEANUP.

    This test first creates a number of files, verifies the file information by using a directory handle, and queries. The files are then opened, written to, and read from. The file information is again queried and checked to see that it has not updated. The file handles are then closed. The file information is again queried and the updated information is verified.

    The test is repeated, but the updated (but not committed) information is changed by using IRP_MJ_SET_INFORMATION. The information that was updated by using the set information IRP is verified when the file handles are closed. The test verified that the set information overwrites any other updated information when the IRP_MJ_CLEANUP causes the file system driver to reconcile the information.

  • UpdateOnCloseDirTest. A directory handle can be used to find a subdirectory that is contained in that directory and obtain the file times, attributes, end-of-file pointer, and allocation size of the subdirectory. The end-of-file pointer and allocation size should be returned as zero. If handles are open on the subdirectory, there might be a difference between changes that have been made to the subdirectory, with regards to the above information, and the information that is read back through of the open directory handle (of the directory that contains the subdirectories). The information is updated when the last open handle to the file object (for the subdirectory) is closed. This closure sends out IRP_MJ_CLEANUP.

    This test first creates a number of subdirectories, verifies the file information through a container directory handle, and queries. The subdirectories are then opened, access by listing, and modified by creating files inside of those test subdirectories. The file information is again queried and checked to see that it has not been updated. The subdirectory handles are then closed. The file information is again queried, and the updated information is verified.

  • TruncateOnCloseTest. If the allocation size is larger than the file size, the file system should reduce the allocation size to the smallest possible size, rounded up to the nearest minimum allocation unit. The allocation size is reduced when IRP_MJ_CLEANUP is sent to the file system. This IRP corresponds to the close of the last open handle to a file object.

    This allocation size reduction is tested with a file whose allocation size is set at creation time. The file is then written with a much smaller amount of data than the allocation size. The handle is then closed. The file is again opened (allocation size not set on open), and the allocation size is checked to see that it has been reduced.

  • TunnelingTest. The short naming convention is in the 8.3 format. Both FAT and NTFS file systems have two namespaces. These namespaces should map to the same files. When a file is created with a name that is not in the 8.3 format and ASCII code page, a short name representation can also be created. The short name can be used to access the file by a Microsoft MS-DOS or Microsoft Windows operating system. The short name can also be used by Windows NT to access the file. A problem arises when legacy applications delete files by their short names and then try to re-create these files. Namely, the long names would be lost. The tunneling cache in the FAT and NTFS file systems takes care of this problem. The cache is process-specific and directory-specific. When a file is deleted and created again by using its short name only, the long name is re-applied to the file.

    This test first opens a test directory. The directory handle is then used to create several files with long names in that directory. The different directory handle is then used to query for long and short name information. The handles to the files are closed. The files are then deleted.

    Files are created by using the directory handle and the previously queried short names. A different directory handle is then used to query the directory for file name information. The long file names are thereby verified.

  • DeleteOnLastCloseTest. Files are deleted on the final handle IRP_MJ_CLEANUP that have previously been marked for deletion. There are two mechanisms for marking a file for deletion. The first is from open or create with the option to delete on close. The second is to set the file information to mark the file to be deleted on close. These two mechanisms have different semantics.

    The following rules describe the purpose of this test:

    • When a handle is opened for delete on close, that handle is now a delete-on-close handle.
    • When a delete-on-close handle is closed (in the IRP_MJ_CLEANUP path), the file is then (and only then) marked for deletion and becomes a delete-on-close file.
    • When the file is deleted through a set information call, the file is marked for deletion and becomes a delete-on-close file.
    • No additional handles can be opened on a delete-on-close file (that is, a file that has been marked for deletion). Such attempts will fail with STATUS_DELETE_PENDING.
    • A query for deletion pending to a file that is a delete-on-close file returns TRUE.
    • When the file information is set not to delete the file on close, the file is unmarked for deletion and is no longer a delete-on-close file. The handle that received the set information call might still be a delete-on-close handle, in which case the file again becomes a delete-on-close file when the handle is closed.
    • When the final handle to a delete-on-close file is closed, the file is deleted.

VolumeInformation File System Test Group

The tests in this group include:

  • VolumeLabelTest. Each volume maintains a label that can be queried and set. This test opens up a handle to a volume and queries the volume information. The volume handle is then closed and two handles, a directory handle and file handle, are then opened. A volume information query is done on both handles and verification is done to make sure the volume information matches that which was queried with the volume handle. Next, the volume label is changed and a query is done to make sure that the label did get changed. If the label was changed, then the original volume label is restored and the test is complete. The test is run three more times to test certain error conditions. First, the test attempts to change the volume label with a directory or file handle. This attempt should return an access-denied error. Second, an attempt is made to set the volume label to a string that is more than 32 Unicode characters long. This attempt should return a invalid volume label error. Third, an attempt is made to query the volume information with a small buffer. This attempt should return a buffer overflow error.

  • VolumeInformationTest. The creation time, serial number, and volume label are applied to the volume at format time. The operating system can query the volume for this information. This test is run three times, opening up a volume handle, directory handle, and a file handle. Each handle is then queried for volume information and the following fields are all verified: volume creation time, volume serial number, volume label length, support objects, and volume label.

  • SizeInformationTest. The size information that can be queried gives information about the allocation units on the volume. The allocation unit is the smallest unit of space that can be allocated on a volume. For example, a file that stores one byte allocates the allocation unit size on the volume. This information is verified here and is used in other tests. This test is run three times, opening up a volume handle, directory handle, and file handle. Each handle is then queried for volume size information and the following fields are all verified: total allocation units, available allocation units, sectors per allocation unit, and bytes per sector.

  • DeviceInformationTest. The characteristics of a volume device can be queried along with the device type. This test is run three times, opening up a volume handle, directory handle, and file handle. Each handle is then queried for volume device information and the following fields are verified: device type and characteristics.

  • AttributeInformationTest. The attributes are initially set during volume formatting. The attributes contain important information about the capabilities of the file system with the volume. This test is run three times, opening up a volume handle, directory handle and a file handle. Each handle is then queried for volume attribute information and the following fields are all verified: file system attributes, maximum component name length, file system name length, and file system name.

FileInformation File System Test Group

The tests in this group include:

  • AllInformationTest. The basic information, standard information, internal information, extended attribute (EA) information, position information, and name information can all be queried on a file at the same time. A file handle or directory handle is opened and the file is queried for all of the information: creation time, last access time, last write time, change time, file attributes, allocation size, end-of-file pointer, number of links, delete pending flag, directory flag, index number, EA size, long file name, long file name length, and current byte offset. All of these values are compared to the known values obtained when the file or directory is created. If all match, then the test has passed.

  • AllocationInformationTest. The allocation size of a file can be set to truncate or extend the file. The allocation size is the amount of space the file system reserves for use by the file. This allocation size can be initialized at create time and later changed. This size is changed automatically by writing beyond the end-of-file. The file size is different from the allocation size. The allocation size must fall on an allocation unit boundary, but the file size can be any value at or before the currently allocated size. A test file is opened with a non-zero allocation size. A query is performed to make sure that the allocation size is equal to what was set when the file was created. Then the allocation size is reduced, which should truncate the file. A query is performed to make sure the allocation size was reduced. If the size was reduced, then the allocation size is even further reduced and another query is performed to make sure the size decreased. A separate query is performed specifically on directory files to verify the change in allocation size. Next, the allocation size is increased on the file and a query is performed to verify this increase. If all of these changes in allocation size are verified, the test is passed.

  • ZeroAllocationInformationTest. A test file that has an allocation size of zero is opened. Then, 1000 bytes of data are written to this file. A query is then performed to obtain the allocation size, which is expected to be a multiple of 512. If this query passes, a second query is done on the file as a directory file. This type of query should return a zero for the allocation size because the allocation size will not be updated on the directory file until the handle to the directory file is closed. If this query passes, the file handle is closed and a second query on the directory file is done to make sure the allocation size is a multiple of 512.

  • CompressionInformationTest. The compression information for the file can be queried if the file system supports file compression. This query returns information about the compression that is used if the file is compressed. Two test files are opened (one that is compressed and one that is not). A query is performed on both files and a check is performed to make sure that the uncompressed file size is greater than the compressed file size.

  • DispositionInformationTest. Files are deleted on close. A file is deleted when a flag is set in the file object. The file can also be flagged to be deleted on close when the file is created. A file handle is opened on a test file and the deletion flag is then set on the file. A query is performed to make sure the Delete Pending flag is set, and then the file handle is closed. Next, an attempt is made to open the deleted file. If this action fails, it has verified that the file was deleted.

  • EndOfFileInformationTest. The end-of-file position can be changed. The end-of-file position marks the actual end-of-file for data reading and writing purposes. The end-of-file position is less than or equal to the allocation size because the granularity of allocation in the file system is usually a power of 2 sectors. This test checks the original size of the file when it was created, and then the end is moved towards the beginning of the file. The allocation size is checked to make sure it was reduced to the nearest possible size. Next, the end-of-file pointer is moved toward the end of the file. The allocation size is checked to see if it is enlarged.

  • LinkInformationTest. This test checks that hard links to an open file can be created. When the file is opened with the linked file name, the data and queried information in the file should look identical to the original file. A file with test data is opened, and a link to the file is created. The file is then closed. The file is opened again, this time by using the link. The data in the file is read and compared with the original data in the file, which should be the same. Next, all of the attributes are compared against the original attributes of the file to see if they are the same. The following data is checked: file attributes, creation time, last access time, last write time, change time, allocation size, end-of-file pointer, number of links, delete pending flag, directory flag, index number, ea size, and current byte offset.

  • SimpleRenameInformationTest. A file or directory can be renamed only within a volume. The root directory cannot be renamed. The rename target can specify either a file or a directory. A handle to a file is opened, and it is renamed to a nonexistent file name. The same is done with a directory. Next, an attempt is made to rename a root directory. This operation should fail with an invalid parameter error. Next, a rename is attempted on a file between two volumes; this rename should also fail with an invalid parameter error.

  • ConflictingRenameInformationTest. A test file is opened and an attempt is made to rename the file to an existing file name. If the file attribute, Replace If Exists, is set, a file can be renamed to an existing file name; otherwise, an error is recorded. When the test file or directory is renamed to an existing file name (Replace If Exists not set), an invalid parameter error occurs. This rename process is attempted again but with the Replace If Exists flag set. This operation should succeed. Next, a second test file is opened twice (two handles are opened to the same file). A file rename is attempted on both handles, and both attempts should return an access-denied error.

  • AlternateNameInformationTest. The long name can be used to obtain the 8.3 file name with a query call. A file name that is more than 15 characters is opened, and data is written to the file. The file is queried to obtain its 8.3 name. The handle to the file is then closed. The file is reopened by using the 8.3 name from the query. The data from the file is read and verified to ensure that it is correct.

  • FileNetworkOpenInformationTest. Network open information is another file information class that can be queried. This information includes creation time, last access time, last write time, change time, allocation size, and end of file. A test file is opened, and the following information is queried and verified: creation time, last access time, last write time, change time, allocation size, and end of file.

  • StreamInformationTest. A file can be queried for the file information. This information includes the stream name, size in bytes, and allocated size in bytes. A primary data stream is written with data. Alternate data streams are created with unique and varying amounts of data. The stream names are verified to be of the format ".%stream name%:DATA$. The stream sizes and allocation sizes are verified. The allocation size should have a granularity of 8 bytes.

  • StreamStandardInformationTest. The standard information, allocation size, and end-of-file pointer should be unique for each stream. The number of links and delete pending information should be common for all streams in the file. A test file that contains multiple streams is opened and the following information is queried and verified: allocation size, end-of-file, number of links, delete pending flag, and directory flag value. A single file handle is used to mark the file for deletion. A different file handle is queried and the Delete Pending flag is verified to be set. A link is made to an open stream handle, and all of the open handles are queried to check the Number of Links value.

  • BasicInformationTest. Basic information can be queried or set. This information includes the file attributes, which are initialized when the file is created. It also includes all of the time stamps on the file including creation and various access times. This test involves opening up a file or directory handle and querying the creation time, last access time, last write time, change time, and file attributes. These values are compared to the known values that are obtained at creation time. If all values are correct, these values are changed. The file is queried again to make sure that the changes have been made.

  • StandardInformationTest. Standard information on a file can be queried. The allocation size is the amount of space that is allocated for the file. The end-of-file pointer points to the end of the file and must be contained in the current allocation size. This end-of-file pointer marks the actual end of the file. The number of links indicates the number of hard links on the file. The delete pending flag indicates the file is marked for deletion and the deletion occurs when all handles to the file are closed. The directory value indicates if it is a directory. This test opens a file or directory handle and queries the standard information on the file: allocation size, end-of-file pointer, number of links, delete pending, and the directory value. All of these values are then compared to the known values.

  • InternalInformationTest. The index of the file is a unique and persistent 64-bit integer. The index value of the file can be used to open up a file (this type of file open might not be supported by all file systems). A file handle or directory handle is opened and the internal information of the file is queried (the query returns the index number of the file). The file handle is then closed. The file is again opened and the index number is queried. Verification is done to make sure that the two index numbers match. If they match, the test is successful.

  • EaInformationTest. The extended attribute size on the file can be queried. This size is the size of the extended attribute information that is stored with the file. A file handle is opened, and the EA information is then queried. The EA size is compared to the known EA size. If they match, then the test is passed.

  • NameInformationTest. The name of the file can be queried. This name is the long file name and the length of the file name. A file handle or directory handle is opened and a query is performed to obtain the long file name and the file name length. The long file name is compared to the file name that was used to open the handle; if they match the test is passed. The test is repeated with a small buffer to query the file name data; this is done to see if a buffer overflow error is returned by the query.

EaInformation File System Test Group

The tests in this group include:

  • FullEaInformationTest. All of the extended attribute (EA) information for a file can be accessed at once. The test file that is used for this test has three extended attributes, each with 4 bytes of data. This file is opened with access privileges that permits its EA data to be read. The file is queried to read out all the EA entries that are associated with this file at once. The data and labels that are returned are verified.

  • ListEaInformationTest. The EA information can be selectively queried based on a list of EA names. The test file that is used for this test has three EAs, each with 4 bytes of data. This file is opened with access privilege that permits its EA data to be read. A query list with a label to just the second entry is created and a query is performed on just the second EA entry. The data that is associated with the second EA entry is verified. Then, the query list is created with a label to just the third entry, and a query is performed on just the third EA entry. The data that is associated with the third EA entry is verified. The same is done for the first entry.

  • IndexEaInformationTest. The EA information can be selectively queried based on an index value. The test file that is used for this test has three Extended Attributes (EA), each with 4 bytes of data. The file is opened with access privileges that permit its EA data to be read. A query is performed that specifically indexes just the second EA entry. The data and label that are associated with the second entry is verified. Then, a query is performed specifically indexing the third EA entry. The data and label for the third entry is verified. The same query is done for the first EA entry.

  • CreateEaInformationTest. The EA information for a file can be specified at creation time. The test file that is used for this test has one EA with 4 bytes of data associated with it. This file is opened with access privilege that permits its EA data to be read. The file is then queried for its EA data. If the query is successful, the file has EA data associated with it, and the CreateEaInformationtest is passed.

  • SetEaInformationTest. The EA information for a file can be set after the file is created. The first part of the test uses a file that has no EAs associated with it. This file is opened with access privileges that permit its EA data to be written and read. First, the file is queried to check the size of the EA, because this file has no EA data the EA size is expected to be zero. Next, there are two EAs, each with 4 bytes of data set for the file. The file is queried one entry at a time, to verify the Extended Attributes that were just set (EA name and EA data). The first test file is then closed. The second part of the test uses a file that has one EA with 4 bytes of data associated with it. The file is opened with access privilege that permits its EA data to be written and read. The second file is queried to check the EA size matches the size of one EA with 4 bytes of data. Next, the existing EA is replaced with new data values, but the label is still the same. The file is queried again to check to see if the label matches that which is expected and to verify the data value change. Last the file is queried again to check that the EA size is that of an EA with 4 bytes of data associated with it.

  • SingleEaEntryTest. The EA information for a file can be read back one entry at a time. The test file that is used for this test has three EAs, each with 4bytes of data associated with it. This file is opened with access privileges that permit its EA data to be read. A query is performed from the start of the EA entries block to return just the first entry. The data and label that are associated with this entry are then verified. This operation is done two more times to verify the second and third EA entries, but these scans are not done from the start of the EA entries block for these two iterations. The scans are done from after the last EA entry that was queried.

DirectoryInformation File System Test Group

The tests in this group include:

  • FullDirectoryInformationTest. The access times, end-of-file pointer, EA size, and allocation size for the files in a directory can be queried. This test is run four times on a directory with four files that have different allocation sizes. The file is opened, and then some data is written to the file. This write operation should update the last access time, last write time, and change time of the file after the file is closed. The file is then reopened and queried for the times, allocation size, EA size, and end-of-file pointer. These values are then checked.

  • FileNameDirectoryInformationTest. The file names and file name length parameters can be queried of a specific directory. Four different files are opened and the file names and file name lengths are checked for each of these files. If the file names and file name lengths match, the test has passed.

  • FileDirectoryInformationTest. The access times, end-of-file pointer, and allocation size for the files in a directory can be queried. This test is run four times on a directory with four files that have different allocation sizes. The file is opened and then data is written that should update the last access time, last write time, and change time of the file after the file is closed. The file is then reopened and queried for the times, allocation size, and end-of-file pointer to confirm that the values have changed.

  • BothDirectoryInformationTest. The access times, end-of-file pointer, and allocation size for the files in a directory can be queried. This test is run four times on a directory with four files that have different allocation sizes. The file is opened and then data is written that should update the last access time, last write time, and change time of the file after a close. The file is then reopened and queried for the times, allocation size, and end-of-file pointer to confirm that the values have changed.

FileLocking File System Test Group

The tests in this group include:

  • LockSharedExTest. This test tests the use of exclusive and shared byte range locking in multiple processes. Process A obtains some exclusive and shared locks on a file. The correct read and write accesses are tested in these locked regions. Process B then attempts to obtain locks on these same regions. These operations are checked for failure. Process B then attempts to access the areas locked by Process A. Correct access is verified.

  • UnlockRangeTest. Process A obtains some exclusive and shared byte range locks on a file. Process A then verifies proper access to the locked regions. Some of these locked regions are then unlocked. Process B attempts access to the still locked and recently unlocked regions. Correct access is verified. Process B then attempts locks on the areas previously locked by Process A. These operations are checked for success.

  • LockOverlapTest. Several exclusive and shared locked ranges are obtained on a file. Overlapping exclusive locks are attempts on locked exclusive regions. Failure is verified for these locking attempts. Shared locks are then attempted on the exclusive and shared locked regions. Success is verified for these attempts.

  • LockRangeTest. Process A locks a whole file with exclusive and shared locks. Proper access is verified when the entire file is locked. Process A then locks a range larger than the current file. Process B attempts access to the area beyond this locked region. This attempt should succeed. Process B then attempts access to the area locked by Process A when the file was smaller than that area. The byte range lock that A holds should be verified on this range in terms of obtaining a lock on the same region.

  • LockFailImmediateTest. The file locking API can be set to fail immediately if a lock is currently held on the region of the file. This failure is tested with a synchronous file handle. The blocking of the thread by the alternate process is tested until the lock is release. The fail immediately will not block with a synchronous handle.

  • LockOverlappedTest. The file locking API can be used with events for synchronization. The APIs are used between two processes. Process A obtains a lock on a byte range. Process B then attempts to obtain a lock and waits on the event handle. This wait should not time out, but the event should become signaled when the lock is released by Process A.

  • UnlockAllTest. Several locks are obtained on a file handle. This handle is then closed. The same locks are attempted with another file handle that is obtained before the first file handle is closed. The locks are again attempted and should be granted since they were all unlocked with the handle close.

  • UnlockRangeOnCloseTest.

    • Start Process A.
    • First get two handles.
    • Obtain some locks on handle 1.
    • Try and fail to obtain same locks on handle 2.
    • Obtain some other locks on handle 2.
    • Start of thread
    • Thread will close handle 1 at t=1 seconds.
    • Thread will close handle 2 at t=2 seconds.
    • Start Process B.
    • Try and fail to obtain all locks on handle 1 and 2.
    • Wait till t=1 second and obtain locks that were on handle 1 only.
    • Wait till t=2 second and obtain locks that were on handle 2.
  • LockKeyTest.

    • Process A gets some shared and exclusive locks.
    • Process A attempts to access this data without key and fails.
    • Process A attempts to access WITH key and succeeds.
    • Process B attempts to access this data without key and fails.
    • Process B attempts to access WITH key and succeeds.

OpLocks File System Test Group

The tests in this group include:

  • BatchOplocksTest. The batch oplock is operationally equivalent to a level 1 op lock (that is, it is exclusive). The difference is that a Level 1I oplock is always backed by a real user handle, a batch oplock can be held by a proxy agent (such as Srv.sys) to indicate that it is keeping a file open in the expectation that a client will need it again. But if there is a reason for the file system to close the file, the system will close it.

    • C opens a test file for reading.
    • C requests a batch oplock on the file by using the FSCTL_REQUEST_BATCH_OPLOCK file control.
    • C should succeed at reading the file.
    • D opens the test file for reading and writing, but this action should be blocked because a break is pending.
    • The IRP from step 2 should complete indicating that the Batch Oplock has been broken. The Information should be FILE_OPLOCK_BROKEN_TO_LEVEL_2.
    • C sends the FSCTL_OPLOCK_BREAK_ACKNOWLEDGE control to the file system to acknowledge the break.
  • BreakNotifyTest. Additional IRPs can be queued to wait for a break to complete. These IRPs will wait for the full break to occur. That involves the completion of the original break IRP and the acknowledge cycle.

    • C opens a test file for reading and writing.
    • C requests a Level I oplock on the file using the FSCTL_REQUEST_OPLOCK_LEVEL_I file control.
    • The file should be written to and read from by C, this should succeed
    • D opens the test file for reading and writing, this should block. This is because the client holding a Level I oplock must be notified of break and the client's buffers flushed.
    • The IRP from step 2 should complete.
    • The FSCTL_OPLOCK_BREAK_NOTIFY control should be sent. This IRP should be queued since there is a break in progress.
    • C issues the FSCTL_OPLOCK_BREAK_ACKNOWLEDGE control. This will acknowledge the break to a level II lock.
    • The IRP from step 6 should now complete indicating that there is now no break in progress.
    • C and D close the file.
  • FilterOplockTest. There is currently no description for this test.

  • CompleteImmediatelyTest. Normally an open to a file that has an oplock will block until the file's oplock is broken. There is a file option that can be specified at open time called FILE_COMPLETE_IF_OPLOCKED that changes the blocking behavior. (This option was added to solve several deadlock conditions within the Srv.sys.) If this option is specified and the open is otherwise successful, the final status will be STATUS_OPLOCK_BREAK_IN_PROGRESS, which is an NTSUCCESS code. If the open fails for any reason, the final status will be the error code. In either case, the Information value will be FILE_OPLOCK_BREAK_UNDERWAY, which tells the caller that an oplock break has been initiated.

    1. A opens a file and requests a Level 1 oplock.
    2. B opens the same file with the FILE_COMPLETE_IF_OPLOCKED option set.
    3. The call should complete normally with FILE_OPLOCK_BREAK_UNDERWAY in the Information field regardless of the final Status of the create operation.
    4. The Oplock IRP from step 1 should complete.
    5. The same open should be attempted without the option.
    6. The call should then block until the oplock break on the file is acknowledged.
  • OplockReadBreakItoIITest. This test should be called the OplockWriteBreakIItoNone test. The only major IRP type that will cause a break is IRP_MJ_WRITE. This test was modified to test the breaking through the "data access FSCTL.

    1. C opens a test file for reading and writing.
    2. D opens the same test file for reading and writing.
    3. C requests a Level II oplock on the file with the FSCTL_REQUEST_OPLOCK_LEVEL_II file control.
    4. The file should be read by C, this should succeed.
    5. D attempts to write to the file issuing the IRP_MJ_WRITE request. This will be blocked because the client holding a Level II oplock must be notified of break to None and the client's buffers flushed.
    6. The IRP from step 3 should complete.
  • OplockLevel1Test. This test tests that Level 1 oplocks are exclusive.

    1. C opens a test file for reading and writing.
    2. D opens the same test file for reading and writing.
    3. C requests and receives a Level 1 oplock on the file with the FSCTL_REQUEST_OPLOCK_LEVEL_I file control. This request should fail with STATUS_OPLOCK_NOT_GRANTED because there is another handle outstanding.
    4. C and D close the file.
  • OplockSetInfoBreakTest. The IRP_MJ_SET_INFORMATION request will cause a break of a Level I or Level II lock to none. This break occurs because when this request is issued by a client, there are changes to critical information that logically invalidate the oplock. These include the following types of Set Information:

    1. FileEndOfFileInformation
    2. FileAllocationInformation
    3. FileRenameInformation
    4. FileLinkInformation

    The first two classes in the preceding list will break any oplock to none, while the latter two will break only batch oplocks to none. Note that the following test is for a single set operation. The following steps should take place 3 times, each time with a different information item being changed:

    1. C opens a test file for reading and writing.
    2. D opens the same test file for reading and writing.
    3. C requests a Level II oplock on the file with the FSCTL_REQUEST_OPLOCK_LEVEL2 file control.
    4. The file should be read from by C, this should succeed.
    5. D uses the NtSetInformationFile()to set the information file. This will be blocked because the client holding a Level II oplock must be notified of break to none.
    6. The IRP from step 3 should complete.
    7. The set information operation from step 5 should now become unblocked and complete successfully.
    8. C and D close their handles.
  • LockOplockBreakTest. Oplocks that are held against an open file object must be broken before the byte range file locking can be completed. The file system performs this break synchronously (the thread requesting lock is blocked until oplock notification cycle has been completed). This ability is tested with the following steps:

    1. Process C requests a Level II oplock on the file and receives back STATUS_PENDING, which indicates that the oplock has been granted.
    2. The file should read from by C; this read should succeed.
    3. Process D attempts to lock a range of the file by using the NtLockFile routine. This thread (of Process D) should block.
    4. The IRP that is obtained in step 1 should complete with FILE_OPLOCK_BROKEN_TO_NONE.
    5. The NtLockFile call from step 3 should now complete.
    6. Process C should attempt writing to the locked range of bytes. This operation should fail because Process D now holds a byte range lock on the file.
  • OplockBreakItoIITest. Only a single Level I oplock can be held on a file. When the file is opened a second time for reading or writing, the Level I oplock will be broken to a Level II. The original owner of the file can keep the Level II lock until the file is written to. The file can be read from with cached reads.

    1. C opens a synchronous handle to the test file for reading and writing.
    2. C requests a Level I oplock on the file. This request should return with STATUS_OPLOCK_NOT_GRANTED.
    3. C opens an asynchronous handle to the test file for reading and writing.
    4. C requests a Level I oplock on the file and receives back STATUS_PENDING, which indicates that the oplock has been granted. An event handle is used to signal an oplock break.
    5. The file should be written to and read from by C; this operation should succeed. The oplock should not break.
    6. D opens the test file for reading and writing; this operation should block. This iblock occurs because the client that is holding a Level I oplock must be notified of break and the client's buffers flushed.
    7. The IRP from step 4 should complete and the event signaled in process C.
    8. C issues the FSCTL_OPLOCK_BREAK_ACKNOWLEDGE control. This control will acknowledge the break to a Level II lock. This FSCTL returns STATUS_PENDING.
    9. The blocked that is open from step 6 should now become unblocked.
    10. C should be able to read from the test file without the Level II oplock breaking.
    11. D should also be able to read from the file without the Level II oplock breaking.
    12. C and D close the file.
  • OplockIIWriteBreakingTest. If a Level II oplock is held by a file, and the file is written to, the oplock will be broken. This break can occur only by a file that has opened the file for read and write access and originally obtained a Level II oplock on the file. It could not occur with any but the first because subsequent opens with the write ability will cause the oplock to break on open. This test simply tests that a write in another process will break the Level II oplock, and a subsequent write operation is successful.

    1. C opens a test file for reading.
    2. C requests a Level II oplock on the file.
    3. The file should be read from by C, this should succeed.
    4. D opens the test file for reading and writing. This breaks the level II oplock.
    5. D then attempts to write to the file. This should be successful.
    6. Both files handles are closed.
  • OplockBreakIItoNoneTest. If a file is written to when a Level II oplock is maintained on the file, the level II oplock is broken to none. The write IRP is queued until the lock is completely broken through the notify-response protocol.

    1. C opens an asynchronous handle to a test file for reading and writing.
    2. C requests a Level I oplock on the file and receives STATUS_PENDING
    3. The file should be written to and read from by C; this operation should succeed.
    4. D opens the test file for reading only; this operation should block because the client that is holding a Level I oplock must be notified of the break and the client's buffers flushed.
    5. The IRP from step 2 should complete with FILE_OPLOCK_BROKEN_TO_LEVEL_2.
    6. C issues the FSCTL_OPLOCK_BREAK_ACKNOWLEDGE control to acknowledge the break to a level II lock.
    7. The blocked open from step 4 should now become unblocked.
    8. D should also be able to read from the file without the level II oplock breaking. These reads will not be cached reads because D does not hold an oplock.
    9. C should be able to read from the test file without the level II oplock breaking.
    10. D should try to write to the file. This attempt should break the level II oplock held on the file by C with FILE_OPLOCK_BROKEN_TO_NONE.
    11. The IRP from step 6 should complete.
  • OplockBreakIandIIOnCloseTest. When a file is closed, Level I or Level II oplocks are broken. This is tested by opening a file with a level I and then level II oplock and closing the file. The breaking of the locks is verified and the correct protocol state is verified by attempting subsequent access. Normally, the break would require a response before the subsequent access would be allowed.

    1. C opens a test file for reading and writing.
    2. C requests a Level I oplock on the file.
    3. The file should be written to and read from by C; this operation should succeed.
    4. C closes the file.
    5. The IRP from step 2 should complete indicating the Level I oplock is broken. The information will show FILE_OPLOCK_BROKEN_TO_NONE.
    6. D opens the same test file for reading and writing. This operation should not block because the oplock has been deleted from the system.
    7. D requests and receives a Level II oplock on the file.
    8. The file should be read from by D. This operation should succeed.
    9. D closes the file.
    10. The IRP from step 7 should complete to indicate that the Level II oplock is broken. The information will show FILE_OPLOCK_BROKEN_TO_NONE.
  • OplockRequestIITest. Multiple files can maintain level II oplocks on a file. This ability enables efficient, cached access by multiple readers.

    1. C opens a test file for reading and writing.
    2. C requests a Level II oplock on the file by using the FSCTL_REQUEST_OPLOCK_LEVEL_II control operation.
    3. The file should be read from by C; this operation should succeed.
    4. D opens a test file for reading and writing.
    5. D requests a Level II oplock on the file by using the FSCTL_REQUEST_OPLOCK_LEVEL_II control operation.
    6. C should be able to do cached reads from the file.
    7. D should be able to do cached reads from the file.
    8. C and D close the file.
  • OplockIIOpenBreakingTest. A level II oplock can be broken with a subsequent open. If the open is for read and write access, the level II oplock will be broken to none.

    1. C opens a test file for reading and writing.
    2. C requests a Level II oplock on the file.
    3. The file should be read from by C, this should succeed.
    4. D opens the test file for reading and writing, this should block since the file has an open oplock.
    5. The level II oplock obtained in step 2 will be broken.
    6. The blocked open from step 4 should now become unblocked.
    7. C and D close the file.

ChangeNotification File System Test Group

There are many combinations of FILTERS, CAUSES, and ACTIONS. The notification events table is used for a coverage test of all expected notification behavior. A file handle is opened in the test directory and a thread is created that will write to the file. Meanwhile, in the main thread, the write is waited upon for 4 seconds; and if the write does not occur, a time-out will happen. When the write does occur, the event is triggered and the test will make sure the correct ACTION was reported. The following tests make up this group:

  • NotificationCleanupAttribTest. This tests that the original DACL is reset to allow the test file to be deleted during cleanup. All notification events should complete.

  • NotificationCleanupFileSizeTest. This tests that the original DACL is reset to allow the test file to be file size returned during cleanup. All notification events should complete.

  • NotificationCloseTest. When an open file handle is closed, all pending notifications should be completed. A file handle is opened in the test directory and a thread is created that will close the file handle. Meanwhile, in the main thread, the close of the file handle is waited upon for 4 seconds; if the file handle is not closed in the time allotted, a time-out will happen. All notification events should complete.

  • NotificationDeleteTest. When a directory is actually deleted, or marked for deletion, all pending notifications on changes in that directory must be completed. A file handle is opened in the test directory and a thread is created that will mark the file for deletion and then close the file handle (this close should then delete the file). Meanwhile, in the main thread, the delete of the file is waited upon for 4 seconds; if the delete does not occur, a time-out will happen. When the delete does occur, the event is triggered and the test will make sure the correct ACTION was reported. This test is then repeated, but instead of deleting the file in a separate thread, it is done in the main thread. When the notification is waited on, a STATUS DELETE PENDING should come back.

  • NotificationFilenameTest. Any changes in the file names in a directory or subtree can be used to trigger a notification event. These changes include renames, creations, and deletions. First, a file handle is opened in the test directory and a thread is created that will rename the file. Meanwhile, in the main thread, the renaming of the file is waited upon for 4 seconds; if the notification does not happen, an error has occurred. When the rename does occur, the event is triggered and the test will make sure the correct ACTION was reported. This test is repeated two more times: once with a file that is created in a separate thread and once with a file that is deleted in a separate thread.

  • NotificationFlushWriteTest. This tests the flushing of the cache before the volume is locked.

  • NotificationNonDirectoryTest. The only way a notification can occur is if a directory handle is supplied to the notification change function. A call made with any other function should return an invalid parameter error. First a file handle is opened in the test directory and a thread is created that will write to the file. Meanwhile, in the main thread, the write of the file is waited upon for 4 seconds;, if the notification does not happen, an error has occurred. This test is repeated but this time a file handle is supplied to the notification function; this operation should return back with an invalid parameter error.

  • NotificationSecurityTest. Any changes in the security descriptors of a file in a directory or subtree can be used to trigger a notification event. A file handle is opened in the test directory and a thread is created that will change the security descriptors of the file. Meanwhile, in the main thread, the changing of the security descriptors of the file is waited on for 4 seconds, ;if the notification does not happen, an error has occurred. When the security descriptor change does occur, the event is triggered and the test will make sure the correct ACTION was reported.

DeviceControl File System Test Group

The tests in this group include:

  • DeviceIOControlTest. The create file function is used to open a file system-related device object such as a partition or floppy device. Device I/O commands are passed through the file system to the device driver directly. The "\DosDevices\?: device is opened where ?: is a DOS drive letter for the volume that is being tested. This test will issue a Device I/O Control command. A successful completion of the command and inspection of the returned information for accuracy will verify the path through the file system driver to the underlying device driver. This test is repeated by using APC completion to help detect file system bugs in request completion.

FileSystemControlVolume File System Test Group

The tests in this group include:

  • ControlDismountVolumeTest. Dismounting a volume disconnects a volume object from its associated file system driver. This dismount can be used when converting volumes, as in the FAT to NTFS converter. The volume starts out as FAT, is dismounted, formatted for NTFS, and then remounted. When it is remounted, the volume will attach to the NTFS driver. The test for dismounting involves being able to see a mount request to the volume. That visibility is necessary because the first reference to the volume after it is dismounted will typically mount the volume back up. The mounting can be observed by the File System Control. Note that the volume can be dismounted ionly if it is locked. A test volume handle is opened and a dismount is issued to it. Next, a file open operation is attempted on a file on the test volume. This operation should fail with an access-denied error, but this open attempt will remount the volume. So a dismount is issued again to the test volume and this dismount should succeed.

  • ControlLockVolumeTest. The File System I/O Control interface can be used to lock the volume. The control file function call gets a handle to an opened volume as a parameter. There are two things that need to be tested. First, a volume can be locked only if there are no other open handles on the volume. This test will have to be performed on a non-system containing volume. Second, a volume is locked then unlocked by using the control file function.

    Next, the open volume handle is closed and a file handle is opened for a file on the test volume. An open is attempted on the test volume, but this operation should fail because there is an open file handle. If this operation succeeds, the volume handle and file handles are closed.

    Next, the volume handle is opened again and a lock is issued to the volume.

    Next, files and directory opens are attempted on the locked volume. These attempts should fail with access-denied errors. Next, files and directories are opened as a relative handle;, these attempts should also fail with access-denied errors.

    The next thing that is tested is the flushing of the cache before the volume is locked. This flushing is done by getting the volume statistics (specifically the read/write counters). Then, the test opens up a couple of files on the test volume and performs read and write operations on those files. After the read/write operations are performed, the volume statistics are again checked to see if they were updated. In the next part of the test, a lock is issued to an already locked volume; this attempt should fail with an access-denied error.

    The volume is issued an unlock now and then the lock is issued again. This lock should return a success.

  • ControlUnlockVolumeTest. The file system control checks that the open volume handle is closed and a file handle is opened for a file on the test volume. An open is attempted on the test volume, but this attempt should fail because a file handle is open. If this attempt succeeds, the volume handle and file handles are closed. See the steps in ControlLockVolumeTest.

  • VolumeMountedTest. The File System Control checks to see if a volume is mounted. This check can be used in conjunction with the dismount control. First, the test volume handle is opened and a dismount is issued to it. Next, the File System Control checks if the volume is mounted is issued. For NTFS, this check should come back with a success; but on FAT volumes, this check will return the wrong volume error.

  • MountedDirtyTest. This File System Control marks a volume as permanently dirty. This operation is done when there has been a corruption detected in the metadata. First, the test volume is opened and the File System Control is issued that will mark the volume dirty. This test is not complete until a restart is performed and the Chkdsk program gets initiated.

  • InvalidateVolumesTest. The File System control that invalidates volumes will search for all of the volumes that are mounted on the same real device and mark them all bad. This marking prevents their further use in the system, because the only operations that can be done on such handles are cleanup and close. First, two test files are opened on the test volume. Next, the test volume itself is opened and an invalidate volumes control is issued to it. A read is performed on both test files and these attempts should return with the invalid handle error. Next, the file handles are closed and then reopened again. The reads are attempted and this time they should succeed.

  • MountVerifyVolumesTest. Mounting is tested implicitly by many of the tests and the test groups. In this test, multiple files are opened on a removable media volume. The removable media is replaced with new media. The error wrong volume will be returned when the handles to the opened files are used to access the files. The original removable media has some files that are modified with new file sizes. A success will be returned when the handles to the opened files are used to access untouched files. The invalid file error will be returned when the handles to the files, which had modified file sizes, are used to access the files.

  • ControlLockVolumeFlushTest. This test tests the flushing of the cache before the volume is locked. Data is written to the file. Statistics on the volume are obtained. The number of bytes written to the block device, the end-of-file pointer, and the last write time should be updated from the flush.

FileSystemControlGeneral File System Test Group

The tests in this group include:

  • QueryRetrievalPointersTest. This test is used only when a new page file is created. The retrieval pointers are queried from the file system for the file so that they can be used later in writing the crash dump to the paging file. This test has not been implemented.

  • GetRetrievalPointersTest. The retrieval pointers consist of a list of extents. An extent is a VCN- to-LCN mapping. This test first creates a file and writes data to the file. Next, the retrieval pointers are obtained by using FSCTL_GET_RETRIEVAL_POINTERS. Additional data is appended to the end of the file. The retrieval pointers are again obtained by using the FSCTL. The additional VCN-to-LCN mapping (for the added clusters) is then observed.

  • SetCompressionTest. The File System Control can be used to compress an individual file on the volume if the File System supports this feature. First, a query is performed on the file system to see if it supports file compression. If the file system supports compression, a test file is opened and a checksum is performed on an uncompressed file. Next, a File System Control is issued to the uncompressed file handle to compress it. The file size is checked to make sure it is less than the file size of the uncompressed file. Next, the file handle is closed then reopened again. Now the File System Control to compress is issued again; this control should uncompress the file. The file size is checked to make sure that it is the same as it was before the compression. The checksum is performed and the result is compared to the checksum of the file prior to compression; these values should be equal.

  • GetStatisticsTest. The File System Control can be used to return the file system performance counters for the volume referred to. This test is performed by opening up a volume handle and then issuing the file system control that will get the volume statistics. The volume handle is then closed and two test files are opened on the volume. After a few read and write operations are performed on these test files, the file handles are then closed. The volume is then opened again and the statistics are retrieved. The read and write counters are then checked to see that each counter is incremented by known increments.

  • PathNameValidTest. This test is supported only on Fat Compatible Volumes. This File System Control checks a path for valid characters, leading backslashes, and for wildcards. It passes the string to the file system to check. This check entirely depends on the syntax of the file system path. A volume handle is opened and two test path are checked. The first path is a valid path and the second path checked is an invalid path.

  • GetVolumeBitmapTest. The volume bitmap is a sequence of bytes that indicate a mapping of used and unused clusters. Each cluster is mapped to a single bit in this bitmap. This test exercises the FSCTL and does a simple test of the bitmap. The volume is opened and the bitmap is obtained. The number of allocated and unallocated clusters is counted. Next, a file is opened on the volume and a significant amount of data (1 MB) is written to the file. The bitmap is again obtained. The allocated clusters count should increase by the amount that is necessary for the new file.

  • MoveFileTest. The File System Control move file information class will move the logical clusters that a file uses to new logical clusters on the volume. A file is created and written with a known data pattern. The initial retrieval pointers are queried by using FSCTL_GET_RETRIEVAL_POINTERS. Next, the file's clusters are moved by using FSCTL_MOVE_FILE. The new retrieval pointers are queried. The expected change in the retrieval pointers is verified. The data is read from the file and checked for consistency.

  • AllowExtendedDASDTest. The File System Control, allow extended DASD I/O, specifies whether a DASD handle can be used to read or write beyond the end of the volume. A test volume is opened and a read is performed starting at the very end of the volume. This read is expected to return an end-of-file error. Next, a file system control, allow extended DASD I/O, is issued to the volume. A second read is performed, reading at the very end of the volume; this read should return with success.

ReadWrite File System Test Group

The tests in this group include:

  • ReadWriteTest. This test will test the reading from and writing to files that the file system manages. First, a synchronous file handle is opened to the test file and a buffer that is full of known data is written to the test file. Next, the data is read from the file and compared to the known data to see if it matches. If the data matches, the file pointer is reset to the beginning of the test file and the data is read again; this time, the parameter FILE_USE_FILE_POINTER_POSITION is specified as an offset to the read function. The handle is then closed. The test file is once again opened with a synchronous file handle and the data is read and checked once again. The file handle is then closed. A synchronous file handle is once again opened to the test file. A buffer that is full of known data is written to the test file, with the FILE_WRITE_TO_END_OF_FILE offset being specified to the write function. This write operation should append the data to the end of the test file. The file is read from and the data is checked. The file handle is then closed. Finally, an asynchronous file handle is opened to the test file and data is read from the file. A query is performed to make sure that the file pointer position did not change. The test is complete.

  • ReadWriteCoherencyTest. The system maintains cache coherency for open files. Two handles are opened for the test file that is used in this test: the first handle opens the file with caching disabled and the second handle opens the file with caching enabled. First, some data is written out to the file by using the non-caching handle; this data is read back and checked by using the caching handle. Second, some data is written out to the file by using the caching handle; this data is read back and checked by using the non-caching handle. The data that is checked for both should be consistent. This test is repeated for an asynchronous handle.

  • WriteThroughTest. A file can be opened with write through caching. Read operations are cached as normal, but write operations will update the cache and write the changed data out to the storage device before they complete. First, a test file is opened with write through caching enabled. A region of the file is read from to ensure that data is cached. The same region is written to and the volume read/write statistics are checked to make sure they are updated. The region is read from again and the data is verified to make sure it has been updated. The test is repeated for an asynchronous handle.

  • WriteThroughSyncTest. A file can be opened with write through caching. Read operations are cached as normal, but write operations will update the cache and write the changed data out to the storage device before they complete. First, a test file is opened with write through caching enabled. A region of the file is read from to ensure that data is cached. The same region is written to and the volume read/write statistics are checked to make sure they are updated. The region is read from again and the data is verified to make sure it has been updated.

  • AppendDataTest. This test appends data to an open file that is opened with the append data access flag set. A file is opened with the append data access flag set. Data is then appended to the file and the new end-of-file information and allocation size are checked to verify it has been updated with the append data. A read is performed on the file to check that the original data as well as the appended data is correct.

  • AtomicSeekReadTest. The byte offset into the file can be specified to the read function. This byte offset performs the equivalent action as a seek before the read. To test this equivalence, a known data pattern is written to the test file. The data is then verified by reading the file at several different points by specifying the byte offset to the read function.

  • ZeroLengthIOTest. If an I/O operation is specified with a zero-byte length, the file offset should not be updated. In addition, zero length extending or beyond the end of the file (EOF) should be success no-ops. A test file is opened and the current file offset is recorded. The read and write operations are performed with a new offset and a non-zero byte length. The new current file offset is recorded and checked to make sure it changed with respect to the read and write calls. The read and write operations are performed again with a new offset, but a zero-byte length. The new current file offset is recorded and checked to ensure that it did not change. This test is repeated with a file offset that is beyond the end of the test file.

  • ReadWriteRangeTest. If a read operation is specified at an offset that is beyond the end of the file, the end-of-file error is returned. If the I/O operation starts at a valid offset within the file, but the range causes a read/write off the end of the file, a success is returned along with the number of bytes that are transferred. Write operations will extend the file. A test file is opened and a read is performed at an offset that is beyond the current end-of-file. The end-of-file error is expected. Next, a read is performed again but with a byte offset near the end of the file and a byte length for reading that extends off the end of the file. A success is expected and the actual number of bytes that are read is verified. This test is repeated for the write operation. When the test writes with an offset near the end-of-file and specifies a byte length that extends off the end-of-file, the end-of-file pointer will increase.

  • EventAsyncIOTest. The read and write functions can perform asynchronous I/O. If an operation cannot proceed immediately, the calls can return a status pending. A test file is opened with an asynchronous file handle. A read and write operation are performed on the test file and a status pending is expected to be returned. Both the read and write operations are waited on for completion.

  • APCSynchRWTest. The read and write functions can perform asynchronous I/O by using asynchronous procedure calls (APCs). If an operation cannot proceed immediately (for example, a file object cannot be locked for exclusive access because another thread has the lock), the calls will return a status pending. If an APC is specified, that call will be made when the I/O completes. A test file is opened with an asynchronous file handle. A write operation is performed on the test file, with an APC routine specified for the write. The APC routine will set the event when the write completes. This completion is waited on in the main thread. This test is repeated for the read operation.

  • ZeroOnExtendTest. If a file is extended either by setting the end-of-file pointer through the Windows NT set function or by writing beyond the end of the file, the contents of the file are cleared for security purposes.

    First, a test file is opened with caching enabled. The Windows NT set function is used to set the end-of-file pointer to a value that is larger than the current file. The data from the file is read back and verified, the data from the beginning of the file to the old end-of-file pointer should be original data, and the data from the old end-of-file pointer to the new end-of-file pointer should all be zero.

    Next, the write function is used to write data at an offset bthat is eyond the end of the file. The data is read back and verified, the data from the beginning to the old end-of-file pointer is all original data, the data from the old end-of-file pointer to the start of write offset should all be zero, and the data from the start of the write offset to the end of the file should all be the new data just written. This test is repeated for non-cached IO.

SectionsCaching File System Test Group

The tests in this group include:

  • ExtendingWithUserMappingTest. A file can be extended when a user mapping exists. The new extended region should be initialized with zeros.

    1. A test file is opened, a user mapped section is created, and a view created.
    2. The file handle is closed.
    3. The test file is again opened with a call to NtCreateFile() with the FILE_WRITE_DATA and FILE_READ_DATA desired access specified.
    4. The file is extended with a Set Information File -> FileEndOfFileInformation call. The end-of-file is specified to be some value that is larger than the current end-of-file. The Set Information File call should succeed.
    5. Another view is created on the extended region.
    6. The file contents are read. The extended region's view should contain all zeros. The original region should have valid data.
  • FlushBuffersTest. This tests involves IRP_MJ_FLUSH_BUFFERS on a file object. A file is first created with the FILE_ATTRIBUTE_TEMPORARY flag set. Data is written to the file. Statistics on the volume are obtained. The open file handle is passed in a call to NtFlushBuffersFile. The statistics are again obtained. The number of bytes written to the block device, the end-of-file pointer, and the last write time should be updated from the flush.

  • FlushBuffersRootTest. This test involves IRP_MJ_FLUSH_BUFFERS on a root directory object. Several files, in several subdirectories, are created with the FILE_ATTRIBUTE_TEMPORARY flag set. Data is written to the files. The root directory of the volume is opened. Statistics on the volume are obtained. The open root directory handle is passed in a call to NtFlushBuffersFile. The statistics are again obtained. The number of bytes written to the block device, the end-of-file pointer, and the last write time should be updated on all files, from the flush.

  • FlushBuffersVolumeTest. This test involves IRP_MJ_FLUSH_BUFFERS on a volume object. Several files, in several subdirectories, are created with the FILE_ATTRIBUTE_TEMPORARY flag set. Data is written to the files. The volume is then directly opened. Statistics on the volume are obtained. The open volume handle is passed in a call to NtFlushBuffersFile. The statistics are again obtained. The number of bytes written to the block device, the end-of-file pointer, and last write time should be updated from the flush on all volumes.

  • MaintainSectionMappingTest. A user mapped section is created with an open file handle. The file handle can be closed and the user mapped section maintained.

    1. A test file is opened.
    2. A user mapped section or view are created with the open handle.
    3. The handle is closed.
    4. A view on the section is used to verify the file contents are still accessible.
    5. Another attempt is made at opening the test file with zero-share access (nothing is shared).
    6. Some data is written to the opened test file.
    7. The written data is verified to exist in the mapped section.
    8. The file is closed.
  • DataImageCoherencyTest. The image section must be kept consistent with the data section. This test first creates a file that contains an executable file. The file is then run, causing the executable image to be mapped into an image section. The cached data section should be flushed to disk before the image is faulted in.

    1. A known working executable file is opened for reading.
    2. A new file is created with write access (and with a file name of "temp.exe").
    3. The contents of the first file are copied into the new file with NtReadFile() and NtWriteFile().
    4. The handles to the files are closed.
    5. The temp.exe executable file is run as in the Microsoft Win32 CreateProcess call.
    6. Proper execution of the file is verified, as well as the flush of dirty data to the disk.
  • ExistingUserMappingTest. A file cannot be superseded or overwritten when a view on a user mapping exists.

    1. A test file is opened, a user mapped section is created, and a view mapped.
    2. The handle to the test file is closed.
    3. The test file is again opened with a call to NtCreateFile(). The FILE_OVERWRITE disposition is specified. The open should fail with STATUS_USER_MAPPED_FILE.
    4. The test file is again opened with a call to NtCreateFile(). The FILE_SUPERSEDE disposition is specified. The open should also fail with STATUS_USER_MAPPED_FILE.
  • TruncateWithUserMappingTest. A file cannot be truncated when a user mapping exists.

    1. A test file is opened, a user mapped section is created, and a view is created.
    2. The handle to the test file is closed.
    3. The test file is again opened with a call to NtCreateFile() with the FILE_WRITE_DATA access right specified.
    4. The file is truncated with a Set Information File -> FileEndOfFileInformation call. The EndOfFile is specified to be some value that is smaller than the current end-of-file.
    5. The Set Information File call should return the STATUS_USER_MAPPED_FILE error.
    6. The test is repeated with Set Information File -> AllocationInformation. By reducing the allocation size on the file below the current end-of-file, the file is truncated.

Security File System Test Group

The tests in this group include:

  • SetOwnerSecurityTest. This test requires that the file system that is being tested is NTFS and that a test user is created with Users rights. This test user is specified at the command line when the test is running with the /u option. The password for this user must be the same as the user name (that is, if the username is HollyHolt, the password must be HollyHolt). The first thing that is done in this test is to start another process, as the test user. This process will create the test file that is used in this test and ownership will belong to the test user. Next, the test file is opened by the current user (the user that is running the test). The user SID is changed so that the current user will take ownership of the file. The file is then queried for its Owner SID to verify that the current owner did take ownership of the file.

  • SetDaclSecurityTest. If the file system supports security on a file and directory basis, the Object Manager will use the set security function to set the security descriptor on the file or directory. A test file is first opened and the security DACL is changed for the file to allow only read operations for the Administrator. The file is then queried for its Security DACL information; the results from this query are compared to what was set on the file. If both Security DACLs match, the original DACL is reset to allow the test file to be deleted during cleanup.

  • SetGroupSecurityTest. This test requires that the file system that is being tested is NTFS and that a test user is created with Users rights. The test file is first opened and the Security Group SID is changed so that the Administrators group has control of this file. The file is then queried for its Security Group SID and this SID is compared to the Group SID that it was set to.

  • SetSaclSecurityTest. This test requires the file system that is being tested is NTFS. First, the Security Privilege is enabled to access the SACL. A SACL list allows you to audit operations that are performed on a file. The test file is opened and the SACL list is set to audit all Read operations that are performed on the test file. Next, the file is opened again and queried for its SACL information. This information is compared to what the SACL was set to earlier (audit all Read operations). If both lists match, the test is passed.

  • AuditDelSecurityTest. This test requires the file system that is being tested is NTFS. First, the Security Privilege is enabled to access the SACL. The test file is then opened, and the SACL is set to audit the deletion of the file; the file is closed and the security changes are now enabled. The file is then opened and marked for deletion on close. After the file is closed, the Event Log should log the deletion of the file. The file is closed and the Event Log is opened and a search is done through the Event Log for the deletion of the test file. If this event has taken place, the test has passed.

  • AuditPermSecurityTest. This test requires that the file system that is being tested is NTFS. First, the Security Privilege is enabled to access the SACL. The test file is then opened and the SACL is set to audit the change of security permissions (the DACL); the file is closed and the security changes now are enabled. The file is then reopened and the DACL is changed; this change should cause the event to be logged in the Event Log. The Event Log is searched for this event if the event is in the log, the test is passed and the original DACL information is reset.

  • AuditOwnerSecurityTest. This test requires that the file system that is being tested is NTFS and that a test user is created with Users rights. This test user is specified at the command line with the /u option. The password for this user must be the same as the user name (that is, if the username is HollyHolt, the password must be HollyHolt). The first thing that is done in this test is to start another process, as the test user. This process will create the test file that is used in this test and ownership will belong to the test user. Next, the Security Privilege is enabled to access the SACL. The test file is then opened, and the SACL is set to audit the change of the owner of the test file; the file is then closed and the security changes are now enabled. The file is opened and the current user takes ownership of the file. This change in ownership should set an event in the Event Log. The Event Log is searched for this event, and if present, the test is passed.

  • DirectoryTraverseTest. The default installation of Microsoft Windows enables Bypass Traverse Checking for all users on the system. This feature allows a user to access a directory (which maintains a legal ACL for the user) that is a subdirectory under a path that contains directories that do not maintain a legal ACL for the user. This test requires that the file system that is being tested is NTFS and that a test user is created with Users rights. There are three directories in this test (the second directory is a subdirectory of the first and the third directory is a subdirectory of the second). The first directory is opened and the DACL is changed so that only administrators can perform operation on it; the same is done with the second directory. Next, a second thread is initiated that will log on the test user and try to create a file in the first directory; this attempt should fail. The same is repeated with the second directory. This attempt is repeated on the third directory as well, but this time a success is expected as a return if the Bypass Traverse Checking is enabled; access denied is expected if this user privilege is not enabled.

ObjectID File System Test Group

Object identifiers (IDs) are used to uniquely identify files and directories on a volume. This feature allows files or directories to be referenced by a unique ID, which is preserved even if the file or directory is renamed. The file or directory can be opened by its Object ID and its path name.

The following tests are part of this group:

  • GetObjectIDVolumeTest. The NtQueryVolumeInformationFile function with the FileFsObjectInformation class can be used to retrieve a volume's Object ID. If the volume does not have an Object ID, the operation fails with STATUS_OBJECT_NAME_NOT_FOUND. Otherwise, the existing Object ID is retrieved and the operation succeeds.

  • NameInformationExTest. The NtQueryInformationFile function with the FileNameInformation class can be used to retrieve the full path of a file or directory through Object IDs. This ability is verified by opening a file or directory by its Object ID and querying its file name. Note that directory traverse privilege is required.

  • ObjectOpenByIDTest. The NtCreateFile function with FILE_OPEN_BY_FILE_ID can be used to open a file or directory by Object ID. Similar to the semi-unique 64-bit file index, the Object ID is used as the file name of length sizeof(OBJECTID).

  • NotificationObjectIDRemovedTest. Changes to the (\$Extend\$ObjId:$O:$INDEX_ALLOCATION) object index can be observed by using the NtNotifyChangeDirectoryFile function. The FILE_OBJECTID_INFORMATION structure is returned. The following notifications are possible:

    • FILE_ACTION_ADDED
    • FILE_ACTION_REMOVED
    • FILE_ACTION_REMOVED_BY_DELETE
    • FILE_ACTION_ID_NOT_TUNNELLED
    • FILE_ACTION_TUNNELLED_ID_COLLISION
    • This test verifies the FILE_ACTION_REMOVED notification.
  • SetExtendedObjectIDTest. FSCTL_SET_OBJECT_ID_EXTENDED is used to set the extended information portion of a file or directory's Object ID. This ability is verified by using FSCTL_GET_OBJECT_ID to retrieve this extended information.

  • SetObjectIDTest. An object ID can be set on a file or directory with the FSCTL_SET_OBJECT_ID control code and the FILE_OBJECTID_BUFFER, provided that the user that is attempting the operation has BACKUP/RESTORE privileges on the system. The SE_RESTORE_NAME privilege must be enabled on the user process and the file or directory handle must be opened with BACKUP/RESTORE intent. Otherwise, STATUS_ACCESS_DENIED is returned.

    This situation is verified by opening a file or directory without the FILE_OPEN_FOR_BACKUP_INTENT create flag and attempting the FSCTL_SET_OBJECT_ID operation. The operation should fail with STATUS_ACCESS_DENIED.

  • SetObjectIDVolumeTest. The NtSetVolumeInformationFile function with FileFsObjectInformation class can be used to set an Object ID on a volume. If the volume does not have an Object ID, the new Object ID is set and the operation succeeds. If the volume already has an Object ID, the old Object ID is replaced with the new Object ID and the operation succeeds. However, if a file or directory already has the same Object ID, the operation fails with STATUS_DUPLICATE_NAME.

  • TunnelObjectIDTest. The tunneling of Object IDs is the process of caching the Object ID of a file or directory. If a file or directory that has an object ID is deleted, and if another file or directory that does not have an object ID is renamed to the file or directory that was just deleted, the renamed file will have an object ID. In this situation, the object ID has been tunneled (from the deleted file to the renamed file).

  • NotificationObjectIDNotTunnelledTest. Changes to the (\$Extend\$ObjId:$O:$INDEX_ALLOCATION) object index can be observed by using NtNotifyChangeDirectoryFile. The FILE_OBJECTID_INFORMATION structure is returned. The following notifications are possible:

    • FILE_ACTION_ADDED
    • FILE_ACTION_REMOVED
    • FILE_ACTION_REMOVED_BY_DELETE
    • FILE_ACTION_ID_NOT_TUNNELLED
    • FILE_ACTION_TUNNELLED_ID_COLLISION

    This test verifies the FILE_ACTION_ID_NOT_TUNNELLED notification.

  • SetUniqueObjectIDNameCollisionTest. The Object IDs should be unique for each file and directory on the volume. This uniqueness is verified by using FSCTL_SET_OBJECT_ID to try setting an Object ID on a file or directory that already has an object ID. The operation should fail with STATUS_OBJECT_NAME_COLLISION.

  • SetUniqueObjectIDDuplicateNameTest. The Object IDs should be unique for each file and directory on the volume. This uniqueness is verified by using FSCTL_SET_OBJECT_ID to try setting an Object ID that is known to already exist on the volume. The operation should fail with STATUS_DUPLICATE_NAME if the file or directory on which the operation is attempted does not have an object ID.

  • NotificationObjectIDAddedTest. Changes to the (\$Extend\$ObjId:$O:$INDEX_ALLOCATION) object index can be observed by using NtNotifyChangeDirectoryFile. The FILE_OBJECTID_INFORMATION structure is returned. The following notifications are possible:

    • FILE_ACTION_ADDED
    • FILE_ACTION_REMOVED
    • FILE_ACTION_REMOVED_BY_DELETE
    • FILE_ACTION_ID_NOT_TUNNELLED
    • FILE_ACTION_TUNNELLED_ID_COLLISION

    This test verifies the FILE_ACTION_ADDED notification.

  • CreateOrGetObjectIDTest. The FSCTL_CREATE_OR_GET_OBJECT_ID control code can be used to return the existing Object ID or generate a new Object ID for the file or directory. This situation is verified by attempting the FSCTL_CREATE_OR_GET_OBJECT_ID operation on a file or directory that has a known Object ID. The operation should succeed and the known Object ID should be returned in a FILE_OBJECTID_BUFFER structure. Then, the Object ID is deleted from the file with FSCTL_DELETE_OBJECT_ID. Finally, the FSCTL_CREATE_OR_GET_OBJECT_ID attempt is made on the same file. The operation should succeed and return a newly created Object ID in the FILE_OBJECTID_BUFFER.

  • NotificationObjectIDTunnelledCollisionTest. Changes to the (\$Extend\$ObjId:$O:$INDEX_ALLOCATION) object index can be observed by using NtNotifyChangeDirectoryFile. The FILE_OBJECTID_INFORMATION structure is returned. The following notifications are possible:

    • FILE_ACTION_ADDED
    • FILE_ACTION_REMOVED
    • FILE_ACTION_REMOVED_BY_DELETE
    • FILE_ACTION_ID_NOT_TUNNELLED
    • FILE_ACTION_TUNNELLED_ID_COLLISION

    This test verifies the FILE_ACTION_TUNNELLED_ID_COLLISION notification.

  • DeleteObjectIDTest. An existing Object ID can be removed from a file or directory by using FSCTL_DELETE_OBJECT_ID, provided the handle is opened with RESTORE intent and WRITE access. This situation is verified by attempting to delete the Object ID of a file or directory with the handle opened without the FILE_OPEN_FOR_BACKUP_INTENT option flag or WRITE access. The operation should fail with STATUS_ACCESS_DENIED. Then, the operation is repeated with a handle that is opened with the FILE_OPEN_FOR_BACKUP_INTENT option flag and WRITE access. The operation should succeed.

  • NotificationObjectIDDeletedTest. Changes to the (\$Extend\$ObjId:$O:$INDEX_ALLOCATION) object index can be observed by using NtNotifyChangeDirectoryFile. The FILE_OBJECTID_INFORMATION structure is returned. The following notifications are possible:

    • FILE_ACTION_ADDED
    • FILE_ACTION_REMOVED
    • FILE_ACTION_REMOVED_BY_DELETE
    • FILE_ACTION_ID_NOT_TUNNELLED
    • FILE_ACTION_TUNNELLED_ID_COLLISION

    This test verifies the FILE_ACTION_REMOVED_BY_DELETE notification.

  • EnumObjectIDTest. The Object IDs on a volume can be queried with NtQueryDirectoryFile and FileObjectIdInformation class. A FILE_OBJECTID_INFORMATION structure is returned for each object. The name of the pseudo-directory to open is (\$Extend\$ObjId:$O:$INDEX_ALLOCATION).

  • GetObjectIDTest. FSCTL_GET_OBJECT_ID and FILE_OBJECTID_BUFFER can be used to retrieve a file or directory's Object ID. This situation is verified by setting the Object ID on a file or directory and retrieving the Object ID with the FSCTL_GET_OBJECT_ID operation. The same ID that was set should be returned.

MountPoints File System Test Group

The tests in this group include:

  • CreateDirectoryExDirectoryTest. The purpose of this test is to copy a directory that contains a name graft. The reparse information should be copied with the special Microsoft Win32 CreateDirectoryEx call. The target directory contains a subdirectory and a file. The test verifies access to these items through the copied reparse point.

  • CreateDirectoryExVolumeTest. The purpose of this test is to create a volume mount point and then copy the directory that contains the point. A special Win32 CreateDirectoryEx call should also copy the reparse information. A file and directory are known to exist on an alternate volume. The file and directory are opened through the copied volume mount point.

  • DirectoryCycleOnReparseTest. The purpose of this test is to attempt the legal operation of linking a lower child directory to its immediate parent and then traversing the self-referencing directory tree up to 16 times before an error status is returned. This limit is imposed by the I/O manager.

  • DirectoryGraftTest. The purpose of this test is to attempt name grafting on a directory. The target directory contains a subdirectory and a file. The test verifies access to these items through the reparse point.

  • DirectoryGraftEmptyFileTest. The purpose of this test is to attempt name grafting on a directory that contains a file. Name grafting requires an empty directory. The STATUS_DIRECTORY_NOT_EMPTY status return is verified.

  • DirectoryGraftEmptyTest. The purpose of this test is to attempt name grafting on a directory that contains a subdirectory. The STATUS_DIRECTORY_NOT_EMPTY status return is verified.

  • DirectoryGraftEmptyStreamTest. The purpose of this test is to attempt name grafting on a directory by using a handle to a named data stream on a directory. Even though a named data stream on the directory was opened, this attempt returns STATUS_NOT_A_DIRECTORY.

  • FileGraftTest. The purpose of this test is to attempt name grafting on a file. A file is opened, and an attempt is made to set the IO_REPARSE_TAG_MOUNT_POINT reparse point with the file handle. On Windows 2000 NTFS volumes and greater, this situation returns STATUS_NOT_A_DIRECTORY.

  • FileGraftStreamTest. The purpose of this test is to attempt name grafting on a named data stream of a file. A named data stream of file is opened, and an attempt is made to set the IO_REPARSE_TAG_MOUNT_POINT reparse point with the file handle. On Windows 2000 NTFS volumes and greater, this situation returns STATUS_NOT_A_DIRECTORY.

  • LocalMountPointTest. The purpose of this test is to create a volume mount point and then exercise it. A file and directory are known to exist on an alternate volume. The file and directory are opened through the volume mount point.

ReparsePoints File System Test Group

The tests in this group include:

  • SetPointDirectoryNotEmptyTest. This test validates the behavior of FSCTL_SET_REPARSE_POINT on a non-empty directory. The code path that returns STATUS_DIRECTORY_NOT_EMPTY is exercised by attempting to set a reparse point on a non-empty directory. This operation is expected to fail with STATUS_DIRECTORY_NOT_EMPTY on NTFS5-compatible file systems.

  • EnumReparsePointsTest. This test verifies that the index (\$EXTEND\$Reparse:$R:$INDEX_ALLOCATION) can be used with the NtQueryDirectoryFile function and that the FileReparsePointInformation class retrieves the reparse tag for a given file or directory with a reparse point. First, a reparse point is set on a file and directory. Then, the index is queried. The reparse tag information for the file and directory with a reparse point retrieved. This operation is expected to succeed on NTFS5-compatible file systems.

  • FileAttributeReparsePointTest. This test verifies that BASIC INFORMATION can be obtained from a file or directory with a reparse point. First, a reparse point is set on a file and directory. Then, the file or directory is queried for BASIC INFORMATION. The attribute field of the FILE_ATTRIBUTE_BASIC_INFORMATION structure is checked for FILE_ATTRIBUTE_REPARSE_POINT. This operation is expected to succeed on NTFS5-compatible file systems.

  • GetPointBufferSmallTest. This test validates the behavior of FSCTL_GET_REPARSE_POINT, which is used to get a reparse point set on a file or directory. The code path that returns STATUS_BUFFER_TOO_SMALL is exercised by attempting to get a reparse point from a file or directory while using an output buffer length argument that is less than REPARSE_DATA_BUFFER_HEADER_SIZE. This operation is expected to fail with STATUS_BUFFER_TOO_SMALL on supported file systems.

  • GetPointNotReparseTest. This test validates the behavior of FSCTL_GET_REPARSE_POINT, which is used to get a reparse point set on a file or directory. The code path that returns STATUS_NOT_A_REPARSE_POINT is exercised by attempting to get a reparse point from a file or directory that has no prior reparse point set. This operation is expected to fail with STATUS_NOT_A_REPARSE_POINT on NTFS5-compatible file systems.

  • GetPointInvalidUserBufferTest. This test validates the behavior of FSCTL_GET_REPARSE_POINT, which is used to get a reparse point set on a file or directory. The code path that returns STATUS_INVALID_USER_BUFFER is exercised by attempting to get a reparse point from a file or directory while using NULL as a reparse buffer argument to the NtFsControlFile function. This operation is expected to fail with STATUS_INVALID_USER_BUFFER on NTFS5-compatible file systems.

  • GetPointInvalidParamTest. This test validates the behavior of FSCTL_GET_REPARSE_POINT, which is used to get a reparse point set on a file or directory. The code path that returns STATUS_INVALID_PARAMETER is exercised by attempting to get a reparse point on a volume or by using an output buffer argument with the NtFsControlFile function. The operation is expected to fail with STATUS_INVALID_PARAMETER n NTFS5-compatible file systems.

  • SetPointInvalidBufferSizeTest. This test validates the behavior of FSCTL_SET_REPARSE_POINT, which is used to set a reparse point on a file or directory. The code path that returns STATUS_INVALID_BUFFER_SIZE is exercised by attempting to set a reparse point on a file and directory while passing NULL as a reparse buffer argument to the NtFsControlFile function. The operation is expected to fail with STATUS_INVALID_BUFFER_SIZE on NTFS5-compatible file systems.

  • SetPointInvalidParamTest. This test validates the behavior of FSCTL_SET_REPARSE_POINT, which is used to set a reparse point on a file or directory. The code path that returns STATUS_INVALID_PARAMETER is exercised by attempting to set a reparse point on a volume or by using an output buffer argument. The operation is expected to fail in both cases with STATUS_INVALID_PARAMETER on supported file systems.

  • SetPointIoReparseDataInvalidTest. This test validates the behavior of FSCTL_SET_REPARSE_POINT, which is used to set a reparse point on a file or directory. The code path that returns STATUS_IO_REPARSE_DATA_INVALID is exercised by using an input buffer length argument that is less than REPARSE_DATA_BUFFER_HEADER_SIZE, an input buffer length argument that is greater than MAX_REPARSE_DATA_BUFFER_SIZE, an input buffer length argument that is different than the reparse data buffer length, or a GUID that is equal to NULL (if ISV reparse tag). The operation is expected to fail in all of these cases with STATUS_IO_REPARSE_DATA_INVALID on NTFS5-compatible file systems.

  • ChangeNotificationReparseTest. This test verifies that the index (\$EXTEND\$Reparse:$R:$INDEX_ALLOCATION) can be used to wait for reparse point additions. First, a change notification is set on a volume index. Then, an event is created to wait for the addition of reparse points.

    Next, a different thread sets a reparse point on a file to trigger the event. Meanwhile, the main thread waits for the event to occur. This operation is expected to fail with IFSTEST_TEST_PENDING_IO_TIMEOUT on NTFS5-compatible file systems because it is not yet supported.

  • OpenReparsePointTest. This test verifies that a file or directory with a reparse point can be opened with the FILE_OPEN_REPARSE_POINT, which inhibits reparse behavior of the file or directory. First, a reparse point is set on a file and directory. Then, an attempt is made to open the file and directory without using FILE_OPEN_REPARSE_POINT. The operation is expected to fail with STATUS_IO_REPARSE_TAG_NOT_HANDLED on NTFS5-compatible file systems. Next, an attempt is made to open the file and directory while using FILE_OPEN_REPARSE_POINT. The operation is expected to succeed on NTFS5-compatible file systems.

  • QueryFullAttributesReparseTest. This test verifies that a file or directory with a reparse point can be queried by using NtQueryFullAttributesFile function, which returns a FILE_NETWORK_OPEN_INFORMATION structure. This operation is expected to succeed on NTFS5-compatible file systems, with the FILE_ATTRIBUTE_REPARSE_POINT attribute set in the attribute field of the returned structure.

  • QueryFileAttributeTagInfoTest. This test verifies that a file or directory with a reparse point can be queried for FileAttributeTagInformation. First, a reparse point is set on a file or directory. Then, the NtQueryInformationFile function is used with the FileAttributeTagInformation class. This operation is expected to succeed on NTFS5-compatible file systems.

  • SetPointIoReparseTagInvalidTest. This test validates the behavior of FSCTL_SET_REPARSE_POINT, which is used to set a reparse point on a file or directory. The code path that returns STATUS_IO_REPARSE_TAG_INVALID is exercised by attempting to set a reparse point on a file or directory while using a reparse tag that is equal to IO_REPARSE_TAG_NSS, IO_REPARSE_TAG_RESERVED_ONE, IO_REPARSE_TAG_RESERVED_ZERO, or ~IO_REPARSE_TAG_VALID_VALUES. The operation is expected to fail in all of these cases with STATUS_IO_REPARSE_TAG_INVALID on NTFS5-compatible file systems.

  • SetPointIoReparseTagMismatchTest. The code path that returns STATUS_IO_REPARSE_TAG_MISMATCH is exercised by attempting to set a reparse point file or directory with a different reparse tag. First, a reparse point is set on a file and directory with one reparse tag. Then, an attempt is made to overwrite the same file and directory while using a different reparse tag as argument. The operation is expected to fail with STATUS_IO_REPARSE_TAG_MISMATCH on NTFS5-compatible file systems.

  • DeleteFileDirReparsePointTest. This test verifies that a file or directory with a reparse point cannot be deleted with normal deletion semantics. First, a reparse point is set on a file and directory. Then, an attempt is made to delete the file and directory with the NtDeleteFile function. The file-delete operation should fail with STATUS_IO_REPARSE_TAG_NOT_HANDLED status on NTFS5-compatible file systems.

  • DelPointAccessDeniedTest. This test validates the behavior of FSCTL_DELETE_REPARSE_POINT, which is used to delete a reparse point on a file or directory. The code path that returns STATUS_ACCESS_DENIED is exercised by attempting to delete a reparse point on a file or directory with no WRITE access. The operation is expected to fail with STATUS_ACCESS_DENIED on NTFS5-compatible file systems.

  • DelPointAttributeConflictTest. This test validates the behavior of FSCTL_DELETE_REPARSE_POINT, which is used to delete a reparse point on a file or directory. First, a reparse point is set on a file and directory with one GUID. Then, an attempt to delete the reparse points on the same file and directory is made, but with a different GUID. The operation is expected to fail on NTFS5-compatible file systems with the STATUS_REPARSE_ATTRIBUTE_CONFLICT status code.

  • DelPointInvalidBufferSizeTest. This test validates the behavior of FSCTL_DELETE_REPARSE_POINT, which is used to delete a reparse point on a file or directory. The code path that returns STATUS_INVALID_BUFFER_SIZE is exercised by attempting to delete a reparse point on a file or directory with a NULL reparse buffer. First, a reparse point is set on a file and directory. Then, an attempt is made to delete the reparse point on the file and directory while passing NULL as a reparse buffer argument to the NtFsControlFile function. The operation is expected to fail with STATUS_INVALID_BUFFER_SIZE on NTFS5-compatible file systems.

  • DelPointIoReparseDataInvalidTest. This test validates the behavior of FSCTL_DELETE_REPARSE_POINT, which is used to delete a reparse point on a file or directory. The code path that returns STATUS_IO_REPARSE_DATA_INVALID is exercised by using an input buffer length argument that is greater than REPARSE_DATA_BUFFER_HEADER_SIZE, an input buffer data length argument that is different than zero, or a buffer size argument that is different than the GUID header size (if ISV reparse tag). The operation is expected to fail in all of these cases with STATUS_IO_REPARSE_DATA_INVALID on NTFS5-compatible file systems.

  • DelPointInvalidParmTest. This test validates the behavior of FSCTL_DELETE_REPARSE_POINT, which is used to delete a reparse point on a file or directory. The code path that returns STATUS_INVALID_PARAMETER is exercised by attempting to delete a reparse point on a volume or by using an output buffer argument. The operation is expected to fail in both cases with STATUS_INVALID_PARAMETER on supported file systems.

  • DelPointIoReparseTagInvalidTest. This test validates the behavior of FSCTL_DELETE_REPARSE_POINT, which is used to delete a reparse point on a file or directory. The code path that returns STATUS_IO_REPARSE_TAG_INVALID is exercised by attempting to delete a reparse point on a file or directory while using a reparse tag that is equal to IO_REPARSE_TAG_RESERVED_ONE or IO_REPARSE_TAG_RESERVED_ZERO. The operation is expected to fail with STATUS_IO_REPARSE_TAG_INVALID on NTFS5-compatible file systems.

  • DelPointIoReparseTagMismatchTest. This test validates the behavior of FSCTL_DELETE_REPARSE_POINT, which is used to delete a reparse point on a file or directory. The code path that returns STATUS_IO_REPARSE_TAG_MISMATCH is exercised by attempting to delete a reparse point file or directory with a different reparse tag. First, a reparse point is set on a file and directory with one reparse tag. Then, an attempt is made to delete the same file and directory while using a different reparse tag as argument. The operation is expected to fail with STATUS_IO_REPARSE_TAG_MISMATCH on NTFS5-compatible file systems.

  • DelPointNotReparseTest. This test validates the behavior of FSCTL_DELETE_REPARSE_POINT, which is used to delete a reparse point on a file or directory. The code path that returns STATUS_NOT_A_REPARSE_POINT is exercised by attempting to delete a reparse point on a file or directory that has no prior reparse point set. The operation is expected to fail with STATUS_NOT_A_REPARSE_POINT on NTFS5-compatible file systems.

  • SetPointEASNotSupportedTest. This test validates the behavior of FSCTL_DELETE_REPARSE_POINT, which is used to delete a reparse point on a file or directory. The code path that returns STATUS_EAS_NOT_SUPPORTED is exercised by attempting to set a reparse point on a file or directory with extended attributes. The operation is expected to fail with STATUS_EAS_NOT_SUPPORTED on NTFS5-compatible file systems because reparse points and extended attributes are mutually exclusive.

  • SetPointAccessDeniedTest. This test validates that the file system is not be able to set reparse points on files and directories with no WRITE access.

  • SetPointAttributeConflictTest. This test validates that the file system must not be able to set reparse points from files and directories with mismatched GUID.

SparseFiles File System Test Group

The tests in this group include:

  • SparseMoveFileTest. The defrag FSCTL_MOVE_FILE call can be used with sparse files. If the VCN range to move is sparse, the specified LCN is not allocated. This test creates a sparse file, obtains the retrieval pointers of the file, and then attempts to move a sparse region over an already committed LCN range. The move should return success because the area takes no allocation. The attempt is then made over a sparse and nonsparse range. This operation should fail with STATUS_ALREADY_COMMITTED.

  • SparseNonSparseStreamTest. The purpose of this test is to test the ability to have sparse and nonsparse data streams on a file. This test uses allocation size to determine this ability. The unnamed data stream of a file is opened and made sparse. Then, a byte is written at the end of the stream. A named stream is then created on the file. The same write is done on the named nonsparse data stream. The allocation size of the file is then checked. The new allocation size is checked to be less than 10% + the size for the nonsparse region of the allocation necessary.

  • NonSparseZeroDataTest. The purpose of this test is to ensure that FSCTL_SET_ZERO_DATA sets a range of a nonsparse file to zero. The test file is first opened. Then, the file is written with 0xffs. The FSCTL is attempted on the first half of the file. The file is then read back and the first half is verified to be zeros and the second half 0xffs.

  • ResetSparseAttrOverwriteTest. When a sparse file is overwritten, it becomes a nonsparse file. This change is tested by way of the sparse attribute, FILE_ATTRIBUTE_SPARSE_FILE. The attribute is checked before and after the overwrite. After the overwrite, the flag is checked to be reset.

  • SparseZeroDataAllocTest. The purpose of this test is to ensure that FSCTL_SET_ZERO_DATA reduces the allocation size of the file. The test file is first opened and made sparse. Then, the file is written with 0xffs. The allocation size is checked to see that at least 100% of the file size is allocated. The FSCTL is attempted on the first half of the file. The allocation size is again checked to verify that no more than 60% of the file size is allocated.

  • SparseZeroDataTest. The purpose of this test is to ensure that FSCTL_SET_ZERO_DATA sets a range of a sparse file to zero. The test file is first opened and made sparse. Then, the file is written with 1s. The FSCTL is attempted on the first half of the file. The file is then read back and the first half is verified to be zeros and the second half 0xffs.

  • SparseStreamTest. The purpose of this test is to test sparse streams by way of allocation size. The unnamed data stream of a file is opened and made sparse. Then, a byte is written at the end of the stream. The allocation size is checked. The new allocation size is checked to be less than 10% of the allocation necessary.

  • SparseStreamDirTest. The purpose of this test is to test sparse streams by way of allocation size. A named data stream of a directory is created and made sparse. Then, a byte is written at the end of the stream. The allocation size is checked. The new allocation size is checked to be less than 10% of the allocation necessary.

  • ResetSparseAttrSupersedeTest. When a sparse file is superseded, it becomes a nonsparse file. This change is tested by way of the sparse attribute, FILE_ATTRIBUTE_SPARSE_FILE. The attribute is checked before and after the supersede. After the supersede, the flag is checked to be reset.

  • SparseAllocatedRangesTest. The purpose of this test is to ensure that FSCTL_SET_ZERO_DATA reduces the allocation size of the file. The test file is first opened and made sparse. Then, the file is written with 0xffs. The allocation size is checked to see that at least 100% of the file size is allocated. The FSCTL is attempted on the first half of the file. The allocation size is again checked to verify that no more than 60% of the file size is allocated.

  • FileInformationSparseAttrTest. The purpose of this test is to test the FILE_ATTRIBUTE_SPARSE_FILE attribute flag. The attributes are obtained by using NtQueryInformationFile with the basic information class. The flag represents the sparse attribute on a stream by stream basis. If one stream in a file is opened that is not sparse, the flag is clear. If a different stream in the same file is opened that is sparse, the flag is then set.

  • SparseCompressedStreamTest. Sparse files can be compressed by using FSCTL_SET_COMPRESSION. The sparse extents are not changed after the compress. This test creates a sparse file, obtains the retrieval pointers of the file, and then attempts to compress the file. The retrieval pointers are again obtained and the sparse extent is verified to be the same. FSCTL_GET_RETRIEVAL_POINTERS is used to obtain the pointers.

  • SparseUserMappedSectionTest. The purpose of this test is to test the creation of a user mapped section and view on a sparse file. The test file is first opened and made sparse. Then, a byte is written at the end of the file. A section and view are then created on the file.

  • SparseUserMapZeroTest. The purpose of this test is to ensure that FSCTL_SET_ZERO_DATA returns STATUS_USER_MAPPED_FILE when there is a user mapped section and view on a sparse file. The test file is first opened and made sparse. Then, a byte is written at the end of the file. A section and view are then created on the file. The FSCTL is attempted and the expected status is verified.

ExtendedSecurity File System Test Group

  • FindFilesBySidTest. The purpose of this test is to verify that FSCTL_FIND_FILES_BY_SID can be used to scan the file records and find entries that a specified SID owns. The FIND_BY_SID_DATA structure is used as input buffer to specify the SID. An output buffer that is aligned on a FILE_NAME_INFORMATION structure boundary is used to return the found files.

ForcedDismount File System Test Group

  • ForceDismountTest. The purpose of this test is to verify that, in Microsoft Windows 2000 and greater, FSCTL_DISMOUNT_VOLUME can be issued on an active volume (that is, with opened file handles). This operation is expected to succeed, except in the following two cases:
    • The volume is the system drive, which cannot be dismounted. The operation fails with STATUS_ACCESS_DENIED.
    • The file system is pre-NT5 FAT, which requires exclusive-lock access to the volume before it can be dismounted. The operation fails with STATUS_NOT_LOCKED.

Encryption File System Test Group

A programmer or user can mark a directory or file as encrypted. A file so marked is encrypted by NTFS by using the current encryption driver. If the file is later marked as not encrypted, it is decrypted and left in a plain text (not encrypted, but still protected by the Windows NT security model) state.

Directories are not themselves encrypted. Rather, by default, in an "encrypted" directory, all new files in the directory are encrypted at creation. A user must specifically change the status of a new file to decrypted if the user does not want the file to be encrypted. An encrypted directory is visible.

To encrypt a file, the CreateFile function with the FILE_ATTRIBUTE_ENCRYPTED flag is used. To encrypt an existing file, the EncryptFile function can be used. All data streams in the file are encrypted. If the file is already encrypted, EncryptFile does nothing but return a nonzero value, which indicates success. If the file is compressed, EncryptFile decompresses the file before encrypting it.

To decrypt an encrypted file, the DecryptFile function is used. If the file is not encrypted, DecryptFile does nothing but return a nonzero value that indicates success.

To retrieve the encryption status of a file, the FileEncryptionStatus function is used. Alternatively, the GetFileAttributes function and the FILE_ATTRIBUTE_ENCRYPTED flag can be used.

Before the tests are run, the volume information should be queried to determine if Encryption is supported (FILE_SUPPORTS_ENCRYPTION). All tests are then run. The expectations of the tests should be altered depending on the determined support.

The call path from Win32 is:

advapi.dll -> feclient.dll -rpc -> LSA

  • SuperOverEncryptedTest. A file can be encrypted by using the NtCreateFile function with the FILE_ATTRIBUTE_ENCRYPTED flag specified. The FILE_SUPERSEDE, FILE_OVERWRITE and FILE_OVERWRITE_IF dispositions can be used on an existing file. Encryption on the files is then tested by opening the file in a different process, with a different security token. ACCESS_DENIED should be returned.

  • ReadWriteRawEncryptedTest. The raw encrypted data can be read and written by using OpenEncryptedFileRaw, ReadEncryptedFileRaw, WriteEncryptedFileRaw, and CloseEncryptedFileRaw. These function are used in off-line recovery. The operations are tested by encrypting a file and then creating a new file and writing with the APIs. The file size of the two files should match.

  • RemoveUsersEncryptionTest. The RemoveUsersFromEncryptedFile function is used to remove a specified user from a list of users that are permitted to access a specified encrypted file. This retrieval is verified by encrypting a file in an alternate user context. Then, the QueryUsersOnEncryptedFile function is called to retrieve the number of users that are allowed access to the file. This number should be at least 1: the file owner. Finally, the RemoveUsersFromEncryptedFile function is called to remove the specified user from the list; the QueryUsersOnEncryptedFile is called again. The number of users allowed to decrypt the file should be one less than before.

  • QueryUsersEncryptionTest. The QueryUsersOnEncryptedFile function is used to retrieve a list of users that are permitted to access a specified encrypted file. This retrieval is verified by encrypting a file in an alternate user context. Then, the QueryUsersOnEncryptedFile function is called to retrieve the number of users that are allowed access to the file. This number should be at least 1: the file owner.

  • QueryRecoveryAgentsTest. The QueryRecoveryAgentsOnEncryptedFile function is used to retrieve a list of users that are permitted to recover a specified encrypted file. The recovery agent can always retrieve the file if the file owner can no longer do so. This retrieval is verified by encrypting a file in an alternate user context. Then, the QueryRecoveryAgentsOnEncryptedFile function is called to retrieve the number of users that are allowed recover to the file. This number should be at least 1: the recovery agent.

  • EncryptDecryptFileTest. A file can be encrypted by using the EncryptFile function. Encryption on the files is tested by opening the file in a different process, with a different security token. ACCESS_DENIED should be returned. The file is then decrypted with the DecryptFile function. An attempt to open and read should be made. NO_ERROR should be returned.

  • EncryptDecryptDirTest. A directory can be encrypted by using the EncryptFile function. When the file or dir attributes are read back, the encryption flag should be set. Directories can be decrypted by calling the DecryptFile function. The attributes should be consistent with the encryption state.

  • EncryptionStatusTest. The FileEncryptionStatus call can be used to check the encryption status of a file or directory. The call is made on files and directories that are and are not encrypted. The FILE_IS_ENCRYPTED is checked for correctness.

  • EncryptionDecompressionTest. In Windows 2000 and greater, file-based compression and encryption are mutually exclusive. When the file is compressed and a call to EncryptFile is made, the file will be uncompressed in the process. The attributes on the file should then show encryption only.

  • EncryptionCompressionTest. In Windows 2000 and greater, file-based compression and encryption are mutually exclusive. If an attempt is made to encrypt a file that is already compressed, the file will be decompressed, and then encryption will be applied. This scenario can be verified by first compressing a directory with FSCTL_SET_COMPRESSION. Then, an encrypted file and directory are created with a call to NtCreateFile while specifying the FILE_ATTRIBUTE_ENCRYPTED flag. The attribute of the file and directory are read back; only the FILE_ATTRIBUTE_ENCRYPTED flag should be observed.

  • EncryptionAttributeTest. GetFileAttributes can be used to check the encryption status of a file or directory. The call is made on files and directories that are and are not encrypted. FILE_ATTRIBUTE_ENCRYPTED is observed.

  • DirectoryEncryptedSuperOverTest. An existing non-empty directory can be encrypted by using the EncryptFile function. The FILE_SUPERSEDE, FILE_OVERWRITE and FILE_OVERWRITE_IF dispositions can then be used on the files in that directory. This action will encrypt the files. Encryption on the files is then verified by opening the file in a different process, with a different security token. ACCESS_DENIED should be returned.

  • DirectoryEncryptedNewFileTest. A directory can be encrypted by using the NtCreateFile function with the FILE_ATTRIBUTE_ENCRYPTED flag specified. A new file cthat is reated under the encrypted directory should be encrypted by default. Encryption on the file is tested by opening the file in a different process, with a different security token. ACCESS_DENIED should be returned.

  • DirectoryEncryptedNewDirTest. A directory can be encrypted by using the NtCreateFile function with the FILE_ATTRIBUTE_ENCRYPTED flag specified. A new directory that is created under the encrypted directory should be encrypted by default. Encryption on the directory is tested by opening the directory and verifying that FILE_ATTRIBUTE_ENCRYPTED is set.

  • CreateEncryptedFileTest. A file can be encrypted by using the CreateFile function with the FILE_ATTRIBUTE_ENCRYPTED flag specified. The CREATE_NEW disposition must be used. Encryption on the file is tested by opening the file in a different process, with a different security token. ACCESS_DENIED should be returned.

  • CreateEncryptedDirTest. A directory can be encrypted by using the NtCreateFile function with the FILE_ATTRIBUTE_ENCRYPTED flag specified. When the file of directory attributes are read back, the encryption flag should be set.

  • AddUsersEncryptionTest. The AddUsersToEncryptedFile function can be used to share encrypted files (that is, allow other users to decrypt an encrypted file). This share is verified by encrypting a file in an alternate user context. The QueryUsersOnEncryptedFile function is used to verify that the number of users allowed to access the file is 1. Then, the AddUsersOnEncryptedFile function is used to add another user to the encrypted file. The QueryUsersOnEncryptedFile function should now report that two users are allowed access to the encrypted file.

Quotas File System Test Group

Quotas are used to limit the amount of data a user is allowed to save on a volume. The tests in this group are:

  • VolumeQuotaEnforceTest. Quota usage changes are tracked and quota enforcement is done. This enforcement uses the FILE_VC_QUOTA_ENFORCE flag with NtSetVolumeInformation and FileFsControlInformation. Attempts to exceed the quota should fail (DISK_FULL) and be logged in the event log if event logging is enabled.

  • VolumeQuotaNoneTest. This test uses the FILE_VC_QUOTA_NONE flag, with NtSetVolumeInformation and FileFsControlInformation class to disable quota usage tracking. Although quota usage changes are not tracked, the quota limits are not removed. This situation is the default for an NTFS volume.

  • QuerySetQueryQuotaTest. NtQueryQuotaInformationFile and NtSetQuotaInformationFile allow SIDs (and their respective quota settings) to be queried and set to the volume quota index. NtQueryQuotaInformationFile and NtSetQuotaInformationFile use FILE_GET_QUOTA_INFORMATION to specify a SID. FILE_QUOTA_INFORMATION is used to set and get. It contains limits, thresholds, and a SID.

  • VolumeQuotaTrackTest. This test uses the FILE_VC_QUOTA_TRACK flag, with NtSetVolumeInformation and FileFsControlInformation to enable disk quota tracking, where quota usage changes are tracked but no quota enforcement is done. This situation means that no file system operation are failed for disk quota violations and no disk quota violations events are generated if disk logging is disabled.

  • VolumeQuotaUserLimitTest. We test the limit logging of user quotas with FILE_VC_LOG_QUOTA_LIMIT. This situation is applied with NtSetVolumeInformation and FileFsControlInformation. When the user quota exceeds the limit, the correct event should be generated.

  • VolumeQuotaUserThresholdTest. We test logging of user quotas with FILE_VC_LOG_QUOTA_THRESHOLD. This situation is applied with NtSetVolumeInformation and FileFsControlInformation. When the user quota exceeds the threshold, the correct events should be generated.

  • VolumeQuotaLimitTest. We test that the FILE_VC_LOG_VOLUME_LIMIT flag has no effect on disk quotas. This situation is applied with NtSetVolumeInformation and FileFsControlInformation. When the user quota exceeds the limit, no disk quota events are generated.

  • VolumeQuotaThresholdTest. We test that the FILE_VC_LOG_VOLUME_THRESHOLD flag has no effect on disk quotas. This situation is applied with NtSetVolumeInformation and FileFsControlInformation. When the user quota exceeds the limit, no disk Quota events are generated.

LinkTracking File System Test Group

The Object IDs of files, directories, and volumes allow IShellLink::Resolve broken links on the same volume and across volumes. This situation is tested by creating files and directories with and without Object IDs. The files and directories are moved, and the Resolve method is then invoked. Resolve has two approaches to finding target objects. The first is the distributed link tracking service. If the service is available, it can find an object that was on an NTFS version 5.0 volume and was moved to another location on that volume. It can also find an object that was moved to another NTFS version 5.0 volume, including volumes on other computers. To suppress the use of this service, set the SLR_NOTRACK flag.

The tests in this group are:

  • IshellLinkResolveTest. The IShellLink interface can be used to create and resolve the object of a link that has moved on the same volume. This test creates two files. The ObjectId is deleted on one of the files with FSCTL_DELETE_OBJECT_ID. Two links are created with the IShellLink interface, one to each file. The target files are moved to a different directory. An attempt is made to resolve the links by using IShellLink::Resolve. The test is repeated for target directories.

  • IShellLinkResolveVolumeTest. The IShellLink interface can be used to create and resolve the object of a link that has been moved onto a different volume (on the same system). This test creates two files. The ObjectId is deleted on one of the files with FSCTL_DELETE_OBJECT_ID. Two links are created with the IShellLink interface, one to each file. The target files are moved to a different volume. An attempt is made to resolve the links by using IShellLink::Resolve. The test is repeated for target directories.

ChangeJournal File System Test Group

The tests in this group are:

  • ChangeJournalTest. There are many events that are recorded in the change journal. The reasons can be tested by performing an operation that would cause the change to be recorded, and then reading the change journal.

    • CREATE
    • WRITE
    • SET_INFORMATION
    • SET_EA
    • FSCTL
  • CreateChangeJournalTest. FSCTL_CREATE_USN_JOURNAL creates a USN journal the first time that it is called. Otherwise, it will either increase the size of the existing journal or have no effect.

  • DeleteChangeJournalTest. FSCTL_DELETE_USN_JOURNAL is used when the user want to delete the current USN journal. This control code will initiate the work to scan the Mft and reset all USN values to zero and remove the UsnJournal file from the disk. This operation is tested with the help of FSCTL_QUERY_USN_JOURNAL.

  • EnumMftUsnDataTest. The FSCTL_ENUM_USN_DATA operation creates an enumeration that lists the change journal entries between two specified boundaries. The FSCTL can be called multiple times on the same range by specifying an ordinal MFT_ENUM_DATA->StartFileReferenceNumber value. This test establishes a known set of USN records. The records are then read through FSCTL_ENUM_USN_DATA.

  • QueryChangeJournalTest. FSCTL_QUERY_USN_JOURNAL returns the information about the current instance of the USN journal in USN_JOURNAL_DATA.

  • ReadChangeJournalTest. FSCTL_READ_USN_JOURNAL has input READ_USN_JOURNAL_DATA and output USN_RECORD. This FSCTL returns the USN records from a specific starting USN. This test establishes a known set of USN records. The records are then read through a call to FSCTL_READ_USN_JOURNAL. The contents of the USN record are verified against the expected values.

  • ReadFileChangeJournalTest. FSCTL_READ_FILE_USN_DATA is used with a file or directory handle. It returns the last USN_RECORD for the open handle.

  • ChangeJournalTrimTest. The FSCTL_CREATE_USN_JOURNAL control can change the size of a USN journal: CREATE_USN_JOURNAL_DATA->MaximumSize. The allocation size should be returned to the free pool on the volume.

  • WriteCloseRecordTest. FSCTL_WRITE_USN_CLOSE_RECORD writes a close USN record for the current file and returns its USN.

StreamEnhancements File System Test Group

Named streams have been enhanced to support renaming, deleting, and querying. In addition, change notification events on name, size, and write changes are also supported. The tests in this group are:

  • StreamQueryNamesTest. The named streams in a file can now be queried by using NtQueryInformationFile with the FileStreamInformation class.

  • StreamRenameTest. Streams can now be opened and renamed with NtSetInformationFile and FileRenameInformation class.

  • StreamNotifySizeTest. NtNotifyChangeDirectoryFile can be used with the FILE_NOTIFY_CHANGE_STREAM_SIZE filter. The file size of a stream is changed to cause this notification.

  • StreamNotifyWriteTest. NtNotifyChangeDirectoryFile can be used with the FILE_NOTIFY_CHANGE_STREAM_WRITE filter. Notification Actions: FILE_ACTION_MODIFIED_STREAM -- Modify :stream1

  • StreamNotifyNameTest. NtNotifyChangeDirectoryFile can be used with the FILE_NOTIFY_CHANGE_STREAM_NAME filter to monitor changes to stream names on a file or directory. The FILE_NOTIFY_CHANGE_STREAM_NAME and FILE_ACTION_ADDED_STREAM pair is observed when streams are added to a file. The FILE_NOTIFY_CHANGE_STREAM_NAME and FILE_ACTION_REMOVED_STREAM pair are added when a file that contains named streams is overwritten or superseded.

  • StreamDeleteTest. Named streams can now be opened and marked for deletion (and deleted on cleanup). This feature is tested here.

DefragEnhancements File System Test Group

The tests in this group are:

  • MoveDirTest. Directories can now be de-fragmented by using FSCTL_GET_RETRIEVAL_POINTERS and FSCTL_MOVE_FILE. This test creates many files in a directory. Then, the retrieval pointers are obtained by using a directory handle. The clusters are then moved by using the directory handle, the retrieval pointers, and a volume handle.

  • MoveViewTest. System view (security, quota, reparse, and object ID) directories can now be de-fragmented by using FSCTL_GET_RETRIEVAL_POINTERS and FSCTL_MOVE_FILE. First, "\$Extend\$Reparse:$R:$INDEX_ALLOCATION" is opened as a directory. The clusters are then moved by using the directory handle, the retrieval pointers, and a volume handle.

Supported operating systems for Logo or Signature testing:

  • Windows 7

  • Windows Server 2008 R2

  • Windows Vista

  • Windows Server 2003

  • Windows XP

Program:

Requirements

Software Requirements

The test tool requires the following software:

Hardware Requirements

The test tool requires the following hardware:

  • 1 NTFS formatted volume of at least 2 Gigabytes in size
  • 1 NTFS formatted volume with compression enabled of at least 2 Gigabytes in size
  • 1 FAT16 formatted volume of 2000 Megabytes in size
  • 1 FAT32 formatted volume of at least 2 Gigabytes in size

Processor

The test tool runs on the following processor architectures:

Running IFS Test

You must create formatted volumes as follows:

  • 1 NTFS formatted volume of at least 2 GB in size

  • 1 NTFS formatted volume with compression enabled of at least 2 GB in size

  • 1 FAT16 formatted volume of 2,000 MB in size

  • 1 FAT32 formatted volume of at least 2 GB in size

You can create these volumes by using the disk management user interface.

You must also add the machine to a WORKGROUP and have the Administrator autologon set up. (The test will automatically set up the correct registry keys, users and groups, and privileges but will require a restart; so you must set up autologon before starting the test.)

To run the test, select the "Installable File System Filter Tests" job in Driver Test Manager (DTM) Studio and schedule it. Modify the parameters to include the appropriate drive letters for each file system type. If you specify NONE for a drive letter, the test will not run for that particular drive type.

Code Tour

File Manifest

File Location

*

[testbinroot]\nttest\basetest\core_file_services\ifstestkit

 

Test Assertions

Anti Virus filter driver does not alter file system behavior.

Test Assertion GUID: A72C4D26-977B-19CB-2E11-D6F93917D718

 

 

Build date: 9/14/2012