VBoxControl.cpp revision ba31bc205e96548d3557ae82087dc020a52b6a0a
682a27d94b9116c719038882487b99053985f91avboxsync * VBoxControl - Guest Additions Command Line Management Interface.
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2008-2010 Oracle Corporation
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * available from http://www.virtualbox.org. This file is free software;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * you can redistribute it and/or modify it under the terms of the GNU
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * General Public License (GPL) as published by the Free Software
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/*******************************************************************************
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync* Header Files *
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync*******************************************************************************/
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/*******************************************************************************
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync* Global Variables *
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync*******************************************************************************/
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** The program name (derived from argv[0]). */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** The current verbosity level. */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * Displays the program usage message.
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync * @param u64Which
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** Helper function */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsyncstatic void doUsage(char const *line, char const *name = "", char const *command = "")
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync /* Allow for up to 15 characters command name length (VBoxControl.exe) with
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync * perfect column alignment. Beyond that there's at least one space between
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync * the command if there are command line parameters. */
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync RTPrintf("%s %-*s%s%s\n", name, strlen(line) ? 35 - strlen(name) : 1,
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** Enumerate the different parts of the usage we might want to print out */
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("print version number and exit", g_pszProgName, "[-v|-version]");
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("suppress the logo", g_pszProgName, "-nologo ...");
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync/* Exclude the Windows bits from the test version. Anyone who needs to test
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * them can fix this. */
7525834c8ff7d6665778b83fb9d0585624ee7ae9vboxsync#if defined(RT_OS_WINDOWS) && !defined(VBOX_CONTROL_TEST)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ((GET_VIDEO_ACCEL == eWhich) || (USAGE_ALL == eWhich))
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("", g_pszProgName, "getvideoacceleration");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ((SET_VIDEO_ACCEL == eWhich) || (USAGE_ALL == eWhich))
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("<on|off>", g_pszProgName, "setvideoacceleration");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ((LIST_CUST_MODES == eWhich) || (USAGE_ALL == eWhich))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ((ADD_CUST_MODE == eWhich) || (USAGE_ALL == eWhich))
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("<width> <height> <bpp>", g_pszProgName, "addcustommode");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ((REMOVE_CUST_MODE == eWhich) || (USAGE_ALL == eWhich))
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("<width> <height> <bpp>", g_pszProgName, "removecustommode");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ((SET_VIDEO_MODE == eWhich) || (USAGE_ALL == eWhich))
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("<width> <height> <bpp> <screen>", g_pszProgName, "setvideomode");
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync if ((GUEST_PROP == eWhich) || (USAGE_ALL == eWhich))
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("get <property> [-verbose]", g_pszProgName, "guestproperty");
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("set <property> [<value> [-flags <flags>]]", g_pszProgName, "guestproperty");
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("enumerate [-patterns <patterns>]", g_pszProgName, "guestproperty");
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("wait <patterns>", g_pszProgName, "guestproperty");
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync if ((GUEST_SHAREDFOLDERS == eWhich) || (USAGE_ALL == eWhich))
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync doUsage("list [-automount]", g_pszProgName, "sharedfolder");
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * Displays an error message.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * @param pszFormat The message text.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * @param ... Format arguments.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsyncstatic void VBoxControlError(const char *pszFormat, ...)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync // RTStrmPrintf(g_pStdErr, "%s: error: ", g_pszProgName);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync#if defined(RT_OS_WINDOWS) && !defined(VBOX_CONTROL_TEST)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncLONG (WINAPI * gpfnChangeDisplaySettingsEx)(LPCTSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic unsigned nextAdjacentRectXP (RECTL *paRects, unsigned nRects, unsigned iRect)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < nRects; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic unsigned nextAdjacentRectXN (RECTL *paRects, unsigned nRects, unsigned iRect)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < nRects; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic unsigned nextAdjacentRectYP (RECTL *paRects, unsigned nRects, unsigned iRect)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < nRects; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncunsigned nextAdjacentRectYN (RECTL *paRects, unsigned nRects, unsigned iRect)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < nRects; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncvoid resizeRect(RECTL *paRects, unsigned nRects, unsigned iPrimary, unsigned iResized, int NewWidth, int NewHeight)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RECTL *paNewRects = (RECTL *)alloca (sizeof (RECTL) * nRects);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync memcpy (paNewRects, paRects, sizeof (RECTL) * nRects);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iResized].right += NewWidth - (paNewRects[iResized].right - paNewRects[iResized].left);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iResized].bottom += NewHeight - (paNewRects[iResized].bottom - paNewRects[iResized].top);
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync /* Verify all pairs of originally adjacent rectangles for all 4 directions.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * If the pair has a "good" delta (that is the first rectangle intersects the second)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * at a direction and the second rectangle is not primary one (which can not be moved),
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * move the second rectangle to make it adjacent to the first one.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* X positive. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find the next adjacent original rect in x positive direction. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iNextRect = nextAdjacentRectXP (paRects, nRects, iRect);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Check whether there is an X intesection between these adjacent rects in the new rectangles
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * and fix the intersection if delta is "good".
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int delta = paNewRects[iRect].right - paNewRects[iNextRect].left;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("XP intersection right %d left %d, diff %d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iRect].right, paNewRects[iNextRect].left,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* X negative. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find the next adjacent original rect in x negative direction. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iNextRect = nextAdjacentRectXN (paRects, nRects, iRect);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Check whether there is an X intesection between these adjacent rects in the new rectangles
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * and fix the intersection if delta is "good".
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int delta = paNewRects[iRect].left - paNewRects[iNextRect].right;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("XN intersection left %d right %d, diff %d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iRect].left, paNewRects[iNextRect].right,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Y positive (in the computer sence, top->down). */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find the next adjacent original rect in y positive direction. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iNextRect = nextAdjacentRectYP (paRects, nRects, iRect);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Check whether there is an Y intesection between these adjacent rects in the new rectangles
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * and fix the intersection if delta is "good".
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int delta = paNewRects[iRect].bottom - paNewRects[iNextRect].top;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("YP intersection bottom %d top %d, diff %d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iRect].bottom, paNewRects[iNextRect].top,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Y negative (in the computer sence, down->top). */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find the next adjacent original rect in x negative direction. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iNextRect = nextAdjacentRectYN (paRects, nRects, iRect);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Check whether there is an Y intesection between these adjacent rects in the new rectangles
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * and fix the intersection if delta is "good".
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int delta = paNewRects[iRect].top - paNewRects[iNextRect].bottom;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("YN intersection top %d bottom %d, diff %d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iRect].top, paNewRects[iNextRect].bottom,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync memcpy (paRects, paNewRects, sizeof (RECTL) * nRects);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/* Returns TRUE to try again. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find out how many display devices the system has */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found primary device. err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found secondary device. err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found total %d devices. err %d\n", NumDevices, GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Requested identifier %d is invalid. err %d\n", Id, GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DISPLAY_DEVICE *paDisplayDevices = (DISPLAY_DEVICE *)alloca (sizeof (DISPLAY_DEVICE) * NumDevices);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DEVMODE *paDeviceModes = (DEVMODE *)alloca (sizeof (DEVMODE) * NumDevices);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RECTL *paRects = (RECTL *)alloca (sizeof (RECTL) * NumDevices);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Fetch information about current devices and modes. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("[%d(%d)] %s\n", i, DevNum, DisplayDevice.DeviceName));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found primary device. err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found secondary device. err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ZeroMemory(&paDeviceModes[DevNum], sizeof(DEVMODE));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("EnumDisplaySettings err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paRects[DevNum].left = paDeviceModes[DevNum].dmPosition.x;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paRects[DevNum].top = paDeviceModes[DevNum].dmPosition.y;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paRects[DevNum].right = paDeviceModes[DevNum].dmPosition.x + paDeviceModes[DevNum].dmPelsWidth;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paRects[DevNum].bottom = paDeviceModes[DevNum].dmPosition.y + paDeviceModes[DevNum].dmPelsHeight;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Check whether a mode reset or a change is requested. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("VBoxDisplayThread : already at desired resolution.\n"));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync resizeRect(paRects, NumDevices, DevPrimaryNum, Id, Width, Height);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < NumDevices; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#endif /* Log */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Without this, Windows will not ask the miniport for its
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * mode table but uses an internal cache instead.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Assign the new rectangles to displays. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < NumDevices; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmPelsWidth = paRects[i].right - paRects[i].left;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmPelsHeight = paRects[i].bottom - paRects[i].top;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync Log(("calling pfnChangeDisplaySettingsEx %x\n", gpfnChangeDisplaySettingsEx));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync gpfnChangeDisplaySettingsEx((LPSTR)paDisplayDevices[i].DeviceName,
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync &paDeviceModes[i], NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("ChangeDisplaySettings position err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* A second call to ChangeDisplaySettings updates the monitor. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("ChangeDisplaySettings update status %d\n", status));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (status == DISP_CHANGE_SUCCESSFUL || status == DISP_CHANGE_BADMODE)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Successfully set new video mode or our driver can not set the requested mode. Stop trying. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Retry the request. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync *(uintptr_t *)&gpfnChangeDisplaySettingsEx = (uintptr_t)GetProcAddress(hUser, "ChangeDisplaySettingsExA");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("VBoxService: pChangeDisplaySettingsEx = %p\n", gpfnChangeDisplaySettingsEx));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* The screen index is 0 based in the ResizeDisplayDevice call. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Horizontal resolution must be a multiple of 8, round down. */
ebd35513cc8c7c67273191d51285629d77a1f736vboxsync RTPrintf("Setting resolution of display %d to %dx%dx%d ...", scr, xres, yres, bpp);
ebd35513cc8c7c67273191d51285629d77a1f736vboxsync else VBoxControlError("Error retrieving API for display change!");
ebd35513cc8c7c67273191d51285629d77a1f736vboxsync else VBoxControlError("Error retrieving handle to user32.dll!");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\VIDEO", 0, KEY_READ, &hkeyDeviceMap);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxControlError("Error opening video device map registry key!\n");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegQueryValueExA(hkeyDeviceMap, "\\Device\\Video0", NULL, &dwKeyType, (LPBYTE)szVideoLocation, &len);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * This value will start with a weird value: \REGISTRY\Machine
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Make sure this is true.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && (_strnicmp(szVideoLocation, "\\REGISTRY\\Machine", 17) == 0))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* open that branch */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, &szVideoLocation[18], 0, KEY_READ | (writable ? KEY_WRITE : 0), &hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxControlError("Error opening registry key '%s'\n", &szVideoLocation[18]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncint handleGetVideoAcceleration(int argc, char *argv[])
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* query the actual value */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegQueryValueExA(hkeyVideo, "EnableVideoAccel", NULL, &dwKeyType, (LPBYTE)&fAcceleration, &len);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTPrintf("Video acceleration: %s\n", fAcceleration ? "on" : "off");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncint handleSetVideoAcceleration(int argc, char *argv[])
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* must have exactly one argument: the new offset */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* set a new value */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegSetValueExA(hkeyVideo, "EnableVideoAccel", 0, REG_DWORD, (LPBYTE)&fAccel, sizeof(fAccel));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxControlError("Error %d writing video acceleration status!\n", status);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/* the table of custom modes */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* null out the table */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dWidth", curMode);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegQueryValueExA(hkeyVideo, valueName, NULL, &dwType, (LPBYTE)&xres, &dwLen);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dHeight", curMode);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegQueryValueExA(hkeyVideo, valueName, NULL, &dwType, (LPBYTE)&yres, &dwLen);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dBPP", curMode);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegQueryValueExA(hkeyVideo, valueName, NULL, &dwType, (LPBYTE)&bpp, &dwLen);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* check if the mode is OK */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* add mode to table */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync } while(1);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* first remove all values */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (int i = 0; i < MAX_CUSTOM_MODES; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dWidth", i);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dHeight", i);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dBPP", i);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* is the table entry present? */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTPrintf("writing mode %d (%dx%dx%d)\n", modeIndex, customModes[tableIndex].xres, customModes[tableIndex].yres, customModes[tableIndex].bpp);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dWidth", modeIndex);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegSetValueExA(hkeyVideo, valueName, 0, REG_DWORD, (LPBYTE)&customModes[tableIndex].xres,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dHeight", modeIndex);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegSetValueExA(hkeyVideo, valueName, 0, REG_DWORD, (LPBYTE)&customModes[tableIndex].yres,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dBPP", modeIndex);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegSetValueExA(hkeyVideo, valueName, 0, REG_DWORD, (LPBYTE)&customModes[tableIndex].bpp,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync } while(1);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (int i = 0; i < (sizeof(customModes) / sizeof(customModes[0])); i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync customModes[i].xres, customModes[i].yres, customModes[i].bpp);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /** @todo better check including xres mod 8 = 0! */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxControlError("Error: invalid mode specified!\n");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < MAX_CUSTOM_MODES; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* mode exists? */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < MAX_CUSTOM_MODES; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* item free? */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (int i = 0; i < MAX_CUSTOM_MODES; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* correct item? */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#endif /* RT_OS_WINDOWS */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Retrieves a value from the guest property store.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * This is accessed through the "VBoxGuestPropSvc" HGCM service.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * @returns 0 on success, 1 on failure
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * @note see the command line API description for parameters
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync using namespace guestProp;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync bool verbose = false;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync if ((2 == argc) && (0 == strcmp(argv[1], "-verbose")))
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * Here we actually retrieve the value from the host.
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync /* The buffer for storing the data and its initial size. We leave a bit
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync * of space here in case the maximum values are raised. */
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync uint32_t cbBuf = MAX_VALUE_LEN + MAX_FLAGS_LEN + 1024;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync /* Because there is a race condition between our reading the size of a
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * property and the guest updating it, we loop a few times here and
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * hope. Actually this should never go wrong, as we are generous
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * enough with buffer space. */
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync bool finish = false;
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cbBuf,
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync /* Leave a bit of extra space to be safe */
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync VBoxControlError("Temporarily unable to retrieve the property\n");
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync else if (!RT_SUCCESS(rc) && (rc != VERR_NOT_FOUND))
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync VBoxControlError("Failed to retrieve the property value, error %Rrc\n", rc);
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * And display it on the guest console.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Writes a value to the guest property store.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * This is accessed through the "VBoxGuestPropSvc" HGCM service.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * @returns 0 on success, 1 on failure
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * @note see the command line API description for parameters
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * Check the syntax. We can deduce the correct syntax from the number of
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * arguments.
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync bool usageOK = true;
7e7e58609ea74ab895389ea8c2a3639557ecb753vboxsync /* This is always needed. */
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * Do the actual setting.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync rc = VbglR3GuestPropWrite(u32ClientId, pszName, pszValue, pszFlags);
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync rc = VbglR3GuestPropWriteValue(u32ClientId, pszName, pszValue);
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync VBoxControlError("Failed to store the property value, error %Rrc\n", rc);
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync * Enumerates the properties in the guest property store.
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync * This is accessed through the "VBoxGuestPropSvc" HGCM service.
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync * @returns 0 on success, 1 on failure
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync * @note see the command line API description for parameters
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsyncstatic int enumGuestProperty(int argc, char *argv[])
9ee72227058430bcead5831131741b5dc1601f00vboxsync * Check the syntax. We can deduce the correct syntax from the number of
9ee72227058430bcead5831131741b5dc1601f00vboxsync * arguments.
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync else if (argc != 0)
9ee72227058430bcead5831131741b5dc1601f00vboxsync * Do the actual enumeration.
9ee72227058430bcead5831131741b5dc1601f00vboxsync rc = VbglR3GuestPropEnum(u32ClientId, papszPatterns, cPatterns, &pHandle,
9ee72227058430bcead5831131741b5dc1601f00vboxsync RTPrintf("Name: %s, value: %s, timestamp: %lld, flags: %s\n",
9ee72227058430bcead5831131741b5dc1601f00vboxsync rc = VbglR3GuestPropEnumNext(pHandle, &pszName, &pszValue, &u64Timestamp, &pszFlags);
9ee72227058430bcead5831131741b5dc1601f00vboxsync VBoxControlError("Error while enumerating guest properties: %Rrc\n", rc);
2a287e364d33444fd0aa85fb2a165d84b7b64586vboxsync VBoxControlError("Failed to enumerate the guest properties! Error: %Rrc\n", rc);
9ee72227058430bcead5831131741b5dc1601f00vboxsync VBoxControlError("Failed to connect to the guest property service! Error: %Rrc\n", rc);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * Waits for notifications of changes to guest properties.
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * This is accessed through the "VBoxGuestPropSvc" HGCM service.
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * @returns 0 on success, 1 on failure
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * @note see the command line API description for parameters
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync using namespace guestProp;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * Handle arguments
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync bool usageOK = true;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync || RTStrToUInt64Full(argv[i + 1], 10, &u64TimestampIn)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * Connect to the service
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * Retrieve the notification from the host
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync /* The buffer for storing the data and its initial size. We leave a bit
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * of space here in case the maximum values are raised. */
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync uint32_t cbBuf = MAX_NAME_LEN + MAX_VALUE_LEN + MAX_FLAGS_LEN + 1024;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync /* Because there is a race condition between our reading the size of a
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * property and the guest updating it, we loop a few times here and
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * hope. Actually this should never go wrong, as we are generous
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * enough with buffer space. */
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync bool finish = false;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync for (unsigned i = 0;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW) && !finish && (i < 10);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync rc = VbglR3GuestPropWait(u32ClientId, pszPatterns, pvBuf, cbBuf,
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync /* Leave a bit of extra space to be safe */
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VBoxControlError("Temporarily unable to get a notification\n");
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VBoxControlError("The request timed out or was interrupted\n");
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync#ifndef RT_OS_WINDOWS /* Windows guests do not do this right */
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync else if (!RT_SUCCESS(rc) && (rc != VERR_NOT_FOUND))
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VBoxControlError("Failed to get a notification, error %Rrc\n", rc);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * And display it on the guest console.
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync RTPrintf("Internal error: unable to determine the size of the data!\n");
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * Access the guest property store through the "VBoxGuestPropSvc" HGCM
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * @returns 0 on success, 1 on failure
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * @note see the command line API description for parameters
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsyncstatic int handleGuestProperty(int argc, char *argv[])
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync * Lists the Shared Folders provided by the host.
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync bool usageOK = true;
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync VBoxControlError("Failed to connect to the shared folder service, error %Rrc\n", rc);
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync rc = VbglR3SharedFolderGetMappings(u32ClientId, fOnlyShowAutoMount,
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync RTPrintf("Auto-mounted Shared Folder mappings (%u):\n\n", cMappings);
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync RTPrintf("Shared Folder mappings (%u):\n\n", cMappings);
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync rc = VbglR3SharedFolderGetName(u32ClientId, paMappings[i].u32Root, &pszName);
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync VBoxControlError("Error while getting the shared folder name for root node = %u, rc = %Rrc\n",
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync VBoxControlError("Error while getting the shared folder mappings, rc = %Rrc\n", rc);
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync * Handles Shared Folders control.
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync * @returns 0 on success, 1 on failure
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync * @note see the command line API description for parameters
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsyncstatic int handleSharedFolder(int argc, char *argv[])
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** command handler type */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsynctypedef DECLCALLBACK(int) FNHANDLER(int argc, char *argv[]);
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** The table of all registered command handlers. */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync const char *command;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync#if defined(RT_OS_WINDOWS) && !defined(VBOX_CONTROL_TEST)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync { "getvideoacceleration", handleGetVideoAcceleration },
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync { "setvideoacceleration", handleSetVideoAcceleration },
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** Main function */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** The application's global return code */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** An IPRT return code for local use */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** The index of the command line argument we are currently processing */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** Should we show the logo text? */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync bool showlogo = true;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync /** Should we print the usage after the logo? For the -help switch. */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync bool dohelp = false;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** Will we be executing a command or just printing information? */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync bool onlyinfo = false;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * Start by handling command line switches
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** Are we finished with handling switches? */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync bool done = false;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /* Print version number, and do nothing else. */
8d43244aa3d322f7807a4b0488f1038dd2595dc1vboxsync RTPrintf("%sr%u\n", VBOX_VERSION_STRING, RTBldCfgRevision());
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /* We have found an argument which isn't a switch. Exit to the
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * command processing bit. */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * Find the application name, show our logo if the user hasn't suppressed it,
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * and show the usage if the user asked us to
d653df42608a5162103b5d3c6bc712d9bb6ce39dvboxsync RTPrintf(VBOX_PRODUCT " Guest Additions Command Line Management Interface Version "
03aef08d59dd179fd178a35f445e731788896cabvboxsync "All rights reserved.\n\n");
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * Do global initialisation for the programme if we will be handling a command
dced478b440a327fb550155c0f73c1ac968ad93bvboxsync rrc = RTR3Init(); /** @todo r=bird: This ALWAYS goes first, the only exception is when you have to parse args to figure out which to call! */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync VBoxControlError("Failed to initialise the VirtualBox runtime - error %Rrc\n", rrc);
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync VBoxControlError("Could not contact the host system. Make sure that you are running this\n"
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync "application inside a VirtualBox guest system, and that you have sufficient\n"
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync "user permissions.\n");
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * Now look for an actual command in the argument list and handle it.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * The input is in the guest OS'es codepage (NT guarantees ACP).
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * For VBox we use UTF-8. For simplicity, just convert the argv[] array
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** Is next parameter a known command? */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync bool found = false;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** And if so, what is its position in the table? */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync unsigned index = 0;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync if (0 == strcmp(argv[iArg], g_commandHandlers[index].command))
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync rc = g_commandHandlers[index].handler(argc - iArg - 1, argv + iArg + 1);
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /* The user didn't specify a command. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Free converted argument vector
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * And exit, returning the status