2.1.5.6.3 Directory Information Queries

Directory queries return requested information about files contained in the directory, based on the Link structures in Open.DirectoryList. Note that for performance reasons an object store MAY delay updating a Link’s duplicated information following modifications to a file, resulting in directory queries returning stale information. Some file modifications require an immediate update of the duplicated information, which will be noted in this document by invoking the algorithm described in section 2.1.4.18.

This section describes how the object store processes directory queries for the following FileInformationClass values:

  • FileBothDirectoryInformation

  • FileDirectoryInformation

  • FileFullDirectoryInformation

  • FileId64ExtdBothDirectoryInformation

  • FileId64ExtdDirectoryInformation

  • FileIdAllExtdBothDirectoryInformation

  • FileIdAllExtdDirectoryInformation

  • FileIdBothDirectoryInformation

  • FileIdExtdDirectoryInformation

  • FileIdFullDirectoryInformation

  • FileNamesInformation

This algorithm uses the following local variables:

  • Boolean value (initialized to FALSE): FirstQuery

  • Link: Link

  • 32-bit Unsigned integers: FileNameBytesToCopy, BaseLength, FoundNameLength

  • Pointer to given FileInformationClass Structure: Entry, LastEntry

  • Status (initialized to STATUS_SUCCESS): StatusToReturn

Pseudocode for the algorithm is as follows:

  • If OutputBufferSize is less than the size needed to return a single entry, the operation MUST be failed with STATUS_INFO_LENGTH_MISMATCH. The following subsections describe the initial size checks for OutputBufferSize to determine whether any entries can be returned.

  • If Open.File is not a DirectoryFile, the operation MUST be failed with STATUS_INVALID_PARAMETER.

  • If Open.QueryPattern is empty:

    • FirstQuery = TRUE

    • Else:

    • FirstQuery = FALSE

  • EndIf

  • If FirstQuery is TRUE or (FileNamePattern is not empty and RestartScan is TRUE)<61>

    • If FileNamePattern is empty:

      • Set FileNamePattern to "*".

    • Else:

      • If FileNamePattern is not a valid filename component as described in [MS-FSCC] section 2.1.5, with the exceptions that wildcard characters described in section 2.1.4.3 are permitted and the strings "." and ".." are permitted, the operation MUST be failed with STATUS_OBJECT_NAME_INVALID.

    • EndIf

    • Set Open.QueryPattern to FileNamePattern for use in subsequent queries.

  • Else:

    • Set FileNamePattern to Open.QueryPattern.

  • EndIf

  • If RestartScan is TRUE or Open.QueryLastEntry is empty:

    • Set Open.QueryLastEntry to the first Link in Open.File.DirectoryList, thus enumerating the directory from its beginning.

  • EndIf

  • Set Entry and LastEntry to point to the front of OutputBuffer.

  • Set ByteCount to zero.

  • Set BaseLength to FieldOffset(FileInformationClass.FileName). In other words save the size of the fixed length portion of the given Information Class.

  • For each Link in Open.File.DirectoryList starting at Open.QueryLastEntry:

    • If ReturnSingleEntry is TRUE and Entry != OutputBuffer, then break.

    • If FirstQuery is TRUE or RestartScan is TRUE, the object store MUST set the "." and ".." file names as the first two records returned, unless one of the following is TRUE:

      • Open.File == File.Volume.RootDirectory

      • FileNamePattern == "."

      • FileNamePattern contains wildcard characters as described in section 2.1.4.3 and the Unicode string "." matches FileNamePattern according to the algorithm in section 2.1.4.4.

    • EndIf

    • If Link.Name or Link.ShortName matches FileNamePattern as described in section 2.1.4.4 using the following parameters: FileName set to Link.Name then Link.ShortName if not empty, Expression set to FileNamePattern and Ignorecase set to Open.IsCaseInsensitive, then:

      • Set FoundNameLength to the length, in bytes, of Link.Name.

      • If Entry != OutputBuffer(one or more structures have already been copied into OutputBuffer) and (ByteCount + BaseLength + FoundNameLength) > OutputBufferSize then break.

      • The object store MUST copy the fixed portion of the given FileInformationClass structure to Entry as described in the subsections below. This does not include copying the FileName field.

      • If (ByteCount + BaseLength + FoundNameLength) > OutputBufferSize then:

        • Set FileNameBytesToCopy to OutputBufferSize - ByteCount - BaseLength.

        • Set StatusToReturn to STATUS_BUFFER_OVERFLOW.

        • The scenario where a partial filename is returned only occurs on the first record being returned. The earlier checks guarantee that there will be room for the fixed portion of the given FileInformationClass structure.

      • EndIf

      • Copy FileNameBytesToCopy bytes from Link.Name into FileInformationClass.Filename field.

      • Set LastEntry.NextEntryOffset to Entry - OutputBuffer.

      • Set ByteCount to BlockAlign(ByteCount, 8) + BaseLength + FileNameBytesToCopy.

      • If StatusToReturn != STATUS_SUCCESS, then break.

      • Set LastEntry to Entry.

      • Set Entry to OutputBuffer + ByteCount, which points to the beginning of the next record to be returned (if any).

    • EndIfSet Open.QueryLastEntry to Link.

  • EndFor

  • If no records are being returned:

    • If FirstQuery is TRUE:

      • Set StatusToReturn to STATUS_NO_SUCH_FILE, which means no files were found in this directory that match the given wildcard pattern.

    • Else:

      • Set StatusToReturn to STATUS_NO_MORE_FILES, which means no more files were found in this directory that match the given wildcard pattern.

  • EndIf

  • The object store MUST note that the file has been accessed as specified in section 2.1.4.19 with Open equal to Open.

  • The object store MUST return:

    • Status set to StatusToReturn.

    • OutputBuffer containing an array of as many entries that match the query as will fit in OutputBufferSize.

    • BytesReturned containing the number of bytes filled in OutputBuffer.