Ken Thomases ken@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.
On Feb 4, 2014, at 3:54 AM, Alexandre Julliard wrote:
Ken Thomases ken@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
Ken Thomases ken@codeweavers.com writes:
I'm open to suggestions for other ways to fix it. Can a directory handle be made to carry additional state?
Not at this point, but we probably want to add a mechanism for that and get rid of the whole getdirentries mess.
On Feb 4, 2014, at 4:37 AM, Alexandre Julliard wrote:
Ken Thomases ken@codeweavers.com writes:
I'm open to suggestions for other ways to fix it. Can a directory handle be made to carry additional state?
Not at this point, but we probably want to add a mechanism for that and get rid of the whole getdirentries mess.
Instead of getdirentries(), we'd use readdir()? And the extra state would be an index of the next entry to return (so NtQueryDirectoryFile() would skip that many entries, unless told to restart)?
Or did you have something else in mind?
-Ken
Ken Thomases ken@codeweavers.com writes:
On Feb 4, 2014, at 4:37 AM, Alexandre Julliard wrote:
Ken Thomases ken@codeweavers.com writes:
I'm open to suggestions for other ways to fix it. Can a directory handle be made to carry additional state?
Not at this point, but we probably want to add a mechanism for that and get rid of the whole getdirentries mess.
Instead of getdirentries(), we'd use readdir()? And the extra state would be an index of the next entry to return (so NtQueryDirectoryFile() would skip that many entries, unless told to restart)?
Or did you have something else in mind?
My plan is rather to move the caching of the whole directory from kernel32 to ntdll.
On Feb 7, 2014, at 5:59 AM, Alexandre Julliard wrote:
Ken Thomases ken@codeweavers.com writes:
On Feb 4, 2014, at 4:37 AM, Alexandre Julliard wrote:
Ken Thomases ken@codeweavers.com writes:
I'm open to suggestions for other ways to fix it. Can a directory handle be made to carry additional state?
Not at this point, but we probably want to add a mechanism for that and get rid of the whole getdirentries mess.
Instead of getdirentries(), we'd use readdir()? And the extra state would be an index of the next entry to return (so NtQueryDirectoryFile() would skip that many entries, unless told to restart)?
Or did you have something else in mind?
My plan is rather to move the caching of the whole directory from kernel32 to ntdll.
Hmm. Isn't a file handle potentially shared among processes? How would the cache, as well as the read position within it, be coordinated?
-Ken