aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/qemu/osdep.h10
-rw-r--r--qga/commands.c17
-rw-r--r--qga/main.c6
-rw-r--r--qga/vss-win32/install.cpp33
-rw-r--r--util/oslib-posix.c35
-rw-r--r--util/oslib-win32.c13
6 files changed, 96 insertions, 18 deletions
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 979a403984..4841b5c6b5 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -655,4 +655,14 @@ static inline void qemu_reset_optind(void)
#endif
}
+/**
+ * qemu_get_host_name:
+ * @errp: Error object
+ *
+ * Operating system agnostic way of querying host name.
+ *
+ * Returns allocated hostname (caller should free), NULL on failure.
+ */
+char *qemu_get_host_name(Error **errp);
+
#endif
diff --git a/qga/commands.c b/qga/commands.c
index efc8b90281..d3fec807c1 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -515,11 +515,20 @@ int ga_parse_whence(GuestFileWhence *whence, Error **errp)
GuestHostName *qmp_guest_get_host_name(Error **errp)
{
GuestHostName *result = NULL;
- gchar const *hostname = g_get_host_name();
- if (hostname != NULL) {
- result = g_new0(GuestHostName, 1);
- result->host_name = g_strdup(hostname);
+ g_autofree char *hostname = qemu_get_host_name(errp);
+
+ /*
+ * We want to avoid using g_get_host_name() because that
+ * caches the result and we wouldn't reflect changes in the
+ * host name.
+ */
+
+ if (!hostname) {
+ hostname = g_strdup("localhost");
}
+
+ result = g_new0(GuestHostName, 1);
+ result->host_name = g_steal_pointer(&hostname);
return result;
}
diff --git a/qga/main.c b/qga/main.c
index f0e454f28d..3febf3b0fd 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -531,7 +531,11 @@ static int send_response(GAState *s, const QDict *rsp)
QString *payload_qstr, *response_qstr;
GIOStatus status;
- g_assert(rsp && s->channel);
+ g_assert(s->channel);
+
+ if (!rsp) {
+ return 0;
+ }
payload_qstr = qobject_to_json(QOBJECT(rsp));
if (!payload_qstr) {
diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp
index a456841360..40de133774 100644
--- a/qga/vss-win32/install.cpp
+++ b/qga/vss-win32/install.cpp
@@ -19,6 +19,7 @@
#include <comdef.h>
#include <comutil.h>
#include <sddl.h>
+#include <winsvc.h>
#define BUFFER_SIZE 1024
@@ -509,26 +510,32 @@ namespace _com_util
}
}
-/* Stop QGA VSS provider service from COM+ Application Admin Catalog */
-
+/* Stop QGA VSS provider service using Winsvc API */
STDAPI StopService(void)
{
HRESULT hr;
- COMInitializer initializer;
- COMPointer<IUnknown> pUnknown;
- COMPointer<ICOMAdminCatalog2> pCatalog;
+ SC_HANDLE manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ SC_HANDLE service = NULL;
- int count = 0;
+ if (!manager) {
+ errmsg(E_FAIL, "Failed to open service manager");
+ hr = E_FAIL;
+ goto out;
+ }
+ service = OpenService(manager, QGA_PROVIDER_NAME, SC_MANAGER_ALL_ACCESS);
- chk(QGAProviderFind(QGAProviderCount, (void *)&count));
- if (count) {
- chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL, CLSCTX_INPROC_SERVER,
- IID_IUnknown, (void **)pUnknown.replace()));
- chk(pUnknown->QueryInterface(IID_ICOMAdminCatalog2,
- (void **)pCatalog.replace()));
- chk(pCatalog->ShutdownApplication(_bstr_t(QGA_PROVIDER_LNAME)));
+ if (!service) {
+ errmsg(E_FAIL, "Failed to open service");
+ hr = E_FAIL;
+ goto out;
+ }
+ if (!(ControlService(service, SERVICE_CONTROL_STOP, NULL))) {
+ errmsg(E_FAIL, "Failed to stop service");
+ hr = E_FAIL;
}
out:
+ CloseServiceHandle(service);
+ CloseServiceHandle(manager);
return hr;
}
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 72907d4d7f..e60aea85b6 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -794,3 +794,38 @@ void sigaction_invoke(struct sigaction *action,
}
action->sa_sigaction(info->ssi_signo, &si, NULL);
}
+
+#ifndef HOST_NAME_MAX
+# ifdef _POSIX_HOST_NAME_MAX
+# define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
+# else
+# define HOST_NAME_MAX 255
+# endif
+#endif
+
+char *qemu_get_host_name(Error **errp)
+{
+ long len = -1;
+ g_autofree char *hostname = NULL;
+
+#ifdef _SC_HOST_NAME_MAX
+ len = sysconf(_SC_HOST_NAME_MAX);
+#endif /* _SC_HOST_NAME_MAX */
+
+ if (len < 0) {
+ len = HOST_NAME_MAX;
+ }
+
+ /* Unfortunately, gethostname() below does not guarantee a
+ * NULL terminated string. Therefore, allocate one byte more
+ * to be sure. */
+ hostname = g_new0(char, len + 1);
+
+ if (gethostname(hostname, len) < 0) {
+ error_setg_errno(errp, errno,
+ "cannot get hostname");
+ return NULL;
+ }
+
+ return g_steal_pointer(&hostname);
+}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index e9b14ab178..3b49d27297 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -808,3 +808,16 @@ bool qemu_write_pidfile(const char *filename, Error **errp)
}
return true;
}
+
+char *qemu_get_host_name(Error **errp)
+{
+ wchar_t tmp[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD size = G_N_ELEMENTS(tmp);
+
+ if (GetComputerNameW(tmp, &size) == 0) {
+ error_setg_win32(errp, GetLastError(), "failed close handle");
+ return NULL;
+ }
+
+ return g_utf16_to_utf8(tmp, size, NULL, NULL, NULL);
+}