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,
36 void unix_name_to_win32(POOLMEM **win32_name, char *name);
37 extern "C" HANDLE get_osfhandle(int fd);
40 void binit(BFILE *bfd)
43 bfd->mode = BF_CLOSED;
44 bfd->use_backup_api = p_BackupRead && p_BackupWrite;
46 bfd->lpContext = NULL;
51 * Enables/disables using the Backup API (win32_data).
52 * Returns 1 if function worked
53 * Returns 0 if failed (i.e. do not have Backup API on this machine)
55 int set_win32_backup(BFILE *bfd, int enable)
58 bfd->use_backup_api = 0;
61 /* We enable if possible here */
62 bfd->use_backup_api = p_BackupRead && p_BackupWrite;
63 return bfd->use_backup_api;
67 * Return 1 if we can do Win32 backup
70 int is_win32_backup(void)
72 return p_BackupRead && p_BackupWrite;
75 int is_stream_supported(int stream)
77 if (is_win32_backup()) {
80 /* No Win32 backup on this machine */
82 case STREAM_WIN32_ATTRIBUTES:
83 case STREAM_WIN32_DATA:
84 case STREAM_WIN32_GZIP_DATA:
88 case STREAM_UNIX_ATTRIBUTES:
89 case STREAM_FILE_DATA:
90 case STREAM_MD5_SIGNATURE:
91 case STREAM_GZIP_DATA:
92 case STREAM_UNIX_ATTRIBUTES_EX:
93 case STREAM_SPARSE_DATA:
94 case STREAM_SPARSE_GZIP_DATA:
95 case STREAM_PROGRAM_NAMES:
96 case STREAM_PROGRAM_DATA:
97 case STREAM_SHA1_SIGNATURE:
104 HANDLE bget_handle(BFILE *bfd)
109 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
111 POOLMEM *win32_fname;
112 DWORD dwaccess, dwflags;
114 /* Convert to Windows path format */
115 win32_fname = get_pool_memory(PM_FNAME);
116 unix_name_to_win32(&win32_fname, (char *)fname);
118 if (flags & O_CREAT) { /* Create */
119 if (bfd->use_backup_api) {
120 dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
121 dwflags = FILE_FLAG_BACKUP_SEMANTICS;
123 dwaccess = GENERIC_WRITE;
126 bfd->fh = CreateFile(win32_fname,
127 dwaccess, /* Requested access */
129 NULL, /* SecurityAttributes */
130 CREATE_ALWAYS, /* CreationDisposition */
131 dwflags, /* Flags and attributes */
132 NULL); /* TemplateFile */
133 bfd->mode = BF_WRITE;
135 } else if (flags & O_WRONLY) { /* Open existing for write */
136 if (bfd->use_backup_api) {
137 dwaccess = FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
138 dwflags = FILE_FLAG_BACKUP_SEMANTICS;
140 dwaccess = GENERIC_WRITE;
143 bfd->fh = CreateFile(win32_fname,
144 dwaccess, /* Requested access */
146 NULL, /* SecurityAttributes */
147 OPEN_EXISTING, /* CreationDisposition */
148 dwflags, /* Flags and attributes */
149 NULL); /* TemplateFile */
150 bfd->mode = BF_WRITE;
153 if (bfd->use_backup_api) {
154 dwaccess = GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY;
155 dwflags = FILE_FLAG_BACKUP_SEMANTICS;
157 dwaccess = GENERIC_READ;
160 bfd->fh = CreateFile(win32_fname,
161 dwaccess, /* Requested access */
162 FILE_SHARE_READ, /* Shared mode */
163 NULL, /* SecurityAttributes */
164 OPEN_EXISTING, /* CreationDisposition */
165 dwflags, /* Flags and attributes */
166 NULL); /* TemplateFile */
170 if (bfd->fh == INVALID_HANDLE_VALUE) {
171 bfd->lerror = GetLastError();
172 bfd->mode = BF_CLOSED;
175 bfd->lpContext = NULL;
176 return bfd->mode == BF_CLOSED ? -1 : 1;
180 * Returns 0 on success
183 int bclose(BFILE *bfd)
188 free_pool_memory(bfd->errmsg);
191 if (bfd->mode == BF_CLOSED) {
194 if (bfd->use_backup_api && bfd->mode == BF_READ) {
196 if (!bfd->lpContext && !p_BackupRead(bfd->fh,
198 (DWORD)0, /* bytes to read */
199 &bfd->rw_bytes, /* bytes read */
201 1, /* ProcessSecurity */
202 &bfd->lpContext)) { /* Read context */
205 } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) {
207 if (!bfd->lpContext && !p_BackupWrite(bfd->fh,
209 (DWORD)0, /* bytes to read */
210 &bfd->rw_bytes, /* bytes written */
212 1, /* ProcessSecurity */
213 &bfd->lpContext)) { /* Write context */
217 if (!CloseHandle(bfd->fh)) {
220 bfd->mode = BF_CLOSED;
221 bfd->lpContext = NULL;
226 * Generate error message
228 char *berror(BFILE *bfd)
232 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
233 FORMAT_MESSAGE_FROM_SYSTEM,
240 strip_trailing_junk(msg);
242 bfd->errmsg = get_pool_memory(PM_FNAME);
244 pm_strcpy(&bfd->errmsg, msg);
249 /* Returns: bytes read on success
253 ssize_t bread(BFILE *bfd, void *buf, size_t count)
257 if (bfd->use_backup_api) {
258 if (!p_BackupRead(bfd->fh,
263 1, /* Process Security */
264 &bfd->lpContext)) { /* Context */
265 bfd->lerror = GetLastError();
269 if (!ReadFile(bfd->fh,
274 bfd->lerror = GetLastError();
279 return (ssize_t)bfd->rw_bytes;
282 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
286 if (bfd->use_backup_api) {
287 if (!p_BackupWrite(bfd->fh,
292 1, /* Process Security */
293 &bfd->lpContext)) { /* Context */
294 bfd->lerror = GetLastError();
298 if (!WriteFile(bfd->fh,
303 bfd->lerror = GetLastError();
307 return (ssize_t)bfd->rw_bytes;
310 int is_bopen(BFILE *bfd)
312 return bfd->mode != BF_CLOSED;
315 off_t blseek(BFILE *bfd, off_t offset, int whence)
317 /* ****FIXME**** this is needed if we want to read Win32 Archives */
321 #else /* Unix systems */
323 /* ===============================================================
327 * ===============================================================
329 void binit(BFILE *bfd)
334 int set_win32_backup(BFILE *bfd, int enable)
339 int is_win32_backup(void)
344 int is_stream_supported(int stream)
346 /* No Win32 backup on this machine */
348 case STREAM_WIN32_ATTRIBUTES:
349 case STREAM_WIN32_DATA:
350 case STREAM_WIN32_GZIP_DATA:
354 case STREAM_UNIX_ATTRIBUTES:
355 case STREAM_FILE_DATA:
356 case STREAM_MD5_SIGNATURE:
357 case STREAM_GZIP_DATA:
358 case STREAM_UNIX_ATTRIBUTES_EX:
359 case STREAM_SPARSE_DATA:
360 case STREAM_SPARSE_GZIP_DATA:
361 case STREAM_PROGRAM_NAMES:
362 case STREAM_PROGRAM_DATA:
363 case STREAM_SHA1_SIGNATURE:
370 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
372 bfd->fid = open(fname, flags, mode);
377 int bclose(BFILE *bfd)
379 int stat = close(bfd->fid);
385 ssize_t bread(BFILE *bfd, void *buf, size_t count)
388 stat = read(bfd->fid, buf, count);
393 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
396 stat = write(bfd->fid, buf, count);
401 int is_bopen(BFILE *bfd)
403 return bfd->fid >= 0;
406 off_t blseek(BFILE *bfd, off_t offset, int whence)
409 pos = lseek(bfd->fid, offset, whence);
414 char *berror(BFILE *bfd)
416 return strerror(bfd->berrno);