From 0b4b49387cce8358783a493004b77c1603b34b5c Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 9 Feb 2016 14:27:16 -0700 Subject: [PATCH 1/9] qga: Support enum names in guest-file-seek Magic constants are a pain to use, especially when we run the risk that our choice of '1' for QGA_SEEK_CUR might differ from the host or guest's choice of SEEK_CUR. Better is to use an enum value, via a qapi alternate type for back-compatibility. With this, {"command":"guest-file-seek", "arguments":{"handle":1, "offset":0, "whence":"cur"}} becomes a synonym for the older {"command":"guest-file-seek", "arguments":{"handle":1, "offset":0, "whence":1}} Signed-off-by: Eric Blake Reviewed-by: Michael Roth Signed-off-by: Michael Roth --- qga/commands-posix.c | 19 ++++++------------- qga/commands-win32.c | 19 ++++++------------- qga/commands.c | 21 +++++++++++++++++++++ qga/guest-agent-core.h | 9 ++------- qga/qapi-schema.json | 33 +++++++++++++++++++++++++++++++-- tests/test-qga.c | 9 ++++----- 6 files changed, 70 insertions(+), 40 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 9589b2d634..9f51faea80 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -550,31 +550,24 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64, } struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset, - int64_t whence_code, Error **errp) + GuestFileWhence *whence_code, + Error **errp) { GuestFileHandle *gfh = guest_file_handle_find(handle, errp); GuestFileSeek *seek_data = NULL; FILE *fh; int ret; int whence; + Error *err = NULL; if (!gfh) { return NULL; } /* We stupidly exposed 'whence':'int' in our qapi */ - switch (whence_code) { - case QGA_SEEK_SET: - whence = SEEK_SET; - break; - case QGA_SEEK_CUR: - whence = SEEK_CUR; - break; - case QGA_SEEK_END: - whence = SEEK_END; - break; - default: - error_setg(errp, "invalid whence code %"PRId64, whence_code); + whence = ga_parse_whence(whence_code, &err); + if (err) { + error_propagate(errp, err); return NULL; } diff --git a/qga/commands-win32.c b/qga/commands-win32.c index cf0757cd0f..2799f5f082 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -385,7 +385,8 @@ done: } GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset, - int64_t whence_code, Error **errp) + GuestFileWhence *whence_code, + Error **errp) { GuestFileHandle *gfh; GuestFileSeek *seek_data; @@ -394,6 +395,7 @@ GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset, off_pos.QuadPart = offset; BOOL res; int whence; + Error *err = NULL; gfh = guest_file_handle_find(handle, errp); if (!gfh) { @@ -401,18 +403,9 @@ GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset, } /* We stupidly exposed 'whence':'int' in our qapi */ - switch (whence_code) { - case QGA_SEEK_SET: - whence = SEEK_SET; - break; - case QGA_SEEK_CUR: - whence = SEEK_CUR; - break; - case QGA_SEEK_END: - whence = SEEK_END; - break; - default: - error_setg(errp, "invalid whence code %"PRId64, whence_code); + whence = ga_parse_whence(whence_code, &err); + if (err) { + error_propagate(errp, err); return NULL; } diff --git a/qga/commands.c b/qga/commands.c index 5b56786ef6..e091ee1af1 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -473,3 +473,24 @@ done: return ge; } + +/* Convert GuestFileWhence (either a raw integer or an enum value) into + * the guest's SEEK_ constants. */ +int ga_parse_whence(GuestFileWhence *whence, Error **errp) +{ + /* Exploit the fact that we picked values to match QGA_SEEK_*. */ + if (whence->type == QTYPE_QSTRING) { + whence->type = QTYPE_QINT; + whence->u.value = whence->u.name; + } + switch (whence->u.value) { + case QGA_SEEK_SET: + return SEEK_SET; + case QGA_SEEK_CUR: + return SEEK_CUR; + case QGA_SEEK_END: + return SEEK_END; + } + error_setg(errp, "invalid whence code %"PRId64, whence->u.value); + return -1; +} diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h index 238dc6b08d..0a49516045 100644 --- a/qga/guest-agent-core.h +++ b/qga/guest-agent-core.h @@ -12,16 +12,10 @@ */ #include "qapi/qmp/dispatch.h" #include "qemu-common.h" +#include "qga-qmp-commands.h" #define QGA_READ_COUNT_DEFAULT 4096 -/* Mapping of whence codes used by guest-file-seek. */ -enum { - QGA_SEEK_SET = 0, - QGA_SEEK_CUR = 1, - QGA_SEEK_END = 2, -}; - typedef struct GAState GAState; typedef struct GACommandState GACommandState; extern GAState *ga_state; @@ -44,6 +38,7 @@ void ga_set_frozen(GAState *s); void ga_unset_frozen(GAState *s); const char *ga_fsfreeze_hook(GAState *s); int64_t ga_get_fd_handle(GAState *s, Error **errp); +int ga_parse_whence(GuestFileWhence *whence, Error **errp); #ifndef _WIN32 void reopen_fd_to_null(int fd); diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index 01c9ee48d8..c21f3084dc 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -313,6 +313,34 @@ { 'struct': 'GuestFileSeek', 'data': { 'position': 'int', 'eof': 'bool' } } +## +# @QGASeek: +# +# Symbolic names for use in @guest-file-seek +# +# @set: Set to the specified offset (same effect as 'whence':0) +# @cur: Add offset to the current location (same effect as 'whence':1) +# @end: Add offset to the end of the file (same effect as 'whence':2) +# +# Since: 2.6 +## +{ 'enum': 'QGASeek', 'data': [ 'set', 'cur', 'end' ] } + +## +# @GuestFileWhence: +# +# Controls the meaning of offset to @guest-file-seek. +# +# @value: Integral value (0 for set, 1 for cur, 2 for end), available +# for historical reasons, and might differ from the host's or +# guest's SEEK_* values (since: 0.15) +# @name: Symbolic name, and preferred interface +# +# Since: 2.6 +## +{ 'alternate': 'GuestFileWhence', + 'data': { 'value': 'int', 'name': 'QGASeek' } } + ## # @guest-file-seek: # @@ -324,14 +352,15 @@ # # @offset: bytes to skip over in the file stream # -# @whence: 0 for SEEK_SET, 1 for SEEK_CUR, or 2 for SEEK_END +# @whence: Symbolic or numeric code for interpreting offset # # Returns: @GuestFileSeek on success. # # Since: 0.15.0 ## { 'command': 'guest-file-seek', - 'data': { 'handle': 'int', 'offset': 'int', 'whence': 'int' }, + 'data': { 'handle': 'int', 'offset': 'int', + 'whence': 'GuestFileWhence' }, 'returns': 'GuestFileSeek' } ## diff --git a/tests/test-qga.c b/tests/test-qga.c index 0973b487d2..72a89dec23 100644 --- a/tests/test-qga.c +++ b/tests/test-qga.c @@ -6,7 +6,6 @@ #include #include "libqtest.h" -#include "qga/guest-agent-core.h" typedef struct { char *test_dir; @@ -450,8 +449,8 @@ static void test_qga_file_ops(gconstpointer fix) /* seek */ cmd = g_strdup_printf("{'execute': 'guest-file-seek'," " 'arguments': { 'handle': %" PRId64 ", " - " 'offset': %d, 'whence': %d } }", - id, 6, QGA_SEEK_SET); + " 'offset': %d, 'whence': '%s' } }", + id, 6, "set"); ret = qmp_fd(fixture->fd, cmd); qmp_assert_no_error(ret); val = qdict_get_qdict(ret, "return"); @@ -543,8 +542,8 @@ static void test_qga_file_write_read(gconstpointer fix) /* seek to 0 */ cmd = g_strdup_printf("{'execute': 'guest-file-seek'," " 'arguments': { 'handle': %" PRId64 ", " - " 'offset': %d, 'whence': %d } }", - id, 0, QGA_SEEK_SET); + " 'offset': %d, 'whence': '%s' } }", + id, 0, "set"); ret = qmp_fd(fixture->fd, cmd); qmp_assert_no_error(ret); val = qdict_get_qdict(ret, "return"); From 01fdadde8070d5355a2b36b80d07f1f412dc0491 Mon Sep 17 00:00:00 2001 From: Leonid Bloch Date: Mon, 11 Jan 2016 11:12:41 +0200 Subject: [PATCH 2/9] qemu-ga: Fixed minor version switch issue With automatically generated GUID, on minor version changes, an error occurred, stating that there is a problem with the installer. Now, a notification is shown, warning the user that another version of this product is already installed, and that configuration or removal of the existing version is possible through Add/Remove Programs on the Control Panel (expected behavior). Signed-off-by: Leonid Bloch Reviewed-by: Michael Roth Signed-off-by: Michael Roth --- qga/installer/qemu-ga.wxs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs index 9473875723..7f9289122f 100644 --- a/qga/installer/qemu-ga.wxs +++ b/qga/installer/qemu-ga.wxs @@ -41,7 +41,7 @@ Date: Mon, 2 Nov 2015 16:49:48 +0200 Subject: [PATCH 3/9] qga: implement the guest-get-vcpus for windows Signed-off-by: Gal Hammer Reviewed-by: Michael Roth * report rather than assert when VCPU count == 0 * fix up subject: s/set-vcpus/get-vcpus/ Signed-off-by: Michael Roth --- qga/commands-win32.c | 68 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 2799f5f082..5ef460f433 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1223,7 +1223,71 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp) GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) { - error_setg(errp, QERR_UNSUPPORTED); + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pslpi, ptr; + DWORD length; + GuestLogicalProcessorList *head, **link; + Error *local_err = NULL; + int64_t current; + + ptr = pslpi = NULL; + length = 0; + current = 0; + head = NULL; + link = &head; + + if ((GetLogicalProcessorInformation(pslpi, &length) == FALSE) && + (GetLastError() == ERROR_INSUFFICIENT_BUFFER) && + (length > sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION))) { + ptr = pslpi = g_malloc0(length); + if (GetLogicalProcessorInformation(pslpi, &length) == FALSE) { + error_setg(&local_err, "Failed to get processor information: %d", + (int)GetLastError()); + } + } else { + error_setg(&local_err, + "Failed to get processor information buffer length: %d", + (int)GetLastError()); + } + + while ((local_err == NULL) && (length > 0)) { + if (pslpi->Relationship == RelationProcessorCore) { + ULONG_PTR cpu_bits = pslpi->ProcessorMask; + + while (cpu_bits > 0) { + if (!!(cpu_bits & 1)) { + GuestLogicalProcessor *vcpu; + GuestLogicalProcessorList *entry; + + vcpu = g_malloc0(sizeof *vcpu); + vcpu->logical_id = current++; + vcpu->online = true; + vcpu->has_can_offline = false; + + entry = g_malloc0(sizeof *entry); + entry->value = vcpu; + + *link = entry; + link = &entry->next; + } + cpu_bits >>= 1; + } + } + length -= sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); + pslpi++; /* next entry */ + } + + g_free(ptr); + + if (local_err == NULL) { + if (head != NULL) { + return head; + } + /* there's no guest with zero VCPUs */ + error_setg(&local_err, "Guest reported zero VCPUs"); + } + + qapi_free_GuestLogicalProcessorList(head); + error_propagate(errp, local_err); return NULL; } @@ -1340,7 +1404,7 @@ GList *ga_command_blacklist_init(GList *blacklist) { const char *list_unsupported[] = { "guest-suspend-hybrid", - "guest-get-vcpus", "guest-set-vcpus", + "guest-set-vcpus", "guest-get-memory-blocks", "guest-set-memory-blocks", "guest-get-memory-block-size", "guest-fsfreeze-freeze-list", From 02506e2d545d2f931442c910ab46be2cb6d9f788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 17 Feb 2016 17:47:51 +0100 Subject: [PATCH 4/9] qga: use more idiomatic qemu-style eol operators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Laszlo Ersek Signed-off-by: Marc-André Lureau Reviewed-by: Laszlo Ersek Reviewed-by: Michael Roth Signed-off-by: Michael Roth --- qga/commands-win32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 5ef460f433..4e3e14741b 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1305,9 +1305,9 @@ get_net_error_message(gint error) wchar_t *msg = NULL; int flags, nchars; - flags = FORMAT_MESSAGE_ALLOCATE_BUFFER - |FORMAT_MESSAGE_IGNORE_INSERTS - |FORMAT_MESSAGE_FROM_SYSTEM; + flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM; if (error >= NERR_BASE && error <= MAX_NERR) { module = LoadLibraryExW(L"netmsg.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); From 6771197dffb214cf9ac5de825bbb24ff5dcc70c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 17 Feb 2016 17:47:52 +0100 Subject: [PATCH 5/9] qga: use size_t for wcslen() return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Laszlo Ersek Signed-off-by: Marc-André Lureau Reviewed-by: Laszlo Ersek Reviewed-by: Michael Roth Signed-off-by: Michael Roth --- qga/commands-win32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 4e3e14741b..1086ac92a8 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1303,7 +1303,8 @@ get_net_error_message(gint error) HMODULE module = NULL; gchar *retval = NULL; wchar_t *msg = NULL; - int flags, nchars; + int flags; + size_t nchars; flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | From 6c6916dac8a146f2e8ee845a2a4e8d459a8689eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 17 Feb 2016 17:47:53 +0100 Subject: [PATCH 6/9] qga: use wide-chars constants for wchar_t comparisons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Laszlo Ersek Signed-off-by: Marc-André Lureau Reviewed-by: Laszlo Ersek Reviewed-by: Michael Roth Signed-off-by: Michael Roth --- qga/commands-win32.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 1086ac92a8..2df1e2d61b 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1323,8 +1323,10 @@ get_net_error_message(gint error) if (msg != NULL) { nchars = wcslen(msg); - if (nchars > 2 && msg[nchars-1] == '\n' && msg[nchars-2] == '\r') { - msg[nchars-2] = '\0'; + if (nchars > 2 && + msg[nchars - 1] == L'\n' && + msg[nchars - 2] == L'\r') { + msg[nchars - 2] = L'\0'; } retval = g_utf16_to_utf8(msg, -1, NULL, NULL, NULL); From 25d943b95703ae45567395db4156b25052ee54c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 17 Feb 2016 17:47:54 +0100 Subject: [PATCH 7/9] qga: fix off-by-one length check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Laszlo Ersek said: "The length check is off by one (in the safe direction); it should be (nchars >= 2). The processing should be active for the wide string L"\r\n" -- resulting in the empty wide string --, I believe." Reported-by: Laszlo Ersek Signed-off-by: Marc-André Lureau Reviewed-by: Laszlo Ersek Reviewed-by: Michael Roth Signed-off-by: Michael Roth --- qga/commands-win32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 2df1e2d61b..043ed684a4 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1323,7 +1323,7 @@ get_net_error_message(gint error) if (msg != NULL) { nchars = wcslen(msg); - if (nchars > 2 && + if (nchars >= 2 && msg[nchars - 1] == L'\n' && msg[nchars - 2] == L'\r') { msg[nchars - 2] = L'\0'; From 8021de10131868a8857e64b91cf0a868b76a61d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 17 Feb 2016 17:47:55 +0100 Subject: [PATCH 8/9] qga: check utf8-to-utf16 conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UTF8 to UTF16 conversion can fail for genuine reasons, let's check errors. Reported-by: Laszlo Ersek Signed-off-by: Marc-André Lureau Reviewed-by: Laszlo Ersek Reviewed-by: Michael Roth Signed-off-by: Michael Roth --- qga/commands-win32.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 043ed684a4..d76327f5a3 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1349,8 +1349,9 @@ void qmp_guest_set_user_password(const char *username, NET_API_STATUS nas; char *rawpasswddata = NULL; size_t rawpasswdlen; - wchar_t *user, *wpass; + wchar_t *user = NULL, *wpass = NULL; USER_INFO_1003 pi1003 = { 0, }; + GError *gerr = NULL; if (crypted) { error_setg(errp, QERR_UNSUPPORTED); @@ -1364,8 +1365,15 @@ void qmp_guest_set_user_password(const char *username, rawpasswddata = g_renew(char, rawpasswddata, rawpasswdlen + 1); rawpasswddata[rawpasswdlen] = '\0'; - user = g_utf8_to_utf16(username, -1, NULL, NULL, NULL); - wpass = g_utf8_to_utf16(rawpasswddata, -1, NULL, NULL, NULL); + user = g_utf8_to_utf16(username, -1, NULL, NULL, &gerr); + if (!user) { + goto done; + } + + wpass = g_utf8_to_utf16(rawpasswddata, -1, NULL, NULL, &gerr); + if (!wpass) { + goto done; + } pi1003.usri1003_password = wpass; nas = NetUserSetInfo(NULL, user, @@ -1378,6 +1386,11 @@ void qmp_guest_set_user_password(const char *username, g_free(msg); } +done: + if (gerr) { + error_setg(errp, QERR_QGA_COMMAND_FAILED, gerr->message); + g_error_free(gerr); + } g_free(user); g_free(wpass); g_free(rawpasswddata); From e55eb806dbb97f53794b0c2f86983d34f6696845 Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Wed, 24 Feb 2016 18:14:52 -0600 Subject: [PATCH 9/9] qga: fix w32 breakage due to missing osdep.h includes requester.h relied on qemu/compiler.h definitions to handle GCC_FMT_ATTR() stub, but this include was removed as part of scripted clean-ups via 30456d5: all: Clean up includes under the assumption that all C files would have included it via qemu/osdep.h at that point. requester.cpp was likely missed due to C++ files requiring manual/special handling as well as VSS build options needing to be enabled to trigger build failures. Fix this by including qemu/osdep.h. That in turn pulls in a macro from qapi/error.h that conflicts with a struct field name in requester.h, so fix that as well by renaming the field. While we're at it, fix up provider.cpp/install.cpp to include osdep.h as well. Cc: Peter Maydell Signed-off-by: Michael Roth Reviewed-by: Eric Blake --- qga/vss-win32.c | 2 +- qga/vss-win32/install.cpp | 3 +-- qga/vss-win32/provider.cpp | 2 +- qga/vss-win32/requester.cpp | 8 ++++---- qga/vss-win32/requester.h | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/qga/vss-win32.c b/qga/vss-win32.c index 5182e3be91..9a0e46356a 100644 --- a/qga/vss-win32.c +++ b/qga/vss-win32.c @@ -150,7 +150,7 @@ void qga_vss_fsfreeze(int *nr_volume, Error **errp, bool freeze) const char *func_name = freeze ? "requester_freeze" : "requester_thaw"; QGAVSSRequesterFunc func; ErrorSet errset = { - .error_setg_win32 = error_setg_win32_internal, + .error_setg_win32_wrapper = error_setg_win32_internal, .errp = errp, }; diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp index b0e4426c72..cd9cdb4a24 100644 --- a/qga/vss-win32/install.cpp +++ b/qga/vss-win32/install.cpp @@ -10,8 +10,7 @@ * See the COPYING file in the top-level directory. */ -#include -#include +#include "qemu/osdep.h" #include "vss-common.h" #include "inc/win2003/vscoordint.h" diff --git a/qga/vss-win32/provider.cpp b/qga/vss-win32/provider.cpp index d5129f8f65..d977393e33 100644 --- a/qga/vss-win32/provider.cpp +++ b/qga/vss-win32/provider.cpp @@ -10,7 +10,7 @@ * See the COPYING file in the top-level directory. */ -#include +#include "qemu/osdep.h" #include "vss-common.h" #include "inc/win2003/vscoordint.h" #include "inc/win2003/vsprov.h" diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp index 9b3e310971..b57d5170e8 100644 --- a/qga/vss-win32/requester.cpp +++ b/qga/vss-win32/requester.cpp @@ -10,7 +10,7 @@ * See the COPYING file in the top-level directory. */ -#include +#include "qemu/osdep.h" #include "vss-common.h" #include "requester.h" #include "assert.h" @@ -23,9 +23,9 @@ /* 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((e)->errp, __FILE__, __LINE__, __func__, \ - err, fmt, ## __VA_ARGS__)) +#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 */ diff --git a/qga/vss-win32/requester.h b/qga/vss-win32/requester.h index ad2bf3df61..2a39d734a2 100644 --- a/qga/vss-win32/requester.h +++ b/qga/vss-win32/requester.h @@ -27,7 +27,7 @@ typedef void (*ErrorSetFunc)(struct Error **errp, int win32_err, const char *fmt, ...) GCC_FMT_ATTR(6, 7); typedef struct ErrorSet { - ErrorSetFunc error_setg_win32; + ErrorSetFunc error_setg_win32_wrapper; struct Error **errp; /* restriction: must not be null */ } ErrorSet;