Cygwin: readdir: drop support for NT4/Win2K shares and Samba < 3.0.22
These systems are at least 18 years old and so buggy that they are hopefully not used anymore. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
8bd6ba8f16
commit
b9ed33dec0
|
@ -2463,66 +2463,16 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
|
||||||
d_cache (dir), DIR_BUF_SIZE,
|
d_cache (dir), DIR_BUF_SIZE,
|
||||||
FileIdBothDirectoryInformation,
|
FileIdBothDirectoryInformation,
|
||||||
FALSE, NULL, dir->__d_position == 0);
|
FALSE, NULL, dir->__d_position == 0);
|
||||||
/* FileIdBothDirectoryInformation isn't supported for remote drives
|
/* FileIdBothDirectoryInformation isn't supported on some
|
||||||
on NT4 and 2K systems. There are also hacked versions of
|
remote drives, but we don't know every system out there.
|
||||||
Samba 3.0.x out there (Debian-based it seems), which return
|
Check various status codes indicating this. */
|
||||||
STATUS_NOT_SUPPORTED rather than handling this info class.
|
if (!NT_SUCCESS (status)
|
||||||
We just fall back to using a standard directory query in
|
|
||||||
this case and note this case using the dirent_get_d_ino flag. */
|
|
||||||
if (!NT_SUCCESS (status) && status != STATUS_NO_MORE_FILES
|
|
||||||
&& (status == STATUS_INVALID_LEVEL
|
&& (status == STATUS_INVALID_LEVEL
|
||||||
|| status == STATUS_NOT_SUPPORTED
|
|| status == STATUS_NOT_SUPPORTED
|
||||||
|| status == STATUS_INVALID_PARAMETER
|
|| status == STATUS_INVALID_PARAMETER
|
||||||
|| status == STATUS_INVALID_NETWORK_RESPONSE
|
|| status == STATUS_INVALID_NETWORK_RESPONSE
|
||||||
|| status == STATUS_INVALID_INFO_CLASS))
|
|| status == STATUS_INVALID_INFO_CLASS))
|
||||||
dir->__flags &= ~dirent_get_d_ino;
|
dir->__flags &= ~dirent_get_d_ino;
|
||||||
/* Something weird happens on Samba up to version 3.0.21c, which is
|
|
||||||
fixed in 3.0.22. FileIdBothDirectoryInformation seems to work
|
|
||||||
nicely, but only up to the 128th entry in the directory. After
|
|
||||||
reaching this entry, the next call to NtQueryDirectoryFile
|
|
||||||
(FileIdBothDirectoryInformation) returns STATUS_INVALID_LEVEL.
|
|
||||||
Why should we care, we can just switch to
|
|
||||||
FileBothDirectoryInformation, isn't it? Nope! The next call to
|
|
||||||
NtQueryDirectoryFile(FileBothDirectoryInformation) actually
|
|
||||||
returns STATUS_NO_MORE_FILES, regardless how many files are left
|
|
||||||
unread in the directory. This does not happen when using
|
|
||||||
FileBothDirectoryInformation right from the start, but since
|
|
||||||
we can't decide whether the server we're talking with has this
|
|
||||||
bug or not, we end up serving Samba shares always in the slow
|
|
||||||
mode using FileBothDirectoryInformation. So, what we do here is
|
|
||||||
to implement the solution suggested by Andrew Tridgell, we just
|
|
||||||
reread all entries up to dir->d_position using
|
|
||||||
FileBothDirectoryInformation.
|
|
||||||
However, We do *not* mark this server as broken and fall back to
|
|
||||||
using FileBothDirectoryInformation further on. This would slow
|
|
||||||
down every access to such a server, even for directories under
|
|
||||||
128 entries. Also, bigger dirs only suffer from one additional
|
|
||||||
call per full directory scan, which shouldn't be too big a hit.
|
|
||||||
This can easily be changed if necessary. */
|
|
||||||
if (status == STATUS_INVALID_LEVEL && dir->__d_position)
|
|
||||||
{
|
|
||||||
d_cachepos (dir) = 0;
|
|
||||||
for (int cnt = 0; cnt < dir->__d_position; ++cnt)
|
|
||||||
{
|
|
||||||
if (d_cachepos (dir) == 0)
|
|
||||||
{
|
|
||||||
status = NtQueryDirectoryFile (get_handle (), NULL, NULL,
|
|
||||||
NULL, &io, d_cache (dir),
|
|
||||||
DIR_BUF_SIZE,
|
|
||||||
FileBothDirectoryInformation,
|
|
||||||
FALSE, NULL, cnt == 0);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
goto go_ahead;
|
|
||||||
}
|
|
||||||
buf = (PFILE_ID_BOTH_DIR_INFORMATION) (d_cache (dir)
|
|
||||||
+ d_cachepos (dir));
|
|
||||||
if (buf->NextEntryOffset == 0)
|
|
||||||
d_cachepos (dir) = 0;
|
|
||||||
else
|
|
||||||
d_cachepos (dir) += buf->NextEntryOffset;
|
|
||||||
}
|
|
||||||
goto go_ahead;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* NFS must use FileNamesInformation! Any other information class
|
/* NFS must use FileNamesInformation! Any other information class
|
||||||
skips all symlinks. */
|
skips all symlinks. */
|
||||||
|
@ -2535,8 +2485,6 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
|
||||||
FALSE, NULL, dir->__d_position == 0);
|
FALSE, NULL, dir->__d_position == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
go_ahead:
|
|
||||||
|
|
||||||
if (status == STATUS_NO_MORE_FILES)
|
if (status == STATUS_NO_MORE_FILES)
|
||||||
/*nothing*/;
|
/*nothing*/;
|
||||||
else if (!NT_SUCCESS (status))
|
else if (!NT_SUCCESS (status))
|
||||||
|
|
|
@ -20,7 +20,7 @@ What changed:
|
||||||
- ps -f now prints the commandline rather than the full path to the
|
- ps -f now prints the commandline rather than the full path to the
|
||||||
executable.
|
executable.
|
||||||
|
|
||||||
- Drop support for NT4 and Samba < 3.0.
|
- Drop support for NT4 and Samba < 3.0.22.
|
||||||
|
|
||||||
- Now that SMBv1 is ultimately deprecated and not installed by default
|
- Now that SMBv1 is ultimately deprecated and not installed by default
|
||||||
on latest Windows versions, enumerating network servers in // and shares
|
on latest Windows versions, enumerating network servers in // and shares
|
||||||
|
|
Loading…
Reference in New Issue