2.1.5.5.3 Directory Information Queries

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

  • FileBothDirectoryInformation

  • FileDirectoryInformation

  • FileFullDirectoryInformation

  • FileIdBothDirectoryInformation

  • 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 below 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:

    • 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

    • FirstQuery = TRUE

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

  • Else:

    • FirstQuery = FALSE

  • 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, 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

  • If Open.File.UserSetAccessTime is FALSE, the object store MUST update Open.File.LastAccessTime to the current system time.

  • 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.

Show: