diff options
Diffstat (limited to 'qemu/qga/vss-win32')
-rw-r--r-- | qemu/qga/vss-win32/Makefile.objs | 23 | ||||
-rw-r--r-- | qemu/qga/vss-win32/install.cpp | 464 | ||||
-rw-r--r-- | qemu/qga/vss-win32/provider.cpp | 534 | ||||
-rw-r--r-- | qemu/qga/vss-win32/qga-vss.def | 13 | ||||
-rw-r--r-- | qemu/qga/vss-win32/qga-vss.idl | 20 | ||||
-rw-r--r-- | qemu/qga/vss-win32/qga-vss.tlb | bin | 1528 -> 0 bytes | |||
-rw-r--r-- | qemu/qga/vss-win32/requester.cpp | 504 | ||||
-rw-r--r-- | qemu/qga/vss-win32/requester.h | 45 | ||||
-rw-r--r-- | qemu/qga/vss-win32/vss-common.h | 128 |
9 files changed, 0 insertions, 1731 deletions
diff --git a/qemu/qga/vss-win32/Makefile.objs b/qemu/qga/vss-win32/Makefile.objs deleted file mode 100644 index 7c96c6b28..000000000 --- a/qemu/qga/vss-win32/Makefile.objs +++ /dev/null @@ -1,23 +0,0 @@ -# rules to build qga-vss.dll - -qga-vss-dll-obj-y += requester.o provider.o install.o - -obj-qga-vss-dll-obj-y = $(addprefix $(obj)/, $(qga-vss-dll-obj-y)) -$(obj-qga-vss-dll-obj-y): QEMU_CXXFLAGS = $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wold-style-declaration -Wold-style-definition -Wredundant-decls -fstack-protector-all -fstack-protector-strong, $(QEMU_CFLAGS)) -Wno-unknown-pragmas -Wno-delete-non-virtual-dtor - -$(obj)/qga-vss.dll: LDFLAGS = -shared -Wl,--add-stdcall-alias,--enable-stdcall-fixup -lole32 -loleaut32 -lshlwapi -luuid -static -$(obj)/qga-vss.dll: $(obj-qga-vss-dll-obj-y) $(SRC_PATH)/$(obj)/qga-vss.def - $(call quiet-command,$(CXX) -o $@ $(qga-vss-dll-obj-y) $(SRC_PATH)/qga/vss-win32/qga-vss.def $(CXXFLAGS) $(LDFLAGS)," LINK $(TARGET_DIR)$@") - - -# rules to build qga-provider.tlb -# Currently, only native build is supported because building .tlb -# (TypeLibrary) from .idl requires WindowsSDK and MIDL (and cl.exe in VC++). -MIDL=$(WIN_SDK)/Bin/midl - -$(obj)/qga-vss.tlb: $(SRC_PATH)/$(obj)/qga-vss.idl -ifeq ($(WIN_SDK),"") - $(call quiet-command,cp $(dir $<)qga-vss.tlb $@, " COPY $(TARGET_DIR)$@") -else - $(call quiet-command,$(MIDL) -tlb $@ -I $(WIN_SDK)/Include $<," MIDL $(TARGET_DIR)$@") -endif diff --git a/qemu/qga/vss-win32/install.cpp b/qemu/qga/vss-win32/install.cpp deleted file mode 100644 index cd9cdb4a2..000000000 --- a/qemu/qga/vss-win32/install.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/* - * QEMU Guest Agent win32 VSS Provider installer - * - * Copyright Hitachi Data Systems Corp. 2013 - * - * Authors: - * Tomoki Sekiyama <tomoki.sekiyama@hds.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#include "qemu/osdep.h" - -#include "vss-common.h" -#include "inc/win2003/vscoordint.h" - -#include <comadmin.h> -#include <wbemidl.h> -#include <comdef.h> -#include <comutil.h> - -extern HINSTANCE g_hinstDll; - -const GUID CLSID_COMAdminCatalog = { 0xF618C514, 0xDFB8, 0x11d1, - {0xA2, 0xCF, 0x00, 0x80, 0x5F, 0xC7, 0x92, 0x35} }; -const GUID IID_ICOMAdminCatalog2 = { 0x790C6E0B, 0x9194, 0x4cc9, - {0x94, 0x26, 0xA4, 0x8A, 0x63, 0x18, 0x56, 0x96} }; -const GUID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0, - {0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} }; -const GUID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf, - {0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} }; - -void errmsg(DWORD err, const char *text) -{ - /* - * `text' contains function call statement when errmsg is called via chk(). - * To make error message more readable, we cut off the text after '('. - * If text doesn't contains '(', negative precision is given, which is - * treated as though it were missing. - */ - char *msg = NULL, *nul = strchr(text, '('); - int len = nul ? nul - text : -1; - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (char *)&msg, 0, NULL); - fprintf(stderr, "%.*s. (Error: %lx) %s\n", len, text, err, msg); - LocalFree(msg); -} - -static void errmsg_dialog(DWORD err, const char *text, const char *opt = "") -{ - char *msg, buf[512]; - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (char *)&msg, 0, NULL); - snprintf(buf, sizeof(buf), "%s%s. (Error: %lx) %s", text, opt, err, msg); - MessageBox(NULL, buf, "Error from " QGA_PROVIDER_NAME, MB_OK|MB_ICONERROR); - LocalFree(msg); -} - -#define _chk(hr, status, msg, err_label) \ - do { \ - hr = (status); \ - if (FAILED(hr)) { \ - errmsg(hr, msg); \ - goto err_label; \ - } \ - } while (0) - -#define chk(status) _chk(hr, status, "Failed to " #status, out) - -#if !defined(__MINGW64_VERSION_MAJOR) || !defined(__MINGW64_VERSION_MINOR) || \ - __MINGW64_VERSION_MAJOR * 100 + __MINGW64_VERSION_MINOR < 301 -void __stdcall _com_issue_error(HRESULT hr) -{ - errmsg(hr, "Unexpected error in COM"); -} -#endif - -template<class T> -HRESULT put_Value(ICatalogObject *pObj, LPCWSTR name, T val) -{ - return pObj->put_Value(_bstr_t(name), _variant_t(val)); -} - -/* Lookup Administrators group name from winmgmt */ -static HRESULT GetAdminName(_bstr_t *name) -{ - HRESULT hr; - COMPointer<IWbemLocator> pLoc; - COMPointer<IWbemServices> pSvc; - COMPointer<IEnumWbemClassObject> pEnum; - COMPointer<IWbemClassObject> pWobj; - ULONG returned; - _variant_t var; - - chk(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, - IID_IWbemLocator, (LPVOID *)pLoc.replace())); - chk(pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, NULL, - 0, 0, 0, pSvc.replace())); - chk(CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, - NULL, RPC_C_AUTHN_LEVEL_CALL, - RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE)); - chk(pSvc->ExecQuery(_bstr_t(L"WQL"), - _bstr_t(L"select * from Win32_Account where " - "SID='S-1-5-32-544' and localAccount=TRUE"), - WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, - NULL, pEnum.replace())); - if (!pEnum) { - hr = E_FAIL; - errmsg(hr, "Failed to query for Administrators"); - goto out; - } - chk(pEnum->Next(WBEM_INFINITE, 1, pWobj.replace(), &returned)); - if (returned == 0) { - hr = E_FAIL; - errmsg(hr, "No Administrators found"); - goto out; - } - - chk(pWobj->Get(_bstr_t(L"Name"), 0, &var, 0, 0)); - try { - *name = var; - } catch(...) { - hr = E_FAIL; - errmsg(hr, "Failed to get name of Administrators"); - goto out; - } - -out: - return hr; -} - -/* Find and iterate QGA VSS provider in COM+ Application Catalog */ -static HRESULT QGAProviderFind( - HRESULT (*found)(ICatalogCollection *, int, void *), void *arg) -{ - HRESULT hr; - COMInitializer initializer; - COMPointer<IUnknown> pUnknown; - COMPointer<ICOMAdminCatalog2> pCatalog; - COMPointer<ICatalogCollection> pColl; - COMPointer<ICatalogObject> pObj; - _variant_t var; - long i, n; - - chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER, - IID_IUnknown, (void **)pUnknown.replace())); - chk(pUnknown->QueryInterface(IID_ICOMAdminCatalog2, - (void **)pCatalog.replace())); - chk(pCatalog->GetCollection(_bstr_t(L"Applications"), - (IDispatch **)pColl.replace())); - chk(pColl->Populate()); - - chk(pColl->get_Count(&n)); - for (i = n - 1; i >= 0; i--) { - chk(pColl->get_Item(i, (IDispatch **)pObj.replace())); - chk(pObj->get_Value(_bstr_t(L"Name"), &var)); - if (var == _variant_t(QGA_PROVIDER_LNAME)) { - if (FAILED(found(pColl, i, arg))) { - goto out; - } - } - } - chk(pColl->SaveChanges(&n)); - -out: - return hr; -} - -/* Count QGA VSS provider in COM+ Application Catalog */ -static HRESULT QGAProviderCount(ICatalogCollection *coll, int i, void *arg) -{ - (*(int *)arg)++; - return S_OK; -} - -/* Remove QGA VSS provider from COM+ Application Catalog Collection */ -static HRESULT QGAProviderRemove(ICatalogCollection *coll, int i, void *arg) -{ - HRESULT hr; - - fprintf(stderr, "Removing COM+ Application: %s\n", QGA_PROVIDER_NAME); - chk(coll->Remove(i)); -out: - return hr; -} - -/* Unregister this module from COM+ Applications Catalog */ -STDAPI COMUnregister(void) -{ - HRESULT hr; - - DllUnregisterServer(); - chk(QGAProviderFind(QGAProviderRemove, NULL)); -out: - return hr; -} - -/* Register this module to COM+ Applications Catalog */ -STDAPI COMRegister(void) -{ - HRESULT hr; - COMInitializer initializer; - COMPointer<IUnknown> pUnknown; - COMPointer<ICOMAdminCatalog2> pCatalog; - COMPointer<ICatalogCollection> pApps, pRoles, pUsersInRole; - COMPointer<ICatalogObject> pObj; - long n; - _bstr_t name; - _variant_t key; - CHAR dllPath[MAX_PATH], tlbPath[MAX_PATH]; - bool unregisterOnFailure = false; - int count = 0; - - if (!g_hinstDll) { - errmsg(E_FAIL, "Failed to initialize DLL"); - return E_FAIL; - } - - chk(QGAProviderFind(QGAProviderCount, (void *)&count)); - if (count) { - errmsg(E_ABORT, "QGA VSS Provider is already installed"); - return E_ABORT; - } - - chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER, - IID_IUnknown, (void **)pUnknown.replace())); - chk(pUnknown->QueryInterface(IID_ICOMAdminCatalog2, - (void **)pCatalog.replace())); - - /* Install COM+ Component */ - - chk(pCatalog->GetCollection(_bstr_t(L"Applications"), - (IDispatch **)pApps.replace())); - chk(pApps->Populate()); - chk(pApps->Add((IDispatch **)&pObj)); - chk(put_Value(pObj, L"Name", QGA_PROVIDER_LNAME)); - chk(put_Value(pObj, L"Description", QGA_PROVIDER_LNAME)); - chk(put_Value(pObj, L"ApplicationAccessChecksEnabled", true)); - chk(put_Value(pObj, L"Authentication", short(6))); - chk(put_Value(pObj, L"AuthenticationCapability", short(2))); - chk(put_Value(pObj, L"ImpersonationLevel", short(2))); - chk(pApps->SaveChanges(&n)); - - /* The app should be deleted if something fails after SaveChanges */ - unregisterOnFailure = true; - - chk(pObj->get_Key(&key)); - - if (!GetModuleFileName(g_hinstDll, dllPath, sizeof(dllPath))) { - hr = HRESULT_FROM_WIN32(GetLastError()); - errmsg(hr, "GetModuleFileName failed"); - goto out; - } - n = strlen(dllPath); - if (n < 3) { - hr = E_FAIL; - errmsg(hr, "Failed to lookup dll"); - goto out; - } - strcpy(tlbPath, dllPath); - strcpy(tlbPath+n-3, "tlb"); - fprintf(stderr, "Registering " QGA_PROVIDER_NAME ":\n"); - fprintf(stderr, " %s\n", dllPath); - fprintf(stderr, " %s\n", tlbPath); - if (!PathFileExists(tlbPath)) { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - errmsg(hr, "Failed to lookup tlb"); - goto out; - } - - chk(pCatalog->CreateServiceForApplication( - _bstr_t(QGA_PROVIDER_LNAME), _bstr_t(QGA_PROVIDER_LNAME), - _bstr_t(L"SERVICE_AUTO_START"), _bstr_t(L"SERVICE_ERROR_NORMAL"), - _bstr_t(L""), _bstr_t(L".\\localsystem"), _bstr_t(L""), FALSE)); - chk(pCatalog->InstallComponent(_bstr_t(QGA_PROVIDER_LNAME), - _bstr_t(dllPath), _bstr_t(tlbPath), - _bstr_t(""))); - - /* Setup roles of the applicaion */ - - chk(pApps->GetCollection(_bstr_t(L"Roles"), key, - (IDispatch **)pRoles.replace())); - chk(pRoles->Populate()); - chk(pRoles->Add((IDispatch **)pObj.replace())); - chk(put_Value(pObj, L"Name", L"Administrators")); - chk(put_Value(pObj, L"Description", L"Administrators group")); - chk(pRoles->SaveChanges(&n)); - chk(pObj->get_Key(&key)); - - /* Setup users in the role */ - - chk(pRoles->GetCollection(_bstr_t(L"UsersInRole"), key, - (IDispatch **)pUsersInRole.replace())); - chk(pUsersInRole->Populate()); - - chk(pUsersInRole->Add((IDispatch **)pObj.replace())); - chk(GetAdminName(&name)); - chk(put_Value(pObj, L"User", _bstr_t(".\\") + name)); - - chk(pUsersInRole->Add((IDispatch **)pObj.replace())); - chk(put_Value(pObj, L"User", L"SYSTEM")); - chk(pUsersInRole->SaveChanges(&n)); - -out: - if (unregisterOnFailure && FAILED(hr)) { - COMUnregister(); - } - - return hr; -} - - -static BOOL CreateRegistryKey(LPCTSTR key, LPCTSTR value, LPCTSTR data) -{ - HKEY hKey; - LONG ret; - DWORD size; - - ret = RegCreateKeyEx(HKEY_CLASSES_ROOT, key, 0, NULL, - REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL); - if (ret != ERROR_SUCCESS) { - goto out; - } - - if (data != NULL) { - size = strlen(data) + 1; - } else { - size = 0; - } - - ret = RegSetValueEx(hKey, value, 0, REG_SZ, (LPBYTE)data, size); - RegCloseKey(hKey); - -out: - if (ret != ERROR_SUCCESS) { - /* As we cannot printf within DllRegisterServer(), show a dialog. */ - errmsg_dialog(ret, "Cannot add registry", key); - return FALSE; - } - return TRUE; -} - -/* Register this dll as a VSS provider */ -STDAPI DllRegisterServer(void) -{ - COMInitializer initializer; - COMPointer<IVssAdmin> pVssAdmin; - HRESULT hr = E_FAIL; - char dllPath[MAX_PATH]; - char key[256]; - - if (!g_hinstDll) { - errmsg_dialog(hr, "Module instance is not available"); - goto out; - } - - /* Add this module to registery */ - - sprintf(key, "CLSID\\%s", g_szClsid); - if (!CreateRegistryKey(key, NULL, g_szClsid)) { - goto out; - } - - if (!GetModuleFileName(g_hinstDll, dllPath, sizeof(dllPath))) { - errmsg_dialog(GetLastError(), "GetModuleFileName failed"); - goto out; - } - - sprintf(key, "CLSID\\%s\\InprocServer32", g_szClsid); - if (!CreateRegistryKey(key, NULL, dllPath)) { - goto out; - } - - if (!CreateRegistryKey(key, "ThreadingModel", "Apartment")) { - goto out; - } - - sprintf(key, "CLSID\\%s\\ProgID", g_szClsid); - if (!CreateRegistryKey(key, NULL, g_szProgid)) { - goto out; - } - - if (!CreateRegistryKey(g_szProgid, NULL, QGA_PROVIDER_NAME)) { - goto out; - } - - sprintf(key, "%s\\CLSID", g_szProgid); - if (!CreateRegistryKey(key, NULL, g_szClsid)) { - goto out; - } - - hr = CoCreateInstance(CLSID_VSSCoordinator, NULL, CLSCTX_ALL, - IID_IVssAdmin, (void **)pVssAdmin.replace()); - if (FAILED(hr)) { - errmsg_dialog(hr, "CoCreateInstance(VSSCoordinator) failed"); - goto out; - } - - hr = pVssAdmin->RegisterProvider(g_gProviderId, CLSID_QGAVSSProvider, - const_cast<WCHAR*>(QGA_PROVIDER_LNAME), - VSS_PROV_SOFTWARE, - const_cast<WCHAR*>(QGA_PROVIDER_VERSION), - g_gProviderVersion); - if (FAILED(hr)) { - errmsg_dialog(hr, "RegisterProvider failed"); - } - -out: - if (FAILED(hr)) { - DllUnregisterServer(); - } - - return hr; -} - -/* Unregister this VSS hardware provider from the system */ -STDAPI DllUnregisterServer(void) -{ - TCHAR key[256]; - COMInitializer initializer; - COMPointer<IVssAdmin> pVssAdmin; - - HRESULT hr = CoCreateInstance(CLSID_VSSCoordinator, - NULL, CLSCTX_ALL, IID_IVssAdmin, - (void **)pVssAdmin.replace()); - if (SUCCEEDED(hr)) { - hr = pVssAdmin->UnregisterProvider(g_gProviderId); - } else { - errmsg(hr, "CoCreateInstance(VSSCoordinator) failed"); - } - - sprintf(key, "CLSID\\%s", g_szClsid); - SHDeleteKey(HKEY_CLASSES_ROOT, key); - SHDeleteKey(HKEY_CLASSES_ROOT, g_szProgid); - - return S_OK; /* Uninstall should never fail */ -} - - -/* Support function to convert ASCII string into BSTR (used in _bstr_t) */ -namespace _com_util -{ - BSTR WINAPI ConvertStringToBSTR(const char *ascii) { - int len = strlen(ascii); - BSTR bstr = SysAllocStringLen(NULL, len); - - if (!bstr) { - return NULL; - } - - if (mbstowcs(bstr, ascii, len) == (size_t)-1) { - fprintf(stderr, "Failed to convert string '%s' into BSTR", ascii); - bstr[0] = 0; - } - return bstr; - } -} diff --git a/qemu/qga/vss-win32/provider.cpp b/qemu/qga/vss-win32/provider.cpp deleted file mode 100644 index d977393e3..000000000 --- a/qemu/qga/vss-win32/provider.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/* - * QEMU Guest Agent win32 VSS Provider implementations - * - * Copyright Hitachi Data Systems Corp. 2013 - * - * Authors: - * Tomoki Sekiyama <tomoki.sekiyama@hds.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#include "qemu/osdep.h" -#include "vss-common.h" -#include "inc/win2003/vscoordint.h" -#include "inc/win2003/vsprov.h" - -#define VSS_TIMEOUT_MSEC (60*1000) - -static long g_nComObjsInUse; -HINSTANCE g_hinstDll; - -/* VSS common GUID's */ - -const CLSID CLSID_VSSCoordinator = { 0xE579AB5F, 0x1CC4, 0x44b4, - {0xBE, 0xD9, 0xDE, 0x09, 0x91, 0xFF, 0x06, 0x23} }; -const IID IID_IVssAdmin = { 0x77ED5996, 0x2F63, 0x11d3, - {0x8A, 0x39, 0x00, 0xC0, 0x4F, 0x72, 0xD8, 0xE3} }; - -const IID IID_IVssHardwareSnapshotProvider = { 0x9593A157, 0x44E9, 0x4344, - {0xBB, 0xEB, 0x44, 0xFB, 0xF9, 0xB0, 0x6B, 0x10} }; -const IID IID_IVssSoftwareSnapshotProvider = { 0x609e123e, 0x2c5a, 0x44d3, - {0x8f, 0x01, 0x0b, 0x1d, 0x9a, 0x47, 0xd1, 0xff} }; -const IID IID_IVssProviderCreateSnapshotSet = { 0x5F894E5B, 0x1E39, 0x4778, - {0x8E, 0x23, 0x9A, 0xBA, 0xD9, 0xF0, 0xE0, 0x8C} }; -const IID IID_IVssProviderNotifications = { 0xE561901F, 0x03A5, 0x4afe, - {0x86, 0xD0, 0x72, 0xBA, 0xEE, 0xCE, 0x70, 0x04} }; - -const IID IID_IVssEnumObject = { 0xAE1C7110, 0x2F60, 0x11d3, - {0x8A, 0x39, 0x00, 0xC0, 0x4F, 0x72, 0xD8, 0xE3} }; - - -void LockModule(BOOL lock) -{ - if (lock) { - InterlockedIncrement(&g_nComObjsInUse); - } else { - InterlockedDecrement(&g_nComObjsInUse); - } -} - -/* Empty enumerator for VssObject */ - -class CQGAVSSEnumObject : public IVssEnumObject -{ -public: - STDMETHODIMP QueryInterface(REFIID riid, void **ppObj); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - /* IVssEnumObject Methods */ - STDMETHODIMP Next( - ULONG celt, VSS_OBJECT_PROP *rgelt, ULONG *pceltFetched); - STDMETHODIMP Skip(ULONG celt); - STDMETHODIMP Reset(void); - STDMETHODIMP Clone(IVssEnumObject **ppenum); - - /* CQGAVSSEnumObject Methods */ - CQGAVSSEnumObject(); - ~CQGAVSSEnumObject(); - -private: - long m_nRefCount; -}; - -CQGAVSSEnumObject::CQGAVSSEnumObject() -{ - m_nRefCount = 0; - LockModule(TRUE); -} - -CQGAVSSEnumObject::~CQGAVSSEnumObject() -{ - LockModule(FALSE); -} - -STDMETHODIMP CQGAVSSEnumObject::QueryInterface(REFIID riid, void **ppObj) -{ - if (riid == IID_IUnknown || riid == IID_IVssEnumObject) { - *ppObj = static_cast<void*>(static_cast<IVssEnumObject*>(this)); - AddRef(); - return S_OK; - } - *ppObj = NULL; - return E_NOINTERFACE; -} - -STDMETHODIMP_(ULONG) CQGAVSSEnumObject::AddRef() -{ - return InterlockedIncrement(&m_nRefCount); -} - -STDMETHODIMP_(ULONG) CQGAVSSEnumObject::Release() -{ - long nRefCount = InterlockedDecrement(&m_nRefCount); - if (m_nRefCount == 0) { - delete this; - } - return nRefCount; -} - -STDMETHODIMP CQGAVSSEnumObject::Next( - ULONG celt, VSS_OBJECT_PROP *rgelt, ULONG *pceltFetched) -{ - *pceltFetched = 0; - return S_FALSE; -} - -STDMETHODIMP CQGAVSSEnumObject::Skip(ULONG celt) -{ - return S_FALSE; -} - -STDMETHODIMP CQGAVSSEnumObject::Reset(void) -{ - return S_OK; -} - -STDMETHODIMP CQGAVSSEnumObject::Clone(IVssEnumObject **ppenum) -{ - return E_NOTIMPL; -} - - -/* QGAVssProvider */ - -class CQGAVssProvider : - public IVssSoftwareSnapshotProvider, - public IVssProviderCreateSnapshotSet, - public IVssProviderNotifications -{ -public: - STDMETHODIMP QueryInterface(REFIID riid, void **ppObj); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - /* IVssSoftwareSnapshotProvider Methods */ - STDMETHODIMP SetContext(LONG lContext); - STDMETHODIMP GetSnapshotProperties( - VSS_ID SnapshotId, VSS_SNAPSHOT_PROP *pProp); - STDMETHODIMP Query( - VSS_ID QueriedObjectId, VSS_OBJECT_TYPE eQueriedObjectType, - VSS_OBJECT_TYPE eReturnedObjectsType, IVssEnumObject **ppEnum); - STDMETHODIMP DeleteSnapshots( - VSS_ID SourceObjectId, VSS_OBJECT_TYPE eSourceObjectType, - BOOL bForceDelete, LONG *plDeletedSnapshots, - VSS_ID *pNondeletedSnapshotID); - STDMETHODIMP BeginPrepareSnapshot( - VSS_ID SnapshotSetId, VSS_ID SnapshotId, - VSS_PWSZ pwszVolumeName, LONG lNewContext); - STDMETHODIMP IsVolumeSupported( - VSS_PWSZ pwszVolumeName, BOOL *pbSupportedByThisProvider); - STDMETHODIMP IsVolumeSnapshotted( - VSS_PWSZ pwszVolumeName, BOOL *pbSnapshotsPresent, - LONG *plSnapshotCompatibility); - STDMETHODIMP SetSnapshotProperty( - VSS_ID SnapshotId, VSS_SNAPSHOT_PROPERTY_ID eSnapshotPropertyId, - VARIANT vProperty); - STDMETHODIMP RevertToSnapshot(VSS_ID SnapshotId); - STDMETHODIMP QueryRevertStatus(VSS_PWSZ pwszVolume, IVssAsync **ppAsync); - - /* IVssProviderCreateSnapshotSet Methods */ - STDMETHODIMP EndPrepareSnapshots(VSS_ID SnapshotSetId); - STDMETHODIMP PreCommitSnapshots(VSS_ID SnapshotSetId); - STDMETHODIMP CommitSnapshots(VSS_ID SnapshotSetId); - STDMETHODIMP PostCommitSnapshots( - VSS_ID SnapshotSetId, LONG lSnapshotsCount); - STDMETHODIMP PreFinalCommitSnapshots(VSS_ID SnapshotSetId); - STDMETHODIMP PostFinalCommitSnapshots(VSS_ID SnapshotSetId); - STDMETHODIMP AbortSnapshots(VSS_ID SnapshotSetId); - - /* IVssProviderNotifications Methods */ - STDMETHODIMP OnLoad(IUnknown *pCallback); - STDMETHODIMP OnUnload(BOOL bForceUnload); - - /* CQGAVssProvider Methods */ - CQGAVssProvider(); - ~CQGAVssProvider(); - -private: - long m_nRefCount; -}; - -CQGAVssProvider::CQGAVssProvider() -{ - m_nRefCount = 0; - LockModule(TRUE); -} - -CQGAVssProvider::~CQGAVssProvider() -{ - LockModule(FALSE); -} - -STDMETHODIMP CQGAVssProvider::QueryInterface(REFIID riid, void **ppObj) -{ - if (riid == IID_IUnknown) { - *ppObj = static_cast<void*>(this); - AddRef(); - return S_OK; - } - if (riid == IID_IVssSoftwareSnapshotProvider) { - *ppObj = static_cast<void*>( - static_cast<IVssSoftwareSnapshotProvider*>(this)); - AddRef(); - return S_OK; - } - if (riid == IID_IVssProviderCreateSnapshotSet) { - *ppObj = static_cast<void*>( - static_cast<IVssProviderCreateSnapshotSet*>(this)); - AddRef(); - return S_OK; - } - if (riid == IID_IVssProviderNotifications) { - *ppObj = static_cast<void*>( - static_cast<IVssProviderNotifications*>(this)); - AddRef(); - return S_OK; - } - *ppObj = NULL; - return E_NOINTERFACE; -} - -STDMETHODIMP_(ULONG) CQGAVssProvider::AddRef() -{ - return InterlockedIncrement(&m_nRefCount); -} - -STDMETHODIMP_(ULONG) CQGAVssProvider::Release() -{ - long nRefCount = InterlockedDecrement(&m_nRefCount); - if (m_nRefCount == 0) { - delete this; - } - return nRefCount; -} - - -/* - * IVssSoftwareSnapshotProvider methods - */ - -STDMETHODIMP CQGAVssProvider::SetContext(LONG lContext) -{ - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::GetSnapshotProperties( - VSS_ID SnapshotId, VSS_SNAPSHOT_PROP *pProp) -{ - return VSS_E_OBJECT_NOT_FOUND; -} - -STDMETHODIMP CQGAVssProvider::Query( - VSS_ID QueriedObjectId, VSS_OBJECT_TYPE eQueriedObjectType, - VSS_OBJECT_TYPE eReturnedObjectsType, IVssEnumObject **ppEnum) -{ - try { - *ppEnum = new CQGAVSSEnumObject; - } catch (...) { - return E_OUTOFMEMORY; - } - (*ppEnum)->AddRef(); - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::DeleteSnapshots( - VSS_ID SourceObjectId, VSS_OBJECT_TYPE eSourceObjectType, - BOOL bForceDelete, LONG *plDeletedSnapshots, VSS_ID *pNondeletedSnapshotID) -{ - *plDeletedSnapshots = 0; - *pNondeletedSnapshotID = SourceObjectId; - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::BeginPrepareSnapshot( - VSS_ID SnapshotSetId, VSS_ID SnapshotId, - VSS_PWSZ pwszVolumeName, LONG lNewContext) -{ - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::IsVolumeSupported( - VSS_PWSZ pwszVolumeName, BOOL *pbSupportedByThisProvider) -{ - HANDLE hEventFrozen; - - /* Check if a requester is qemu-ga by whether an event is created */ - hEventFrozen = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_FROZEN); - if (!hEventFrozen) { - *pbSupportedByThisProvider = FALSE; - return S_OK; - } - CloseHandle(hEventFrozen); - - *pbSupportedByThisProvider = TRUE; - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::IsVolumeSnapshotted(VSS_PWSZ pwszVolumeName, - BOOL *pbSnapshotsPresent, LONG *plSnapshotCompatibility) -{ - *pbSnapshotsPresent = FALSE; - *plSnapshotCompatibility = 0; - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::SetSnapshotProperty(VSS_ID SnapshotId, - VSS_SNAPSHOT_PROPERTY_ID eSnapshotPropertyId, VARIANT vProperty) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CQGAVssProvider::RevertToSnapshot(VSS_ID SnapshotId) -{ - return E_NOTIMPL; -} - -STDMETHODIMP CQGAVssProvider::QueryRevertStatus( - VSS_PWSZ pwszVolume, IVssAsync **ppAsync) -{ - return E_NOTIMPL; -} - - -/* - * IVssProviderCreateSnapshotSet methods - */ - -STDMETHODIMP CQGAVssProvider::EndPrepareSnapshots(VSS_ID SnapshotSetId) -{ - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::PreCommitSnapshots(VSS_ID SnapshotSetId) -{ - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::CommitSnapshots(VSS_ID SnapshotSetId) -{ - HRESULT hr = S_OK; - HANDLE hEventFrozen, hEventThaw, hEventTimeout; - - hEventFrozen = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_FROZEN); - if (!hEventFrozen) { - return E_FAIL; - } - - hEventThaw = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_THAW); - if (!hEventThaw) { - CloseHandle(hEventFrozen); - return E_FAIL; - } - - hEventTimeout = OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME_TIMEOUT); - if (!hEventTimeout) { - CloseHandle(hEventFrozen); - CloseHandle(hEventThaw); - return E_FAIL; - } - - /* Send event to qemu-ga to notify filesystem is frozen */ - SetEvent(hEventFrozen); - - /* Wait until the snapshot is taken by the host. */ - if (WaitForSingleObject(hEventThaw, VSS_TIMEOUT_MSEC) != WAIT_OBJECT_0) { - /* Send event to qemu-ga to notify the provider is timed out */ - SetEvent(hEventTimeout); - hr = E_ABORT; - } - - CloseHandle(hEventThaw); - CloseHandle(hEventFrozen); - CloseHandle(hEventTimeout); - return hr; -} - -STDMETHODIMP CQGAVssProvider::PostCommitSnapshots( - VSS_ID SnapshotSetId, LONG lSnapshotsCount) -{ - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::PreFinalCommitSnapshots(VSS_ID SnapshotSetId) -{ - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::PostFinalCommitSnapshots(VSS_ID SnapshotSetId) -{ - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::AbortSnapshots(VSS_ID SnapshotSetId) -{ - return S_OK; -} - -/* - * IVssProviderNotifications methods - */ - -STDMETHODIMP CQGAVssProvider::OnLoad(IUnknown *pCallback) -{ - return S_OK; -} - -STDMETHODIMP CQGAVssProvider::OnUnload(BOOL bForceUnload) -{ - return S_OK; -} - - -/* - * CQGAVssProviderFactory class - */ - -class CQGAVssProviderFactory : public IClassFactory -{ -public: - STDMETHODIMP QueryInterface(REFIID riid, void **ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - STDMETHODIMP CreateInstance( - IUnknown *pUnknownOuter, REFIID iid, void **ppv); - STDMETHODIMP LockServer(BOOL lock) { return E_NOTIMPL; } - - CQGAVssProviderFactory(); - ~CQGAVssProviderFactory(); - -private: - long m_nRefCount; -}; - -CQGAVssProviderFactory::CQGAVssProviderFactory() -{ - m_nRefCount = 0; - LockModule(TRUE); -} - -CQGAVssProviderFactory::~CQGAVssProviderFactory() -{ - LockModule(FALSE); -} - -STDMETHODIMP CQGAVssProviderFactory::QueryInterface(REFIID riid, void **ppv) -{ - if (riid == IID_IUnknown || riid == IID_IClassFactory) { - *ppv = static_cast<void*>(this); - AddRef(); - return S_OK; - } - *ppv = NULL; - return E_NOINTERFACE; -} - -STDMETHODIMP_(ULONG) CQGAVssProviderFactory::AddRef() -{ - return InterlockedIncrement(&m_nRefCount); -} - -STDMETHODIMP_(ULONG) CQGAVssProviderFactory::Release() -{ - long nRefCount = InterlockedDecrement(&m_nRefCount); - if (m_nRefCount == 0) { - delete this; - } - return nRefCount; -} - -STDMETHODIMP CQGAVssProviderFactory::CreateInstance( - IUnknown *pUnknownOuter, REFIID iid, void **ppv) -{ - CQGAVssProvider *pObj; - - if (pUnknownOuter) { - return CLASS_E_NOAGGREGATION; - } - try { - pObj = new CQGAVssProvider; - } catch (...) { - return E_OUTOFMEMORY; - } - HRESULT hr = pObj->QueryInterface(iid, ppv); - if (FAILED(hr)) { - delete pObj; - } - return hr; -} - - -/* - * DLL functions - */ - -STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) -{ - CQGAVssProviderFactory *factory; - try { - factory = new CQGAVssProviderFactory; - } catch (...) { - return E_OUTOFMEMORY; - } - factory->AddRef(); - HRESULT hr = factory->QueryInterface(riid, ppv); - factory->Release(); - return hr; -} - -STDAPI DllCanUnloadNow() -{ - return g_nComObjsInUse == 0 ? S_OK : S_FALSE; -} - -EXTERN_C -BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved) -{ - if (dwReason == DLL_PROCESS_ATTACH) { - g_hinstDll = hinstDll; - DisableThreadLibraryCalls(hinstDll); - } - return TRUE; -} diff --git a/qemu/qga/vss-win32/qga-vss.def b/qemu/qga/vss-win32/qga-vss.def deleted file mode 100644 index 927782c31..000000000 --- a/qemu/qga/vss-win32/qga-vss.def +++ /dev/null @@ -1,13 +0,0 @@ -LIBRARY "QGA-PROVIDER.DLL" - -EXPORTS - COMRegister PRIVATE - COMUnregister PRIVATE - DllCanUnloadNow PRIVATE - DllGetClassObject PRIVATE - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE - requester_init PRIVATE - requester_deinit PRIVATE - requester_freeze PRIVATE - requester_thaw PRIVATE diff --git a/qemu/qga/vss-win32/qga-vss.idl b/qemu/qga/vss-win32/qga-vss.idl deleted file mode 100644 index 17abca0da..000000000 --- a/qemu/qga/vss-win32/qga-vss.idl +++ /dev/null @@ -1,20 +0,0 @@ -import "oaidl.idl"; -import "ocidl.idl"; - -[ - uuid(103B8142-6CE5-48A7-BDE1-794D3192FCF1), - version(1.0), - helpstring("QGAVSSProvider Type Library") -] -library QGAVSSHWProviderLib -{ - importlib("stdole2.tlb"); - [ - uuid(6E6A3492-8D4D-440C-9619-5E5D0CC31CA8), - helpstring("QGAVSSProvider Class") - ] - coclass QGAVSSHWProvider - { - [default] interface IUnknown; - }; -}; diff --git a/qemu/qga/vss-win32/qga-vss.tlb b/qemu/qga/vss-win32/qga-vss.tlb Binary files differdeleted file mode 100644 index 226452a18..000000000 --- a/qemu/qga/vss-win32/qga-vss.tlb +++ /dev/null diff --git a/qemu/qga/vss-win32/requester.cpp b/qemu/qga/vss-win32/requester.cpp deleted file mode 100644 index 889052ded..000000000 --- a/qemu/qga/vss-win32/requester.cpp +++ /dev/null @@ -1,504 +0,0 @@ -/* - * QEMU Guest Agent win32 VSS Requester implementations - * - * Copyright Hitachi Data Systems Corp. 2013 - * - * Authors: - * Tomoki Sekiyama <tomoki.sekiyama@hds.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#include "qemu/osdep.h" -#include "vss-common.h" -#include "requester.h" -#include "inc/win2003/vswriter.h" -#include "inc/win2003/vsbackup.h" - -/* Max wait time for frozen event (VSS can only hold writes for 10 seconds) */ -#define VSS_TIMEOUT_FREEZE_MSEC 10000 - -/* Call QueryStatus every 10 ms while waiting for frozen event */ -#define VSS_TIMEOUT_EVENT_MSEC 10 - -#define err_set(e, err, fmt, ...) \ - ((e)->error_setg_win32_wrapper((e)->errp, __FILE__, __LINE__, __func__, \ - err, fmt, ## __VA_ARGS__)) -/* Bad idea, works only when (e)->errp != NULL: */ -#define err_is_set(e) ((e)->errp && *(e)->errp) -/* To lift this restriction, error_propagate(), like we do in QEMU code */ - -/* Handle to VSSAPI.DLL */ -static HMODULE hLib; - -/* Functions in VSSAPI.DLL */ -typedef HRESULT(STDAPICALLTYPE * t_CreateVssBackupComponents)( - OUT IVssBackupComponents**); -typedef void(APIENTRY * t_VssFreeSnapshotProperties)(IN VSS_SNAPSHOT_PROP*); -static t_CreateVssBackupComponents pCreateVssBackupComponents; -static t_VssFreeSnapshotProperties pVssFreeSnapshotProperties; - -/* Variables used while applications and filesystes are frozen by VSS */ -static struct QGAVSSContext { - IVssBackupComponents *pVssbc; /* VSS requester interface */ - IVssAsync *pAsyncSnapshot; /* async info of VSS snapshot operation */ - HANDLE hEventFrozen; /* notify fs/writer freeze from provider */ - HANDLE hEventThaw; /* request provider to thaw */ - HANDLE hEventTimeout; /* notify timeout in provider */ - int cFrozenVols; /* number of frozen volumes */ -} vss_ctx; - -STDAPI requester_init(void) -{ - COMInitializer initializer; /* to call CoInitializeSecurity */ - HRESULT hr = CoInitializeSecurity( - NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, - RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL); - if (FAILED(hr)) { - fprintf(stderr, "failed to CoInitializeSecurity (error %lx)\n", hr); - return hr; - } - - hLib = LoadLibraryA("VSSAPI.DLL"); - if (!hLib) { - fprintf(stderr, "failed to load VSSAPI.DLL\n"); - return HRESULT_FROM_WIN32(GetLastError()); - } - - pCreateVssBackupComponents = (t_CreateVssBackupComponents) - GetProcAddress(hLib, -#ifdef _WIN64 /* 64bit environment */ - "?CreateVssBackupComponents@@YAJPEAPEAVIVssBackupComponents@@@Z" -#else /* 32bit environment */ - "?CreateVssBackupComponents@@YGJPAPAVIVssBackupComponents@@@Z" -#endif - ); - if (!pCreateVssBackupComponents) { - fprintf(stderr, "failed to get proc address from VSSAPI.DLL\n"); - return HRESULT_FROM_WIN32(GetLastError()); - } - - pVssFreeSnapshotProperties = (t_VssFreeSnapshotProperties) - GetProcAddress(hLib, "VssFreeSnapshotProperties"); - if (!pVssFreeSnapshotProperties) { - fprintf(stderr, "failed to get proc address from VSSAPI.DLL\n"); - return HRESULT_FROM_WIN32(GetLastError()); - } - - return S_OK; -} - -static void requester_cleanup(void) -{ - if (vss_ctx.hEventFrozen) { - CloseHandle(vss_ctx.hEventFrozen); - vss_ctx.hEventFrozen = NULL; - } - if (vss_ctx.hEventThaw) { - CloseHandle(vss_ctx.hEventThaw); - vss_ctx.hEventThaw = NULL; - } - if (vss_ctx.hEventTimeout) { - CloseHandle(vss_ctx.hEventTimeout); - vss_ctx.hEventTimeout = NULL; - } - if (vss_ctx.pAsyncSnapshot) { - vss_ctx.pAsyncSnapshot->Release(); - vss_ctx.pAsyncSnapshot = NULL; - } - if (vss_ctx.pVssbc) { - vss_ctx.pVssbc->Release(); - vss_ctx.pVssbc = NULL; - } - vss_ctx.cFrozenVols = 0; -} - -STDAPI requester_deinit(void) -{ - requester_cleanup(); - - pCreateVssBackupComponents = NULL; - pVssFreeSnapshotProperties = NULL; - if (hLib) { - FreeLibrary(hLib); - hLib = NULL; - } - - return S_OK; -} - -static HRESULT WaitForAsync(IVssAsync *pAsync) -{ - HRESULT ret, hr; - - do { - hr = pAsync->Wait(); - if (FAILED(hr)) { - ret = hr; - break; - } - hr = pAsync->QueryStatus(&ret, NULL); - if (FAILED(hr)) { - ret = hr; - break; - } - } while (ret == VSS_S_ASYNC_PENDING); - - return ret; -} - -static void AddComponents(ErrorSet *errset) -{ - unsigned int cWriters, i; - VSS_ID id, idInstance, idWriter; - BSTR bstrWriterName = NULL; - VSS_USAGE_TYPE usage; - VSS_SOURCE_TYPE source; - unsigned int cComponents, c1, c2, j; - COMPointer<IVssExamineWriterMetadata> pMetadata; - COMPointer<IVssWMComponent> pComponent; - PVSSCOMPONENTINFO info; - HRESULT hr; - - hr = vss_ctx.pVssbc->GetWriterMetadataCount(&cWriters); - if (FAILED(hr)) { - err_set(errset, hr, "failed to get writer metadata count"); - goto out; - } - - for (i = 0; i < cWriters; i++) { - hr = vss_ctx.pVssbc->GetWriterMetadata(i, &id, pMetadata.replace()); - if (FAILED(hr)) { - err_set(errset, hr, "failed to get writer metadata of %d/%d", - i, cWriters); - goto out; - } - - hr = pMetadata->GetIdentity(&idInstance, &idWriter, - &bstrWriterName, &usage, &source); - if (FAILED(hr)) { - err_set(errset, hr, "failed to get identity of writer %d/%d", - i, cWriters); - goto out; - } - - hr = pMetadata->GetFileCounts(&c1, &c2, &cComponents); - if (FAILED(hr)) { - err_set(errset, hr, "failed to get file counts of %S", - bstrWriterName); - goto out; - } - - for (j = 0; j < cComponents; j++) { - hr = pMetadata->GetComponent(j, pComponent.replace()); - if (FAILED(hr)) { - err_set(errset, hr, - "failed to get component %d/%d of %S", - j, cComponents, bstrWriterName); - goto out; - } - - hr = pComponent->GetComponentInfo(&info); - if (FAILED(hr)) { - err_set(errset, hr, - "failed to get component info %d/%d of %S", - j, cComponents, bstrWriterName); - goto out; - } - - if (info->bSelectable) { - hr = vss_ctx.pVssbc->AddComponent(idInstance, idWriter, - info->type, - info->bstrLogicalPath, - info->bstrComponentName); - if (FAILED(hr)) { - err_set(errset, hr, "failed to add component %S(%S)", - info->bstrComponentName, bstrWriterName); - goto out; - } - } - SysFreeString(bstrWriterName); - bstrWriterName = NULL; - pComponent->FreeComponentInfo(info); - info = NULL; - } - } -out: - if (bstrWriterName) { - SysFreeString(bstrWriterName); - } - if (pComponent && info) { - pComponent->FreeComponentInfo(info); - } -} - -void requester_freeze(int *num_vols, ErrorSet *errset) -{ - COMPointer<IVssAsync> pAsync; - HANDLE volume; - HRESULT hr; - LONG ctx; - GUID guidSnapshotSet = GUID_NULL; - SECURITY_DESCRIPTOR sd; - SECURITY_ATTRIBUTES sa; - WCHAR short_volume_name[64], *display_name = short_volume_name; - DWORD wait_status; - int num_fixed_drives = 0, i; - - if (vss_ctx.pVssbc) { /* already frozen */ - *num_vols = 0; - return; - } - - CoInitialize(NULL); - - /* Allow unrestricted access to events */ - InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); - SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = &sd; - sa.bInheritHandle = FALSE; - - vss_ctx.hEventFrozen = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_FROZEN); - if (!vss_ctx.hEventFrozen) { - err_set(errset, GetLastError(), "failed to create event %s", - EVENT_NAME_FROZEN); - goto out; - } - vss_ctx.hEventThaw = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_THAW); - if (!vss_ctx.hEventThaw) { - err_set(errset, GetLastError(), "failed to create event %s", - EVENT_NAME_THAW); - goto out; - } - vss_ctx.hEventTimeout = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_TIMEOUT); - if (!vss_ctx.hEventTimeout) { - err_set(errset, GetLastError(), "failed to create event %s", - EVENT_NAME_TIMEOUT); - goto out; - } - - assert(pCreateVssBackupComponents != NULL); - hr = pCreateVssBackupComponents(&vss_ctx.pVssbc); - if (FAILED(hr)) { - err_set(errset, hr, "failed to create VSS backup components"); - goto out; - } - - hr = vss_ctx.pVssbc->InitializeForBackup(); - if (FAILED(hr)) { - err_set(errset, hr, "failed to initialize for backup"); - goto out; - } - - hr = vss_ctx.pVssbc->SetBackupState(true, true, VSS_BT_FULL, false); - if (FAILED(hr)) { - err_set(errset, hr, "failed to set backup state"); - goto out; - } - - /* - * Currently writable snapshots are not supported. - * To prevent the final commit (which requires to write to snapshots), - * ATTR_NO_AUTORECOVERY and ATTR_TRANSPORTABLE are specified here. - */ - ctx = VSS_CTX_APP_ROLLBACK | VSS_VOLSNAP_ATTR_TRANSPORTABLE | - VSS_VOLSNAP_ATTR_NO_AUTORECOVERY | VSS_VOLSNAP_ATTR_TXF_RECOVERY; - hr = vss_ctx.pVssbc->SetContext(ctx); - if (hr == (HRESULT)VSS_E_UNSUPPORTED_CONTEXT) { - /* Non-server version of Windows doesn't support ATTR_TRANSPORTABLE */ - ctx &= ~VSS_VOLSNAP_ATTR_TRANSPORTABLE; - hr = vss_ctx.pVssbc->SetContext(ctx); - } - if (FAILED(hr)) { - err_set(errset, hr, "failed to set backup context"); - goto out; - } - - hr = vss_ctx.pVssbc->GatherWriterMetadata(pAsync.replace()); - if (SUCCEEDED(hr)) { - hr = WaitForAsync(pAsync); - } - if (FAILED(hr)) { - err_set(errset, hr, "failed to gather writer metadata"); - goto out; - } - - AddComponents(errset); - if (err_is_set(errset)) { - goto out; - } - - hr = vss_ctx.pVssbc->StartSnapshotSet(&guidSnapshotSet); - if (FAILED(hr)) { - err_set(errset, hr, "failed to start snapshot set"); - goto out; - } - - volume = FindFirstVolumeW(short_volume_name, sizeof(short_volume_name)); - if (volume == INVALID_HANDLE_VALUE) { - err_set(errset, hr, "failed to find first volume"); - goto out; - } - for (;;) { - if (GetDriveTypeW(short_volume_name) == DRIVE_FIXED) { - VSS_ID pid; - hr = vss_ctx.pVssbc->AddToSnapshotSet(short_volume_name, - g_gProviderId, &pid); - if (FAILED(hr)) { - WCHAR volume_path_name[PATH_MAX]; - if (GetVolumePathNamesForVolumeNameW( - short_volume_name, volume_path_name, - sizeof(volume_path_name), NULL) && *volume_path_name) { - display_name = volume_path_name; - } - err_set(errset, hr, "failed to add %S to snapshot set", - display_name); - FindVolumeClose(volume); - goto out; - } - num_fixed_drives++; - } - if (!FindNextVolumeW(volume, short_volume_name, - sizeof(short_volume_name))) { - FindVolumeClose(volume); - break; - } - } - - if (num_fixed_drives == 0) { - goto out; /* If there is no fixed drive, just exit. */ - } - - hr = vss_ctx.pVssbc->PrepareForBackup(pAsync.replace()); - if (SUCCEEDED(hr)) { - hr = WaitForAsync(pAsync); - } - if (FAILED(hr)) { - err_set(errset, hr, "failed to prepare for backup"); - goto out; - } - - hr = vss_ctx.pVssbc->GatherWriterStatus(pAsync.replace()); - if (SUCCEEDED(hr)) { - hr = WaitForAsync(pAsync); - } - if (FAILED(hr)) { - err_set(errset, hr, "failed to gather writer status"); - goto out; - } - - /* - * Start VSS quiescing operations. - * CQGAVssProvider::CommitSnapshots will kick vss_ctx.hEventFrozen - * after the applications and filesystems are frozen. - */ - hr = vss_ctx.pVssbc->DoSnapshotSet(&vss_ctx.pAsyncSnapshot); - if (FAILED(hr)) { - err_set(errset, hr, "failed to do snapshot set"); - goto out; - } - - /* Need to call QueryStatus several times to make VSS provider progress */ - for (i = 0; i < VSS_TIMEOUT_FREEZE_MSEC/VSS_TIMEOUT_EVENT_MSEC; i++) { - HRESULT hr2 = vss_ctx.pAsyncSnapshot->QueryStatus(&hr, NULL); - if (FAILED(hr2)) { - err_set(errset, hr, "failed to do snapshot set"); - goto out; - } - if (hr != VSS_S_ASYNC_PENDING) { - err_set(errset, E_FAIL, - "DoSnapshotSet exited without Frozen event"); - goto out; - } - wait_status = WaitForSingleObject(vss_ctx.hEventFrozen, - VSS_TIMEOUT_EVENT_MSEC); - if (wait_status != WAIT_TIMEOUT) { - break; - } - } - if (wait_status != WAIT_OBJECT_0) { - err_set(errset, E_FAIL, - "couldn't receive Frozen event from VSS provider"); - goto out; - } - - *num_vols = vss_ctx.cFrozenVols = num_fixed_drives; - return; - -out: - if (vss_ctx.pVssbc) { - vss_ctx.pVssbc->AbortBackup(); - } - requester_cleanup(); - CoUninitialize(); -} - - -void requester_thaw(int *num_vols, ErrorSet *errset) -{ - COMPointer<IVssAsync> pAsync; - - if (!vss_ctx.hEventThaw) { - /* - * In this case, DoSnapshotSet is aborted or not started, - * and no volumes must be frozen. We return without an error. - */ - *num_vols = 0; - return; - } - - /* Tell the provider that the snapshot is finished. */ - SetEvent(vss_ctx.hEventThaw); - - assert(vss_ctx.pVssbc); - assert(vss_ctx.pAsyncSnapshot); - - HRESULT hr = WaitForAsync(vss_ctx.pAsyncSnapshot); - switch (hr) { - case VSS_S_ASYNC_FINISHED: - hr = vss_ctx.pVssbc->BackupComplete(pAsync.replace()); - if (SUCCEEDED(hr)) { - hr = WaitForAsync(pAsync); - } - if (FAILED(hr)) { - err_set(errset, hr, "failed to complete backup"); - } - break; - - case (HRESULT)VSS_E_OBJECT_NOT_FOUND: - /* - * On Windows earlier than 2008 SP2 which does not support - * VSS_VOLSNAP_ATTR_NO_AUTORECOVERY context, the final commit is not - * skipped and VSS is aborted by VSS_E_OBJECT_NOT_FOUND. However, as - * the system had been frozen until fsfreeze-thaw command was issued, - * we ignore this error. - */ - vss_ctx.pVssbc->AbortBackup(); - break; - - case VSS_E_UNEXPECTED_PROVIDER_ERROR: - if (WaitForSingleObject(vss_ctx.hEventTimeout, 0) != WAIT_OBJECT_0) { - err_set(errset, hr, "unexpected error in VSS provider"); - break; - } - /* fall through if hEventTimeout is signaled */ - - case (HRESULT)VSS_E_HOLD_WRITES_TIMEOUT: - err_set(errset, hr, "couldn't hold writes: " - "fsfreeze is limited up to 10 seconds"); - break; - - default: - err_set(errset, hr, "failed to do snapshot set"); - } - - if (err_is_set(errset)) { - vss_ctx.pVssbc->AbortBackup(); - } - *num_vols = vss_ctx.cFrozenVols; - requester_cleanup(); - - CoUninitialize(); -} diff --git a/qemu/qga/vss-win32/requester.h b/qemu/qga/vss-win32/requester.h deleted file mode 100644 index 2a39d734a..000000000 --- a/qemu/qga/vss-win32/requester.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * QEMU Guest Agent VSS requester declarations - * - * Copyright Hitachi Data Systems Corp. 2013 - * - * Authors: - * Tomoki Sekiyama <tomoki.sekiyama@hds.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef VSS_WIN32_REQUESTER_H -#define VSS_WIN32_REQUESTER_H - -#include <basetyps.h> /* STDAPI */ - -#ifdef __cplusplus -extern "C" { -#endif - -struct Error; - -/* Callback to set Error; used to avoid linking glib to the DLL */ -typedef void (*ErrorSetFunc)(struct Error **errp, - const char *src, int line, const char *func, - int win32_err, const char *fmt, ...) - GCC_FMT_ATTR(6, 7); -typedef struct ErrorSet { - ErrorSetFunc error_setg_win32_wrapper; - struct Error **errp; /* restriction: must not be null */ -} ErrorSet; - -STDAPI requester_init(void); -STDAPI requester_deinit(void); - -typedef void (*QGAVSSRequesterFunc)(int *, ErrorSet *); -void requester_freeze(int *num_vols, ErrorSet *errset); -void requester_thaw(int *num_vols, ErrorSet *errset); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/qemu/qga/vss-win32/vss-common.h b/qemu/qga/vss-win32/vss-common.h deleted file mode 100644 index 91dae0c38..000000000 --- a/qemu/qga/vss-win32/vss-common.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * QEMU Guest Agent win32 VSS common declarations - * - * Copyright Hitachi Data Systems Corp. 2013 - * - * Authors: - * Tomoki Sekiyama <tomoki.sekiyama@hds.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef VSS_WIN32_H -#define VSS_WIN32_H - -#define __MIDL_user_allocate_free_DEFINED__ -#include <windows.h> -#include <shlwapi.h> - -/* Reduce warnings to include vss.h */ - -/* Ignore annotations for MS IDE */ -#define __in IN -#define __out OUT -#define __RPC_unique_pointer -#define __RPC_string -#define __RPC__deref_inout_opt -#define __RPC__out -#ifndef __RPC__out_ecount_part -#define __RPC__out_ecount_part(x, y) -#endif -#define _declspec(x) -#undef uuid -#define uuid(x) - -/* Undef some duplicated error codes redefined in vss.h */ -#undef VSS_E_BAD_STATE -#undef VSS_E_PROVIDER_NOT_REGISTERED -#undef VSS_E_PROVIDER_VETO -#undef VSS_E_OBJECT_NOT_FOUND -#undef VSS_E_VOLUME_NOT_SUPPORTED -#undef VSS_E_VOLUME_NOT_SUPPORTED_BY_PROVIDER -#undef VSS_E_OBJECT_ALREADY_EXISTS -#undef VSS_E_UNEXPECTED_PROVIDER_ERROR -#undef VSS_E_INVALID_XML_DOCUMENT -#undef VSS_E_MAXIMUM_NUMBER_OF_VOLUMES_REACHED -#undef VSS_E_MAXIMUM_NUMBER_OF_SNAPSHOTS_REACHED - -/* - * VSS headers must be installed from Microsoft VSS SDK 7.2 available at: - * http://www.microsoft.com/en-us/download/details.aspx?id=23490 - */ -#include "inc/win2003/vss.h" - -/* Macros to convert char definitions to wchar */ -#define _L(a) L##a -#define L(a) _L(a) - -/* Constants for QGA VSS Provider */ - -#define QGA_PROVIDER_NAME "QEMU Guest Agent VSS Provider" -#define QGA_PROVIDER_LNAME L(QGA_PROVIDER_NAME) -#define QGA_PROVIDER_VERSION L(QEMU_VERSION) - -#define EVENT_NAME_FROZEN "Global\\QGAVSSEvent-frozen" -#define EVENT_NAME_THAW "Global\\QGAVSSEvent-thaw" -#define EVENT_NAME_TIMEOUT "Global\\QGAVSSEvent-timeout" - -const GUID g_gProviderId = { 0x3629d4ed, 0xee09, 0x4e0e, - {0x9a, 0x5c, 0x6d, 0x8b, 0xa2, 0x87, 0x2a, 0xef} }; -const GUID g_gProviderVersion = { 0x11ef8b15, 0xcac6, 0x40d6, - {0x8d, 0x5c, 0x8f, 0xfc, 0x16, 0x3f, 0x24, 0xca} }; - -const CLSID CLSID_QGAVSSProvider = { 0x6e6a3492, 0x8d4d, 0x440c, - {0x96, 0x19, 0x5e, 0x5d, 0x0c, 0xc3, 0x1c, 0xa8} }; - -const TCHAR g_szClsid[] = TEXT("{6E6A3492-8D4D-440C-9619-5E5D0CC31CA8}"); -const TCHAR g_szProgid[] = TEXT("QGAVSSProvider"); - -/* Enums undefined in VSS SDK 7.2 but defined in newer Windows SDK */ -enum __VSS_VOLUME_SNAPSHOT_ATTRIBUTES { - VSS_VOLSNAP_ATTR_NO_AUTORECOVERY = 0x00000002, - VSS_VOLSNAP_ATTR_TXF_RECOVERY = 0x02000000 -}; - - -/* COM pointer utility; call ->Release() when it goes out of scope */ -template <class T> -class COMPointer { - COMPointer(const COMPointer<T> &p) { } /* no copy */ - T *p; -public: - COMPointer &operator=(T *new_p) - { - /* Assignment of a new T* (or NULL) causes release of previous p */ - if (p && p != new_p) { - p->Release(); - } - p = new_p; - return *this; - } - /* Replace by assignment to the pointer of p */ - T **replace(void) - { - *this = NULL; - return &p; - } - /* Make COMPointer be used like T* */ - operator T*() { return p; } - T *operator->(void) { return p; } - T &operator*(void) { return *p; } - operator bool() { return !!p; } - - COMPointer(T *p = NULL) : p(p) { } - ~COMPointer() { *this = NULL; } /* Automatic release */ -}; - -/* - * COM initializer; this should declared before COMPointer to uninitialize COM - * after releasing COM objects. - */ -class COMInitializer { -public: - COMInitializer() { CoInitialize(NULL); } - ~COMInitializer() { CoUninitialize(); } -}; - -#endif |