diff options
Diffstat (limited to 'src/libutil/FileUtils.cpp')
-rw-r--r-- | src/libutil/FileUtils.cpp | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/src/libutil/FileUtils.cpp b/src/libutil/FileUtils.cpp index 64b1bb1..975a78c 100644 --- a/src/libutil/FileUtils.cpp +++ b/src/libutil/FileUtils.cpp @@ -7,6 +7,8 @@ #else #define WIN32_MEAN_AND_LEAN #include <windows.h> +#include "util/win32/errormsg.hpp" +#include "win32/tcharutils.h" #endif #include <sstream> @@ -61,10 +63,65 @@ static vector<string> directory_entries_unix( const string &dir, bool absolute, #endif #ifdef _WIN32 -static vector<string> directory_entries_win32( const string &/*dir*/, bool /*absolute*/, bool /* recursive */ ) +static vector<string> directory_entries_win32( const string &dir, bool absolute, bool recursive ) { vector<string> files; + wstringstream wpath; + wpath << utf8toucs2( dir ) << L"\\*."; + + WIN32_FIND_DATAW fd; + HANDLE h = FindFirstFileW( wpath.str( ).c_str( ), &fd ); + if( h == INVALID_HANDLE_VALUE ) { + DWORD err = GetLastError( ); + if( err == ERROR_NO_MORE_FILES ) { + FindClose( h ); + return files; + } + ostringstream ss; + ss << "FindFirstFileW failed with '" << dir << "': " << getLastError( ); + throw runtime_error( ss.str( ) ); + } + + while( h != INVALID_HANDLE_VALUE ) { + if( ( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) != 0 ) { + if( wcscmp( fd.cFileName, L"." ) == 0 || + wcscmp( fd.cFileName, L".." ) == 0 ) { + goto NEXT; + } + if( recursive ) { + ostringstream ss; + ss << dir << "\\" << wchartoutf8( fd.cFileName ); + vector<string> subfiles = directory_entries_win32( ss.str( ), absolute, recursive ); + files.insert( files.end( ), subfiles.begin( ), subfiles.end( ) ); + } + } else if( ( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) { + if( absolute ) { + ostringstream ss; + ss << dir << "\\" << wchartoutf8( fd.cFileName ); + files.push_back( ss.str( ) ); + } else { + files.push_back( string( wchartoutf8( fd.cFileName ) ) ); + } + } +NEXT: + if( !FindNextFileW( h, &fd ) ) { + DWORD err = GetLastError( ); + if( err == ERROR_NO_MORE_FILES ) { + // finish iterating + FindClose( h ); + return files; + } else { + FindClose( h ); + ostringstream ss; + ss << "FindNextFileW failed with '" << dir << "': " << getLastError( ); + throw runtime_error( ss.str( ) ); + } + } + } + + FindClose( h ); + return files; } #endif |