]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/vss.cpp
Fix path issues.
[bacula/bacula] / bacula / src / win32 / filed / vss.cpp
1
2 // vss.cpp -- Interface to Volume Shadow Copies (VSS)
3 //
4 // Copyright transferred from MATRIX-Computer GmbH to
5 //   Kern Sibbald by express permission.
6 //
7 // Author          : Thorsten Engel
8 // Created On      : Fri May 06 21:44:00 2005
9 /*
10    Bacula® - The Network Backup Solution
11
12    Copyright (C) 2005-2006 Free Software Foundation Europe e.V.
13
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 plus additions
19    that are listed in the file LICENSE.
20
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.
25
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
29    02110-1301, USA.
30
31    Bacula® is a registered trademark of John Walker.
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.
35 */
36
37
38 #ifdef WIN32_VSS
39 #include "bacula.h"
40 #include "compat.h"
41
42 #include "ms_atl.h"
43 #include <objbase.h>
44
45 #include "vss.h"
46
47 VSSClient *g_pVSSClient;
48
49 void 
50 VSSCleanup()
51 {
52    if (g_pVSSClient)
53       delete (g_pVSSClient);
54 }
55
56 void
57 VSSInit()
58 {
59    /* decide which vss class to initialize */
60    switch (g_MinorVersion) {
61       case 1: 
62          g_pVSSClient = new VSSClientXP();
63          atexit(VSSCleanup);
64          break;
65       case 2: 
66          g_pVSSClient = new VSSClient2003();
67          atexit(VSSCleanup);
68          break;
69    }
70 }
71
72 BOOL
73 VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen)
74 {
75    return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen);
76 }
77
78 BOOL
79 VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
80 {
81    return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen);
82 }
83
84 // Constructor
85 VSSClient::VSSClient()
86 {
87     m_bCoInitializeCalled = false;
88     m_bCoInitializeSecurityCalled = false;
89     m_dwContext = 0; // VSS_CTX_BACKUP;
90     m_bDuringRestore = false;
91     m_bBackupIsInitialized = false;
92     m_pVssObject = NULL;
93     m_pAlistWriterState = New (alist(10, not_owned_by_alist));
94     m_pAlistWriterInfoText = New (alist(10, owned_by_alist));
95     m_uidCurrentSnapshotSet = GUID_NULL;
96     memset(m_wszUniqueVolumeName, 0, sizeof(m_wszUniqueVolumeName));
97     memset(m_szShadowCopyName, 0, sizeof(m_szShadowCopyName));
98 }
99
100 // Destructor
101 VSSClient::~VSSClient()
102 {
103    // Release the IVssBackupComponents interface 
104    // WARNING: this must be done BEFORE calling CoUninitialize()
105    if (m_pVssObject) {
106       m_pVssObject->Release();
107       m_pVssObject = NULL;
108    }
109
110    DestroyWriterInfo();
111    delete (alist*) m_pAlistWriterState;
112    delete (alist*) m_pAlistWriterInfoText;
113
114    // Call CoUninitialize if the CoInitialize was performed successfully
115    if (m_bCoInitializeCalled)
116       CoUninitialize();
117 }
118
119 BOOL VSSClient::InitializeForBackup()
120 {
121     //return Initialize (VSS_CTX_BACKUP);
122    return Initialize(0);
123 }
124
125
126
127
128 BOOL VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen)
129 {
130    if (!m_bBackupIsInitialized)
131       return FALSE;
132
133    /* check for valid pathname */
134    BOOL bIsValidName;
135    
136    bIsValidName = strlen(szFilePath) > 3;
137    if (bIsValidName)
138       bIsValidName &= isalpha (szFilePath[0]) &&
139                       szFilePath[1]==':' && 
140                       szFilePath[2] == '\\';
141
142    if (bIsValidName) {
143       int nDriveIndex = toupper(szFilePath[0])-'A';
144       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
145
146          if (WideCharToMultiByte(CP_UTF8,0,m_szShadowCopyName[nDriveIndex],-1,szShadowPath,nBuflen-1,NULL,NULL)) {
147             nBuflen -= (int)strlen(szShadowPath);
148             bstrncat(szShadowPath, szFilePath+2, nBuflen);
149             return TRUE;
150          }
151       }
152    }
153    
154    bstrncpy(szShadowPath, szFilePath, nBuflen);
155    errno = EINVAL;
156    return FALSE;   
157 }
158
159 BOOL VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
160 {
161    if (!m_bBackupIsInitialized)
162       return FALSE;
163
164    /* check for valid pathname */
165    BOOL bIsValidName;
166    
167    bIsValidName = wcslen(szFilePath) > 3;
168    if (bIsValidName)
169       bIsValidName &= iswalpha (szFilePath[0]) &&
170                       szFilePath[1]==':' && 
171                       szFilePath[2] == '\\';
172
173    if (bIsValidName) {
174       int nDriveIndex = towupper(szFilePath[0])-'A';
175       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
176          wcsncpy(szShadowPath, m_szShadowCopyName[nDriveIndex], nBuflen);
177          nBuflen -= (int)wcslen(m_szShadowCopyName[nDriveIndex]);
178          wcsncat(szShadowPath, szFilePath+2, nBuflen);
179          return TRUE;
180       }
181    }
182    
183    wcsncpy(szShadowPath, szFilePath, nBuflen);
184    errno = EINVAL;
185    return FALSE;   
186 }
187
188
189 const size_t VSSClient::GetWriterCount()
190 {
191    alist* pV = (alist*)m_pAlistWriterInfoText;
192    return pV->size();
193 }
194
195 const char* VSSClient::GetWriterInfo(int nIndex)
196 {
197    alist* pV = (alist*)m_pAlistWriterInfoText;
198    return (char*)pV->get(nIndex);
199 }
200
201
202 const int VSSClient::GetWriterState(int nIndex)
203 {
204    alist* pV = (alist*)m_pAlistWriterState;   
205    return (int)pV->get(nIndex);
206 }
207
208 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
209 {
210    alist* pT = (alist*) m_pAlistWriterInfoText;
211    alist* pS = (alist*) m_pAlistWriterState;
212
213    pT->push(bstrdup(pszInfo));
214    pS->push((void*)nState);   
215 }
216
217 void VSSClient::DestroyWriterInfo()
218 {
219    alist* pT = (alist*)m_pAlistWriterInfoText;
220    alist* pS = (alist*)m_pAlistWriterState;
221
222    while (!pT->empty())
223       free(pT->pop());
224
225    while (!pS->empty())
226       pS->pop();      
227 }
228
229 #endif