VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/hostversion.cpp@ 54647

Last change on this file since 54647 was 54008, checked in by vboxsync, 10 years ago

Additions/x11/VBoxClient: initialise the guest library from the services, as preparation for running the display service without using the VMM device.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/** @file
2 * X11 guest client - host version check.
3 */
4
5/*
6 * Copyright (C) 2011-2012 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16#include <stdio.h>
17#include <iprt/assert.h>
18#include <iprt/err.h>
19#include <iprt/mem.h>
20#include <iprt/ldr.h>
21#include <iprt/string.h>
22#include <iprt/thread.h>
23
24#ifdef VBOX_WITH_DBUS
25# include <VBox/dbus.h>
26#endif
27#include <VBox/log.h>
28#include <VBox/VBoxGuestLib.h>
29#ifdef VBOX_OSE
30# include <VBox/version.h>
31#endif
32
33#include "VBoxClient.h"
34
35static const char *getPidFilePath()
36{
37 return ".vboxclient-hostversion.pid";
38}
39
40static int showNotify(const char *pcHeader, const char *pcBody)
41{
42 int rc;
43# ifdef VBOX_WITH_DBUS
44 DBusConnection *conn;
45 DBusMessage* msg = NULL;
46 conn = dbus_bus_get (DBUS_BUS_SESSON, NULL);
47 if (conn == NULL)
48 {
49 LogRelFlowFunc(("Could not retrieve D-BUS session bus!\n"));
50 rc = VERR_INVALID_HANDLE;
51 }
52 else
53 {
54 msg = dbus_message_new_method_call("org.freedesktop.Notifications",
55 "/org/freedesktop/Notifications",
56 "org.freedesktop.Notifications",
57 "Notify");
58 if (msg == NULL)
59 {
60 LogRel(("Could not create D-BUS message!\n"));
61 rc = VERR_INVALID_HANDLE;
62 }
63 else
64 rc = VINF_SUCCESS;
65 }
66 if (RT_SUCCESS(rc))
67 {
68 uint32_t msg_replace_id = 0;
69 const char *msg_app = "VBoxClient";
70 const char *msg_icon = "";
71 const char *msg_summary = pcHeader;
72 const char *msg_body = pcBody;
73 int32_t msg_timeout = -1; /* Let the notification server decide */
74
75 DBusMessageIter iter;
76 DBusMessageIter array;
77 DBusMessageIter dict;
78 DBusMessageIter value;
79 DBusMessageIter variant;
80 DBusMessageIter data;
81
82 /* Format: UINT32 org.freedesktop.Notifications.Notify
83 * (STRING app_name, UINT32 replaces_id, STRING app_icon, STRING summary, STRING body,
84 * ARRAY actions, DICT hints, INT32 expire_timeout)
85 */
86 dbus_message_iter_init_append(msg,&iter);
87 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_app);
88 dbus_message_iter_append_basic(&iter,DBUS_TYPE_UINT32,&msg_replace_id);
89 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_icon);
90 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_summary);
91 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_body);
92 dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array);
93 dbus_message_iter_close_container(&iter,&array);
94 dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,"{sv}",&array);
95 dbus_message_iter_close_container(&iter,&array);
96 dbus_message_iter_append_basic(&iter,DBUS_TYPE_INT32,&msg_timeout);
97
98 DBusError err;
99 dbus_error_init(&err);
100
101 DBusMessage *reply;
102 reply = dbus_connection_send_with_reply_and_block(conn, msg,
103 30 * 1000 /* 30 seconds timeout */, &err);
104 if (dbus_error_is_set(&err))
105 {
106 LogRel(("D-BUS returned an error while sending the notification: %s", err.message));
107 }
108 else if (reply)
109 {
110 dbus_connection_flush(conn);
111 dbus_message_unref(reply);
112 }
113 if (dbus_error_is_set(&err))
114 dbus_error_free(&err);
115 }
116 if (msg != NULL)
117 dbus_message_unref(msg);
118# else
119 /* TODO: Implement me */
120 rc = VINF_SUCCESS;
121# endif /* VBOX_WITH_DBUS */
122 return rc;
123}
124
125/** @todo Move this part in VbglR3 and just provide a callback for the platform-specific
126 notification stuff, since this is very similar to the VBoxTray code. */
127static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised)
128{
129 int rc;
130 LogFlowFunc(("\n"));
131
132 NOREF(ppInterface);
133 /* Initialise the guest library. */
134 rc = VbglR3InitUser();
135 if (RT_FAILURE(rc))
136 VBClFatalError(("Failed to connect to the VirtualBox kernel service, rc=%Rrc\n", rc));
137 /* Because we need desktop notifications to be displayed, wait
138 * some time to make the desktop environment load (as a work around). */
139 if (fDaemonised)
140 RTThreadSleep(30 * 1000 /* Wait 30 seconds */);
141
142# ifdef VBOX_WITH_DBUS
143 rc = RTDBusLoadLib();
144 if (RT_FAILURE(rc))
145 LogRel(("VBoxClient: D-Bus seems not to be installed; no host version check/notification done.\n"));
146# else
147 rc = VERR_NOT_IMPLEMENTED;
148# endif /* VBOX_WITH_DBUS */
149
150# ifdef VBOX_WITH_GUEST_PROPS
151 uint32_t uGuestPropSvcClientID;
152 if (RT_SUCCESS(rc))
153 {
154 rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
155 if (RT_FAILURE(rc))
156 LogRel(("VBoxClient: Cannot connect to guest property service while chcking for host version! rc = %Rrc\n", rc));
157 }
158
159 if (RT_SUCCESS(rc))
160 {
161 char *pszHostVersion;
162 char *pszGuestVersion;
163 bool bUpdate;
164
165 rc = VbglR3HostVersionCheckForUpdate(uGuestPropSvcClientID, &bUpdate, &pszHostVersion, &pszGuestVersion);
166 if (RT_SUCCESS(rc))
167 {
168 if (bUpdate)
169 {
170 char szMsg[1024];
171 char szTitle[64];
172
173 /** @todo add some translation macros here */
174 RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions update available!");
175#ifndef VBOX_OSE
176 RTStrPrintf(szMsg, sizeof(szMsg), "Your guest is currently running the Guest Additions version %s. "
177 "We recommend updating to the latest version (%s) by choosing the "
178 "install option from the Devices menu.", pszGuestVersion, pszHostVersion);
179#else
180/* This is the message which appears for non-Oracle builds of the
181* Guest Additions. Distributors are encouraged to customise this. */
182 RTStrPrintf(szMsg, sizeof(szMsg), "Your virtual machine is currently running the Guest Additions version %s. Since you are running a version of the Guest Additions provided by the operating system you installed in the virtual machine we recommend that you update it to at least version %s using that system's update features, or alternatively that you remove this version and then install the " VBOX_VENDOR_SHORT " Guest Additions package using the install option from the Devices menu. Please consult the documentation for the operating system you are running to find out how to update or remove the current Guest Additions package.", pszGuestVersion, pszHostVersion);
183#endif
184 rc = showNotify(szTitle, szMsg);
185 LogRel(("VBoxClient: VirtualBox Guest Additions update available!"));
186 if (RT_FAILURE(rc))
187 LogRel(("VBoxClient: Could not show version notifier tooltip! rc = %d\n", rc));
188 }
189
190 /* Store host version to not notify again */
191 rc = VbglR3HostVersionLastCheckedStore(uGuestPropSvcClientID, pszHostVersion);
192
193 VbglR3GuestPropReadValueFree(pszHostVersion);
194 VbglR3GuestPropReadValueFree(pszGuestVersion);
195 }
196 VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
197 }
198# endif /* VBOX_WITH_GUEST_PROPS */
199 VbglR3Term();
200 LogFlowFunc(("returning %Rrc\n", rc));
201 return rc;
202}
203
204struct VBCLSERVICE vbclHostVersionInterface =
205{
206 getPidFilePath,
207 VBClServiceDefaultHandler, /* init */
208 run,
209 VBClServiceDefaultHandler, /* pause */
210 VBClServiceDefaultHandler, /* resume */
211 VBClServiceDefaultCleanup
212};
213
214struct HOSTVERSIONSERVICE
215{
216 struct VBCLSERVICE *pInterface;
217};
218
219/* Static factory */
220struct VBCLSERVICE **VBClGetHostVersionService()
221{
222 struct HOSTVERSIONSERVICE *pService =
223 (struct HOSTVERSIONSERVICE *)RTMemAlloc(sizeof(*pService));
224
225 if (!pService)
226 VBClFatalError(("Out of memory\n"));
227 pService->pInterface = &vbclHostVersionInterface;
228 return &pService->pInterface;
229}
230
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette