// ************************************************************************** // * This file is part of the FreeFileSync project. It is distributed under * // * GNU General Public License: http://www.gnu.org/licenses/gpl.html * // * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * // ************************************************************************** #ifndef FIND_FIRST_FILE_PLUS_HEADER_087483434 #define FIND_FIRST_FILE_PLUS_HEADER_087483434 #ifdef FIND_FILE_PLUS_DLL_EXPORTS #define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllexport) #else #define DLL_FUNCTION_DECLARATION extern "C" __declspec(dllimport) #endif #ifdef FIND_FILE_PLUS_DLL_EXPORTS #include //driver level headers must be included *before* windows api headers! #endif #include // #undef min #undef max #include namespace findplus { /*-------------- |declarations| --------------*/ struct FileInformation { FILETIME creationTime; FILETIME lastWriteTime; ULARGE_INTEGER fileSize; ULARGE_INTEGER fileId; //optional: may be 0 if not supported DWORD fileAttributes; DWORD reparseTag; //set if "fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT" DWORD shortNameLength; WCHAR shortName[MAX_PATH + 1]; //shortName is 0-terminated }; //no need for #pragma pack -> all members are perfectly 4, 8 byte aligned! class FileSearcher; typedef FileSearcher* FindHandle; DLL_FUNCTION_DECLARATION FindHandle openDir(const wchar_t* dirname); //returns nullptr on error, call ::GetLastError() //note: do NOT place an asterisk at end, e.g. C:\SomeDir\*, as you would do for ::FindFirstFile() 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: 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, then fails with STATUS_INVALID_LEVEL. Fallback to FileBothDirectoryInformation will return STATUS_NO_MORE_FILES, even if there *are* more files - NtQueryDirectoryFile() may *not* respect "restartScan" for some weird Win2000 file system drivers, so we cannot rely on this as a replacement for a "hDir" reset - Windows 7 Remote Desktop sharing does not work unless "hDir" is reset! => let's assume worst case in general and do a reset! perf note: implementing this reset at a folder level is possible, but a huge perf-killer (additional open/close handle), therefore fallback must apply to a complete folder (sub-)tree! => caller needs to handle this and implement FindFirstFile()/FindNextFile() fallback! */ DLL_FUNCTION_DECLARATION void closeDir(FindHandle hnd); /*---------- |typedefs| ----------*/ typedef FindHandle (*FunType_openDir )(const wchar_t* dirname); typedef bool (*FunType_readDir )(FindHandle hnd, FileInformation& dirInfo); typedef void (*FunType_closeDir)(FindHandle hnd); /*-------------- |symbol names| --------------*/ //const pointers ensure internal linkage const char funName_openDir [] = "openDir"; const char funName_readDir [] = "readDir"; const char funName_closeDir[] = "closeDir"; /*--------------- |library names| ---------------*/ inline const wchar_t* getDllName() { return zen::is64BitBuild ? L"FindFilePlus_x64.dll" : L"FindFilePlus_Win32.dll"; } } #undef DLL_FUNCTION_DECLARATION #endif //FIND_FIRST_FILE_PLUS_HEADER_087483434