diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs
index 51340f7ecc..df572adb4a 100644
--- a/qga/installer/qemu-ga.wxs
+++ b/qga/installer/qemu-ga.wxs
@@ -31,6 +31,7 @@
/>
1
+
@@ -121,27 +122,31 @@
+
+
+
-
+
diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp
index b57508fbe0..68662a6dfc 100644
--- a/qga/vss-win32/install.cpp
+++ b/qga/vss-win32/install.cpp
@@ -357,6 +357,15 @@ out:
return hr;
}
+STDAPI_(void) CALLBACK DLLCOMRegister(HWND, HINSTANCE, LPSTR, int)
+{
+ COMRegister();
+}
+
+STDAPI_(void) CALLBACK DLLCOMUnregister(HWND, HINSTANCE, LPSTR, int)
+{
+ COMUnregister();
+}
static BOOL CreateRegistryKey(LPCTSTR key, LPCTSTR value, LPCTSTR data)
{
diff --git a/qga/vss-win32/qga-vss.def b/qga/vss-win32/qga-vss.def
index 927782c31b..ee97a81427 100644
--- a/qga/vss-win32/qga-vss.def
+++ b/qga/vss-win32/qga-vss.def
@@ -1,6 +1,8 @@
LIBRARY "QGA-PROVIDER.DLL"
EXPORTS
+ DLLCOMRegister
+ DLLCOMUnregister
COMRegister PRIVATE
COMUnregister PRIVATE
DllCanUnloadNow PRIVATE
diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp
index b371affeab..3e998af4a8 100644
--- a/qga/vss-win32/requester.cpp
+++ b/qga/vss-win32/requester.cpp
@@ -23,6 +23,8 @@
/* Call QueryStatus every 10 ms while waiting for frozen event */
#define VSS_TIMEOUT_EVENT_MSEC 10
+#define DEFAULT_VSS_BACKUP_TYPE VSS_BT_FULL
+
#define err_set(e, err, fmt, ...) \
((e)->error_setg_win32_wrapper((e)->errp, __FILE__, __LINE__, __func__, \
err, fmt, ## __VA_ARGS__))
@@ -234,6 +236,42 @@ out:
}
}
+DWORD get_reg_dword_value(HKEY baseKey, LPCSTR subKey, LPCSTR valueName,
+ DWORD defaultData)
+{
+ DWORD regGetValueError;
+ DWORD dwordData;
+ DWORD dataSize = sizeof(DWORD);
+
+ regGetValueError = RegGetValue(baseKey, subKey, valueName, RRF_RT_DWORD,
+ NULL, &dwordData, &dataSize);
+ if (regGetValueError != ERROR_SUCCESS) {
+ return defaultData;
+ }
+ return dwordData;
+}
+
+bool is_valid_vss_backup_type(VSS_BACKUP_TYPE vssBT)
+{
+ return (vssBT > VSS_BT_UNDEFINED && vssBT < VSS_BT_OTHER);
+}
+
+VSS_BACKUP_TYPE get_vss_backup_type(
+ VSS_BACKUP_TYPE defaultVssBT = DEFAULT_VSS_BACKUP_TYPE)
+{
+ VSS_BACKUP_TYPE vssBackupType;
+
+ vssBackupType = static_cast(
+ get_reg_dword_value(HKEY_LOCAL_MACHINE,
+ QGA_PROVIDER_REGISTRY_ADDRESS,
+ "VssOption",
+ defaultVssBT));
+ if (!is_valid_vss_backup_type(vssBackupType)) {
+ return defaultVssBT;
+ }
+ return vssBackupType;
+}
+
void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset)
{
COMPointer pAsync;
@@ -247,6 +285,7 @@ void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset)
DWORD wait_status;
int num_fixed_drives = 0, i;
int num_mount_points = 0;
+ VSS_BACKUP_TYPE vss_bt = get_vss_backup_type();
if (vss_ctx.pVssbc) { /* already frozen */
*num_vols = 0;
@@ -294,7 +333,7 @@ void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset)
goto out;
}
- hr = vss_ctx.pVssbc->SetBackupState(true, true, VSS_BT_FULL, false);
+ hr = vss_ctx.pVssbc->SetBackupState(true, true, vss_bt, false);
if (FAILED(hr)) {
err_set(errset, hr, "failed to set backup state");
goto out;
diff --git a/qga/vss-win32/vss-handles.h b/qga/vss-win32/vss-handles.h
index 0f8a741ad2..1a7d842129 100644
--- a/qga/vss-win32/vss-handles.h
+++ b/qga/vss-win32/vss-handles.h
@@ -6,6 +6,9 @@
#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 QGA_PROVIDER_REGISTRY_ADDRESS "SYSTEM\\CurrentControlSet"\
+ "\\Services"\
+ "\\" QGA_PROVIDER_NAME
#define EVENT_NAME_FROZEN "Global\\QGAVSSEvent-frozen"
#define EVENT_NAME_THAW "Global\\QGAVSSEvent-thaw"