After reimplementing readdir() in Cygwin using the
NtQueryDirectoryFile(FileIdBothDirectoryInformation) call, we encountered the
following weird behaviour when accessing remote Samba shares: In directories
with a lot of entries (> 128), we only ever got the first 128 directory
entries, never any more. The next NtQueryDirectoryFile call after getting
the first 128 directory entries returns STATUS_INVALID_LEVEL. If we switch to
using the FileBothDirectoryInformation after getting this error, that call
returns STATUS_NO_MORE_FILES. This does not happen when using the
FileBothDirectoryInformation level right from the start.
I *think* I found the cause of the problem. In source/smbd/trans2.c,
there are the two functions call_trans2findfirst and call_trans2findnext.
The call_trans2findfirst function knows about SMB_FIND_ID_FULL_DIRECTORY_INFO
and SMB_FIND_ID_BOTH_DIRECTORY_INFO, and handles them gracefully. The
call_trans2findnext function does not know these two values and returns
NT_STATUS_INVALID_LEVEL in line 1936. If I didn't miss anything, this problem
should be solved by adding the SMB_FIND_ID_FULL_DIRECTORY_INFO and
SMB_FIND_ID_BOTH_DIRECTORY_INFO values to the allowed values in the
affected switch statement.
Perfect analysis - thanks !
Will be fixed in 3.0.21c.