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