]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/bfile.c
Restore win32 dir from Branch-5.2 and update it
[bacula/bacula] / bacula / src / findlib / bfile.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2018 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *  Bacula low level File I/O routines.  This routine simulates
21  *    open(), read(), write(), and close(), but using native routines.
22  *    I.e. on Windows, we use Windows APIs.
23  *
24  *    Kern Sibbald, April MMIII
25  *
26  */
27
28 #include "bacula.h"
29 #include "find.h"
30
31 const int dbglvl = 200;
32
33 int       (*plugin_bopen)(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode) = NULL;
34 int       (*plugin_bclose)(BFILE *bfd) = NULL;
35 ssize_t   (*plugin_bread)(BFILE *bfd, void *buf, size_t count) = NULL;
36 ssize_t   (*plugin_bwrite)(BFILE *bfd, void *buf, size_t count) = NULL;
37 boffset_t (*plugin_blseek)(BFILE *bfd, boffset_t offset, int whence) = NULL;
38
39
40 #ifdef HAVE_DARWIN_OS
41 #include <sys/paths.h>
42 #endif
43
44 #if !defined(HAVE_FDATASYNC)
45 #define fdatasync(fd)
46 #endif
47
48 #ifdef HAVE_WIN32
49 void pause_msg(const char *file, const char *func, int line, const char *msg)
50 {
51    char buf[1000];
52    if (msg) {
53       bsnprintf(buf, sizeof(buf), "%s:%s:%d %s", file, func, line, msg);
54    } else {
55       bsnprintf(buf, sizeof(buf), "%s:%s:%d", file, func, line);
56    }
57    MessageBox(NULL, buf, "Pause", MB_OK);
58 }
59 #endif
60
61 /* ===============================================================
62  *
63  *            U N I X   AND   W I N D O W S
64  *
65  * ===============================================================
66  */
67
68 bool is_win32_stream(int stream)
69 {
70    switch (stream) {
71    case STREAM_WIN32_DATA:
72    case STREAM_WIN32_GZIP_DATA:
73    case STREAM_WIN32_COMPRESSED_DATA:
74    case STREAM_ENCRYPTED_WIN32_DATA:
75    case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
76    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
77       return true;
78    }
79    return false;
80 }
81
82 const char *stream_to_ascii(int stream)
83 {
84    static char buf[20];
85
86    switch (stream & STREAMMASK_TYPE) {
87       case STREAM_UNIX_ATTRIBUTES:
88          return _("Unix attributes");
89       case STREAM_FILE_DATA:
90          return _("File data");
91       case STREAM_MD5_DIGEST:
92          return _("MD5 digest");
93       case STREAM_GZIP_DATA:
94          return _("GZIP data");
95       case STREAM_COMPRESSED_DATA:
96          return _("Compressed data");
97       case STREAM_UNIX_ATTRIBUTES_EX:
98          return _("Extended attributes");
99       case STREAM_SPARSE_DATA:
100          return _("Sparse data");
101       case STREAM_SPARSE_GZIP_DATA:
102          return _("GZIP sparse data");
103       case STREAM_SPARSE_COMPRESSED_DATA:
104          return _("Compressed sparse data");
105       case STREAM_PROGRAM_NAMES:
106          return _("Program names");
107       case STREAM_PROGRAM_DATA:
108          return _("Program data");
109       case STREAM_SHA1_DIGEST:
110          return _("SHA1 digest");
111       case STREAM_WIN32_DATA:
112          return _("Win32 data");
113       case STREAM_WIN32_GZIP_DATA:
114          return _("Win32 GZIP data");
115       case STREAM_WIN32_COMPRESSED_DATA:
116          return _("Win32 compressed data");
117       case STREAM_MACOS_FORK_DATA:
118          return _("MacOS Fork data");
119       case STREAM_HFSPLUS_ATTRIBUTES:
120          return _("HFS+ attribs");
121       case STREAM_UNIX_ACCESS_ACL:
122          return _("Standard Unix ACL attribs");
123       case STREAM_UNIX_DEFAULT_ACL:
124          return _("Default Unix ACL attribs");
125       case STREAM_SHA256_DIGEST:
126          return _("SHA256 digest");
127       case STREAM_SHA512_DIGEST:
128          return _("SHA512 digest");
129       case STREAM_SIGNED_DIGEST:
130          return _("Signed digest");
131       case STREAM_ENCRYPTED_FILE_DATA:
132          return _("Encrypted File data");
133       case STREAM_ENCRYPTED_WIN32_DATA:
134          return _("Encrypted Win32 data");
135       case STREAM_ENCRYPTED_SESSION_DATA:
136          return _("Encrypted session data");
137       case STREAM_ENCRYPTED_FILE_GZIP_DATA:
138          return _("Encrypted GZIP data");
139       case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
140          return _("Encrypted compressed data");
141       case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
142          return _("Encrypted Win32 GZIP data");
143       case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
144          return _("Encrypted Win32 Compressed data");
145       case STREAM_ENCRYPTED_MACOS_FORK_DATA:
146          return _("Encrypted MacOS fork data");
147       case STREAM_PLUGIN_NAME:
148          return _("Plugin Name");
149       case STREAM_PLUGIN_DATA:
150          return _("Plugin Data");
151       case STREAM_RESTORE_OBJECT:
152          return _("Restore Object");
153       case STREAM_XACL_AIX_TEXT:
154          return _("AIX ACL attribs");
155       case STREAM_XACL_DARWIN_ACCESS:
156          return _("Darwin ACL attribs");
157       case STREAM_XACL_FREEBSD_DEFAULT:
158          return _("FreeBSD Default ACL attribs");
159       case STREAM_XACL_FREEBSD_ACCESS:
160          return _("FreeBSD Access ACL attribs");
161       case STREAM_XACL_HPUX_ACL_ENTRY:
162          return _("HPUX ACL attribs");
163       case STREAM_XACL_IRIX_DEFAULT:
164          return _("Irix Default ACL attribs");
165       case STREAM_XACL_IRIX_ACCESS:
166          return _("Irix Access ACL attribs");
167       case STREAM_XACL_LINUX_DEFAULT:
168          return _("Linux Default ACL attribs");
169       case STREAM_XACL_LINUX_ACCESS:
170          return _("Linux Access ACL attribs");
171       case STREAM_XACL_TRU64_DEFAULT:
172          return _("TRU64 Default ACL attribs");
173       case STREAM_XACL_TRU64_ACCESS:
174          return _("TRU64 Access ACL attribs");
175       case STREAM_XACL_SOLARIS_POSIX:
176          return _("Solaris POSIX ACL attribs");
177       case STREAM_XACL_SOLARIS_NFS4:
178          return _("Solaris NFSv4/ZFS ACL attribs");
179       case STREAM_XACL_AFS_TEXT:
180          return _("AFS ACL attribs");
181       case STREAM_XACL_AIX_AIXC:
182          return _("AIX POSIX ACL attribs");
183       case STREAM_XACL_AIX_NFS4:
184          return _("AIX NFSv4 ACL attribs");
185       case STREAM_XACL_FREEBSD_NFS4:
186          return _("FreeBSD NFSv4/ZFS ACL attribs");
187       case STREAM_XACL_HURD_DEFAULT:
188          return _("GNU Hurd Default ACL attribs");
189       case STREAM_XACL_HURD_ACCESS:
190          return _("GNU Hurd Access ACL attribs");
191       case STREAM_XACL_HURD_XATTR:
192          return _("GNU Hurd Extended attribs");
193       case STREAM_XACL_IRIX_XATTR:
194          return _("IRIX Extended attribs");
195       case STREAM_XACL_TRU64_XATTR:
196          return _("TRU64 Extended attribs");
197       case STREAM_XACL_AIX_XATTR:
198          return _("AIX Extended attribs");
199       case STREAM_XACL_OPENBSD_XATTR:
200          return _("OpenBSD Extended attribs");
201       case STREAM_XACL_SOLARIS_SYS_XATTR:
202          return _("Solaris Extensible attribs or System Extended attribs");
203       case STREAM_XACL_SOLARIS_XATTR:
204          return _("Solaris Extended attribs");
205       case STREAM_XACL_DARWIN_XATTR:
206          return _("Darwin Extended attribs");
207       case STREAM_XACL_FREEBSD_XATTR:
208          return _("FreeBSD Extended attribs");
209       case STREAM_XACL_LINUX_XATTR:
210          return _("Linux Extended attribs");
211       case STREAM_XACL_NETBSD_XATTR:
212          return _("NetBSD Extended attribs");
213       default:
214          sprintf(buf, "%d", stream);
215          return (const char *)buf;
216       }
217 }
218
219 /**
220  *  Convert a 64 bit little endian to a big endian
221  */
222 void int64_LE2BE(int64_t* pBE, const int64_t v)
223 {
224    /* convert little endian to big endian */
225    if (htonl(1) != 1L) { /* no work if on little endian machine */
226       memcpy(pBE, &v, sizeof(int64_t));
227    } else {
228       int i;
229       uint8_t rv[sizeof(int64_t)];
230       uint8_t *pv = (uint8_t *) &v;
231
232       for (i = 0; i < 8; i++) {
233          rv[i] = pv[7 - i];
234       }
235       memcpy(pBE, &rv, sizeof(int64_t));
236    }
237 }
238
239 /**
240  *  Convert a 32 bit little endian to a big endian
241  */
242 void int32_LE2BE(int32_t* pBE, const int32_t v)
243 {
244    /* convert little endian to big endian */
245    if (htonl(1) != 1L) { /* no work if on little endian machine */
246       memcpy(pBE, &v, sizeof(int32_t));
247    } else {
248       int i;
249       uint8_t rv[sizeof(int32_t)];
250       uint8_t *pv = (uint8_t *) &v;
251
252       for (i = 0; i < 4; i++) {
253          rv[i] = pv[3 - i];
254       }
255       memcpy(pBE, &rv, sizeof(int32_t));
256    }
257 }
258
259
260 /**
261  *  Read a BackupRead block and pull out the file data
262  */
263 bool processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, ssize_t dwSize)
264 {
265    int64_t len = dwSize;
266    char *dat=(char *)pBuffer;
267    int64_t use_len;
268
269    while (len>0 && bfd->win32filter.have_data(&dat, &len, &use_len)) {
270       if (bwrite(bfd, dat, use_len) != (ssize_t)use_len) {
271          return false;
272       }
273       dat+=use_len;
274    }
275    return true;
276 }
277
278 /* ===============================================================
279  *
280  *            W I N D O W S
281  *
282  * ===============================================================
283  */
284
285 #if defined(HAVE_WIN32)
286
287 void unix_name_to_win32(POOLMEM **win32_name, const char *name);
288 extern "C" HANDLE get_osfhandle(int fd);
289
290
291 void binit(BFILE *bfd)
292 {
293    memset(bfd, 0, sizeof(BFILE));
294    bfd->fid = -1;
295    bfd->mode = BF_CLOSED;
296    bfd->use_backup_api = have_win32_api();
297    bfd->cmd_plugin = false;
298 }
299
300 /*
301  * Enables using the Backup API (win32_data).
302  *   Returns 1 if function worked
303  *   Returns 0 if failed (i.e. do not have Backup API on this machine)
304  */
305 bool set_win32_backup(BFILE *bfd)
306 {
307    /* We enable if possible here */
308    bfd->use_backup_api = have_win32_api();
309    return bfd->use_backup_api;
310 }
311
312 void set_fattrs(BFILE *bfd, struct stat *statp)
313 {
314    bfd->fattrs = statp->st_fattrs;
315    Dmsg1(200, "set_fattrs 0x%x\n", bfd->fattrs);
316 }
317
318 bool set_portable_backup(BFILE *bfd)
319 {
320    bfd->use_backup_api = false;
321    return true;
322 }
323
324 bool set_cmd_plugin(BFILE *bfd, JCR *jcr)
325 {
326    bfd->cmd_plugin = true;
327    bfd->jcr = jcr;
328    return true;
329 }
330
331 /*
332  * Return 1 if we are NOT using Win32 BackupWrite()
333  * return 0 if are
334  */
335 bool is_portable_backup(BFILE *bfd)
336 {
337    return !bfd->use_backup_api;
338 }
339
340 bool have_win32_api()
341 {
342    return p_BackupRead && p_BackupWrite;
343 }
344
345
346 /*
347  * Return true  if we support the stream
348  *        false if we do not support the stream
349  *
350  *  This code is running under Win32, so we
351  *    do not need #ifdef on MACOS ...
352  */
353 bool is_restore_stream_supported(int stream)
354 {
355    switch (stream) {
356
357 /* Streams known not to be supported */
358 #ifndef HAVE_LIBZ
359    case STREAM_GZIP_DATA:
360    case STREAM_SPARSE_GZIP_DATA:
361    case STREAM_WIN32_GZIP_DATA:
362 #endif
363 #ifndef HAVE_LZO
364    case STREAM_COMPRESSED_DATA:
365    case STREAM_SPARSE_COMPRESSED_DATA:
366    case STREAM_WIN32_COMPRESSED_DATA:
367    case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
368    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
369 #endif
370    case STREAM_MACOS_FORK_DATA:
371    case STREAM_HFSPLUS_ATTRIBUTES:
372    case STREAM_ENCRYPTED_MACOS_FORK_DATA:
373       return false;
374
375    /* Known streams */
376 #ifdef HAVE_LIBZ
377    case STREAM_GZIP_DATA:
378    case STREAM_SPARSE_GZIP_DATA:
379    case STREAM_WIN32_GZIP_DATA:
380 #endif
381 #ifdef HAVE_LZO
382    case STREAM_COMPRESSED_DATA:
383    case STREAM_SPARSE_COMPRESSED_DATA:
384    case STREAM_WIN32_COMPRESSED_DATA:
385 #endif
386    case STREAM_WIN32_DATA:
387    case STREAM_UNIX_ATTRIBUTES:
388    case STREAM_FILE_DATA:
389    case STREAM_MD5_DIGEST:
390    case STREAM_UNIX_ATTRIBUTES_EX:
391    case STREAM_SPARSE_DATA:
392    case STREAM_PROGRAM_NAMES:
393    case STREAM_PROGRAM_DATA:
394    case STREAM_SHA1_DIGEST:
395 #ifdef HAVE_SHA2
396    case STREAM_SHA256_DIGEST:
397    case STREAM_SHA512_DIGEST:
398 #endif
399 #ifdef HAVE_CRYPTO
400    case STREAM_SIGNED_DIGEST:
401    case STREAM_ENCRYPTED_FILE_DATA:
402    case STREAM_ENCRYPTED_FILE_GZIP_DATA:
403    case STREAM_ENCRYPTED_WIN32_DATA:
404    case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
405 #ifdef HAVE_LZO
406    case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
407    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
408 #endif
409 #endif     /* !HAVE_CRYPTO */
410    case 0:                            /* compatibility with old tapes */
411       return true;
412    }
413    return false;
414 }
415
416 HANDLE bget_handle(BFILE *bfd)
417 {
418    return bfd->fh;
419 }
420
421 /*
422  * The following code was contributed by Graham Keeling from his
423  *  burp project.  August 2014
424  */
425 static int encrypt_bopen(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
426 {
427    ULONG ulFlags = 0;
428    POOLMEM *win32_fname;
429    POOLMEM *win32_fname_wchar;
430
431    bfd->mode = BF_CLOSED;
432    bfd->fid = -1;
433
434    if (!(p_OpenEncryptedFileRawA || p_OpenEncryptedFileRawW)) {
435       Dmsg0(50, "No OpenEncryptedFileRawA and no OpenEncryptedFileRawW APIs!!!\n");
436       return -1;
437    }
438
439    /* Convert to Windows path format */
440    win32_fname = get_pool_memory(PM_FNAME);
441    win32_fname_wchar = get_pool_memory(PM_FNAME);
442
443    unix_name_to_win32(&win32_fname, (char *)fname);
444
445    if (p_CreateFileW && p_MultiByteToWideChar) {
446       make_win32_path_UTF8_2_wchar(&win32_fname_wchar, fname);
447    }
448
449    if ((flags & O_CREAT) || (flags & O_WRONLY)) {
450       ulFlags = CREATE_FOR_IMPORT | OVERWRITE_HIDDEN;
451       if (bfd->fattrs & FILE_ATTRIBUTE_DIRECTORY) {
452          mkdir(fname, 0777);
453          ulFlags |= CREATE_FOR_DIR;
454       }
455       bfd->mode = BF_WRITE;
456       Dmsg0(200, "encrypt_bopen for write.\n");
457    } else {
458       /* Open existing for read */
459       ulFlags = CREATE_FOR_EXPORT;
460       bfd->mode = BF_READ;
461       Dmsg0(200, "encrypt_bopen for read.\n");
462    }
463
464    if (p_OpenEncryptedFileRawW && p_MultiByteToWideChar) {
465       /* unicode open */
466       if (p_OpenEncryptedFileRawW((LPCWSTR)win32_fname_wchar,
467                    ulFlags, &(bfd->pvContext))) {
468          bfd->mode = BF_CLOSED;
469          errno = b_errno_win32;
470          bfd->berrno = b_errno_win32;
471       }
472    } else {
473       /* ascii open */
474       if (p_OpenEncryptedFileRawA(win32_fname, ulFlags, &(bfd->pvContext))) {
475          bfd->mode = BF_CLOSED;
476          errno = b_errno_win32;
477          bfd->berrno = b_errno_win32;
478       }
479    }
480    free_pool_memory(win32_fname_wchar);
481    free_pool_memory(win32_fname);
482    bfd->fid = (bfd->mode == BF_CLOSED) ? -1 : 0;
483    return bfd->mode==BF_CLOSED ? -1: 1;
484 }
485
486 static int encrypt_bclose(BFILE *bfd)
487 {
488    Dmsg0(200, "encrypt_bclose\n");
489    if (p_CloseEncryptedFileRaw) {
490       p_CloseEncryptedFileRaw(bfd->pvContext);
491    }
492    bfd->pvContext = NULL;
493    bfd->mode = BF_CLOSED;
494    bfd->fattrs = 0;
495    bfd->fid = -1;
496    return 0;
497 }
498
499 /* Windows */
500 int bopen(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
501 {
502    POOLMEM *win32_fname;
503    POOLMEM *win32_fname_wchar;
504
505    DWORD dwaccess, dwflags, dwshare;
506
507    if (bfd->fattrs & FILE_ATTRIBUTE_ENCRYPTED) {
508       return encrypt_bopen(bfd, fname, flags, mode);
509    }
510
511    /* Convert to Windows path format */
512    win32_fname = get_pool_memory(PM_FNAME);
513    win32_fname_wchar = get_pool_memory(PM_FNAME);
514
515    unix_name_to_win32(&win32_fname, (char *)fname);
516
517    if (bfd->cmd_plugin && plugin_bopen) {
518       int rtnstat;
519       Dmsg1(50, "call plugin_bopen fname=%s\n", fname);
520       rtnstat = plugin_bopen(bfd, fname, flags, mode);
521       Dmsg1(50, "return from plugin_bopen status=%d\n", rtnstat);
522       if (rtnstat >= 0) {
523          if (flags & O_CREAT || flags & O_WRONLY) {   /* Open existing for write */
524             Dmsg1(50, "plugin_open for write OK file=%s.\n", fname);
525             bfd->mode = BF_WRITE;
526          } else {
527             Dmsg1(50, "plugin_open for read OK file=%s.\n", fname);
528             bfd->mode = BF_READ;
529          }
530          bfd->fid = -1;         /* The file descriptor is invalid */
531       } else {
532          bfd->mode = BF_CLOSED;
533          bfd->fid = -1;
534          Dmsg1(000, "==== plugin_bopen returned bad status=%d\n", rtnstat);
535       }
536       free_pool_memory(win32_fname_wchar);
537       free_pool_memory(win32_fname);
538       return bfd->mode == BF_CLOSED ? -1 : 1;
539    }
540    Dmsg0(100, "=== NO plugin\n");
541
542    if (!(p_CreateFileA || p_CreateFileW)) {
543       Dmsg0(50, "No CreateFileA and no CreateFileW!!!!!\n");
544       return 0;
545    }
546
547    if (p_CreateFileW && p_MultiByteToWideChar) {
548       make_win32_path_UTF8_2_wchar(&win32_fname_wchar, fname);
549    }
550
551    if (flags & O_CREAT) {             /* Create */
552       if (bfd->use_backup_api) {
553          dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
554          dwflags = FILE_FLAG_BACKUP_SEMANTICS;
555       } else {
556          dwaccess = GENERIC_WRITE;
557          dwflags = 0;
558       }
559
560       if (p_CreateFileW && p_MultiByteToWideChar) {
561          // unicode open for create write
562          Dmsg1(100, "Create CreateFileW=%ls\n", win32_fname_wchar);
563          bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
564                 dwaccess,                /* Requested access */
565                 0,                       /* Shared mode */
566                 NULL,                    /* SecurityAttributes */
567                 CREATE_ALWAYS,           /* CreationDisposition */
568                 dwflags,                 /* Flags and attributes */
569                 NULL);                   /* TemplateFile */
570       } else {
571          // ascii open
572          Dmsg1(100, "Create CreateFileA=%s\n", win32_fname);
573          bfd->fh = p_CreateFileA(win32_fname,
574                 dwaccess,                /* Requested access */
575                 0,                       /* Shared mode */
576                 NULL,                    /* SecurityAttributes */
577                 CREATE_ALWAYS,           /* CreationDisposition */
578                 dwflags,                 /* Flags and attributes */
579                 NULL);                   /* TemplateFile */
580       }
581
582       bfd->mode = BF_WRITE;
583
584    } else if (flags & O_WRONLY) {     /* Open existing for write */
585       if (bfd->use_backup_api) {
586          dwaccess = GENERIC_READ|GENERIC_WRITE|WRITE_OWNER|WRITE_DAC;
587          /* If deduped we do not want to open the reparse point */
588          if (bfd->fattrs & FILE_ATTRIBUTE_DEDUP) {
589             dwflags = FILE_FLAG_BACKUP_SEMANTICS;
590          } else {
591             dwflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;
592          }
593       } else {
594          dwaccess = GENERIC_READ|GENERIC_WRITE;
595          dwflags = 0;
596       }
597
598       if (p_CreateFileW && p_MultiByteToWideChar) {
599          // unicode open for open existing write
600          Dmsg1(100, "Write only CreateFileW=%s\n", win32_fname);
601          bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
602                 dwaccess,                /* Requested access */
603                 0,                       /* Shared mode */
604                 NULL,                    /* SecurityAttributes */
605                 OPEN_EXISTING,           /* CreationDisposition */
606                 dwflags,                 /* Flags and attributes */
607                 NULL);                   /* TemplateFile */
608       } else {
609          // ascii open
610          Dmsg1(100, "Write only CreateFileA=%s\n", win32_fname);
611          bfd->fh = p_CreateFileA(win32_fname,
612                 dwaccess,                /* Requested access */
613                 0,                       /* Shared mode */
614                 NULL,                    /* SecurityAttributes */
615                 OPEN_EXISTING,           /* CreationDisposition */
616                 dwflags,                 /* Flags and attributes */
617                 NULL);                   /* TemplateFile */
618
619       }
620
621       bfd->mode = BF_WRITE;
622
623    } else {                           /* Read */
624       if (bfd->use_backup_api) {
625          dwaccess = GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY;
626          dwflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_SEQUENTIAL_SCAN |
627                    FILE_FLAG_OPEN_REPARSE_POINT;
628          dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
629       } else {
630          dwaccess = GENERIC_READ;
631          dwflags = 0;
632          dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE;
633       }
634
635       if (p_CreateFileW && p_MultiByteToWideChar) {
636          // unicode open for open existing read
637          Dmsg1(100, "Read CreateFileW=%ls\n", win32_fname_wchar);
638          bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
639                 dwaccess,                /* Requested access */
640                 dwshare,                 /* Share modes */
641                 NULL,                    /* SecurityAttributes */
642                 OPEN_EXISTING,           /* CreationDisposition */
643                 dwflags,                 /* Flags and attributes */
644                 NULL);                   /* TemplateFile */
645       } else {
646          // ascii open
647          Dmsg1(100, "Read CreateFileA=%s\n", win32_fname);
648          bfd->fh = p_CreateFileA(win32_fname,
649                 dwaccess,                /* Requested access */
650                 dwshare,                 /* Share modes */
651                 NULL,                    /* SecurityAttributes */
652                 OPEN_EXISTING,           /* CreationDisposition */
653                 dwflags,                 /* Flags and attributes */
654                 NULL);                   /* TemplateFile */
655       }
656
657       bfd->mode = BF_READ;
658    }
659
660    if (bfd->fh == INVALID_HANDLE_VALUE) {
661       berrno be;
662       bfd->lerror = GetLastError();
663       bfd->berrno = b_errno_win32;
664       errno = b_errno_win32;
665       bfd->mode = BF_CLOSED;
666       Dmsg1(100, "Open failed: %s\n", be.bstrerror());
667    }
668    bfd->block = 0;
669    bfd->total_bytes = 0;
670    bfd->errmsg = NULL;
671    bfd->lpContext = NULL;
672    bfd->win32filter.init();
673    free_pool_memory(win32_fname_wchar);
674    free_pool_memory(win32_fname);
675    bfd->fid = (bfd->mode == BF_CLOSED) ? -1 : 0;
676    return bfd->mode == BF_CLOSED ? -1 : 1;
677 }
678
679 /*
680  * Returns  0 on success
681  *         -1 on error
682  */
683 /* Windows */
684 int bclose(BFILE *bfd)
685 {
686    int stat = 0;
687
688    if (bfd->mode == BF_CLOSED) {
689       Dmsg0(50, "=== BFD already closed.\n");
690       return 0;
691    }
692
693    if (bfd->cmd_plugin && plugin_bclose) {
694       stat = plugin_bclose(bfd);
695       Dmsg0(50, "==== BFD closed!!!\n");
696       goto all_done;
697    }
698
699    if (bfd->fattrs & FILE_ATTRIBUTE_ENCRYPTED) {
700       return encrypt_bclose(bfd);
701    }
702
703    /*
704     * We need to tell the API to release the buffer it
705     *  allocated in lpContext.  We do so by calling the
706     *  API one more time, but with the Abort bit set.
707     */
708    if (bfd->use_backup_api && bfd->mode == BF_READ) {
709       BYTE buf[10];
710       if (bfd->lpContext && !p_BackupRead(bfd->fh,
711               buf,                    /* buffer */
712               (DWORD)0,               /* bytes to read */
713               &bfd->rw_bytes,         /* bytes read */
714               1,                      /* Abort */
715               1,                      /* ProcessSecurity */
716               &bfd->lpContext)) {     /* Read context */
717          errno = b_errno_win32;
718          stat = -1;
719       }
720    } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) {
721       BYTE buf[10];
722       if (bfd->lpContext && !p_BackupWrite(bfd->fh,
723               buf,                    /* buffer */
724               (DWORD)0,               /* bytes to read */
725               &bfd->rw_bytes,         /* bytes written */
726               1,                      /* Abort */
727               1,                      /* ProcessSecurity */
728               &bfd->lpContext)) {     /* Write context */
729          errno = b_errno_win32;
730          stat = -1;
731       }
732    }
733    if (!CloseHandle(bfd->fh)) {
734       stat = -1;
735       errno = b_errno_win32;
736    }
737
738 all_done:
739    if (bfd->errmsg) {
740       free_pool_memory(bfd->errmsg);
741       bfd->errmsg = NULL;
742    }
743    bfd->mode = BF_CLOSED;
744    bfd->fattrs = 0;
745    bfd->fid = -1;
746    bfd->lpContext = NULL;
747    bfd->cmd_plugin = false;
748    return stat;
749 }
750
751 /* Returns: bytes read on success
752  *           0         on EOF
753  *          -1         on error
754  */
755 /* Windows */
756 ssize_t bread(BFILE *bfd, void *buf, size_t count)
757 {
758    bfd->rw_bytes = 0;
759
760    if (bfd->cmd_plugin && plugin_bread) {
761       return plugin_bread(bfd, buf, count);
762    }
763
764    if (bfd->use_backup_api) {
765       if (!p_BackupRead(bfd->fh,
766            (BYTE *)buf,
767            count,
768            &bfd->rw_bytes,
769            0,                           /* no Abort */
770            1,                           /* Process Security */
771            &bfd->lpContext)) {          /* Context */
772          berrno be;
773          bfd->lerror = GetLastError();
774          bfd->berrno = b_errno_win32;
775          errno = b_errno_win32;
776          Dmsg1(100, "Read failed: %s\n", be.bstrerror());
777          return -1;
778       }
779    } else {
780       if (!ReadFile(bfd->fh,
781            buf,
782            count,
783            &bfd->rw_bytes,
784            NULL)) {
785          bfd->lerror = GetLastError();
786          bfd->berrno = b_errno_win32;
787          errno = b_errno_win32;
788          return -1;
789       }
790    }
791    bfd->block++;
792    if (bfd->rw_bytes > 0) {
793       bfd->total_bytes += bfd->rw_bytes;
794    }
795    return (ssize_t)bfd->rw_bytes;
796 }
797
798 /* Windows */
799 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
800 {
801    bfd->rw_bytes = 0;
802
803    if (bfd->cmd_plugin && plugin_bwrite) {
804       return plugin_bwrite(bfd, buf, count);
805    }
806
807    if (bfd->use_backup_api) {
808       if (!p_BackupWrite(bfd->fh,
809            (BYTE *)buf,
810            count,
811            &bfd->rw_bytes,
812            0,                           /* No abort */
813            1,                           /* Process Security */
814            &bfd->lpContext)) {          /* Context */
815          berrno be;
816          bfd->lerror = GetLastError();
817          bfd->berrno = b_errno_win32;
818          errno = b_errno_win32;
819          Dmsg1(100, "Write failed: %s\n", be.bstrerror());
820          return -1;
821       }
822    } else {
823       if (!WriteFile(bfd->fh,
824            buf,
825            count,
826            &bfd->rw_bytes,
827            NULL)) {
828          bfd->lerror = GetLastError();
829          bfd->berrno = b_errno_win32;
830          errno = b_errno_win32;
831          return -1;
832       }
833    }
834    bfd->block++;
835    if (bfd->rw_bytes > 0) {
836       bfd->total_bytes += bfd->rw_bytes;
837    }
838    return (ssize_t)bfd->rw_bytes;
839 }
840
841 /* Windows */
842 bool is_bopen(BFILE *bfd)
843 {
844    return bfd->mode != BF_CLOSED;
845 }
846
847 /* Windows */
848 boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
849 {
850    LONG  offset_low = (LONG)offset;
851    LONG  offset_high = (LONG)(offset >> 32);
852    DWORD dwResult;
853
854    if (bfd->cmd_plugin && plugin_blseek) {
855       return plugin_blseek(bfd, offset, whence);
856    }
857
858    dwResult = SetFilePointer(bfd->fh, offset_low, &offset_high, whence);
859
860    if (dwResult == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
861       return (boffset_t)-1;
862    }
863
864    return ((boffset_t)offset_high << 32) | dwResult;
865 }
866
867 #else  /* Unix systems */
868
869 /* ===============================================================
870  *
871  *            U N I X
872  *
873  * ===============================================================
874  */
875 /* Unix */
876 void binit(BFILE *bfd)
877 {
878    memset(bfd, 0, sizeof(BFILE));
879    bfd->fid = -1;
880 }
881
882 /* Unix */
883 bool have_win32_api()
884 {
885    return false;                       /* no can do */
886 }
887
888 /*
889  * Enables using the Backup API (win32_data).
890  *   Returns true  if function worked
891  *   Returns false if failed (i.e. do not have Backup API on this machine)
892  */
893 /* Unix */
894 bool set_win32_backup(BFILE *bfd)
895 {
896    return false;                       /* no can do */
897 }
898
899
900 /* Unix */
901 bool set_portable_backup(BFILE *bfd)
902 {
903    return true;                        /* no problem */
904 }
905
906 /*
907  * Return true  if we are writing in portable format
908  * return false if not
909  */
910 /* Unix */
911 bool is_portable_backup(BFILE *bfd)
912 {
913    return true;                       /* portable by definition */
914 }
915
916 /* Unix */
917 bool set_prog(BFILE *bfd, char *prog, JCR *jcr)
918 {
919    return false;
920 }
921
922 /* Unix */
923 bool set_cmd_plugin(BFILE *bfd, JCR *jcr)
924 {
925    bfd->cmd_plugin = true;
926    bfd->jcr = jcr;
927    return true;
928 }
929
930 /*
931  * This code is running on a non-Win32 machine
932  */
933 /* Unix */
934 bool is_restore_stream_supported(int stream)
935 {
936    /* No Win32 backup on this machine */
937      switch (stream) {
938 #ifndef HAVE_LIBZ
939    case STREAM_GZIP_DATA:
940    case STREAM_SPARSE_GZIP_DATA:
941    case STREAM_WIN32_GZIP_DATA:
942 #endif
943 #ifndef HAVE_LZO
944    case STREAM_COMPRESSED_DATA:
945    case STREAM_SPARSE_COMPRESSED_DATA:
946    case STREAM_WIN32_COMPRESSED_DATA:
947    case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
948    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
949 #endif
950 #ifndef HAVE_DARWIN_OS
951    case STREAM_MACOS_FORK_DATA:
952    case STREAM_HFSPLUS_ATTRIBUTES:
953 #endif
954       return false;
955
956    /* Known streams */
957 #ifdef HAVE_LIBZ
958    case STREAM_GZIP_DATA:
959    case STREAM_SPARSE_GZIP_DATA:
960    case STREAM_WIN32_GZIP_DATA:
961 #endif
962 #ifdef HAVE_LZO
963    case STREAM_COMPRESSED_DATA:
964    case STREAM_SPARSE_COMPRESSED_DATA:
965    case STREAM_WIN32_COMPRESSED_DATA:
966    case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
967    case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
968 #endif
969    case STREAM_WIN32_DATA:
970    case STREAM_UNIX_ATTRIBUTES:
971    case STREAM_FILE_DATA:
972    case STREAM_MD5_DIGEST:
973    case STREAM_UNIX_ATTRIBUTES_EX:
974    case STREAM_SPARSE_DATA:
975    case STREAM_PROGRAM_NAMES:
976    case STREAM_PROGRAM_DATA:
977    case STREAM_SHA1_DIGEST:
978 #ifdef HAVE_SHA2
979    case STREAM_SHA256_DIGEST:
980    case STREAM_SHA512_DIGEST:
981 #endif
982 #ifdef HAVE_CRYPTO
983    case STREAM_SIGNED_DIGEST:
984    case STREAM_ENCRYPTED_FILE_DATA:
985    case STREAM_ENCRYPTED_FILE_GZIP_DATA:
986    case STREAM_ENCRYPTED_WIN32_DATA:
987    case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
988 #endif
989 #ifdef HAVE_DARWIN_OS
990    case STREAM_MACOS_FORK_DATA:
991    case STREAM_HFSPLUS_ATTRIBUTES:
992 #ifdef HAVE_CRYPTO
993    case STREAM_ENCRYPTED_MACOS_FORK_DATA:
994 #endif /* HAVE_CRYPTO */
995 #endif /* HAVE_DARWIN_OS */
996    case 0:   /* compatibility with old tapes */
997       return true;
998
999    }
1000    return false;
1001 }
1002
1003 /* Unix */
1004 int bopen(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
1005 {
1006    if (bfd->cmd_plugin && plugin_bopen) {
1007       Dmsg1(400, "call plugin_bopen fname=%s\n", fname);
1008       bfd->fid = plugin_bopen(bfd, fname, flags, mode);
1009       Dmsg2(400, "Plugin bopen fid=%d file=%s\n", bfd->fid, fname);
1010       return bfd->fid;
1011    }
1012
1013    /* Normal file open */
1014    Dmsg1(dbglvl, "open file %s\n", fname);
1015
1016    /* We use fnctl to set O_NOATIME if requested to avoid open error */
1017    bfd->fid = open(fname, flags & ~O_NOATIME, mode);
1018
1019    /* Set O_NOATIME if possible */
1020    if (bfd->fid != -1 && flags & O_NOATIME) {
1021       int oldflags = fcntl(bfd->fid, F_GETFL, 0);
1022       if (oldflags == -1) {
1023          bfd->berrno = errno;
1024          close(bfd->fid);
1025          bfd->fid = -1;
1026       } else {
1027          int ret = fcntl(bfd->fid, F_SETFL, oldflags | O_NOATIME);
1028         /* EPERM means setting O_NOATIME was not allowed  */
1029          if (ret == -1 && errno != EPERM) {
1030             bfd->berrno = errno;
1031             close(bfd->fid);
1032             bfd->fid = -1;
1033          }
1034       }
1035    }
1036    bfd->berrno = errno;
1037    bfd->m_flags = flags;
1038    bfd->block = 0;
1039    bfd->total_bytes = 0;
1040    Dmsg1(400, "Open file %d\n", bfd->fid);
1041    errno = bfd->berrno;
1042
1043    bfd->win32filter.init();
1044
1045 #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1046    /* If not RDWR or WRONLY must be Read Only */
1047    if (bfd->fid != -1 && !(flags & (O_RDWR|O_WRONLY))) {
1048       int stat = posix_fadvise(bfd->fid, 0, 0, POSIX_FADV_WILLNEED);
1049       Dmsg3(400, "Did posix_fadvise WILLNEED on %s fid=%d stat=%d\n", fname, bfd->fid, stat);
1050    }
1051 #endif
1052
1053    return bfd->fid;
1054 }
1055
1056 #ifdef HAVE_DARWIN_OS
1057 /* Open the resource fork of a file. */
1058 int bopen_rsrc(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
1059 {
1060    POOLMEM *rsrc_fname;
1061
1062    rsrc_fname = get_pool_memory(PM_FNAME);
1063    pm_strcpy(rsrc_fname, fname);
1064    pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
1065    bopen(bfd, rsrc_fname, flags, mode);
1066    free_pool_memory(rsrc_fname);
1067    return bfd->fid;
1068 }
1069 #else /* Unix */
1070
1071 /* Unix */
1072 int bopen_rsrc(BFILE *bfd, const char *fname, uint64_t flags, mode_t mode)
1073     { return -1; }
1074
1075 #endif
1076
1077
1078 /* Unix */
1079 int bclose(BFILE *bfd)
1080 {
1081    int stat;
1082
1083    Dmsg2(400, "Close bfd=%p file %d\n", bfd, bfd->fid);
1084
1085    if (bfd->fid == -1) {
1086       return 0;
1087    }
1088    if (bfd->cmd_plugin && plugin_bclose) {
1089       stat = plugin_bclose(bfd);
1090       bfd->fid = -1;
1091       bfd->cmd_plugin = false;
1092    }
1093
1094 #if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
1095    /* If not RDWR or WRONLY must be Read Only */
1096    if (!(bfd->m_flags & (O_RDWR|O_WRONLY))) {
1097       fdatasync(bfd->fid);            /* sync the file */
1098       /* Tell OS we don't need it any more */
1099       posix_fadvise(bfd->fid, 0, 0, POSIX_FADV_DONTNEED);
1100       Dmsg1(400, "Did posix_fadvise DONTNEED on fid=%d\n", bfd->fid);
1101    }
1102 #endif
1103
1104    /* Close normal file */
1105    stat = close(bfd->fid);
1106    bfd->berrno = errno;
1107    bfd->fid = -1;
1108    bfd->cmd_plugin = false;
1109    return stat;
1110 }
1111
1112 /* Unix */
1113 ssize_t bread(BFILE *bfd, void *buf, size_t count)
1114 {
1115    ssize_t stat;
1116
1117    if (bfd->cmd_plugin && plugin_bread) {
1118       return plugin_bread(bfd, buf, count);
1119    }
1120
1121    stat = read(bfd->fid, buf, count);
1122    bfd->berrno = errno;
1123    bfd->block++;
1124    if (stat > 0) {
1125       bfd->total_bytes += stat;
1126    }
1127    return stat;
1128 }
1129
1130 /* Unix */
1131 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
1132 {
1133    ssize_t stat;
1134
1135    if (bfd->cmd_plugin && plugin_bwrite) {
1136       return plugin_bwrite(bfd, buf, count);
1137    }
1138    stat = write(bfd->fid, buf, count);
1139    bfd->berrno = errno;
1140    bfd->block++;
1141    if (stat > 0) {
1142       bfd->total_bytes += stat;
1143    }
1144    return stat;
1145 }
1146
1147 /* Unix */
1148 bool is_bopen(BFILE *bfd)
1149 {
1150    return bfd->fid >= 0;
1151 }
1152
1153 /* Unix */
1154 boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
1155 {
1156    boffset_t pos;
1157
1158    if (bfd->cmd_plugin && plugin_bwrite) {
1159       return plugin_blseek(bfd, offset, whence);
1160    }
1161    pos = (boffset_t)lseek(bfd->fid, offset, whence);
1162    bfd->berrno = errno;
1163    return pos;
1164 }
1165
1166 #endif