]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/win32/compat/compat.cpp
kes Remove previous changes to compat.cpp as they create problems.
[bacula/bacula] / bacula / src / win32 / compat / compat.cpp
index 03d8835b2d3688efa5b3f27cb8ab66fd9fea90d3..d5931f439254f717d11449ff39accd88c2b01ecf 100644 (file)
 // Created On      : Sat Jan 31 15:55:00 2004
 // $Id$
 
-#ifdef __APCUPSD__
-
-#include "apc.h"
-#include "compat.h"
-#include "winapi.h"
-
-#else
-
 #include "bacula.h"
 #include "compat.h"
 #include "jcr.h"
-#include "../../lib/winapi.h"
-#include "vss.h"
-
-#endif
 
 #define b_errno_win32 (1<<29)
 
 
+/* UTF-8 to UCS2 path conversion is expensive,
+   so we cache the conversion. During backup the
+   conversion is called 3 times (lstat, attribs, open),
+   by using the cache this is reduced to 1 time */
+
+static POOLMEM *g_pWin32ConvUTF8Cache = get_pool_memory (PM_FNAME);
+static POOLMEM *g_pWin32ConvUCS2Cache = get_pool_memory (PM_FNAME);
+static DWORD g_dwWin32ConvUTF8strlen = 0;
+static pthread_mutex_t Win32Convmutex = PTHREAD_MUTEX_INITIALIZER;
+
+static t_pVSSPathConvert   g_pVSSPathConvert;
+static t_pVSSPathConvertW  g_pVSSPathConvertW;
+
+void SetVSSPathConvert(t_pVSSPathConvert pPathConvert, t_pVSSPathConvertW pPathConvertW)
+{
+   g_pVSSPathConvert = pPathConvert;
+   g_pVSSPathConvertW = pPathConvertW;
+}
+
+void Win32ConvCleanupCache()
+{
+   if (g_pWin32ConvUTF8Cache) {
+      free_pool_memory(g_pWin32ConvUTF8Cache);
+      g_pWin32ConvUTF8Cache = NULL;
+   }
+
+   if (g_pWin32ConvUCS2Cache) {
+      free_pool_memory(g_pWin32ConvUCS2Cache);   
+      g_pWin32ConvUCS2Cache = NULL;
+   }
+
+   g_dwWin32ConvUTF8strlen = 0;
+}
+
+
 /* to allow the usage of the original version in this file here */
 #undef fputs
 
 
-#define USE_WIN32_COMPAT_IO 1
+//#define USE_WIN32_COMPAT_IO 1
 #define USE_WIN32_32KPATHCONVERSION 1
 
-extern void d_msg(const char *file, int line, int level, const char *fmt,...);
 extern DWORD   g_platform_id;
-extern int enable_vss;
+extern DWORD   g_MinorVersion;
 
 // from MicroSoft SDK (KES) is the diff between Jan 1 1601 and Jan 1 1970
 #ifdef HAVE_MINGW
@@ -64,6 +86,22 @@ void conv_unix_to_win32_path(const char *name, char *win32_name, DWORD dwSize)
 {
     const char *fname = name;
     char *tname = win32_name;
+
+    Dmsg0(100, "Enter convert_unix_to_win32_path\n");
+
+    if ((name[0] == '/' || name[0] == '\\') &&
+        (name[1] == '/' || name[1] == '\\') &&
+        (name[2] == '.') &&
+        (name[3] == '/' || name[3] == '\\')) {
+
+        *win32_name++ = '\\';
+        *win32_name++ = '\\';
+        *win32_name++ = '.';
+        *win32_name++ = '\\';
+
+        name += 4;
+    }
+
     while (*name) {
         /* Check for Unix separator and convert to Win32 */
         if (name[0] == '/' && name[1] == '/') {  /* double slash? */
@@ -88,49 +126,66 @@ void conv_unix_to_win32_path(const char *name, char *win32_name, DWORD dwSize)
         *win32_name = 0;
     }
 
-#ifdef WIN32_VSS
     /* here we convert to VSS specific file name which
        can get longer because VSS will make something like
        \\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy1\\bacula\\uninstall.exe
        from c:\bacula\uninstall.exe
     */
-    if (g_pVSSClient && enable_vss && g_pVSSClient->IsInitialized()) {
+    Dmsg1(100, "path=%s\n", tname);
+    if (g_pVSSPathConvert != NULL) {
        POOLMEM *pszBuf = get_pool_memory (PM_FNAME);
        pszBuf = check_pool_memory_size(pszBuf, dwSize);
        bstrncpy(pszBuf, tname, strlen(tname)+1);
-       g_pVSSClient->GetShadowPath(pszBuf, tname, dwSize);
+       g_pVSSPathConvert(pszBuf, tname, dwSize);
        free_pool_memory(pszBuf);
     }
-#endif
+    Dmsg1(100, "Leave cvt_u_to_win32_path path=%s\n", tname);
+}
+
+/* Conversion of a Unix filename to a Win32 filename */
+void unix_name_to_win32(POOLMEM **win32_name, char *name)
+{
+   /* One extra byte should suffice, but we double it */
+   /* add MAX_PATH bytes for VSS shadow copy name */
+   DWORD dwSize = 2*strlen(name)+MAX_PATH;
+   *win32_name = check_pool_memory_size(*win32_name, dwSize);
+   conv_unix_to_win32_path(name, *win32_name, dwSize);
 }
 
 POOLMEM* 
-make_wchar_win32_path(POOLMEM* pszUCSPath, BOOL* pBIsRawPath /*= NULL*/)
+make_wchar_win32_path(POOLMEM *pszUCSPath, BOOL *pBIsRawPath /*= NULL*/)
 {
    /* created 02/27/2006 Thorsten Engel
-      
-      This function expects an UCS-encoded standard wchar_t in pszUCSPath and
-      will complete the input path to an absolue path of the form \\?\c:\path\file
-
-      With this trick, it is possible to have 32K characters long paths.
-
-      Optionally one can use pBIsRawPath to determine id pszUCSPath contains a path
-      to a raw windows partition */
+    * 
+    * This function expects an UCS-encoded standard wchar_t in pszUCSPath and
+    * will complete the input path to an absolue path of the form \\?\c:\path\file
+    * 
+    * With this trick, it is possible to have 32K characters long paths.
+    *
+    * Optionally one can use pBIsRawPath to determine id pszUCSPath contains a path
+    * to a raw windows partition.  
+    */
 
-   if (pBIsRawPath)
-      *pBIsRawPath = FALSE;
+   Dmsg0(100, "Enter wchar_win32_path\n");
+   if (pBIsRawPath) {
+      *pBIsRawPath = FALSE;              /* Initialize, set later */
+   }
 
-   if (!p_GetCurrentDirectoryW)
+   if (!p_GetCurrentDirectoryW) {
+      Dmsg0(100, "Leave wchar_win32_path no change \n");
       return pszUCSPath;
+   }
    
-   wchar_t * name = (wchar_t *) pszUCSPath;
+   wchar_t *name = (wchar_t *)pszUCSPath;
 
    /* if it has already the desired form, exit without changes */
-   if (wcslen(name) > 3 && wcsncmp (name, L"\\\\?\\", 4) == 0)
+   if (wcslen(name) > 3 && wcsncmp(name, L"\\\\?\\", 4) == 0) {
+      Dmsg0(100, "Leave wchar_win32_path no change \n");
       return pszUCSPath;
+   }
 
-   POOLMEM* pwszBuf = get_pool_memory (PM_FNAME);
-   POOLMEM* pwszCurDirBuf = get_pool_memory (PM_FNAME);
+   POOLMEM *pwszBuf = get_pool_memory(PM_FNAME);
+   POOLMEM *pwszCurDirBuf = get_pool_memory(PM_FNAME);
    DWORD dwCurDirPathSize = 0;
 
    /* get buffer with enough size (name+max 6. wchars+1 null terminator */
@@ -157,17 +212,18 @@ make_wchar_win32_path(POOLMEM* pszUCSPath, BOOL* pBIsRawPath /*= NULL*/)
       bAddCurrentPath = FALSE; 
 
    /* is path relative to itself?, if yes, skip ./ */
-   if (wcslen(name) > 2 && ((wcsncmp (name, L"./", 2) == 0) || (wcsncmp (name, L".\\", 2) == 0))) {
-      name+=2;
+   if (wcslen(name) > 2 && ((wcsncmp(name, L"./", 2) == 0) || (wcsncmp(name, L".\\", 2) == 0))) {
+      name += 2;
    }
 
    /* is path of form '//./'? */   
-   if (wcslen(name) > 3 && ((wcsncmp (name, L"//./", 4) == 0) || (wcsncmp (name, L"\\\\.\\", 4) == 0))) {
+   if (wcslen(name) > 3 && ((wcsncmp(name, L"//./", 4) == 0) || (wcsncmp(name, L"\\\\.\\", 4) == 0))) {
       bAddDrive = FALSE;
       bAddCurrentPath = FALSE;
       bAddPrefix = FALSE;
-      if (pBIsRawPath)
+      if (pBIsRawPath) {
          *pBIsRawPath = TRUE;
+      }
    }
 
    int nParseOffset = 0;
@@ -175,7 +231,7 @@ make_wchar_win32_path(POOLMEM* pszUCSPath, BOOL* pBIsRawPath /*= NULL*/)
    /* add 4 bytes header */
    if (bAddPrefix) {
       nParseOffset = 4;
-      wcscpy ((wchar_t *) pwszBuf,L"\\\\?\\");
+      wcscpy((wchar_t *)pwszBuf, L"\\\\?\\");
    }
 
    /* get current path if needed */
@@ -185,9 +241,7 @@ make_wchar_win32_path(POOLMEM* pszUCSPath, BOOL* pBIsRawPath /*= NULL*/)
          /* get directory into own buffer as it may either return c:\... or \\?\C:\.... */         
          pwszCurDirBuf = check_pool_memory_size(pwszCurDirBuf, (dwCurDirPathSize+1)*sizeof(wchar_t));
          p_GetCurrentDirectoryW(dwCurDirPathSize,(wchar_t *)pwszCurDirBuf);
-      }
-      else
-      {
+      } else {
          /* we have no info for doing so */
          bAddDrive = FALSE;
          bAddCurrentPath = FALSE;
@@ -199,16 +253,17 @@ make_wchar_win32_path(POOLMEM* pszUCSPath, BOOL* pBIsRawPath /*= NULL*/)
    if (bAddDrive && !bAddCurrentPath) {
       wchar_t szDrive[3];
 
-      if (dwCurDirPathSize > 3 && wcsncmp((LPCWSTR)pwszCurDirBuf, L"\\\\?\\", 4) == 0)
+      if (dwCurDirPathSize > 3 && wcsncmp((LPCWSTR)pwszCurDirBuf, L"\\\\?\\", 4) == 0) {
          /* copy drive character */
-         wcsncpy((wchar_t *) szDrive, (LPCWSTR)pwszCurDirBuf+4,2);          
-      else
+         wcsncpy((wchar_t *)szDrive, (LPCWSTR)pwszCurDirBuf+4, 2);          
+      } else {
          /* copy drive character */
-         wcsncpy((wchar_t *) szDrive, (LPCWSTR)pwszCurDirBuf,2);  
+         wcsncpy((wchar_t *)szDrive, (LPCWSTR)pwszCurDirBuf, 2);  
+      }
 
       szDrive[2] = 0;
             
-      wcscat((wchar_t *) pwszBuf, szDrive);  
+      wcscat((wchar_t *)pwszBuf, szDrive);  
       nParseOffset +=2;
    }
 
@@ -219,24 +274,25 @@ make_wchar_win32_path(POOLMEM* pszUCSPath, BOOL* pBIsRawPath /*= NULL*/)
       pwszBuf = check_pool_memory_size(pwszBuf, dwBufCharsNeeded*sizeof(wchar_t));
       /* get directory into own buffer as it may either return c:\... or \\?\C:\.... */
       
-      if (dwCurDirPathSize > 3 && wcsncmp ((LPCWSTR)pwszCurDirBuf, L"\\\\?\\", 4) == 0)
+      if (dwCurDirPathSize > 3 && wcsncmp((LPCWSTR)pwszCurDirBuf, L"\\\\?\\", 4) == 0) {
          /* copy complete string */
-         wcscpy((wchar_t *) pwszBuf, (LPCWSTR)pwszCurDirBuf);          
-      else
+         wcscpy((wchar_t *)pwszBuf, (LPCWSTR)pwszCurDirBuf);          
+      } else {
          /* append path  */
-         wcscat((wchar_t *) pwszBuf, (LPCWSTR)pwszCurDirBuf);       
+         wcscat((wchar_t *)pwszBuf, (LPCWSTR)pwszCurDirBuf);       
+      }
 
-      nParseOffset = wcslen ((LPCWSTR) pwszBuf);
+      nParseOffset = wcslen((LPCWSTR) pwszBuf);
 
       /* check if path ends with backslash, if not, add one */
-      if (*((wchar_t *) pwszBuf+nParseOffset-1) != L'\\') {
-         wcscat((wchar_t *) pwszBuf, L"\\");
+      if (*((wchar_t *)pwszBuf+nParseOffset-1) != L'\\') {
+         wcscat((wchar_t *)pwszBuf, L"\\");
          nParseOffset++;
       }      
    }
 
 
-   wchar_t * win32_name = (wchar_t *)pwszBuf+nParseOffset;
+   wchar_t *win32_name = (wchar_t *)pwszBuf+nParseOffset;
 
    while (*name) {
       /* Check for Unix separator and convert to Win32 */
@@ -244,11 +300,14 @@ make_wchar_win32_path(POOLMEM* pszUCSPath, BOOL* pBIsRawPath /*= NULL*/)
          *win32_name++ = '\\';     /* convert char */
          /* If Win32 separated that is "quoted", remove quote */
 /* HELPME (Thorsten Engel): I don't understand the following part
-   and it removes a backslash from e.g. "\\.\c:" which I need for 
-   RAW device access. So I took it out */
-/*      } else if (*name == '\\' && name[1] == '\\') {
+ * and it removes a backslash from e.g. "\\.\c:" which I need for 
+ * RAW device access. So I took it out.  
+ */
+#ifdef needed
+        } else if (*name == '\\' && name[1] == '\\') {
          *win32_name++ = '\\';
-         name++;  */                 /* skip first \ */ 
+         name++;                     /* skip first \ */ 
+#endif
       } else {
          *win32_name++ = *name;    /* copy character */
       }
@@ -258,13 +317,12 @@ make_wchar_win32_path(POOLMEM* pszUCSPath, BOOL* pBIsRawPath /*= NULL*/)
    /* null terminate string */
    *win32_name = 0;
 
-#ifdef WIN32_VSS
    /* here we convert to VSS specific file name which
-   can get longer because VSS will make something like
-   \\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy1\\bacula\\uninstall.exe
-   from c:\bacula\uninstall.exe
+    * can get longer because VSS will make something like
+    * \\\\?\\GLOBALROOT\\Device\\HarddiskVolumeShadowCopy1\\bacula\\uninstall.exe
+    * from c:\bacula\uninstall.exe
    */ 
-   if (g_pVSSClient && enable_vss && g_pVSSClient->IsInitialized()) {
+   if (g_pVSSPathConvertW != NULL) {
       /* is output buffer large enough? */
       pwszBuf = check_pool_memory_size(pwszBuf, (dwBufCharsNeeded+MAX_PATH)*sizeof(wchar_t));
       /* create temp. buffer */
@@ -274,15 +332,15 @@ make_wchar_win32_path(POOLMEM* pszUCSPath, BOOL* pBIsRawPath /*= NULL*/)
          nParseOffset = 4;
       else
          nParseOffset = 0; 
-      wcsncpy((wchar_t *) pszBuf, (wchar_t *) pwszBuf+nParseOffset, wcslen((wchar_t *)pwszBuf)+1-nParseOffset);
-      g_pVSSClient->GetShadowPathW((wchar_t *)pszBuf,(wchar_t *)pwszBuf,dwBufCharsNeeded+MAX_PATH);
+      wcsncpy((wchar_t *)pszBuf, (wchar_t *)pwszBuf+nParseOffset, wcslen((wchar_t *)pwszBuf)+1-nParseOffset);
+      g_pVSSPathConvertW((wchar_t *)pszBuf, (wchar_t *)pwszBuf, dwBufCharsNeeded+MAX_PATH);
       free_pool_memory(pszBuf);
    }   
-#endif
 
-   free_pool_memory (pszUCSPath);
-   free_pool_memory (pwszCurDirBuf);
+   free_pool_memory(pszUCSPath);
+   free_pool_memory(pwszCurDirBuf);
 
+   Dmsg1(100, "Leave wchar_win32_path=%s\n", pwszBuf);
    return pwszBuf;
 }
 
@@ -349,6 +407,20 @@ wchar_win32_path(const char *name, wchar_t *win32_name)
 int 
 make_win32_path_UTF8_2_wchar(POOLMEM **pszUCS, const char *pszUTF, BOOL* pBIsRawPath /*= NULL*/)
 {
+   P(Win32Convmutex);
+   /* if we find the utf8 string in cache, we use the cached ucs2 version.
+      we compare the stringlength first (quick check) and then compare the content.            
+   */
+   if (g_dwWin32ConvUTF8strlen == strlen(pszUTF)) {
+      if (bstrcmp(pszUTF, g_pWin32ConvUTF8Cache)) {
+         int32_t nBufSize = sizeof_pool_memory(g_pWin32ConvUCS2Cache);
+         *pszUCS = check_pool_memory_size(*pszUCS, nBufSize);      
+         wcscpy((LPWSTR) *pszUCS, (LPWSTR) g_pWin32ConvUCS2Cache);
+         V(Win32Convmutex);
+         return nBufSize / sizeof (WCHAR);
+      }
+   }
+
    /* helper to convert from utf-8 to UCS-2 and to complete a path for 32K path syntax */
    int nRet = UTF8_2_wchar(pszUCS, pszUTF);
 
@@ -360,38 +432,44 @@ make_win32_path_UTF8_2_wchar(POOLMEM **pszUCS, const char *pszUTF, BOOL* pBIsRaw
       *pBIsRawPath = FALSE;
 #endif
 
+   /* populate cache */      
+   g_pWin32ConvUCS2Cache = check_pool_memory_size(g_pWin32ConvUCS2Cache, sizeof_pool_memory(*pszUCS));
+   wcscpy((LPWSTR) g_pWin32ConvUCS2Cache, (LPWSTR) *pszUCS);
+   
+   g_dwWin32ConvUTF8strlen = strlen(pszUTF);
+   g_pWin32ConvUTF8Cache = check_pool_memory_size(g_pWin32ConvUTF8Cache, g_dwWin32ConvUTF8strlen+1);
+   bstrncpy(g_pWin32ConvUTF8Cache, pszUTF, g_dwWin32ConvUTF8strlen+1);
+   V(Win32Convmutex);
+
    return nRet;
 }
 
-#ifndef HAVE_VC8
+#if !defined(_MSC_VER) || (_MSC_VER < 1400) // VC8+
 int umask(int)
 {
    return 0;
 }
 #endif
 
-int chmod(const char *, mode_t)
+int fcntl(int fd, int cmd)
 {
    return 0;
 }
 
-int chown(const char *k, uid_t, gid_t)
+int chmod(const char *, mode_t)
 {
    return 0;
 }
 
-int lchown(const char *k, uid_t, gid_t)
+int chown(const char *k, uid_t, gid_t)
 {
    return 0;
 }
 
-#ifdef needed
-bool fstype(const char *fname, char *fs, int fslen)
+int lchown(const char *k, uid_t, gid_t)
 {
-   return true;                       /* accept anything */
+   return 0;
 }
-#endif
-
 
 long int
 random(void)
@@ -410,16 +488,16 @@ srandom(unsigned int seed)
 void
 cvt_utime_to_ftime(const time_t  &time, FILETIME &wintime)
 {
-    uint64_t mstime = time;
-    mstime *= WIN32_FILETIME_SCALE;
-    mstime += WIN32_FILETIME_ADJUST;
+   uint64_t mstime = time;
+   mstime *= WIN32_FILETIME_SCALE;
+   mstime += WIN32_FILETIME_ADJUST;
 
-    #ifdef HAVE_MINGW
-    wintime.dwLowDateTime = (DWORD)(mstime & 0xffffffffUL);
-    #else
-    wintime.dwLowDateTime = (DWORD)(mstime & 0xffffffffI64);
-    #endif
-    wintime.dwHighDateTime = (DWORD) ((mstime>>32)& 0xffffffffUL);
+#if defined(_MSC_VER)
+   wintime.dwLowDateTime = (DWORD)(mstime & 0xffffffffI64);
+#else
+   wintime.dwLowDateTime = (DWORD)(mstime & 0xffffffffUL);
+#endif
+   wintime.dwHighDateTime = (DWORD) ((mstime>>32)& 0xffffffffUL);
 }
 
 time_t
@@ -479,7 +557,7 @@ statDir(const char *file, struct stat *sb)
    FILETIME* pftCreationTime;
 
    if (file[1] == ':' && file[2] == 0) {
-        d_msg(__FILE__, __LINE__, 99, "faking ROOT attrs(%s).\n", file);
+        Dmsg1(99, "faking ROOT attrs(%s).\n", file);
         sb->st_mode = S_IFDIR;
         sb->st_mode |= S_IREAD|S_IEXEC|S_IWRITE;
         time(&sb->st_ctime);
@@ -518,7 +596,7 @@ statDir(const char *file, struct stat *sb)
 
     if (h == INVALID_HANDLE_VALUE) {
         const char *err = errorString();
-        d_msg(__FILE__, __LINE__, 99, "FindFirstFile(%s):%s\n", file, err);
+        Dmsg2(99, "FindFirstFile(%s):%s\n", file, err);
         LocalFree((void *)err);
         errno = b_errno_win32;
         return -1;
@@ -547,10 +625,53 @@ statDir(const char *file, struct stat *sb)
     return 0;
 }
 
+int
+fstat(int fd, struct stat *sb)
+{
+    BY_HANDLE_FILE_INFORMATION info;
+    char tmpbuf[1024];
+
+    if (!GetFileInformationByHandle((HANDLE)fd, &info)) {
+        const char *err = errorString();
+        Dmsg2(99, "GetfileInformationByHandle(%s): %s\n", tmpbuf, err);
+        LocalFree((void *)err);
+        errno = b_errno_win32;
+        return -1;
+    }
+
+    sb->st_dev = info.dwVolumeSerialNumber;
+    sb->st_ino = info.nFileIndexHigh;
+    sb->st_ino <<= 32;
+    sb->st_ino |= info.nFileIndexLow;
+    sb->st_nlink = (short)info.nNumberOfLinks;
+    if (sb->st_nlink > 1) {
+       Dmsg1(99,  "st_nlink=%d\n", sb->st_nlink);
+    }
+
+    sb->st_mode = 0777;               /* start with everything */
+    if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+        sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
+    if (info.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
+        sb->st_mode &= ~S_IRWXO; /* remove everything for other */
+    if (info.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+        sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */
+    sb->st_mode |= S_IFREG;
+
+    sb->st_size = info.nFileSizeHigh;
+    sb->st_size <<= 32;
+    sb->st_size |= info.nFileSizeLow;
+    sb->st_blksize = 4096;
+    sb->st_blocks = (uint32_t)(sb->st_size + 4095)/4096;
+    sb->st_atime = cvt_ftime_to_utime(info.ftLastAccessTime);
+    sb->st_mtime = cvt_ftime_to_utime(info.ftLastWriteTime);
+    sb->st_ctime = cvt_ftime_to_utime(info.ftCreationTime);
+
+    return 0;
+}
+
 static int
 stat2(const char *file, struct stat *sb)
 {
-    BY_HANDLE_FILE_INFORMATION info;
     HANDLE h;
     int rval = 0;
     char tmpbuf[1024];
@@ -568,10 +689,9 @@ stat2(const char *file, struct stat *sb)
        attr = p_GetFileAttributesA(tmpbuf);
     }
 
-    if (attr == -1) {
+    if (attr == (DWORD)-1) {
         const char *err = errorString();
-        d_msg(__FILE__, __LINE__, 99,
-              "GetFileAttributes(%s): %s\n", tmpbuf, err);
+        Dmsg2(99, "GetFileAttributes(%s): %s\n", tmpbuf, err);
         LocalFree((void *)err);
         errno = b_errno_win32;
         return -1;
@@ -585,53 +705,15 @@ stat2(const char *file, struct stat *sb)
 
     if (h == INVALID_HANDLE_VALUE) {
         const char *err = errorString();
-        d_msg(__FILE__, __LINE__, 99,
-              "Cannot open file for stat (%s):%s\n", tmpbuf, err);
+        Dmsg2(99, "Cannot open file for stat (%s):%s\n", tmpbuf, err);
         LocalFree((void *)err);
-        rval = -1;
         errno = b_errno_win32;
-        goto error;
-    }
-
-    if (!GetFileInformationByHandle(h, &info)) {
-        const char *err = errorString();
-        d_msg(__FILE__, __LINE__, 99,
-              "GetfileInformationByHandle(%s): %s\n", tmpbuf, err);
-        LocalFree((void *)err);
-        rval = -1;
-        errno = b_errno_win32;
-        goto error;
-    }
-
-    sb->st_dev = info.dwVolumeSerialNumber;
-    sb->st_ino = info.nFileIndexHigh;
-    sb->st_ino <<= 32;
-    sb->st_ino |= info.nFileIndexLow;
-    sb->st_nlink = (short)info.nNumberOfLinks;
-    if (sb->st_nlink > 1) {
-       d_msg(__FILE__, __LINE__, 99,  "st_nlink=%d\n", sb->st_nlink);
+        return -1;
     }
 
-    sb->st_mode = 0777;               /* start with everything */
-    if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
-        sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
-    if (info.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
-        sb->st_mode &= ~S_IRWXO; /* remove everything for other */
-    if (info.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
-        sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */
-    sb->st_mode |= S_IFREG;
-
-    sb->st_size = info.nFileSizeHigh;
-    sb->st_size <<= 32;
-    sb->st_size |= info.nFileSizeLow;
-    sb->st_blksize = 4096;
-    sb->st_blocks = (uint32_t)(sb->st_size + 4095)/4096;
-    sb->st_atime = cvt_ftime_to_utime(info.ftLastAccessTime);
-    sb->st_mtime = cvt_ftime_to_utime(info.ftLastWriteTime);
-    sb->st_ctime = cvt_ftime_to_utime(info.ftCreationTime);
-
-error:
+    rval = fstat((int)h, sb);
     CloseHandle(h);
     return rval;
 }
 
@@ -698,6 +780,28 @@ stat(const char *file, struct stat *sb)
    return 0;
 }
 
+int fcntl(int fd, int cmd, long arg)
+{
+   int rval = 0;
+
+   switch (cmd) {
+   case F_GETFL:
+      rval = O_NONBLOCK;
+      break;
+
+   case F_SETFL:
+      rval = 0;
+      break;
+
+   default:
+      errno = EINVAL;
+      rval = -1;
+      break;
+   }
+
+   return rval;
+}
+
 int
 lstat(const char *file, struct stat *sb)
 {
@@ -778,23 +882,24 @@ strcasecmp(const char *s1, const char *s2)
 int
 strncasecmp(const char *s1, const char *s2, int len)
 {
-    register int ch1, ch2;
+   register int ch1 = 0, ch2 = 0;
 
-    if (s1==s2)
-        return 0;       /* strings are equal if same object. */
-    else if (!s1)
-        return -1;
-    else if (!s2)
-        return 1;
-    while (len--) {
-        ch1 = *s1;
-        ch2 = *s2;
-        s1++;
-        s2++;
-        if (ch1 == 0 || tolower(ch1) != tolower(ch2)) break;
-    }
+   if (s1==s2)
+      return 0;       /* strings are equal if same object. */
+   else if (!s1)
+      return -1;
+   else if (!s2)
+      return 1;
 
-    return (ch1 - ch2);
+   while (len--) {
+      ch1 = *s1;
+      ch2 = *s2;
+      s1++;
+      s2++;
+      if (ch1 == 0 || tolower(ch1) != tolower(ch2)) break;
+   }
+
+   return (ch1 - ch2);
 }
 
 int
@@ -825,14 +930,17 @@ gettimeofday(struct timeval *tv, struct timezone *)
 }
 
 /* For apcupsd this is in src/lib/wincompat.c */
-#ifndef __APCUPSD__
 extern "C" void syslog(int type, const char *fmt, ...) 
 {
 /*#ifndef HAVE_CONSOLE
     MessageBox(NULL, msg, "Bacula", MB_OK);
 #endif*/
 }
-#endif
+
+void
+closelog()
+{
+}
 
 struct passwd *
 getpwuid(uid_t)
@@ -870,6 +978,7 @@ opendir(const char *path)
        return NULL;
     }
 
+    Dmsg1(100, "Opendir path=%s\n", path);
     rval = (_dir *)malloc(sizeof(_dir));
     memset (rval, 0, sizeof (_dir));
     if (rval == NULL) return NULL;
@@ -880,6 +989,7 @@ opendir(const char *path)
 #ifdef WIN32_VSS
        /* will append \\?\ at front itself */
        conv_unix_to_win32_path(path, tspec, max_len-4);
+       Dmsg1(100, "win32 path=%s\n", tspec);
 #else
        /* allow path to be 32767 bytes */
        tspec[0] = '\\';
@@ -888,9 +998,11 @@ opendir(const char *path)
        tspec[3] = '\\';
        tspec[4] = 0;
        conv_unix_to_win32_path(path, tspec+4, max_len-4);
+       Dmsg1(100, "win32 path=%s\n", tspec);
 #endif
     } else {
        conv_unix_to_win32_path(path, tspec, max_len);
+       Dmsg1(100, "win32 path=%s\n", tspec);
     }
 
     // add backslash only if there is none yet (think of c:\)
@@ -904,7 +1016,7 @@ opendir(const char *path)
     // convert to wchar_t
     if (p_FindFirstFileW) {
       POOLMEM* pwcBuf = get_pool_memory(PM_FNAME);;
-      make_win32_path_UTF8_2_wchar(&pwcBuf,rval->spec);
+      make_win32_path_UTF8_2_wchar(&pwcBuf, rval->spec);
 
       rval->dirh = p_FindFirstFileW((LPCWSTR)pwcBuf, &rval->data_w);
 
@@ -920,21 +1032,20 @@ opendir(const char *path)
     } else goto err;
 
 
-    d_msg(__FILE__, __LINE__,
-          99, "opendir(%s)\n\tspec=%s,\n\tFindFirstFile returns %d\n",
+    Dmsg3(99, "opendir(%s)\n\tspec=%s,\n\tFindFirstFile returns %d\n",
           path, rval->spec, rval->dirh);
 
     rval->offset = 0;
     if (rval->dirh == INVALID_HANDLE_VALUE)
         goto err;
 
-    if (rval->valid_w)
-      d_msg(__FILE__, __LINE__,
-            99, "\tFirstFile=%s\n", rval->data_w.cFileName);
+    if (rval->valid_w) {
+      Dmsg1(99, "\tFirstFile=%s\n", rval->data_w.cFileName);
+    }
 
-    if (rval->valid_a)
-      d_msg(__FILE__, __LINE__,
-            99, "\tFirstFile=%s\n", rval->data_a.cFileName);
+    if (rval->valid_a) {
+      Dmsg1(99, "\tFirstFile=%s\n", rval->data_a.cFileName);
+    }
 
     return (DIR *)rval;
 
@@ -1001,11 +1112,10 @@ readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
       }
 
       *result = entry;              /* return entry address */
-      d_msg(__FILE__, __LINE__,
-            99, "readdir_r(%p, { d_name=\"%s\", d_reclen=%d, d_off=%d\n",
+      Dmsg4(99, "readdir_r(%p, { d_name=\"%s\", d_reclen=%d, d_off=%d\n",
             dirp, entry->d_name, entry->d_reclen, entry->d_off);
     } else {
-//      d_msg(__FILE__, __LINE__, 99, "readdir_r !valid\n");
+//      Dmsg0(99, "readdir_r !valid\n");
         errno = b_errno_win32;
         return -1;
     }
@@ -1373,7 +1483,7 @@ winver::winver(void)
         }
 
     bstrncpy(WIN_VERSION_LONG, version, sizeof(WIN_VERSION_LONG));
-    snprintf(WIN_VERSION, sizeof(WIN_VERSION), "%s %d.%d.%d",
+    snprintf(WIN_VERSION, sizeof(WIN_VERSION), "%s %lu.%lu.%lu",
              platform, osvinfo.dwMajorVersion, osvinfo.dwMinorVersion, osvinfo.dwBuildNumber);
 
 #if 0
@@ -1504,8 +1614,7 @@ CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err)
     if (bFuncRetn == 0) {
         ErrorExit("CreateProcess failed\n");
         const char *err = errorString();
-        d_msg(__FILE__, __LINE__, 99,
-              "CreateProcess(%s, %s, ...)=%s\n", exeFile, cmdLine, err);
+        Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n", exeFile, cmdLine, err);
         LocalFree((void *)err);
         return INVALID_HANDLE_VALUE;
     }
@@ -1520,7 +1629,7 @@ CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err)
 void
 ErrorExit (LPCSTR lpszMessage)
 {
-    d_msg(__FILE__, __LINE__, 0, "%s", lpszMessage);
+    Dmsg1(0, "%s", lpszMessage);
 }
 
 
@@ -1542,7 +1651,6 @@ CloseIfValid(HANDLE handle)
         CloseHandle(handle);
 }
 
-#ifndef HAVE_MINGW
 BPIPE *
 open_bpipe(char *prog, int wait, const char *mode)
 {
@@ -1668,7 +1776,6 @@ cleanup:
     return NULL;
 }
 
-#endif //HAVE_MINGW
 
 int
 kill(int pid, int signal)
@@ -1682,7 +1789,6 @@ kill(int pid, int signal)
    return rval;
 }
 
-#ifndef HAVE_MINGW
 
 int
 close_bpipe(BPIPE *bpipe)
@@ -1698,8 +1804,7 @@ close_bpipe(BPIPE *bpipe)
       if (!GetExitCodeProcess((HANDLE)bpipe->worker_pid, &exitCode)) {
          const char *err = errorString();
          rval = b_errno_win32;
-         d_msg(__FILE__, __LINE__, 0,
-               "GetExitCode error %s\n", err);
+         Dmsg1(0, "GetExitCode error %s\n", err);
          LocalFree((void *)err);
          break;
       }
@@ -1783,8 +1888,7 @@ utime(const char *fname, struct utimbuf *times)
 
     if (h == INVALID_HANDLE_VALUE) {
         const char *err = errorString();
-        d_msg(__FILE__, __LINE__, 99,
-              "Cannot open file \"%s\" for utime(): ERR=%s", tmpbuf, err);
+        Dmsg2(99, "Cannot open file \"%s\" for utime(): ERR=%s", tmpbuf, err);
         LocalFree((void *)err);
         errno = b_errno_win32;
         return -1;
@@ -1798,67 +1902,9 @@ utime(const char *fname, struct utimbuf *times)
     return rval;
 }
 
-#if USE_WIN32_COMPAT_IO
-
-int
-open(const char *file, int flags, int mode)
-{
-   if (p_wopen) {
-      POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
-      make_win32_path_UTF8_2_wchar(&pwszBuf, file);
-
-      int nRet = p_wopen((LPCWSTR) pwszBuf, flags|_O_BINARY, mode);
-      free_pool_memory(pwszBuf);
-
-      return nRet;
-   }
-
-   return _open(file, flags|_O_BINARY, mode);
-}
-
-/*
- * Note, this works only for a file. If you want
- *   to close a socket, use closesocket().
- *   Bacula has been modified in src/lib/bnet.c
- *   to use closesocket().
- */
-#ifndef HAVE_VC8
-int
-close(int fd)
-{
-    return _close(fd);
-}
-
-#ifndef HAVE_WXCONSOLE
-ssize_t
-read(int fd, void *buf, ssize_t len)
-{
-    return _read(fd, buf, (size_t)len);
-}
-
-ssize_t
-write(int fd, const void *buf, ssize_t len)
-{
-    return _write(fd, buf, (size_t)len);
-}
-#endif
-
-
-off_t
-lseek(int fd, off_t offset, int whence)
-{
-    return (off_t)_lseeki64(fd, offset, whence);
-}
-
-int
-dup2(int fd1, int fd2)
-{
-    return _dup2(fd1, fd2);
-}
-#endif
-#else
+#if 0
 int
-open(const char *file, int flags, int mode)
+file_open(const char *file, int flags, int mode)
 {
     DWORD access = 0;
     DWORD shareMode = 0;
@@ -1871,13 +1917,18 @@ open(const char *file, int flags, int mode)
     else if (flags & O_RDWR) access = GENERIC_READ|GENERIC_WRITE;
     else access = GENERIC_READ;
 
-    if (flags & O_CREAT) create = CREATE_NEW;
-    else create = OPEN_EXISTING;
+    if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
+       create = CREATE_NEW;
+    else if ((flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
+       create = CREATE_ALWAYS;
+    else if (flags & O_CREAT)
+       create = OPEN_ALWAYS;
+    else if (flags & O_TRUNC)
+       create = TRUNCATE_EXISTING;
+    else 
+       create = OPEN_EXISTING;
 
-    if (flags & O_TRUNC) create = TRUNCATE_EXISTING;
-
-    if (!(flags & O_EXCL))
-        shareMode = FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE;
+    shareMode = 0;
 
     if (flags & O_APPEND) {
         printf("open...APPEND not implemented yet.");
@@ -1886,7 +1937,7 @@ open(const char *file, int flags, int mode)
 
     if (p_CreateFileW) {
        POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
-       make_win32_path_UTF8_2_wchar(pwszBuf, file);
+       make_win32_path_UTF8_2_wchar(&pwszBuf, file);
 
        foo = p_CreateFileW((LPCWSTR) pwszBuf, access, shareMode, NULL, create, msflags, NULL);
        free_pool_memory(pwszBuf);
@@ -1903,7 +1954,7 @@ open(const char *file, int flags, int mode)
 
 
 int
-close(int fd)
+file_close(int fd)
 {
     if (!CloseHandle((HANDLE)fd)) {
         errno = b_errno_win32;
@@ -1914,7 +1965,7 @@ close(int fd)
 }
 
 ssize_t
-write(int fd, const void *data, ssize_t len)
+file_write(int fd, const void *data, ssize_t len)
 {
     BOOL status;
     DWORD bwrite;
@@ -1926,7 +1977,7 @@ write(int fd, const void *data, ssize_t len)
 
 
 ssize_t
-read(int fd, void *data, ssize_t len)
+file_read(int fd, void *data, ssize_t len)
 {
     BOOL status;
     DWORD bread;
@@ -1938,7 +1989,7 @@ read(int fd, void *data, ssize_t len)
 }
 
 off_t
-lseek(int fd, off_t offset, int whence)
+file_seek(int fd, off_t offset, int whence)
 {
     DWORD method = 0;
     DWORD val;
@@ -1966,27 +2017,14 @@ lseek(int fd, off_t offset, int whence)
 }
 
 int
-dup2(int, int)
+file_dup2(int, int)
 {
     errno = ENOSYS;
     return -1;
 }
-
-
 #endif
 
-#endif //HAVE_MINGW
-
 #ifdef HAVE_MINGW
 /* syslog function, added by Nicolas Boichat */
-void closelog() {}
 void openlog(const char *ident, int option, int facility) {}  
 #endif //HAVE_MINGW
-
-/* Temp kludges ***FIXME**** */
-#ifdef __APCUPSD__
-unsigned int alarm(unsigned int seconds) 
-{
-   return 0;
-}
-#endif