]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/bfile.c
Major part of Win32 BackupRead/Write done
[bacula/bacula] / bacula / src / findlib / bfile.c
1 /*
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.
5  *
6  *    Kern Sibbald, April MMIII
7  *
8  *   Version $Id$
9  *
10  */
11 /*
12    Copyright (C) 2000-2003 Kern Sibbald and John Walker
13
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.
18
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.
23
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,
27    MA 02111-1307, USA.
28
29  */
30
31 #include "bacula.h"
32 #include "find.h"
33
34 #ifdef HAVE_CYGWIN
35
36 void unix_name_to_win32(POOLMEM **win32_name, char *name);
37 extern "C" HANDLE get_osfhandle(int fd);
38
39
40 void binit(BFILE *bfd)
41 {
42    bfd->fid = -1;
43    bfd->mode = BF_CLOSED;
44    bfd->use_backup_api = p_BackupRead && p_BackupWrite;
45    bfd->errmsg = NULL;
46    bfd->lpContext = NULL;
47    bfd->lerror = 0;
48 }
49
50 /*
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)
54  */
55 int set_win32_data(BFILE *bfd, int enable)
56 {
57    if (!enable) {
58       bfd->use_backup_api = 0;
59       return 1;
60    }
61    /* We enable if possible here */
62    bfd->use_backup_api = p_BackupRead && p_BackupWrite;
63    return bfd->use_backup_api;
64 }
65
66 int is_win32_data(BFILE *bfd)
67 {
68    return bfd->use_backup_api;
69 }
70
71 HANDLE bget_handle(BFILE *bfd)
72 {
73 #ifdef xxx
74    if (!bfd->use_win_api) {
75       return get_osfhandle(bfd->fid);
76    }
77 #endif
78    return bfd->fh;
79 }
80
81 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
82 {
83    POOLMEM *win32_fname;
84
85 #ifdef xxx
86    if (!bfd->use_win_api) {
87       bfd->fid = open(fname, flags, mode);
88       if (bfd->fid >= 0) {
89          bfd->mode = BF_READ;         /* not important if BF_READ or BF_WRITE */
90       }
91       return bfd->fid;
92    }
93 #endif
94
95    /* Convert to Windows path format */
96    win32_fname = get_pool_memory(PM_FNAME);
97    unix_name_to_win32(&win32_fname, (char *)fname);
98
99    if (flags & O_CREAT) {
100       bfd->fh = CreateFile(win32_fname,
101              GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY,    /* access */
102              0,
103              NULL,                                   /* SecurityAttributes */
104              CREATE_ALWAYS,                          /* CreationDisposition */
105              FILE_FLAG_BACKUP_SEMANTICS,             /* Flags and attributes */
106              NULL);                                  /* TemplateFile */
107       bfd->mode = BF_WRITE;
108    } else if (flags & O_WRONLY) {            /* creating */
109       bfd->fh = CreateFile(win32_fname,
110              FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY,    /* access */
111              0,
112              NULL,                                   /* SecurityAttributes */
113              OPEN_EXISTING,                          /* CreationDisposition */
114              FILE_FLAG_BACKUP_SEMANTICS,             /* Flags and attributes */
115              NULL);
116       bfd->mode = BF_WRITE;
117    } else {
118       bfd->fh = CreateFile(win32_fname,
119              GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY,       /* access */
120              FILE_SHARE_READ,                         /* shared mode */
121              NULL,                                   /* SecurityAttributes */
122              OPEN_EXISTING,                          /* CreationDisposition */
123              FILE_FLAG_BACKUP_SEMANTICS,  /* Flags and attributes */
124              NULL);                       /* TemplateFile */
125
126       bfd->mode = BF_READ;
127    }
128    if (bfd->fh == INVALID_HANDLE_VALUE) {
129       bfd->lerror = GetLastError();
130       bfd->mode = BF_CLOSED;
131    }
132    bfd->errmsg = NULL;
133    bfd->lpContext = NULL;
134    return bfd->mode == BF_CLOSED ? -1 : 1;
135 }
136
137 /* 
138  * Returns  0 on success
139  *         -1 on error
140  */
141 int bclose(BFILE *bfd)
142
143    int stat = 0;
144 #ifdef xxx
145    if (!bfd->use_win_api) {
146       int stat = close(bfd->fid);
147       bfd->fid = -1;
148       bfd->mode = BF_CLOSED;
149       return stat;
150    }
151 #endif
152    if (bfd->errmsg) {
153       free_pool_memory(bfd->errmsg);
154       bfd->errmsg = NULL;
155    }
156    if (bfd->mode == BF_CLOSED) {
157       return 0;
158    }
159    if (bfd->use_backup_api && bfd->mode == BF_READ) {
160       BYTE buf[10];
161       if (!bfd->lpContext && !p_BackupRead(bfd->fh,   
162               buf,                    /* buffer */
163               (DWORD)0,               /* bytes to read */
164               &bfd->rw_bytes,         /* bytes read */
165               1,                      /* Abort */
166               1,                      /* ProcessSecurity */
167               &bfd->lpContext)) {     /* Read context */
168          stat = -1;
169       } 
170    } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) {
171       BYTE buf[10];
172       if (!bfd->lpContext && !p_BackupWrite(bfd->fh,   
173               buf,                    /* buffer */
174               (DWORD)0,               /* bytes to read */
175               &bfd->rw_bytes,         /* bytes written */
176               1,                      /* Abort */
177               1,                      /* ProcessSecurity */
178               &bfd->lpContext)) {     /* Write context */
179          stat = -1;
180       } 
181    }
182    if (!CloseHandle(bfd->fh)) {
183       stat = -1;
184    }
185    bfd->mode = BF_CLOSED;
186    bfd->lpContext = NULL;
187    return stat;
188 }
189
190 /*
191  * Generate error message 
192  */
193 char *berror(BFILE *bfd)
194 {
195    LPTSTR msg;
196 #ifdef xxx
197    if (!bfd->use_win_api) {
198       return strerror(errno);
199    }
200 #endif
201    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
202                  FORMAT_MESSAGE_FROM_SYSTEM,
203                  NULL,
204                  bfd->lerror,
205                  0,
206                  (LPTSTR)&msg,
207                  0,
208                  NULL);
209    strip_trailing_junk(msg);
210    if (!bfd->errmsg) {
211       bfd->errmsg = get_pool_memory(PM_FNAME);
212    }
213    pm_strcpy(&bfd->errmsg, msg);
214    LocalFree(msg);
215    return bfd->errmsg;
216 }
217
218 /* Returns: bytes read on success
219  *           0         on EOF
220  *          -1         on error
221  */
222 ssize_t bread(BFILE *bfd, void *buf, size_t count)
223 {
224 #ifdef xxx
225    if (!bfd->use_win_api) {
226       return read(bfd->fid, buf, count);
227    }
228 #endif
229    bfd->rw_bytes = 0;
230
231    if (bfd->use_backup_api) {
232       if (!p_BackupRead(bfd->fh,
233            (BYTE *)buf,
234            count,
235            &bfd->rw_bytes,
236            0,                           /* no Abort */
237            1,                           /* Process Security */
238            &bfd->lpContext)) {          /* Context */
239          bfd->lerror = GetLastError();
240          return -1;
241       }
242    } else {
243       if (!ReadFile(bfd->fh,
244            buf,
245            count,
246            &bfd->rw_bytes,
247            NULL)) {
248          bfd->lerror = GetLastError();
249          return -1;
250       }
251    }
252
253    return (ssize_t)bfd->rw_bytes;
254 }
255
256 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
257 {
258 #ifdef xxx
259    if (!bfd->use_win_api) {
260       return write(bfd->fid, buf, count);
261    }
262 #endif
263    bfd->rw_bytes = 0;
264
265    if (bfd->use_backup_api) {
266       if (!p_BackupWrite(bfd->fh,
267            (BYTE *)buf,
268            count,
269            &bfd->rw_bytes,
270            0,                           /* No abort */
271            1,                           /* Process Security */
272            &bfd->lpContext)) {          /* Context */
273          bfd->lerror = GetLastError();
274          return -1;
275       }
276    } else {
277       if (!WriteFile(bfd->fh,
278            buf,
279            count,
280            &bfd->rw_bytes,
281            NULL)) {
282          bfd->lerror = GetLastError();
283          return -1;
284       }
285    }
286    return (ssize_t)bfd->rw_bytes;
287 }
288
289 int is_bopen(BFILE *bfd)
290 {
291    return bfd->mode != BF_CLOSED;
292 }
293
294 off_t blseek(BFILE *bfd, off_t offset, int whence)
295 {
296 #ifdef xxx
297    if (!bfd->use_win_api) {
298       return lseek(bfd->fid, offset, whence);
299    }
300 #endif
301    /* ****FIXME**** this is needed if we want to read Win32 Archives */
302    return -1;
303 }
304
305 #else  /* Unix systems */
306
307 /* ===============================================================
308  * 
309  *            U N I X
310  *
311  * ===============================================================
312  */
313 void binit(BFILE *bfd)
314 {
315    bfd->fid = -1;
316 }
317
318 int is_win32_data(BFILE *bfd)
319 {
320    return 0;
321 }
322
323
324 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
325 {
326    bfd->fid = open(fname, flags, mode);
327    bfd->berrno = errno;
328    return bfd->fid;
329 }
330
331 int bclose(BFILE *bfd)
332
333    int stat = close(bfd->fid);
334    bfd->berrno = errno;
335    bfd->fid = -1;
336    return stat;
337 }
338
339 ssize_t bread(BFILE *bfd, void *buf, size_t count)
340 {
341    ssize_t stat;
342    stat = read(bfd->fid, buf, count);
343    bfd->berrno = errno;
344    return stat;
345 }
346
347 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
348 {
349    ssize_t stat;
350    stat = write(bfd->fid, buf, count);
351    bfd->berrno = errno;
352    return stat;
353 }
354
355 int is_bopen(BFILE *bfd)
356 {
357    return bfd->fid >= 0;
358 }
359
360 off_t blseek(BFILE *bfd, off_t offset, int whence)
361 {
362     off_t pos;
363     pos = lseek(bfd->fid, offset, whence);
364     bfd->berrno = errno;
365     return pos;
366 }
367
368 char *berror(BFILE *bfd)
369 {
370     return strerror(bfd->berrno);
371 }
372
373 #endif