]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/vss.cpp
Detect the case where logfiles but no databases are being restored.
[bacula/bacula] / bacula / src / win32 / filed / vss.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2005-2008 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 && g_MinorVersion == 0) {
78    } else if (g_MajorVersion >= 6) {
79       g_pVSSClient = new VSSClientVista();
80       atexit(VSSCleanup);
81       return;
82    }
83 }
84
85 BOOL
86 VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen)
87 {
88    return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen);
89 }
90
91 BOOL
92 VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
93 {
94    return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen);
95 }
96
97 // Constructor
98 VSSClient::VSSClient()
99 {
100     m_bCoInitializeCalled = false;
101     m_bCoInitializeSecurityCalled = false;
102     m_dwContext = 0; // VSS_CTX_BACKUP;
103     m_bDuringRestore = false;
104     m_bBackupIsInitialized = false;
105     m_pVssObject = NULL;
106     m_pAlistWriterState = New(alist(10, not_owned_by_alist));
107     m_pAlistWriterInfoText = New(alist(10, owned_by_alist));
108     m_uidCurrentSnapshotSet = GUID_NULL;
109     memset(m_wszUniqueVolumeName, 0, sizeof(m_wszUniqueVolumeName));
110     memset(m_szShadowCopyName, 0, sizeof(m_szShadowCopyName));
111 }
112
113 // Destructor
114 VSSClient::~VSSClient()
115 {
116    // Release the IVssBackupComponents interface 
117    // WARNING: this must be done BEFORE calling CoUninitialize()
118    if (m_pVssObject) {
119       m_pVssObject->Release();
120       m_pVssObject = NULL;
121    }
122
123    DestroyWriterInfo();
124    delete (alist*)m_pAlistWriterState;
125    delete (alist*)m_pAlistWriterInfoText;
126
127    // Call CoUninitialize if the CoInitialize was performed successfully
128    if (m_bCoInitializeCalled)
129       CoUninitialize();
130 }
131
132 BOOL VSSClient::InitializeForBackup()
133 {
134     //return Initialize (VSS_CTX_BACKUP);
135    return Initialize(0);
136 }
137
138
139
140
141 BOOL VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen)
142 {
143    if (!m_bBackupIsInitialized)
144       return FALSE;
145
146    /* check for valid pathname */
147    BOOL bIsValidName;
148    
149    bIsValidName = strlen(szFilePath) > 3;
150    if (bIsValidName)
151       bIsValidName &= isalpha (szFilePath[0]) &&
152                       szFilePath[1]==':' && 
153                       szFilePath[2] == '\\';
154
155    if (bIsValidName) {
156       int nDriveIndex = toupper(szFilePath[0])-'A';
157       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
158
159          if (WideCharToMultiByte(CP_UTF8,0,m_szShadowCopyName[nDriveIndex],-1,szShadowPath,nBuflen-1,NULL,NULL)) {
160             nBuflen -= (int)strlen(szShadowPath);
161             bstrncat(szShadowPath, szFilePath+2, nBuflen);
162             return TRUE;
163          }
164       }
165    }
166    
167    bstrncpy(szShadowPath, szFilePath, nBuflen);
168    errno = EINVAL;
169    return FALSE;   
170 }
171
172 BOOL VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
173 {
174    if (!m_bBackupIsInitialized)
175       return FALSE;
176
177    /* check for valid pathname */
178    BOOL bIsValidName;
179    
180    bIsValidName = wcslen(szFilePath) > 3;
181    if (bIsValidName)
182       bIsValidName &= iswalpha (szFilePath[0]) &&
183                       szFilePath[1]==':' && 
184                       szFilePath[2] == '\\';
185
186    if (bIsValidName) {
187       int nDriveIndex = towupper(szFilePath[0])-'A';
188       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
189          wcsncpy(szShadowPath, m_szShadowCopyName[nDriveIndex], nBuflen);
190          nBuflen -= (int)wcslen(m_szShadowCopyName[nDriveIndex]);
191          wcsncat(szShadowPath, szFilePath+2, nBuflen);
192          return TRUE;
193       }
194    }
195    
196    wcsncpy(szShadowPath, szFilePath, nBuflen);
197    errno = EINVAL;
198    return FALSE;   
199 }
200
201
202 const size_t VSSClient::GetWriterCount()
203 {
204    alist* pV = (alist*)m_pAlistWriterInfoText;
205    return pV->size();
206 }
207
208 const char* VSSClient::GetWriterInfo(int nIndex)
209 {
210    alist* pV = (alist*)m_pAlistWriterInfoText;
211    return (char*)pV->get(nIndex);
212 }
213
214
215 const int VSSClient::GetWriterState(int nIndex)
216 {
217    alist* pV = (alist*)m_pAlistWriterState;   
218    return (int)pV->get(nIndex);
219 }
220
221 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
222 {
223    alist* pT = (alist*) m_pAlistWriterInfoText;
224    alist* pS = (alist*) m_pAlistWriterState;
225
226    pT->push(bstrdup(pszInfo));
227    pS->push((void*)nState);   
228 }
229
230 void VSSClient::DestroyWriterInfo()
231 {
232    alist* pT = (alist*)m_pAlistWriterInfoText;
233    alist* pS = (alist*)m_pAlistWriterState;
234
235    while (!pT->empty())
236       free(pT->pop());
237
238    while (!pS->empty())
239       pS->pop();      
240 }
241
242 #endif