From 0b4b49387cce8358783a493004b77c1603b34b5c Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 9 Feb 2016 14:27:16 -0700 Subject: 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-win32.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'qga/commands-win32.c') 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; } -- cgit 1.4.1 From a7a173624e66785c6364e9f2f3ae0e7bea44bcb4 Mon Sep 17 00:00:00 2001 From: Gal Hammer Date: Mon, 2 Nov 2015 16:49:48 +0200 Subject: 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(-) (limited to 'qga/commands-win32.c') 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", -- cgit 1.4.1 From 02506e2d545d2f931442c910ab46be2cb6d9f788 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 17 Feb 2016 17:47:51 +0100 Subject: 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(-) (limited to 'qga/commands-win32.c') 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); -- cgit 1.4.1 From 6771197dffb214cf9ac5de825bbb24ff5dcc70c2 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 17 Feb 2016 17:47:52 +0100 Subject: 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(-) (limited to 'qga/commands-win32.c') 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 | -- cgit 1.4.1 From 6c6916dac8a146f2e8ee845a2a4e8d459a8689eb Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 17 Feb 2016 17:47:53 +0100 Subject: 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(-) (limited to 'qga/commands-win32.c') 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); -- cgit 1.4.1 From 25d943b95703ae45567395db4156b25052ee54c4 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 17 Feb 2016 17:47:54 +0100 Subject: 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(-) (limited to 'qga/commands-win32.c') 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'; -- cgit 1.4.1 From 8021de10131868a8857e64b91cf0a868b76a61d8 Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Wed, 17 Feb 2016 17:47:55 +0100 Subject: 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(-) (limited to 'qga/commands-win32.c') 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); -- cgit 1.4.1