8d43244aa3d322f7807a4b0488f1038dd2595dc1vboxsync/* $Id$ */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** @file
682a27d94b9116c719038882487b99053985f91avboxsync * VBoxControl - Guest Additions Command Line Management Interface.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/*
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * Copyright (C) 2008-2013 Oracle Corporation
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync *
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
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/*******************************************************************************
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync* Header Files *
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync*******************************************************************************/
682a27d94b9116c719038882487b99053985f91avboxsync#include <iprt/alloca.h>
b8f36a8f77f0140f48170d5b3cd9ee9ea1c14294vboxsync#include <iprt/cpp/autores.h>
8d43244aa3d322f7807a4b0488f1038dd2595dc1vboxsync#include <iprt/buildconfig.h>
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync#include <iprt/getopt.h>
682a27d94b9116c719038882487b99053985f91avboxsync#include <iprt/initterm.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <iprt/mem.h>
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync#include <iprt/message.h>
682a27d94b9116c719038882487b99053985f91avboxsync#include <iprt/path.h>
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync#include <iprt/string.h>
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync#include <iprt/stream.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#include <VBox/log.h>
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync#include <VBox/version.h>
682a27d94b9116c719038882487b99053985f91avboxsync#include <VBox/VBoxGuestLib.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#ifdef RT_OS_WINDOWS
682a27d94b9116c719038882487b99053985f91avboxsync# include <Windows.h>
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#endif
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#ifdef VBOX_WITH_GUEST_PROPS
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync# include <VBox/HostServices/GuestPropertySvc.h>
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync#endif
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync# include <VBox/VBoxGuest.h>
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync# include "../VBoxGuestLib/VBGLR3Internal.h" /* HACK ALERT! Using vbglR3DoIOCtl directly!! */
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync#endif
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/*******************************************************************************
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync* Global Variables *
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync*******************************************************************************/
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** The program name (derived from argv[0]). */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsyncchar const *g_pszProgName = "";
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** The current verbosity level. */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsyncint g_cVerbosity = 0;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/**
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * Displays the program usage message.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync *
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync * @param u64Which
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync *
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * @{
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** Helper function */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsyncstatic void doUsage(char const *line, char const *name = "", char const *command = "")
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync{
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,
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync command, strlen(line) ? " " : "", line);
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync}
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** Enumerate the different parts of the usage we might want to print out */
d09ef734532edd0e40ffe9a471e0a31152572065vboxsyncenum VBoxControlUsage
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync{
7525834c8ff7d6665778b83fb9d0585624ee7ae9vboxsync#ifdef RT_OS_WINDOWS
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync GET_VIDEO_ACCEL,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync SET_VIDEO_ACCEL,
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync VIDEO_FLAGS,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync LIST_CUST_MODES,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ADD_CUST_MODE,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync REMOVE_CUST_MODE,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync SET_VIDEO_MODE,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#endif
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#ifdef VBOX_WITH_GUEST_PROPS
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync GUEST_PROP,
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync#endif
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync#ifdef VBOX_WITH_SHARED_FOLDERS
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync GUEST_SHAREDFOLDERS,
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync#endif
683bc538c5d6598479b7da2ad464939422d449d6vboxsync#if !defined(VBOX_CONTROL_TEST)
b608f15cba5036182124f1eee68b761535aa6d14vboxsync WRITE_CORE_DUMP,
683bc538c5d6598479b7da2ad464939422d449d6vboxsync#endif
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync WRITE_LOG,
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync TAKE_SNAPSHOT,
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync SAVE_STATE,
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync SUSPEND,
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync POWER_OFF,
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync VERSION,
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync HELP,
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync USAGE_ALL = UINT32_MAX
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync};
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsyncstatic RTEXITCODE usage(enum VBoxControlUsage eWhich = USAGE_ALL)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync{
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync RTPrintf("Usage:\n\n");
45b6bbe8e4a372bc22e5bfd3b8765214b3e213cavboxsync doUsage("print version number and exit", g_pszProgName, "[-V|--version]");
29ca486256e4e37b75574bda09c385d5e6b076c0vboxsync doUsage("suppress the logo", g_pszProgName, "--nologo ...");
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync RTPrintf("\n");
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync /* Exclude the Windows bits from the test version. Anyone who needs to
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync test them can fix this. */
7525834c8ff7d6665778b83fb9d0585624ee7ae9vboxsync#if defined(RT_OS_WINDOWS) && !defined(VBOX_CONTROL_TEST)
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync if (eWhich == GET_VIDEO_ACCEL || eWhich == USAGE_ALL)
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("", g_pszProgName, "getvideoacceleration");
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync if (eWhich == SET_VIDEO_ACCEL || eWhich == USAGE_ALL)
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("<on|off>", g_pszProgName, "setvideoacceleration");
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (eWhich == VIDEO_FLAGS || eWhich == USAGE_ALL)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync doUsage("<get|set|clear|delete> [hex mask]", g_pszProgName, "videoflags");
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync if (eWhich == LIST_CUST_MODES || eWhich == USAGE_ALL)
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("", g_pszProgName, "listcustommodes");
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync if (eWhich == ADD_CUST_MODE || eWhich == USAGE_ALL)
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("<width> <height> <bpp>", g_pszProgName, "addcustommode");
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync if (eWhich == REMOVE_CUST_MODE || eWhich == USAGE_ALL)
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("<width> <height> <bpp>", g_pszProgName, "removecustommode");
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync if (eWhich == SET_VIDEO_MODE || eWhich == USAGE_ALL)
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("<width> <height> <bpp> <screen>", g_pszProgName, "setvideomode");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#endif
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#ifdef VBOX_WITH_GUEST_PROPS
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync if (eWhich == GUEST_PROP || eWhich == USAGE_ALL)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync {
29ca486256e4e37b75574bda09c385d5e6b076c0vboxsync doUsage("get <property> [--verbose]", g_pszProgName, "guestproperty");
29ca486256e4e37b75574bda09c385d5e6b076c0vboxsync doUsage("set <property> [<value> [--flags <flags>]]", g_pszProgName, "guestproperty");
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync doUsage("delete|unset <property>", g_pszProgName, "guestproperty");
29ca486256e4e37b75574bda09c385d5e6b076c0vboxsync doUsage("enumerate [--patterns <patterns>]", g_pszProgName, "guestproperty");
4c953c3c459d80bc3e31a0a65a9dc0463f340e6bvboxsync doUsage("wait <patterns>", g_pszProgName, "guestproperty");
29ca486256e4e37b75574bda09c385d5e6b076c0vboxsync doUsage("[--timestamp <last timestamp>]");
29ca486256e4e37b75574bda09c385d5e6b076c0vboxsync doUsage("[--timeout <timeout in ms>");
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync }
b83d9b1072dd8491c7ffe37830e8fd10f2dba561vboxsync#endif
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync#ifdef VBOX_WITH_SHARED_FOLDERS
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync if (eWhich == GUEST_SHAREDFOLDERS || eWhich == USAGE_ALL)
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync {
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync doUsage("list [-automount]", g_pszProgName, "sharedfolder");
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync }
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync#endif
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync
683bc538c5d6598479b7da2ad464939422d449d6vboxsync#if !defined(VBOX_CONTROL_TEST)
b608f15cba5036182124f1eee68b761535aa6d14vboxsync if (eWhich == WRITE_CORE_DUMP || eWhich == USAGE_ALL)
b608f15cba5036182124f1eee68b761535aa6d14vboxsync doUsage("", g_pszProgName, "writecoredump");
683bc538c5d6598479b7da2ad464939422d449d6vboxsync#endif
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync if (eWhich == WRITE_LOG || eWhich == USAGE_ALL)
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync doUsage("", g_pszProgName, "writelog [-n|--no-newline] [--] <msg>");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync if (eWhich == TAKE_SNAPSHOT || eWhich == USAGE_ALL)
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync doUsage("", g_pszProgName, "takesnapshot");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync if (eWhich == SAVE_STATE || eWhich == USAGE_ALL)
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync doUsage("", g_pszProgName, "savestate");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync if (eWhich == SUSPEND || eWhich == USAGE_ALL)
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync doUsage("", g_pszProgName, "suspend");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync if (eWhich == POWER_OFF || eWhich == USAGE_ALL)
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync doUsage("", g_pszProgName, "poweroff");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync if (eWhich == HELP || eWhich == USAGE_ALL)
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync doUsage("[command]", g_pszProgName, "help");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync if (eWhich == VERSION || eWhich == USAGE_ALL)
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync doUsage("", g_pszProgName, "version");
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync return RTEXITCODE_SUCCESS;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** @} */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync/**
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync * Implementation of the '--version' option.
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync *
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync * @returns RTEXITCODE_SUCCESS
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync */
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsyncstatic RTEXITCODE printVersion(void)
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync{
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync RTPrintf("%sr%u\n", VBOX_VERSION_STRING, RTBldCfgRevision());
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync return RTEXITCODE_SUCCESS;
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync}
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/**
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * Displays an error message.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync *
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync * @returns RTEXITCODE_FAILURE.
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync * @param pszFormat The message text. No newline.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * @param ... Format arguments.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync */
d09ef734532edd0e40ffe9a471e0a31152572065vboxsyncstatic RTEXITCODE VBoxControlError(const char *pszFormat, ...)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync{
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync /** @todo prefix with current command. */
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync va_list va;
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync va_start(va, pszFormat);
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync RTMsgErrorV(pszFormat, va);
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync va_end(va);
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync return RTEXITCODE_FAILURE;
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync}
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync/**
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync * Displays a getopt error.
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync *
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync * @returns RTEXITCODE_FAILURE.
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync * @param ch The RTGetOpt return value.
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync * @param pValueUnion The RTGetOpt return data.
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync */
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsyncstatic RTEXITCODE VBoxCtrlGetOptError(int ch, PCRTGETOPTUNION pValueUnion)
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync{
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync /** @todo prefix with current command. */
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync return RTGetOptPrintError(ch, pValueUnion);
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync}
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync/**
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync * Displays an syntax error message.
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync *
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync * @returns RTEXITCODE_FAILURE.
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync * @param pszFormat The message text. No newline.
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync * @param ... Format arguments.
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync */
d09ef734532edd0e40ffe9a471e0a31152572065vboxsyncstatic RTEXITCODE VBoxControlSyntaxError(const char *pszFormat, ...)
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync{
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync /** @todo prefix with current command. */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync va_list va;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync va_start(va, pszFormat);
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync RTMsgErrorV(pszFormat, va);
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync va_end(va);
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync return RTEXITCODE_FAILURE;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync}
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync#if defined(RT_OS_WINDOWS) && !defined(VBOX_CONTROL_TEST)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncLONG (WINAPI * gpfnChangeDisplaySettingsEx)(LPCTSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic unsigned nextAdjacentRectXP (RECTL *paRects, unsigned nRects, unsigned iRect)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < nRects; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (paRects[iRect].right == paRects[i].left)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return ~0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic unsigned nextAdjacentRectXN (RECTL *paRects, unsigned nRects, unsigned iRect)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < nRects; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (paRects[iRect].left == paRects[i].right)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return ~0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic unsigned nextAdjacentRectYP (RECTL *paRects, unsigned nRects, unsigned iRect)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < nRects; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (paRects[iRect].bottom == paRects[i].top)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return ~0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncunsigned nextAdjacentRectYN (RECTL *paRects, unsigned nRects, unsigned iRect)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < nRects; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (paRects[iRect].top == paRects[i].bottom)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return ~0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncvoid resizeRect(RECTL *paRects, unsigned nRects, unsigned iPrimary, unsigned iResized, int NewWidth, int NewHeight)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
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
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 */
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* X positive. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iRect;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (iRect = 0; iRect < nRects; iRect++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find the next adjacent original rect in x positive direction. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iNextRect = nextAdjacentRectXP (paRects, nRects, iRect);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("next %d -> %d\n", iRect, iNextRect));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (iNextRect == ~0 || iNextRect == iPrimary)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync continue;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* Check whether there is an X intersection between these adjacent rects in the new rectangles
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * and fix the intersection if delta is "good".
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int delta = paNewRects[iRect].right - paNewRects[iNextRect].left;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (delta > 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("XP intersection right %d left %d, diff %d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iRect].right, paNewRects[iNextRect].left,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync delta));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iNextRect].left += delta;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iNextRect].right += delta;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* X negative. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (iRect = 0; iRect < nRects; iRect++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find the next adjacent original rect in x negative direction. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iNextRect = nextAdjacentRectXN (paRects, nRects, iRect);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("next %d -> %d\n", iRect, iNextRect));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (iNextRect == ~0 || iNextRect == iPrimary)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync continue;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* Check whether there is an X intersection between these adjacent rects in the new rectangles
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * and fix the intersection if delta is "good".
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int delta = paNewRects[iRect].left - paNewRects[iNextRect].right;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (delta < 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("XN intersection left %d right %d, diff %d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iRect].left, paNewRects[iNextRect].right,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync delta));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iNextRect].left += delta;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iNextRect].right += delta;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* Y positive (in the computer sense, top->down). */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (iRect = 0; iRect < nRects; iRect++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find the next adjacent original rect in y positive direction. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iNextRect = nextAdjacentRectYP (paRects, nRects, iRect);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("next %d -> %d\n", iRect, iNextRect));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (iNextRect == ~0 || iNextRect == iPrimary)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync continue;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* Check whether there is an Y intersection between these adjacent rects in the new rectangles
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * and fix the intersection if delta is "good".
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int delta = paNewRects[iRect].bottom - paNewRects[iNextRect].top;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (delta > 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("YP intersection bottom %d top %d, diff %d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iRect].bottom, paNewRects[iNextRect].top,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync delta));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iNextRect].top += delta;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iNextRect].bottom += delta;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* Y negative (in the computer sense, down->top). */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (iRect = 0; iRect < nRects; iRect++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find the next adjacent original rect in x negative direction. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync unsigned iNextRect = nextAdjacentRectYN (paRects, nRects, iRect);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("next %d -> %d\n", iRect, iNextRect));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (iNextRect == ~0 || iNextRect == iPrimary)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync continue;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* Check whether there is an Y intersection between these adjacent rects in the new rectangles
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * and fix the intersection if delta is "good".
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int delta = paNewRects[iRect].top - paNewRects[iNextRect].bottom;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (delta < 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("YN intersection top %d bottom %d, diff %d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iRect].top, paNewRects[iNextRect].bottom,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync delta));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iNextRect].top += delta;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paNewRects[iNextRect].bottom += delta;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync memcpy (paRects, paNewRects, sizeof (RECTL) * nRects);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/* Returns TRUE to try again. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstatic BOOL ResizeDisplayDevice(ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync BOOL fModeReset = (Width == 0 && Height == 0 && BitsPerPixel == 0);
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DISPLAY_DEVICE DisplayDevice;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DisplayDevice.cb = sizeof(DisplayDevice);
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Find out how many display devices the system has */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD NumDevices = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD i = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0))
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("[%d] %s\n", i, DisplayDevice.DeviceName));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found primary device. err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync NumDevices++;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found secondary device. err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync NumDevices++;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DisplayDevice.cb = sizeof(DisplayDevice);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync i++;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found total %d devices. err %d\n", NumDevices, GetLastError ()));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (NumDevices == 0 || Id >= NumDevices)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Requested identifier %d is invalid. err %d\n", Id, GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return FALSE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
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);
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Fetch information about current devices and modes. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD DevNum = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD DevPrimaryNum = 0;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync i = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync while (EnumDisplayDevices (NULL, i, &DisplayDevice, 0))
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("[%d(%d)] %s\n", i, DevNum, DisplayDevice.DeviceName));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync BOOL bFetchDevice = FALSE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found primary device. err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DevPrimaryNum = DevNum;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync bFetchDevice = TRUE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync else if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("Found secondary device. err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync bFetchDevice = TRUE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (bFetchDevice)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (DevNum >= NumDevices)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("%d >= %d\n", NumDevices, DevNum));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return FALSE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDisplayDevices[DevNum] = DisplayDevice;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ZeroMemory(&paDeviceModes[DevNum], sizeof(DEVMODE));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[DevNum].dmSize = sizeof(DEVMODE);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ENUM_REGISTRY_SETTINGS, &paDeviceModes[DevNum]))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("EnumDisplaySettings err %d\n", GetLastError ()));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return FALSE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("%dx%d at %d,%d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[DevNum].dmPelsWidth,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[DevNum].dmPelsHeight,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[DevNum].dmPosition.x,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[DevNum].dmPosition.y));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
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 DevNum++;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ZeroMemory(&DisplayDevice, sizeof(DISPLAY_DEVICE));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync i++;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (Width == 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Width = paRects[Id].right - paRects[Id].left;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (Height == 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Height = paRects[Id].bottom - paRects[Id].top;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Check whether a mode reset or a change is requested. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( !fModeReset
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && paRects[Id].right - paRects[Id].left == Width
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && paRects[Id].bottom - paRects[Id].top == Height
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && paDeviceModes[Id].dmBitsPerPel == BitsPerPixel)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("VBoxDisplayThread : already at desired resolution.\n"));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return FALSE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync resizeRect(paRects, NumDevices, DevPrimaryNum, Id, Width, Height);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#ifdef Log
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < NumDevices; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("[%d]: %d,%d %dx%d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync i, paRects[i].left, paRects[i].top,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paRects[i].right - paRects[i].left,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paRects[i].bottom - paRects[i].top));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#endif /* Log */
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Without this, Windows will not ask the miniport for its
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * mode table but uses an internal cache instead.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DEVMODE tempDevMode;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ZeroMemory (&tempDevMode, sizeof (tempDevMode));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync tempDevMode.dmSize = sizeof(DEVMODE);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync EnumDisplaySettings(NULL, 0xffffff, &tempDevMode);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Assign the new rectangles to displays. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < NumDevices; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmPosition.x = paRects[i].left;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmPosition.y = paRects[i].top;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmPelsWidth = paRects[i].right - paRects[i].left;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmPelsHeight = paRects[i].bottom - paRects[i].top;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmFields = DM_POSITION | DM_PELSHEIGHT | DM_PELSWIDTH;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( i == Id
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && BitsPerPixel != 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmFields |= DM_BITSPERPEL;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync paDeviceModes[i].dmBitsPerPel = BitsPerPixel;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
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 }
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* A second call to ChangeDisplaySettings updates the monitor. */
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync LONG status = ChangeDisplaySettings(NULL, 0);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("ChangeDisplaySettings update status %d\n", status));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (status == DISP_CHANGE_SUCCESSFUL || status == DISP_CHANGE_BADMODE)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Successfully set new video mode or our driver can not set the requested mode. Stop trying. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return FALSE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Retry the request. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return TRUE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE handleSetVideoMode(int argc, char *argv[])
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (argc != 3 && argc != 4)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync usage(SET_VIDEO_MODE);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD xres = atoi(argv[0]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD yres = atoi(argv[1]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD bpp = atoi(argv[2]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD scr = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (argc == 4)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync scr = atoi(argv[3]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
51df2768ddb5c4dd975267b4ba82ba02da82d20avboxsync HMODULE hUser = GetModuleHandle("user32.dll");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (hUser)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync *(uintptr_t *)&gpfnChangeDisplaySettingsEx = (uintptr_t)GetProcAddress(hUser, "ChangeDisplaySettingsExA");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync Log(("VBoxService: pChangeDisplaySettingsEx = %p\n", gpfnChangeDisplaySettingsEx));
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (gpfnChangeDisplaySettingsEx)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* The screen index is 0 based in the ResizeDisplayDevice call. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync scr = scr > 0? scr - 1: 0;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* Horizontal resolution must be a multiple of 8, round down. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync xres &= ~0x7;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
ebd35513cc8c7c67273191d51285629d77a1f736vboxsync RTPrintf("Setting resolution of display %d to %dx%dx%d ...", scr, xres, yres, bpp);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ResizeDisplayDevice(scr, xres, yres, bpp);
ebd35513cc8c7c67273191d51285629d77a1f736vboxsync RTPrintf("done.\n");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync else
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync VBoxControlError("Error retrieving API for display change!");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync else
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync VBoxControlError("Error retrieving handle to user32.dll!");
dced478b440a327fb550155c0f73c1ac968ad93bvboxsync
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_SUCCESS;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsyncstatic int checkVBoxVideoKey(HKEY hkeyVideo)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync char szValue[128];
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync DWORD len = sizeof(szValue);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync DWORD dwKeyType;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync LONG status = RegQueryValueExA(hkeyVideo, "Device Description", NULL, &dwKeyType,
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync (LPBYTE)szValue, &len);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if (status == ERROR_SUCCESS)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync /* WDDM has additional chars after "Adapter" */
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync static char sszDeviceDescription[] = "VirtualBox Graphics Adapter";
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if (_strnicmp(szValue, sszDeviceDescription, sizeof(sszDeviceDescription) - sizeof(char)) == 0)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync return VINF_SUCCESS;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync return VERR_NOT_FOUND;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync}
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsyncstatic HKEY getVideoKey(bool writable)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync{
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync HKEY hkeyDeviceMap = 0;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync LONG status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\VIDEO", 0, KEY_READ, &hkeyDeviceMap);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if (status != ERROR_SUCCESS || !hkeyDeviceMap)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxControlError("Error opening video device map registry key!\n");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync HKEY hkeyVideo = 0;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync ULONG iDevice;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD dwKeyType;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /*
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync * Scan all '\Device\VideoX' REG_SZ keys to find VBox video driver entry.
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync * 'ObjectNumberList' REG_BINARY is an array of 32 bit device indexes (X).
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync */
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync /* Get the 'ObjectNumberList' */
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync ULONG numDevices = 0;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync DWORD adwObjectNumberList[256];
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync DWORD len = sizeof(adwObjectNumberList);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync status = RegQueryValueExA(hkeyDeviceMap, "ObjectNumberList", NULL, &dwKeyType, (LPBYTE)&adwObjectNumberList[0], &len);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if ( status == ERROR_SUCCESS
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync && dwKeyType == REG_BINARY)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync numDevices = len / sizeof(DWORD);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync else
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync /* The list might not exists. Use 'MaxObjectNumber' REG_DWORD and build a list. */
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync DWORD dwMaxObjectNumber = 0;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync len = sizeof(dwMaxObjectNumber);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync status = RegQueryValueExA(hkeyDeviceMap, "MaxObjectNumber", NULL, &dwKeyType, (LPBYTE)&dwMaxObjectNumber, &len);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if ( status == ERROR_SUCCESS
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync && dwKeyType == REG_DWORD)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync /* 'MaxObjectNumber' is inclusive. */
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync numDevices = RT_MIN(dwMaxObjectNumber + 1, RT_ELEMENTS(adwObjectNumberList));
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync for (iDevice = 0; iDevice < numDevices; iDevice++)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync adwObjectNumberList[iDevice] = iDevice;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
642c5426705752783a84f96829690f69c1ab199evboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if (numDevices == 0)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync /* Always try '\Device\Video0' as the old code did. Enum can be used in this case in principle. */
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync adwObjectNumberList[0] = 0;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync numDevices = 1;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync /* Scan device entries */
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync for (iDevice = 0; iDevice < numDevices; iDevice++)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync char szValueName[64];
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync RTStrPrintf(szValueName, sizeof(szValueName), "\\Device\\Video%u", adwObjectNumberList[iDevice]);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync char szVideoLocation[256];
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync len = sizeof(szVideoLocation);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync status = RegQueryValueExA(hkeyDeviceMap, szValueName, NULL, &dwKeyType, (LPBYTE)&szVideoLocation[0], &len);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync /* This value starts with '\REGISTRY\Machine' */
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if ( status == ERROR_SUCCESS
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync && dwKeyType == REG_SZ
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync && _strnicmp(szVideoLocation, "\\REGISTRY\\Machine", 17) == 0)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, &szVideoLocation[18], 0,
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync KEY_READ | (writable ? KEY_WRITE : 0), &hkeyVideo);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if (status == ERROR_SUCCESS)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync int rc = checkVBoxVideoKey(hkeyVideo);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if (RT_SUCCESS(rc))
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync /* Found, return hkeyVideo to the caller. */
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync break;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync RegCloseKey(hkeyVideo);
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync hkeyVideo = 0;
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync if (hkeyVideo == 0)
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync {
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync VBoxControlError("Error opening video registry key!\n");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
faa47a2ab7e8738caf95fc3211622d04487558cevboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegCloseKey(hkeyDeviceMap);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync return hkeyVideo;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE handleGetVideoAcceleration(int argc, char *argv[])
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ULONG status;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync HKEY hkeyVideo = getVideoKey(false);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (hkeyVideo)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* query the actual value */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD fAcceleration = 1;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD len = sizeof(fAcceleration);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD dwKeyType;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegQueryValueExA(hkeyVideo, "EnableVideoAccel", NULL, &dwKeyType, (LPBYTE)&fAcceleration, &len);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (status != ERROR_SUCCESS)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTPrintf("Video acceleration: default\n");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync else
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTPrintf("Video acceleration: %s\n", fAcceleration ? "on" : "off");
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegCloseKey(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_SUCCESS;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE handleSetVideoAcceleration(int argc, char *argv[])
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ULONG status;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync HKEY hkeyVideo;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* must have exactly one argument: the new offset */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( (argc != 1)
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync || ( RTStrICmp(argv[0], "on")
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync && RTStrICmp(argv[0], "off")))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync usage(SET_VIDEO_ACCEL);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync hkeyVideo = getVideoKey(true);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (hkeyVideo)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int fAccel = 0;
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync if (RTStrICmp(argv[0], "on") == 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync fAccel = 1;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* set a new value */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegSetValueExA(hkeyVideo, "EnableVideoAccel", 0, REG_DWORD, (LPBYTE)&fAccel, sizeof(fAccel));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (status != ERROR_SUCCESS)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxControlError("Error %d writing video acceleration status!\n", status);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegCloseKey(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_SUCCESS;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsyncstatic RTEXITCODE videoFlagsGet(void)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync{
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync HKEY hkeyVideo = getVideoKey(false);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (hkeyVideo)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync DWORD dwFlags = 0;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync DWORD len = sizeof(dwFlags);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync DWORD dwKeyType;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync ULONG status = RegQueryValueExA(hkeyVideo, "VBoxVideoFlags", NULL, &dwKeyType, (LPBYTE)&dwFlags, &len);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (status != ERROR_SUCCESS)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync RTPrintf("Video flags: default\n");
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync else
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync RTPrintf("Video flags: 0x%08X\n", dwFlags);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync RegCloseKey(hkeyVideo);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync return RTEXITCODE_SUCCESS;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync return RTEXITCODE_FAILURE;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync}
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsyncstatic RTEXITCODE videoFlagsDelete(void)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync{
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync HKEY hkeyVideo = getVideoKey(true);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (hkeyVideo)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync ULONG status = RegDeleteValueA(hkeyVideo, "VBoxVideoFlags");
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (status != ERROR_SUCCESS)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync VBoxControlError("Error %d deleting video flags.\n", status);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync RegCloseKey(hkeyVideo);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync return RTEXITCODE_SUCCESS;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync return RTEXITCODE_FAILURE;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync}
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsyncstatic RTEXITCODE videoFlagsModify(bool fSet, int argc, char *argv[])
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync{
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (argc != 1)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync VBoxControlError("Mask required.\n");
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync return RTEXITCODE_FAILURE;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync uint32_t u32Mask = 0;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync int rc = RTStrToUInt32Full(argv[0], 16, &u32Mask);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (RT_FAILURE(rc))
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync VBoxControlError("Invalid video flags mask.\n");
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync return RTEXITCODE_FAILURE;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync RTEXITCODE exitCode = RTEXITCODE_SUCCESS;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync HKEY hkeyVideo = getVideoKey(true);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (hkeyVideo)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync DWORD dwFlags = 0;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync DWORD len = sizeof(dwFlags);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync DWORD dwKeyType;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync ULONG status = RegQueryValueExA(hkeyVideo, "VBoxVideoFlags", NULL, &dwKeyType, (LPBYTE)&dwFlags, &len);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (status != ERROR_SUCCESS)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync dwFlags = 0;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync dwFlags = fSet? (dwFlags | u32Mask):
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync (dwFlags & ~u32Mask);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync status = RegSetValueExA(hkeyVideo, "VBoxVideoFlags", 0, REG_DWORD, (LPBYTE)&dwFlags, sizeof(dwFlags));
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (status != ERROR_SUCCESS)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync VBoxControlError("Error %d writing video flags.\n", status);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync exitCode = RTEXITCODE_FAILURE;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync RegCloseKey(hkeyVideo);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync else
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync exitCode = RTEXITCODE_FAILURE;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync return exitCode;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync}
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsyncstatic RTEXITCODE handleVideoFlags(int argc, char *argv[])
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync{
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync /* Must have a keyword and optional value (32 bit hex string). */
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (argc != 1 && argc != 2)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync VBoxControlError("Invalid number of arguments.\n");
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync usage(VIDEO_FLAGS);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync return RTEXITCODE_FAILURE;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync RTEXITCODE exitCode = RTEXITCODE_SUCCESS;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (RTStrICmp(argv[0], "get") == 0)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync exitCode = videoFlagsGet();
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync else if (RTStrICmp(argv[0], "delete") == 0)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync exitCode = videoFlagsDelete();
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync else if (RTStrICmp(argv[0], "set") == 0)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync exitCode = videoFlagsModify(true, argc - 1, &argv[1]);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync else if (RTStrICmp(argv[0], "clear") == 0)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync exitCode = videoFlagsModify(false, argc - 1, &argv[1]);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync else
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync VBoxControlError("Invalid command.\n");
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync exitCode = RTEXITCODE_FAILURE;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync if (exitCode != RTEXITCODE_SUCCESS)
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync {
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync usage(VIDEO_FLAGS);
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync }
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync return exitCode;
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync}
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#define MAX_CUSTOM_MODES 128
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/* the table of custom modes */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncstruct
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD xres;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD yres;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD bpp;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync} customModes[MAX_CUSTOM_MODES] = {0};
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncvoid getCustomModes(HKEY hkeyVideo)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ULONG status;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int curMode = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* null out the table */
48d832e07616531bbb720d9c98103c83b561ebb6vboxsync RT_ZERO(customModes);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync do
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync char valueName[20];
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD xres, yres, bpp = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD dwType;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD dwLen = sizeof(DWORD);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dWidth", curMode);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegQueryValueExA(hkeyVideo, valueName, NULL, &dwType, (LPBYTE)&xres, &dwLen);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (status != ERROR_SUCCESS)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync break;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dHeight", curMode);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegQueryValueExA(hkeyVideo, valueName, NULL, &dwType, (LPBYTE)&yres, &dwLen);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (status != ERROR_SUCCESS)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync break;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dBPP", curMode);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegQueryValueExA(hkeyVideo, valueName, NULL, &dwType, (LPBYTE)&bpp, &dwLen);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (status != ERROR_SUCCESS)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync break;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* check if the mode is OK */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( (xres > (1 << 16))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && (yres > (1 << 16))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && ( (bpp != 16)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync || (bpp != 24)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync || (bpp != 32)))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync break;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* add mode to table */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync customModes[curMode].xres = xres;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync customModes[curMode].yres = yres;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync customModes[curMode].bpp = bpp;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ++curMode;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (curMode >= MAX_CUSTOM_MODES)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync break;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync } while(1);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncvoid writeCustomModes(HKEY hkeyVideo)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync ULONG status;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int tableIndex = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int modeIndex = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* first remove all values */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (int i = 0; i < MAX_CUSTOM_MODES; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync char valueName[20];
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dWidth", i);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegDeleteValueA(hkeyVideo, valueName);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dHeight", i);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegDeleteValueA(hkeyVideo, valueName);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dBPP", i);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegDeleteValueA(hkeyVideo, valueName);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync do
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (tableIndex >= MAX_CUSTOM_MODES)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync break;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* is the table entry present? */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( (!customModes[tableIndex].xres)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync || (!customModes[tableIndex].yres)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync || (!customModes[tableIndex].bpp))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync tableIndex++;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync continue;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTPrintf("writing mode %d (%dx%dx%d)\n", modeIndex, customModes[tableIndex].xres, customModes[tableIndex].yres, customModes[tableIndex].bpp);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync char valueName[20];
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dWidth", modeIndex);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync status = RegSetValueExA(hkeyVideo, valueName, 0, REG_DWORD, (LPBYTE)&customModes[tableIndex].xres,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync sizeof(customModes[tableIndex].xres));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dHeight", modeIndex);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegSetValueExA(hkeyVideo, valueName, 0, REG_DWORD, (LPBYTE)&customModes[tableIndex].yres,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync sizeof(customModes[tableIndex].yres));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTStrPrintf(valueName, sizeof(valueName), "CustomMode%dBPP", modeIndex);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegSetValueExA(hkeyVideo, valueName, 0, REG_DWORD, (LPBYTE)&customModes[tableIndex].bpp,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync sizeof(customModes[tableIndex].bpp));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync modeIndex++;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync tableIndex++;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync } while(1);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE handleListCustomModes(int argc, char *argv[])
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (argc != 0)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync usage(LIST_CUST_MODES);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync HKEY hkeyVideo = getVideoKey(false);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (hkeyVideo)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync getCustomModes(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (int i = 0; i < (sizeof(customModes) / sizeof(customModes[0])); i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( !customModes[i].xres
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync || !customModes[i].yres
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync || !customModes[i].bpp)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync continue;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTPrintf("Mode: %d x %d x %d\n",
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync customModes[i].xres, customModes[i].yres, customModes[i].bpp);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegCloseKey(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_SUCCESS;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE handleAddCustomMode(int argc, char *argv[])
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (argc != 3)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync usage(ADD_CUST_MODE);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD xres = atoi(argv[0]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD yres = atoi(argv[1]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD bpp = atoi(argv[2]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /** @todo better check including xres mod 8 = 0! */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( (xres > (1 << 16))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && (yres > (1 << 16))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && ( (bpp != 16)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync || (bpp != 24)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync || (bpp != 32)))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync VBoxControlError("invalid mode specified!\n");
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync HKEY hkeyVideo = getVideoKey(true);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (hkeyVideo)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int i;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int fModeExists = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync getCustomModes(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < MAX_CUSTOM_MODES; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* mode exists? */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( customModes[i].xres == xres
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && customModes[i].yres == yres
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && customModes[i].bpp == bpp
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync )
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync fModeExists = 1;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (!fModeExists)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (i = 0; i < MAX_CUSTOM_MODES; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* item free? */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (!customModes[i].xres)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync customModes[i].xres = xres;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync customModes[i].yres = yres;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync customModes[i].bpp = bpp;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync break;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync writeCustomModes(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegCloseKey(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_SUCCESS;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE handleRemoveCustomMode(int argc, char *argv[])
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (argc != 3)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync usage(REMOVE_CUST_MODE);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD xres = atoi(argv[0]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD yres = atoi(argv[1]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync DWORD bpp = atoi(argv[2]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync HKEY hkeyVideo = getVideoKey(true);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if (hkeyVideo)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync getCustomModes(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync for (int i = 0; i < MAX_CUSTOM_MODES; i++)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync /* correct item? */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync if ( (customModes[i].xres == xres)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && (customModes[i].yres == yres)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync && (customModes[i].bpp == bpp))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync {
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RTPrintf("found mode at index %d\n", i);
0f46260983ce0c8dc90e45b71602e2c02276ce6dvboxsync RT_ZERO(customModes[i]);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync break;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync writeCustomModes(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync RegCloseKey(hkeyVideo);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync }
dced478b440a327fb550155c0f73c1ac968ad93bvboxsync
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_SUCCESS;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync}
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#endif /* RT_OS_WINDOWS */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#ifdef VBOX_WITH_GUEST_PROPS
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/**
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Retrieves a value from the guest property store.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * This is accessed through the "VBoxGuestPropSvc" HGCM service.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync *
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync * @returns Command exit code.
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * @note see the command line API description for parameters
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE getGuestProperty(int argc, char **argv)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync{
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync using namespace guestProp;
12767477bc2dbc7815e4784576a15c990f5590d3vboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync bool fVerbose = false;
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync if ( 2 == argc
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync && ( strcmp(argv[1], "-verbose") == 0
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync || strcmp(argv[1], "--verbose") == 0)
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync )
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync fVerbose = true;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync else if (argc != 1)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync usage(GUEST_PROP);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync uint32_t u32ClientId = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int rc = VINF_SUCCESS;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync rc = VbglR3GuestPropConnect(&u32ClientId);
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync if (RT_FAILURE(rc))
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * Here we actually retrieve the value from the host.
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync const char *pszName = argv[0];
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync char *pszValue = NULL;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync uint64_t u64Timestamp = 0;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync char *pszFlags = NULL;
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 void *pvBuf = NULL;
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync uint32_t cbBuf = MAX_VALUE_LEN + MAX_FLAGS_LEN + 1024;
12767477bc2dbc7815e4784576a15c990f5590d3vboxsync if (RT_SUCCESS(rc))
12767477bc2dbc7815e4784576a15c990f5590d3vboxsync {
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 for (unsigned i = 0; (i < 10) && !finish; ++i)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync {
aeca728c901587edda5cdc79092a6432ad85d3e7vboxsync void *pvTmpBuf = RTMemRealloc(pvBuf, cbBuf);
aeca728c901587edda5cdc79092a6432ad85d3e7vboxsync if (NULL == pvTmpBuf)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync {
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync rc = VERR_NO_MEMORY;
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync VBoxControlError("Out of memory\n");
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync }
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync else
aeca728c901587edda5cdc79092a6432ad85d3e7vboxsync {
aeca728c901587edda5cdc79092a6432ad85d3e7vboxsync pvBuf = pvTmpBuf;
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cbBuf,
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync &pszValue, &u64Timestamp, &pszFlags,
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync &cbBuf);
aeca728c901587edda5cdc79092a6432ad85d3e7vboxsync }
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync if (VERR_BUFFER_OVERFLOW == rc)
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync /* Leave a bit of extra space to be safe */
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync cbBuf += 1024;
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync else
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync finish = true;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync }
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync if (VERR_TOO_MUCH_DATA == rc)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync VBoxControlError("Temporarily unable to retrieve the property\n");
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync else if (RT_FAILURE(rc) && rc != VERR_NOT_FOUND)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync VBoxControlError("Failed to retrieve the property value, error %Rrc\n", rc);
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * And display it on the guest console.
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
12767477bc2dbc7815e4784576a15c990f5590d3vboxsync if (VERR_NOT_FOUND == rc)
12767477bc2dbc7815e4784576a15c990f5590d3vboxsync RTPrintf("No value set!\n");
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync else if (RT_SUCCESS(rc))
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync {
fe5d5577da3c7bb5fd1b37ad108000b0825000d0vboxsync RTPrintf("Value: %s\n", pszValue);
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync if (fVerbose)
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync {
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync RTPrintf("Timestamp: %lld ns\n", u64Timestamp);
fe5d5577da3c7bb5fd1b37ad108000b0825000d0vboxsync RTPrintf("Flags: %s\n", pszFlags);
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync }
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync }
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync if (u32ClientId != 0)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync VbglR3GuestPropDisconnect(u32ClientId);
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync RTMemFree(pvBuf);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync}
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/**
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Writes a value to the guest property store.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * This is accessed through the "VBoxGuestPropSvc" HGCM service.
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync *
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync * @returns Command exit code.
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * @note see the command line API description for parameters
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE setGuestProperty(int argc, char *argv[])
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync{
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * Check the syntax. We can deduce the correct syntax from the number of
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * arguments.
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync bool usageOK = true;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync const char *pszName = NULL;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync const char *pszValue = NULL;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync const char *pszFlags = NULL;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync if (2 == argc)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync pszValue = argv[1];
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync }
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync else if (3 == argc)
cea6f586a9afef7aabf5d1cbe4d8ec929cfa4778vboxsync usageOK = false;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync else if (4 == argc)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync {
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync pszValue = argv[1];
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync if ( strcmp(argv[2], "-flags") != 0
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync && strcmp(argv[2], "--flags") != 0)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync usageOK = false;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync pszFlags = argv[3];
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync }
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync else if (argc != 1)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync usageOK = false;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync if (!usageOK)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync {
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync usage(GUEST_PROP);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
7e7e58609ea74ab895389ea8c2a3639557ecb753vboxsync /* This is always needed. */
7e7e58609ea74ab895389ea8c2a3639557ecb753vboxsync pszName = argv[0];
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * Do the actual setting.
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync uint32_t u32ClientId = 0;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int rc = VINF_SUCCESS;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync rc = VbglR3GuestPropConnect(&u32ClientId);
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync if (RT_FAILURE(rc))
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync else
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync if (pszFlags != NULL)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync rc = VbglR3GuestPropWrite(u32ClientId, pszName, pszValue, pszFlags);
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync else
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync rc = VbglR3GuestPropWriteValue(u32ClientId, pszName, pszValue);
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync if (RT_FAILURE(rc))
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync VBoxControlError("Failed to store the property value, error %Rrc\n", rc);
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync if (u32ClientId != 0)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync VbglR3GuestPropDisconnect(u32ClientId);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync}
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync/**
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * Deletes a guest property from the guest property store.
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * This is accessed through the "VBoxGuestPropSvc" HGCM service.
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync *
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * @returns Command exit code.
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * @note see the command line API description for parameters
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync */
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsyncstatic RTEXITCODE deleteGuestProperty(int argc, char *argv[])
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync{
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync /*
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * Check the syntax. We can deduce the correct syntax from the number of
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * arguments.
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync */
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync bool usageOK = true;
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync const char *pszName = NULL;
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync if (argc < 1)
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync usageOK = false;
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync if (!usageOK)
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync {
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync usage(GUEST_PROP);
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync return RTEXITCODE_FAILURE;
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync }
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync /* This is always needed. */
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync pszName = argv[0];
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync /*
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * Do the actual setting.
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync */
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync uint32_t u32ClientId = 0;
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync int rc = VbglR3GuestPropConnect(&u32ClientId);
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync if (RT_FAILURE(rc))
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync else
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync {
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync rc = VbglR3GuestPropDelete(u32ClientId, pszName);
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync if (RT_FAILURE(rc))
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync VBoxControlError("Failed to delete the property value, error %Rrc\n", rc);
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync }
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync if (u32ClientId != 0)
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync VbglR3GuestPropDisconnect(u32ClientId);
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync}
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync/**
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync * Enumerates the properties in the guest property store.
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync * This is accessed through the "VBoxGuestPropSvc" HGCM service.
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync *
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync * @returns Command exit code.
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync * @note see the command line API description for parameters
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE enumGuestProperty(int argc, char *argv[])
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync{
9ee72227058430bcead5831131741b5dc1601f00vboxsync /*
9ee72227058430bcead5831131741b5dc1601f00vboxsync * Check the syntax. We can deduce the correct syntax from the number of
9ee72227058430bcead5831131741b5dc1601f00vboxsync * arguments.
9ee72227058430bcead5831131741b5dc1601f00vboxsync */
9ee72227058430bcead5831131741b5dc1601f00vboxsync char const * const *papszPatterns = NULL;
e454bad3fb59eb6e94e98f2bb655323b7acaddf9vboxsync uint32_t cPatterns = 0;
9ee72227058430bcead5831131741b5dc1601f00vboxsync if ( argc > 1
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync && ( strcmp(argv[0], "-patterns") == 0
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync || strcmp(argv[0], "--patterns") == 0))
9ee72227058430bcead5831131741b5dc1601f00vboxsync {
9ee72227058430bcead5831131741b5dc1601f00vboxsync papszPatterns = (char const * const *)&argv[1];
9ee72227058430bcead5831131741b5dc1601f00vboxsync cPatterns = argc - 1;
9ee72227058430bcead5831131741b5dc1601f00vboxsync }
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync else if (argc != 0)
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync {
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync usage(GUEST_PROP);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync }
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync
9ee72227058430bcead5831131741b5dc1601f00vboxsync /*
9ee72227058430bcead5831131741b5dc1601f00vboxsync * Do the actual enumeration.
9ee72227058430bcead5831131741b5dc1601f00vboxsync */
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync uint32_t u32ClientId = 0;
9ee72227058430bcead5831131741b5dc1601f00vboxsync int rc = VbglR3GuestPropConnect(&u32ClientId);
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync if (RT_SUCCESS(rc))
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync {
9ee72227058430bcead5831131741b5dc1601f00vboxsync PVBGLR3GUESTPROPENUM pHandle;
9ee72227058430bcead5831131741b5dc1601f00vboxsync const char *pszName, *pszValue, *pszFlags;
9ee72227058430bcead5831131741b5dc1601f00vboxsync uint64_t u64Timestamp;
9ee72227058430bcead5831131741b5dc1601f00vboxsync
9ee72227058430bcead5831131741b5dc1601f00vboxsync rc = VbglR3GuestPropEnum(u32ClientId, papszPatterns, cPatterns, &pHandle,
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync &pszName, &pszValue, &u64Timestamp, &pszFlags);
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync if (RT_SUCCESS(rc))
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync {
ada022f71e6728d4f2b15e643d35aa94992656c7vboxsync while (RT_SUCCESS(rc) && pszName)
9ee72227058430bcead5831131741b5dc1601f00vboxsync {
9ee72227058430bcead5831131741b5dc1601f00vboxsync RTPrintf("Name: %s, value: %s, timestamp: %lld, flags: %s\n",
9ee72227058430bcead5831131741b5dc1601f00vboxsync pszName, pszValue, u64Timestamp, pszFlags);
9ee72227058430bcead5831131741b5dc1601f00vboxsync
9ee72227058430bcead5831131741b5dc1601f00vboxsync rc = VbglR3GuestPropEnumNext(pHandle, &pszName, &pszValue, &u64Timestamp, &pszFlags);
9ee72227058430bcead5831131741b5dc1601f00vboxsync if (RT_FAILURE(rc))
9ee72227058430bcead5831131741b5dc1601f00vboxsync VBoxControlError("Error while enumerating guest properties: %Rrc\n", rc);
9ee72227058430bcead5831131741b5dc1601f00vboxsync }
9ee72227058430bcead5831131741b5dc1601f00vboxsync
9ee72227058430bcead5831131741b5dc1601f00vboxsync VbglR3GuestPropEnumFree(pHandle);
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync }
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync else if (VERR_NOT_FOUND == rc)
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync RTPrintf("No properties found.\n");
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync else
2a287e364d33444fd0aa85fb2a165d84b7b64586vboxsync VBoxControlError("Failed to enumerate the guest properties! Error: %Rrc\n", rc);
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync VbglR3GuestPropDisconnect(u32ClientId);
9ee72227058430bcead5831131741b5dc1601f00vboxsync }
9ee72227058430bcead5831131741b5dc1601f00vboxsync else
9ee72227058430bcead5831131741b5dc1601f00vboxsync VBoxControlError("Failed to connect to the guest property service! Error: %Rrc\n", rc);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync}
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync/**
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * Waits for notifications of changes to guest properties.
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * This is accessed through the "VBoxGuestPropSvc" HGCM service.
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync *
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync * @returns Command exit code.
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * @note see the command line API description for parameters
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE waitGuestProperty(int argc, char **argv)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync{
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync using namespace guestProp;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync /*
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * Handle arguments
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync */
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync const char *pszPatterns = NULL;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync uint64_t u64TimestampIn = 0;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync uint32_t u32Timeout = RT_INDEFINITE_WAIT;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync bool usageOK = true;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync if (argc < 1)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync usageOK = false;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync pszPatterns = argv[0];
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync for (int i = 1; usageOK && i < argc; ++i)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync {
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync if ( strcmp(argv[i], "-timeout") == 0
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync || strcmp(argv[i], "--timeout") == 0)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync {
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync if ( i + 1 >= argc
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync || RTStrToUInt32Full(argv[i + 1], 10, &u32Timeout)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync != VINF_SUCCESS
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync )
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync usageOK = false;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync else
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync ++i;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync }
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync else if ( strcmp(argv[i], "-timestamp") == 0
60124f8bdc1927b7bb28d8bb4fad7bbdd93811c9vboxsync || strcmp(argv[i], "--timestamp") == 0)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync {
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync if ( i + 1 >= argc
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync || RTStrToUInt64Full(argv[i + 1], 10, &u64TimestampIn)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync != VINF_SUCCESS
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync )
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync usageOK = false;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync else
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync ++i;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync }
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync else
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync usageOK = false;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync }
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync if (!usageOK)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync {
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync usage(GUEST_PROP);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync }
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync /*
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * Connect to the service
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync */
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync uint32_t u32ClientId = 0;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync int rc = VINF_SUCCESS;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync rc = VbglR3GuestPropConnect(&u32ClientId);
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync if (RT_FAILURE(rc))
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync /*
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync * Retrieve the notification from the host
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync */
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync char *pszName = NULL;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync char *pszValue = NULL;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync uint64_t u64TimestampOut = 0;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync char *pszFlags = NULL;
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 void *pvBuf = NULL;
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 ++i)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync {
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync void *pvTmpBuf = RTMemRealloc(pvBuf, cbBuf);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync if (NULL == pvTmpBuf)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync {
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync rc = VERR_NO_MEMORY;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VBoxControlError("Out of memory\n");
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync }
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync else
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync {
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync pvBuf = pvTmpBuf;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync rc = VbglR3GuestPropWait(u32ClientId, pszPatterns, pvBuf, cbBuf,
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync u64TimestampIn, u32Timeout,
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync &pszName, &pszValue, &u64TimestampOut,
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync &pszFlags, &cbBuf);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync }
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync if (VERR_BUFFER_OVERFLOW == rc)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync /* Leave a bit of extra space to be safe */
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync cbBuf += 1024;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync else
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync finish = true;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync if (rc == VERR_TOO_MUCH_DATA)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VBoxControlError("Temporarily unable to get a notification\n");
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync else if (rc == VERR_INTERRUPTED)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VBoxControlError("The request timed out or was interrupted\n");
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync#ifndef RT_OS_WINDOWS /* Windows guests do not do this right */
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync else if (RT_FAILURE(rc) && rc != VERR_NOT_FOUND)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VBoxControlError("Failed to get a notification, error %Rrc\n", rc);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync#endif
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync }
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * And display it on the guest console.
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync if (VERR_NOT_FOUND == rc)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync RTPrintf("No value set!\n");
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync else if (rc == VERR_BUFFER_OVERFLOW)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync RTPrintf("Internal error: unable to determine the size of the data!\n");
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync else if (RT_SUCCESS(rc))
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync {
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync RTPrintf("Name: %s\n", pszName);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync RTPrintf("Value: %s\n", pszValue);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync RTPrintf("Timestamp: %lld ns\n", u64TimestampOut);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync RTPrintf("Flags: %s\n", pszFlags);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync }
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync if (u32ClientId != 0)
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync VbglR3GuestPropDisconnect(u32ClientId);
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync RTMemFree(pvBuf);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync}
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync/**
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * Access the guest property store through the "VBoxGuestPropSvc" HGCM
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * service.
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync *
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * @returns 0 on success, 1 on failure
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync * @note see the command line API description for parameters
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE handleGuestProperty(int argc, char *argv[])
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync{
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync if (0 == argc)
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync {
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync usage(GUEST_PROP);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync if (!strcmp(argv[0], "get"))
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync return getGuestProperty(argc - 1, argv + 1);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync else if (!strcmp(argv[0], "set"))
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync return setGuestProperty(argc - 1, argv + 1);
c24e992c75b7bae5c1a769f0063ba69e037351cevboxsync else if (!strcmp(argv[0], "delete") || !strcmp(argv[0], "unset"))
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync return deleteGuestProperty(argc - 1, argv + 1);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync else if (!strcmp(argv[0], "enumerate"))
62592281fc2971692c6755401b5ce1ed61b96d7cvboxsync return enumGuestProperty(argc - 1, argv + 1);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync else if (!strcmp(argv[0], "wait"))
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync return waitGuestProperty(argc - 1, argv + 1);
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync /* else */
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync usage(GUEST_PROP);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync}
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync#endif
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync#ifdef VBOX_WITH_SHARED_FOLDERS
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync/**
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync * Lists the Shared Folders provided by the host.
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE listSharedFolders(int argc, char **argv)
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync{
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync bool usageOK = true;
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync bool fOnlyShowAutoMount = false;
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync if (argc == 1)
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync {
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync if ( !strcmp(argv[0], "-automount")
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync || !strcmp(argv[0], "--automount"))
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync fOnlyShowAutoMount = true;
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync else
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync usageOK = false;
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync }
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync else if (argc > 1)
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync usageOK = false;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync if (!usageOK)
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync {
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync usage(GUEST_SHAREDFOLDERS);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync }
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync uint32_t u32ClientId;
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync int rc = VbglR3SharedFolderConnect(&u32ClientId);
2410b4077c45a0d14a6390e35a3897a7abca542avboxsync if (RT_FAILURE(rc))
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync VBoxControlError("Failed to connect to the shared folder service, error %Rrc\n", rc);
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync else
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync {
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync PVBGLR3SHAREDFOLDERMAPPING paMappings;
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync uint32_t cMappings;
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync rc = VbglR3SharedFolderGetMappings(u32ClientId, fOnlyShowAutoMount,
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync &paMappings, &cMappings);
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync if (RT_SUCCESS(rc))
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync {
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync if (fOnlyShowAutoMount)
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync RTPrintf("Auto-mounted Shared Folder mappings (%u):\n\n", cMappings);
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync else
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync RTPrintf("Shared Folder mappings (%u):\n\n", cMappings);
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync for (uint32_t i = 0; i < cMappings; i++)
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync {
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync char *pszName;
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync rc = VbglR3SharedFolderGetName(u32ClientId, paMappings[i].u32Root, &pszName);
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync if (RT_SUCCESS(rc))
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync {
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync RTPrintf("%02u - %s\n", i + 1, pszName);
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync RTStrFree(pszName);
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync }
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync else
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync VBoxControlError("Error while getting the shared folder name for root node = %u, rc = %Rrc\n",
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync paMappings[i].u32Root, rc);
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync }
0fb42f85d3c82308466ce750f2126a11f56005dfvboxsync if (!cMappings)
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync RTPrintf("No Shared Folders available.\n");
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync VbglR3SharedFolderFreeMappings(paMappings);
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync }
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync else
ba31bc205e96548d3557ae82087dc020a52b6a0avboxsync VBoxControlError("Error while getting the shared folder mappings, rc = %Rrc\n", rc);
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync VbglR3SharedFolderDisconnect(u32ClientId);
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync}
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync/**
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync * Handles Shared Folders control.
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync *
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync * @returns 0 on success, 1 on failure
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync * @note see the command line API description for parameters
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync * (r=bird: yeah, right. The API description contains nil about params)
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsyncstatic RTEXITCODE handleSharedFolder(int argc, char *argv[])
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync{
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync if (0 == argc)
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync {
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync usage(GUEST_SHAREDFOLDERS);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync if (!strcmp(argv[0], "list"))
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync return listSharedFolders(argc - 1, argv + 1);
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync /* else */
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync usage(GUEST_SHAREDFOLDERS);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTEXITCODE_FAILURE;
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync}
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync#endif
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
683bc538c5d6598479b7da2ad464939422d449d6vboxsync#if !defined(VBOX_CONTROL_TEST)
b608f15cba5036182124f1eee68b761535aa6d14vboxsync/**
02b7bb9ce9337224d8099a0dd2fc2323ef5ec3a0vboxsync * @callback_method_impl{FNVBOXCTRLCMDHANDLER, Command: writecoredump}
b608f15cba5036182124f1eee68b761535aa6d14vboxsync */
b608f15cba5036182124f1eee68b761535aa6d14vboxsyncstatic RTEXITCODE handleWriteCoreDump(int argc, char *argv[])
b608f15cba5036182124f1eee68b761535aa6d14vboxsync{
b608f15cba5036182124f1eee68b761535aa6d14vboxsync int rc = VbglR3WriteCoreDump();
b608f15cba5036182124f1eee68b761535aa6d14vboxsync if (RT_SUCCESS(rc))
b608f15cba5036182124f1eee68b761535aa6d14vboxsync {
bca204eec2cdfdbbbf15d9cf2be05d4be785febevboxsync RTPrintf("Guest core dump successful.\n");
b608f15cba5036182124f1eee68b761535aa6d14vboxsync return RTEXITCODE_SUCCESS;
b608f15cba5036182124f1eee68b761535aa6d14vboxsync }
b608f15cba5036182124f1eee68b761535aa6d14vboxsync else
b608f15cba5036182124f1eee68b761535aa6d14vboxsync {
bca204eec2cdfdbbbf15d9cf2be05d4be785febevboxsync VBoxControlError("Error while taking guest core dump. rc=%Rrc\n", rc);
b608f15cba5036182124f1eee68b761535aa6d14vboxsync return RTEXITCODE_FAILURE;
b608f15cba5036182124f1eee68b761535aa6d14vboxsync }
b608f15cba5036182124f1eee68b761535aa6d14vboxsync}
683bc538c5d6598479b7da2ad464939422d449d6vboxsync#endif
b608f15cba5036182124f1eee68b761535aa6d14vboxsync
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync/**
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync * @callback_method_impl{FNVBOXCTRLCMDHANDLER, Command: help}
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync */
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsyncstatic RTEXITCODE handleDpc(int argc, char *argv[])
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync{
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync# ifndef VBOX_CONTROL_TEST
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync int rc;
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync for (int i = 0; i < 30; i++)
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync {
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_DPC_LATENCY_CHECKER, NULL, 0);
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync if (RT_FAILURE(rc))
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync break;
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync RTPrintf("%d\n", i);
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync }
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync# else
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync int rc = VERR_NOT_IMPLEMENTED;
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync# endif
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync if (RT_FAILURE(rc))
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync return VBoxControlError("Error. rc=%Rrc\n", rc);
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync RTPrintf("Samples collection completed.\n");
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync return RTEXITCODE_SUCCESS;
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync}
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync#endif /* VBOX_WITH_DPC_LATENCY_CHECKER */
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync/**
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync * @callback_method_impl{FNVBOXCTRLCMDHANDLER, Command: writelog}
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync */
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsyncstatic RTEXITCODE handleWriteLog(int argc, char *argv[])
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync{
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync static const RTGETOPTDEF s_aOptions[] =
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync {
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync { "--no-newline", 'n', RTGETOPT_REQ_NOTHING },
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync };
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync bool fNoNewline = false;
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync RTGETOPTSTATE GetOptState;
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync int rc = RTGetOptInit(&GetOptState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions),
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync 0 /*iFirst*/, RTGETOPTINIT_FLAGS_OPTS_FIRST);
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync if (RT_SUCCESS(rc))
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync {
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync RTGETOPTUNION ValueUnion;
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync int ch;
37a7059c2242ab72304fd217c74bb54127ae35a3vboxsync while ((ch = RTGetOpt(&GetOptState, &ValueUnion)) != 0)
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync {
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync switch (ch)
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync {
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync case VINF_GETOPT_NOT_OPTION:
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync {
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync size_t cch = strlen(ValueUnion.psz);
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync if ( fNoNewline
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync || (cch > 0 && ValueUnion.psz[cch - 1] == '\n') )
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync rc = VbglR3WriteLog(ValueUnion.psz, cch);
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync else
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync {
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync char *pszDup = (char *)RTMemDupEx(ValueUnion.psz, cch, 2);
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync if (RT_SUCCESS(rc))
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync {
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync pszDup[cch++] = '\n';
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync pszDup[cch] = '\0';
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync rc = VbglR3WriteLog(pszDup, cch);
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync RTMemFree(pszDup);
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync }
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync else
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync rc = VERR_NO_MEMORY;
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync }
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync if (RT_FAILURE(rc))
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync return VBoxControlError("VbglR3WriteLog: %Rrc", rc);
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync break;
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync }
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync case 'n':
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync fNoNewline = true;
0ae9e1af5e46486d76a96e4ff59aaf09f51b4027vboxsync break;
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync case 'h': return usage(WRITE_LOG);
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync case 'V': return printVersion();
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync default:
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync return VBoxCtrlGetOptError(ch, &ValueUnion);
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync }
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync }
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync }
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync else
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync return VBoxControlError("RTGetOptInit: %Rrc", rc);
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync return RTEXITCODE_SUCCESS;
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync}
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync/**
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync * @callback_method_impl{FNVBOXCTRLCMDHANDLER, Command: takesnapshot}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync */
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsyncstatic RTEXITCODE handleTakeSnapshot(int argc, char *argv[])
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync{
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync //VbglR3VmTakeSnapshot(argv[0], argv[1]);
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync return VBoxControlError("not implemented");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync/**
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync * @callback_method_impl{FNVBOXCTRLCMDHANDLER, Command: savestate}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync */
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsyncstatic RTEXITCODE handleSaveState(int argc, char *argv[])
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync{
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync //VbglR3VmSaveState();
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync return VBoxControlError("not implemented");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync/**
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync * @callback_method_impl{FNVBOXCTRLCMDHANDLER, Command: suspend|pause}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync */
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsyncstatic RTEXITCODE handleSuspend(int argc, char *argv[])
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync{
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync //VbglR3VmSuspend();
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync return VBoxControlError("not implemented");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync/**
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync * @callback_method_impl{FNVBOXCTRLCMDHANDLER, Command: poweroff|powerdown}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync */
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsyncstatic RTEXITCODE handlePowerOff(int argc, char *argv[])
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync{
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync //VbglR3VmPowerOff();
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync return VBoxControlError("not implemented");
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync/**
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync * @callback_method_impl{FNVBOXCTRLCMDHANDLER, Command: version}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync */
d09ef734532edd0e40ffe9a471e0a31152572065vboxsyncstatic RTEXITCODE handleVersion(int argc, char *argv[])
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync{
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync if (argc)
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync return VBoxControlSyntaxError("getversion does not take any arguments");
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync return printVersion();
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync}
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync/**
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync * @callback_method_impl{FNVBOXCTRLCMDHANDLER, Command: help}
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync */
d09ef734532edd0e40ffe9a471e0a31152572065vboxsyncstatic RTEXITCODE handleHelp(int argc, char *argv[])
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync{
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync /* ignore arguments for now. */
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync usage();
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync return RTEXITCODE_SUCCESS;
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync}
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync
258511aa4b33ed962c316ae5934e400edf09d3d6vboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** command handler type */
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsynctypedef DECLCALLBACK(RTEXITCODE) FNVBOXCTRLCMDHANDLER(int argc, char *argv[]);
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsynctypedef FNVBOXCTRLCMDHANDLER *PFNVBOXCTRLCMDHANDLER;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** The table of all registered command handlers. */
b46baa80c8be5ebac38e73ce6136d67146cc80d6vboxsyncstruct COMMANDHANDLER
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync{
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync const char *pszCommand;
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync PFNVBOXCTRLCMDHANDLER pfnHandler;
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync} g_aCommandHandlers[] =
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync{
c448f9b0b8382e4665c9700488002c45a9b3f137vboxsync#if defined(RT_OS_WINDOWS) && !defined(VBOX_CONTROL_TEST)
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync { "getvideoacceleration", handleGetVideoAcceleration },
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync { "setvideoacceleration", handleSetVideoAcceleration },
3d5847db3882b6af81db232f55ee404b22141e5dvboxsync { "videoflags", handleVideoFlags },
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync { "listcustommodes", handleListCustomModes },
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync { "addcustommode", handleAddCustomMode },
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync { "removecustommode", handleRemoveCustomMode },
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync { "setvideomode", handleSetVideoMode },
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#endif
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync#ifdef VBOX_WITH_GUEST_PROPS
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync { "guestproperty", handleGuestProperty },
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync#endif
f1301dd8b6870b5a25c7dbdd46e0a0671bb62031vboxsync#ifdef VBOX_WITH_SHARED_FOLDERS
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync { "sharedfolder", handleSharedFolder },
b608f15cba5036182124f1eee68b761535aa6d14vboxsync#endif
b608f15cba5036182124f1eee68b761535aa6d14vboxsync#if !defined(VBOX_CONTROL_TEST)
b608f15cba5036182124f1eee68b761535aa6d14vboxsync { "writecoredump", handleWriteCoreDump },
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync#endif
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
63b5b2edb3bb80b9bdef27c089e87072f6175b42vboxsync { "dpc", handleDpc },
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync#endif
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync { "writelog", handleWriteLog },
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync { "takesnapshot", handleTakeSnapshot },
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync { "savestate", handleSaveState },
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync { "suspend", handleSuspend },
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync { "pause", handleSuspend },
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync { "poweroff", handlePowerOff },
4b4dcfe69a693fa32dd64da3d9ea88e996ca1bf5vboxsync { "powerdown", handlePowerOff },
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync { "getversion", handleVersion },
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync { "version", handleVersion },
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync { "help", handleHelp }
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync};
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync/** Main function */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsyncint main(int argc, char **argv)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync{
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** The application's global return code */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** An IPRT return code for local use */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync int rrc = VINF_SUCCESS;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** The index of the command line argument we are currently processing */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync int iArg = 1;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** Should we show the logo text? */
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync bool fShowLogo = true;
e68e2431dbeeab80792bbd9b1c64a68fc3358d0evboxsync /** Should we print the usage after the logo? For the -help switch. */
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync bool fDoHelp = false;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /** Will we be executing a command or just printing information? */
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync bool fOnlyInfo = false;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
230bd8589bba39933ac5ec21482d6186d675e604vboxsync rrc = RTR3InitExe(argc, &argv, 0);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync if (RT_FAILURE(rrc))
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return RTMsgInitFailure(rrc);
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * Start by handling command line switches
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync /** @todo RTGetOpt conversion of the whole file. */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync bool done = false; /**< Are we finished with handling switches? */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync while (!done && (iArg < argc))
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync if ( !strcmp(argv[iArg], "-V")
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync || !strcmp(argv[iArg], "-v")
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync || !strcmp(argv[iArg], "--version")
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync || !strcmp(argv[iArg], "-version")
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync )
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync {
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync /* Print version number, and do nothing else. */
6b0577f7fc626b475f5177a9049817b5eea6c7f6vboxsync printVersion();
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync fOnlyInfo = true;
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync fShowLogo = false;
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync done = true;
e157a8db78517b3361d2f3bedc398d6a75b7f0dfvboxsync }
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync else if ( !strcmp(argv[iArg], "-nologo")
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync || !strcmp(argv[iArg], "--nologo"))
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync fShowLogo = false;
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync else if ( !strcmp(argv[iArg], "-help")
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync || !strcmp(argv[iArg], "--help"))
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync fOnlyInfo = true;
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync fDoHelp = true;
24b9d11a24f96f5da0351475e0b6486ec4cb0d30vboxsync done = true;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync else
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /* We have found an argument which isn't a switch. Exit to the
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync * command processing bit. */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync done = true;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync if (!done)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync ++iArg;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * Find the application name, show our logo if the user hasn't suppressed it,
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * and show the usage if the user asked us to
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync g_pszProgName = RTPathFilename(argv[0]);
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync if (fShowLogo)
d653df42608a5162103b5d3c6bc712d9bb6ce39dvboxsync RTPrintf(VBOX_PRODUCT " Guest Additions Command Line Management Interface Version "
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync VBOX_VERSION_STRING "\n"
b32ff101ade65c2831c31247c411cdc8234fa7fcvboxsync "(C) 2008-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
03aef08d59dd179fd178a35f445e731788896cabvboxsync "All rights reserved.\n\n");
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync if (fDoHelp)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync usage();
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * Do global initialisation for the programme if we will be handling a command
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync if (!fOnlyInfo)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync rrc = VbglR3Init();
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync if (RT_FAILURE(rrc))
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync VBoxControlError("Could not contact the host system. Make sure that you are running this\n"
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync "application inside a VirtualBox guest system, and that you have sufficient\n"
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync "user permissions.\n");
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync rcExit = RTEXITCODE_FAILURE;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * Now look for an actual command in the argument list and handle it.
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync if (!fOnlyInfo && rcExit == RTEXITCODE_SUCCESS)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync if (argc > iArg)
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync /*
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync * Try locate the command and execute it, complain if not found.
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync */
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync unsigned i;
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync for (i = 0; i < RT_ELEMENTS(g_aCommandHandlers); i++)
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync if (!strcmp(argv[iArg], g_aCommandHandlers[i].pszCommand))
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync {
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync rcExit = g_aCommandHandlers[i].pfnHandler(argc - iArg - 1, argv + iArg + 1);
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync break;
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync }
d09ef734532edd0e40ffe9a471e0a31152572065vboxsync if (i >= RT_ELEMENTS(g_aCommandHandlers))
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync rcExit = RTEXITCODE_FAILURE;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync usage();
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync else
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync {
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync /* The user didn't specify a command. */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync rcExit = RTEXITCODE_FAILURE;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync usage();
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync }
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync /*
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync * And exit, returning the status
4f4b2d99ad789c62e8d25156869ee7ea741de8d0vboxsync */
810e2dff19cb2bda7ee6f98fa1a9e25ca1bb32d8vboxsync return rcExit;
c785dbab313731d1f4662b4684c0808cc14703dbvboxsync}
682a27d94b9116c719038882487b99053985f91avboxsync