188.8.131.52.3 Directory Information Queries
This section describes how the object store processes directory queries for the following FileInformationClass values:
This algorithm uses the following local variables:
Boolean value (initialized to FALSE): FirstQuery
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 "*".
FirstQuery = TRUE
Set Open.QueryPattern to FileNamePattern for use in subsequent queries.
FirstQuery = FALSE
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.
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:
If Link.Name or Link.ShortName matches FileNamePattern as described in section 184.108.40.206 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.
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.
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.
Set StatusToReturn to STATUS_NO_MORE_FILES, which means no more files were found in this directory that match the given wildcard pattern.
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.