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_win_api = p_BackupRead && p_BackupWrite;
46 bfd->lpContext = NULL;
50 HANDLE bget_handle(BFILE *bfd)
52 if (!bfd->use_win_api) {
53 return get_osfhandle(bfd->fid);
58 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
62 if (!bfd->use_win_api) {
63 bfd->fid = open(fname, flags, mode);
65 bfd->mode = BF_READ; /* not important if BF_READ or BF_WRITE */
70 /* Convert to Windows path format */
71 win32_fname = get_pool_memory(PM_FNAME);
72 unix_name_to_win32(&win32_fname, (char *)fname);
74 if (flags & O_WRONLY) { /* creating */
75 bfd->fh = CreateFile(win32_fname,
76 FILE_ALL_ACCESS|WRITE_DAC|ACCESS_SYSTEM_SECURITY, /* access */
78 NULL, /* SecurityAttributes */
79 CREATE_ALWAYS, /* CreationDisposition */
80 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, /* Flags and attributes */
81 NULL); /* TemplateFile */
83 if (bfd->fh == INVALID_HANDLE_VALUE) {
84 bfd->lerror = GetLastError();
85 bfd->mode = BF_CLOSED;
90 bfd->fh = CreateFile(win32_fname,
91 GENERIC_READ|ACCESS_SYSTEM_SECURITY, /* access */
92 FILE_SHARE_READ, /* shared mode */
93 NULL, /* SecurityAttributes */
94 OPEN_EXISTING, /* CreationDisposition */
95 FILE_FLAG_BACKUP_SEMANTICS, /* Flags and attributes */
96 NULL); /* TemplateFile */
98 if (bfd->fh == INVALID_HANDLE_VALUE) {
99 bfd->lerror = GetLastError();
100 bfd->mode = BF_CLOSED;
106 bfd->lpContext = NULL;
107 return bfd->mode == BF_CLOSED ? -1 : 1;
111 * Returns 0 on success
114 int bclose(BFILE *bfd)
117 if (!bfd->use_win_api) {
118 int stat = close(bfd->fid);
120 bfd->mode = BF_CLOSED;
124 free_pool_memory(bfd->errmsg);
127 if (bfd->mode == BF_CLOSED) {
130 if (bfd->mode == BF_READ) {
132 if (!bfd->lpContext && !p_BackupRead(bfd->fh,
134 (DWORD)0, /* bytes to read */
135 &bfd->rw_bytes, /* bytes read */
137 1, /* ProcessSecurity */
138 &bfd->lpContext)) { /* Read context */
143 if (!bfd->lpContext && !p_BackupWrite(bfd->fh,
145 (DWORD)0, /* bytes to read */
146 &bfd->rw_bytes, /* bytes written */
148 1, /* ProcessSecurity */
149 &bfd->lpContext)) { /* Write context */
153 if (!CloseHandle(bfd->fh)) {
156 bfd->mode = BF_CLOSED;
157 bfd->lpContext = NULL;
162 * Generate error message
164 char *berror(BFILE *bfd)
168 if (!bfd->use_win_api) {
169 return strerror(errno);
171 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
172 FORMAT_MESSAGE_FROM_SYSTEM,
179 strip_trailing_junk(msg);
181 bfd->errmsg = get_pool_memory(PM_FNAME);
183 pm_strcpy(&bfd->errmsg, msg);
188 /* Returns: bytes read on success
192 ssize_t bread(BFILE *bfd, void *buf, size_t count)
194 if (!bfd->use_win_api) {
195 return read(bfd->fid, buf, count);
199 if (!p_BackupRead(bfd->fh,
204 1, /* Process Security */
205 &bfd->lpContext)) { /* Context */
206 bfd->lerror = GetLastError();
209 return (ssize_t)bfd->rw_bytes;
212 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
214 if (!bfd->use_win_api) {
215 return write(bfd->fid, buf, count);
219 if (!p_BackupWrite(bfd->fh,
224 1, /* Process Security */
225 &bfd->lpContext)) { /* Context */
226 bfd->lerror = GetLastError();
229 return (ssize_t)bfd->rw_bytes;
232 int is_bopen(BFILE *bfd)
234 return bfd->mode != BF_CLOSED;
237 off_t blseek(BFILE *bfd, off_t offset, int whence)
239 if (!bfd->use_win_api) {
240 return lseek(bfd->fid, offset, whence);
245 #else /* Unix systems */
247 /* ===============================================================
251 * ===============================================================
253 void binit(BFILE *bfd)
258 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
260 return bfd->fid = open(fname, flags, mode);
263 int bclose(BFILE *bfd)
265 int stat = close(bfd->fid);
270 ssize_t bread(BFILE *bfd, void *buf, size_t count)
272 return read(bfd->fid, buf, count);
275 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
277 return write(bfd->fid, buf, count);
280 int is_bopen(BFILE *bfd)
282 return bfd->fid >= 0;
285 off_t blseek(BFILE *bfd, off_t offset, int whence)
287 return lseek(bfd->fid, offset, whence);
290 char *berror(BFILE *bfd)
292 return strerror(errno);