VBoxControl.cpp revision b357df727b216b85d4517efecf466a7b14c2e80c
/** @file
*
* VBoxControl - Guest Additions Utility
*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <malloc.h>
#include <VBox/VBoxGuest.h>
#ifdef VBOX_WITH_INFO_SVC
#endif /* VBOX_WITH_INFO_SVC */
void printHelp()
{
printf("VBoxControl getversion\n"
"\n"
"VBoxControl getvideoacceleration\n"
"\n"
"VBoxControl setvideoacceleration <on|off>\n"
"\n"
"VBoxControl listcustommodes\n"
"\n"
"VBoxControl addcustommode <width> <height> <bpp>\n"
"\n"
"VBoxControl removecustommode <width> <height> <bpp>\n"
"\n"
"VBoxControl setvideomode <width> <height> <bpp> <screen>\n"
"\n"
#ifdef VBOX_WITH_INFO_SVC
"VBoxControl getguestproperty <key>\n"
"\n"
"VBoxControl setguestproperty <key> [<value>] (no value to delete)\n"
#endif /* VBOX_WITH_INFO_SVC */
);
}
void printVersion()
{
}
#if defined(DEBUG) || defined(LOG_ENABLED)
#else
#define dprintf(a) do {} while (0)
#endif /* DEBUG */
LONG (WINAPI * gpfnChangeDisplaySettingsEx)(LPCTSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);
{
unsigned i;
for (i = 0; i < nRects; i++)
{
{
return i;
}
}
return ~0;
}
{
unsigned i;
for (i = 0; i < nRects; i++)
{
{
return i;
}
}
return ~0;
}
{
unsigned i;
for (i = 0; i < nRects; i++)
{
{
return i;
}
}
return ~0;
}
{
unsigned i;
for (i = 0; i < nRects; i++)
{
{
return i;
}
}
return ~0;
}
void resizeRect(RECTL *paRects, unsigned nRects, unsigned iPrimary, unsigned iResized, int NewWidth, int NewHeight)
{
paNewRects[iResized].bottom += NewHeight - (paNewRects[iResized].bottom - paNewRects[iResized].top);
/* Verify all pairs of originally adjacent rectangles for all 4 directions.
* If the pair has a "good" delta (that is the first rectangle intersects the second)
* at a direction and the second rectangle is not primary one (which can not be moved),
* move the second rectangle to make it adjacent to the first one.
*/
/* X positive. */
unsigned iRect;
{
/* Find the next adjacent original rect in x positive direction. */
{
continue;
}
/* Check whether there is an X intesection between these adjacent rects in the new rectangles
* and fix the intersection if delta is "good".
*/
if (delta > 0)
{
dprintf(("XP intersection right %d left %d, diff %d\n",
delta));
}
}
/* X negative. */
{
/* Find the next adjacent original rect in x negative direction. */
{
continue;
}
/* Check whether there is an X intesection between these adjacent rects in the new rectangles
* and fix the intersection if delta is "good".
*/
if (delta < 0)
{
dprintf(("XN intersection left %d right %d, diff %d\n",
delta));
}
}
/* Y positive (in the computer sence, top->down). */
{
/* Find the next adjacent original rect in y positive direction. */
{
continue;
}
/* Check whether there is an Y intesection between these adjacent rects in the new rectangles
* and fix the intersection if delta is "good".
*/
if (delta > 0)
{
dprintf(("YP intersection bottom %d top %d, diff %d\n",
delta));
}
}
/* Y negative (in the computer sence, down->top). */
{
/* Find the next adjacent original rect in x negative direction. */
{
continue;
}
/* Check whether there is an Y intesection between these adjacent rects in the new rectangles
* and fix the intersection if delta is "good".
*/
if (delta < 0)
{
dprintf(("YN intersection top %d bottom %d, diff %d\n",
delta));
}
}
return;
}
/* Returns TRUE to try again. */
{
/* Find out how many display devices the system has */
DWORD NumDevices = 0;
DWORD i = 0;
{
{
NumDevices++;
}
{
NumDevices++;
}
i++;
}
{
return FALSE;
}
/* Fetch information about current devices and modes. */
DWORD DevPrimaryNum = 0;
i = 0;
{
{
bFetchDevice = TRUE;
}
{
bFetchDevice = TRUE;
}
if (bFetchDevice)
{
if (DevNum >= NumDevices)
{
return FALSE;
}
{
return FALSE;
}
dprintf(("%dx%d at %d,%d\n",
DevNum++;
}
i++;
}
if (Width == 0)
{
}
if (Height == 0)
{
}
/* Check whether a mode reset or a change is requested. */
if ( !fModeReset
{
dprintf(("VBoxDisplayThread : already at desired resolution.\n"));
return FALSE;
}
#ifdef dprintf
for (i = 0; i < NumDevices; i++)
{
dprintf(("[%d]: %d,%d %dx%d\n",
}
#endif /* dprintf */
/* Without this, Windows will not ask the miniport for its
* mode table but uses an internal cache instead.
*/
/* Assign the new rectangles to displays. */
for (i = 0; i < NumDevices; i++)
{
if ( i == Id
&& BitsPerPixel != 0)
{
}
}
/* A second call to ChangeDisplaySettings updates the monitor. */
{
/* Successfully set new video mode or our driver can not set the requested mode. Stop trying. */
return FALSE;
}
/* Retry the request. */
return TRUE;
}
{
{
printf("Error: not enough parameters!\n");
return;
}
if (argc == 4)
{
}
if (hUser)
{
*(uintptr_t *)&gpfnChangeDisplaySettingsEx = (uintptr_t)GetProcAddress(hUser, "ChangeDisplaySettingsExA");
{
/* The screen index is 0 based in the ResizeDisplayDevice call. */
/* Horizontal resolution must be a multiple of 8, round down. */
xres &= ~0x7;
}
}
}
{
HKEY hkeyDeviceMap = 0;
status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\VIDEO", 0, KEY_READ, &hkeyDeviceMap);
{
printf("Error opening video device map registry key!\n");
return 0;
}
char szVideoLocation[256];
szVideoLocation[0] = 0;
status = RegQueryValueExA(hkeyDeviceMap, "\\Device\\Video0", NULL, &dwKeyType, (LPBYTE)szVideoLocation, &len);
/*
* This value will start with a weird value: \REGISTRY\Machine
* Make sure this is true.
*/
if ( (status == ERROR_SUCCESS)
{
/* open that branch */
status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, &szVideoLocation[18], 0, KEY_READ | (writable ? KEY_WRITE : 0), &hkeyVideo);
}
else
{
}
return hkeyVideo;
}
{
if (hkeyVideo)
{
/* query the actual value */
status = RegQueryValueExA(hkeyVideo, "EnableVideoAccel", NULL, &dwKeyType, (LPBYTE)&fAcceleration, &len);
if (status != ERROR_SUCCESS)
printf("Video acceleration: default\n");
else
}
}
{
/* must have exactly one argument: the new offset */
if ( (argc != 1)
{
printf("Error: invalid video acceleration status!\n");
return;
}
hkeyVideo = getVideoKey(true);
if (hkeyVideo)
{
int fAccel = 0;
fAccel = 1;
/* set a new value */
status = RegSetValueExA(hkeyVideo, "EnableVideoAccel", 0, REG_DWORD, (LPBYTE)&fAccel, sizeof(fAccel));
if (status != ERROR_SUCCESS)
{
}
}
}
#define MAX_CUSTOM_MODES 128
/* the table of custom modes */
struct
{
} customModes[MAX_CUSTOM_MODES] = {0};
{
int curMode = 0;
/* null out the table */
do
{
char valueName[20];
if (status != ERROR_SUCCESS)
break;
if (status != ERROR_SUCCESS)
break;
if (status != ERROR_SUCCESS)
break;
/* check if the mode is OK */
&& ( (bpp != 16)
|| (bpp != 24)
|| (bpp != 32)))
break;
/* add mode to table */
++curMode;
if (curMode >= MAX_CUSTOM_MODES)
break;
} while(1);
}
{
int tableIndex = 0;
int modeIndex = 0;
/* first remove all values */
for (int i = 0; i < MAX_CUSTOM_MODES; i++)
{
char valueName[20];
}
do
{
if (tableIndex >= MAX_CUSTOM_MODES)
break;
/* is the table entry present? */
{
tableIndex++;
continue;
}
printf("writing mode %d (%dx%dx%d)\n", modeIndex, customModes[tableIndex].xres, customModes[tableIndex].yres, customModes[tableIndex].bpp);
char valueName[20];
modeIndex++;
tableIndex++;
} while(1);
}
{
if (argc != 0)
{
printf("Error: too many parameters!");
return;
}
if (hkeyVideo)
{
for (int i = 0; i < (sizeof(customModes) / sizeof(customModes[0])); i++)
{
if ( !customModes[i].xres
|| !customModes[i].yres
|| !customModes[i].bpp)
continue;
printf("Mode: %d x %d x %d\n",
}
}
}
{
if (argc != 3)
{
printf("Error: not enough parameters!\n");
return;
}
/** @todo better check including xres mod 8 = 0! */
&& ( (bpp != 16)
|| (bpp != 24)
|| (bpp != 32)))
{
printf("Error: invalid mode specified!\n");
return;
}
if (hkeyVideo)
{
int i;
int fModeExists = 0;
for (i = 0; i < MAX_CUSTOM_MODES; i++)
{
/* mode exists? */
)
{
fModeExists = 1;
}
}
if (!fModeExists)
{
for (i = 0; i < MAX_CUSTOM_MODES; i++)
{
/* item free? */
if (!customModes[i].xres)
{
break;
}
}
}
}
}
{
if (argc != 3)
{
printf("Error: not enough parameters!\n");
return;
}
if (hkeyVideo)
{
for (int i = 0; i < MAX_CUSTOM_MODES; i++)
{
/* correct item? */
{
printf("found mode at index %d\n", i);
break;
}
}
}
}
#ifdef VBOX_WITH_INFO_SVC
/**
* Open the VirtualBox guest device.
* @returns IPRT status value
* @param hDevice where to store the handle to the open device
*/
{
return VERR_INVALID_POINTER;
NULL,
NULL);
}
/**
* Connect to an HGCM service.
* @returns IPRT status code
* @param hDevice handle to the VBox device
* @param pszService the name of the service to connect to
* @param pu32ClientID where to store the connection handle
*/
{
return VERR_INVALID_POINTER;
int rc = VINF_SUCCESS;
return false;
if (DeviceIoControl (hDevice,
NULL))
else
if (RT_SUCCESS(rc))
return rc;
}
/** Set a 32bit unsigned integer parameter to an HGCM request */
{
}
/** Get a 32bit unsigned integer returned from an HGCM request */
{
{
return VINF_SUCCESS;
}
return VERR_INVALID_PARAMETER;
}
/** Set a pointer parameter to an HGCM request */
{
}
/** Make an HGCM call */
{
int rc = VERR_NOT_SUPPORTED;
if (DeviceIoControl (hDevice,
NULL))
rc = VINF_SUCCESS;
return rc;
}
/**
* @returns IPRT status code
* @param hDevice handle to the VBox device
* @param u32ClientID The client id returned by VbglR3ClipboardConnect().
* @param pszKey The registry key to save to.
* @param pszValue Where to store the value retrieved.
* @param cbValue The size of the buffer pszValue points to.
* @param pcbActual Where to store the required buffer size on
* overflow or the value size on success. A value
* of zero means that the property does not exist.
* Optional.
*/
{
using namespace svcInfo;
return VERR_INVALID_POINTER;
Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc2))
{
}
else
}
return rc;
}
/**
* @returns IPRT status code
* @param hDevice handle to the VBox device
* @param u32ClientID The client id returned by VbglR3ClipboardConnect().
* @param pszKey The registry key to save to.
* @param pszValue The value to store. If this is NULL then the key
* will be removed.
*/
{
using namespace svcInfo;
return VERR_INVALID_POINTER;
return VERR_INVALID_POINTER;
int rc;
{
Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
if (RT_SUCCESS(rc))
}
else
{
Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
if (RT_SUCCESS(rc))
}
return rc;
}
/** Disconnects from an HGCM service. */
{
if (u32ClientID == 0)
return;
NULL);
}
/**
* This is accessed through the "VBoxSharedInfoSvc" HGCM service.
*
* @returns IPRT status value
* @param key (string) the key which the value is stored under.
*/
{
uint32_t u32ClientID = 0;
int rc = VINF_SUCCESS;
if (argc != 1)
{
printHelp();
return 1;
}
if (!RT_SUCCESS(rc))
if (RT_SUCCESS(rc))
{
if (!RT_SUCCESS(rc))
}
if (RT_SUCCESS(rc))
{
if (!RT_SUCCESS(rc))
}
if (RT_SUCCESS(rc))
{
}
if (VERR_NOT_FOUND == rc)
RTPrintf("No value set!\n");
if (RT_SUCCESS(rc))
if (u32ClientID != 0)
if (hDevice != INVALID_HANDLE_VALUE)
return rc;
}
/**
* This is accessed through the "VBoxSharedInfoSvc" HGCM service.
*
* @returns IPRT status value
* @param key (string) the key which the value is stored under.
* @param value (string) the value to write. If empty, the key will be
* removed.
*/
{
uint32_t u32ClientID = 0;
int rc = VINF_SUCCESS;
{
printHelp();
return 1;
}
if (!RT_SUCCESS(rc))
{
if (!RT_SUCCESS(rc))
}
if (RT_SUCCESS(rc))
{
if (!RT_SUCCESS(rc))
}
if (RT_SUCCESS(rc))
{
if (!RT_SUCCESS(rc))
}
if (RT_SUCCESS(rc))
{
if (!RT_SUCCESS(rc))
}
if (u32ClientID != 0)
if (hDevice != INVALID_HANDLE_VALUE)
return rc;
}
#endif /* VBOX_WITH_INFO_SVC */
/**
* Main function
*/
{
if (argc < 2)
{
printHelp();
return 1;
}
/* todo: add better / stable command line handling here! */
/* determine which command */
{
printVersion();
}
{
}
{
}
{
}
{
}
{
}
{
}
#ifdef VBOX_WITH_INFO_SVC
{
}
{
}
#endif /* VBOX_WITH_INFO_SVC */
else
{
printHelp();
return 1;
}
return 0;
}