]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/vss.cpp
Attempt to disactivate old exchange-fd.dll if no plugin= line in FileSet
[bacula/bacula] / bacula / src / win32 / filed / vss.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2005-2010 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 // vss.cpp -- Interface to Volume Shadow Copies (VSS)
29 //
30 // Copyright transferred from MATRIX-Computer GmbH to
31 //   Kern Sibbald by express permission.
32 //
33 // Author          : Thorsten Engel
34 // Created On      : Fri May 06 21:44:00 2005
35
36
37 #ifdef WIN32_VSS
38 #include "bacula.h"
39 #include "compat.h"
40
41 #include "ms_atl.h"
42 #include <objbase.h>
43
44 #include "vss.h"
45
46 VSSClient *g_pVSSClient;
47
48 // {b5946137-7b9f-4925-af80-51abd60b20d5}
49
50 static const GUID VSS_SWPRV_ProviderID =
51    { 0xb5946137, 0x7b9f, 0x4925, { 0xaf, 0x80, 0x51, 0xab, 0xd6, 0x0b, 0x20, 0xd5 } };
52
53
54 void 
55 VSSCleanup()
56 {
57    if (g_pVSSClient) {
58       delete (g_pVSSClient);
59       g_pVSSClient = NULL;
60    }
61 }
62
63 /*
64  * May be called multiple times 
65  */
66 void VSSInit()
67 {
68    if (g_pVSSClient) {
69       return;                   /* already initialized */
70    }
71    /* decide which vss class to initialize */
72    if (g_MajorVersion == 5) {
73       switch (g_MinorVersion) {
74       case 1: 
75          g_pVSSClient = new VSSClientXP();
76          break;
77       case 2: 
78          g_pVSSClient = new VSSClient2003();
79          break;
80       }
81    /* Vista or Longhorn or later */
82    } else if (g_MajorVersion >= 6) {
83       g_pVSSClient = new VSSClientVista();
84    }
85    if (g_pVSSClient) {
86       atexit(VSSCleanup);
87    }
88 }
89
90 BOOL
91 VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen)
92 {
93    return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen);
94 }
95
96 BOOL
97 VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
98 {
99    return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen);
100 }
101
102 // Constructor
103 VSSClient::VSSClient()
104 {
105     m_bCoInitializeCalled = false;
106     m_bCoInitializeSecurityCalled = false;
107     m_dwContext = 0; // VSS_CTX_BACKUP;
108     m_bDuringRestore = false;
109     m_bBackupIsInitialized = false;
110     m_pVssObject = NULL;
111     m_pAlistWriterState = New(alist(10, not_owned_by_alist));
112     m_pAlistWriterInfoText = New(alist(10, owned_by_alist));
113     m_uidCurrentSnapshotSet = GUID_NULL;
114     memset(m_wszUniqueVolumeName, 0, sizeof(m_wszUniqueVolumeName));
115     memset(m_szShadowCopyName, 0, sizeof(m_szShadowCopyName));
116 }
117
118 // Destructor
119 VSSClient::~VSSClient()
120 {
121    // Release the IVssBackupComponents interface 
122    // WARNING: this must be done BEFORE calling CoUninitialize()
123    if (m_pVssObject) {
124       m_pVssObject->Release();
125       m_pVssObject = NULL;
126    }
127
128    DestroyWriterInfo();
129    delete m_pAlistWriterState;
130    delete m_pAlistWriterInfoText;
131
132    // Call CoUninitialize if the CoInitialize was performed successfully
133    if (m_bCoInitializeCalled)
134       CoUninitialize();
135 }
136
137 bool VSSClient::InitializeForBackup(JCR *jcr)
138 {
139     //return Initialize (VSS_CTX_BACKUP);
140    m_jcr = jcr;
141    return Initialize(0);
142 }
143
144
145 bool VSSClient::InitializeForRestore(JCR *jcr, bool (*VssInitCallback)(JCR *, int), WCHAR *job_metadata)
146 {
147    m_metadata = job_metadata;
148    m_jcr = jcr;
149    return Initialize(0, true/*=>Restore*/, VssInitCallback);
150 }
151
152 bool VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen)
153 {
154    if (!m_bBackupIsInitialized)
155       return false;
156
157    /* check for valid pathname */
158    bool bIsValidName;
159    
160    bIsValidName = strlen(szFilePath) > 3;
161    if (bIsValidName)
162       bIsValidName &= isalpha (szFilePath[0]) &&
163                       szFilePath[1]==':' && 
164                       szFilePath[2] == '\\';
165
166    if (bIsValidName) {
167       int nDriveIndex = toupper(szFilePath[0])-'A';
168       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
169
170          if (WideCharToMultiByte(CP_UTF8,0,m_szShadowCopyName[nDriveIndex],-1,szShadowPath,nBuflen-1,NULL,NULL)) {
171             nBuflen -= (int)strlen(szShadowPath);
172             bstrncat(szShadowPath, szFilePath+2, nBuflen);
173             return true;
174          }
175       }
176    }
177    
178    bstrncpy(szShadowPath, szFilePath, nBuflen);
179    errno = EINVAL;
180    return false;   
181 }
182
183 bool VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
184 {
185    if (!m_bBackupIsInitialized)
186       return false;
187
188    /* check for valid pathname */
189    bool bIsValidName;
190    
191    bIsValidName = wcslen(szFilePath) > 3;
192    if (bIsValidName)
193       bIsValidName &= iswalpha (szFilePath[0]) &&
194                       szFilePath[1]==':' && 
195                       szFilePath[2] == '\\';
196
197    if (bIsValidName) {
198       int nDriveIndex = towupper(szFilePath[0])-'A';
199       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
200          wcsncpy(szShadowPath, m_szShadowCopyName[nDriveIndex], nBuflen);
201          nBuflen -= (int)wcslen(m_szShadowCopyName[nDriveIndex]);
202          wcsncat(szShadowPath, szFilePath+2, nBuflen);
203          return true;
204       }
205    }
206    
207    wcsncpy(szShadowPath, szFilePath, nBuflen);
208    errno = EINVAL;
209    return false;   
210 }
211
212
213 const size_t VSSClient::GetWriterCount()
214 {
215    return m_pAlistWriterInfoText->size();
216 }
217
218 const char* VSSClient::GetWriterInfo(int nIndex)
219 {
220    return (char*)m_pAlistWriterInfoText->get(nIndex);
221 }
222
223
224 const int VSSClient::GetWriterState(int nIndex)
225 {
226    void *item = m_pAlistWriterState->get(nIndex);
227
228 /* Eliminate compiler warnings */
229 #ifdef HAVE_VSS64
230    return (int64_t)(char *)item;
231 #else
232    return (int)(char *)item;
233 #endif
234 }
235
236 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
237 {
238    m_pAlistWriterInfoText->push(bstrdup(pszInfo));
239    m_pAlistWriterState->push((void*)nState);   
240 }
241
242 /*
243  * Note, this is called at the end of every job, so release all
244  *  the items in the alists, but do not delete the alist.
245  */
246 void VSSClient::DestroyWriterInfo()
247 {
248    while (!m_pAlistWriterInfoText->empty()) {
249       free(m_pAlistWriterInfoText->pop());
250    }
251
252    while (!m_pAlistWriterState->empty()) {
253       m_pAlistWriterState->pop();      
254    }
255 }
256
257 #endif