VBoxBFE.cpp revision cc74f15083bf80fbc96723a89faa06c15d0dead8
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * Basic Frontend (BFE): VBoxBFE main routines.
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * VBoxBFE is a limited frontend that sits directly on the Virtual Machine
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * Manager (VMM) and does _not_ use COM to communicate.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * On Linux and Windows, VBoxBFE is based on SDL; on L4 it's based on the
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * L4 console. Much of the code has been copied over from the other frontends
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * Copyright (C) 2006-2009 Oracle Corporation
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * available from http://www.virtualbox.org. This file is free software;
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * you can redistribute it and/or modify it under the terms of the GNU
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * General Public License (GPL) as published by the Free Software
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync/*******************************************************************************
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync* Header Files *
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync*******************************************************************************/
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsyncusing namespace com;
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync/*******************************************************************************
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync* Defined Constants And Macros *
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync*******************************************************************************/
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/*******************************************************************************
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync* Internal Functions *
a2828f06a7a97fd85445ed5b2c5cb6a12a185d1dvboxsync*******************************************************************************/
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic DECLCALLBACK(int) vboxbfeConfigConstructor(PVM pVM, void *pvUser);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic DECLCALLBACK(void) vmstateChangeCallback(PVM pVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic DECLCALLBACK(void) setVMErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL,
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsyncstatic DECLCALLBACK(int) VMPowerUpThread(RTTHREAD Thread, void *pvUser);
ed24120b1d8a2eddf4291a9654cf45b2372135abvboxsync/*******************************************************************************
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync* Global Variables *
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync*******************************************************************************/
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** flag whether keyboard/mouse events are grabbed */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** see <l4/input/macros.h> for key definitions */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync// my mini kbd doesn't have RCTRL...
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic bool g_fIOAPIC = false;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic bool g_fACPI = true;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic bool g_fAudio = false;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic bool g_fUSB = false;
4d8251400411b4dcf2c86b5b0376a326ff45938cvboxsyncstatic bool g_fHdaSpf = false;
4d8251400411b4dcf2c86b5b0376a326ff45938cvboxsyncstatic bool g_fHdbSpf = false;
a2828f06a7a97fd85445ed5b2c5cb6a12a185d1dvboxsyncstatic bool g_fRawR0 = true;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic bool g_fRawR3 = true;
4d8251400411b4dcf2c86b5b0376a326ff45938cvboxsyncstatic bool g_fPATM = true;
a2828f06a7a97fd85445ed5b2c5cb6a12a185d1dvboxsyncstatic bool g_fCSAM = true;
4d8251400411b4dcf2c86b5b0376a326ff45938cvboxsyncstatic bool g_fRestoreState = false;
4d8251400411b4dcf2c86b5b0376a326ff45938cvboxsyncstatic const char *g_pszShareName[MaxSharedFolders];
4d8251400411b4dcf2c86b5b0376a326ff45938cvboxsyncstatic unsigned g_uNumShares;
4d8251400411b4dcf2c86b5b0376a326ff45938cvboxsyncstatic bool g_fPreAllocRam = false;
4d8251400411b4dcf2c86b5b0376a326ff45938cvboxsyncstatic bool g_fReleaseLog = true; /**< Set if we should open the release. */
4d8251400411b4dcf2c86b5b0376a326ff45938cvboxsync unsigned g_uProgressPercent = ~0U;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Network device config info.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync bool fSniff; /**< Set if the network sniffer should be installed. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync const char *pszSniff; /**< Output file for the network sniffer. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync const char *pszName; /**< The device name of a HIF device. The name of the internal network. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync bool fHaveConnectTo; /**< Whether fConnectTo is set. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int32_t iConnectTo; /**< The lanX to connect to (bridge with). */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync int32_t fd; /**< The file descriptor of a HIF device.*/
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** Array of network device configurations. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync/** @todo currently this is only set but never read. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return !!(g_uNumShares > 0);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Converts the passed in network option
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @returns Index into g_aNetDevs on success. (positive)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @returns VERR_INVALID_PARAMETER on failure. (negative)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pszArg The argument.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param cchRoot The length of the argument root.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncstatic int networkArg2Index(const char *pszArg, int cchRoot)
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync int rc = RTStrToUInt32Ex(&pszArg[cchRoot], NULL, 10, &n);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTPrintf("Error: invalid network device option (rc=%Rrc): %s\n", rc, pszArg);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTPrintf("Error: The network device number is out of range: %RU32 (1 <= 0 <= %u) (%s)\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Generates a new unique MAC address based on our vendor ID and
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * parts of a GUID.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @returns iprt status code
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pAddress An array into which to store the newly generated address
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncint GenerateMACAddress(char pszAddress[MAC_STRING_LEN + 1])
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Our strategy is as follows: the first three bytes are our fixed
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * vendor ID (080027). The remaining 3 bytes will be taken from the
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * start of a GUID. This is a fairly safe algorithm.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync LogFlowFunc(("RTUuidCreate failed, returning %Rrc\n", rc));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTStrPrintf(pszAddress, MAC_STRING_LEN + 1, "080027%02X%02X%02X",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync LogFlowFunc(("generated MAC: '%s'\n", pszAddress));
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * Print a syntax error.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @returns return value for main().
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pszMsg The message format string.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param ... Format arguments.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Print a fatal error.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @returns return value for main().
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pszMsg The message format string.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param ... Format arguments.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Start progress display.
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync * Update progress display.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncint callProgressInfo(PVM pVM, unsigned uPercent, void *pvUser)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * End progress display.
b5e27e3959258723aa2c45f72d2b2e91d10b6deevboxsync * Print program usage.
468c2bcb36eb9a032f5dd0fcb34db10bd58e9996vboxsync " -hda <file> Set first hard disk to file\n"
a2828f06a7a97fd85445ed5b2c5cb6a12a185d1dvboxsync " -hdb <file> Set second hard disk to file\n"
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync " -fda <file> Set first floppy disk to file\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -cdrom <file> Set CDROM to file/device ('none' to unmount)\n"
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync " -boot <a|c|d> Set boot device (a = floppy, c = first hard disk, d = DVD)\n"
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync " -boot menu <0|1|2> Boot menu (0 = disable, 1 = menu only, 2 = message + menu)\n"
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync " -m <size> Set memory size in megabytes (default 128MB)\n"
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync " -vram <size> Set size of video memory in megabytes\n"
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync " -prealloc Force RAM pre-allocation\n"
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync " -fullscreen Start VM in fullscreen mode\n"
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync " -statefile <file> Define the file name for VM save/restore\n"
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync " -restore Restore the VM if the statefile exists, normal start otherwise\n"
9429e79ee2743cb878d5f3680e2dcad036125e02vboxsync " -nofstoggle Forbid switching to/from fullscreen mode\n"
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync " -share <dir> <name> [readonly]\n"
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync " Share directory <dir> as name <name>. Optionally read-only.\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -nohostkey Disable hostkey\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -[no]acpi Enable or disable ACPI (default: enabled)\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -[no]ioapic Enable or disable the IO-APIC (default: disabled)\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -audio Enable audio\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -natdev<1-N> [mac] Use NAT networking on network adapter <N>. Use hardware\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " address <mac> if specified.\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -hifdev<1-N> Use Host Interface Networking with host interface <int>\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " <int> [mac] on network adapter <N>. Use hardware address <mac> if\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " specified.\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -intnet<1-N> Attach network adapter <N> to internal network <net>. Use\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " <net> [mac] hardware address <mac> if specified.\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -netsniff<1-N> Enable packet sniffer\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -brdev<1-N> lan<X> Bridge network adaptor <N> with the 'lanX' device.\n"
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync " -tapfd<1-N> <fd> Use existing TAP device, don't allocate\n"
5d69af51557e9e9db029ecd243e820383af49b18vboxsync " -vrdp [port] Listen for VRDP connections on port (default if not specified)\n"
5d69af51557e9e9db029ecd243e820383af49b18vboxsync " -securelabel Display a secure VM label at the top of the screen\n"
5d69af51557e9e9db029ecd243e820383af49b18vboxsync " -seclabelfnt TrueType (.ttf) font file for secure session label\n"
5d69af51557e9e9db029ecd243e820383af49b18vboxsync " -seclabelsiz Font point size for secure session label (default 12)\n"
5d69af51557e9e9db029ecd243e820383af49b18vboxsync " -[no]rellog Enable or disable the release log './VBoxBFE.log' (default: enabled)\n"
5d69af51557e9e9db029ecd243e820383af49b18vboxsync " -[no]rawr0 Enable or disable raw ring 3\n"
a2828f06a7a97fd85445ed5b2c5cb6a12a185d1dvboxsync " -[no]rawr3 Enable or disable raw ring 0\n"
a2828f06a7a97fd85445ed5b2c5cb6a12a185d1dvboxsync " -[no]patm Enable or disable PATM\n"
5d69af51557e9e9db029ecd243e820383af49b18vboxsync " -[no]csam Enable or disable CSAM\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync " -env <var=value> Set the given environment variable to \"value\"\n"
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync/** entry point */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsyncextern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char **envp)
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync bool fFullscreen = false;
ba8183e1a0c699f5b5131a03e157fc7e39ed3009vboxsync bool fSecureLabel = false;
817d003403ed9395143bd4ba88fbd9cb60e5eeebvboxsync RTPrintf(VBOX_PRODUCT " Simple SDL GUI built %s %s\n", __DATE__, __TIME__);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync // less than one parameter is not possible
817d003403ed9395143bd4ba88fbd9cb60e5eeebvboxsync * Parse the command line arguments.
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("missing argument for boot drive!\n");
760446f710619a9daa6cedc7f0601f49e4ea3442vboxsync return SyntaxError("invalid argument for boot drive! (%s)\n", argv[curArg]);
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("wrong argument for boot drive! (%s)\n", argv[curArg]);
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("missing argument for boot menu!\n");
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync if (strlen(argv[curArg]) != 1 || *argv[curArg] < '0' || *argv[curArg] > '2')
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("invalid argument for boot menu! (%s)\n", argv[curArg]);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("missing argument for memory size!\n");
b5e27e3959258723aa2c45f72d2b2e91d10b6deevboxsync rc = RTStrToUInt32Ex(argv[curArg], NULL, 0, &g_u32MemorySizeMB);
b5e27e3959258723aa2c45f72d2b2e91d10b6deevboxsync return SyntaxError("bad memory size: %s (error %Rrc)\n",
a2828f06a7a97fd85445ed5b2c5cb6a12a185d1dvboxsync return SyntaxError("missing argument for vram size!\n");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTStrToUInt32Ex(argv[curArg], NULL, 0, &uVRAMMB);
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("bad video ram size: %s (error %Rrc)\n",
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("missing argument for restore!\n");
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("too many shared folders specified!\n");
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("missing 1s argument for share!\n");
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("missing 2nd argument for share!\n");
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync if (curArg < argc-1 && strcmp(argv[curArg+1], "readonly") == 0)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync return SyntaxError("missing file name for first hard disk!\n");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* resolve it. */
817d003403ed9395143bd4ba88fbd9cb60e5eeebvboxsync return SyntaxError("The path to the specified harddisk, '%s', could not be resolved.\n", argv[curArg]);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("missing file name for second hard disk!\n");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* resolve it. */
817d003403ed9395143bd4ba88fbd9cb60e5eeebvboxsync return SyntaxError("The path to the specified harddisk, '%s', could not be resolved.\n", argv[curArg]);
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("missing file/device name for first floppy disk!\n");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* resolve it. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("The path to the specified floppy disk, '%s', could not be resolved.\n", argv[curArg]);
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("missing file/device name for first hard disk!\n");
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync /* resolve it. */
9eea21d61089fe62b80ef3f4549600091c2b1967vboxsync return SyntaxError("The path to the specified cdrom, '%s', could not be resolved.\n", argv[curArg]);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* This is leaving a lot of dead code in the L4 version of course,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync but I don't think that that is a major problem. We may even
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync activate it sometime... */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync g_aNetDevs[i].enmType = !strncmp(pszArg, "-natdev", 7)
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /* The HIF device name / The Internal Network name. */
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync return SyntaxError(g_aNetDevs[i].enmType == BFENETDEV::HIF
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync ? "The TAP network device name is missing! (%s)\n"
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync : "The internal network name is missing! (%s)\n"
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync /* The MAC address. */
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync const char *pszMac;
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync if ((curArg + 1 < argc) && (argv[curArg + 1][0] != '-'))
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync return SyntaxError("failed to generate a hardware address for network device %d (error %Rrc)\n",
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync return SyntaxError("The network MAC address has an invalid length: %s (%s)\n", pszMac, pszArg);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync for (unsigned j = 0; j < RT_ELEMENTS(g_aNetDevs[i].Mac.au8); j++)
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("Invalid MAC address: %s\n", argv[curArg]);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync g_aNetDevs[i].Mac.au8[j] = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync /** @todo filename */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("%d is not a hif device! Make sure you put the -hifdev argument first.\n", i);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("missing argument for %s!\n", pszArg);
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync return SyntaxError("bad interface name '%s' specified with '%s'. Expected 'lan0', 'lan1' and similar.\n",
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync return SyntaxError("missing argument for %s!\n", pszArg);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = RTStrToInt32Ex(argv[curArg], NULL, 0, &g_aNetDevs[i].fd);
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync return SyntaxError("bad tap file descriptor: %s (error %Rrc)\n", argv[curArg], rc);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync#endif /* RT_OS_LINUX */
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync // -vrdp might take a port number (positive).
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync if (curArg + 1 < argc && argv[curArg + 1][0] != '-')
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync rc = RTStrToInt32Ex(argv[curArg], NULL, 0, &portVRDP);
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync return SyntaxError("cannot vrpd port: %s (%Rrc)\n", argv[curArg], rc);
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync return SyntaxError("vrdp port number is out of range: %RI32\n", portVRDP);
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync return SyntaxError("missing font file name for secure label!\n");
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("missing font point size for secure label!\n");
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync#endif /* VBOXSDL_ADVANCED_OPTIONS */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync#endif /* RT_OS_L4 */
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync /* just show the help screen */
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync SyntaxError("unrecognized argument '%s'\n", pszArg);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* First console, then framebuffer!! */
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync /* start with something in the titlebar */
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync * Start the VM execution thread. This has to be done
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync * asynchronously as powering up can take some time
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync * (accessing devices such as the host DVD drive). In
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync * the meantime, we have to service the SDL event loop.
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync rc = RTThreadCreate(&thread, VMPowerUpThread, 0, 0, RTTHREADTYPE_MAIN_WORKER, 0, "PowerUp");
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync RTPrintf("Error: Thread creation failed with %d\n", rc);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /* Start the external IDL interface */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /* loop until the powerup processing is done */
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync /* notify the display that the resize has been completed */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync RTPrintf("Error: failed to power up VM! No error text available.\n");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* did the power up succeed? */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTPrintf("Error: failed to power up VM! No error text available (rc = 0x%x state = %d)\n", rc, machineState);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* The L4 console provides (currently) a fixed resolution. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync gDisplay->SetVideoModeHint(gFramebuffer->getHostXres(), gFramebuffer->getHostYres(), 0, 0);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* Limit the VRAM of the guest to the amount of memory we got actually
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * mapped from the L4 console. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync u32MaxVRAM = (gFramebuffer->getHostYres() + 18) /* don't omit the status bar */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTPrintf("Limiting the video memory to %u bytes\n", u32MaxVRAM);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * Main event loop
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /* Handled internally */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /// @todo that somehow doesn't seem to work!
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* notify the display that the resize has been completed */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * Query the new label text
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync gMachine->COMGETTER(ExtraData)(key, label.asOutParam());
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync * Now update the label
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync#endif /* VBOX_SECURELABEL */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * If get here because the guest terminated using ACPI off we don't have to
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * switch off the VM because we were notified via vmstateChangeCallback()
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * that this already happened. In any other case stop the VM before killing her.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /* Power off VM */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /* And destroy it */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * Main entry point.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /* clear Fiasco kernel trace buffer */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /* set the environment. Must be done before the runtime is
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync initialised. Yes, it really must. */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync for (int i = 0; i < argc; i++)
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync if (++i >= argc)
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("missing argument to -env (format: var=value)!\n");
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /* add it to the environment */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return SyntaxError("Error setting environment string %s.\n", argv[i]);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync# endif /* RT_OS_L4 */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * Before we do *anything*, we initialize the runtime.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync return FatalError("RTR3Init failed rc=%Rrc\n", rc);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync#endif /* !VBOX_WITH_HARDENING */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * VM state callback function. Called by the VMM
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * using its state machine states.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * Primarily used to handle VM initiated power off, suspend and state saving,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * but also for doing termination completed work (VMSTATE_TERMINATE).
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * In general this function is called in the context of the EMT.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @todo machineState is set to VMSTATE_RUNNING before all devices have received power on events
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * this can prematurely allow the main thread to enter the event loop
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @param pVM The VM handle.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @param enmState The new state.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @param enmOldState The old state.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @param pvUser The user argument.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncstatic DECLCALLBACK(void) vmstateChangeCallback(PVM pVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser)
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync LogFlow(("vmstateChangeCallback: changing state from %d to %d\n", enmOldState, enmState));
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * The VM has terminated
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * The VM has been completely destroyed.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * Note: This state change can happen at two points:
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * 1) At the end of VMR3Destroy() if it was not called from EMT.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * 2) At the end of vmR3EmulationThread if VMR3Destroy() was called by EMT.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync default: /* shut up gcc */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * VM error callback function. Called by the various VM components.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @param pVM The VM handle.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @param pvUser The user argument.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @param rc VBox status code.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @param pszError Error message format string.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @param args Error message arguments.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * @thread EMT.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncDECLCALLBACK(void) setVMErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL,
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync /** @todo accessing shared resource without any kind of synchronization */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync va_copy(va2, args); /* Have to make a copy here or GCC will break. */
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync "%N!\nVBox status code: %d (%Rrc)", pszFormat, &va2, rc, rc);
3ff8aa7d3c74cfbe8da5f77b8ea6c748cc79213avboxsync * VM Runtime error callback function. Called by the various VM components.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pVM The VM handle.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pvUser The user argument.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pszErrorId Error ID string.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param pszError Error message format string.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @param va Error message arguments.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * @thread EMT.
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncDECLCALLBACK(void) setVMRuntimeErrorCallback(PVM pVM, void *pvUser, uint32_t fFlags,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync va_copy(va2, va); /* Have to make a copy here or GCC/AMD64 will break. */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync fFlags & VMSETRTERR_FLAGS_FATAL ? "Error" : "Warning",
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync/** VM asynchronous operations thread */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsyncDECLCALLBACK(int) VMPowerUpThread(RTTHREAD Thread, void *pvUser)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Setup the release log instance in current directory.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc2 = RTLogCreateEx(&pLogger, RTLOGFLAGS_PREFIX_TIME_PROG, "all",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTLOGDEST_FILE, s_szError, sizeof(s_szError), "./VBoxBFE.log");
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* some introductory information */
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync RTTimeSpecToString(RTTimeNow(&TimeSpec), szNowUct, sizeof(szNowUct));
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync "VBoxBFE %s (%s %s) release log\n"
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync "Log opened %s\n",
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync /* register this logger as the release logger */
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTPrintf("Could not open release log (%s)\n", s_szError);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync * Start VM (also from saved state) and track progress
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Create empty VM.
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VMR3Create(1, NULL, setVMErrorCallback, NULL, vboxbfeConfigConstructor, NULL, &gpVM);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync RTPrintf("Error: VM creation failed with %Rrc.\n", rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Register VM state change handler
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync rc = VMR3AtStateRegister(gpVM, vmstateChangeCallback, NULL);
d8e12fa5dd1c35282b98cb165e42b6b395cf971bvboxsync RTPrintf("Error: VMR3AtStateRegister failed with %Rrc.\n", rc);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync * Add shared folders to the VM
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync for (unsigned i=0; i<g_uNumShares; i++)
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync cbString = (RTUtf16Len (aHostPath) + 1) * sizeof (RTUTF16);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync pFolderName = (SHFLSTRING *) RTMemAllocZ (sizeof (SHFLSTRING) + cbString);
462e60a19d02a99b2b1a5c08dff74bb0808d707cvboxsync memcpy (pFolderName->String.ucs2, aHostPath, cbString);
#ifdef VBOXBFE_WITH_USB
if (g_fUSB)
if ( g_fRestoreState
&& *g_pszStateFile
goto failure;
if (gpVM)
int rc;
AssertReleaseMsg(u32Version == VBOX_VERSION, ("u32Version=%#x VBOX_VERSION=%#x\n", u32Version, VBOX_VERSION));
return rc;
return rc;
return rc;
return rc;
return rc;
return VINF_SUCCESS;
int rc;
if (g_fPreAllocRam)
#ifdef VBOXSDL_ADVANCED_OPTIONS
if (g_fACPI)
if (g_pszFdaFile)
#ifdef DEBUG
if (g_fIOAPIC)
#ifdef RT_OS_L4
if (g_pszHdaFile)
if (g_fHdaSpf)
if (g_pszHdbFile)
if (g_fHdbSpf)
if (g_pszCdromFile)
UPDATE_RC();
UPDATE_RC();
#if defined(RT_OS_LINUX)
return rc;
return VERR_BUFFER_OVERFLOW;
if (rc)
return rc2;
if (rc)
return rc2;
# ifdef VBOX_WITH_CROSSBOW
rc = CFGMR3InsertBytes(pCfg, "MAC", &g_aNetDevs[ulInstance].Mac, sizeof(g_aNetDevs[ulInstance].Mac));
UPDATE_RC();
UPDATE_RC();
return VERR_NOT_IMPLEMENTED;
if (g_fAudio)
#ifdef RT_OS_WINDOWS
# ifdef VBOX_WITH_SOLARIS_OSS
#ifdef VBOXBFE_WITH_USB
if (g_fUSB)
return rc;