2 * Bacula low level File I/O routines. This routine simulates
3 * open(), read(), write(), and close(), but using native routines.
4 * I.e. on Windows, we use Windows APIs.
6 * Kern Sibbald, April MMIII
12 Copyright (C) 2000-2003 Kern Sibbald and John Walker
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of
17 the License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public
25 License along with this program; if not, write to the Free
26 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
34 /* ===============================================================
36 * U N I X AND W I N D O W S
38 * ===============================================================
41 int is_win32_stream(int stream)
44 case STREAM_WIN32_DATA:
45 case STREAM_WIN32_GZIP_DATA:
51 char *stream_to_ascii(int stream)
56 case STREAM_GZIP_DATA:
58 case STREAM_SPARSE_GZIP_DATA:
59 return "GZIP sparse data";
60 case STREAM_WIN32_DATA:
62 case STREAM_WIN32_GZIP_DATA:
63 return "Win32 GZIP data";
64 case STREAM_UNIX_ATTRIBUTES:
65 return "File attributes";
66 case STREAM_FILE_DATA:
68 case STREAM_MD5_SIGNATURE:
69 return "MD5 signature";
70 case STREAM_UNIX_ATTRIBUTES_EX:
71 return "Extended attributes";
72 case STREAM_SPARSE_DATA:
74 case STREAM_PROGRAM_NAMES:
75 return "Program names";
76 case STREAM_PROGRAM_DATA:
77 return "Program data";
78 case STREAM_SHA1_SIGNATURE:
79 return "SHA1 signature";
81 sprintf(buf, "%d", stream);
88 /* ===============================================================
92 * ===============================================================
97 void unix_name_to_win32(POOLMEM **win32_name, char *name);
98 extern "C" HANDLE get_osfhandle(int fd);
102 void binit(BFILE *bfd)
105 bfd->mode = BF_CLOSED;
106 bfd->use_backup_api = have_win32_api();
108 bfd->lpContext = NULL;
113 * Enables using the Backup API (win32_data).
114 * Returns 1 if function worked
115 * Returns 0 if failed (i.e. do not have Backup API on this machine)
117 int set_win32_backup(BFILE *bfd)
119 /* We enable if possible here */
120 bfd->use_backup_api = have_win32_api();
121 return bfd->use_backup_api;
125 int set_portable_backup(BFILE *bfd)
127 bfd->use_backup_api = 0;
132 * Return 1 if we are NOT using Win32 BackupWrite()
135 int is_portable_backup(BFILE *bfd)
137 return !bfd->use_backup_api;
142 return p_BackupRead && p_BackupWrite;
148 * Return 1 if we support the stream
149 * 0 if we do not support the stream
151 int is_stream_supported(int stream)
153 /* No Win32 backup on this machine */
156 case STREAM_GZIP_DATA:
157 case STREAM_SPARSE_GZIP_DATA:
160 case STREAM_WIN32_DATA:
161 case STREAM_WIN32_GZIP_DATA:
162 return have_win32_api();
166 case STREAM_GZIP_DATA:
167 case STREAM_SPARSE_GZIP_DATA:
169 case STREAM_UNIX_ATTRIBUTES:
170 case STREAM_FILE_DATA:
171 case STREAM_MD5_SIGNATURE:
172 case STREAM_UNIX_ATTRIBUTES_EX:
173 case STREAM_SPARSE_DATA:
174 case STREAM_PROGRAM_NAMES:
175 case STREAM_PROGRAM_DATA:
176 case STREAM_SHA1_SIGNATURE:
177 case 0: /* compatibility with old tapes */
183 HANDLE bget_handle(BFILE *bfd)
188 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
190 POOLMEM *win32_fname;
191 DWORD dwaccess, dwflags;
193 /* Convert to Windows path format */
194 win32_fname = get_pool_memory(PM_FNAME);
195 unix_name_to_win32(&win32_fname, (char *)fname);
197 if (flags & O_CREAT) { /* Create */
198 if (bfd->use_backup_api) {
199 dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
200 dwflags = FILE_FLAG_BACKUP_SEMANTICS;
202 dwaccess = GENERIC_WRITE;
205 bfd->fh = CreateFile(win32_fname,
206 dwaccess, /* Requested access */
208 NULL, /* SecurityAttributes */
209 CREATE_ALWAYS, /* CreationDisposition */
210 dwflags, /* Flags and attributes */
211 NULL); /* TemplateFile */
212 bfd->mode = BF_WRITE;
214 } else if (flags & O_WRONLY) { /* Open existing for write */
215 if (bfd->use_backup_api) {
216 dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
217 dwflags = FILE_FLAG_BACKUP_SEMANTICS;
219 dwaccess = GENERIC_WRITE;
222 bfd->fh = CreateFile(win32_fname,
223 dwaccess, /* Requested access */
225 NULL, /* SecurityAttributes */
226 OPEN_EXISTING, /* CreationDisposition */
227 dwflags, /* Flags and attributes */
228 NULL); /* TemplateFile */
229 bfd->mode = BF_WRITE;
232 if (bfd->use_backup_api) {
233 dwaccess = GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY;
234 dwflags = FILE_FLAG_BACKUP_SEMANTICS;
236 dwaccess = GENERIC_READ;
239 bfd->fh = CreateFile(win32_fname,
240 dwaccess, /* Requested access */
241 FILE_SHARE_READ, /* Shared mode */
242 NULL, /* SecurityAttributes */
243 OPEN_EXISTING, /* CreationDisposition */
244 dwflags, /* Flags and attributes */
245 NULL); /* TemplateFile */
249 if (bfd->fh == INVALID_HANDLE_VALUE) {
250 bfd->lerror = GetLastError();
251 bfd->mode = BF_CLOSED;
254 bfd->lpContext = NULL;
255 free_pool_memory(win32_fname);
256 return bfd->mode == BF_CLOSED ? -1 : 1;
260 * Returns 0 on success
263 int bclose(BFILE *bfd)
268 free_pool_memory(bfd->errmsg);
271 if (bfd->mode == BF_CLOSED) {
274 if (bfd->use_backup_api && bfd->mode == BF_READ) {
276 if (!bfd->lpContext && !p_BackupRead(bfd->fh,
278 (DWORD)0, /* bytes to read */
279 &bfd->rw_bytes, /* bytes read */
281 1, /* ProcessSecurity */
282 &bfd->lpContext)) { /* Read context */
285 } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) {
287 if (!bfd->lpContext && !p_BackupWrite(bfd->fh,
289 (DWORD)0, /* bytes to read */
290 &bfd->rw_bytes, /* bytes written */
292 1, /* ProcessSecurity */
293 &bfd->lpContext)) { /* Write context */
297 if (!CloseHandle(bfd->fh)) {
300 bfd->mode = BF_CLOSED;
301 bfd->lpContext = NULL;
306 * Generate error message
308 char *berror(BFILE *bfd)
312 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
313 FORMAT_MESSAGE_FROM_SYSTEM,
320 strip_trailing_junk(msg);
322 bfd->errmsg = get_pool_memory(PM_FNAME);
324 pm_strcpy(&bfd->errmsg, msg);
329 /* Returns: bytes read on success
333 ssize_t bread(BFILE *bfd, void *buf, size_t count)
337 if (bfd->use_backup_api) {
338 if (!p_BackupRead(bfd->fh,
343 1, /* Process Security */
344 &bfd->lpContext)) { /* Context */
345 bfd->lerror = GetLastError();
349 if (!ReadFile(bfd->fh,
354 bfd->lerror = GetLastError();
359 return (ssize_t)bfd->rw_bytes;
362 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
366 if (bfd->use_backup_api) {
367 if (!p_BackupWrite(bfd->fh,
372 1, /* Process Security */
373 &bfd->lpContext)) { /* Context */
374 bfd->lerror = GetLastError();
378 if (!WriteFile(bfd->fh,
383 bfd->lerror = GetLastError();
387 return (ssize_t)bfd->rw_bytes;
390 int is_bopen(BFILE *bfd)
392 return bfd->mode != BF_CLOSED;
395 off_t blseek(BFILE *bfd, off_t offset, int whence)
397 /* ****FIXME**** this is needed if we want to read Win32 Archives */
401 #else /* Unix systems */
403 /* ===============================================================
407 * ===============================================================
409 void binit(BFILE *bfd)
416 return 0; /* no can do */
420 * Enables using the Backup API (win32_data).
421 * Returns 1 if function worked
422 * Returns 0 if failed (i.e. do not have Backup API on this machine)
424 int set_win32_backup(BFILE *bfd)
426 return 0; /* no can do */
430 int set_portable_backup(BFILE *bfd)
432 return 1; /* no problem */
436 * Return 1 if we are writing in portable format
439 int is_portable_backup(BFILE *bfd)
441 return 1; /* portable by definition */
444 int is_stream_supported(int stream)
446 /* No Win32 backup on this machine */
449 case STREAM_GZIP_DATA:
450 case STREAM_SPARSE_GZIP_DATA:
452 case STREAM_WIN32_DATA:
453 case STREAM_WIN32_GZIP_DATA:
458 case STREAM_GZIP_DATA:
459 case STREAM_SPARSE_GZIP_DATA:
461 case STREAM_UNIX_ATTRIBUTES:
462 case STREAM_FILE_DATA:
463 case STREAM_MD5_SIGNATURE:
464 case STREAM_UNIX_ATTRIBUTES_EX:
465 case STREAM_SPARSE_DATA:
466 case STREAM_PROGRAM_NAMES:
467 case STREAM_PROGRAM_DATA:
468 case STREAM_SHA1_SIGNATURE:
469 case 0: /* compatibility with old tapes */
476 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
478 bfd->fid = open(fname, flags, mode);
480 Dmsg1(50, "Open file %d\n", bfd->fid);
484 int bclose(BFILE *bfd)
487 Dmsg1(50, "Close file %d\n", bfd->fid);
488 stat = close(bfd->fid);
495 ssize_t bread(BFILE *bfd, void *buf, size_t count)
498 stat = read(bfd->fid, buf, count);
503 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
506 stat = write(bfd->fid, buf, count);
511 int is_bopen(BFILE *bfd)
513 return bfd->fid >= 0;
516 off_t blseek(BFILE *bfd, off_t offset, int whence)
519 pos = lseek(bfd->fid, offset, whence);
524 char *berror(BFILE *bfd)
526 return strerror(bfd->berrno);