Changeset 2992 for box/trunk/lib


Ignore:
Timestamp:
28/08/2011 20:07:17 (9 months ago)
Author:
chris
Message:

Use "more standard" Windows API functions FindFirstFileW and FindNextFileW
for directory enumeration instead of _wfindfirst and _wfindnext.

Ignore reparse points when enumerating directories to avoid infinite loops.

Convert VSS paths back to real paths when notifying users about backup
progress.

Location:
box/trunk/lib/win32
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • box/trunk/lib/win32/emu.cpp

    r2962 r2992  
    11// Box Backup Win32 native port by Nick Knight 
    2  
    3 // Need at least 0x0500 to use GetFileSizeEx on Cygwin/MinGW 
    4 #define WINVER 0x0500 
    52 
    63#include "emu.h" 
     
    10811078        } 
    10821079 
    1083         pDir->fd = _wfindfirst((const wchar_t*)pDir->name, &(pDir->info)); 
    1084  
    1085         if (pDir->fd == -1) 
     1080        pDir->fd = FindFirstFileW(pDir->name, &pDir->info); 
     1081        DWORD tmp = GetLastError(); 
     1082 
     1083        if (pDir->fd == INVALID_HANDLE_VALUE) 
    10861084        { 
    10871085                delete [] pDir->name; 
     
    11121110                struct dirent *den = NULL; 
    11131111 
    1114                 if (dp && dp->fd != -1) 
    1115                 { 
    1116                         if (!dp->result.d_name ||  
    1117                                 _wfindnext(dp->fd, &dp->info) != -1) 
     1112                if (dp && dp->fd != INVALID_HANDLE_VALUE) 
     1113                { 
     1114                        // first time around, when dp->result.d_name == NULL, use 
     1115                        // the values returned by FindFirstFile. After that, call 
     1116                        // FindNextFileW to return new ones. 
     1117                        if (!dp->result.d_name || 
     1118                                FindNextFileW(dp->fd, &dp->info) != 0) 
    11181119                        { 
    11191120                                den = &dp->result; 
    1120                                 std::wstring input(dp->info.name); 
     1121                                std::wstring input(dp->info.cFileName); 
    11211122                                memset(tempbuff, 0, sizeof(tempbuff)); 
    1122                                 WideCharToMultiByte(CP_UTF8, 0, dp->info.name,  
     1123                                WideCharToMultiByte(CP_UTF8, 0, dp->info.cFileName,  
    11231124                                        -1, &tempbuff[0], sizeof (tempbuff),  
    11241125                                        NULL, NULL); 
    11251126                                //den->d_name = (char *)dp->info.name; 
    11261127                                den->d_name = &tempbuff[0]; 
    1127                                 if (dp->info.attrib & FILE_ATTRIBUTE_DIRECTORY) 
     1128                                den->d_type = dp->info.dwFileAttributes; 
     1129                        } 
     1130                        else // FindNextFileW failed 
     1131                        { 
     1132                                // Why did it fail? No more files? 
     1133                                winerrno = GetLastError(); 
     1134                                den = NULL; 
     1135 
     1136                                if (winerrno == ERROR_NO_MORE_FILES) 
    11281137                                { 
    1129                                         den->d_type = S_IFDIR; 
     1138                                        errno = 0; // no more files 
    11301139                                } 
    11311140                                else 
    11321141                                { 
    1133                                         den->d_type = S_IFREG; 
     1142                                        errno = ENOSYS; 
    11341143                                } 
    11351144                        } 
     
    11391148                        errno = EBADF; 
    11401149                } 
     1150 
    11411151                return den; 
    11421152        } 
     
    11601170        try 
    11611171        { 
    1162                 int finres = -1; 
     1172                BOOL finres = false; 
     1173 
    11631174                if (dp) 
    11641175                { 
    1165                         if(dp->fd != -1) 
     1176                        if(dp->fd != INVALID_HANDLE_VALUE) 
    11661177                        { 
    1167                                 finres = _findclose(dp->fd); 
     1178                                finres = FindClose(dp->fd); 
    11681179                        } 
    11691180 
     
    11721183                } 
    11731184 
    1174                 if (finres == -1) // errors go to EBADF  
    1175                 { 
     1185                if (finres == FALSE) // errors go to EBADF  
     1186                { 
     1187                        winerrno = GetLastError(); 
    11761188                        errno = EBADF; 
    11771189                } 
    11781190 
    1179                 return finres; 
     1191                return (finres == TRUE) ? 0 : -1; 
    11801192        } 
    11811193        catch (...) 
  • box/trunk/lib/win32/emu.h

    r2929 r2992  
    5151#endif 
    5252 
     53// We need WINVER at least 0x0500 to use GetFileSizeEx on Cygwin/MinGW, 
     54// and 0x0501 for FindFirstFile(W) for opendir/readdir. 
     55// 
    5356// WIN32_WINNT versions 0x0600 (Vista) and higher enable WSAPoll() in 
    5457// winsock2.h, whose struct pollfd conflicts with ours below, so for 
    55 // now we just set it lower than that, to Windows 2000. 
     58// now we just set it lower than that, to Windows XP (0x0501). 
     59 
    5660#ifdef WINVER 
    57         #if WINVER != 0x0500 
    58                 #error Must include emu.h before setting WINVER 
    59         #endif 
    60 #endif 
    61 #define WINVER 0x0500 
     61#       if WINVER != 0x0501 
     62// provoke a redefinition warning to track down the offender 
     63#               define WINVER 0x0501 
     64#               error Must include emu.h before setting WINVER 
     65#       endif 
     66#endif 
     67#define WINVER 0x0501 
    6268 
    6369#ifdef _WIN32_WINNT 
    64         #if _WIN32_WINNT != 0x0500 
    65                 #error Must include emu.h before setting _WIN32_WINNT 
    66         #endif 
    67 #endif 
    68 #define _WIN32_WINNT 0x0500 
     70#       if _WIN32_WINNT != 0x0501 
     71// provoke a redefinition warning to track down the offender 
     72#               define _WIN32_WINNT 0x0501 
     73#               error Must include emu.h before setting _WIN32_WINNT 
     74#       endif 
     75#endif 
     76#define _WIN32_WINNT 0x0501 
    6977 
    7078// Windows headers 
     
    238246{ 
    239247        char *d_name; 
    240         unsigned long d_type; 
     248        DWORD d_type; // file attributes 
    241249}; 
    242250 
    243251struct DIR 
    244252{ 
    245         intptr_t                fd;     // filedescriptor 
    246         // struct _finddata_t   info; 
    247         struct _wfinddata_t     info; 
    248         // struct _finddata_t   info; 
    249         struct dirent           result; // d_name (first time null) 
    250         wchar_t                 *name;  // null-terminated byte string 
     253        HANDLE           fd;     // the HANDLE returned by FindFirstFile 
     254        WIN32_FIND_DATAW info; 
     255        struct dirent    result; // d_name (first time null) 
     256        wchar_t*         name;   // null-terminated byte string 
    251257}; 
    252258 
Note: See TracChangeset for help on using the changeset viewer.