2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2018 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
23 // Copyright transferred from MATRIX-Computer GmbH to
24 // Kern Sibbald by express permission.
27 * Author : Thorsten Engel
28 * Created On : Fri May 06 21:44:00 2006
35 #define b_errno_win32 (1<<29)
40 #define VSS_INIT_RESTORE_AFTER_INIT 1
41 #define VSS_INIT_RESTORE_AFTER_GATHER 2
43 // some forward declarations
46 #define bwcsdup(str) wcscpy((WCHAR *)bmalloc((wcslen(str)+1)*sizeof(WCHAR)),(str))
48 /* The MTabEntry class is representing a mounted volume,
49 * it associates a volume name with mount paths and a device name
51 class MTabEntry: public SMARTALLOC {
53 WCHAR *volumeName; // Name of the current volume
54 WCHAR *mountPaths; // List of mount paths
56 WCHAR *shadowCopyName;
66 in_SnapshotSet = false;
67 shadowCopyName = NULL;
72 MTabEntry(WCHAR *DeviceName, WCHAR *VolumeName) {
73 int last = wcslen(VolumeName);
74 if (VolumeName[last - 1] == L'\\') {
75 volumeName = bwcsdup(VolumeName);
76 } else { /* \\ + \0 */
77 volumeName = (WCHAR *)bmalloc(last+2*sizeof(WCHAR));
78 wcscpy(volumeName, VolumeName);
79 volumeName[last] = L'\\';
80 volumeName[last+1] = L'\0';
83 in_SnapshotSet = false;
84 deviceName = bwcsdup(DeviceName);
85 shadowCopyName = NULL;
108 if (shadowCopyName) {
109 free(shadowCopyName);
110 shadowCopyName = NULL;
114 /* Return the drive type (cdrom, fixed, network, ...) */
117 /* Return true if the current volume can be snapshoted (ie not CDROM or fat32) */
118 bool isSuitableForSnapshot();
120 void setInSnapshotSet() {
121 Dmsg1(050, "Marking %ls for the SnapshotSet\n", mountPaths);
122 in_SnapshotSet = true;
127 /* Display the paths in the list. */
128 if (mountPaths != NULL) {
129 Dmsg2(DT_VOLUME|10, "Device: [%ls], Volume: [%ls]\n", deviceName, volumeName);
130 for ( p = mountPaths; p[0] != L'\0'; p += wcslen(p) + 1) {
131 Dmsg1(DT_VOLUME|10, " %ls\n", p);
136 /* Compute the path list assiciated with the current volume */
138 DWORD count = MAX_PATH + 1;
142 // Allocate a buffer to hold the paths.
143 mountPaths = (WCHAR*) malloc(count * sizeof(WCHAR));
145 // Obtain all of the paths
147 ret = GetVolumePathNamesForVolumeNameW(volumeName, mountPaths,
153 if (GetLastError() != ERROR_MORE_DATA) {
157 // Try again with the
158 // new suggested size.
166 /* Return the first mount point */
171 /* Return the next mount point */
172 WCHAR *next(WCHAR *prev) {
173 if (prev == NULL || prev[0] == L'\0') {
177 prev += wcslen(prev) + 1;
179 return (prev[0] == L'\0') ? NULL : prev;
183 /* Class to handle all volumes of the system, it contains
184 * a list of all current volumes (MTabEntry)
186 class MTab: public SMARTALLOC {
189 const char *lasterror_str;
190 rblist *entries; /* MTabEntry */
191 int nb_in_SnapshotSet;
194 MTabEntry *elt = NULL;
195 lasterror = ERROR_SUCCESS;
197 nb_in_SnapshotSet = 0;
198 entries = New(rblist(elt, &elt->link));
204 foreach_rblist(elt, entries) {
210 /* Get a Volume by name */
211 MTabEntry *search(char *file);
213 /* Try to add a volume to the current snapshotset */
214 bool addInSnapshotSet(char *file);
216 /* Fill the "entries" list will all detected volumes of the system*/
224 virtual ~VSSClient();
227 bool InitializeForBackup(JCR *jcr);
228 bool InitializeForRestore(JCR *jcr);
229 virtual bool CreateSnapshots(alist *mount_points) = 0;
230 virtual bool CloseBackup() = 0;
231 virtual bool CloseRestore() = 0;
232 virtual WCHAR *GetMetadata() = 0;
233 virtual const char* GetDriverName() = 0;
234 bool GetShadowPath (const char* szFilePath, char* szShadowPath, int nBuflen);
235 bool GetShadowPathW (const wchar_t* szFilePath, wchar_t* szShadowPath, int nBuflen); /* nBuflen in characters */
237 const size_t GetWriterCount();
238 const char* GetWriterInfo(int nIndex);
239 const int GetWriterState(int nIndex);
240 void DestroyWriterInfo();
241 void AppendWriterInfo(int nState, const char* pszInfo);
242 const bool IsInitialized() { return m_bBackupIsInitialized; };
243 IUnknown *GetVssObject() { return m_pVssObject; };
246 virtual bool Initialize(DWORD dwContext, bool bDuringRestore = FALSE) = 0;
247 virtual bool WaitAndCheckForAsyncOperation(IVssAsync* pAsync) = 0;
248 virtual void QuerySnapshotSet(GUID snapshotSetID) = 0;
255 IUnknown* m_pVssObject;
256 GUID m_uidCurrentSnapshotSet;
260 alist *m_pAlistWriterState;
261 alist *m_pAlistWriterInfoText;
263 bool m_bCoInitializeCalled;
264 bool m_bCoInitializeSecurityCalled;
265 bool m_bDuringRestore; /* true if we are doing a restore */
266 bool m_bBackupIsInitialized;
267 bool m_bWriterStatusCurrent;
271 void CreateVSSVolumeList();
272 void DeleteVSSVolumeList();
275 class VSSClientXP:public VSSClient
279 virtual ~VSSClientXP();
280 virtual bool CreateSnapshots(alist *mount_points);
281 virtual bool CloseBackup();
282 virtual bool CloseRestore();
283 virtual WCHAR *GetMetadata();
285 virtual const char* GetDriverName() { return "Win64 VSS"; };
287 virtual const char* GetDriverName() { return "Win32 VSS"; };
290 virtual bool Initialize(DWORD dwContext, bool bDuringRestore);
291 virtual bool WaitAndCheckForAsyncOperation(IVssAsync* pAsync);
292 virtual void QuerySnapshotSet(GUID snapshotSetID);
293 bool CheckWriterStatus();
296 class VSSClient2003:public VSSClient
300 virtual ~VSSClient2003();
301 virtual bool CreateSnapshots(alist *mount_points);
302 virtual bool CloseBackup();
303 virtual bool CloseRestore();
304 virtual WCHAR *GetMetadata();
306 virtual const char* GetDriverName() { return "Win64 VSS"; };
308 virtual const char* GetDriverName() { return "Win32 VSS"; };
311 virtual bool Initialize(DWORD dwContext, bool bDuringRestore);
312 virtual bool WaitAndCheckForAsyncOperation(IVssAsync* pAsync);
313 virtual void QuerySnapshotSet(GUID snapshotSetID);
314 bool CheckWriterStatus();
317 class VSSClientVista:public VSSClient
321 virtual ~VSSClientVista();
322 virtual bool CreateSnapshots(alist *mount_points);
323 virtual bool CloseBackup();
324 virtual bool CloseRestore();
325 virtual WCHAR *GetMetadata();
327 virtual const char* GetDriverName() { return "Win64 VSS"; };
329 virtual const char* GetDriverName() { return "Win32 VSS"; };
332 virtual bool Initialize(DWORD dwContext, bool bDuringRestore);
333 virtual bool WaitAndCheckForAsyncOperation(IVssAsync* pAsync);
334 virtual void QuerySnapshotSet(GUID snapshotSetID);
335 bool CheckWriterStatus();
339 BOOL VSSPathConvert(const char *szFilePath, char *szShadowPath, int nBuflen);
340 BOOL VSSPathConvertW(const wchar_t *szFilePath, wchar_t *szShadowPath, int nBuflen);
342 #endif /* WIN32_VSS */
344 #endif /* __VSS_H_ */