]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/vss.cpp
Tweak comments + indenting
[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 two of the GNU 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 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))
140 {
141    m_jcr = jcr;
142    return Initialize(0, true/*=>Restore*/, VssInitCallback);
143 }
144
145 bool VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen)
146 {
147    if (!m_bBackupIsInitialized)
148       return false;
149
150    /* check for valid pathname */
151    bool bIsValidName;
152    
153    bIsValidName = strlen(szFilePath) > 3;
154    if (bIsValidName)
155       bIsValidName &= isalpha (szFilePath[0]) &&
156                       szFilePath[1]==':' && 
157                       szFilePath[2] == '\\';
158
159    if (bIsValidName) {
160       int nDriveIndex = toupper(szFilePath[0])-'A';
161       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
162
163          if (WideCharToMultiByte(CP_UTF8,0,m_szShadowCopyName[nDriveIndex],-1,szShadowPath,nBuflen-1,NULL,NULL)) {
164             nBuflen -= (int)strlen(szShadowPath);
165             bstrncat(szShadowPath, szFilePath+2, nBuflen);
166             return true;
167          }
168       }
169    }
170    
171    bstrncpy(szShadowPath, szFilePath, nBuflen);
172    errno = EINVAL;
173    return false;   
174 }
175
176 bool VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
177 {
178    if (!m_bBackupIsInitialized)
179       return false;
180
181    /* check for valid pathname */
182    bool bIsValidName;
183    
184    bIsValidName = wcslen(szFilePath) > 3;
185    if (bIsValidName)
186       bIsValidName &= iswalpha (szFilePath[0]) &&
187                       szFilePath[1]==':' && 
188                       szFilePath[2] == '\\';
189
190    if (bIsValidName) {
191       int nDriveIndex = towupper(szFilePath[0])-'A';
192       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
193          wcsncpy(szShadowPath, m_szShadowCopyName[nDriveIndex], nBuflen);
194          nBuflen -= (int)wcslen(m_szShadowCopyName[nDriveIndex]);
195          wcsncat(szShadowPath, szFilePath+2, nBuflen);
196          return true;
197       }
198    }
199    
200    wcsncpy(szShadowPath, szFilePath, nBuflen);
201    errno = EINVAL;
202    return false;   
203 }
204
205
206 const size_t VSSClient::GetWriterCount()
207 {
208    alist* pV = m_pAlistWriterInfoText;
209    return pV->size();
210 }
211
212 const char* VSSClient::GetWriterInfo(int nIndex)
213 {
214    alist* pV = m_pAlistWriterInfoText;
215    return (char*)pV->get(nIndex);
216 }
217
218
219 const int VSSClient::GetWriterState(int nIndex)
220 {
221    alist* pV = m_pAlistWriterState;   
222    void *item = pV->get(nIndex);
223 /* Eliminate compiler warnings */
224 #ifdef HAVE_VSS64
225    return (int64_t)(char *)item;
226 #else
227    return (int)(char *)item;
228 #endif
229 }
230
231 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
232 {
233    alist* pT = m_pAlistWriterInfoText;
234    alist* pS = m_pAlistWriterState;
235
236    pT->push(bstrdup(pszInfo));
237    pS->push((void*)nState);   
238 }
239
240 void VSSClient::DestroyWriterInfo()
241 {
242    alist* pT = m_pAlistWriterInfoText;
243    alist* pS = m_pAlistWriterState;
244
245    while (!pT->empty())
246       free(pT->pop());
247
248    while (!pS->empty())
249       pS->pop();      
250 }
251
252 #endif