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 } };
58 delete (g_pVSSClient);
64 * May be called multiple times
69 return; /* already initialized */
71 /* decide which vss class to initialize */
72 if (g_MajorVersion == 5) {
73 switch (g_MinorVersion) {
75 g_pVSSClient = new VSSClientXP();
78 g_pVSSClient = new VSSClient2003();
81 /* Vista or Longhorn or later */
82 } else if (g_MajorVersion >= 6) {
83 g_pVSSClient = new VSSClientVista();
91 VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen)
93 return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen);
97 VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
99 return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen);
103 VSSClient::VSSClient()
105 m_bCoInitializeCalled = false;
106 m_bCoInitializeSecurityCalled = false;
107 m_dwContext = 0; // VSS_CTX_BACKUP;
108 m_bDuringRestore = false;
109 m_bBackupIsInitialized = false;
111 m_pAlistWriterState = New(alist(10, not_owned_by_alist));
112 m_pAlistWriterInfoText = New(alist(10, owned_by_alist));
113 m_uidCurrentSnapshotSet = GUID_NULL;
114 memset(m_wszUniqueVolumeName, 0, sizeof(m_wszUniqueVolumeName));
115 memset(m_szShadowCopyName, 0, sizeof(m_szShadowCopyName));
119 VSSClient::~VSSClient()
121 // Release the IVssBackupComponents interface
122 // WARNING: this must be done BEFORE calling CoUninitialize()
124 m_pVssObject->Release();
129 delete m_pAlistWriterState;
130 delete m_pAlistWriterInfoText;
132 // Call CoUninitialize if the CoInitialize was performed successfully
133 if (m_bCoInitializeCalled)
137 bool VSSClient::InitializeForBackup(JCR *jcr)
139 //return Initialize (VSS_CTX_BACKUP);
141 return Initialize(0);
145 bool VSSClient::InitializeForRestore(JCR *jcr, bool (*VssInitCallback)(JCR *, int), WCHAR *job_metadata)
147 m_metadata = job_metadata;
149 return Initialize(0, true/*=>Restore*/, VssInitCallback);
152 bool VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen)
154 if (!m_bBackupIsInitialized)
157 /* check for valid pathname */
160 bIsValidName = strlen(szFilePath) > 3;
162 bIsValidName &= isalpha (szFilePath[0]) &&
163 szFilePath[1]==':' &&
164 szFilePath[2] == '\\';
167 int nDriveIndex = toupper(szFilePath[0])-'A';
168 if (m_szShadowCopyName[nDriveIndex][0] != 0) {
170 if (WideCharToMultiByte(CP_UTF8,0,m_szShadowCopyName[nDriveIndex],-1,szShadowPath,nBuflen-1,NULL,NULL)) {
171 nBuflen -= (int)strlen(szShadowPath);
172 bstrncat(szShadowPath, szFilePath+2, nBuflen);
178 bstrncpy(szShadowPath, szFilePath, nBuflen);
183 bool VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
185 if (!m_bBackupIsInitialized)
188 /* check for valid pathname */
191 bIsValidName = wcslen(szFilePath) > 3;
193 bIsValidName &= iswalpha (szFilePath[0]) &&
194 szFilePath[1]==':' &&
195 szFilePath[2] == '\\';
198 int nDriveIndex = towupper(szFilePath[0])-'A';
199 if (m_szShadowCopyName[nDriveIndex][0] != 0) {
200 wcsncpy(szShadowPath, m_szShadowCopyName[nDriveIndex], nBuflen);
201 nBuflen -= (int)wcslen(m_szShadowCopyName[nDriveIndex]);
202 wcsncat(szShadowPath, szFilePath+2, nBuflen);
207 wcsncpy(szShadowPath, szFilePath, nBuflen);
213 const size_t VSSClient::GetWriterCount()
215 return m_pAlistWriterInfoText->size();
218 const char* VSSClient::GetWriterInfo(int nIndex)
220 return (char*)m_pAlistWriterInfoText->get(nIndex);
224 const int VSSClient::GetWriterState(int nIndex)
226 void *item = m_pAlistWriterState->get(nIndex);
228 /* Eliminate compiler warnings */
230 return (int64_t)(char *)item;
232 return (int)(char *)item;
236 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
238 m_pAlistWriterInfoText->push(bstrdup(pszInfo));
239 m_pAlistWriterState->push((void*)nState);
243 * Note, this is called at the end of every job, so release all
244 * the items in the alists, but do not delete the alist.
246 void VSSClient::DestroyWriterInfo()
248 while (!m_pAlistWriterInfoText->empty()) {
249 free(m_pAlistWriterInfoText->pop());
252 while (!m_pAlistWriterState->empty()) {
253 m_pAlistWriterState->pop();