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