2 // vss.cpp -- Interface to Volume Shadow Copies (VSS)
4 // Copyright transferred from MATRIX-Computer GmbH to
5 // Kern Sibbald by express permission.
7 // Author : Thorsten Engel
8 // Created On : Fri May 06 21:44:00 2005
10 Bacula® - The Network Backup Solution
12 Copyright (C) 2005-2007 Free Software Foundation Europe e.V.
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
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.
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
31 Bacula® is a registered trademark of Kern Sibbald.
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.
47 VSSClient *g_pVSSClient;
49 // {b5946137-7b9f-4925-af80-51abd60b20d5}
51 static const GUID VSS_SWPRV_ProviderID =
52 { 0xb5946137, 0x7b9f, 0x4925, { 0xaf, 0x80, 0x51, 0xab, 0xd6, 0x0b, 0x20, 0xd5 } };
59 delete (g_pVSSClient);
65 /* decide which vss class to initialize */
66 if (g_MajorVersion == 5) {
67 switch (g_MinorVersion) {
69 g_pVSSClient = new VSSClientXP();
73 g_pVSSClient = new VSSClient2003();
77 /* Vista or Longhorn */
78 } else if (g_MajorVersion == 6 && g_MinorVersion == 0) {
79 /* Probably will not work */
80 g_pVSSClient = new VSSClientVista();
87 VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen)
89 return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen);
93 VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
95 return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen);
99 VSSClient::VSSClient()
101 m_bCoInitializeCalled = false;
102 m_bCoInitializeSecurityCalled = false;
103 m_dwContext = 0; // VSS_CTX_BACKUP;
104 m_bDuringRestore = false;
105 m_bBackupIsInitialized = false;
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));
115 VSSClient::~VSSClient()
117 // Release the IVssBackupComponents interface
118 // WARNING: this must be done BEFORE calling CoUninitialize()
120 m_pVssObject->Release();
125 delete (alist*)m_pAlistWriterState;
126 delete (alist*)m_pAlistWriterInfoText;
128 // Call CoUninitialize if the CoInitialize was performed successfully
129 if (m_bCoInitializeCalled)
133 BOOL VSSClient::InitializeForBackup()
135 //return Initialize (VSS_CTX_BACKUP);
136 return Initialize(0);
142 BOOL VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen)
144 if (!m_bBackupIsInitialized)
147 /* check for valid pathname */
150 bIsValidName = strlen(szFilePath) > 3;
152 bIsValidName &= isalpha (szFilePath[0]) &&
153 szFilePath[1]==':' &&
154 szFilePath[2] == '\\';
157 int nDriveIndex = toupper(szFilePath[0])-'A';
158 if (m_szShadowCopyName[nDriveIndex][0] != 0) {
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);
168 bstrncpy(szShadowPath, szFilePath, nBuflen);
173 BOOL VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
175 if (!m_bBackupIsInitialized)
178 /* check for valid pathname */
181 bIsValidName = wcslen(szFilePath) > 3;
183 bIsValidName &= iswalpha (szFilePath[0]) &&
184 szFilePath[1]==':' &&
185 szFilePath[2] == '\\';
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);
197 wcsncpy(szShadowPath, szFilePath, nBuflen);
203 const size_t VSSClient::GetWriterCount()
205 alist* pV = (alist*)m_pAlistWriterInfoText;
209 const char* VSSClient::GetWriterInfo(int nIndex)
211 alist* pV = (alist*)m_pAlistWriterInfoText;
212 return (char*)pV->get(nIndex);
216 const int VSSClient::GetWriterState(int nIndex)
218 alist* pV = (alist*)m_pAlistWriterState;
219 return (int)pV->get(nIndex);
222 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
224 alist* pT = (alist*) m_pAlistWriterInfoText;
225 alist* pS = (alist*) m_pAlistWriterState;
227 pT->push(bstrdup(pszInfo));
228 pS->push((void*)nState);
231 void VSSClient::DestroyWriterInfo()
233 alist* pT = (alist*)m_pAlistWriterInfoText;
234 alist* pS = (alist*)m_pAlistWriterState;