diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:20:07 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:20:07 +0200 |
commit | 88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170 (patch) | |
tree | c6c5babb49b90293380106b81ae5c446959ac70f /zen/FindFilePlus | |
parent | 5.3 (diff) | |
download | FreeFileSync-88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170.tar.gz FreeFileSync-88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170.tar.bz2 FreeFileSync-88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170.zip |
5.4
Diffstat (limited to 'zen/FindFilePlus')
-rw-r--r-- | zen/FindFilePlus/FindFilePlus.vcxproj | 8 | ||||
-rw-r--r-- | zen/FindFilePlus/find_file_plus.cpp | 43 | ||||
-rw-r--r-- | zen/FindFilePlus/find_file_plus.h | 3 |
3 files changed, 44 insertions, 10 deletions
diff --git a/zen/FindFilePlus/FindFilePlus.vcxproj b/zen/FindFilePlus/FindFilePlus.vcxproj index 2c4256a6..a50239ab 100644 --- a/zen/FindFilePlus/FindFilePlus.vcxproj +++ b/zen/FindFilePlus/FindFilePlus.vcxproj @@ -80,10 +80,10 @@ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">FindFilePlus_$(Platform)</TargetName> <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">FindFilePlus_$(Platform)</TargetName> <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">FindFilePlus_$(Platform)</TargetName> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">D:\Data\WinDDK\inc\ddk;D:\Data\WinDDK\inc\api;D:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">D:\Data\WinDDK\inc\ddk;D:\Data\WinDDK\inc\api;D:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">D:\Data\WinDDK\inc\ddk;D:\Data\WinDDK\inc\api;D:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> - <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">D:\Data\WinDDK\inc\ddk;D:\Data\WinDDK\inc\api;D:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> + <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Data\WinDDK\inc\ddk;C:\Data\WinDDK\inc\api;C:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> + <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\Data\WinDDK\inc\ddk;C:\Data\WinDDK\inc\api;C:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> + <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\Data\WinDDK\inc\ddk;C:\Data\WinDDK\inc\api;C:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> + <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\Data\WinDDK\inc\ddk;C:\Data\WinDDK\inc\api;C:\Data\WinDDK\inc\crt;$(WindowsSdkDir)\include;$(VCInstallDir)include</IncludePath> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <BuildLog> diff --git a/zen/FindFilePlus/find_file_plus.cpp b/zen/FindFilePlus/find_file_plus.cpp index ad385668..9fba5f1a 100644 --- a/zen/FindFilePlus/find_file_plus.cpp +++ b/zen/FindFilePlus/find_file_plus.cpp @@ -265,14 +265,49 @@ void FileSearcher::readDirImpl(FileInformation& output) //throw FileError false); //__in BOOLEAN restartScan if (!NT_SUCCESS(rv)) { - if (rv == STATUS_NO_SUCH_FILE) //harmonize ntQueryDirectoryFile() error handling! failure to find a file on first call returns STATUS_NO_SUCH_FILE, - rv = STATUS_NO_MORE_FILES; //while on subsequent accesses returns STATUS_NO_MORE_FILES - //note: not all directories contain "., .." entries! E.g. a drive's root directory or NetDrive + ftp.gnu.org\CRYPTO.README" - //-> addon: this is NOT a directory, it looks like one in NetDrive, but it's a file in Opera + /* + fallback to default directory query method, if FileIdBothDirectoryInformation is not properly implemented + this is required for NetDrive mounted Webdav, e.g. www.box.net and NT4, 2000 remote drives, et al. + + NT status code | Win32 error code + --------------------------------|------------------------ + STATUS_INVALID_LEVEL | ERROR_INVALID_LEVEL + STATUS_NOT_SUPPORTED | ERROR_NOT_SUPPORTED + STATUS_UNEXPECTED_NETWORK_ERROR | ERROR_UNEXP_NET_ERR -> traverse network drive hosted by Win98 + STATUS_INVALID_PARAMETER | ERROR_INVALID_PARAMETER + STATUS_INVALID_NETWORK_RESPONSE | ERROR_BAD_NET_RESP + STATUS_INVALID_INFO_CLASS | ERROR_INVALID_PARAMETER + STATUS_UNSUCCESSFUL | ERROR_GEN_FAILURE + STATUS_ACCESS_VIOLATION | ERROR_NOACCESS ->FileIdBothDirectoryInformation on XP accessing UDF + STATUS_NO_SUCH_FILE | ERROR_FILE_NOT_FOUND + + rv == STATUS_NO_SUCH_FILE: + failure to find a file on first call returns STATUS_NO_SUCH_FILE, while subsequent accesses return STATUS_NO_MORE_FILES + note: not all directories contain ".", ".." entries! E.g. a drive's root directory or NetDrive + ftp.gnu.org\CRYPTO.README" + -> addon: this is NOT a directory, it looks like one in NetDrive, but it's a file in Opera + STATUS_NO_SUCH_FILE is abused by some citrix shares instead of "STATUS_INVALID_PARAMETER" so we treat it as such! + => since the directory is "truly empty" a fallback won't hurt + */ + if (rv == STATUS_INVALID_LEVEL || + rv == STATUS_NOT_SUPPORTED || + rv == STATUS_UNEXPECTED_NETWORK_ERROR || + rv == STATUS_INVALID_PARAMETER || + rv == STATUS_INVALID_NETWORK_RESPONSE || + rv == STATUS_INVALID_INFO_CLASS || + rv == STATUS_UNSUCCESSFUL || + rv == STATUS_ACCESS_VIOLATION || + rv == STATUS_NO_SUCH_FILE) + rv = STATUS_NOT_SUPPORTED; throw NtFileError(rv); //throws STATUS_NO_MORE_FILES when finished } + //for (NTSTATUS i = 0xC0000000L; i != -1; ++i) + //{ + // if (rtlNtStatusToDosError(i) == 59) //ERROR_UNEXP_NET_ERR + // __asm int 3; + //} + if (status.Information == 0) //except for the first call to call ::NtQueryDirectoryFile(): throw NtFileError(STATUS_BUFFER_OVERFLOW); //if buffer size is too small, return value is STATUS_SUCCESS and Information == 0 -> we don't expect this! } diff --git a/zen/FindFilePlus/find_file_plus.h b/zen/FindFilePlus/find_file_plus.h index 7d03d98b..3799a1e1 100644 --- a/zen/FindFilePlus/find_file_plus.h +++ b/zen/FindFilePlus/find_file_plus.h @@ -50,8 +50,7 @@ FindHandle openDir(const wchar_t* dirname); //returns nullptr on error, call ::G DLL_FUNCTION_DECLARATION bool readDir(FindHandle hnd, FileInformation& output); //returns false on error or if there are no more files; ::GetLastError() returns ERROR_NO_MORE_FILES in this case /* -warning:; this may also return file system implementation dependent error codes like ERROR_NOT_SUPPORTED, ERROR_INVALID_LEVEL, -ect. if "FileIdBothDirectoryInformation" is not supported! We need a fallback: +warning: may also return with ERROR_NOT_SUPPORTED if "FileIdBothDirectoryInformation" is not supported! We need a fallback: sometimes it's *not* sufficient to use fallback for NtQueryDirectoryFile() alone, we need to reset "hDir", since it may be fucked up by some poor file system layer implementation: - Samba before v3.0.22 (Mar 30, 2006) seems to have a bug which sucessfully returns 128 elements via NtQueryDirectoryFile() and FileIdBothDirectoryInformation, |