-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
filesystem::is_directory() returns wrong result for directories on smb 1 network shares #282
Comments
Please, retest with the latest version from git develop or Boost 1.82 beta1. |
With the latest version of boost the problem still persists. We've debugged library source code in operations.cpp for our example - it follows "normal" execution path. The function GetFileInformationByHandleEx just returns, that problematic directory is a file. |
Well, in that case I'm not sure what I can do. What Windows version are you using? Both client and server. |
Also, I noticed you explicitly mention SMBv1. Note that this protocol is deprecated and not installed by default. Does this reproduce with SMBv2 or SMBv3? |
We've used win 10 as a client and win server 2008 as a server in our experiment. We were unable to reproduce the issue with SMBv2 or SMBv3 in our setup, but we don't know exactly whether these results are reliable since we don't know the underlying nature of the problem at the OS level. We know, that SMB v1 is deprecated, but many users have legacy network infrastructure with only SMB v1 in use. For GetFileInformationByHandleEx and GetFileInformationByHandle Microsoft explicitly states in their documentation that
With old GetFileAttributesW-based implementation the issue doesn't arise. Also, std::filesystem works a expected in this case. |
Using Therefore we need to query file attributes through file handles, at least in the majority of cases where this is possible. I would consider adding a workaround for SMBv1 - if we can detect this particular case. I'm unlikely to be able to set up a test system any time soon, so I would appreciate if you could help with this. Here are a few ideas to test:
|
We've tried to test GetFileInformationByHandleEx with our setup and accidentally discovered, that changing dwDesiredAccess to GENERIC_READ or FILE_READ_EA in call to CreateFile solves the issue (but i don't know whether such change can be safely applied). So that code (like in current boost):
gives 128 (i.e. "FILE_ATTRIBUTE_NORMAL") And that code:
gives 16 (i.e. "FILE_ATTRIBUTE_DIRECTORY") |
Call to GetFileInformationByHandleEx for FileStandardInfo also reports that filesystem object is a directory (in info.Directory field of FILE_STANDARD_INFO) even with dwDesiredAccess=FILE_READ_ATTRIBUTES in CreateFile:
|
Thanks for all the information. I have implemented a fix in branch It would be great if you could run library tests in an SMBv1 share, or at least check if other file operations, such as |
The fix is now merged into develop. Thanks again for all the testing. If you can, please still test that your usecase works with the fixed Boost.Filesystem. |
This patch solves the problem in our setup. Thank you! |
I believe directory_iterators are still broken with smbv1. Should I file another issue? |
Yes, and I would appreciate the detailed info on what system call is failing and how. |
…rectories Before trying to open/create the destination file `mkvmerge` always tries to ensure that the destination directory exists by calling the function `boost::filesystem::create_directories()`. Unfortunately the Boost.Filesystem library contained [a bug](boostorg/filesystem#282) in recent versions that manifested when determining directory entry information on a network share connected via SMB1. The result was that Boost.Filesystem thought that an existing directory either didn't exist or that the filesystem entry is not actually a directory. Boost.Filesystem would then try to create the directory, which failed as it existed already, causing `create_directories()` to fail which in turn caused `mkvmerge` to abort. This bug was fixed in Boost.Filesystem's version 1.82.0, which MKVToolNix for Windows will be built with from now on. Fixes #3547.
We have switched our codebase from boost 1.61 to 1.80 and observed wrong behaviour of function is_directory(p) for some directories located on some network shares. Namely, this function returns that filesystem object is not a directory even in reality it is. After some investigations we were able to reproduce the issue on a virtual machine, which runs smb version 1 network share. The following code (here "\WIN-ZL5F8K2HI90\Users\Default" is beforementioned smb1 network share on a virtual machine):
produces the following output:
0 // that is boost::filesystems thinks that "\WIN-ZL5F8K2HI90\Users\Default" is not a directory
19 // that is GetFileAttributesW states that "\WIN-ZL5F8K2HI90\Users\Default" is a directory
We believe that the root cause of the issue is commit 97722a3
The text was updated successfully, but these errors were encountered: