]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/win32/filed/vss.cpp
Update .cvsignore files
[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 //  Copyright (C) 2005-2006 Kern Sibbald
8 //
9 //  This program is free software; you can redistribute it and/or
10 //  modify it under the terms of the GNU General Public License
11 //  version 2 as amended with additional clauses defined in the
12 //  file LICENSE in the main source directory.
13 //
14 //  This program is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
17 //  the file LICENSE for additional details.
18 //
19 //  
20 // Author          : Thorsten Engel
21 // Created On      : Fri May 06 21:44:00 2005
22
23
24 #ifdef WIN32_VSS
25 #include "bacula.h"
26 #include "compat.h"
27
28 #include "ms_atl.h"
29 #include <objbase.h>
30
31 #include "vss.h"
32
33 VSSClient *g_pVSSClient;
34
35 void 
36 VSSCleanup()
37 {
38    if (g_pVSSClient)
39       delete (g_pVSSClient);
40 }
41
42 void
43 VSSInit()
44 {
45    /* decide which vss class to initialize */
46    switch (g_MinorVersion) {
47       case 1: 
48          g_pVSSClient = new VSSClientXP();
49          atexit(VSSCleanup);
50          break;
51       case 2: 
52          g_pVSSClient = new VSSClient2003();
53          atexit(VSSCleanup);
54          break;
55    }
56 }
57
58 BOOL
59 VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen)
60 {
61    return g_pVSSClient->GetShadowPath(szFilePath, szShadowPath, nBuflen);
62 }
63
64 BOOL
65 VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
66 {
67    return g_pVSSClient->GetShadowPathW(szFilePath, szShadowPath, nBuflen);
68 }
69
70 // Constructor
71 VSSClient::VSSClient()
72 {
73     m_bCoInitializeCalled = false;
74     m_bCoInitializeSecurityCalled = false;
75     m_dwContext = 0; // VSS_CTX_BACKUP;
76     m_bDuringRestore = false;
77     m_bBackupIsInitialized = false;
78     m_pVssObject = NULL;
79     m_pAlistWriterState = New (alist(10, not_owned_by_alist));
80     m_pAlistWriterInfoText = New (alist(10, owned_by_alist));
81     m_uidCurrentSnapshotSet = GUID_NULL;
82     memset(m_wszUniqueVolumeName, 0, sizeof(m_wszUniqueVolumeName));
83     memset(m_szShadowCopyName, 0, sizeof(m_szShadowCopyName));
84 }
85
86 // Destructor
87 VSSClient::~VSSClient()
88 {
89    // Release the IVssBackupComponents interface 
90    // WARNING: this must be done BEFORE calling CoUninitialize()
91    if (m_pVssObject) {
92       m_pVssObject->Release();
93       m_pVssObject = NULL;
94    }
95
96    DestroyWriterInfo();
97    delete (alist*) m_pAlistWriterState;
98    delete (alist*) m_pAlistWriterInfoText;
99
100    // Call CoUninitialize if the CoInitialize was performed successfully
101    if (m_bCoInitializeCalled)
102       CoUninitialize();
103 }
104
105 BOOL VSSClient::InitializeForBackup()
106 {
107     //return Initialize (VSS_CTX_BACKUP);
108    return Initialize(0);
109 }
110
111
112
113
114 BOOL VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen)
115 {
116    if (!m_bBackupIsInitialized)
117       return FALSE;
118
119    /* check for valid pathname */
120    BOOL bIsValidName;
121    
122    bIsValidName = strlen(szFilePath) > 3;
123    if (bIsValidName)
124       bIsValidName &= isalpha (szFilePath[0]) &&
125                       szFilePath[1]==':' && 
126                       szFilePath[2] == '\\';
127
128    if (bIsValidName) {
129       int nDriveIndex = toupper(szFilePath[0])-'A';
130       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
131
132          if (WideCharToMultiByte(CP_UTF8,0,m_szShadowCopyName[nDriveIndex],-1,szShadowPath,nBuflen-1,NULL,NULL)) {
133             nBuflen -= (int)strlen(szShadowPath);
134             strncat(szShadowPath, szFilePath+2, nBuflen);
135             return TRUE;
136          }
137       }
138    }
139    
140    strncpy(szShadowPath,  szFilePath, nBuflen);
141    errno = EINVAL;
142    return FALSE;   
143 }
144
145 BOOL VSSClient::GetShadowPathW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen)
146 {
147    if (!m_bBackupIsInitialized)
148       return FALSE;
149
150    /* check for valid pathname */
151    BOOL bIsValidName;
152    
153    bIsValidName = wcslen(szFilePath) > 3;
154    if (bIsValidName)
155       bIsValidName &= iswalpha (szFilePath[0]) &&
156                       szFilePath[1]==':' && 
157                       szFilePath[2] == '\\';
158
159    if (bIsValidName) {
160       int nDriveIndex = towupper(szFilePath[0])-'A';
161       if (m_szShadowCopyName[nDriveIndex][0] != 0) {
162          wcsncpy(szShadowPath, m_szShadowCopyName[nDriveIndex], nBuflen);
163          nBuflen -= (int)wcslen(m_szShadowCopyName[nDriveIndex]);
164          wcsncat(szShadowPath, szFilePath+2, nBuflen);
165          return TRUE;
166       }
167    }
168    
169    wcsncpy(szShadowPath,  szFilePath, nBuflen);
170    errno = EINVAL;
171    return FALSE;   
172 }
173
174
175 const size_t VSSClient::GetWriterCount()
176 {
177    alist* pV = (alist*) m_pAlistWriterInfoText;
178    return pV->size();
179 }
180
181 const char* VSSClient::GetWriterInfo(int nIndex)
182 {
183    alist* pV = (alist*) m_pAlistWriterInfoText;
184    return (char*) pV->get(nIndex);
185 }
186
187
188 const int VSSClient::GetWriterState(int nIndex)
189 {
190    alist* pV = (alist*) m_pAlistWriterState;   
191    return (int) pV->get(nIndex);
192 }
193
194 void VSSClient::AppendWriterInfo(int nState, const char* pszInfo)
195 {
196    alist* pT = (alist*) m_pAlistWriterInfoText;
197    alist* pS = (alist*) m_pAlistWriterState;
198
199    pT->push (bstrdup(pszInfo));
200    pS->push ((void*) nState);   
201 }
202
203 void VSSClient::DestroyWriterInfo()
204 {
205    alist* pT = (alist*) m_pAlistWriterInfoText;
206    alist* pS = (alist*) m_pAlistWriterState;
207
208    while (!pT->empty())
209       free (pT->pop());
210
211    while (!pS->empty())
212       pS->pop();      
213 }
214
215 #endif