implemented log file monitoring using Windows VSS snapshots
[public/netxms.git] / src / libnxlp / vss.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Log Parsing Library
4 ** Copyright (C) 2003-2017 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 ** File: wevt.cpp
21 **
22 **/
23
24 #define _WIN32_WINNT 0x0600
25 #include "libnxlp.h"
26 #include <vss.h>
27 #include <vswriter.h>
28 #include <vsbackup.h>
29 #include <comdef.h>
30
31 #define DEBUG_TAG _T("logwatch.vss")
32
33 /**
34 * Helper function to display error and return failure in FileSnapshot::create
35 */
36 inline FileSnapshot *CreateFailure(HRESULT hr, IVssBackupComponents *bc, const TCHAR *format)
37 {
38 _com_error err(hr);
39 nxlog_debug_tag(DEBUG_TAG, 3, format, err.ErrorMessage(), hr);
40 if (bc != NULL)
41 bc->Release();
42 return NULL;
43 }
44
45 /**
46 * Create file snapshot using VSS
47 */
48 FileSnapshot *FileSnapshot::create(const TCHAR *path)
49 {
50 IVssBackupComponents *bc;
51 HRESULT hr = CreateVssBackupComponents(&bc);
52 if (FAILED(hr))
53 return CreateFailure(hr, NULL, _T("Call to CreateVssBackupComponents failed (%s) HRESULT=0x%08X"));
54
55 hr = bc->InitializeForBackup();
56 if (FAILED(hr))
57 return CreateFailure(hr, bc, _T("Call to IVssBackupComponents::InitializeForBackup failed (%s) HRESULT=0x%08X"));
58
59 hr = bc->SetBackupState(false, false, VSS_BT_COPY);
60 if (FAILED(hr))
61 return CreateFailure(hr, bc, _T("Call to IVssBackupComponents::SetBackupState failed (%s) HRESULT=0x%08X"));
62
63 hr = bc->SetContext(VSS_CTX_FILE_SHARE_BACKUP);
64 if (FAILED(hr))
65 return CreateFailure(hr, bc, _T("Call to IVssBackupComponents::SetContext failed (%s) HRESULT=0x%08X"));
66
67 VSS_ID snapshotSetId;
68 hr = bc->StartSnapshotSet(&snapshotSetId);
69 if (FAILED(hr))
70 return CreateFailure(hr, bc, _T("Call to IVssBackupComponents::StartSnapshotSet failed (%s) HRESULT=0x%08X"));
71
72 const TCHAR *s = _tcschr(path, _T(':'));
73 if (s == NULL)
74 return CreateFailure(S_OK, bc, _T("Unsupported file path format"));
75 s++;
76
77 size_t len = s - path;
78 TCHAR device[64];
79 _tcslcpy(device, path, std::min(static_cast<size_t>(64), len + 1));
80 _tcslcat(device, _T("\\"), 64);
81 nxlog_debug_tag(DEBUG_TAG, 7, _T("Adding device %s to VSS snapshot"), device);
82
83 VSS_ID snapshotId;
84 hr = bc->AddToSnapshotSet(device, GUID_NULL, &snapshotId);
85 if (FAILED(hr))
86 return CreateFailure(hr, bc, _T("Call to IVssBackupComponents::AddToSnapshotSet failed (%s) HRESULT=0x%08X"));
87
88 IVssAsync *async;
89 hr = bc->DoSnapshotSet(&async);
90 if (FAILED(hr))
91 return CreateFailure(hr, bc, _T("Call to IVssBackupComponents::DoSnapshotSet failed (%s) HRESULT=0x%08X"));
92
93 hr = async->Wait();
94 async->Release();
95 if (FAILED(hr))
96 return CreateFailure(hr, bc, _T("Call to IVssAsync::Wait failed (%s) HRESULT=0x%08X"));
97
98 VSS_SNAPSHOT_PROP prop;
99 hr = bc->GetSnapshotProperties(snapshotId, &prop);
100 if (FAILED(hr))
101 return CreateFailure(hr, bc, _T("Call to IVssBackupComponents::GetSnapshotProperties failed (%s) HRESULT=0x%08X"));
102
103 nxlog_debug_tag(DEBUG_TAG, 7, _T("Created VSS snapshot %s"), prop.m_pwszSnapshotDeviceObject);
104 String sname(prop.m_pwszSnapshotDeviceObject);
105 sname.append(s);
106
107 FileSnapshot *object = new FileSnapshot();
108 object->m_handle = bc;
109 object->m_name = _tcsdup(sname);
110 return object;
111 }
112
113 /**
114 * File snapshot object constructor
115 */
116 FileSnapshot::FileSnapshot()
117 {
118 m_handle = NULL;
119 m_name = NULL;
120 }
121
122 /**
123 * File snapshot destructor
124 */
125 FileSnapshot::~FileSnapshot()
126 {
127 m_handle->Release();
128 free(m_name);
129 }