VBoxServiceVMInfo.cpp revision 2c042a102824ed308044077b31cbe508ba732721
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/* $Id$ */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** @file
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * VBoxService - Virtual Machine Information for the Host.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync */
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/*
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync * Copyright (C) 2009-2010 Oracle Corporation
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync *
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * available from http://www.virtualbox.org. This file is free software;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * General Public License (GPL) as published by the Free Software
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync */
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/*******************************************************************************
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync* Header Files *
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync*******************************************************************************/
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#ifdef RT_OS_WINDOWS
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync# include <winsock2.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <iphlpapi.h>
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# include <ws2tcpip.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <windows.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <Ntsecapi.h>
f5e53763b0a581b0299e98028c6c52192eb06785vboxsync#else
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# define __STDC_LIMIT_MACROS
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <arpa/inet.h>
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# include <errno.h>
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# include <netinet/in.h>
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# include <sys/ioctl.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <sys/socket.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <net/if.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <unistd.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# ifndef RT_OS_FREEBSD /* The header does not exist anymore since FreeBSD 9-current */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <utmp.h>
9b7ab382b3f9667e8847020e1e58f7143c4d2334vboxsync# endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# ifdef RT_OS_SOLARIS
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <sys/sockio.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# ifdef RT_OS_FREEBSD
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <ifaddrs.h> /* getifaddrs, freeifaddrs */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <net/if_dl.h> /* LLADDR */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# include <netdb.h> /* getnameinfo */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync#endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync#include <iprt/mem.h>
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync#include <iprt/thread.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync#include <iprt/string.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync#include <iprt/semaphore.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync#include <iprt/system.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync#include <iprt/time.h>
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync#include <iprt/assert.h>
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync#include <VBox/version.h>
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync#include <VBox/VBoxGuestLib.h>
7697e43970d863558b6c168a55e8948ccb18d8d1vboxsync#include "VBoxServiceInternal.h"
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync#include "VBoxServiceUtils.h"
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync#include "VBoxServicePropCache.h"
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/*******************************************************************************
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync* Global Variables *
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync*******************************************************************************/
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** The vminfo interval (millseconds). */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic uint32_t g_cMsVMInfoInterval = 0;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** The semaphore we're blocking on. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic RTSEMEVENTMULTI g_hVMInfoEvent = NIL_RTSEMEVENTMULTI;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** The guest property service client ID. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic uint32_t g_uVMInfoGuestPropSvcClientID = 0;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** Number of logged in users in OS. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic uint32_t g_cVMInfoLoggedInUsers = UINT32_MAX;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** The guest property cache. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic VBOXSERVICEVEPROPCACHE g_VMInfoPropCache;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** @copydoc VBOXSERVICE::pfnPreInit */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoPreInit(void)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync{
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync return VINF_SUCCESS;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync}
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** @copydoc VBOXSERVICE::pfnOption */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoOption(const char **ppszShort, int argc, char **argv, int *pi)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync{
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync int rc = -1;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (ppszShort)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /* no short options */;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync else if (!strcmp(argv[*pi], "--vminfo-interval"))
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VBoxServiceArgUInt32(argc, argv, "", pi,
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync &g_cMsVMInfoInterval, 1, UINT32_MAX - 1);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync return rc;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync}
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync/** @copydoc VBOXSERVICE::pfnInit */
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsyncstatic DECLCALLBACK(int) VBoxServiceVMInfoInit(void)
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync{
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync /*
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync * If not specified, find the right interval default.
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync * Then create the event sem to block on.
9b7ab382b3f9667e8847020e1e58f7143c4d2334vboxsync */
9b7ab382b3f9667e8847020e1e58f7143c4d2334vboxsync if (!g_cMsVMInfoInterval)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync g_cMsVMInfoInterval = g_DefaultInterval * 1000;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (!g_cMsVMInfoInterval)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync g_cMsVMInfoInterval = 10 * 1000;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync int rc = RTSemEventMultiCreate(&g_hVMInfoEvent);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync AssertRCReturn(rc, rc);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync rc = VbglR3GuestPropConnect(&g_uVMInfoGuestPropSvcClientID);
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync if (RT_SUCCESS(rc))
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync VBoxServiceVerbose(3, "VMInfo: Property Service Client ID: %#x\n", g_uVMInfoGuestPropSvcClientID);
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync else
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync {
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync /* If the service was not found, we disable this service without
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync causing VBoxService to fail. */
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync {
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync VBoxServiceVerbose(0, "VMInfo: Guest property service is not available, disabling the service\n");
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync rc = VERR_SERVICE_DISABLED;
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync }
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync else
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync VBoxServiceError("VMInfo: Failed to connect to the guest property service! Error: %Rrc\n", rc);
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync RTSemEventMultiDestroy(g_hVMInfoEvent);
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync g_hVMInfoEvent = NIL_RTSEMEVENTMULTI;
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync }
c060166f65b9dd2f1ed53e6e4cffdad948e01722vboxsync
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync if (RT_SUCCESS(rc))
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync {
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync VBoxServicePropCacheCreate(&g_VMInfoPropCache, g_uVMInfoGuestPropSvcClientID);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /*
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Declare some guest properties with flags and reset values.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY, NULL /* Delete on exit */);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY, "0");
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY, "true");
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE, NULL /* Delete on exit */);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync return rc;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync}
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/**
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync * Writes the properties that won't change while the service is running.
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync *
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync * Errors are ignored.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync */
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsyncstatic void vboxserviceVMInfoWriteFixedProperties(void)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync{
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync /*
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync * First get OS information that won't change.
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync */
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync char szInfo[256];
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync int rc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szInfo, sizeof(szInfo));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Product",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync "%s", RT_FAILURE(rc) ? "" : szInfo);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szInfo, sizeof(szInfo));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Release",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync "%s", RT_FAILURE(rc) ? "" : szInfo);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szInfo, sizeof(szInfo));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/Version",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync "%s", RT_FAILURE(rc) ? "" : szInfo);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = RTSystemQueryOSInfo(RTSYSOSINFO_SERVICE_PACK, szInfo, sizeof(szInfo));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestInfo/OS/ServicePack",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync "%s", RT_FAILURE(rc) ? "" : szInfo);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /*
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Retrieve version information about Guest Additions and installed files (components).
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync char *pszAddVer;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync char *pszAddRev;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VbglR3GetAdditionsVersion(&pszAddVer, &pszAddRev);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Version",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync "%s", RT_FAILURE(rc) ? "" : pszAddVer);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/Revision",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync "%s", RT_FAILURE(rc) ? "" : pszAddRev);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (RT_SUCCESS(rc))
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrFree(pszAddVer);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrFree(pszAddRev);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync#ifdef RT_OS_WINDOWS
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /*
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Do windows specific properties.
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync char *pszInstDir;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VbglR3GetAdditionsInstallationPath(&pszInstDir);
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync VBoxServiceWritePropF(g_uVMInfoGuestPropSvcClientID, "/VirtualBox/GuestAdd/InstallDir",
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync "%s", RT_FAILURE(rc) ? "" : pszInstDir);
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync if (RT_SUCCESS(rc))
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrFree(pszInstDir);
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync
762a68c2bb3ccde807330e3d1cb05f8b244a5f72vboxsync VBoxServiceWinGetComponentVersions(g_uVMInfoGuestPropSvcClientID);
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync#endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync}
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync/**
9540eeb13face31ddc1c5f15338556fe46f18a77vboxsync * Provide information about active users.
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync */
9540eeb13face31ddc1c5f15338556fe46f18a77vboxsyncstatic int vboxserviceVMInfoWriteUsers(void)
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync{
8287c906b9b1d215824d4cdf6c1eaf40681ebfa8vboxsync int rc;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync char *pszUserList = NULL;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync uint32_t cUsersInList = 0;
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync#ifdef RT_OS_WINDOWS
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# ifndef TARGET_NT4
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VBoxServiceVMInfoWinWriteUsers(&pszUserList, &cUsersInList);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# else
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VERR_NOT_IMPLEMENTED;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# endif
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync#elif defined(RT_OS_FREEBSD)
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync /** @todo FreeBSD: Port logged on user info retrival. */
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync rc = VERR_NOT_IMPLEMENTED;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync#elif defined(RT_OS_OS2)
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrival. */
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync rc = VERR_NOT_IMPLEMENTED;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync#else
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync rc = utmpname(UTMP_FILE);
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync# ifdef RT_OS_SOLARIS
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync if (rc != 1)
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync# else
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync if (rc != 0)
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync# endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Users: Could not set UTMP file! Error: %ld\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VERR_GENERAL_FAILURE;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync else
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VINF_SUCCESS;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync setutent();
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync utmp *ut_user;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync while ((ut_user = getutent()))
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /* Make sure we don't add user names which are not
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync * part of type USER_PROCESS. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /** @todo Do we want to filter out user names? What if a user is logged in twice? */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync if (ut_user->ut_type == USER_PROCESS)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync if (cUsersInList > 0)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = RTStrAAppend(&pszUserList, ",");
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync AssertRCBreakStmt(rc, RTStrFree(pszUserList));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = RTStrAAppend(&pszUserList, ut_user->ut_user);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync AssertRCBreakStmt(rc, RTStrFree(pszUserList));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync cUsersInList++;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync }
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync endutent();
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync#endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync Assert(RT_FAILURE(rc) || cUsersInList == 0 || (pszUserList && *pszUserList));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (RT_FAILURE(rc))
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync cUsersInList = 0;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync if (pszUserList && cUsersInList > 0)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", pszUserList);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync else
762a68c2bb3ccde807330e3d1cb05f8b244a5f72vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (g_cVMInfoLoggedInUsers != cUsersInList)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers",
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync cUsersInList == 0 ? "true" : "false");
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync g_cVMInfoLoggedInUsers = cUsersInList;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync if (RT_SUCCESS(rc) && pszUserList)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync RTStrFree(pszUserList);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync return VINF_SUCCESS;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync}
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync/**
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Provide information about the guest network.
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsyncstatic int vboxserviceVMInfoWriteNetwork(void)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync{
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync int cIfacesReport = 0;
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync char szPropPath[256];
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync#ifdef RT_OS_WINDOWS
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync IP_ADAPTER_INFO *pAdpInfo = NULL;
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# ifndef TARGET_NT4
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync ULONG cbAdpInfo = sizeof(*pAdpInfo);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pAdpInfo = (IP_ADAPTER_INFO *)RTMemAlloc(cbAdpInfo);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync if (!pAdpInfo)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to allocate IP_ADAPTER_INFO\n");
7697e43970d863558b6c168a55e8948ccb18d8d1vboxsync return VERR_NO_MEMORY;
7697e43970d863558b6c168a55e8948ccb18d8d1vboxsync }
7697e43970d863558b6c168a55e8948ccb18d8d1vboxsync DWORD dwRet = GetAdaptersInfo(pAdpInfo, &cbAdpInfo);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (dwRet == ERROR_BUFFER_OVERFLOW)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync IP_ADAPTER_INFO *pAdpInfoNew = (IP_ADAPTER_INFO*)RTMemRealloc(pAdpInfo, cbAdpInfo);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (pAdpInfoNew)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pAdpInfo = pAdpInfoNew;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync dwRet = GetAdaptersInfo(pAdpInfo, &cbAdpInfo);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync if (dwRet != ERROR_SUCCESS)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync if (pAdpInfo)
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync RTMemFree(pAdpInfo);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo/Network: Failed to get adapter info: Error %d\n", dwRet);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync return RTErrConvertFromWin32(dwRet);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync# endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync if (sd == SOCKET_ERROR) /* Socket invalid. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to get a socket: Error %d\n", WSAGetLastError());
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (pAdpInfo)
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync RTMemFree(pAdpInfo);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync return RTErrConvertFromWin32(WSAGetLastError());
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync INTERFACE_INFO InterfaceList[20] = {0};
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync unsigned long nBytesReturned = 0;
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync if (WSAIoctl(sd,
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync SIO_GET_INTERFACE_LIST,
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync 0,
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync 0,
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync &InterfaceList,
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync sizeof(InterfaceList),
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync &nBytesReturned,
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync 0,
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync 0) == SOCKET_ERROR)
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to WSAIoctl() on socket: Error: %d\n", WSAGetLastError());
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync if (pAdpInfo)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTMemFree(pAdpInfo);
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync return RTErrConvertFromWin32(WSAGetLastError());
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync int cIfacesSystem = nBytesReturned / sizeof(INTERFACE_INFO);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync /** @todo Use GetAdaptersInfo() and GetAdapterAddresses (IPv4 + IPv6) for more information. */
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync for (int i = 0; i < cIfacesSystem; ++i)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync sockaddr_in *pAddress;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync u_long nFlags = 0;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (InterfaceList[i].iiFlags & IFF_LOOPBACK) /* Skip loopback device. */
3956d0151065a11e49d2213b38a5efdad46807e0vboxsync continue;
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync nFlags = InterfaceList[i].iiFlags;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync pAddress = (sockaddr_in *)&(InterfaceList[i].iiAddress);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync Assert(pAddress);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync char szIp[32];
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szIp, sizeof(szIp), "%s", inet_ntoa(pAddress->sin_addr));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szIp);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pAddress = (sockaddr_in *) & (InterfaceList[i].iiBroadcastAddress);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pAddress = (sockaddr_in *)&(InterfaceList[i].iiNetmask);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, nFlags & IFF_UP ? "Up" : "Down");
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
3b1aa24d99d0f9cc157cf72ca76444b2feca3277vboxsync# ifndef TARGET_NT4
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync IP_ADAPTER_INFO *pAdp;
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync for (pAdp = pAdpInfo; pAdp; pAdp = pAdp->Next)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync if (!strcmp(pAdp->IpAddressList.IpAddress.String, szIp))
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync break;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync if (pAdp)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync {
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync char szMac[32];
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync pAdp->Address[0], pAdp->Address[1], pAdp->Address[2],
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync pAdp->Address[3], pAdp->Address[4], pAdp->Address[5]);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync else
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, NULL);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# endif
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync cIfacesReport++;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync }
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync if (pAdpInfo)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTMemFree(pAdpInfo);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (sd >= 0)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync closesocket(sd);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync#elif defined(RT_OS_FREEBSD)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync int rc = 0;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync struct ifaddrs *pIfHead = NULL;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Get all available interfaces */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync rc = getifaddrs(&pIfHead);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (rc < 0)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to get all interfaces: Error %d\n", errno);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync return RTErrConvertFromErrno(errno);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Loop through all interfaces and set the data. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync for (struct ifaddrs *pIfCurr = pIfHead; pIfCurr; pIfCurr = pIfCurr->ifa_next)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync {
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /*
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * Only AF_INET and no loopback interfaces
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * @todo: IPv6 interfaces
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync if ( pIfCurr->ifa_addr->sa_family == AF_INET
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync && !(pIfCurr->ifa_flags & IFF_LOOPBACK))
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync char szInetAddr[NI_MAXHOST];
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync memset(szInetAddr, 0, NI_MAXHOST);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync getnameinfo(pIfCurr->ifa_addr, sizeof(struct sockaddr_in),
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync szInetAddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync memset(szInetAddr, 0, NI_MAXHOST);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync getnameinfo(pIfCurr->ifa_broadaddr, sizeof(struct sockaddr_in),
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync szInetAddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync memset(szInetAddr, 0, NI_MAXHOST);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync getnameinfo(pIfCurr->ifa_netmask, sizeof(struct sockaddr_in),
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync szInetAddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szInetAddr);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Search for the AF_LINK interface of the current AF_INET one and get the mac. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync for (struct ifaddrs *pIfLinkCurr = pIfHead; pIfLinkCurr; pIfLinkCurr = pIfLinkCurr->ifa_next)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync {
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync if ( pIfLinkCurr->ifa_addr->sa_family == AF_LINK
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync && !strcmp(pIfCurr->ifa_name, pIfLinkCurr->ifa_name))
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync {
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync char szMac[32];
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync uint8_t *pu8Mac = NULL;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync struct sockaddr_dl *pLinkAddress = (struct sockaddr_dl *)pIfLinkCurr->ifa_addr;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync AssertPtr(pLinkAddress);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pu8Mac = (uint8_t *)LLADDR(pLinkAddress);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3], pu8Mac[4], pu8Mac[5]);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync break;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, pIfCurr->ifa_flags & IFF_UP ? "Up" : "Down");
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
067712a8118321d460f98b437ecafb6b8dbce301vboxsync cIfacesReport++;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync }
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync }
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync /* Free allocated resources. */
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync freeifaddrs(pIfHead);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync#else /* !RT_OS_WINDOWS && !RT_OS_FREEBSD */
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync int sd = socket(AF_INET, SOCK_DGRAM, 0);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync if (sd < 0)
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync {
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServiceError("VMInfo/Network: Failed to get a socket: Error %d\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync return RTErrConvertFromErrno(errno);
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync }
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync ifconf ifcfg;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync char buffer[1024] = {0};
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync ifcfg.ifc_len = sizeof(buffer);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync ifcfg.ifc_buf = buffer;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (ioctl(sd, SIOCGIFCONF, &ifcfg) < 0)
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFCONF) on socket: Error %d\n", errno);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync return RTErrConvertFromErrno(errno);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync }
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync ifreq* ifrequest = ifcfg.ifc_req;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync int cIfacesSystem = ifcfg.ifc_len / sizeof(ifreq);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync for (int i = 0; i < cIfacesSystem; ++i)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync sockaddr_in *pAddress;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (ioctl(sd, SIOCGIFFLAGS, &ifrequest[i]) < 0)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFFLAGS) on socket: Error %d\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync close(sd);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync return RTErrConvertFromErrno(errno);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync }
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync if (ifrequest[i].ifr_flags & IFF_LOOPBACK) /* Skip the loopback device. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync continue;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync bool fIfUp = !!(ifrequest[i].ifr_flags & IFF_UP);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync pAddress = ((sockaddr_in *)&ifrequest[i].ifr_addr);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync Assert(pAddress);
36fbf6dcd3e6b2e5891456b730577ff0eb355c9fvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/IP", cIfacesReport);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
36fbf6dcd3e6b2e5891456b730577ff0eb355c9fvboxsync if (ioctl(sd, SIOCGIFBRDADDR, &ifrequest[i]) < 0)
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync {
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync close(sd);
762a68c2bb3ccde807330e3d1cb05f8b244a5f72vboxsync return RTErrConvertFromErrno(errno);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync pAddress = (sockaddr_in *)&ifrequest[i].ifr_broadaddr;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Broadcast", cIfacesReport);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
36fbf6dcd3e6b2e5891456b730577ff0eb355c9fvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (ioctl(sd, SIOCGIFNETMASK, &ifrequest[i]) < 0)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync {
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFBRDADDR) on socket: Error %d\n", errno);
36fbf6dcd3e6b2e5891456b730577ff0eb355c9fvboxsync close(sd);
36fbf6dcd3e6b2e5891456b730577ff0eb355c9fvboxsync return RTErrConvertFromErrno(errno);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync }
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync# if defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync pAddress = (sockaddr_in *)&ifrequest[i].ifr_addr;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# else
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync pAddress = (sockaddr_in *)&ifrequest[i].ifr_netmask;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# endif
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/V4/Netmask", cIfacesReport);
762a68c2bb3ccde807330e3d1cb05f8b244a5f72vboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", inet_ntoa(pAddress->sin_addr));
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# if defined(RT_OS_SOLARIS)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (ioctl(sd, SIOCGENADDR, &ifrequest[i]) < 0)
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync# else
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync if (ioctl(sd, SIOCGIFHWADDR, &ifrequest[i]) < 0)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync {
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceError("VMInfo/Network: Failed to ioctl(SIOCGIFHWADDR) on socket: Error %d\n", errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync close(sd);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync return RTErrConvertFromErrno(errno);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync char szMac[32];
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# if defined(RT_OS_SOLARIS)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync uint8_t *pu8Mac = (uint8_t*)&ifrequest[i].ifr_enaddr[0];
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync# else
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync uint8_t *pu8Mac = (uint8_t*)&ifrequest[i].ifr_hwaddr.sa_data[0];
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync# endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szMac, sizeof(szMac), "%02X%02X%02X%02X%02X%02X",
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync pu8Mac[0], pu8Mac[1], pu8Mac[2], pu8Mac[3], pu8Mac[4], pu8Mac[5]);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/MAC", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, "%s", szMac);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestInfo/Net/%d/Status", cIfacesReport);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, szPropPath, fIfUp ? "Up" : "Down");
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync cIfacesReport++;
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
3b1aa24d99d0f9cc157cf72ca76444b2feca3277vboxsync close(sd);
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync#endif /* !RT_OS_WINDOWS */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync /*
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * This property is a beacon which is _always_ written, even if the network configuration
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * does not change. If this property is missing, the host assumes that all other GuestInfo
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * properties are no longer valid.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", "%d",
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync cIfacesReport);
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync /** @todo r=bird: if cIfacesReport decreased compared to the previous run, zap
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * the stale data. This can probably be encorporated into the cache. */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync return VINF_SUCCESS;
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync}
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync/** @copydoc VBOXSERVICE::pfnWorker */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsyncDECLCALLBACK(int) VBoxServiceVMInfoWorker(bool volatile *pfShutdown)
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync{
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync int rc;
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync /*
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * Tell the control thread that it can continue
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * spawning services.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync RTThreadUserSignal(RTThreadSelf());
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync#ifdef RT_OS_WINDOWS
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync /* Required for network information (must be called per thread). */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync WSADATA wsaData;
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync if (WSAStartup(MAKEWORD(2, 2), &wsaData))
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync VBoxServiceError("VMInfo/Network: WSAStartup failed! Error: %Rrc\n", RTErrConvertFromWin32(WSAGetLastError()));
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync#endif /* RT_OS_WINDOWS */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync /*
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * Write the fixed properties first.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync vboxserviceVMInfoWriteFixedProperties();
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync /*
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * Now enter the loop retrieving runtime data continuously.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync for (;;)
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync {
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync rc = vboxserviceVMInfoWriteUsers();
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync if (RT_FAILURE(rc))
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync break;
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync rc = vboxserviceVMInfoWriteNetwork();
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync if (RT_FAILURE(rc))
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync break;
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync /*
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * Block for a while.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync *
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * The event semaphore takes care of ignoring interruptions and it
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync * allows us to implement service wakeup later.
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync */
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync if (*pfShutdown)
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync break;
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync int rc2 = RTSemEventMultiWait(g_hVMInfoEvent, g_cMsVMInfoInterval);
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync if (*pfShutdown)
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync break;
8a54ed337392872c7cfcfb96f173468bbbb0f7fcvboxsync if (rc2 != VERR_TIMEOUT && RT_FAILURE(rc2))
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync {
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServiceError("VMInfo: RTSemEventMultiWait failed; rc2=%Rrc\n", rc2);
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync rc = rc2;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync break;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync }
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync }
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync#ifdef RT_OS_WINDOWS
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync WSACleanup();
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync#endif
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync return rc;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync}
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** @copydoc VBOXSERVICE::pfnStop */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncstatic DECLCALLBACK(void) VBoxServiceVMInfoStop(void)
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync{
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTSemEventMultiSignal(g_hVMInfoEvent);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync}
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync/** @copydoc VBOXSERVICE::pfnTerm */
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsyncstatic DECLCALLBACK(void) VBoxServiceVMInfoTerm(void)
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync{
3614117c1132a61599e6190939e775cafe549411vboxsync int rc;
034f0367d3b0431c6346b1a3af3abb435ee50d4evboxsync
3614117c1132a61599e6190939e775cafe549411vboxsync if (g_hVMInfoEvent != NIL_RTSEMEVENTMULTI)
3614117c1132a61599e6190939e775cafe549411vboxsync {
3614117c1132a61599e6190939e775cafe549411vboxsync /** @todo temporary solution: Zap all values which are not valid
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * anymore when VM goes down (reboot/shutdown ). Needs to
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * be replaced with "temporary properties" later.
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync *
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * One idea is to introduce a (HGCM-)session guest property
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * flag meaning that a guest property is only valid as long
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * as the HGCM session isn't closed (e.g. guest application
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * terminates). [don't remove till implemented]
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /** @todo r=bird: Drop the VbglR3GuestPropDelSet call here and use the cache
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync * since it remembers what we've written. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Delete the "../Net" branch. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync const char *apszPat[1] = { "/VirtualBox/GuestInfo/Net/*" };
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync rc = VbglR3GuestPropDelSet(g_uVMInfoGuestPropSvcClientID, &apszPat[0], RT_ELEMENTS(apszPat));
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Destroy property cache. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServicePropCacheDestroy(&g_VMInfoPropCache);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* Disconnect from guest properties service. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync rc = VbglR3GuestPropDisconnect(g_uVMInfoGuestPropSvcClientID);
fe554d9c0e3a6de4ba221610ac95a44c7d288e01vboxsync if (RT_FAILURE(rc))
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync VBoxServiceError("VMInfo: Failed to disconnect from guest property service! Error: %Rrc\n", rc);
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync g_uVMInfoGuestPropSvcClientID = 0;
7c48fdac0546978ed14617c8096734ce2d18c8e5vboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync RTSemEventMultiDestroy(g_hVMInfoEvent);
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync g_hVMInfoEvent = NIL_RTSEMEVENTMULTI;
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync }
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync}
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync/**
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync * The 'vminfo' service description.
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsyncVBOXSERVICE g_VMInfo =
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync{
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync /* pszName. */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync "vminfo",
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync /* pszDescription. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync "Virtual Machine Information",
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync /* pszUsage. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync " [--vminfo-interval <ms>]"
762a68c2bb3ccde807330e3d1cb05f8b244a5f72vboxsync ,
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync /* pszOptions. */
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync " --vminfo-interval Specifies the interval at which to retrieve the\n"
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync " VM information. The default is 10000 ms.\n"
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync ,
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync /* methods */
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceVMInfoPreInit,
016096e367cd20c3d3c3fd9a6650b55935c2e31dvboxsync VBoxServiceVMInfoOption,
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServiceVMInfoInit,
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServiceVMInfoWorker,
3ebd5757516d21eccdad25ddd456d2913c2fb215vboxsync VBoxServiceVMInfoStop,
ac6445a70a26cb69d08734f1d9dbc171cec86cd8vboxsync VBoxServiceVMInfoTerm
ac6445a70a26cb69d08734f1d9dbc171cec86cd8vboxsync};
b2bc8de1367ae24e1b27b53921d0b32ee3df7acdvboxsync
ac6445a70a26cb69d08734f1d9dbc171cec86cd8vboxsync