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 two of the GNU 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 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 /* decide which vss class to initialize */
65 if (g_MajorVersion == 5) {
66 switch (g_MinorVersion) {
68 g_pVSSClient = new VSSClientXP();
72 g_pVSSClient = new VSSClient2003();
76 /* Vista or Longhorn or later */
77 } else if (g_MajorVersion >= 6) {
78 g_pVSSClient = new VSSClientVista();
85 VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen)
87 return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen);
91 VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
93 return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen);
97 VSSClient::VSSClient()
99 m_bCoInitializeCalled = false;
100 m_bCoInitializeSecurityCalled = false;
101 m_dwContext = 0; // VSS_CTX_BACKUP;
102 m_bDuringRestore = false;
103 m_bBackupIsInitialized = false;
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));
113 VSSClient::~VSSClient()
115 // Release the IVssBackupComponents interface
116 // WARNING: this must be done BEFORE calling CoUninitialize()
118 m_pVssObject->Release();
123 delete m_pAlistWriterState;
124 delete m_pAlistWriterInfoText;
126 // Call CoUninitialize if the CoInitialize was performed successfully
127 if (m_bCoInitializeCalled)
131 bool VSSClient::InitializeForBackup(JCR *jcr)
133 //return Initialize (VSS_CTX_BACKUP);
135 return Initialize(0);
139 bool VSSClient::InitializeForRestore(JCR *jcr, bool (*VssInitCallback)(JCR *, int))
142 return Initialize(0, true/*=>Restore*/, VssInitCallback);
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 alist* pV = m_pAlistWriterInfoText;
212 const char* VSSClient::GetWriterInfo(int nIndex)
214 alist* pV = m_pAlistWriterInfoText;
215 return (char*)pV->get(nIndex);
219 const int VSSClient::GetWriterState(int nIndex)
221 alist* pV = m_pAlistWriterState;
222 void *item = pV->get(nIndex);
223 /* Eliminate compiler warnings */
225 return (int64_t)(char *)item;
227 return (int)(char *)item;
231 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
233 alist* pT = m_pAlistWriterInfoText;
234 alist* pS = m_pAlistWriterState;
236 pT->push(bstrdup(pszInfo));
237 pS->push((void*)nState);
240 void VSSClient::DestroyWriterInfo()
242 alist* pT = m_pAlistWriterInfoText;
243 alist* pS = m_pAlistWriterState;