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 * Written by James Harper, July 2010
21 *
22 * Used only in "old Exchange plugin" now deprecated.
23 */
24
25 #include "exchange-fd.h"
26
file_node_t(char * name,node_t * parent_node)27 file_node_t::file_node_t(char *name, node_t *parent_node) : node_t(name, NODE_TYPE_FILE, parent_node)
28 {
29 backup_file_handle = INVALID_HANDLE_VALUE;
30 restore_file_handle = INVALID_HANDLE_VALUE;
31 restore_at_file_level = FALSE;
32 }
33
~file_node_t()34 file_node_t::~file_node_t()
35 {
36 if (backup_file_handle != INVALID_HANDLE_VALUE)
37 {
38 //_DebugMessage(100, "closing file handle in destructor\n");
39 CloseHandle(backup_file_handle);
40 }
41 if (restore_file_handle != INVALID_HANDLE_VALUE)
42 {
43 //_DebugMessage(100, "closing file handle in destructor\n");
44 if (restore_at_file_level)
45 {
46 CloseHandle(restore_file_handle);
47 }
48 else
49 {
50 // maybe one day
51 }
52 }
53 }
54
55 bRC
startBackupFile(exchange_fd_context_t * context,struct save_pkt * sp)56 file_node_t::startBackupFile(exchange_fd_context_t *context, struct save_pkt *sp)
57 {
58 time_t now = time(NULL);
59 _DebugMessage(100, "startBackupNode_FILE state = %d\n", state);
60
61 if (context->job_level == 'F' || parent->type == NODE_TYPE_STORAGE_GROUP) {
62 sp->fname = full_path;
63 sp->link = full_path;
64 _DebugMessage(100, "fname = %s\n", sp->fname);
65 sp->statp.st_mode = 0700 | S_IFREG;
66 sp->statp.st_ctime = now;
67 sp->statp.st_mtime = now;
68 sp->statp.st_atime = now;
69 sp->statp.st_size = (uint64_t)-1;
70 sp->type = FT_REG;
71 return bRC_OK;
72 } else {
73 bfuncs->setBaculaValue(context->bpContext, bVarFileSeen, (void *)full_path);
74 return bRC_Seen;
75 }
76 }
77
78 bRC
endBackupFile(exchange_fd_context_t * context)79 file_node_t::endBackupFile(exchange_fd_context_t *context)
80 {
81 _DebugMessage(100, "endBackupNode_FILE state = %d\n", state);
82
83 context->current_node = parent;
84
85 return bRC_OK;
86 }
87
88 bRC
createFile(exchange_fd_context_t * context,struct restore_pkt * rp)89 file_node_t::createFile(exchange_fd_context_t *context, struct restore_pkt *rp)
90 {
91 //HrESERestoreOpenFile with name of log file
92
93 _DebugMessage(0, "createFile_FILE state = %d\n", state);
94 rp->create_status = CF_EXTRACT;
95 return bRC_OK;
96 }
97
98 bRC
endRestoreFile(exchange_fd_context_t * context)99 file_node_t::endRestoreFile(exchange_fd_context_t *context)
100 {
101 _DebugMessage(0, "endRestoreFile_FILE state = %d\n", state);
102 context->current_node = parent;
103 return bRC_OK;
104 }
105
106 bRC
pluginIoOpen(exchange_fd_context_t * context,struct io_pkt * io)107 file_node_t::pluginIoOpen(exchange_fd_context_t *context, struct io_pkt *io)
108 {
109 HRESULT result;
110 HANDLE handle;
111 char *tmp = new char[wcslen(filename) + 1];
112 wcstombs(tmp, filename, wcslen(filename) + 1);
113
114 _DebugMessage(0, "pluginIoOpen_FILE - filename = %s\n", tmp);
115 io->status = 0;
116 io->io_errno = 0;
117 if (context->job_type == JOB_TYPE_BACKUP)
118 {
119 _DebugMessage(10, "Calling HrESEBackupOpenFile\n");
120 result = HrESEBackupOpenFile(hccx, filename, 65535, 1, &backup_file_handle, §ion_size);
121 if (result)
122 {
123 _JobMessage(M_FATAL, "HrESEBackupOpenFile failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
124 backup_file_handle = INVALID_HANDLE_VALUE;
125 io->io_errno = 1;
126 return bRC_Error;
127 }
128 }
129 else
130 {
131 _DebugMessage(10, "Calling HrESERestoreOpenFile for '%s'\n", tmp);
132 result = HrESERestoreOpenFile(hccx, filename, 1, &restore_file_handle);
133 if (result == hrRestoreAtFileLevel)
134 {
135 restore_at_file_level = true;
136 _DebugMessage(100, "Calling CreateFileW for '%s'\n", tmp);
137 handle = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
138 if (handle == INVALID_HANDLE_VALUE)
139 {
140 _JobMessage(M_FATAL, "CreateFile failed");
141 return bRC_Error;
142 }
143 restore_file_handle = (void *)handle;
144 return bRC_OK;
145 }
146 else if (result == 0)
147 {
148 _JobMessage(M_FATAL, "Exchange File IO API not yet supported for restore\n");
149 restore_at_file_level = false;
150 return bRC_Error;
151 }
152 else
153 {
154 _JobMessage(M_FATAL, "HrESERestoreOpenFile failed with error 0x%08x - %s\n", result, ESEErrorMessage(result));
155 return bRC_Error;
156 }
157 }
158 return bRC_OK;
159 }
160
161 bRC
pluginIoRead(exchange_fd_context_t * context,struct io_pkt * io)162 file_node_t::pluginIoRead(exchange_fd_context_t *context, struct io_pkt *io)
163 {
164 HRESULT result;
165 uint32_t readLength;
166
167 io->status = 0;
168 io->io_errno = 0;
169 _DebugMessage(200, "Calling HrESEBackupReadFile\n");
170 result = HrESEBackupReadFile(hccx, backup_file_handle, io->buf, io->count, &readLength);
171 if (result)
172 {
173 io->io_errno = 1;
174 return bRC_Error;
175 }
176 io->status = readLength;
177 size += readLength;
178 return bRC_OK;
179 }
180
181 bRC
pluginIoWrite(exchange_fd_context_t * context,struct io_pkt * io)182 file_node_t::pluginIoWrite(exchange_fd_context_t *context, struct io_pkt *io)
183 {
184 DWORD bytes_written;
185
186 io->io_errno = 0;
187 if (!restore_at_file_level)
188 return bRC_Error;
189
190 if (!WriteFile(restore_file_handle, io->buf, io->count, &bytes_written, NULL))
191 {
192 _JobMessage(M_FATAL, "Write Error");
193 return bRC_Error;
194 }
195
196 if (bytes_written != (DWORD)io->count)
197 {
198 _JobMessage(M_FATAL, "Short write");
199 return bRC_Error;
200 }
201 io->status = bytes_written;
202
203 return bRC_OK;
204 }
205
206 bRC
pluginIoClose(exchange_fd_context_t * context,struct io_pkt * io)207 file_node_t::pluginIoClose(exchange_fd_context_t *context, struct io_pkt *io)
208 {
209 if (context->job_type == JOB_TYPE_BACKUP)
210 {
211 _DebugMessage(100, "Calling HrESEBackupCloseFile\n");
212 HrESEBackupCloseFile(hccx, backup_file_handle);
213 backup_file_handle = INVALID_HANDLE_VALUE;
214 return bRC_OK;
215 }
216 else
217 {
218 if (restore_at_file_level)
219 {
220 CloseHandle(restore_file_handle);
221 restore_file_handle = INVALID_HANDLE_VALUE;
222 return bRC_OK;
223 }
224 else
225 {
226 return bRC_OK;
227 }
228 }
229 }
230