Changeset 3055


Ignore:
Timestamp:
01/19/12 18:27:44 (3 years ago)
Author:
invisnet
Message:

Big batch of EMU changes for new Win32 lib

Location:
box/invisnet/vs2010/0.11
Files:
23 added
1 deleted
22 edited

Legend:

Unmodified
Added
Removed
  • box/invisnet/vs2010/0.11/bin/bbackupd/BackupClientDirectoryRecord.cpp

    r2714 r3055  
    291291                                // DT_DIR, etc, but we only use it here and  
    292292                                // prefer S_IFREG, S_IFDIR... 
    293                                 int type = en->d_type; 
     293                                int type = 0; 
     294                                type = (DT_DIR == en->d_type) ? S_IFDIR : type; 
     295                                type = (DT_REG == en->d_type) ? S_IFREG : type; 
    294296                                #else 
    295297                                if(EMU_LSTAT(filename.c_str(), &file_st) != 0) 
  • box/invisnet/vs2010/0.11/bin/bbackupd/Win32ServiceFunctions.cpp

    r2771 r3055  
    2222#endif 
    2323 
     24using namespace Win32; 
     25 
    2426extern void TerminateService(void); 
    2527extern unsigned int WINAPI RunService(LPVOID lpParameter); 
     
    101103{ 
    102104        // initialise service status 
    103         gServiceStatus.dwServiceType = SERVICE_WIN32; 
     105        gServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 
    104106        gServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    105107        gServiceStatus.dwControlsAccepted = 0; 
     
    191193        if (!success) 
    192194        { 
    193                 ErrorHandler("Failed to start service. Did you start " 
    194                         "Box Backup from the Service Control Manager? " 
    195                         "(StartServiceCtrlDispatcher)", GetLastError()); 
     195//              ErrorHandler("Failed to start service. Did you start " 
     196//                      "Box Backup from the Service Control Manager? " 
     197//                      "(StartServiceCtrlDispatcher)", GetLastError()); 
    196198                return 1; 
    197199        } 
  • box/invisnet/vs2010/0.11/bin/bbackupd/bbackupd.cpp

    r2180 r3055  
    3636#ifdef WIN32 
    3737 
    38         EnableBackupRights(); 
     38        Win32::EnableBackupRights(); 
    3939 
    4040        gpDaemonService = new Win32BackupService(); 
  • box/invisnet/vs2010/0.11/bin/bbackupquery/bbackupquery.cpp

    r2663 r3055  
    5959#include "MemLeakFindOn.h" 
    6060 
     61#ifdef WIN32 
     62using namespace Win32; 
     63#endif 
     64 
    6165void PrintUsageAndExit() 
    6266{ 
     
    293297                return 1; 
    294298        } 
     299#ifdef WIN32 
     300        char path[MAX_PATH]; 
     301 
     302        if(FAILED(SHGetFolderPath(NULL,CSIDL_COMMON_APPDATA,NULL,0,path)) || !PathAppend(path,"Box Backup")) 
     303        { 
     304                BOX_FATAL("Can't build DataDirectory"); 
     305                return 1; 
     306        } 
     307 
     308        config->AddKeyValue("DataDirectory",path); 
     309#endif 
    295310        // Easier coding 
    296311        const Configuration &conf(*config); 
     
    301316        // Read in the certificates creating a TLS context 
    302317        TLSContext tlsContext; 
     318#ifdef WIN32 
     319        std::string certFile(conf.GetKeyValue("AccountNumber")); 
     320        std::string keyFile; 
     321        std::string caFile; 
     322        std::string keysFile; 
     323#else 
    303324        std::string certFile(conf.GetKeyValue("CertificateFile")); 
    304325        std::string keyFile(conf.GetKeyValue("PrivateKeyFile")); 
    305326        std::string caFile(conf.GetKeyValue("TrustedCAsFile")); 
     327        std::string keysFile(conf.GetKeyValue("KeysFile")); 
     328#endif 
    306329        tlsContext.Initialise(false /* as client */, certFile.c_str(), keyFile.c_str(), caFile.c_str()); 
    307330         
    308331        // Initialise keys 
    309         BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile").c_str()); 
     332        BackupClientCryptoKeys_Setup(keysFile.c_str()); 
    310333 
    311334        // 2. Connect to server 
  • box/invisnet/vs2010/0.11/lib/backupclient/BackupClientFileAttributes.cpp

    r2811 r3055  
    844844 
    845845                // Try to apply 
    846                 if(::utimes(Filename, times) != 0) 
     846                if(EMU_UTIMES(Filename, times) != 0) 
    847847                { 
    848848                        BOX_LOG_SYS_ERROR("Failed to change times of " 
  • box/invisnet/vs2010/0.11/lib/backupclient/BackupClientRestore.cpp

    r2813 r3055  
    386386        if((exists == ObjectExists_NoObject || 
    387387                exists == ObjectExists_File) &&  
    388                 ::mkdir(rLocalDirectoryName.c_str(), S_IRWXU) != 0) 
     388                EMU_MKDIR(rLocalDirectoryName.c_str(), S_IRWXU) != 0) 
    389389        { 
    390390                BOX_LOG_SYS_ERROR("Failed to create directory '" << 
  • box/invisnet/vs2010/0.11/lib/common/Box.h

    r2663 r3055  
    182182inline int8_t   ntoh(int8_t in)   { return in; } 
    183183 
     184using namespace BoxBackup; 
     185 
    184186#endif // BOX__H 
    185187 
  • box/invisnet/vs2010/0.11/lib/common/BoxConfig-MSVC.h

    r2067 r3055  
    204204 
    205205/* Define to 1 if you have the <stdint.h> header file. */ 
    206 // #define HAVE_STDINT_H 1 
     206#define HAVE_STDINT_H 1 
    207207 
    208208/* Define to 1 if you have the <stdlib.h> header file. */ 
  • box/invisnet/vs2010/0.11/lib/common/BoxPlatform.h

    r2801 r3055  
    121121#endif 
    122122 
    123 #if defined WIN32 && !defined __MINGW32__ 
    124         typedef __int8  int8_t; 
    125         typedef __int16 int16_t; 
    126         typedef __int32 int32_t; 
    127         typedef __int64 int64_t; 
    128  
    129         typedef unsigned __int8  u_int8_t; 
    130         typedef unsigned __int16 u_int16_t; 
    131         typedef unsigned __int32 u_int32_t; 
    132         typedef unsigned __int64 u_int64_t; 
    133  
    134         #define HAVE_U_INT8_T 
    135         #define HAVE_U_INT16_T 
    136         #define HAVE_U_INT32_T 
    137         #define HAVE_U_INT64_T 
    138 #endif // WIN32 && !__MINGW32__ 
    139  
    140123// Define missing types 
    141124#ifndef HAVE_UINT8_T 
     
    181164#endif 
    182165 
    183 #ifdef WIN32 
    184         #define WIN32_LEAN_AND_MEAN 
    185 #endif 
    186  
    187166#include "emu.h" 
    188167 
  • box/invisnet/vs2010/0.11/lib/common/FileStream.cpp

    r2792 r3055  
    6868                MEMLEAKFINDER_NOT_A_LEAK(this); 
    6969 
    70                 #ifdef WIN32 
    71                 BOX_LOG_WIN_WARNING_NUMBER("Failed to open file: " << 
    72                         mFileName, winerrno); 
    73                 #else 
     70                #ifndef WIN32 
    7471                BOX_LOG_SYS_WARNING("Failed to open file: " << 
    7572                        mFileName); 
  • box/invisnet/vs2010/0.11/lib/common/Logging.cpp

    r2663 r3055  
    1717#include <cstdio> 
    1818 
     19#ifdef HAVE_PROCESS_H 
     20        #include <process.h> 
     21#endif 
    1922#ifdef HAVE_SYSLOG_H 
    2023        #include <syslog.h> 
  • box/invisnet/vs2010/0.11/lib/common/Logging.h

    r2663 r3055  
    6060{ 
    6161#ifdef WIN32 
    62         return GetErrorMessage(GetLastError()); 
     62        return BoxBackup::Win32::GetErrorMessage(GetLastError()); 
    6363#else 
    6464        std::ostringstream _box_log_line; 
     
    7070#ifdef WIN32 
    7171        #define BOX_LOG_WIN_ERROR(stuff) \ 
    72                 BOX_ERROR(stuff << ": " << GetErrorMessage(GetLastError())) 
     72                BOX_ERROR(stuff << ": " << Win32::GetErrorMessage(GetLastError())) 
    7373        #define BOX_LOG_WIN_WARNING(stuff) \ 
    74                 BOX_WARNING(stuff << ": " << GetErrorMessage(GetLastError())) 
     74                BOX_WARNING(stuff << ": " << Win32::GetErrorMessage(GetLastError())) 
    7575        #define BOX_LOG_WIN_ERROR_NUMBER(stuff, number) \ 
    76                 BOX_ERROR(stuff << ": " << GetErrorMessage(number)) 
     76                BOX_ERROR(stuff << ": " << Win32::GetErrorMessage(number)) 
    7777        #define BOX_LOG_WIN_WARNING_NUMBER(stuff, number) \ 
    78                 BOX_WARNING(stuff << ": " << GetErrorMessage(number)) 
     78                BOX_WARNING(stuff << ": " << Win32::GetErrorMessage(number)) 
    7979        #define BOX_LOG_NATIVE_ERROR(stuff)   BOX_LOG_WIN_ERROR(stuff) 
    8080        #define BOX_LOG_NATIVE_WARNING(stuff) BOX_LOG_WIN_WARNING(stuff) 
  • box/invisnet/vs2010/0.11/lib/common/Timer.cpp

    r2767 r3055  
    429429                == FALSE) 
    430430        { 
    431                 BOX_ERROR(TIMER_ID "failed to create timer: " << 
    432                         GetErrorMessage(GetLastError())); 
     431                BOX_LOG_WIN_ERROR(TIMER_ID "failed to create timer"); 
    433432                mTimerHandle = INVALID_HANDLE_VALUE; 
    434433        } 
     
    455454                        INVALID_HANDLE_VALUE) == FALSE) 
    456455                { 
    457                         BOX_ERROR(TIMER_ID "failed to delete timer: " << 
    458                                 GetErrorMessage(GetLastError())); 
     456                        BOX_LOG_WIN_ERROR(TIMER_ID "failed to delete timer"); 
    459457                } 
    460458                mTimerHandle = INVALID_HANDLE_VALUE; 
  • box/invisnet/vs2010/0.11/lib/common/WaitForEvent.cpp

    r456 r3055  
    164164         
    165165        // Poll! 
    166         switch(::poll(mpPollInfo, mItems.size(), mTimeout)) 
     166        switch(EMU_POLL(mpPollInfo, mItems.size(), mTimeout)) 
    167167        { 
    168168        case -1: 
  • box/invisnet/vs2010/0.11/lib/server/Daemon.cpp

    r2500 r3055  
    1010#include "Box.h" 
    1111 
     12#ifdef HAVE_PROCESS_H 
     13        #include <process.h> 
     14#endif 
    1215#ifdef HAVE_UNISTD_H 
    1316        #include <unistd.h> 
  • box/invisnet/vs2010/0.11/lib/server/LocalProcessStream.cpp

    r2659 r3055  
    122122        if(!CreatePipe(&readFromChild, &writeInChild, &secAttr, 0)) 
    123123        { 
    124                 BOX_ERROR("Failed to CreatePipe for child process: " << 
    125                         GetErrorMessage(GetLastError())); 
     124                BOX_LOG_WIN_ERROR("Failed to CreatePipe for child process"); 
    126125                THROW_EXCEPTION(ServerException, SocketPairFailed) 
    127126        } 
     
    157156        if(!result) 
    158157        { 
    159                 BOX_ERROR("Failed to CreateProcess: '" << rCommandLine << 
    160                         "': " << GetErrorMessage(GetLastError())); 
     158                BOX_LOG_WIN_ERROR("Failed to CreateProcess: '" << rCommandLine); 
    161159                CloseHandle(writeInChild); 
    162160                CloseHandle(readFromChild); 
  • box/invisnet/vs2010/0.11/lib/server/SocketStream.cpp

    r2451 r3055  
    214214                p.events = POLLIN; 
    215215                p.revents = 0; 
    216                 switch(::poll(&p, 1, (Timeout == IOStream::TimeOutInfinite)?INFTIM:Timeout)) 
     216                switch(EMU_POLL(&p, 1, (Timeout == IOStream::TimeOutInfinite)?INFTIM:Timeout)) 
    217217                { 
    218218                case -1: 
     
    333333                        p.revents = 0; 
    334334                         
    335                         if(::poll(&p, 1, 16000 /* 16 seconds */) == -1) 
     335                        if(EMU_POLL(&p, 1, 16000 /* 16 seconds */) == -1) 
    336336                        { 
    337337                                // Don't exception if it's just a signal 
  • box/invisnet/vs2010/0.11/lib/server/SocketStreamTLS.cpp

    r2792 r3055  
    262262                        poll_timeout = INFTIM; 
    263263                } 
    264                 result = ::poll(&p, 1, poll_timeout); 
     264                result = EMU_POLL(&p, 1, poll_timeout); 
    265265        } 
    266266        while(result == -1 && errno == EINTR); 
  • box/invisnet/vs2010/0.11/lib/server/WinNamedPipeStream.cpp

    r2792 r3055  
    2626 
    2727#include "MemLeakFindOn.h" 
     28 
     29using namespace Win32; 
    2830 
    2931std::string WinNamedPipeStream::sPipeNamePrefix = "\\\\.\\pipe\\"; 
  • box/invisnet/vs2010/0.11/lib/win32/emu.cpp

    r2790 r3055  
    1 // Box Backup Win32 native port by Nick Knight 
     1#include "Box.h" 
    22 
    3 // Need at least 0x0500 to use GetFileSizeEx on Cygwin/MinGW 
    4 #define WINVER 0x0500 
     3#include <cstdio> 
    54 
    6 #include "emu.h" 
    75 
    8 #ifdef WIN32 
     6using namespace Win32; 
    97 
    10 #include <assert.h> 
    11 #include <fcntl.h> 
    12 #include <process.h> 
    13 #include <windows.h> 
    14 #include "Shlobj.h" 
    15 #include "Shlwapi.h" 
    168 
    17 #ifdef HAVE_UNISTD_H 
    18         #include <unistd.h> 
    19 #endif 
    20  
    21 #include <string> 
    22 #include <list> 
    23 #include <sstream> 
    24  
    25 // message resource definitions for syslog() 
    26 #include "messages.h" 
    27  
    28 DWORD winerrno; 
    299struct passwd gTempPasswd; 
    3010 
    31 bool EnableBackupRights() 
    32 { 
    33         HANDLE hToken; 
    34         TOKEN_PRIVILEGES token_priv; 
    35  
    36         //open current process to adjust privileges 
    37         if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, 
    38                 &hToken)) 
    39         { 
    40                 ::syslog(LOG_ERR, "Failed to open process token: %s", 
    41                         GetErrorMessage(GetLastError()).c_str()); 
    42                 return false; 
    43         } 
    44  
    45         //let's build the token privilege struct - 
    46         //first, look up the LUID for the backup privilege 
    47  
    48         if (!LookupPrivilegeValue( 
    49                 NULL, //this system 
    50                 SE_BACKUP_NAME, //the name of the privilege 
    51                 &( token_priv.Privileges[0].Luid ))) //result 
    52         { 
    53                 ::syslog(LOG_ERR, "Failed to lookup backup privilege: %s", 
    54                         GetErrorMessage(GetLastError()).c_str()); 
    55                 CloseHandle(hToken); 
    56                 return false; 
    57         } 
    58  
    59         token_priv.PrivilegeCount = 1; 
    60         token_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    61  
    62         // now set the privilege 
    63         // because we're going exit right after dumping the streams, there isn't 
    64         // any need to save current state 
    65  
    66         if (!AdjustTokenPrivileges( 
    67                 hToken, //our process token 
    68                 false,  //we're not disabling everything 
    69                 &token_priv, //address of structure 
    70                 sizeof(token_priv), //size of structure 
    71                 NULL, NULL)) //don't save current state 
    72         { 
    73                 //this function is a little tricky - if we were adjusting 
    74                 //more than one privilege, it could return success but not 
    75                 //adjust them all - in the general case, you need to trap this 
    76                 ::syslog(LOG_ERR, "Failed to enable backup privilege: %s", 
    77                         GetErrorMessage(GetLastError()).c_str()); 
    78                 CloseHandle(hToken); 
    79                 return false; 
    80  
    81         } 
    82  
    83         CloseHandle(hToken); 
    84         return true; 
    85 } 
    86  
    87 // forward declaration 
    88 char* ConvertFromWideString(const WCHAR* pString, unsigned int codepage); 
    8911 
    9012// -------------------------------------------------------------------------- 
     
    9921// 
    10022// -------------------------------------------------------------------------- 
    101 std::string GetDefaultConfigFilePath(const std::string& rName) 
     23std::string GetDefaultConfigFilePath(const std::string& rName) throw() 
    10224{ 
    10325        // we just ask the system where to get the file... 
    104         char path[MAX_PATH]; 
     26        wchar_t path[MAX_PATH]; 
    10527 
    106         if(FAILED(SHGetFolderPath(NULL,CSIDL_COMMON_APPDATA,NULL,0,path)) 
    107                 || FALSE == PathAppend(path,"Box Backup") 
    108                 || FALSE == PathAppend(path,rName.c_str())) 
     28        try 
    10929        { 
    110                 return ""; 
    111         } 
    112  
    113         return std::string(path); 
    114 } 
    115  
    116 // -------------------------------------------------------------------------- 
    117 // 
    118 // Function 
    119 //              Name:    ConvertToWideString 
    120 //              Purpose: Converts a string from specified codepage to 
    121 //                       a wide string (WCHAR*). Returns a buffer which 
    122 //                       MUST be freed by the caller with delete[]. 
    123 //                       In case of fire, logs the error and returns NULL. 
    124 //              Created: 4th February 2006 
    125 // 
    126 // -------------------------------------------------------------------------- 
    127 WCHAR* ConvertToWideString(const char* pString, unsigned int codepage, 
    128         bool logErrors) 
    129 { 
    130         int len = MultiByteToWideChar 
    131         ( 
    132                 codepage, // source code page 
    133                 0,        // character-type options 
    134                 pString,  // string to map 
    135                 -1,       // number of bytes in string - auto detect 
    136                 NULL,     // wide-character buffer 
    137                 0         // size of buffer - work out 
    138                           //   how much space we need 
    139         ); 
    140  
    141         if (len == 0) 
    142         { 
    143                 winerrno = GetLastError(); 
    144                 if (logErrors) 
     30                if(SUCCEEDED(SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,path)) 
     31                        && PathAppendW(path,L"Box Backup") 
     32                        && PathAppendW(path,multi2wide(rName.c_str()).c_str())) 
    14533                { 
    146                         ::syslog(LOG_WARNING, 
    147                                 "Failed to convert string to wide string: " 
    148                                 "%s", GetErrorMessage(winerrno).c_str()); 
    149                 } 
    150                 errno = EINVAL; 
    151                 return NULL; 
    152         } 
    153  
    154         WCHAR* buffer = new WCHAR[len]; 
    155  
    156         if (buffer == NULL) 
    157         { 
    158                 if (logErrors) 
    159                 { 
    160                         ::syslog(LOG_WARNING, 
    161                                 "Failed to convert string to wide string: " 
    162                                 "out of memory"); 
    163                 } 
    164                 winerrno = ERROR_OUTOFMEMORY; 
    165                 errno = ENOMEM; 
    166                 return NULL; 
    167         } 
    168  
    169         len = MultiByteToWideChar 
    170         ( 
    171                 codepage, // source code page 
    172                 0,        // character-type options 
    173                 pString,  // string to map 
    174                 -1,       // number of bytes in string - auto detect 
    175                 buffer,   // wide-character buffer 
    176                 len       // size of buffer 
    177         ); 
    178  
    179         if (len == 0) 
    180         { 
    181                 winerrno = GetLastError(); 
    182                 if (logErrors) 
    183                 { 
    184                         ::syslog(LOG_WARNING, 
    185                                 "Failed to convert string to wide string: " 
    186                                 "%s", GetErrorMessage(winerrno).c_str()); 
    187                 } 
    188                 errno = EACCES; 
    189                 delete [] buffer; 
    190                 return NULL; 
    191         } 
    192  
    193         return buffer; 
    194 } 
    195  
    196 // -------------------------------------------------------------------------- 
    197 // 
    198 // Function 
    199 //              Name:    ConvertUtf8ToWideString 
    200 //              Purpose: Converts a string from UTF-8 to a wide string. 
    201 //                       Returns a buffer which MUST be freed by the caller 
    202 //                       with delete[]. 
    203 //                       In case of fire, logs the error and returns NULL. 
    204 //              Created: 4th February 2006 
    205 // 
    206 // -------------------------------------------------------------------------- 
    207 WCHAR* ConvertUtf8ToWideString(const char* pString) 
    208 { 
    209         return ConvertToWideString(pString, CP_UTF8, true); 
    210 } 
    211  
    212 // -------------------------------------------------------------------------- 
    213 // 
    214 // Function 
    215 //              Name:    ConvertFromWideString 
    216 //              Purpose: Converts a wide string to a narrow string in the 
    217 //                       specified code page. Returns a buffer which MUST 
    218 //                       be freed by the caller with delete[]. 
    219 //                       In case of fire, logs the error and returns NULL. 
    220 //              Created: 4th February 2006 
    221 // 
    222 // -------------------------------------------------------------------------- 
    223 char* ConvertFromWideString(const WCHAR* pString, unsigned int codepage) 
    224 { 
    225         int len = WideCharToMultiByte 
    226         ( 
    227                 codepage, // destination code page 
    228                 0,        // character-type options 
    229                 pString,  // string to map 
    230                 -1,       // number of bytes in string - auto detect 
    231                 NULL,     // output buffer 
    232                 0,        // size of buffer - work out 
    233                           //   how much space we need 
    234                 NULL,     // replace unknown chars with system default 
    235                 NULL      // don't tell us when that happened 
    236         ); 
    237  
    238         if (len == 0) 
    239         { 
    240                 ::syslog(LOG_WARNING, 
    241                         "Failed to convert wide string to narrow: " 
    242                         "error %d", GetLastError()); 
    243                 errno = EINVAL; 
    244                 return NULL; 
    245         } 
    246  
    247         char* buffer = new char[len]; 
    248  
    249         if (buffer == NULL) 
    250         { 
    251                 ::syslog(LOG_WARNING, 
    252                         "Failed to convert wide string to narrow: " 
    253                         "out of memory"); 
    254                 errno = ENOMEM; 
    255                 return NULL; 
    256         } 
    257  
    258         len = WideCharToMultiByte 
    259         ( 
    260                 codepage, // source code page 
    261                 0,        // character-type options 
    262                 pString,  // string to map 
    263                 -1,       // number of bytes in string - auto detect 
    264                 buffer,   // output buffer 
    265                 len,      // size of buffer 
    266                 NULL,     // replace unknown chars with system default 
    267                 NULL      // don't tell us when that happened 
    268         ); 
    269  
    270         if (len == 0) 
    271         { 
    272                 ::syslog(LOG_WARNING, 
    273                         "Failed to convert wide string to narrow: " 
    274                         "error %i", GetLastError()); 
    275                 errno = EACCES; 
    276                 delete [] buffer; 
    277                 return NULL; 
    278         } 
    279  
    280         return buffer; 
    281 } 
    282  
    283 // -------------------------------------------------------------------------- 
    284 // 
    285 // Function 
    286 //              Name:    ConvertEncoding(const std::string&, int, 
    287 //                       std::string&, int) 
    288 //              Purpose: Converts a string from one code page to another. 
    289 //                       On success, replaces contents of rDest and returns 
    290 //                       true. In case of fire, logs the error and returns 
    291 //                       false. 
    292 //              Created: 15th October 2006 
    293 // 
    294 // -------------------------------------------------------------------------- 
    295 bool ConvertEncoding(const std::string& rSource, int sourceCodePage, 
    296         std::string& rDest, int destCodePage) 
    297 { 
    298         WCHAR* pWide = ConvertToWideString(rSource.c_str(), sourceCodePage, 
    299                 true); 
    300         if (pWide == NULL) 
    301         { 
    302                 ::syslog(LOG_ERR, "Failed to convert string '%s' from " 
    303                         "current code page %d to wide string: %s", 
    304                         rSource.c_str(), sourceCodePage, 
    305                         GetErrorMessage(GetLastError()).c_str()); 
    306                 return false; 
    307         } 
    308  
    309         char* pConsole = ConvertFromWideString(pWide, destCodePage); 
    310         delete [] pWide; 
    311  
    312         if (!pConsole) 
    313         { 
    314                 // Error should have been logged by ConvertFromWideString 
    315                 return false; 
    316         } 
    317  
    318         rDest = pConsole; 
    319         delete [] pConsole; 
    320  
    321         return true; 
    322 } 
    323  
    324 bool ConvertToUtf8(const std::string& rSource, std::string& rDest, 
    325         int sourceCodePage) 
    326 { 
    327         return ConvertEncoding(rSource, sourceCodePage, rDest, CP_UTF8); 
    328 } 
    329  
    330 bool ConvertFromUtf8(const std::string& rSource, std::string& rDest, 
    331         int destCodePage) 
    332 { 
    333         return ConvertEncoding(rSource, CP_UTF8, rDest, destCodePage); 
    334 } 
    335  
    336 bool ConvertConsoleToUtf8(const std::string& rSource, std::string& rDest) 
    337 { 
    338         return ConvertToUtf8(rSource, rDest, GetConsoleCP()); 
    339 } 
    340  
    341 bool ConvertUtf8ToConsole(const std::string& rSource, std::string& rDest) 
    342 { 
    343         return ConvertFromUtf8(rSource, rDest, GetConsoleOutputCP()); 
    344 } 
    345  
    346 // -------------------------------------------------------------------------- 
    347 // 
    348 // Function 
    349 //              Name:    ConvertPathToAbsoluteUnicode 
    350 //              Purpose: Converts relative paths to absolute (with unicode marker) 
    351 //              Created: 4th February 2006 
    352 // 
    353 // -------------------------------------------------------------------------- 
    354 std::string ConvertPathToAbsoluteUnicode(const char *pFileName) 
    355 { 
    356         std::string filename; 
    357         for (int i = 0; pFileName[i] != 0; i++) 
    358         { 
    359                 if (pFileName[i] == '/') 
    360                 { 
    361                         filename += '\\'; 
    362                 } 
    363                 else 
    364                 { 
    365                         filename += pFileName[i]; 
     34                        return wide2multi(path); 
    36635                } 
    36736        } 
    368  
    369         std::string tmpStr("\\\\?\\"); 
    370  
    371         // Is the path relative or absolute? 
    372         // Absolute paths on Windows are always a drive letter 
    373         // followed by ':' 
    374  
    375         char wd[PATH_MAX]; 
    376         if (::getcwd(wd, PATH_MAX) == 0) 
    377         { 
    378                 ::syslog(LOG_WARNING, 
    379                         "Failed to open '%s': path too long", 
    380                         pFileName); 
    381                 errno = ENAMETOOLONG; 
    382                 winerrno = ERROR_INVALID_NAME; 
    383                 tmpStr = ""; 
    384                 return tmpStr; 
    385         } 
    386  
    387         if (filename.length() > 2 && filename[0] == '\\' && 
    388                 filename[1] == '\\') 
    389         { 
    390                 tmpStr += "UNC\\"; 
    391                 filename.replace(0, 2, ""); 
    392                 // \\?\UNC\<server>\<share> 
    393                 // see http://msdn2.microsoft.com/en-us/library/aa365247.aspx 
    394         } 
    395         else if (filename.length() >= 1 && filename[0] == '\\') 
    396         { 
    397                 // root directory of current drive. 
    398                 tmpStr = wd; 
    399                 tmpStr.resize(2); // drive letter and colon 
    400         } 
    401         else if (filename.length() >= 2 && filename[1] != ':') 
    402         { 
    403                 // Must be relative. We need to get the 
    404                 // current directory to make it absolute. 
    405                 tmpStr += wd; 
    406                 if (tmpStr[tmpStr.length()] != '\\') 
    407                 { 
    408                         tmpStr += '\\'; 
    409                 } 
    410         } 
    411  
    412         tmpStr += filename; 
    413  
    414         // We are using direct filename access, which does not support .., 
    415         // so we need to implement it ourselves. 
    416  
    417         for (std::string::size_type i = 1; i < tmpStr.size() - 3; i++) 
    418         { 
    419                 if (tmpStr.substr(i, 3) == "\\..") 
    420                 { 
    421                         std::string::size_type lastSlash = 
    422                                 tmpStr.rfind('\\', i - 1); 
    423  
    424                         if (lastSlash == std::string::npos) 
    425                         { 
    426                                 // no previous directory, ignore it, 
    427                                 // CreateFile will fail with error 123 
    428                         } 
    429                         else 
    430                         { 
    431                                 tmpStr.replace(lastSlash, i + 3 - lastSlash, 
    432                                         ""); 
    433                         } 
    434  
    435                         i = lastSlash; 
    436                 } 
    437         } 
    438  
    439         return tmpStr; 
    440 } 
    441  
    442 std::string GetErrorMessage(DWORD errorCode) 
    443 { 
    444         char* pMsgBuf = NULL; 
    445  
    446         DWORD chars = FormatMessage 
    447         ( 
    448                 FORMAT_MESSAGE_ALLOCATE_BUFFER | 
    449                 FORMAT_MESSAGE_FROM_SYSTEM, 
    450                 NULL, 
    451                 errorCode, 
    452                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
    453                 (char *)(&pMsgBuf), 
    454                 0, NULL 
    455         ); 
    456  
    457         if (chars == 0 || pMsgBuf == NULL) 
    458         { 
    459                 return std::string("failed to get error message"); 
    460         } 
    461  
    462         // remove embedded newline 
    463         pMsgBuf[chars - 1] = 0; 
    464         pMsgBuf[chars - 2] = 0; 
    465  
    466         std::ostringstream line; 
    467         line << pMsgBuf << " (" << errorCode << ")"; 
    468         LocalFree(pMsgBuf); 
    469  
    470         return line.str(); 
    471 } 
    472  
    473 // -------------------------------------------------------------------------- 
    474 // 
    475 // Function 
    476 //              Name:    openfile 
    477 //              Purpose: replacement for any open calls - handles unicode 
    478 //                      filenames - supplied in utf8 
    479 //              Created: 25th October 2004 
    480 // 
    481 // -------------------------------------------------------------------------- 
    482 HANDLE openfile(const char *pFileName, int flags, int mode) 
    483 { 
    484         winerrno = ERROR_INVALID_FUNCTION; 
    485  
    486         std::string AbsPathWithUnicode = 
    487                 ConvertPathToAbsoluteUnicode(pFileName); 
    488  
    489         if (AbsPathWithUnicode.size() == 0) 
    490         { 
    491                 // error already logged by ConvertPathToAbsoluteUnicode() 
    492                 return INVALID_HANDLE_VALUE; 
    493         } 
    494  
    495         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str()); 
    496         // We are responsible for freeing pBuffer 
    497  
    498         if (pBuffer == NULL) 
    499         { 
    500                 // error already logged by ConvertUtf8ToWideString() 
    501                 return INVALID_HANDLE_VALUE; 
    502         } 
    503  
    504         // flags could be O_WRONLY | O_CREAT | O_RDONLY 
    505         DWORD createDisposition = OPEN_EXISTING; 
    506         DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE 
    507                 | FILE_SHARE_DELETE; 
    508         DWORD accessRights = FILE_READ_ATTRIBUTES | FILE_LIST_DIRECTORY 
    509                 | FILE_READ_EA; 
    510  
    511         if (flags & O_WRONLY) 
    512         { 
    513                 accessRights = FILE_WRITE_DATA; 
    514         } 
    515         else if (flags & O_RDWR) 
    516         { 
    517                 accessRights |= FILE_WRITE_ATTRIBUTES 
    518                         | FILE_WRITE_DATA | FILE_WRITE_EA; 
    519         } 
    520  
    521         if (flags & O_CREAT) 
    522         { 
    523                 createDisposition = OPEN_ALWAYS; 
    524         } 
    525  
    526         if (flags & O_TRUNC) 
    527         { 
    528                 createDisposition = CREATE_ALWAYS; 
    529         } 
    530  
    531         if ((flags & O_CREAT) && (flags & O_EXCL)) 
    532         { 
    533                 createDisposition = CREATE_NEW; 
    534         } 
    535  
    536         if (flags & O_LOCK) 
    537         { 
    538                 shareMode = 0; 
    539         } 
    540  
    541         DWORD winFlags = FILE_FLAG_BACKUP_SEMANTICS; 
    542         if (flags & O_TEMPORARY) 
    543         { 
    544                 winFlags  |= FILE_FLAG_DELETE_ON_CLOSE; 
    545         } 
    546  
    547         HANDLE hdir = CreateFileW(pBuffer, 
    548                 accessRights, 
    549                 shareMode, 
    550                 NULL, 
    551                 createDisposition, 
    552                 winFlags, 
    553                 NULL); 
    554  
    555         delete [] pBuffer; 
    556  
    557         if (hdir == INVALID_HANDLE_VALUE) 
    558         { 
    559                 winerrno = GetLastError(); 
    560                 switch(winerrno) 
    561                 { 
    562                         case ERROR_SHARING_VIOLATION: 
    563                         errno = EBUSY; 
    564                         break; 
    565  
    566                         default: 
    567                         errno = EINVAL; 
    568                 } 
    569  
    570                 ::syslog(LOG_WARNING, "Failed to open file '%s': " 
    571                         "%s", pFileName, 
    572                         GetErrorMessage(GetLastError()).c_str()); 
    573  
    574                 return INVALID_HANDLE_VALUE; 
    575         } 
    576  
    577         if (flags & O_APPEND) 
    578         { 
    579                 if (SetFilePointer(hdir, 0, NULL, FILE_END) == 
    580                         INVALID_SET_FILE_POINTER) 
    581                 { 
    582                         winerrno = GetLastError(); 
    583                         errno = EINVAL; 
    584                         CloseHandle(hdir); 
    585                         return INVALID_HANDLE_VALUE; 
    586                 } 
    587         } 
    588  
    589         winerrno = NO_ERROR; 
    590         return hdir; 
    591 } 
    592  
    593 // -------------------------------------------------------------------------- 
    594 // 
    595 // Function 
    596 //              Name:    emu_fstat 
    597 //              Purpose: replacement for fstat. Supply a windows handle. 
    598 //                       Returns a struct emu_stat to have room for 64-bit 
    599 //                       file identifier in st_ino (mingw allows only 16!) 
    600 //              Created: 25th October 2004 
    601 // 
    602 // -------------------------------------------------------------------------- 
    603 int emu_fstat(HANDLE hdir, struct emu_stat * st) 
    604 { 
    605         if (hdir == INVALID_HANDLE_VALUE) 
    606         { 
    607                 ::syslog(LOG_ERR, "Error: invalid file handle in emu_fstat()"); 
    608                 errno = EBADF; 
    609                 return -1; 
    610         } 
    611  
    612         BY_HANDLE_FILE_INFORMATION fi; 
    613         if (!GetFileInformationByHandle(hdir, &fi)) 
    614         { 
    615                 ::syslog(LOG_WARNING, "Failed to read file information: " 
    616                         "%s", GetErrorMessage(GetLastError()).c_str()); 
    617                 errno = EACCES; 
    618                 return -1; 
    619         } 
    620  
    621         if (INVALID_FILE_ATTRIBUTES == fi.dwFileAttributes) 
    622         { 
    623                 ::syslog(LOG_WARNING, "Failed to get file attributes: " 
    624                         "%s", GetErrorMessage(GetLastError()).c_str()); 
    625                 errno = EACCES; 
    626                 return -1; 
    627         } 
    628  
    629         memset(st, 0, sizeof(*st)); 
    630  
    631         // This is how we get our INODE (equivalent) information 
    632         ULARGE_INTEGER conv; 
    633         conv.HighPart = fi.nFileIndexHigh; 
    634         conv.LowPart  = fi.nFileIndexLow; 
    635         st->st_ino = conv.QuadPart; 
    636  
    637         // get the time information 
    638         st->st_ctime = ConvertFileTimeToTime_t(&fi.ftCreationTime); 
    639         st->st_atime = ConvertFileTimeToTime_t(&fi.ftLastAccessTime); 
    640         st->st_mtime = ConvertFileTimeToTime_t(&fi.ftLastWriteTime); 
    641  
    642         if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
    643         { 
    644                 st->st_size = 0; 
    645         } 
    646         else 
    647         { 
    648                 conv.HighPart = fi.nFileSizeHigh; 
    649                 conv.LowPart  = fi.nFileSizeLow; 
    650                 st->st_size = (_off_t)conv.QuadPart; 
    651         } 
    652  
    653         // at the mo 
    654         st->st_uid = 0; 
    655         st->st_gid = 0; 
    656         st->st_nlink = 1; 
    657  
    658         // the mode of the file 
    659         // mode zero will make it impossible to restore on Unix 
    660         // (no access to anybody, including the owner). 
    661         // we'll fake a sensible mode: 
    662         // all objects get user read (0400) 
    663         // if it's a directory it gets user execute (0100) 
    664         // if it's not read-only it gets user write (0200) 
    665         st->st_mode = S_IREAD; 
    666  
    667         if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
    668         { 
    669                 st->st_mode |= S_IFDIR | S_IEXEC; 
    670         } 
    671         else 
    672         { 
    673                 st->st_mode |= S_IFREG; 
    674         } 
    675  
    676         if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) 
    677         { 
    678                 st->st_mode |= S_IWRITE; 
    679         } 
    680  
    681         // st_dev is normally zero, regardless of the drive letter, 
    682         // since backup locations can't normally span drives. However, 
    683         // a reparse point does allow all kinds of weird stuff to happen. 
    684         // We set st_dev to 1 for a reparse point, so that Box will detect 
    685         // a change of device number (from 0) and refuse to recurse down 
    686         // the reparse point (which could lead to havoc). 
    687  
    688         if (fi.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) 
    689         { 
    690                 st->st_dev = 1; 
    691         } 
    692         else 
    693         { 
    694                 st->st_dev = 0; 
    695         } 
    696  
    697         return 0; 
    698 } 
    699  
    700 // -------------------------------------------------------------------------- 
    701 // 
    702 // Function 
    703 //              Name:    OpenFileByNameUtf8 
    704 //              Purpose: Converts filename to Unicode and returns 
    705 //                      a handle to it. In case of error, sets errno, 
    706 //                      logs the error and returns NULL. 
    707 //              Created: 10th December 2004 
    708 // 
    709 // -------------------------------------------------------------------------- 
    710 HANDLE OpenFileByNameUtf8(const char* pFileName, DWORD flags) 
    711 { 
    712         std::string AbsPathWithUnicode = 
    713                 ConvertPathToAbsoluteUnicode(pFileName); 
    714  
    715         if (AbsPathWithUnicode.size() == 0) 
    716         { 
    717                 // error already logged by ConvertPathToAbsoluteUnicode() 
    718                 return NULL; 
    719         } 
    720  
    721         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str()); 
    722         // We are responsible for freeing pBuffer 
    723  
    724         if (pBuffer == NULL) 
    725         { 
    726                 // error already logged by ConvertUtf8ToWideString() 
    727                 return NULL; 
    728         } 
    729  
    730         HANDLE handle = CreateFileW(pBuffer, 
    731                 flags, 
    732                 FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, 
    733                 NULL, 
    734                 OPEN_EXISTING, 
    735                 FILE_FLAG_BACKUP_SEMANTICS, 
    736                 NULL); 
    737  
    738         if (handle == INVALID_HANDLE_VALUE) 
    739         { 
    740                 // if our open fails we should always be able to 
    741                 // open in this mode - to get the inode information 
    742                 // at least one process must have the file open - 
    743                 // in this case someone else does. 
    744                 handle = CreateFileW(pBuffer, 
    745                         READ_CONTROL, 
    746                         FILE_SHARE_READ, 
    747                         NULL, 
    748                         OPEN_EXISTING, 
    749                         FILE_FLAG_BACKUP_SEMANTICS, 
    750                         NULL); 
    751         } 
    752  
    753         delete [] pBuffer; 
    754  
    755         if (handle == INVALID_HANDLE_VALUE) 
    756         { 
    757                 DWORD err = GetLastError(); 
    758  
    759                 if (err == ERROR_FILE_NOT_FOUND || 
    760                         err == ERROR_PATH_NOT_FOUND) 
    761                 { 
    762                         errno = ENOENT; 
    763                 } 
    764                 else 
    765                 { 
    766                         ::syslog(LOG_WARNING, "Failed to open '%s': " 
    767                                 "%s", pFileName, 
    768                                 GetErrorMessage(err).c_str()); 
    769                         errno = EACCES; 
    770                 } 
    771  
    772                 return NULL; 
    773         } 
    774  
    775         return handle; 
    776 } 
    777  
    778 // -------------------------------------------------------------------------- 
    779 // 
    780 // Function 
    781 //              Name:    emu_stat 
    782 //              Purpose: replacement for the lstat and stat functions. 
    783 //                       Works with unicode filenames supplied in utf8. 
    784 //                       Returns a struct emu_stat to have room for 64-bit 
    785 //                       file identifier in st_ino (mingw allows only 16!) 
    786 //              Created: 25th October 2004 
    787 // 
    788 // -------------------------------------------------------------------------- 
    789 int emu_stat(const char * pName, struct emu_stat * st) 
    790 { 
    791         HANDLE handle = OpenFileByNameUtf8(pName, 
    792                 FILE_READ_ATTRIBUTES | FILE_READ_EA); 
    793  
    794         if (handle == NULL) 
    795         { 
    796                 // errno already set and error logged by OpenFileByNameUtf8() 
    797                 return -1; 
    798         } 
    799  
    800         int retVal = emu_fstat(handle, st); 
    801         if (retVal != 0) 
    802         { 
    803                 // error logged, but without filename 
    804                 ::syslog(LOG_WARNING, "Failed to get file information " 
    805                         "for '%s'", pName); 
    806         } 
    807  
    808         // close the handle 
    809         CloseHandle(handle); 
    810  
    811         return retVal; 
    812 } 
    813  
    814 // -------------------------------------------------------------------------- 
    815 // 
    816 // Function 
    817 //              Name:    statfs 
    818 //              Purpose: returns the mount point of where a file is located - 
    819 //                      in this case the volume serial number 
    820 //              Created: 25th October 2004 
    821 // 
    822 // -------------------------------------------------------------------------- 
    823 int statfs(const char * pName, struct statfs * s) 
    824 { 
    825         HANDLE handle = OpenFileByNameUtf8(pName, 
    826                 FILE_READ_ATTRIBUTES | FILE_READ_EA); 
    827  
    828         if (handle == NULL) 
    829         { 
    830                 // errno already set and error logged by OpenFileByNameUtf8() 
    831                 return -1; 
    832         } 
    833  
    834         BY_HANDLE_FILE_INFORMATION fi; 
    835         if (!GetFileInformationByHandle(handle, &fi)) 
    836         { 
    837                 ::syslog(LOG_WARNING, "Failed to get file information " 
    838                         "for '%s': %s", pName, 
    839                         GetErrorMessage(GetLastError()).c_str()); 
    840                 CloseHandle(handle); 
    841                 errno = EACCES; 
    842                 return -1; 
    843         } 
    844  
    845         // convert volume serial number to a string 
    846         _ui64toa(fi.dwVolumeSerialNumber, s->f_mntonname + 1, 16); 
    847  
    848         // pseudo unix mount point 
    849         s->f_mntonname[0] = '\\'; 
    850  
    851         CloseHandle(handle);   // close the handle 
    852  
    853         return 0; 
    854 } 
    855  
    856 // -------------------------------------------------------------------------- 
    857 // 
    858 // Function 
    859 //              Name:    emu_utimes 
    860 //              Purpose: replacement for the POSIX utimes() function, 
    861 //                      works with unicode filenames supplied in utf8 format, 
    862 //                      sets creation time instead of last access time. 
    863 //              Created: 25th July 2006 
    864 // 
    865 // -------------------------------------------------------------------------- 
    866 int emu_utimes(const char * pName, const struct timeval times[]) 
    867 { 
    868         FILETIME creationTime; 
    869         if (!ConvertTime_tToFileTime(times[0].tv_sec, &creationTime)) 
    870         { 
    871                 errno = EINVAL; 
    872                 return -1; 
    873         } 
    874  
    875         FILETIME modificationTime; 
    876         if (!ConvertTime_tToFileTime(times[1].tv_sec, &modificationTime)) 
    877         { 
    878                 errno = EINVAL; 
    879                 return -1; 
    880         } 
    881  
    882         HANDLE handle = OpenFileByNameUtf8(pName, FILE_WRITE_ATTRIBUTES); 
    883  
    884         if (handle == NULL) 
    885         { 
    886                 // errno already set and error logged by OpenFileByNameUtf8() 
    887                 return -1; 
    888         } 
    889  
    890         if (!SetFileTime(handle, &creationTime, NULL, &modificationTime)) 
    891         { 
    892                 ::syslog(LOG_ERR, "Failed to set times on '%s': %s", pName, 
    893                         GetErrorMessage(GetLastError()).c_str()); 
    894                 CloseHandle(handle); 
    895                 return 1; 
    896         } 
    897  
    898         CloseHandle(handle); 
    899         return 0; 
    900 } 
    901  
    902 // -------------------------------------------------------------------------- 
    903 // 
    904 // Function 
    905 //              Name:    emu_chmod 
    906 //              Purpose: replacement for the POSIX chmod function, 
    907 //                      works with unicode filenames supplied in utf8 format 
    908 //              Created: 26th July 2006 
    909 // 
    910 // -------------------------------------------------------------------------- 
    911 int emu_chmod(const char * pName, mode_t mode) 
    912 { 
    913         std::string AbsPathWithUnicode = 
    914                 ConvertPathToAbsoluteUnicode(pName); 
    915  
    916         if (AbsPathWithUnicode.size() == 0) 
    917         { 
    918                 // error already logged by ConvertPathToAbsoluteUnicode() 
    919                 return -1; 
    920         } 
    921  
    922         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str()); 
    923         // We are responsible for freeing pBuffer 
    924  
    925         if (pBuffer == NULL) 
    926         { 
    927                 // error already logged by ConvertUtf8ToWideString() 
    928                 free(pBuffer); 
    929                 return -1; 
    930         } 
    931  
    932         DWORD attribs = GetFileAttributesW(pBuffer); 
    933         if (attribs == INVALID_FILE_ATTRIBUTES) 
    934         { 
    935                 ::syslog(LOG_ERR, "Failed to get file attributes of '%s': %s", 
    936                         pName, GetErrorMessage(GetLastError()).c_str()); 
    937                 errno = EACCES; 
    938                 free(pBuffer); 
    939                 return -1; 
    940         } 
    941  
    942         if (mode & S_IWRITE) 
    943         { 
    944                 attribs &= ~FILE_ATTRIBUTE_READONLY; 
    945         } 
    946         else 
    947         { 
    948                 attribs |= FILE_ATTRIBUTE_READONLY; 
    949         } 
    950  
    951         if (!SetFileAttributesW(pBuffer, attribs)) 
    952         { 
    953                 ::syslog(LOG_ERR, "Failed to set file attributes of '%s': %s", 
    954                         pName, GetErrorMessage(GetLastError()).c_str()); 
    955                 errno = EACCES; 
    956                 free(pBuffer); 
    957                 return -1; 
    958         } 
    959  
    960         delete [] pBuffer; 
    961         return 0; 
     37        EMU_EXCEPTION_HANDLING_RETURN("") 
    96238} 
    96339 
    96440 
    965 // -------------------------------------------------------------------------- 
    966 // 
    967 // Function 
    968 //              Name:    opendir 
    969 //              Purpose: replacement for unix function, uses win32 findfirst routines 
    970 //              Created: 25th October 2004 
    971 // 
    972 // -------------------------------------------------------------------------- 
    973 DIR *opendir(const char *name) 
     41int console_read(char* pBuffer, const size_t BufferSize) throw() 
    97442{ 
    975         if (!name || !name[0]) 
    976         { 
    977                 errno = EINVAL; 
    978                 return NULL; 
    979         } 
    980  
    981         std::string dirName(name); 
    982  
    983         //append a '\' win32 findfirst is sensitive to this 
    984         if ( dirName[dirName.size()-1] != '\\' || dirName[dirName.size()-1] != '/' ) 
    985         { 
    986                 dirName += '\\'; 
    987         } 
    988  
    989         // what is the search string? - everything 
    990         dirName += '*'; 
    991  
    992         DIR *pDir = new DIR; 
    993         if (pDir == NULL) 
    994         { 
    995                 errno = ENOMEM; 
    996                 return NULL; 
    997         } 
    998  
    999         pDir->name = ConvertUtf8ToWideString(dirName.c_str()); 
    1000         // We are responsible for freeing dir->name with delete[] 
    1001  
    1002         if (pDir->name == NULL) 
    1003         { 
    1004                 delete pDir; 
    1005                 return NULL; 
    1006         } 
    1007  
    1008         pDir->fd = _wfindfirst((const wchar_t*)pDir->name, &(pDir->info)); 
    1009  
    1010         if (pDir->fd == -1) 
    1011         { 
    1012                 delete [] pDir->name; 
    1013                 delete pDir; 
    1014                 return NULL; 
    1015         } 
    1016  
    1017         pDir->result.d_name = 0; 
    1018         return pDir; 
    1019 } 
    1020  
    1021 // this kinda makes it not thread friendly! 
    1022 // but I don't think it needs to be. 
    1023 char tempbuff[MAX_PATH]; 
    1024  
    1025 // -------------------------------------------------------------------------- 
    1026 // 
    1027 // Function 
    1028 //              Name:    readdir 
    1029 //              Purpose: as function above 
    1030 //              Created: 25th October 2004 
    1031 // 
    1032 // -------------------------------------------------------------------------- 
    1033 struct dirent *readdir(DIR *dp) 
    1034 { 
     43        HANDLE hConsole; 
     44         
    103545        try 
    103646        { 
    1037                 struct dirent *den = NULL; 
     47                if (INVALID_HANDLE_VALUE == (hConsole = GetStdHandle(STD_INPUT_HANDLE))) 
     48                        throw Win32Exception(Win32Exception::API_GetStdHandle); 
    103849 
    1039                 if (dp && dp->fd != -1) 
    1040                 { 
    1041                         if (!dp->result.d_name || 
    1042                                 _wfindnext(dp->fd, &dp->info) != -1) 
    1043                         { 
    1044                                 den = &dp->result; 
    1045                                 std::wstring input(dp->info.name); 
    1046                                 memset(tempbuff, 0, sizeof(tempbuff)); 
    1047                                 WideCharToMultiByte(CP_UTF8, 0, dp->info.name, 
    1048                                         -1, &tempbuff[0], sizeof (tempbuff), 
    1049                                         NULL, NULL); 
    1050                                 //den->d_name = (char *)dp->info.name; 
    1051                                 den->d_name = &tempbuff[0]; 
    1052                                 if (dp->info.attrib & FILE_ATTRIBUTE_DIRECTORY) 
    1053                                 { 
    1054                                         den->d_type = S_IFDIR; 
    1055                                 } 
    1056                                 else 
    1057                                 { 
    1058                                         den->d_type = S_IFREG; 
    1059                                 } 
    1060                         } 
    1061                 } 
    1062                 else 
    1063                 { 
    1064                         errno = EBADF; 
    1065                 } 
    1066                 return den; 
     50                size_t wideSize = BufferSize / 5; 
     51                std::unique_ptr<wchar_t[]> wide(new wchar_t[wideSize+1]); 
     52 
     53                DWORD numCharsRead = 0; 
     54                if (!ReadConsoleW(hConsole,wide.get(),static_cast<DWORD>(wideSize),&numCharsRead,NULL)) 
     55                        throw Win32Exception(Win32Exception::API_ReadConsole); 
     56 
     57                wide[numCharsRead] = '\0'; 
     58                std::string multi(wide2multi(wide.get())); 
     59                strcpy(pBuffer,multi.c_str()); 
     60 
     61                return static_cast<int>(multi.size()); 
    106762        } 
    1068         catch (...) 
    1069         { 
    1070                 printf("Caught readdir"); 
    1071         } 
    1072         return NULL; 
     63        EMU_EXCEPTION_HANDLING_RETURN(-1) 
    107364} 
    1074  
    1075 // -------------------------------------------------------------------------- 
    1076 // 
    1077 // Function 
    1078 //              Name:    closedir 
    1079 //              Purpose: as function above 
    1080 //              Created: 25th October 2004 
    1081 // 
    1082 // -------------------------------------------------------------------------- 
    1083 int closedir(DIR *dp) 
    1084 { 
    1085         try 
    1086         { 
    1087                 int finres = -1; 
    1088                 if (dp) 
    1089                 { 
    1090                         if(dp->fd != -1) 
    1091                         { 
    1092                                 finres = _findclose(dp->fd); 
    1093                         } 
    1094  
    1095                         delete [] dp->name; 
    1096                         delete dp; 
    1097                 } 
    1098  
    1099                 if (finres == -1) // errors go to EBADF 
    1100                 { 
    1101                         errno = EBADF; 
    1102                 } 
    1103  
    1104                 return finres; 
    1105         } 
    1106         catch (...) 
    1107         { 
    1108                 printf("Caught closedir"); 
    1109         } 
    1110         return -1; 
    1111 } 
    1112  
    1113 // -------------------------------------------------------------------------- 
    1114 // 
    1115 // Function 
    1116 //              Name:    poll 
    1117 //              Purpose: a weak implimentation (just enough for box) 
    1118 //                      of the unix poll for winsock2 
    1119 //              Created: 25th October 2004 
    1120 // 
    1121 // -------------------------------------------------------------------------- 
    1122 int poll (struct pollfd *ufds, unsigned long nfds, int timeout) 
    1123 { 
    1124         try 
    1125         { 
    1126                 fd_set readfd; 
    1127                 fd_set writefd; 
    1128  
    1129                 FD_ZERO(&readfd); 
    1130                 FD_ZERO(&writefd); 
    1131  
    1132                 // struct pollfd *ufdsTmp = ufds; 
    1133  
    1134                 timeval timOut; 
    1135                 timeval *tmpptr; 
    1136  
    1137                 if (timeout == INFTIM) 
    1138                         tmpptr = NULL; 
    1139                 else 
    1140                         tmpptr = &timOut; 
    1141  
    1142                 timOut.tv_sec  = timeout / 1000; 
    1143                 timOut.tv_usec = timeout * 1000; 
    1144  
    1145                 for (unsigned long i = 0; i < nfds; i++) 
    1146                 { 
    1147                         struct pollfd* ufd = &(ufds[i]); 
    1148  
    1149                         if (ufd->events & POLLIN) 
    1150                         { 
    1151                                 FD_SET(ufd->fd, &readfd); 
    1152                         } 
    1153  
    1154                         if (ufd->events & POLLOUT) 
    1155                         { 
    1156                                 FD_SET(ufd->fd, &writefd); 
    1157                         } 
    1158  
    1159                         if (ufd->events & ~(POLLIN | POLLOUT)) 
    1160                         { 
    1161                                 printf("Unsupported poll bits %d", 
    1162                                         ufd->events); 
    1163                                 return -1; 
    1164                         } 
    1165                 } 
    1166  
    1167                 int nready = select(0, &readfd, &writefd, 0, tmpptr); 
    1168  
    1169                 if (nready == SOCKET_ERROR) 
    1170                 { 
    1171                         // int errval = WSAGetLastError(); 
    1172  
    1173                         struct pollfd* pufd = ufds; 
    1174                         for (unsigned long i = 0; i < nfds; i++) 
    1175                         { 
    1176                                 pufd->revents = POLLERR; 
    1177                                 pufd++; 
    1178                         } 
    1179                         return (-1); 
    1180                 } 
    1181                 else if (nready > 0) 
    1182                 { 
    1183                         for (unsigned long i = 0; i < nfds; i++) 
    1184                         { 
    1185                                 struct pollfd *ufd = &(ufds[i]); 
    1186  
    1187                                 if (FD_ISSET(ufd->fd, &readfd)) 
    1188                                 { 
    1189                                         ufd->revents |= POLLIN; 
    1190                                 } 
    1191  
    1192                                 if (FD_ISSET(ufd->fd, &writefd)) 
    1193                                 { 
    1194                                         ufd->revents |= POLLOUT; 
    1195                                 } 
    1196                         } 
    1197                 } 
    1198  
    1199                 return nready; 
    1200         } 
    1201         catch (...) 
    1202         { 
    1203                 printf("Caught poll"); 
    1204         } 
    1205  
    1206         return -1; 
    1207 } 
    1208  
    1209 // copied from MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/eventlog/base/adding_a_source_to_the_registry.asp 
    1210  
    1211 BOOL AddEventSource 
    1212 ( 
    1213         LPTSTR pszSrcName, // event source name 
    1214         DWORD  dwNum       // number of categories 
    1215 ) 
    1216 { 
    1217         // Work out the executable file name, to register ourselves 
    1218         // as the event source 
    1219  
    1220         WCHAR cmd[MAX_PATH]; 
    1221         DWORD len = GetModuleFileNameW(NULL, cmd, MAX_PATH); 
    1222  
    1223         if (len == 0) 
    1224         { 
    1225                 ::syslog(LOG_ERR, "Failed to get the program file name: %s", 
    1226                         GetErrorMessage(GetLastError()).c_str()); 
    1227                 return FALSE; 
    1228         } 
    1229  
    1230         // Create the event source as a subkey of the log. 
    1231  
    1232         std::string regkey("SYSTEM\\CurrentControlSet\\Services\\EventLog\\" 
    1233                 "Application\\"); 
    1234         regkey += pszSrcName; 
    1235  
    1236         HKEY hk; 
    1237         DWORD dwDisp; 
    1238  
    1239         if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, regkey.c_str(), 
    1240                          0, NULL, REG_OPTION_NON_VOLATILE, 
    1241                          KEY_WRITE, NULL, &hk, &dwDisp)) 
    1242         { 
    1243                 ::syslog(LOG_ERR, "Failed to create the registry key: %s", 
    1244                         GetErrorMessage(GetLastError()).c_str()); 
    1245                 return FALSE; 
    1246         } 
    1247  
    1248         // Set the name of the message file. 
    1249  
    1250         if (RegSetValueExW(hk,                 // subkey handle 
    1251                            L"EventMessageFile", // value name 
    1252                            0,                  // must be zero 
    1253                            REG_EXPAND_SZ,      // value type 
    1254                            (LPBYTE)cmd,        // pointer to value data 
    1255                            len*sizeof(WCHAR))) // data size 
    1256         { 
    1257                 ::syslog(LOG_ERR, "Failed to set the event message file: %s", 
    1258                         GetErrorMessage(GetLastError()).c_str()); 
    1259                 RegCloseKey(hk); 
    1260                 return FALSE; 
    1261         } 
    1262  
    1263         // Set the supported event types. 
    1264  
    1265         DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | 
    1266                   EVENTLOG_INFORMATION_TYPE; 
    1267  
    1268         if (RegSetValueEx(hk,               // subkey handle 
    1269                           "TypesSupported", // value name 
    1270                           0,                // must be zero 
    1271                           REG_DWORD,        // value type 
    1272                           (LPBYTE) &dwData, // pointer to value data 
    1273                           sizeof(DWORD)))   // length of value data 
    1274         { 
    1275                 ::syslog(LOG_ERR, "Failed to set the supported types: %s", 
    1276                         GetErrorMessage(GetLastError()).c_str()); 
    1277                 RegCloseKey(hk); 
    1278                 return FALSE; 
    1279         } 
    1280  
    1281         // Set the category message file and number of categories. 
    1282  
    1283         if (RegSetValueExW(hk,                    // subkey handle 
    1284                            L"CategoryMessageFile", // value name 
    1285                            0,                     // must be zero 
    1286                            REG_EXPAND_SZ,         // value type 
    1287                            (LPBYTE)cmd,           // pointer to value data 
    1288                            len*sizeof(WCHAR)))    // data size 
    1289         { 
    1290                 ::syslog(LOG_ERR, "Failed to set the category message file: " 
    1291                         "%s", GetErrorMessage(GetLastError()).c_str()); 
    1292                 RegCloseKey(hk); 
    1293                 return FALSE; 
    1294         } 
    1295  
    1296         if (RegSetValueEx(hk,              // subkey handle 
    1297                           "CategoryCount", // value name 
    1298                           0,               // must be zero 
    1299                           REG_DWORD,       // value type 
    1300                           (LPBYTE) &dwNum, // pointer to value data 
    1301                           sizeof(DWORD)))  // length of value data 
    1302         { 
    1303                 ::syslog(LOG_ERR, "Failed to set the category count: %s", 
    1304                         GetErrorMessage(GetLastError()).c_str()); 
    1305                 RegCloseKey(hk); 
    1306                 return FALSE; 
    1307         } 
    1308  
    1309         RegCloseKey(hk); 
    1310         return TRUE; 
    1311 } 
    1312  
    1313 static HANDLE gSyslogH = 0; 
    1314 static bool sHaveWarnedEventLogFull = false; 
    1315  
    1316 void openlog(const char * daemonName, int, int) 
    1317 { 
    1318         std::string nameStr = "Box Backup ("; 
    1319         nameStr += daemonName; 
    1320         nameStr += ")"; 
    1321  
    1322         // register a default event source, so that we can 
    1323         // log errors with the process of adding or registering our own. 
    1324         gSyslogH = RegisterEventSource( 
    1325                 NULL,        // uses local computer 
    1326                 nameStr.c_str()); // source name 
    1327         if (gSyslogH == NULL) 
    1328         { 
    1329         } 
    1330  
    1331         char* name = strdup(nameStr.c_str()); 
    1332         BOOL success = AddEventSource(name, 0); 
    1333         free(name); 
    1334  
    1335         if (!success) 
    1336         { 
    1337                 ::syslog(LOG_ERR, "Failed to add our own event source"); 
    1338                 return; 
    1339         } 
    1340  
    1341         HANDLE newSyslogH = RegisterEventSource(NULL, nameStr.c_str()); 
    1342         if (newSyslogH == NULL) 
    1343         { 
    1344                 ::syslog(LOG_ERR, "Failed to register our own event source: " 
    1345                         "%s", GetErrorMessage(GetLastError()).c_str()); 
    1346                 return; 
    1347         } 
    1348  
    1349         DeregisterEventSource(gSyslogH); 
    1350         gSyslogH = newSyslogH; 
    1351 } 
    1352  
    1353 void closelog(void) 
    1354 { 
    1355         DeregisterEventSource(gSyslogH); 
    1356 } 
    1357  
    1358 void syslog(int loglevel, const char *frmt, ...) 
    1359 { 
    1360         WORD errinfo; 
    1361         char buffer[1024]; 
    1362         std::string sixfour(frmt); 
    1363  
    1364         switch (loglevel) 
    1365         { 
    1366         case LOG_INFO: 
    1367                 errinfo = EVENTLOG_INFORMATION_TYPE; 
    1368                 break; 
    1369         case LOG_ERR: 
    1370                 errinfo = EVENTLOG_ERROR_TYPE; 
    1371                 break; 
    1372         case LOG_WARNING: 
    1373                 errinfo = EVENTLOG_WARNING_TYPE; 
    1374                 break; 
    1375         default: 
    1376                 errinfo = EVENTLOG_WARNING_TYPE; 
    1377                 break; 
    1378         } 
    1379  
    1380         // taken from MSDN 
    1381         int sixfourpos; 
    1382         while ( (sixfourpos = (int)sixfour.find("%ll")) != -1 ) 
    1383         { 
    1384                 // maintain portability - change the 64 bit formater... 
    1385                 std::string temp = sixfour.substr(0,sixfourpos); 
    1386                 temp += "%I64"; 
    1387                 temp += sixfour.substr(sixfourpos+3, sixfour.length()); 
    1388                 sixfour = temp; 
    1389         } 
    1390  
    1391         // printf("parsed string is:%s\r\n", sixfour.c_str()); 
    1392  
    1393         va_list args; 
    1394         va_start(args, frmt); 
    1395  
    1396         int len = vsnprintf(buffer, sizeof(buffer)-1, sixfour.c_str(), args); 
    1397         assert(len >= 0); 
    1398         if (len < 0) 
    1399         { 
    1400                 printf("%s\r\n", buffer); 
    1401                 fflush(stdout); 
    1402                 return; 
    1403         } 
    1404  
    1405         assert((size_t)len < sizeof(buffer)); 
    1406         buffer[sizeof(buffer)-1] = 0; 
    1407  
    1408         va_end(args); 
    1409  
    1410         if (gSyslogH == 0) 
    1411         { 
    1412                 printf("%s\r\n", buffer); 
    1413                 fflush(stdout); 
    1414                 return; 
    1415         } 
    1416  
    1417         WCHAR* pWide = ConvertToWideString(buffer, CP_UTF8, false); 
    1418         // must delete[] pWide 
    1419  
    1420         DWORD result; 
    1421  
    1422         if (pWide == NULL) 
    1423         { 
    1424                 std::string buffer2 = buffer; 
    1425                 buffer2 += " (failed to convert string encoding)"; 
    1426                 LPCSTR strings[] = { buffer2.c_str(), NULL }; 
    1427  
    1428                 result = ReportEventA(gSyslogH, // event log handle 
    1429                         errinfo,               // event type 
    1430                         0,                     // category zero 
    1431                         MSG_ERR,               // event identifier - 
    1432                                                // we will call them all the same 
    1433                         NULL,                  // no user security identifier 
    1434                         1,                     // one substitution string 
    1435                         0,                     // no data 
    1436                         strings,               // pointer to string array 
    1437                         NULL);                 // pointer to data 
    1438         } 
    1439         else 
    1440         { 
    1441                 LPCWSTR strings[] = { pWide, NULL }; 
    1442                 result = ReportEventW(gSyslogH, // event log handle 
    1443                         errinfo,               // event type 
    1444                         0,                     // category zero 
    1445                         MSG_ERR,               // event identifier - 
    1446                                                // we will call them all the same 
    1447                         NULL,                  // no user security identifier 
    1448                         1,                     // one substitution string 
    1449                         0,                     // no data 
    1450                         strings,               // pointer to string array 
    1451                         NULL);                 // pointer to data 
    1452                 delete [] pWide; 
    1453         } 
    1454  
    1455         if (result == 0) 
    1456         { 
    1457                 DWORD err = GetLastError(); 
    1458                 if (err == ERROR_LOG_FILE_FULL) 
    1459                 { 
    1460                         if (!sHaveWarnedEventLogFull) 
    1461                         { 
    1462                                 printf("Unable to send message to Event Log " 
    1463                                         "(Event Log is full):\r\n"); 
    1464                                 fflush(stdout); 
    1465                                 sHaveWarnedEventLogFull = TRUE; 
    1466                         } 
    1467                 } 
    1468                 else 
    1469                 { 
    1470                         printf("Unable to send message to Event Log: %s:\r\n", 
    1471                                 GetErrorMessage(err).c_str()); 
    1472                         fflush(stdout); 
    1473                 } 
    1474         } 
    1475         else 
    1476         { 
    1477                 sHaveWarnedEventLogFull = false; 
    1478         } 
    1479 } 
    1480  
    1481 int emu_chdir(const char* pDirName) 
    1482 { 
    1483         /* 
    1484         std::string AbsPathWithUnicode = 
    1485                 ConvertPathToAbsoluteUnicode(pDirName); 
    1486  
    1487         if (AbsPathWithUnicode.size() == 0) 
    1488         { 
    1489                 // error already logged by ConvertPathToAbsoluteUnicode() 
    1490                 return -1; 
    1491         } 
    1492  
    1493         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str()); 
    1494         */ 
    1495  
    1496         WCHAR* pBuffer = ConvertUtf8ToWideString(pDirName); 
    1497         if (!pBuffer) return -1; 
    1498  
    1499         int result = SetCurrentDirectoryW(pBuffer); 
    1500         delete [] pBuffer; 
    1501  
    1502         if (result != 0) return 0; 
    1503  
    1504         errno = EACCES; 
    1505         fprintf(stderr, "Failed to change directory to '%s': %s\n", 
    1506                 pDirName, GetErrorMessage(GetLastError()).c_str()); 
    1507         return -1; 
    1508 } 
    1509  
    1510 char* emu_getcwd(char* pBuffer, int BufSize) 
    1511 { 
    1512         DWORD len = GetCurrentDirectoryW(0, NULL); 
    1513         if (len == 0) 
    1514         { 
    1515                 errno = EINVAL; 
    1516                 return NULL; 
    1517         } 
    1518  
    1519         if ((int)len > BufSize) 
    1520         { 
    1521                 errno = ENAMETOOLONG; 
    1522                 return NULL; 
    1523         } 
    1524  
    1525         WCHAR* pWide = new WCHAR [len]; 
    1526         if (!pWide) 
    1527         { 
    1528                 errno = ENOMEM; 
    1529                 return NULL; 
    1530         } 
    1531  
    1532         DWORD result = GetCurrentDirectoryW(len, pWide); 
    1533         if (result <= 0 || result >= len) 
    1534         { 
    1535                 errno = EACCES; 
    1536                 delete [] pWide; 
    1537                 return NULL; 
    1538         } 
    1539  
    1540         char* pUtf8 = ConvertFromWideString(pWide, CP_UTF8); 
    1541         delete [] pWide; 
    1542  
    1543         if (!pUtf8) 
    1544         { 
    1545                 return NULL; 
    1546         } 
    1547  
    1548         strncpy(pBuffer, pUtf8, BufSize - 1); 
    1549         pBuffer[BufSize - 1] = 0; 
    1550         delete [] pUtf8; 
    1551  
    1552         return pBuffer; 
    1553 } 
    1554  
    1555 int emu_mkdir(const char* pPathName) 
    1556 { 
    1557         std::string AbsPathWithUnicode = 
    1558                 ConvertPathToAbsoluteUnicode(pPathName); 
    1559  
    1560         if (AbsPathWithUnicode.size() == 0) 
    1561         { 
    1562                 // error already logged by ConvertPathToAbsoluteUnicode() 
    1563                 return -1; 
    1564         } 
    1565  
    1566         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str()); 
    1567         if (!pBuffer) 
    1568         { 
    1569                 return -1; 
    1570         } 
    1571  
    1572         BOOL result = CreateDirectoryW(pBuffer, NULL); 
    1573         delete [] pBuffer; 
    1574  
    1575         if (!result) 
    1576         { 
    1577                 errno = EACCES; 
    1578                 return -1; 
    1579         } 
    1580  
    1581         return 0; 
    1582 } 
    1583  
    1584 int emu_unlink(const char* pFileName) 
    1585 { 
    1586         std::string AbsPathWithUnicode = 
    1587                 ConvertPathToAbsoluteUnicode(pFileName); 
    1588  
    1589         if (AbsPathWithUnicode.size() == 0) 
    1590         { 
    1591                 // error already logged by ConvertPathToAbsoluteUnicode() 
    1592                 return -1; 
    1593         } 
    1594  
    1595         WCHAR* pBuffer = ConvertUtf8ToWideString(AbsPathWithUnicode.c_str()); 
    1596         if (!pBuffer) 
    1597         { 
    1598                 return -1; 
    1599         } 
    1600  
    1601         BOOL result = DeleteFileW(pBuffer); 
    1602         DWORD err = GetLastError(); 
    1603         delete [] pBuffer; 
    1604  
    1605         if (!result) 
    1606         { 
    1607                 if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) 
    1608                 { 
    1609                         errno = ENOENT; 
    1610                 } 
    1611                 else if (err == ERROR_SHARING_VIOLATION) 
    1612                 { 
    1613                         errno = EBUSY; 
    1614                 } 
    1615                 else if (err == ERROR_ACCESS_DENIED) 
    1616                 { 
    1617                         errno = EACCES; 
    1618                 } 
    1619                 else 
    1620                 { 
    1621                         ::syslog(LOG_WARNING, "Failed to delete file " 
    1622                                 "'%s': %s", pFileName, 
    1623                                 GetErrorMessage(err).c_str()); 
    1624                         errno = ENOSYS; 
    1625                 } 
    1626                 return -1; 
    1627         } 
    1628  
    1629         return 0; 
    1630 } 
    1631  
    1632 int emu_rename(const char* pOldFileName, const char* pNewFileName) 
    1633 { 
    1634         std::string OldPathWithUnicode = 
    1635                 ConvertPathToAbsoluteUnicode(pOldFileName); 
    1636  
    1637         if (OldPathWithUnicode.size() == 0) 
    1638         { 
    1639                 // error already logged by ConvertPathToAbsoluteUnicode() 
    1640                 return -1; 
    1641         } 
    1642  
    1643         WCHAR* pOldBuffer = ConvertUtf8ToWideString(OldPathWithUnicode.c_str()); 
    1644         if (!pOldBuffer) 
    1645         { 
    1646                 return -1; 
    1647         } 
    1648  
    1649         std::string NewPathWithUnicode = 
    1650                 ConvertPathToAbsoluteUnicode(pNewFileName); 
    1651  
    1652         if (NewPathWithUnicode.size() == 0) 
    1653         { 
    1654                 // error already logged by ConvertPathToAbsoluteUnicode() 
    1655                 delete [] pOldBuffer; 
    1656                 return -1; 
    1657         } 
    1658  
    1659         WCHAR* pNewBuffer = ConvertUtf8ToWideString(NewPathWithUnicode.c_str()); 
    1660         if (!pNewBuffer) 
    1661         { 
    1662                 delete [] pOldBuffer; 
    1663                 return -1; 
    1664         } 
    1665  
    1666         BOOL result = MoveFileW(pOldBuffer, pNewBuffer); 
    1667         DWORD err = GetLastError(); 
    1668         delete [] pOldBuffer; 
    1669         delete [] pNewBuffer; 
    1670  
    1671         if (!result) 
    1672         { 
    1673                 if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) 
    1674                 { 
    1675                         errno = ENOENT; 
    1676                 } 
    1677                 else if (err == ERROR_SHARING_VIOLATION) 
    1678                 { 
    1679                         errno = EBUSY; 
    1680                 } 
    1681                 else if (err == ERROR_ACCESS_DENIED) 
    1682                 { 
    1683                         errno = EACCES; 
    1684                 } 
    1685                 else 
    1686                 { 
    1687                         ::syslog(LOG_WARNING, "Failed to rename file " 
    1688                                 "'%s' to '%s': %s", pOldFileName, pNewFileName, 
    1689                                 GetErrorMessage(err).c_str()); 
    1690                         errno = ENOSYS; 
    1691                 } 
    1692                 return -1; 
    1693         } 
    1694  
    1695         return 0; 
    1696 } 
    1697  
    1698 int console_read(char* pBuffer, size_t BufferSize) 
    1699 { 
    1700         HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); 
    1701  
    1702         if (hConsole == INVALID_HANDLE_VALUE) 
    1703         { 
    1704                 ::fprintf(stderr, "Failed to get a handle on standard input: " 
    1705                         "%s", GetErrorMessage(GetLastError()).c_str()); 
    1706                 return -1; 
    1707         } 
    1708  
    1709         size_t WideSize = BufferSize / 5; 
    1710         WCHAR* pWideBuffer = new WCHAR [WideSize + 1]; 
    1711  
    1712         if (!pWideBuffer) 
    1713         { 
    1714                 ::perror("Failed to allocate wide character buffer"); 
    1715                 return -1; 
    1716         } 
    1717  
    1718         DWORD numCharsRead = 0; 
    1719  
    1720         if (!ReadConsoleW( 
    1721                         hConsole, 
    1722                         pWideBuffer, 
    1723                         WideSize, // will not be null terminated by ReadConsole 
    1724                         &numCharsRead, 
    1725                         NULL // reserved 
    1726                 )) 
    1727         { 
    1728                 ::fprintf(stderr, "Failed to read from console: %s\n", 
    1729                         GetErrorMessage(GetLastError()).c_str()); 
    1730                 return -1; 
    1731         } 
    1732  
    1733         pWideBuffer[numCharsRead] = 0; 
    1734  
    1735         char* pUtf8 = ConvertFromWideString(pWideBuffer, GetConsoleCP()); 
    1736         delete [] pWideBuffer; 
    1737  
    1738         strncpy(pBuffer, pUtf8, BufferSize); 
    1739         delete [] pUtf8; 
    1740  
    1741         return strlen(pBuffer); 
    1742 } 
    1743  
    1744 int readv (int filedes, const struct iovec *vector, size_t count) 
    1745 { 
    1746         int bytes = 0; 
    1747  
    1748         for (size_t i = 0; i < count; i++) 
    1749         { 
    1750                 int result = read(filedes, vector[i].iov_base, 
    1751                         vector[i].iov_len); 
    1752                 if (result < 0) 
    1753                 { 
    1754                         return result; 
    1755                 } 
    1756                 bytes += result; 
    1757         } 
    1758  
    1759         return bytes; 
    1760 } 
    1761  
    1762 int writev(int filedes, const struct iovec *vector, size_t count) 
    1763 { 
    1764         int bytes = 0; 
    1765  
    1766         for (size_t i = 0; i < count; i++) 
    1767         { 
    1768                 int result = write(filedes, vector[i].iov_base, 
    1769                         vector[i].iov_len); 
    1770                 if (result < 0) 
    1771                 { 
    1772                         return result; 
    1773                 } 
    1774                 bytes += result; 
    1775         } 
    1776  
    1777         return bytes; 
    1778 } 
    1779  
    1780 // need this for conversions 
    1781 time_t ConvertFileTimeToTime_t(FILETIME *fileTime) 
    1782 { 
    1783         SYSTEMTIME stUTC; 
    1784         struct tm timeinfo; 
    1785  
    1786         // Convert the last-write time to local time. 
    1787         FileTimeToSystemTime(fileTime, &stUTC); 
    1788  
    1789         memset(&timeinfo, 0, sizeof(timeinfo)); 
    1790         timeinfo.tm_sec = stUTC.wSecond; 
    1791         timeinfo.tm_min = stUTC.wMinute; 
    1792         timeinfo.tm_hour = stUTC.wHour; 
    1793         timeinfo.tm_mday = stUTC.wDay; 
    1794         timeinfo.tm_wday = stUTC.wDayOfWeek; 
    1795         timeinfo.tm_mon = stUTC.wMonth - 1; 
    1796         // timeinfo.tm_yday = ...; 
    1797         timeinfo.tm_year = stUTC.wYear - 1900; 
    1798  
    1799         time_t retVal = mktime(&timeinfo) - _timezone; 
    1800         return retVal; 
    1801 } 
    1802  
    1803 bool ConvertTime_tToFileTime(const time_t from, FILETIME *pTo) 
    1804 { 
    1805         time_t adjusted = from + _timezone; 
    1806         struct tm *time_breakdown = gmtime(&adjusted); 
    1807         if (time_breakdown == NULL) 
    1808         { 
    1809                 ::syslog(LOG_ERR, "Error: failed to convert time format: " 
    1810                         "%d is not a valid time\n", from); 
    1811                 return false; 
    1812         } 
    1813  
    1814         SYSTEMTIME stUTC; 
    1815         stUTC.wSecond       = time_breakdown->tm_sec; 
    1816         stUTC.wMinute       = time_breakdown->tm_min; 
    1817         stUTC.wHour         = time_breakdown->tm_hour; 
    1818         stUTC.wDay          = time_breakdown->tm_mday; 
    1819         stUTC.wDayOfWeek    = time_breakdown->tm_wday; 
    1820         stUTC.wMonth        = time_breakdown->tm_mon  + 1; 
    1821         stUTC.wYear         = time_breakdown->tm_year + 1900; 
    1822         stUTC.wMilliseconds = 0; 
    1823  
    1824         // Convert the last-write time to local time. 
    1825         if (!SystemTimeToFileTime(&stUTC, pTo)) 
    1826         { 
    1827                 syslog(LOG_ERR, "Failed to convert between time formats: %s", 
    1828                         GetErrorMessage(GetLastError()).c_str()); 
    1829                 return false; 
    1830         } 
    1831  
    1832         return true; 
    1833 } 
    1834  
    1835 #endif // WIN32 
    1836  
  • box/invisnet/vs2010/0.11/lib/win32/emu.h

    r2773 r3055  
    1 // emulates unix syscalls to win32 functions 
     1#ifndef EMU_INCLUDE 
     2#       define EMU_INCLUDE 
    23 
    3 #ifdef WIN32 
    4         #define EMU_STRUCT_STAT struct emu_stat 
    5         #define EMU_STAT  emu_stat 
    6         #define EMU_FSTAT emu_fstat 
    7         #define EMU_LSTAT emu_stat 
    8 #else 
    9         #define EMU_STRUCT_STAT struct stat 
    10         #define EMU_STAT  ::stat 
    11         #define EMU_FSTAT ::fstat 
    12         #define EMU_LSTAT ::lstat 
    13 #endif 
     4#       ifdef WIN32 
     5#               pragma once 
    146 
    15 #if ! defined EMU_INCLUDE && defined WIN32 
    16 #define EMU_INCLUDE 
     7#               include "win32.h" 
     8#               include "dirent.h" 
     9#               include "getopt.h" 
     10#               include "poll.h" 
     11#               include "pwd.h" 
     12#               include "unicode.h" 
     13#               include "unistd.h" 
     14 
     15#               include "_sys/mount.h" 
     16#               include "_sys/resource.h" 
     17#               include "_sys/socket.h" 
     18#               include "_sys/stat.h" 
     19#               include "_sys/syslog.h" 
     20#               include "_sys/time.h" 
     21#               include "_sys/uio.h" 
     22 
     23 
     24                extern passwd gTempPasswd; 
     25 
     26 
     27#               define EMU_EXCEPTION_HANDLING \ 
     28                catch(std::bad_alloc &e) \ 
     29                { \ 
     30                        (void)e; /* make the compiler happy */ \ 
     31                        errno = ENOMEM; \ 
     32                } \ 
     33                catch(Win32Exception &e) \ 
     34                { \ 
     35                        BOX_LOG_WIN_ERROR_NUMBER(e.GetMessage(),e.GetLastError()); \ 
     36                } \ 
     37                catch(...) \ 
     38                { \ 
     39                        BOX_FATAL("Unexpected exception") \ 
     40                } 
     41 
     42#               define EMU_EXCEPTION_HANDLING_RETURN(rv) \ 
     43                catch(std::bad_alloc &e) \ 
     44                { \ 
     45                        (void)e; /* make the compiler happy */ \ 
     46                        errno = ENOMEM; \ 
     47                } \ 
     48                catch(Win32Exception &e) \ 
     49                { \ 
     50                        BOX_LOG_WIN_ERROR_NUMBER(e.GetMessage(),e.GetLastError()); \ 
     51                } \ 
     52                catch(...) \ 
     53                { \ 
     54                        BOX_FATAL("Unexpected exception") \ 
     55                } \ 
     56                return rv; 
     57 
     58 
    1759 
    1860// basic types, may be required by other headers since we 
    1961// don't include sys/types.h 
    2062 
    21 #ifdef __MINGW32__ 
    22         #include <stdint.h> 
    23 #else // MSVC 
    24         typedef unsigned __int64 u_int64_t; 
    25         typedef unsigned __int64 uint64_t; 
    26         typedef          __int64 int64_t; 
    27         typedef unsigned __int32 uint32_t; 
    28         typedef unsigned __int32 u_int32_t; 
    29         typedef          __int32 int32_t; 
    30         typedef unsigned __int16 uint16_t; 
    31         typedef          __int16 int16_t; 
    32         typedef unsigned __int8  uint8_t; 
    33         typedef          __int8  int8_t; 
    34 #endif 
    3563 
    3664// emulated types, present on MinGW but not MSVC or vice versa 
     
    3967        typedef uint32_t u_int32_t; 
    4068#else 
    41         typedef unsigned int mode_t; 
    42         typedef unsigned int pid_t; 
    4369#endif 
    44  
    45 // set up to include the necessary parts of Windows headers 
    46  
    47 #define WIN32_LEAN_AND_MEAN 
    48  
    49 #ifndef __MSVCRT_VERSION__ 
    50 #define __MSVCRT_VERSION__ 0x0601 
    51 #endif 
    52  
    53 // Windows headers 
    54  
    55 #include <winsock2.h> 
    56 #include <fcntl.h> 
    57 #include <sys/stat.h> 
    58 #include <direct.h> 
    59 #include <errno.h> 
    60 #include <io.h> 
    61 #include <stdlib.h> 
    62 #include <string.h> 
    63 #include <stdio.h> 
    64 #include <stdarg.h> 
    65 #include <time.h> 
    66  
    67 #include <string> 
    6870 
    6971// emulated functions 
     
    7577#define ITIMER_REAL 0 
    7678 
    77 struct passwd { 
    78         char *pw_name; 
    79         char *pw_passwd; 
    80         int pw_uid; 
    81         int pw_gid; 
    82         time_t pw_change; 
    83         char *pw_class; 
    84         char *pw_gecos; 
    85         char *pw_dir; 
    86         char *pw_shell; 
    87         time_t pw_expire; 
    88 }; 
    8979 
    90 extern passwd gTempPasswd; 
    91 inline struct passwd * getpwnam(const char * name) 
    92 { 
    93         //for the mo pretend to be root 
    94         gTempPasswd.pw_uid = 0; 
    95         gTempPasswd.pw_gid = 0; 
    9680 
    97         return &gTempPasswd; 
    98 } 
    9981 
    100 #define S_IRWXG 1 
    101 #define S_IRWXO 2 
    102 #define S_ISUID 4 
    103 #define S_ISGID 8 
    104 #define S_ISVTX 16 
    10582 
    106 #ifndef __MINGW32__ 
    107         //not sure if these are correct 
    108         //S_IWRITE -   writing permitted 
    109         //_S_IREAD -   reading permitted 
    110         //_S_IREAD | _S_IWRITE -  
    111         #define S_IRUSR S_IWRITE 
    112         #define S_IWUSR S_IREAD 
    113         #define S_IRWXU (S_IREAD|S_IWRITE|S_IEXEC) 
    114  
    115         #define S_ISREG(x) (S_IFREG & x) 
    116         #define S_ISDIR(x) (S_IFDIR & x) 
    117 #endif 
    118  
    119 inline int chown(const char * Filename, u_int32_t uid, u_int32_t gid) 
    120 { 
    121         //important - this needs implementing 
    122         //If a large restore is required then  
    123         //it needs to restore files AND permissions 
    124         //reference AdjustTokenPrivileges 
    125         //GetAccountSid 
    126         //InitializeSecurityDescriptor 
    127         //SetSecurityDescriptorOwner 
    128         //The next function looks like the guy to use... 
    129         //SetFileSecurity 
    130  
    131         //indicate success 
    132         return 0; 
    133 } 
    134  
    135 // Windows and Unix owners and groups are pretty fundamentally different. 
    136 // Ben prefers that we kludge here rather than litter the code with #ifdefs. 
    137 // Pretend to be root, and pretend that set...() operations succeed. 
    138 inline int setegid(int) 
    139 { 
    140         return true; 
    141 } 
    142 inline int seteuid(int) 
    143 { 
    144         return true; 
    145 } 
    146 inline int setgid(int) 
    147 { 
    148         return true; 
    149 } 
    150 inline int setuid(int) 
    151 { 
    152         return true; 
    153 } 
    154 inline int getgid(void) 
    155 { 
    156         return 0; 
    157 } 
    158 inline int getuid(void) 
    159 { 
    160         return 0; 
    161 } 
    162 inline int geteuid(void) 
    163 { 
    164         return 0; 
    165 } 
    16683 
    16784#ifndef PATH_MAX 
     
    16986#endif 
    17087 
    171 // MinGW provides a getopt implementation 
    172 #ifndef __MINGW32__ 
    173 #include "getopt.h" 
    174 #endif // !__MINGW32__ 
    175  
    17688#define timespec timeval 
    17789 
    17890//win32 deals in usec not nsec - so need to ensure this follows through 
    17991#define tv_nsec tv_usec  
    180  
    181 #ifndef __MINGW32__ 
    182         typedef int socklen_t; 
    183 #endif 
    18492 
    18593#define S_IRGRP S_IWRITE 
     
    208116#endif 
    209117 
    210 struct dirent 
    211 { 
    212         char *d_name; 
    213         unsigned long d_type; 
    214 }; 
    215  
    216 struct DIR 
    217 { 
    218         intptr_t                fd;     // filedescriptor 
    219         // struct _finddata_t   info; 
    220         struct _wfinddata_t     info; 
    221         // struct _finddata_t   info; 
    222         struct dirent           result; // d_name (first time null) 
    223         wchar_t                 *name;  // null-terminated byte string 
    224 }; 
    225  
    226 DIR *opendir(const char *name); 
    227 struct dirent *readdir(DIR *dp); 
    228 int closedir(DIR *dp); 
    229  
    230118// local constant to open file exclusively without shared access 
    231119#define O_LOCK 0x10000 
    232120 
    233 extern DWORD winerrno; /* used to report errors from openfile() */ 
    234121HANDLE openfile(const char *filename, int flags, int mode); 
    235122inline int closefile(HANDLE handle) 
     
    243130} 
    244131 
    245 #define LOG_DEBUG LOG_INFO 
    246 #define LOG_INFO 6 
    247 #define LOG_NOTICE LOG_INFO 
    248 #define LOG_WARNING 4 
    249 #define LOG_ERR 3 
    250 #define LOG_CRIT LOG_ERR 
    251 #define LOG_PID 0 
    252 #define LOG_LOCAL5 0 
    253 #define LOG_LOCAL6 0 
    254  
    255 void openlog (const char * daemonName, int, int); 
    256 void closelog(void); 
    257 void syslog  (int loglevel, const char *fmt, ...); 
    258  
    259 #define LOG_LOCAL0 0 
    260 #define LOG_LOCAL1 0 
    261 #define LOG_LOCAL2 0 
    262 #define LOG_LOCAL3 0 
    263 #define LOG_LOCAL4 0 
    264 #define LOG_LOCAL5 0 
    265 #define LOG_LOCAL6 0 
    266 #define LOG_DAEMON 0 
    267132 
    268133#ifndef __MINGW32__ 
     
    270135#endif 
    271136 
    272 inline unsigned int sleep(unsigned int secs) 
    273 { 
    274         Sleep(secs*1000); 
    275         return(ERROR_SUCCESS); 
    276 } 
    277137 
    278 #define INFTIM -1 
    279 #if(_WIN32_WINNT < 0x0600) 
    280 #define POLLIN 0x1 
    281 #define POLLERR 0x8 
    282 #define POLLOUT 0x4 
    283 #endif 
    284138 
    285 #define SHUT_RDWR SD_BOTH 
    286 #define SHUT_RD SD_RECEIVE 
    287 #define SHUT_WR SD_SEND 
    288139 
    289 #if(_WIN32_WINNT < 0x0600) 
    290 struct pollfd 
    291 { 
    292         SOCKET fd; 
    293         short int events; 
    294         short int revents; 
    295 }; 
    296 #endif 
    297  
    298 inline int ioctl(SOCKET sock, int flag,  int * something) 
    299 { 
    300         //indicate success 
    301         return 0; 
    302 } 
    303  
    304 extern "C" inline int getpid() 
    305 { 
    306         return (int)GetCurrentProcessId(); 
    307 } 
    308  
    309 inline int waitpid(pid_t pid, int *status, int) 
    310 { 
    311         return 0; 
    312 } 
    313  
    314 //this shouldn't be needed. 
    315 struct statfs 
    316 { 
    317         TCHAR f_mntonname[MAX_PATH]; 
    318 }; 
    319  
    320 struct emu_stat { 
    321         int st_dev; 
    322         uint64_t st_ino; 
    323         DWORD st_mode; 
    324         short st_nlink; 
    325         short st_uid; 
    326         short st_gid; 
    327         //_dev_t st_rdev; 
    328         uint64_t st_size; 
    329         time_t st_atime; 
    330         time_t st_mtime; 
    331         time_t st_ctime; 
    332 }; 
    333  
    334 // need this for conversions 
    335 time_t ConvertFileTimeToTime_t(FILETIME *fileTime); 
    336 bool   ConvertTime_tToFileTime(const time_t from, FILETIME *pTo); 
    337  
    338 int   emu_chdir  (const char* pDirName); 
    339 int   emu_mkdir  (const char* pPathName); 
    340 int   emu_unlink (const char* pFileName); 
    341 int   emu_fstat  (HANDLE file,       struct emu_stat* st); 
    342 int   emu_stat   (const char* pName, struct emu_stat* st); 
    343 int   emu_utimes (const char* pName, const struct timeval[]); 
    344 int   emu_chmod  (const char* pName, mode_t mode); 
    345 char* emu_getcwd (char* pBuffer,     int BufSize); 
    346 int   emu_rename (const char* pOldName, const char* pNewName); 
    347  
    348 #define chdir(directory)        emu_chdir  (directory) 
    349 #define mkdir(path,     mode)   emu_mkdir  (path) 
    350 #define unlink(file)            emu_unlink (file) 
    351 #define utimes(buffer,  times)  emu_utimes (buffer,   times) 
    352 #define chmod(file,     mode)   emu_chmod  (file,     mode) 
    353 #define getcwd(buffer,  size)   emu_getcwd (buffer,   size) 
    354 #define rename(oldname, newname) emu_rename (oldname, newname) 
    355  
    356 // Not safe to replace stat/fstat/lstat on mingw at least, as struct stat 
    357 // has a 16-bit st_ino and we need a 64-bit one. 
    358 // 
    359 // #define stat(filename,  struct) emu_stat   (filename, struct) 
    360 // #define lstat(filename, struct) emu_stat   (filename, struct) 
    361 // #define fstat(handle,   struct) emu_fstat  (handle,   struct) 
    362 // 
    363 // But lstat doesn't exist on Windows, so we have to provide something: 
    364  
    365 #define lstat(filename, struct) stat(filename, struct) 
    366  
    367 int statfs(const char * name, struct statfs * s); 
    368  
    369 int poll(struct pollfd *ufds, unsigned long nfds, int timeout); 
    370  
    371 struct iovec { 
    372         void *iov_base;   /* Starting address */ 
    373         size_t iov_len;   /* Number of bytes */ 
    374 }; 
    375  
    376 int readv (int filedes, const struct iovec *vector, size_t count); 
    377 int writev(int filedes, const struct iovec *vector, size_t count); 
    378140 
    379141// The following functions are not emulations, but utilities for other  
     
    383145bool EnableBackupRights( void ); 
    384146 
    385 bool ConvertEncoding (const std::string& rSource, int sourceCodePage, 
    386         std::string& rDest, int destCodePage); 
    387 bool ConvertToUtf8   (const std::string& rSource, std::string& rDest,  
    388         int sourceCodePage); 
    389 bool ConvertFromUtf8 (const std::string& rSource, std::string& rDest, 
    390         int destCodePage); 
    391 bool ConvertUtf8ToConsole(const std::string& rSource, std::string& rDest); 
    392 bool ConvertConsoleToUtf8(const std::string& rSource, std::string& rDest); 
    393  
    394147// Utility function which returns a default config file name, 
    395148// based on the path of the current executable. 
    396149std::string GetDefaultConfigFilePath(const std::string& rName); 
    397  
    398 // GetErrorMessage() returns a system error message, like strerror()  
    399 // but for Windows error codes. 
    400 std::string GetErrorMessage(DWORD errorCode); 
    401150 
    402151// console_read() is a replacement for _cgetws which requires a  
     
    405154 
    406155#endif // !EMU_INCLUDE && WIN32 
     156 
     157#endif 
  • box/invisnet/vs2010/0.11/lib/win32/getopt.h

    r946 r3055  
    3737 * POSSIBILITY OF SUCH DAMAGE. 
    3838 */ 
     39 
     40#ifdef WIN32 
     41#       pragma once 
     42#       ifdef __MINGW32__ 
     43#               define _GETOPT_H_ 
     44#       else 
     45 
     46#       endif 
     47#endif 
    3948 
    4049#ifndef _GETOPT_H_ 
Note: See TracChangeset for help on using the changeset viewer.