]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/plugins/exch_file_node.c
Restore win32 dir from Branch-5.2 and update it
[bacula/bacula] / bacula / src / win32 / filed / plugins / exch_file_node.c
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
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
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
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
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
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
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
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, &section_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
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
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
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 }