kernel32: In FindFirstFileExW(), call NtQueryDirectoryFile() again to determine if it read all files.

Ken Thomases ken at codeweavers.com
Tue Feb 4 04:31:16 CST 2014


On Feb 4, 2014, at 3:54 AM, Alexandre Julliard wrote:

> Ken Thomases <ken at codeweavers.com> writes:
> 
>> Previously, it only checked if the first call failed to fill the buffer.  This
>> is unreliable since the underlying implementation may be forced to return
>> a short buffer by the semantics of the system calls used.  In particular,
>> getdirentries() on Mac OS X can only read at the resolution of whole blocks
>> rather than individual directory entries for AFP-mounted volumes.
> 
> It would be better to fix the ntdll side.

I'm not sure it can be fixed.  That's where I started looking.

I'm also not entirely sure that the ntdll side is broken.  That is, I didn't find any clear indication that NtQueryDirectoryFile() can't return fewer entries than would fill its buffer even if there are more entries in the directory.  Or that the logic in FindFirstFileExW(), where it uses a putative maximum entry size to decide if the buffer has "too much" remaining free space, is justified.

The issue is that the only state that persists between calls to NtQueryDirectoryFile()/read_directory_getdirentries() is the file descriptor's file position.  getdirentries() does not necessarily allow for leaving the file position at any desired entry.  For some file systems, it reads its data in blocks.  On those file systems, for any given buffer size passed in to NtQueryDirectoryFile(), getdirentries() is likely to only be able to read more than will fit or fewer than will fit, not just as many as will fit.

I'm open to suggestions for other ways to fix it.  Can a directory handle be made to carry additional state?

-Ken




More information about the wine-devel mailing list