#define MODE_RW 0666
 #endif
 
-#ifdef DEBUG_MUTEX
+#if defined(HAVE_WIN32)
+typedef int64_t   boffset_t;
+#else
+typedef off_t     boffset_t;
+#endif
+
+#if defined(DEBUG_MUTEX)
 extern void _p(char *file, int line, pthread_mutex_t *m);
 extern void _v(char *file, int line, pthread_mutex_t *m);
 
 #define REPLACE_NEVER    'n'
 #define REPLACE_IFOLDER  'o'
 
-/* This probably should be done on a machine by machine basic, but it works */
+/* This probably should be done on a machine by machine basis, but it works */
 /* This is critical for the smartalloc routines to properly align memory */
 #define ALIGN_SIZE (sizeof(double))
 #define BALIGN(x) (((x) + ALIGN_SIZE - 1) & ~(ALIGN_SIZE -1))
 #endif
 
 
+#if defined(HAVE_WIN32)
+#define DEFAULT_CONFIGDIR "C:\\Documents and Settings\\All Users\\Application Data\\Bacula"
+
+inline bool IsPathSeparator(int ch) { return ch == '/' || ch == '\\'; }
+inline char *first_path_separator(char *path) { return strpbrk(path, ":/\\"); }
+inline const char *first_path_separator(const char *path) { return strpbrk(path, ":/\\"); }
+
+#else
 /* Define Winsock functions if we aren't on Windows */
-#if !defined HAVE_WIN32
+
 #define WSA_Init() 0 /* 0 = success */
 #define WSACleanup() 0 /* 0 = success */
-#endif
 
-#ifdef HAVE_AIX_OS
+inline bool IsPathSeparator(int ch) { return ch == '/'; }
+inline char *first_path_separator(char *path) { return strchr(path, '/'); }
+inline const char *first_path_separator(const char *path) { return strchr(path, '/'); }
 #endif
 
+
 /* HP-UX 11 specific workarounds */
 
 #ifdef HAVE_HPUX_OS
 #endif
 
 
-/* Added by KES to deal with Win32 systems */
-#ifndef S_ISWIN32
-#define S_ISWIN32 020000
-#endif
-
-
 /* Disabled because it breaks internationalisation...
 #undef HAVE_SETLOCALE
 #ifdef HAVE_SETLOCALE
 
    POOLMEM *dbf;
 
    dbf = get_pool_memory(PM_FNAME);
-   if (working_directory[strlen(working_directory)-1] == '/') {
+   if (IsPathSeparator(working_directory[strlen(working_directory)-1])) {
       sep = 0;
    } else {
       sep = '/';
 
     * must be a path name (e.g. c:).
     */
    for (p=f=fname; *p; p++) {
-      if (*p == '/') {
+      if (IsPathSeparator(*p)) {
          f = p;                       /* set pos of last slash */
       }
    }
-   if (*f == '/') {                   /* did we find a slash? */
+   if (IsPathSeparator(*f)) {                   /* did we find a slash? */
       f++;                            /* yes, point to filename */
    } else {                           /* no, whole thing must be path name */
       f = p;
 
             res_incexe.current_opts->wilddir.append(bstrdup(lc->str));
             newsize = res_incexe.current_opts->wilddir.size();
          } else if (item->code == 2) {
-            if (strchr(lc->str, '/') != NULL) {
+            if (strpbrk(lc->str, "/\\") != NULL) {
                type = "wildfile";
                res_incexe.current_opts->wildfile.append(bstrdup(lc->str));
                newsize = res_incexe.current_opts->wildfile.size();
 
                break;
             }
             /* Add trailing slash to end of directory names */
-            if (ua->cmd[0] != '<' && ua->cmd[len-1] != '/') {
+            if (ua->cmd[0] != '<' && !IsPathSeparator(ua->cmd[len-1])) {
                strcat(ua->cmd, "/");
             }
             insert_one_file_or_dir(ua, rx, date, true);
     * must be a path name (e.g. c:).
     */
    for (p=f=name; *p; p++) {
-      if (*p == '/') {
+      if (IsPathSeparator(*p)) {
          f = p;                       /* set pos of last slash */
       }
    }
-   if (*f == '/') {                   /* did we find a slash? */
+   if (IsPathSeparator(*f)) {         /* did we find a slash? */
       f++;                            /* yes, point to filename */
    } else {                           /* no, whole thing must be path name */
       f = p;
 
             free(jcr->where);
             jcr->where = NULL;
          }
-         if (ua->cmd[0] == '/' && ua->cmd[1] == 0) {
+         if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
             ua->cmd[0] = 0;
          }
          jcr->where = bstrdup(ua->cmd);
 
 
 // Dmsg4(000, "Path=%s%s FI=%s JobId=%s\n", row[0], row[1],
 //    row[2], row[3]);
-   if (*row[1] == 0) {                /* no filename => directory */
-      if (*row[0] != '/') {           /* Must be Win32 directory */
+   if (*row[1] == 0) {                 /* no filename => directory */
+      if (!IsPathSeparator(*row[0])) { /* Must be Win32 directory */
          type = TN_DIR_NLS;
       } else {
          type = TN_DIR;
 
       return EXIT_FAILURE;
    }
 
-   prgname = strrchr(argv[0], '/');
+   prgname = last_path_separator(argv[0]);
    if (prgname == NULL || *++prgname == '\0') {
       prgname = argv[0];
    }
 
 #ifdef HAVE_LIBZ
       /* Do compression if turned on */
       if (!sparseBlock && (ff_pkt->flags & FO_GZIP) && jcr->pZLIB_compress_workset) {
-         Dmsg4(400, "cbuf=0x%x len=%u rbuf=0x%x len=%u\n", cbuf, compress_len,
-            rbuf, sd->msglen);
+         Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
          
          ((z_stream*)jcr->pZLIB_compress_workset)->next_in   = (Bytef *)rbuf;
                 ((z_stream*)jcr->pZLIB_compress_workset)->avail_in  = sd->msglen;
 
       if (!sparseBlock && (ff_pkt->flags & FO_ENCRYPT)) {
          uint32_t initial_len = 0;
+         ser_declare;
 
          if (ff_pkt->flags & FO_SPARSE) {
             cipher_input_len += SPARSE_FADDR_SIZE;
          }
 
          /* Encrypt the length of the input block */
-         uint32_t packet_len = htonl(cipher_input_len);
+         uint8_t packet_len[sizeof(uint32_t)];
+
+         ser_begin(packet_len, sizeof(uint32_t));
+         ser_uint32(cipher_input_len);    /* store fileAddr in begin of buffer */
 
-         if (!crypto_cipher_update(cipher_ctx, (const u_int8_t *)&packet_len, 
-              sizeof(packet_len), (u_int8_t *)jcr->crypto_buf, &initial_len)) {
+         if (!crypto_cipher_update(cipher_ctx, packet_len, sizeof(packet_len),
+                  (u_int8_t *)jcr->crypto_buf, &initial_len)) {
             /* Encryption failed. Shouldn't happen. */
             Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
             goto err;
 
       *where = 0;
    }
    /* Turn / into nothing */
-   if (where[0] == '/' && where[1] == 0) {
-      where[0] = 0;
+   if (IsPathSeparator(where[0]) && where[1] == '\0') {
+      where[0] = '\0';
    }
 
    Dmsg2(150, "Got replace %c, where=%s\n", replace, where);
 
  * Close a bfd check that we are at the expected file offset.
  * Makes some code in set_attributes().
  */
-int bclose_chksize(JCR *jcr, BFILE *bfd, off_t osize)
+int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
 {
    char ec1[50], ec2[50];
-   off_t fsize;
+   boffset_t fsize;
 
    fsize = blseek(bfd, 0, SEEK_CUR);
    bclose(bfd);                              /* first close file */
 
    if (flags & FO_ENCRYPT) {
       ASSERT(cipher);
+      unser_declare;
 
       while (jcr->crypto_size > 0 && jcr->crypto_count > 0 && wsize > 0) {
          uint32_t chunk_size = 16;
       jcr->crypto_count += decrypted_len;
 
       if (jcr->crypto_size == 0 && jcr->crypto_count >= 4) {
-         jcr->crypto_size = ntohl(*(uint32_t *)&jcr->crypto_buf[0]) + 4;
+         unser_begin(&jcr->crypto_buf[0], sizeof(uint32_t));
+         unser_uint32(jcr->crypto_size);
+         jcr->crypto_size += 4;
       }
 
       if (jcr->crypto_size == 0 || jcr->crypto_count < jcr->crypto_size) {
    }
 
    if (flags & FO_SPARSE) {
-      ser_declare;
+      unser_declare;
       uint64_t faddr;
       char ec1[50];
-      ser_begin(wbuf, SPARSE_FADDR_SIZE);
+      unser_begin(wbuf, SPARSE_FADDR_SIZE);
       unser_uint64(faddr);
       if (*addr != faddr) {
          *addr = faddr;
-         if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) {
+         if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
             berrno be;
             Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
                   edit_uint64(*addr, ec1), jcr->last_fname, 
 
          edit_uint64_with_commas(sm_buffers, b3),
          edit_uint64_with_commas(sm_max_buffers, b4));
    sendit(msg, len, arg);
-   len = Mmsg(msg, _(" Sizeof: off_t=%d size_t=%d debug=%d trace=%d\n"),
-         sizeof(off_t), sizeof(size_t), debug_level, get_trace());
+   len = Mmsg(msg, _(" Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d\n"),
+         sizeof(boffset_t), sizeof(size_t), debug_level, get_trace());
    sendit(msg, len, arg);
 
    /*
 
    struct utimbuf ut;
    mode_t old_mask;
    bool ok = true;
-   off_t fsize;
+   boffset_t fsize;
 
 #if defined(HAVE_WIN32)
    if (attr->stream == STREAM_UNIX_ATTRIBUTES_EX &&
       char ec1[50], ec2[50];
       fsize = blseek(ofd, 0, SEEK_END);
       bclose(ofd);                    /* first close file */
-      if (attr->type == FT_REG && fsize > 0 && fsize != (off_t)attr->statp.st_size) {
+      if (attr->type == FT_REG && fsize > 0 && fsize != (boffset_t)attr->statp.st_size) {
          Jmsg3(jcr, M_ERROR, 0, _("File size of restored file %s not correct. Original %s, restored %s.\n"),
             attr->ofname, edit_uint64(attr->statp.st_size, ec1),
             edit_uint64(fsize, ec2));
 
 
 
 bool processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, ssize_t dwSize)
-{   
+{
    /* pByte contains the buffer 
       dwSize the len to be processed.  function assumes to be
       called in successive incremental order over the complete
     */
    int32_t dwSizeHeader = 20; 
 
-   do {               
-      if (pContext->liNextHeader >= dwSize) {                        
+   do {
+      if (pContext->liNextHeader >= dwSize) {
          dwDataLen = dwSize-dwDataOffset;
          bContinue = false; /* 1 iteration is enough */
-      }
-      else {                        
+      } else {
          dwDataLen = pContext->liNextHeader-dwDataOffset;
          bContinue = true; /* multiple iterations may be necessary */
       }
       /* copy block of real DATA */
       if (pContext->bIsInData) {
          if (bwrite(bfd, ((char *)pBuffer)+dwDataOffset, dwDataLen) != (ssize_t)dwDataLen)
-            return false;         
+            return false;
       }
 
       if (pContext->liNextHeader < dwSize) {/* is a header in this block ? */
          int32_t dwOffsetTarget;
          int32_t dwOffsetSource;
-            
+
          if (pContext->liNextHeader < 0) {
             /* start of header was before this block, so we
              * continue with the part in the current block 
              */
-            dwOffsetTarget = -pContext->liNextHeader;        
-            dwOffsetSource = 0;                            
+            dwOffsetTarget = -pContext->liNextHeader;
+            dwOffsetSource = 0;
          } else {
             /* start of header is inside of this block */
             dwOffsetTarget = 0;
-            dwOffsetSource = pContext->liNextHeader;                        
+            dwOffsetSource = pContext->liNextHeader;
          }
 
          int32_t dwHeaderPartLen = dwSizeHeader-dwOffsetTarget;
          bool bHeaderIsComplete;
 
-         if (dwHeaderPartLen <= dwSize-dwOffsetSource) 
+         if (dwHeaderPartLen <= dwSize-dwOffsetSource) {
             /* header (or rest of header) is completely available
                in current block 
              */
             bHeaderIsComplete = true;
-         else  {
+         } else {
             /* header will continue in next block */
             bHeaderIsComplete = false;
             dwHeaderPartLen = dwSize-dwOffsetSource;
             int32_t dwNameSize; 
             int32_LE2BE (&dwNameSize, pContext->header_stream.dwStreamNameSize);
             dwDataOffset = dwNameSize+pContext->liNextHeader+dwSizeHeader;
-            
+
             /* convert stream size (64 bit little endian) to machine type */
             int64_LE2BE (&(pContext->liNextHeader), pContext->header_stream.Size);
             pContext->liNextHeader += dwDataOffset;
 
             pContext->bIsInData = pContext->header_stream.dwStreamId == WIN32_BACKUP_DATA;
             if (dwDataOffset == dwSize)
-                  bContinue = false;
-         }
-         else {
+               bContinue = false;
+         } else {
             /* stop and continue with next block */
             bContinue = false;
             pContext->bIsInData = false;
          }
-      }                
-   } while (bContinue);    
+      }
+   } while (bContinue);
 
    /* set "NextHeader" relative to the beginning of the next block */
    pContext->liNextHeader-= dwSize;
 extern "C" HANDLE get_osfhandle(int fd);
 
 
-
 void binit(BFILE *bfd)
 {
    memset(bfd, 0, sizeof(BFILE));
 }
 
 
-
 /*
  * Return true  if we support the stream
  *        false if we do not support the stream
    if (!(p_CreateFileA || p_CreateFileW))
       return 0;
 
-   if (p_CreateFileW && p_MultiByteToWideChar)               
+   if (p_CreateFileW && p_MultiByteToWideChar)
       make_win32_path_UTF8_2_wchar(&win32_fname_wchar, fname);
 
    if (flags & O_CREAT) {             /* Create */
    return bfd->mode != BF_CLOSED;
 }
 
-off_t blseek(BFILE *bfd, off_t offset, int whence)
+boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
 {
-   /* ****FIXME**** this must be implemented if we want to read Win32 Archives */
-   return -1;
+   LONG  offset_low = (LONG)offset;
+   LONG  offset_high = (LONG)(offset >> 32);
+   DWORD dwResult;
+
+   dwResult = SetFilePointer(bfd->fh, offset_low, &offset_high, whence);
+
+   if (dwResult == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
+      return (boffset_t)-1;
+   }
+
+   return ((boffset_t)offset_high << 32) | dwResult;
 }
 
 #else  /* Unix systems */
    return bfd->fid >= 0;
 }
 
-off_t blseek(BFILE *bfd, off_t offset, int whence)
+boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
 {
-    off_t pos;
-    pos = lseek(bfd->fid, offset, whence);
+    boffset_t pos;
+    pos = (boffset_t)lseek(bfd->fid, (off_t)offset, whence);
     bfd->berrno = errno;
     return pos;
 }
 
 int     bclose(BFILE *bfd);
 ssize_t bread(BFILE *bfd, void *buf, size_t count);
 ssize_t bwrite(BFILE *bfd, void *buf, size_t count);
-off_t   blseek(BFILE *bfd, off_t offset, int whence);
+boffset_t blseek(BFILE *bfd, boffset_t offset, int whence);
 const char   *stream_to_ascii(int stream);
 
 bool processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, ssize_t dwSize);
 
             be.set_errno(bfd->berrno);
 #ifdef HAVE_WIN32
             /* Check for trying to create a drive, if so, skip */
-            if (attr->ofname[1] == ':' && attr->ofname[2] == '/' && attr->ofname[3] == 0) {
+            if (attr->ofname[1] == ':' && 
+                IsPathSeparator(attr->ofname[2]) && 
+                attr->ofname[3] == '\0') {
                return CF_SKIP;
             }
 #endif
    /* Separate pathname and filename */
    for (q=p=f=ofile; *p; p++) {
 #ifdef HAVE_WIN32
-      if (*p == '\\' || *p == '/') {
+      if (IsPathSeparator(*p)) {
          f = q;
-         if (p[1] == '\\' || p[1] == '/') {
+         if (IsPathSeparator(p[1])) {
             p++;
          }
       }
       *q++ = *p;                   /* copy data */
 #else
-      if (*p == '/') {
+      if (IsPathSeparator(*p)) {
          f = q;                    /* possible filename */
       }
       q++;
 #endif
    }
 
-   if (*f == '/') {
+   if (IsPathSeparator(*f)) {
       f++;
    }
    *q = 0;                         /* terminate string */
 
 
    if (ff->flags & FO_ENHANCEDWILD) {
       match_func = enh_fnmatch;
-      if ((basename = strrchr(ff->fname, '/')) != NULL)
+      if ((basename = last_path_separator(ff->fname)) != NULL)
          basename++;
       else
          basename = ff->fname;
       basename = ff->fname;
    }
 
-   for (j=0; j<incexe->opts_list.size(); j++) {
+   for (j = 0; j < incexe->opts_list.size(); j++) {
       findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
       ff->flags = fo->flags;
       ff->GZIP_level = fo->GZIP_level;
 
 
    /* This is not a link to a previously dumped file, so dump it.  */
    if (S_ISREG(ff_pkt->statp.st_mode)) {
-      off_t sizeleft;
+      boffset_t sizeleft;
 
       sizeleft = ff_pkt->statp.st_size;
 
       link = (char *)bmalloc(link_len + 2);
       bstrncpy(link, fname, link_len);
       /* Strip all trailing slashes */
-      while (len >= 1 && link[len - 1] == '/')
+      while (len >= 1 && IsPathSeparator(link[len - 1]))
         len--;
       link[len++] = '/';             /* add back one */
       link[len] = 0;
 
 isAbsolute(const char *path)
 {
 #if defined(HAVE_WIN32)
-    return path[1] == ':' || *path == '/' || *path == '\\';     /* drivespec:/blah is absolute */
+    return path[1] == ':' || IsPathSeparator(*path);     /* drivespec:/blah is absolute */
 #else
-    return *path == '/';
+    return IsPathSeparator(*path);
 #endif
 }
 
       }
 
       /* Skip over leading slashes.  */
-#if defined(HAVE_WIN32)
-      while (*slash == '/' || *slash == '\\')
-         slash++;
-#else
-      while (*slash == '/')
+      while (IsPathSeparator(*slash))
          slash++;
-#endif
-      while (1) {
+
+      for ( ; ; ) {
           int newly_created_dir;
           int fail;
 
           /* slash points to the leftmost unprocessed component of dirpath.  */
           basename_dir = slash;
-
-#if defined(HAVE_WIN32)
-          slash = strpbrk(slash, ":/\\");
-          if (slash == NULL) {
-             break;
-          }
-#else
-          slash = strchr (slash, '/');
+          slash = first_path_separator(slash);
           if (slash == NULL) {
              break;
           }
-#endif
 
           /* If we're *not* doing chdir before each mkdir, then we have to refer
              to the target using the full (multi-component) directory name.  */
 
           /* Avoid unnecessary calls to `stat' when given
              pathnames containing multiple adjacent slashes.  */
-#if defined(HAVE_WIN32)
-         while (*slash == '/' || *slash == '\\')
-            slash++;
-#else
-         while (*slash == '/')
+         while (IsPathSeparator(*slash))
             slash++;
-#endif
       } /* end while (1) */
 
       if (!cwd.do_chdir) {
 
    len = strlen(p);
    /* Zap trailing slashes.  */
    p += len - 1;
-   while (p > inc->fname && *p == '/') {
+   while (p > inc->fname && IsPathSeparator(*p)) {
       *p-- = 0;
       len--;
    }
 
    Dmsg1(20, "Add name to exclude: %s\n", fname);
 
-#if defined(HAVE_WIN32)
-   if (strchr(fname, '/') || strchr(fname, '\\')) {
-#else
-   if (strchr(fname, '/')) {
-#endif
+   if (first_path_separator(fname) != NULL) {
       list = &ff->excluded_paths_list;
    } else {
       list = &ff->excluded_files_list;
       if (inc->len == len && strcmp(inc->fname, file) == 0) {
          return 1;
       }
-      if (inc->len < len && file[inc->len] == '/' &&
+      if (inc->len < len && IsPathSeparator(file[inc->len]) &&
           strncmp(inc->fname, file, inc->len) == 0) {
          return 1;
       }
-      if (inc->len == 1 && inc->fname[0] == '/') {
+      if (inc->len == 1 && IsPathSeparator(inc->fname[0])) {
          return 1;
       }
    }
    /* Try each component */
    for (p = file; *p; p++) {
       /* Match from the beginning of a component only */
-      if ((p == file || (*p != '/' && *(p-1) == '/'))
+      if ((p == file || (!IsPathSeparator(*p) && IsPathSeparator(p[-1])))
            && file_in_excluded_list(ff->excluded_files_list, p)) {
          return 1;
       }
 
 {
    char *p = fname;
    while (p && *p) {
-      p = strchr(p, '/');
-      if (p && p[1] == '/') {
-         strcpy(p, p+1);
-      }      
-      if (p) {
+      p = strpbrk(p, "/\\");
+      if (p != NULL) {
+         if (IsPathSeparator(p[1])) {
+            strcpy(p, p+1);
+         }
          p++;
       }
    }
 #endif
       fn = attr->fname;            /* take whole name */
       /* Ensure where is terminated with a slash */
-      if (jcr->where[wherelen-1] != '/' && fn[0] != '/') {
+      if (!IsPathSeparator(jcr->where[wherelen-1]) && !IsPathSeparator(fn[0])) {
          pm_strcat(attr->ofname, "/");
       }
       pm_strcat(attr->ofname, fn); /* copy rest of name */
          /* Always add prefix to hard links (FT_LNKSAVED) and
           *  on user request to soft links
           */
-         if (attr->lname[0] == '/' &&
+         if (IsPathSeparator(attr->lname[0]) &&
              (attr->type == FT_LNKSAVED || jcr->prefix_links)) {
             pm_strcpy(attr->olname, jcr->where);
             add_link = true;
 #endif
          fn = attr->lname;       /* take whole name */
          /* Ensure where is terminated with a slash */
-         if (add_link && jcr->where[wherelen-1] != '/' && fn[0] != '/') {
+         if (add_link && 
+            !IsPathSeparator(jcr->where[wherelen-1]) && 
+            !IsPathSeparator(fn[0])) {
             pm_strcat(attr->olname, "/");
          }
          pm_strcat(attr->olname, fn);     /* copy rest of link */
       }
    }
 #if defined(HAVE_WIN32)
-      strip_double_slashes(attr->ofname);
-      strip_double_slashes(attr->olname);
+   strip_double_slashes(attr->ofname);
+   strip_double_slashes(attr->olname);
 #endif
 }
 
 
         case '?':
           if (*n == '\0')
             return 0;
-          else if ((flags & FNM_FILE_NAME) && *n == '/')
+          else if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
             return 0;
           else if ((flags & FNM_PERIOD) && *n == '.' &&
-                   (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+                   (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
             return 0;
           break;
 
 
         case '*':
           if ((flags & FNM_PERIOD) && *n == '.' &&
-              (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+              (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
             return FNM_NOMATCH;
 
           if ((p - pattern) >= patternlen)
 
           for (c = *p++; ((p - pattern) <= patternlen) && (c == '?' || c == '*'); c = *p++)
             {
-              if ((flags & FNM_FILE_NAME) && *n == '/')
+              if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
                 /* A slash does not match a wildcard under FNM_FILE_NAME.  */
                 return 0;
               else if (c == '?')
                   }
                 else
                   {
-                    if ((flags & FNM_FILE_NAME) && *n == '/')
+                    if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
                       return 0;    /* A slash does not match a wildcard under FNM_FILE_NAME.  */
                   }
 
               return 0;
 
             if ((flags & FNM_PERIOD) && *n == '.' &&
-                (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+                (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
               return 0;
 
             nnot = (*p == '!' || *p == '^');
                 c = *p++;
                 c = FOLD (c);
 
-                if ((flags & FNM_FILE_NAME) && c == '/')
+                if ((flags & FNM_FILE_NAME) && IsPathSeparator(c))
                   /* [/] can never match.  */
                   return 0;
 
   if (string[matchlen] == '\0')
     return 0;
 
-  if ((flags & FNM_LEADING_DIR) && string[matchlen] == '/')
+  if ((flags & FNM_LEADING_DIR) && IsPathSeparator(string[matchlen]))
     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
     return 0;
 
 
         case '?':
           if (*n == '\0')
             return FNM_NOMATCH;
-          else if ((flags & FNM_FILE_NAME) && *n == '/')
+          else if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
             return FNM_NOMATCH;
           else if ((flags & FNM_PERIOD) && *n == '.' &&
-                   (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+                   (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
             return FNM_NOMATCH;
           break;
 
 
         case '*':
           if ((flags & FNM_PERIOD) && *n == '.' &&
-              (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+              (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
             return FNM_NOMATCH;
 
           for (c = *p++; c == '?' || c == '*'; c = *p++)
             {
-              if ((flags & FNM_FILE_NAME) && *n == '/')
+              if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
                 /* A slash does not match a wildcard under FNM_FILE_NAME.  */
                 return FNM_NOMATCH;
               else if (c == '?')
               return FNM_NOMATCH;
 
             if ((flags & FNM_PERIOD) && *n == '.' &&
-                (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+                (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
               return FNM_NOMATCH;
 
             nnot = (*p == '!' || *p == '^');
                 c = *p++;
                 c = FOLD (c);
 
-                if ((flags & FNM_FILE_NAME) && c == '/')
+                if ((flags & FNM_FILE_NAME) && IsPathSeparator(c))
                   /* [/] can never match.  */
                   return FNM_NOMATCH;
 
   if (*n == '\0')
     return 0;
 
-  if ((flags & FNM_LEADING_DIR) && *n == '/')
+  if ((flags & FNM_LEADING_DIR) && IsPathSeparator(*n))
     /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
     return 0;
 
 
 
 char *getuser(uid_t uid, char *name, int len)
 {
-  register struct userid *tail;
-  struct passwd *pwent;
-  char usernum_string[20];
-
-  P(mutex);
-  for (tail = user_alist; tail; tail = tail->next) {
-    if (tail->id.u == uid) {
-      goto uid_done;
-    }
-  }
+   register struct userid *tail;
+   char usernum_string[20];
+
+   P(mutex);
+   for (tail = user_alist; tail; tail = tail->next) {
+      if (tail->id.u == uid) {
+         goto uid_done;
+      }
+   }
+
+   tail = (struct userid *)malloc(sizeof (struct userid));
+   tail->id.u = uid;
+   tail->name = NULL;
+
+#if !defined(HAVE_WIN32)
+   {
+      struct passwd *pwent = getpwuid(uid);
+
+      if (pwent != NULL && strcmp(pwent->pw_name, "????????") != 0) {
+         tail->name = bstrdup(pwent->pw_name);
+      }
+   }
+#endif
 
-  pwent = getpwuid(uid);
-  tail = (struct userid *)malloc(sizeof (struct userid));
-  tail->id.u = uid;
-#ifndef HAVE_WIN32
-  if (pwent == NULL || strcmp(pwent->pw_name, "????????") == 0) {
+   if (tail->name == NULL) {
       sprintf(usernum_string, "%u", (uint32_t)uid);
       tail->name = bstrdup(usernum_string);
-  } else {
-      tail->name = bstrdup(pwent->pw_name);
-  }
-#else
-      sprintf(usernum_string, "%u", (uint32_t)uid);
-      tail->name = bstrdup(usernum_string);
-#endif
+   }
 
-  /* Add to the head of the list, so most recently used is first.  */
-  tail->next = user_alist;
-  user_alist = tail;
+   /* Add to the head of the list, so most recently used is first.  */
+   tail->next = user_alist;
+   user_alist = tail;
 
 uid_done:
-  bstrncpy(name, tail->name, len);
-  V(mutex);
-  return name;
+   bstrncpy(name, tail->name, len);
+   V(mutex);
+   return name;
 }
 
 void free_getuser_cache()
 
 
 /* Translate GID to a group name or a stringified number,
-   with cache. */
+   with cache. */
 char *getgroup(gid_t gid, char *name, int len)
 {
-  register struct userid *tail;
-  struct group *grent;
-  char groupnum_string[20];
-
-  P(mutex);
-  for (tail = group_alist; tail; tail = tail->next) {
-    if (tail->id.g == gid) {
-      goto gid_done;
-    }
-  }
+   register struct userid *tail;
+   char groupnum_string[20];
+
+   P(mutex);
+   for (tail = group_alist; tail; tail = tail->next) {
+      if (tail->id.g == gid) {
+         goto gid_done;
+      }
+   }
+
+   tail = (struct userid *)malloc(sizeof (struct userid));
+   tail->id.g = gid;
+   tail->name = NULL;
+
+#if !defined(HAVE_WIN32)
+   {
+      struct group *grent = getgrgid(gid);
+
+      if (grent != NULL && strcmp(grent->gr_name, "????????") != 0) {
+         tail->name = bstrdup(grent->gr_name);
+      }
+   }
+#endif
 
-  grent = getgrgid(gid);
-  tail = (struct userid *)malloc(sizeof (struct userid));
-  tail->id.g = gid;
-#ifndef HAVE_WIN32
-  if (grent == NULL || strcmp(grent->gr_name, "????????") == 0) {
+   if (tail->name == NULL) {
       sprintf (groupnum_string, "%u", (uint32_t)gid);
       tail->name = bstrdup(groupnum_string);
-  } else {
-      tail->name = bstrdup(grent->gr_name);
-  }
-#else
-      sprintf (groupnum_string, "%u", (uint32_t)gid);
-      tail->name = bstrdup(groupnum_string);
-#endif
-  /* Add to the head of the list, so most recently used is first.  */
-  tail->next = group_alist;
-  group_alist = tail;
+   }
+
+   /* Add to the head of the list, so most recently used is first. */
+   tail->next = group_alist;
+   group_alist = tail;
 
 gid_done:
-  bstrncpy(name, tail->name, len);
-  V(mutex);
-  return name;
+   bstrncpy(name, tail->name, len);
+   V(mutex);
+   return name;
 }
 
 void free_getgroup_cache()
 
    if (argc>0 && argv && argv[0]) {
       /* strip trailing filename and save exepath */
       for (l=p=argv[0]; *p; p++) {
-         if (*p == '/') {
+         if (IsPathSeparator(*p)) {
             l = p;                       /* set pos of last slash */
          }
       }
-      if (*l == '/') {
+      if (IsPathSeparator(*l)) {
          l++;
       } else {
          l = argv[0];
          *q++ = *p++;
       }
       *q = 0;
-      if (strchr(exepath, '.') || exepath[0] != '/') {
+      if (strchr(exepath, '.') || !IsPathSeparator(exepath[0])) {
          if (getcwd(cpath, sizeof(cpath))) {
             free(exepath);
             exepath = (char *)malloc(strlen(cpath) + 1 + len);
 
 const char *get_default_configdir()
 {
 #if defined(HAVE_WIN32)
-#define DEFAULT_CONFIGDIR "C:\\Documents and Settings\\All Users\\Application Data\\Bacula"
-
    HRESULT hr;
    static char szConfigDir[MAX_PATH + 1] = { 0 };
 
 bool
 find_config_file(const char *config_file, char *full_path)
 {
-#if defined(HAVE_WIN32)
-   if (strpbrk(config_file, ":/\\") != NULL) {
-      return false;
-   }
-#else
-   if (strchr(config_file, '/') != NULL) {
+   if (first_path_separator(config_file) != NULL) {
       return false;
    }
-#endif
 
    struct stat st;
 
 
    memcpy(full_path, config_dir, dir_length + 1);
 
-   if (full_path[dir_length - 1] != '/' && 
-       full_path[dir_length - 1] != '\\') {
+   if (!IsPathSeparator(full_path[dir_length - 1])) {
       full_path[dir_length++] = '/';
    }
 
 
 const char *     job_status_to_str       (int stat);
 const char *     job_level_to_str        (int level);
 void             make_session_key        (char *key, char *seed, int mode);
-POOLMEM         *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to);
-void             set_working_directory(char *wd);
+POOLMEM *        edit_job_codes          (JCR *jcr, char *omsg, char *imsg, const char *to);
+void             set_working_directory   (char *wd);
+const char *     last_path_separator     (const char *str);
 
 
 /* watchdog.c */
 
    p = dir + strlen(dir) - 1;
 
    /* strip trailing slashes */
-   while ((p >= dir) && (*p == '/'))
+   while (p >= dir && IsPathSeparator(*p))
       *p-- = 0;
 }
 
     */
    f = fname + len - 1;
    /* "strip" any trailing slashes */
-   while (slen > 1 && *f == '/') {
+   while (slen > 1 && IsPathSeparator(*f)) {
       slen--;
       f--;
    }
    /* Walk back to last slash -- begin of filename */
-   while (slen > 0 && *f != '/') {
+   while (slen > 0 && !IsPathSeparator(*f)) {
       slen--;
       f--;
    }
-   if (*f == '/') {                   /* did we find a slash? */
+   if (IsPathSeparator(*f)) {         /* did we find a slash? */
       f++;                            /* yes, point to filename */
    } else {                           /* no, whole thing must be path name */
       f = fname;
 
          bstrncpy(btpath, "btraceback", sizeof(btpath));
       } else {
          bstrncpy(btpath, exepath, sizeof(btpath));
-         if (btpath[exelen-1] == '/') {
+         if (IsPathSeparator(btpath[exelen-1])) {
             btpath[exelen-1] = 0;
          }
          bstrncat(btpath, "/btraceback", sizeof(btpath));
       }
-      if (exepath[exelen-1] != '/') {
+      if (!IsPathSeparator(exepath[exelen - 1])) {
          strcat(exepath, "/");
       }
       strcat(exepath, exename);
 
     */
    if (path_len > 0) {
       q = path + path_len - 1;
-      if (*q == '/') {
+      if (IsPathSeparator(*q)) {
          *q = 0;                      /* strip trailing slash */
       } else {
          q = NULL;                    /* no trailing slash */
    }
    /* If no filename, strip last component of path as "filename" */
    if (*fname == 0) {
-      p = strrchr(path, '/');         /* separate path and filename */
+      p = (char *)last_path_separator(path);  /* separate path and filename */
       if (p) {
          fname = p + 1;               /* set new filename */
-         *p = 0;                      /* terminate new path */
+         *p = '\0';                   /* terminate new path */
       }
    } else {
       p = NULL;
       Dmsg0(100, "make_tree_path: parent=*root*\n");
       return (TREE_NODE *)root;
    }
-   p = strrchr(path, '/');           /* get last dir component of path */
+   p = (char *)last_path_separator(path);           /* get last dir component of path */
    if (p) {
       fname = p + 1;
       *p = 0;                         /* terminate path */
     *    there is only a / in the buffer, remove it since
     *    win32 names don't generally start with /
     */
-   if (node->type == TN_DIR_NLS && buf[0] == '/' && buf[1] == 0) {
-      buf[0] = 0;
+   if (node->type == TN_DIR_NLS && IsPathSeparator(buf[0]) && buf[1] == '\0') {
+      buf[0] = '\0';
    }
    bstrncat(buf, node->fname, buf_size);
    /* Add a slash for all directories unless we are at the root,
     *  also add a slash to a soft linked file if it has children
     *  i.e. it is linked to a directory.
     */
-   if ((node->type != TN_FILE && !(buf[0] == '/' && buf[1] == 0)) ||
+   if ((node->type != TN_FILE && !(IsPathSeparator(buf[0]) && buf[1] == '\0')) ||
        (node->soft_link && tree_node_has_child(node))) {
       bstrncat(buf, "/", buf_size);
    }
          return tree_cwd(path+3, root, parent);
       }
    }
-   if (path[0] == '/') {
+   if (IsPathSeparator(path[0])) {
       Dmsg0(100, "Doing absolute lookup.\n");
       return tree_relcwd(path+1, root, (TREE_NODE *)root);
    }
       return node;
    }
    /* Check the current segment only */
-   p = strchr(path, '/');
-   if (p) {
+   if ((p = first_path_separator(path)) != NULL) {
       len = p - path;
    } else {
       len = strlen(path);
 
    }
    working_directory = wd;            /* set global */
 }
+
+const char *last_path_separator(const char *str)
+{
+   if (*str != '\0') {
+      for (const char *p = &str[strlen(str) - 1]; p >= str; p--) {
+         if (IsPathSeparator(*p)) {
+            return p;
+         }
+      }
+   }
+   return NULL;
+}
+
 
             unser_uint64(faddr);
             if (fileAddr != faddr) {
                fileAddr = faddr;
-               if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+               if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) {
                   berrno be;
                   Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"),
                      attr->ofname, be.strerror());
             unser_uint64(faddr);
             if (fileAddr != faddr) {
                fileAddr = faddr;
-               if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+               if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) {
                   berrno be;
                   Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
                      edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
 
          }
       } else {
          Dmsg0(200, "Seek to beginning of block for reread.\n");
-         off_t pos = dev->lseek(dcr, (off_t)0, SEEK_CUR); /* get curr pos */
+         boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
          pos -= block->read_len;
          dev->lseek(dcr, pos, SEEK_SET);
          dev->file_addr = pos;
    Dmsg0(200, "At end of read block\n");
    if (block->read_len > block->block_len && !dev->is_tape()) {
       char ed1[50];
-      off_t pos = dev->lseek(dcr, (off_t)0, SEEK_CUR); /* get curr pos */
+      boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
       Dmsg1(200, "Current lseek pos=%s\n", edit_int64(pos, ed1));
       pos -= (block->read_len - block->block_len);
       dev->lseek(dcr, pos, SEEK_SET);
 
    if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
       Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
    }
-   if (sizeof(off_t) < 8) {
-      Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. off_t=%d should be 8 or more !!!!!\n\n\n"),
-         sizeof(off_t));
+   if (sizeof(boffset_t) < 8) {
+      Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
+         sizeof(boffset_t));
    }
    x32 = 123456789;
    bsnprintf(buf, sizeof(buf), "%u", x32);
 static void do_unfill()
 {
    DEV_BLOCK *block = dcr->block;
-   bool autochanger;
+   int autochanger;
 
    dumped = 0;
    VolBytes = 0;
          dev->offline();
       }
       autochanger = autoload_device(dcr, 1, NULL);
-      if (!autochanger) {
+      if (autochanger != 1) {
          dev->close();
          get_cmd(_("Mount first tape. Press enter when ready: "));
       }
    set_volume_name("TestVolume2", 2);
 
    autochanger = autoload_device(dcr, 1, NULL);
-   if (!autochanger) {
+   if (autochanger != 1) {
       dev->close();
       get_cmd(_("Mount second tape. Press enter when ready: "));
    }
 
 bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
 {
-   bool autochanger;
+   int autochanger;
    DEVICE *dev = dcr->dev;
    Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
    if (stop == 0) {
       dev->offline();
    }
    autochanger = autoload_device(dcr, 1, NULL);
-   if (!autochanger) {
+   if (autochanger != 1) {
       fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
          dev->print_name());
       dev->close();
 
          /* Try stripping file part */
          p = dev_name + strlen(dev_name);
 
-         while (p >= dev_name && *p != '/')
+         while (p >= dev_name && !IsPathSeparator(*p))
             p--;
-         if (*p == '/') {
+         if (IsPathSeparator(*p)) {
             bstrncpy(VolName, p+1, sizeof(VolName));
             *p = 0;
          }
 
          return;
       }
 
-      if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
+      if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) {
          pm_strcat(archive_name, "/");
       }
       pm_strcat(archive_name, VolCatInfo.VolCatName);
          break;
       }
    } else if (is_file() || is_dvd()) {
-      if (lseek(dcr, (off_t)0, SEEK_SET) < 0) {
+      if (lseek(dcr, (boffset_t)0, SEEK_SET) < 0) {
          berrno be;
          dev_errno = errno;
          Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
    struct mtop mt_com;
    struct mtget mt_stat;
    bool ok = true;
-   off_t pos;
+   boffset_t pos;
 
    if (fd < 0) {
       dev_errno = EBADF;
       return true;
    }
    if (!is_tape()) {
-      pos = lseek(dcr, (off_t)0, SEEK_END);
+      pos = lseek(dcr, (boffset_t)0, SEEK_END);
 //    Dmsg1(100, "====== Seek to %lld\n", pos);
       if (pos >= 0) {
          update_pos(dcr);
  */
 bool DEVICE::update_pos(DCR *dcr)
 {
-   off_t pos;
+   boffset_t pos;
    bool ok = true;
 
    if (!is_open()) {
    if (is_file() || is_dvd()) {
       file = 0;
       file_addr = 0;
-      pos = lseek(dcr, (off_t)0, SEEK_CUR);
+      pos = lseek(dcr, (boffset_t)0, SEEK_CUR);
       if (pos < 0) {
          berrno be;
          dev_errno = errno;
    }
 
    if (!is_tape()) {
-      off_t pos = (((off_t)rfile)<<32) + (off_t)rblock;
+      boffset_t pos = (((boffset_t)rfile)<<32) | rblock;
       Dmsg1(100, "===== lseek to %d\n", (int)pos);
-      if (lseek(dcr, pos, SEEK_SET) == (off_t)-1) {
+      if (lseek(dcr, pos, SEEK_SET) == (boffset_t)-1) {
          berrno be;
          dev_errno = errno;
          Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
    dcr->VolCatInfo = saveVolCatInfo;  /* structure assignment */
 }
 
-off_t DEVICE::lseek(DCR *dcr, off_t offset, int whence)
+boffset_t DEVICE::lseek(DCR *dcr, boffset_t offset, int whence)
 {
    switch (dev_type) {
    case B_DVD_DEV:
       return lseek_dvd(dcr, offset, whence);
    case B_FILE_DEV:
-      return ::lseek(fd, offset, whence);
-   }  
+#if defined(HAVE_WIN32)
+      return ::_lseeki64(fd, (__int64)offset, whence);
+#else
+      return ::lseek(fd, (off_t)offset, whence);
+#endif
+   }
    return -1;
 }
 
 
    bool scan_dir_for_volume(DCR *dcr); /* in scan.c */
    bool reposition(DCR *dcr, uint32_t rfile, uint32_t rblock); /* in dev.c */
    void clrerror(int func);      /* in dev.c */
-   off_t lseek(DCR *dcr, off_t offset, int whence); /* in dev.c */
+   boffset_t lseek(DCR *dcr, boffset_t offset, int whence); /* in dev.c */
    bool update_pos(DCR *dcr);    /* in dev.c */
    bool update_freespace();      /* in dvd.c */
 
 
 {
    char partnumber[20];
 
-   if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
+   if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) {
       pm_strcat(archive_name, "/");
    }
 
 /* 
  * Do an lseek on a DVD handling all the different parts
  */
-off_t lseek_dvd(DCR *dcr, off_t offset, int whence)
+boffset_t lseek_dvd(DCR *dcr, boffset_t offset, int whence)
 {
    DEVICE *dev = dcr->dev;
-   off_t pos;
+   boffset_t pos;
    char ed1[50], ed2[50];
    
    Dmsg5(400, "Enter lseek_dvd fd=%d off=%s w=%d part=%d nparts=%d\n", dev->fd,
          if ((uint64_t)offset == dev->part_start || 
              (uint64_t)offset < dev->part_start+dev->part_size) {
             /* We are staying in the current part, just seek */
-            if ((pos = lseek(dev->fd, offset-dev->part_start, SEEK_SET)) < 0) {
+#if defined(HAVE_WIN32)
+            pos = _lseeki64(dev->fd, offset-dev->part_start, SEEK_SET);
+#else
+            pos = lseek(dev->fd, offset-dev->part_start, SEEK_SET);
+#endif
+            if (pos < 0) {
                return pos;
             } else {
                return pos + dev->part_start;
             /* Found a file, checking it is empty */
             POOL_MEM filename(PM_FNAME);
             pm_strcpy(filename, dev->device->mount_point);
-            if (filename.c_str()[strlen(filename.c_str())-1] != '/') {
+            if (!IsPathSeparator(filename.c_str()[strlen(filename.c_str())-1])) {
                pm_strcat(filename, "/");
             }
             pm_strcat(filename, result->d_name);
 
 bool    truncate_dvd(DCR *dcr);
 bool    check_can_write_on_non_blank_dvd(DCR *dcr);
 int     find_num_dvd_parts(DCR *dcr);
-off_t   lseek_dvd(DCR *dcr, off_t offset, int whence);
+boffset_t   lseek_dvd(DCR *dcr, boffset_t offset, int whence);
 void    dvd_remove_empty_part(DCR *dcr);
 
 /* From device.c */
 
    
    len = strlen(mount_point);
    if (len > 0) {
-      need_slash = mount_point[len - 1] != '/';
+      need_slash = !IsPathSeparator(mount_point[len - 1]);
    }
    entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
    for ( ;; ) {
 
       if (stat != (ssize_t)sizeof(hdr)) {
          /* If we wrote something, truncate it, then despool */
          if (stat != -1) {
-            if (ftruncate(dcr->spool_fd, lseek(dcr->spool_fd, (off_t)0, SEEK_CUR) - stat) != 0) {
+#if defined(HAVE_WIN32)
+            boffset_t   pos = _lseeki64(dcr->spool_fd, (__int64)0, SEEK_CUR);
+#else
+            boffset_t   pos = lseek(dcr->spool_fd, (off_t)0, SEEK_CUR);
+#endif
+            if (ftruncate(dcr->spool_fd, pos - stat) != 0) {
                berrno be;
                Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
                   be.strerror());
           * If we wrote something, truncate it and the header, then despool
           */
          if (stat != -1) {
-            if (ftruncate(dcr->spool_fd, lseek(dcr->spool_fd, (off_t)0, SEEK_CUR)
-                      - stat - sizeof(spool_hdr)) != 0) {
+#if defined(HAVE_WIN32)
+            boffset_t   pos = _lseeki64(dcr->spool_fd, (__int64)0, SEEK_CUR);
+#else
+            boffset_t   pos = lseek(dcr->spool_fd, (off_t)0, SEEK_CUR);
+#endif
+            if (ftruncate(dcr->spool_fd, pos - stat - sizeof(spool_hdr)) != 0) {
                berrno be;
                Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
                   be.strerror());
 
    pm_strcpy(cleanup, "/bin/rm -f ");
 #endif
    pm_strcat(cleanup, me->working_directory);
-   if (len > 0 && me->working_directory[len-1] != '/'
-#if defined(HAVE_WIN32)
-       && me->working_directory[len-1] != '\\'
-#endif
-       ) {
+   if (len > 0 && !IsPathSeparator(me->working_directory[len-1])) {
       pm_strcat(cleanup, "/");
    }
    pm_strcat(cleanup, my_name);
 
             printf("%s\n", db_strerror(db));
          }
          /* Strip trailing slash(es) */
-         for (len=strlen(name); len > 0 && name[len-1]=='/'; len--)
+         for (len=strlen(name); len > 0 && IsPathSeparator(name[len-1]); len--)
             {  }
          if (len == 0) {
             len = 1;
 
     * must be a path name (e.g. c:).
     */
    for (p=l=ar->fname; *p; p++) {
-      if (*p == '/') {
+      if (IsPathSeparator(*p)) {
          l = p;                       /* set pos of last slash */
       }
    }
-   if (*l == '/') {                   /* did we find a slash? */
+   if (IsPathSeparator(*l)) {                   /* did we find a slash? */
       l++;                            /* yes, point to filename */
    } else {                           /* no, whole thing must be path name */
       l = p;
 
 
     Dmsg0(100, "Enter convert_unix_to_win32_path\n");
 
-    if ((name[0] == '/' || name[0] == '\\') &&
-        (name[1] == '/' || name[1] == '\\') &&
-        (name[2] == '.') &&
-        (name[3] == '/' || name[3] == '\\')) {
+    if (IsPathSeparator(name[0]) &&
+        IsPathSeparator(name[1]) &&
+        name[2] == '.' &&
+        IsPathSeparator(name[3])) {
 
         *win32_name++ = '\\';
         *win32_name++ = '\\';
         }
         if (*name == '/') {
             *win32_name++ = '\\';     /* convert char */
-        /* If Win32 separated that is "quoted", remove quote */
+        /* If Win32 separator that is "quoted", remove quote */
         } else if (*name == '\\' && name[1] == '\\') {
             *win32_name++ = '\\';
             name++;                   /* skip first \ */
       return pszUCSPath;
    }
 
-   POOLMEM *pwszBuf = get_pool_memory(PM_FNAME);
-   POOLMEM *pwszCurDirBuf = get_pool_memory(PM_FNAME);
+   wchar_t *pwszBuf = (wchar_t *)get_pool_memory(PM_FNAME);
+   wchar_t *pwszCurDirBuf = (wchar_t *)get_pool_memory(PM_FNAME);
    DWORD dwCurDirPathSize = 0;
 
    /* get buffer with enough size (name+max 6. wchars+1 null terminator */
    DWORD dwBufCharsNeeded = (wcslen(name)+7);
-   pwszBuf = check_pool_memory_size(pwszBuf, dwBufCharsNeeded*sizeof(wchar_t));
+   pwszBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)pwszBuf, dwBufCharsNeeded*sizeof(wchar_t));
       
    /* add \\?\ to support 32K long filepaths 
       it is important to make absolute paths, so we add drive and
    BOOL bAddPrefix = TRUE;
 
    /* does path begin with drive? if yes, it is absolute */
-   if (wcslen(name) >= 3 && (iswalpha (*name) && *(name+1) == ':'
-       && (*(name+2) == '\\' || *(name+2) == '/'))) {
+   if (iswalpha(name[0]) && name[1] == ':' && IsPathSeparator(name[2])) {
       bAddDrive = FALSE;
       bAddCurrentPath = FALSE;
    }
 
    /* is path absolute? */
-   if (*name == '/' || *name == '\\')
+   if (IsPathSeparator(name[0]))
       bAddCurrentPath = FALSE; 
 
    /* is path relative to itself?, if yes, skip ./ */
-   if (wcslen(name) > 2 && ((wcsncmp(name, L"./", 2) == 0) || (wcsncmp(name, L".\\", 2) == 0))) {
+   if (name[0] == '.' && IsPathSeparator(name[1])) {
       name += 2;
    }
 
-   /* is path of form '//./'? */   
-   if (wcslen(name) > 3 && ((wcsncmp(name, L"//./", 4) == 0) || (wcsncmp(name, L"\\\\.\\", 4) == 0))) {
+   /* is path of form '//./'? */
+   if (IsPathSeparator(name[0]) && 
+       IsPathSeparator(name[1]) && 
+       name[2] == '.' && 
+       IsPathSeparator(name[3])) {
       bAddDrive = FALSE;
       bAddCurrentPath = FALSE;
       bAddPrefix = FALSE;
    /* add 4 bytes header */
    if (bAddPrefix) {
       nParseOffset = 4;
-      wcscpy((wchar_t *)pwszBuf, L"\\\\?\\");
+      wcscpy(pwszBuf, L"\\\\?\\");
    }
 
    /* get current path if needed */
       dwCurDirPathSize = p_GetCurrentDirectoryW(0, NULL);
       if (dwCurDirPathSize > 0) {
          /* 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);
+         pwszCurDirBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)pwszCurDirBuf, (dwCurDirPathSize+1)*sizeof(wchar_t));
+         p_GetCurrentDirectoryW(dwCurDirPathSize, pwszCurDirBuf);
       } else {
          /* we have no info for doing so */
          bAddDrive = FALSE;
    if (bAddDrive && !bAddCurrentPath) {
       wchar_t szDrive[3];
 
-      if (dwCurDirPathSize > 3 && wcsncmp((LPCWSTR)pwszCurDirBuf, L"\\\\?\\", 4) == 0) {
+      if (IsPathSeparator(pwszCurDirBuf[0]) && 
+          IsPathSeparator(pwszCurDirBuf[1]) && 
+          pwszCurDirBuf[2] == '?' && 
+          IsPathSeparator(pwszCurDirBuf[3])) {
          /* copy drive character */
-         wcsncpy((wchar_t *)szDrive, (LPCWSTR)pwszCurDirBuf+4, 2);          
+         szDrive[0] = pwszCurDirBuf[4];
       } else {
          /* copy drive character */
-         wcsncpy((wchar_t *)szDrive, (LPCWSTR)pwszCurDirBuf, 2);  
+         szDrive[0] = pwszCurDirBuf[0];
       }
 
+      szDrive[1] = ':';
       szDrive[2] = 0;
-            
-      wcscat((wchar_t *)pwszBuf, szDrive);  
+
+      wcscat(pwszBuf, szDrive);
       nParseOffset +=2;
    }
 
    if (bAddCurrentPath) {
       /* the 1 add. character is for the eventually added backslash */
       dwBufCharsNeeded += dwCurDirPathSize+1; 
-      pwszBuf = check_pool_memory_size(pwszBuf, dwBufCharsNeeded*sizeof(wchar_t));
+      pwszBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)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 (IsPathSeparator(pwszCurDirBuf[0]) && 
+          IsPathSeparator(pwszCurDirBuf[1]) && 
+          pwszCurDirBuf[2] == '?' && 
+          IsPathSeparator(pwszCurDirBuf[3])) {
          /* copy complete string */
-         wcscpy((wchar_t *)pwszBuf, (LPCWSTR)pwszCurDirBuf);          
+         wcscpy(pwszBuf, pwszCurDirBuf);
       } else {
          /* append path  */
-         wcscat((wchar_t *)pwszBuf, (LPCWSTR)pwszCurDirBuf);       
+         wcscat(pwszBuf, pwszCurDirBuf);
       }
 
       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 (!IsPathSeparator(pwszBuf[nParseOffset-1])) {
+         wcscat(pwszBuf, L"\\");
          nParseOffset++;
-      }      
+      }
    }
 
-
-   wchar_t *win32_name = (wchar_t *)pwszBuf+nParseOffset;
+   wchar_t *win32_name = &pwszBuf[nParseOffset];
    wchar_t *name_start = name;
 
    while (*name) {
       /* Check for Unix separator and convert to Win32, eliminating 
        * duplicate separators.
        */
-      if (*name == '/' || *name == '\\') {
+      if (IsPathSeparator(*name)) {
          *win32_name++ = '\\';     /* convert char */
 
          /* Eliminate consecutive slashes, but not at the start so that 
           * \\.\ still works.
           */
-         if (name_start != name && (name[1] == '/' || name[1] == '\\')) {
+         if (name_start != name && IsPathSeparator(name[1])) {
             name++;
          }
       } else {
    */ 
    if (g_pVSSPathConvertW != NULL) {
       /* is output buffer large enough? */
-      pwszBuf = check_pool_memory_size(pwszBuf, (dwBufCharsNeeded+MAX_PATH)*sizeof(wchar_t));
+      pwszBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)pwszBuf, 
+                                                  (dwBufCharsNeeded+MAX_PATH)*sizeof(wchar_t));
       /* create temp. buffer */
-      POOLMEM* pszBuf = get_pool_memory(PM_FNAME);
-      pszBuf = check_pool_memory_size(pszBuf, (dwBufCharsNeeded+MAX_PATH)*sizeof(wchar_t));
+      wchar_t *pszBuf = (wchar_t *)get_pool_memory(PM_FNAME);
+      pszBuf = (wchar_t *)check_pool_memory_size((POOLMEM *)pszBuf, 
+                                                 (dwBufCharsNeeded+MAX_PATH)*sizeof(wchar_t));
       if (bAddPrefix)
          nParseOffset = 4;
       else
          nParseOffset = 0; 
-      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);
+      wcsncpy(pszBuf, &pwszBuf[nParseOffset], wcslen(pwszBuf)+1-nParseOffset);
+      g_pVSSPathConvertW(pszBuf, pwszBuf, dwBufCharsNeeded+MAX_PATH);
+      free_pool_memory((POOLMEM *)pszBuf);
    }   
 
    free_pool_memory(pszUCSPath);
-   free_pool_memory(pwszCurDirBuf);
+   free_pool_memory((POOLMEM *)pwszCurDirBuf);
 
    Dmsg1(100, "Leave wchar_win32_path=%s\n", pwszBuf);
-   return pwszBuf;
+   return (POOLMEM *)pwszBuf;
 }
 
 int
    {
       if (*current == '.') {
          pExtension = current;
-      } else if ((*current == '\\' || *current == '/') && current[1] != '\0') {
+      } else if (IsPathSeparator(*current) && current[1] != '\0') {
          pBasename = ¤t[1];
          pExtension = NULL;
       }
     return -1;
 }
 
-off_t
-file_seek(int fd, off_t offset, int whence)
+boffset_t
+file_seek(int fd, boffset_t offset, int whence)
 {
     DWORD method = 0;
     DWORD val;
+    LONG  offset_low = (LONG)offset;
+    LONG  offset_high = (LONG)(offset >> 32);
+
     switch (whence) {
     case SEEK_SET :
         method = FILE_BEGIN;
         return -1;
     }
 
-    if ((val=SetFilePointer((HANDLE)fd, (DWORD)offset, NULL, method)) == INVALID_SET_FILE_POINTER) {
+
+    if ((val=SetFilePointer((HANDLE)fd, offset_low, &offset_high, method)) == INVALID_SET_FILE_POINTER) {
        errno = b_errno_win32;
        return -1;
     }
 
 typedef long time_t;
 #endif
 
-#if __STDC__
-#if !defined(HAVE_MINGW)
+#if __STDC__ && !defined(HAVE_MINGW)
 typedef _dev_t dev_t;
 #if !defined(HAVE_WXCONSOLE)
 typedef __int64 ino_t;
-typedef __int64 off_t;          /* STDC=1 means we can define this */
 #endif
 #endif
-#else
-typedef long _off_t;            /* must be same as sys/types.h */
-#endif
 
 typedef UINT32 u_int32_t;
 typedef unsigned char u_int8_t;
       return 0;
 }
 
-#define ftruncate    _chsize
+#define ftruncate    _chsize_s
 #else
 #define  ffs   __builtin_ffs
 #endif
 
                                Name="VCResourceCompilerTool"\r
                                PreprocessorDefinitions="NDEBUG"\r
                                Culture="1033"\r
-                               AdditionalIncludeDirectories=""\r
+                               AdditionalIncludeDirectories="../libwin32"\r
                        />\r
                        <Tool\r
                                Name="VCPreLinkEventTool"\r
 
 _Z5bopenP5BFILEPKcit
 _Z5breadP5BFILEPvj
 _Z6bcloseP5BFILE
-_Z6blseekP5BFILEli
+_Z6blseekP5BFILExi
 _Z6bwriteP5BFILEPvj
 _Z8is_bopenP5BFILE
 _Z8set_progP5BFILEPcP3JCR
 
 ?bread@@YAHPAUBFILE@@PAXI@Z
 ?bwrite@@YAHPAUBFILE@@PAXI@Z
 ?is_bopen@@YA_NPAUBFILE@@@Z
-?blseek@@YAJPAUBFILE@@JH@Z
+?blseek@@YA_JPAUBFILE@@_JH@Z
  
 ; bget_msg.obj 
 ?bget_msg@@YAHPAUBSOCK@@@Z
 
 
    memset(&TapeHandleTable[idxFile], 0, sizeof(TapeHandleTable[idxFile]));
 
-   if (file[0] != '\\' && file[0] != '/') {
+   if (!IsPathSeparator(file[0])) {
        bstrncpy(&szDeviceName[4], file, sizeof(szDeviceName) - 4);
    } else {
        bstrncpy(&szDeviceName[0], file, sizeof(szDeviceName));
 
 
 
 void console_thread::SetWorkingDirectory(wxString w_dir) {
-   if ((w_dir.Last() == '/') || (w_dir.Last() == '\\')) {
+   if (IsPathSeparator(w_dir.Last())) {
       console_thread::working_dir = w_dir.Mid(0, w_dir.Length()-1);
    }
    else {
 
             wxFileName filename(::wxGetHomeDir());
             filename.MakeAbsolute();
             configfile = filename.GetLongPath();
-            if (configfile.Last() != '/')
+            if (!IsPathSeparator(configfile.Last())
                configfile += '/';
             configfile += "Library/Preferences/org.bacula.wxconsole.conf";
 #else
 
       wxString file;
 
       if (dir != wxT("/")) {
-         if (dir.GetChar(dir.Length()-1) == '/') {
+         if (IsPathSeparator(dir.GetChar(dir.Length()-1))) {
             dir.RemoveLast();
          }
 
 
       wxTreeItemId treeid;
 
-      if (entry.fullname.GetChar(entry.fullname.Length()-1) == '/') {
+      if (IsPathSeparator(entry.fullname.GetChar(entry.fullname.Length()-1))) {
          wxString itemStr;
 
 #if wxCHECK_VERSION(2, 6, 0)
    entry->fullname = tkz.GetString();
    
    /* Get only the filename (cut path by finding the last '/') */
-   if (entry->fullname.GetChar(entry->fullname.Length()-1) == '/') {
+   if (IsPathSeparator(entry->fullname.GetChar(entry->fullname.Length()-1))) {
       wxString tmp = entry->fullname;
       tmp.RemoveLast();
       entry->filename = entry->fullname.Mid(tmp.Find('/', true)+1);
       long cookie;
 #endif
 
-      if (name.GetChar(name.Length()-1) == '/') {
+      if (IsPathSeparator(name.GetChar(name.Length()-1))) {
          wxTreeItemId currentChild = tree->GetFirstChild(currentTreeItem, cookie);
 
          while (currentChild.IsOk()) {