2 Bacula® - The Network Backup Solution
4 Copyright (C) 2005-2010 Free Software Foundation Europe e.V.
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
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.
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
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.
28 // vss.cpp -- Interface to Volume Shadow Copies (VSS)
30 // Copyright transferred from MATRIX-Computer GmbH to
31 // Kern Sibbald by express permission.
33 // Author : Thorsten Engel
34 // Created On : Fri May 06 21:44:00 2005
46 VSSClient *g_pVSSClient;
48 // {b5946137-7b9f-4925-af80-51abd60b20d5}
50 static const GUID VSS_SWPRV_ProviderID =
51 { 0xb5946137, 0x7b9f, 0x4925, { 0xaf, 0x80, 0x51, 0xab, 0xd6, 0x0b, 0x20, 0xd5 } };
57 delete (g_pVSSClient);
63 * May be called multiple times
68 return; /* already initialized */
70 /* decide which vss class to initialize */
71 if (g_MajorVersion == 5) {
72 switch (g_MinorVersion) {
74 g_pVSSClient = new VSSClientXP();
77 g_pVSSClient = new VSSClient2003();
80 /* Vista or Longhorn or later */
81 } else if (g_MajorVersion >= 6) {
82 g_pVSSClient = new VSSClientVista();
90 VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen)
92 return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen);
96 VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
98 return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen);
102 VSSClient::VSSClient()
104 memset(this, 0, sizeof(VSSClient));
105 m_pAlistWriterState = New(alist(10, not_owned_by_alist));
106 m_pAlistWriterInfoText = New(alist(10, owned_by_alist));
107 m_uidCurrentSnapshotSet = GUID_NULL;
111 VSSClient::~VSSClient()
113 // Release the IVssBackupComponents interface
114 // WARNING: this must be done BEFORE calling CoUninitialize()
116 // m_pVssObject->Release();
121 delete m_pAlistWriterState;
122 delete m_pAlistWriterInfoText;
124 // Call CoUninitialize if the CoInitialize was performed successfully
125 if (m_bCoInitializeCalled) {
130 bool VSSClient::InitializeForBackup(JCR *jcr)
132 //return Initialize (VSS_CTX_BACKUP);
134 return Initialize(0);
138 bool VSSClient::InitializeForRestore(JCR *jcr)
142 return Initialize(0, true/*=>Restore*/);
145 bool VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen)
147 if (!m_bBackupIsInitialized)
150 /* check for valid pathname */
153 bIsValidName = strlen(szFilePath) > 3;
155 bIsValidName &= isalpha (szFilePath[0]) &&
156 szFilePath[1]==':' &&
157 szFilePath[2] == '\\';
160 int nDriveIndex = toupper(szFilePath[0])-'A';
161 if (m_szShadowCopyName[nDriveIndex][0] != 0) {
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);
171 bstrncpy(szShadowPath, szFilePath, nBuflen);
176 bool VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
178 if (!m_bBackupIsInitialized)
181 /* check for valid pathname */
184 bIsValidName = wcslen(szFilePath) > 3;
186 bIsValidName &= iswalpha (szFilePath[0]) &&
187 szFilePath[1]==':' &&
188 szFilePath[2] == '\\';
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);
200 wcsncpy(szShadowPath, szFilePath, nBuflen);
206 const size_t VSSClient::GetWriterCount()
208 return m_pAlistWriterInfoText->size();
211 const char* VSSClient::GetWriterInfo(int nIndex)
213 return (char*)m_pAlistWriterInfoText->get(nIndex);
217 const int VSSClient::GetWriterState(int nIndex)
219 void *item = m_pAlistWriterState->get(nIndex);
221 /* Eliminate compiler warnings */
223 return (int64_t)(char *)item;
225 return (int)(char *)item;
229 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
231 m_pAlistWriterInfoText->push(bstrdup(pszInfo));
232 m_pAlistWriterState->push((void*)nState);
236 * Note, this is called at the end of every job, so release all
237 * the items in the alists, but do not delete the alist.
239 void VSSClient::DestroyWriterInfo()
241 while (!m_pAlistWriterInfoText->empty()) {
242 free(m_pAlistWriterInfoText->pop());
245 while (!m_pAlistWriterState->empty()) {
246 m_pAlistWriterState->pop();