]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/vss.cpp
Tweak fix MySQL quoting again :-(
[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    }
60 }
61
62 void VSSInit()
63 {
64    /* decide which vss class to initialize */
65    if (g_MajorVersion == 5) {
66       switch (g_MinorVersion) {
67       case 1: 
68          g_pVSSClient = new VSSClientXP();
69          atexit(VSSCleanup);
70          return;
71       case 2: 
72          g_pVSSClient = new VSSClient2003();
73          atexit(VSSCleanup);
74          return;
75       }
76    /* Vista or Longhorn or later */
77    } else if (g_MajorVersion >= 6) {
78       g_pVSSClient = new VSSClientVista();
79       atexit(VSSCleanup);
80       return;
81    }
82 }
83
84 BOOL
85 VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen)
86 {
87    return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen);
88 }
89
90 BOOL
91 VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
92 {
93    return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen);
94 }
95
96 // Constructor
97 VSSClient::VSSClient()
98 {
99     m_bCoInitializeCalled = false;
100     m_bCoInitializeSecurityCalled = false;
101     m_dwContext = 0; // VSS_CTX_BACKUP;
102     m_bDuringRestore = false;
103     m_bBackupIsInitialized = false;
104     m_pVssObject = NULL;
105     m_pAlistWriterState = New(alist(10, not_owned_by_alist));
106     m_pAlistWriterInfoText = New(alist(10, owned_by_alist));
107     m_uidCurrentSnapshotSet = GUID_NULL;
108     memset(m_wszUniqueVolumeName, 0, sizeof(m_wszUniqueVolumeName));
109     memset(m_szShadowCopyName, 0, sizeof(m_szShadowCopyName));
110 }
111
112 // Destructor
113 VSSClient::~VSSClient()
114 {
115    // Release the IVssBackupComponents interface 
116    // WARNING: this must be done BEFORE calling CoUninitialize()
117    if (m_pVssObject) {
118       m_pVssObject->Release();
119       m_pVssObject = NULL;
120    }
121
122    DestroyWriterInfo();
123    delete m_pAlistWriterState;
124    delete m_pAlistWriterInfoText;
125
126    // Call CoUninitialize if the CoInitialize was performed successfully
127    if (m_bCoInitializeCalled)
128       CoUninitialize();
129 }
130
131 bool VSSClient::InitializeForBackup(JCR *jcr)
132 {
133     //return Initialize (VSS_CTX_BACKUP);
134    m_jcr = jcr;
135    return Initialize(0);
136 }
137
138
139 bool VSSClient::InitializeForRestore(JCR *jcr, bool (*VssInitCallback)(JCR *, int), WCHAR *job_metadata)
140 {
141    m_metadata = job_metadata;
142    m_jcr = jcr;
143    return Initialize(0, true/*=>Restore*/, VssInitCallback);
144 }
145
146 bool VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen)
147 {
148    if (!m_bBackupIsInitialized)
149       return false;
150
151    /* check for valid pathname */
152    bool bIsValidName;
153    
154    bIsValidName = strlen(szFilePath) > 3;
155    if (bIsValidName)
156       bIsValidName &= isalpha (szFilePath[0]) &&
157                       szFilePath[1]==':' && 
158                       szFilePath[2] == '\\';
159
160    if (bIsValidName) {
161       int nDriveIndex = toupper(szFilePath[0])-'A';
162       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
163
164          if (WideCharToMultiByte(CP_UTF8,0,m_szShadowCopyName[nDriveIndex],-1,szShadowPath,nBuflen-1,NULL,NULL)) {
165             nBuflen -= (int)strlen(szShadowPath);
166             bstrncat(szShadowPath, szFilePath+2, nBuflen);
167             return true;
168          }
169       }
170    }
171    
172    bstrncpy(szShadowPath, szFilePath, nBuflen);
173    errno = EINVAL;
174    return false;   
175 }
176
177 bool VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
178 {
179    if (!m_bBackupIsInitialized)
180       return false;
181
182    /* check for valid pathname */
183    bool bIsValidName;
184    
185    bIsValidName = wcslen(szFilePath) > 3;
186    if (bIsValidName)
187       bIsValidName &= iswalpha (szFilePath[0]) &&
188                       szFilePath[1]==':' && 
189                       szFilePath[2] == '\\';
190
191    if (bIsValidName) {
192       int nDriveIndex = towupper(szFilePath[0])-'A';
193       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
194          wcsncpy(szShadowPath, m_szShadowCopyName[nDriveIndex], nBuflen);
195          nBuflen -= (int)wcslen(m_szShadowCopyName[nDriveIndex]);
196          wcsncat(szShadowPath, szFilePath+2, nBuflen);
197          return true;
198       }
199    }
200    
201    wcsncpy(szShadowPath, szFilePath, nBuflen);
202    errno = EINVAL;
203    return false;   
204 }
205
206
207 const size_t VSSClient::GetWriterCount()
208 {
209    alist* pV = m_pAlistWriterInfoText;
210    return pV->size();
211 }
212
213 const char* VSSClient::GetWriterInfo(int nIndex)
214 {
215    alist* pV = m_pAlistWriterInfoText;
216    return (char*)pV->get(nIndex);
217 }
218
219
220 const int VSSClient::GetWriterState(int nIndex)
221 {
222    alist* pV = m_pAlistWriterState;   
223    void *item = pV->get(nIndex);
224 /* Eliminate compiler warnings */
225 #ifdef HAVE_VSS64
226    return (int64_t)(char *)item;
227 #else
228    return (int)(char *)item;
229 #endif
230 }
231
232 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
233 {
234    alist* pT = m_pAlistWriterInfoText;
235    alist* pS = m_pAlistWriterState;
236
237    pT->push(bstrdup(pszInfo));
238    pS->push((void*)nState);   
239 }
240
241 void VSSClient::DestroyWriterInfo()
242 {
243    alist* pT = m_pAlistWriterInfoText;
244    alist* pS = m_pAlistWriterState;
245
246    while (!pT->empty())
247       free(pT->pop());
248
249    while (!pS->empty())
250       pS->pop();      
251 }
252
253 #endif