VBoxServiceVMInfo.cpp revision 9df808060e0e4b6da01006c2800a3d47cec2cc18
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * VBoxService - Virtual Machine Information for the Host.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Copyright (C) 2009-2010 Oracle Corporation
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * available from http://www.virtualbox.org. This file is free software;
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * you can redistribute it and/or modify it under the terms of the GNU
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * General Public License (GPL) as published by the Free Software
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/*******************************************************************************
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync* Header Files *
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync*******************************************************************************/
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync# ifdef TARGET_NT4 /* HACK ALERT! PMIB_IPSTATS undefined if 0x0400 with newer SDKs. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync# if !defined(RT_OS_OS2) && !defined(RT_OS_FREEBSD) && !defined(RT_OS_HAIKU)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync# include <utmpx.h> /* @todo FreeBSD 9 should have this. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/*******************************************************************************
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync* Global Variables *
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync*******************************************************************************/
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** The vminfo interval (milliseconds). */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** The semaphore we're blocking on. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsyncstatic RTSEMEVENTMULTI g_hVMInfoEvent = NIL_RTSEMEVENTMULTI;
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** The guest property service client ID. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** Number of logged in users in OS. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsyncstatic uint32_t g_cVMInfoLoggedInUsers = UINT32_MAX;
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** The guest property cache. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** The VM session ID. Changes whenever the VM is restored or reset. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/*******************************************************************************
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync*******************************************************************************/
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** ConsoleKit defines (taken from 0.4.5). */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync#define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync#define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Signals the event so that a re-enumeration of VM-specific
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * information (like logged in users) can happen.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * @return IPRT status code.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Trigger a re-enumeration of all logged-in users by unblocking
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * the multi event semaphore of the VMInfo thread. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** @copydoc VBOXSERVICE::pfnPreInit */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoPreInit(void)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** @copydoc VBOXSERVICE::pfnOption */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoOption(const char **ppszShort, int argc, char **argv, int *pi)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* no short options */;
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync/** @copydoc VBOXSERVICE::pfnInit */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoInit(void)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * If not specified, find the right interval default.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Then create the event sem to block on.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* The status code is ignored as this information is not available with VBox < 3.2.10. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = VbglR3GuestPropConnect(&g_uVMInfoGuestPropSvcClientID);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceVerbose(3, "VMInfo: Property Service Client ID: %#x\n", g_uVMInfoGuestPropSvcClientID);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* If the service was not found, we disable this service without
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync causing VBoxService to fail. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceVerbose(0, "VMInfo: Guest property service is not available, disabling the service\n");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceError("VMInfo: Failed to connect to the guest property service! Error: %Rrc\n", rc);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServicePropCacheCreate(&g_VMInfoPropCache, g_uVMInfoGuestPropSvcClientID);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Declare some guest properties with flags and reset values.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_TRANSIENT, NULL /* Delete on exit */);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_TRANSIENT, "0");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_TRANSIENT, "true");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE, NULL /* Delete on exit */);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Writes the properties that won't change while the service is running.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Errors are ignored.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsyncstatic void vboxserviceVMInfoWriteFixedProperties(void)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * First get OS information that won't change.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync int rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szInfo, sizeof(szInfo));
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Product",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szInfo, sizeof(szInfo));
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Release",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szInfo, sizeof(szInfo));
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Version",
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szInfo, sizeof(szInfo));
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/ServicePack",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Retrieve version information about Guest Additions and installed files (components).
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = VbglR3GetAdditionsVersion(&pszAddVer, &pszAddVerExt, &pszAddRev);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Version",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/VersionExt",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Revision",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Do windows specific properties.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = VbglR3GetAdditionsInstallationPath(&pszInstDir);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/InstallDir",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceWinGetComponentVersions(g_uVMInfoGuestPropSvcClientID);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync#if defined(VBOX_WITH_DBUS) && defined(RT_OS_LINUX) /* Not yet for Solaris/FreeBSB. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Simple wrapper to work around compiler-specific va_list madness.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsyncstatic dbus_bool_t vboxService_dbus_message_get_args(DBusMessage *message,
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync dbus_bool_t ret = dbus_message_get_args_valist(message, error,
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Provide information about active users.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = VBoxServiceVMInfoWinWriteUsers(&pszUserList, &cUsersInList);
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync /** @todo FreeBSD: Port logged on user info retrieval.
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync * However, FreeBSD 9 supports utmpx, so we could use the code
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync * block below (?). */
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync /** @todo Haiku: Port logged on user info retrieval. */
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrieval. */
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync /* Allocate a first array to hold 32 users max. */
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync char **papszUsers = (char **)RTMemAllocZ(cListSize * sizeof(char *));
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Process all entries in the utmp file.
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Note: This only handles */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceVerbose(4, "Found entry \"%s\" (type: %d, PID: %RU32, session: %RU32)\n",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync ut_user->ut_user, ut_user->ut_type, ut_user->ut_pid, ut_user->ut_session);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync void *pvNew = RTMemRealloc(papszUsers, cListSize * sizeof(char*));
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync /* Make sure we don't add user names which are not
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync * part of type USER_PROCES. */
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync if (ut_user->ut_type == USER_PROCESS) /* Regular user process. */
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync bool fFound = false;
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync for (uint32_t i = 0; i < cUsersInList && !fFound; i++)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync fFound = strcmp(papszUsers[i], ut_user->ut_user) == 0;
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync VBoxServiceVerbose(4, "Adding user \"%s\" (type: %d) to list\n",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = RTStrDupEx(&papszUsers[cUsersInList], (const char *)ut_user->ut_user);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync# if defined(RT_OS_LINUX) /* Not yet for Solaris/FreeBSB. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Handle desktop sessions using ConsoleKit. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceVerbose(4, "Checking ConsoleKit sessions ...\n");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync pConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &dbErr);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Get all available sessions. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync DBusMessage *pMsgSessions = dbus_message_new_method_call("org.freedesktop.ConsoleKit",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync "org.freedesktop.ConsoleKit.Manager",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync "GetSessions");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync && (dbus_message_get_type(pMsgSessions) == DBUS_MESSAGE_TYPE_METHOD_CALL))
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync DBusMessage *pReplySessions = dbus_connection_send_with_reply_and_block(pConnection,
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync if ( (dbus_message_get_type(pMsgSessions) == DBUS_MESSAGE_TYPE_METHOD_CALL)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync && vboxService_dbus_message_get_args(pReplySessions, &dbErr, DBUS_TYPE_ARRAY,
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceVerbose(4, "ConsoleKit: retrieved %RU16 session(s)\n", cSessions);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync ppszCurSession && *ppszCurSession; ppszCurSession++)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceVerbose(4, "ConsoleKit: processing session '%s' ...\n", *ppszCurSession);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Only respect active sessions .*/
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync bool fActive = false;
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync DBusMessage *pMsgSessionActive = dbus_message_new_method_call("org.freedesktop.ConsoleKit",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync "org.freedesktop.ConsoleKit.Session",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync "IsActive");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync && dbus_message_get_type(pMsgSessionActive) == DBUS_MESSAGE_TYPE_METHOD_CALL)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync DBusMessage *pReplySessionActive = dbus_connection_send_with_reply_and_block(pConnection,
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync if ( dbus_message_iter_init(pReplySessionActive, &itMsg)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync && dbus_message_iter_get_arg_type(&itMsg) == DBUS_TYPE_BOOLEAN)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Get uid from message. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceVerbose(4, "ConsoleKit: session '%s' is %s\n",
359f2915f947abde1bba4358eada89941ee87cccvboxsync *ppszCurSession, fActive ? "active" : "not active");
359f2915f947abde1bba4358eada89941ee87cccvboxsync /* *ppszCurSession now contains the object path
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * (e.g. "/org/freedesktop/ConsoleKit/Session1"). */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync DBusMessage *pMsgUnixUser = dbus_message_new_method_call("org.freedesktop.ConsoleKit",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync "org.freedesktop.ConsoleKit.Session",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync "GetUnixUser");
359f2915f947abde1bba4358eada89941ee87cccvboxsync && dbus_message_get_type(pMsgUnixUser) == DBUS_MESSAGE_TYPE_METHOD_CALL)
359f2915f947abde1bba4358eada89941ee87cccvboxsync DBusMessage *pReplyUnixUser = dbus_connection_send_with_reply_and_block(pConnection,
359f2915f947abde1bba4358eada89941ee87cccvboxsync if ( dbus_message_iter_init(pReplyUnixUser, &itMsg)
359f2915f947abde1bba4358eada89941ee87cccvboxsync && dbus_message_iter_get_arg_type(&itMsg) == DBUS_TYPE_UINT32)
359f2915f947abde1bba4358eada89941ee87cccvboxsync /* Get uid from message. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /** @todo Add support for getting UID_MIN (/etc/login.defs on
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Debian). */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Look up user name (realname) from uid. */
359f2915f947abde1bba4358eada89941ee87cccvboxsync && ppwEntry->pw_uid >= uid_min /* Only respect users, not daemons etc. */
359f2915f947abde1bba4358eada89941ee87cccvboxsync VBoxServiceVerbose(4, "ConsoleKit: session '%s' -> %s (uid: %RU32)\n",
359f2915f947abde1bba4358eada89941ee87cccvboxsync bool fFound = false;
359f2915f947abde1bba4358eada89941ee87cccvboxsync for (uint32_t i = 0; i < cUsersInList && !fFound; i++)
359f2915f947abde1bba4358eada89941ee87cccvboxsync fFound = strcmp(papszUsers[i], ppwEntry->pw_name) == 0;
359f2915f947abde1bba4358eada89941ee87cccvboxsync VBoxServiceVerbose(4, "ConsoleKit: adding user \"%s\" to list\n",
359f2915f947abde1bba4358eada89941ee87cccvboxsync rc = RTStrDupEx(&papszUsers[cUsersInList], (const char *)ppwEntry->pw_name);
359f2915f947abde1bba4358eada89941ee87cccvboxsync VBoxServiceError("ConsoleKit: unable to lookup user name for uid=%RU32\n", uid);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync AssertMsgFailed(("ConsoleKit: GetUnixUser returned a wrong argument type\n"));
359f2915f947abde1bba4358eada89941ee87cccvboxsync VBoxServiceError("ConsoleKit: unable to retrieve user for session '%s' (msg type=%d): %s",
359f2915f947abde1bba4358eada89941ee87cccvboxsync *ppszCurSession, dbus_message_get_type(pMsgUnixUser),
359f2915f947abde1bba4358eada89941ee87cccvboxsync dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available\n");
359f2915f947abde1bba4358eada89941ee87cccvboxsync VBoxServiceError("ConsoleKit: unable to retrieve session parameters (msg type=%d): %s",
359f2915f947abde1bba4358eada89941ee87cccvboxsync dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available\n");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceError("Unable to invoke ConsoleKit (%d/3) -- maybe not installed / used? Error: %s\n",
359f2915f947abde1bba4358eada89941ee87cccvboxsync dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available\n");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync static int s_iBitchedAboutDBus = 0;
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceError("Unable to connect to system D-Bus (%d/3): %s\n", s_iBitchedAboutDBus,
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync dbus_error_is_set(&dbErr) ? dbErr.message : "D-Bus not installed\n");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync# endif /* RT_OS_LINUX */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync#endif /* VBOX_WITH_DBUS */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /** @todo Fedora/others: Handle systemd-loginctl. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Calc the string length. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Build the user list. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync if (i != 0)
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* Cleanup. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync Assert(RT_FAILURE(rc) || cUsersInList == 0 || (pszUserList && *pszUserList));
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* If the user enumeration above failed, reset the user count to 0 except
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * we didn't have enough memory anymore. In that case we want to preserve
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * the previous user count in order to not confuse third party tools which
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * rely on that count. */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync static int s_iVMInfoBitchedOOM = 0;
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceVerbose(0, "Warning: Not enough memory available to enumerate users! Keeping old value (%u)\n",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceVerbose(4, "cUsersInList=%RU32, pszUserList=%s, rc=%Rrc\n",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync cUsersInList, pszUserList ? pszUserList : "<NULL>", rc);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", pszUserList);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceError("VMInfo: Error writing logged on users list, rc=%Rrc\n", rc);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceError("VMInfo: Error writing logged on users count, rc=%Rrc\n", rc);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync rc = VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync VBoxServiceError("VMInfo: Error writing no logged in users beacon, rc=%Rrc\n", rc);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * Provide information about the guest network.
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync pAdpInfo = (IP_ADAPTER_INFO *)RTMemAlloc(cbAdpInfo);
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync VBoxServiceError("VMInfo/Network: Failed to allocate IP_ADAPTER_INFO\n");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync DWORD dwRet = GetAdaptersInfo(pAdpInfo, &cbAdpInfo);
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync IP_ADAPTER_INFO *pAdpInfoNew = (IP_ADAPTER_INFO*)RTMemRealloc(pAdpInfo, cbAdpInfo);
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync VBoxServiceVerbose(3, "VMInfo/Network: No network adapters available\n");
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync /* If no network adapters available / present in the
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync * system we pretend success to not bail out too early. */
0a7c9cc36ee176228eab4150144ad2561b0c4647vboxsync VBoxServiceError("VMInfo/Network: Failed to get adapter info: Error %d\n", dwRet);
359f2915f947abde1bba4358eada89941ee87cccvboxsync# endif /* !TARGET_NT4 */
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
359f2915f947abde1bba4358eada89941ee87cccvboxsync /* Don't complain/bail out with an error if network stack is not up; can happen
359f2915f947abde1bba4358eada89941ee87cccvboxsync * on NT4 due to start up when not connected shares dialogs pop up. */
359f2915f947abde1bba4358eada89941ee87cccvboxsync VBoxServiceVerbose(0, "VMInfo/Network: Network is not up yet.\n");
359f2915f947abde1bba4358eada89941ee87cccvboxsync VBoxServiceError("VMInfo/Network: Failed to get a socket: Error %d\n", wsaErr);
359f2915f947abde1bba4358eada89941ee87cccvboxsync unsigned long nBytesReturned = 0;
359f2915f947abde1bba4358eada89941ee87cccvboxsync VBoxServiceError("VMInfo/Network: Failed to WSAIoctl() on socket: Error: %d\n", WSAGetLastError());
2b73ea648457a8fb1ec027d1eeea63f879dad507vboxsync int cIfacesSystem = nBytesReturned / sizeof(INTERFACE_INFO);
for (int i = 0; i < cIfacesSystem; ++i)
RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Broadcast", cIfacesReport);
RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Netmask", cIfacesReport);
# ifndef TARGET_NT4
if (pAdp)
if (pAdpInfo)
if (sd >= 0)
return VERR_NOT_IMPLEMENTED;
if (rc < 0)
return rc;
RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Broadcast", cIfacesReport);
RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Netmask", cIfacesReport);
VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, pIfCurr->ifa_flags & IFF_UP ? "Up" : "Down");
if (sd < 0)
return rc;
return rc;
for (int i = 0; i < cIfacesSystem; ++i)
RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Broadcast", cIfacesReport);
RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%u/V4/Netmask", cIfacesReport);
# if defined(RT_OS_SOLARIS)
VBoxServiceVerbose(2, "VMInfo/Network: Interface %d has no assigned IP address, skipping ...\n", i);
# if defined(RT_OS_SOLARIS)
VBoxServiceError("VMInfo/Network: Network enumeration for interface %u failed with error %Rrc\n", cIfacesReport, rc);
rc = VBoxServiceReadPropUInt32(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/Net/Count", &cIfacesReportOld,
VBoxServiceVerbose(3, "VMInfo/Network: Deleting stale data of interface %d ...\n", uIfaceDeleteIdx);
rc = VBoxServicePropCacheUpdateByPath(&g_VMInfoPropCache, NULL /* Value, delete */, 0 /* Flags */, "/VirtualBox/GuestInfo/Net/%u", uIfaceDeleteIdx++);
VBoxServiceError("VMInfo/Network: Failed retrieving old network interfaces count with error %Rrc\n", rc);
return VINF_SUCCESS;
int rc;
#ifdef RT_OS_WINDOWS
VBoxServiceError("VMInfo/Network: WSAStartup failed! Error: %Rrc\n", RTErrConvertFromWin32(WSAGetLastError()));
if (*pfShutdown)
if (*pfShutdown)
#ifdef RT_OS_WINDOWS
WSACleanup();
return rc;