The err_set macro expands its 'err' parameter three times. When
callers pass GetLastError(), the Win32 error code is fetched on
each expansion and may change between evaluations, since the
intervening function calls can reset the thread's last-error value.

Capture the argument in a local DWORD once and reference that
throughout the macro body.

Signed-off-by: Marc-André Lureau <[email protected]>
---
 qga/vss-win32/requester.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp
index d7907c230656..e3a15f83bf90 100644
--- a/qga/vss-win32/requester.cpp
+++ b/qga/vss-win32/requester.cpp
@@ -27,10 +27,11 @@
 #define DEFAULT_VSS_BACKUP_TYPE VSS_BT_FULL
 
 #define err_set(e, err, fmt, ...) {                                         \
+    DWORD _e = (DWORD)(err);                                                \
     (e)->error_setg_win32_wrapper((e)->errp, __FILE__, __LINE__, __func__,  \
-                                   err, fmt ": Windows error 0x%lx",        \
-                                   ## __VA_ARGS__, err);                    \
-    qga_debug(fmt ": Windows error 0x%lx", ## __VA_ARGS__, err);            \
+                                   _e, fmt ": Windows error 0x%lx",         \
+                                   ## __VA_ARGS__, _e);                     \
+    qga_debug(fmt ": Windows error 0x%lx", ## __VA_ARGS__, _e);             \
 }
 /* Bad idea, works only when (e)->errp != NULL: */
 #define err_is_set(e) ((e)->errp && *(e)->errp)

-- 
2.55.0.543.g5ebe2ebe4ea8


Reply via email to