Logo Search packages:      
Sourcecode: virtualbox-ose version File versions

int main ( int  argc,
char **  argv 
)

entry point

Todo:
filename

Todo:
that somehow doesn't seem to work!

Definition at line 364 of file VBoxBFE.cpp.

References _1M, com::Bstr::asOutParam(), AssertRC, PDMMAC::au8, BFENetworkDevice::enmType, Console::eventWait(), FatalError(), BFENetworkDevice::fHaveFd, BFENetworkDevice::fSniff, GenerateMACAddress(), Console::initialized(), LogFlow, BFENetworkDevice::Mac, networkArg2Index(), BFENetworkDevice::pszName, com::Utf8Str::raw(), RT_ELEMENTS, RT_FAILURE, RT_INDEFINITE_WAIT, RTTHREADTYPE_MAIN_WORKER, show_usage(), strncmp(), SyntaxError(), Console::updateTitlebar(), VBOX_FAILURE, VINF_SUCCESS, VMSTATE_CREATING, VMSTATE_LOADING, VMSTATE_OFF, VMSTATE_RUNNING, and VMSTATE_TERMINATED.

Referenced by QIMessageBox::QIMessageBox().

{
#ifdef RT_OS_L4
#ifndef L4API_l4v2onv4
    /* clear Fiasco kernel trace buffer */
    fiasco_tbuf_clear();
#endif
    /* set the environment.  Must be done before the runtime is
       initialised.  Yes, it really must. */
    for (int i = 0; i < argc; i++)
        if (strcmp(argv[i], "-env") == 0)
        {
            if (++i >= argc)
                return SyntaxError("missing argument to -env (format: var=value)!\n");
            /* add it to the environment */
            if (putenv(argv[i]) != 0)
                return SyntaxError("Error setting environment string %s.\n", argv[i]);
        }
#endif /* RT_OS_L4 */

    /*
     * Before we do *anything*, we initialize the runtime.
     */
    int rc = RTR3Init();
    if (VBOX_FAILURE(rc))
        return FatalError("RTR3Init failed rc=%Vrc\n", rc);


    bool fFullscreen = false;
#ifdef VBOX_VRDP
    int32_t portVRDP = -1;
#endif
#ifdef VBOX_SECURELABEL
    bool fSecureLabel = false;
    uint32_t secureLabelPointSize = 12;
    char *secureLabelFontFile = NULL;
#endif
    RTPrintf("VirtualBox Simple SDL GUI built %s %s\n", __DATE__, __TIME__);

    // less than one parameter is not possible
    if (argc < 2)
    {
        show_usage();
        return 1;
    }

    /*
     * Parse the command line arguments.
     */
    for (int curArg = 1; curArg < argc; curArg++)
    {
        const char * const pszArg = argv[curArg];
        if (strcmp(pszArg, "-boot") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing argument for boot drive!\n");
            if (strlen(argv[curArg]) != 1)
                return SyntaxError("invalid argument for boot drive! (%s)\n", argv[curArg]);
            rc = VINF_SUCCESS;
            switch (argv[curArg][0])
            {
                case 'a':
                {
                    pszBootDevice = "FLOPPY";
                    break;
                }

                case 'c':
                {
                    pszBootDevice = "IDE";
                    break;
                }

                case 'd':
                {
                    pszBootDevice = "DVD";
                    break;
                }

                default:
                    return SyntaxError("wrong argument for boot drive! (%s)\n", argv[curArg]);
            }
        }
        else if (strcmp(pszArg, "-bootmenu") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing argument for boot menu!\n");
            if (strlen(argv[curArg]) != 1 || *argv[curArg] < '0' || *argv[curArg] > '2')
                return SyntaxError("invalid argument for boot menu! (%s)\n", argv[curArg]);
            rc = VINF_SUCCESS;
            g_iBootMenu = *argv[curArg] - 0;
        }
        else if (strcmp(pszArg, "-m") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing argument for memory size!\n");
            rc = RTStrToUInt32Ex(argv[curArg], NULL, 0, &g_u32MemorySizeMB);
            if (VBOX_FAILURE(rc))
                return SyntaxError("bad memory size: %s (error %Vrc)\n",
                                   argv[curArg], rc);
        }
        else if (strcmp(pszArg, "-vram") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing argument for vram size!\n");
            rc = RTStrToUInt32Ex(argv[curArg], NULL, 0, &g_u32VRamSizeMB);
            if (VBOX_FAILURE(rc))
                return SyntaxError("bad video ram size: %s (error %Vrc)\n",
                                   argv[curArg], rc);
        }
        else if (strcmp(pszArg, "-fullscreen") == 0)
            fFullscreen = true;
        else if (strcmp(pszArg, "-nofstoggle") == 0)
            gfAllowFullscreenToggle = false;
        else if (strcmp(pszArg, "-nohostkey") == 0)
        {
            gHostKey = 0;
            gHostKeySym = 0;
        }
        else if (strcmp(pszArg, "-acpi") == 0)
            g_fACPI = true;
        else if (strcmp(pszArg, "-noacpi") == 0)
            g_fACPI = false;
        else if (strcmp(pszArg, "-ioapic") == 0)
            g_fIOAPIC = true;
        else if (strcmp(pszArg, "-noioapic") == 0)
            g_fIOAPIC = false;
        else if (strcmp(pszArg, "-audio") == 0)
            g_fAudio = true;
#ifdef VBOXBFE_WITH_USB
        else if (strcmp(pszArg, "-usb") == 0)
            g_fUSB = true;
#endif
        else if (strcmp(pszArg, "-hda") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing file name for first hard disk!\n");

            /* resolve it. */
            if (RTPathExists(argv[curArg]))
                g_pszHdaFile = RTPathRealDup(argv[curArg]);
            if (!g_pszHdaFile)
                return SyntaxError("The path to the specified harddisk, '%s', could not be resolved.\n", argv[curArg]);
        }
        else if (strcmp(pszArg, "-hdb") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing file name for second hard disk!\n");

            /* resolve it. */
            if (RTPathExists(argv[curArg]))
                g_pszHdbFile = RTPathRealDup(argv[curArg]);
            if (!g_pszHdbFile)
                return SyntaxError("The path to the specified harddisk, '%s', could not be resolved.\n", argv[curArg]);
        }
        else if (strcmp(pszArg, "-fda") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing file/device name for first floppy disk!\n");

            /* resolve it. */
            if (RTPathExists(argv[curArg]))
                g_pszFdaFile = RTPathRealDup(argv[curArg]);
            if (!g_pszFdaFile)
                return SyntaxError("The path to the specified floppy disk, '%s', could not be resolved.\n", argv[curArg]);
        }
        else if (strcmp(pszArg, "-cdrom") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing file/device name for first hard disk!\n");

            /* resolve it. */
            if (RTPathExists(argv[curArg]))
                g_pszCdromFile = RTPathRealDup(argv[curArg]);
            if (!g_pszCdromFile)
                return SyntaxError("The path to the specified cdrom, '%s', could not be resolved.\n", argv[curArg]);
        }
#ifdef RT_OS_L4
        /* This is leaving a lot of dead code in the L4 version of course,
           but I don't think that that is a major problem.  We may even
           activate it sometime... */
        else if (   strncmp(pszArg, "-hifdev", 7) == 0
                 || strncmp(pszArg, "-nonetd", 7) == 0)
#else
        else if (   strncmp(pszArg, "-natdev", 7) == 0
                 || strncmp(pszArg, "-hifdev", 7) == 0
                 || strncmp(pszArg, "-nonetd", 7) == 0
                 || strncmp(pszArg, "-intnet", 7) == 0)
#endif
        {
            int i = networkArg2Index(pszArg, 7);
            if (i < 0)
                return 1;
            g_aNetDevs[i].enmType = !strncmp(pszArg, "-natdev", 7)
                                  ? BFENETDEV::NAT
                                  : !strncmp(pszArg, "-hifdev", 7)
                                  ? BFENETDEV::HIF
                                  : !strncmp(pszArg, "-intnet", 7)
                                  ? BFENETDEV::INTNET
                                  : BFENETDEV::NONE;

            /* The HIF device name / The Internal Network name. */
            g_aNetDevs[i].pszName = NULL;
            if (    g_aNetDevs[i].enmType == BFENETDEV::HIF
                ||  g_aNetDevs[i].enmType == BFENETDEV::INTNET)
            {
                if (curArg + 1 >= argc)
                    return SyntaxError(g_aNetDevs[i].enmType == BFENETDEV::HIF
                                       ? "The TAP network device name is missing! (%s)\n"
                                       : "The internal network name is missing! (%s)\n"
                                       , pszArg);
                g_aNetDevs[i].pszName = argv[++curArg];
            }

            /* The MAC address. */
            const char *pszMac;
            char szMacGen[MAC_STRING_LEN + 1];
            if ((curArg + 1 < argc) && (argv[curArg + 1][0] != '-'))
                pszMac = argv[++curArg];
            else
            {
                rc = GenerateMACAddress(szMacGen);
                if (RT_FAILURE(rc))
                    return SyntaxError("failed to generate a hardware address for network device %d (error %Vrc)\n",
                                       i, rc);
                pszMac = szMacGen;
            }
            if (strlen(pszMac) != MAC_STRING_LEN)
                return SyntaxError("The network MAC address has an invalid length: %s (%s)\n", pszMac, pszArg);
            for (unsigned j = 0; j < RT_ELEMENTS(g_aNetDevs[i].Mac.au8); j++)
            {
                char c1 = toupper(*pszMac++) - '0';
                if (c1 > 9)
                    c1 -= 7;
                char c2 = toupper(*pszMac++) - '0';
                if (c2 > 9)
                    c2 -= 7;
                if (c2 > 16 || c1 > 16)
                    return SyntaxError("Invalid MAC address: %s\n", argv[curArg]);
                g_aNetDevs[i].Mac.au8[j] = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
            }
        }
        else if (strncmp(pszArg, "-netsniff", 9) == 0)
        {
            int i = networkArg2Index(pszArg, 7);
            if (rc < 0)
                return 1;
            g_aNetDevs[i].fSniff = true;
            /** @todo filename */
        }
#ifdef RT_OS_LINUX
        else if (strncmp(pszArg, "-tapfd", 6) == 0)
        {
            int i = networkArg2Index(pszArg, 7);
            if (++curArg >= argc)
                return SyntaxError("missing argument for %s!\n", pszArg);
            rc = RTStrToInt32Ex(argv[curArg], NULL, 0, &g_aNetDevs[i].fd);
            if (VBOX_FAILURE(rc))
                return SyntaxError("bad tap file descriptor: %s (error %VRc)\n", argv[curArg], rc);
            g_aNetDevs[i].fHaveFd = true;
        }
#endif /* RT_OS_LINUX */
#ifdef VBOX_VRDP
        else if (strcmp(pszArg, "-vrdp") == 0)
        {
            // -vrdp might take a port number (positive).
            portVRDP = 0;       // indicate that it was encountered.
            if (curArg + 1 < argc && argv[curArg + 1][0] != '-')
            {
                rc = RTStrToInt32Ex(argv[curArg], NULL, 0, &portVRDP);
                if (VBOX_FAILURE(rc))
                    return SyntaxError("cannot vrpd port: %s (%VRc)\n", argv[curArg], rc);
                if (portVRDP < 0 || portVRDP >= 0x10000)
                    return SyntaxError("vrdp port number is out of range: %RI32\n", portVRDP);
            }
        }
#endif /* VBOX_VRDP */
#ifdef VBOX_SECURELABEL
        else if (strcmp(pszArg, "-securelabel") == 0)
        {
            fSecureLabel = true;
            LogFlow(("Secure labelling turned on\n"));
        }
        else if (strcmp(pszArg, "-seclabelfnt") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing font file name for secure label!\n");
            secureLabelFontFile = argv[curArg];
        }
        else if (strcmp(pszArg, "-seclabelsiz") == 0)
        {
            if (++curArg >= argc)
                return SyntaxError("missing font point size for secure label!\n");
            secureLabelPointSize = atoi(argv[curArg]);
        }
#endif
        else if (strcmp(pszArg, "-rellog") == 0)
            g_fReleaseLog = true;
        else if (strcmp(pszArg, "-norellog") == 0)
            g_fReleaseLog = false;
        else if (strcmp(pszArg, "-prealloc") == 0)
            g_fPreAllocRam = true;
#ifdef VBOXSDL_ADVANCED_OPTIONS
        else if (strcmp(pszArg, "-rawr0") == 0)
            g_fRawR0 = true;
        else if (strcmp(pszArg, "-norawr0") == 0)
            g_fRawR0 = false;
        else if (strcmp(pszArg, "-rawr3") == 0)
            g_fRawR3 = true;
        else if (strcmp(pszArg, "-norawr3") == 0)
            g_fRawR3 = false;
        else if (strcmp(pszArg, "-patm") == 0)
            g_fPATM = true;
        else if (strcmp(pszArg, "-nopatm") == 0)
            g_fPATM = false;
        else if (strcmp(pszArg, "-csam") == 0)
            g_fCSAM = true;
        else if (strcmp(pszArg, "-nocsam") == 0)
            g_fCSAM = false;
#endif /* VBOXSDL_ADVANCED_OPTIONS */
#ifdef RT_OS_L4
        else if (strcmp(pszArg, "-env") == 0)
            ++curArg;
#endif /* RT_OS_L4 */
        /* just show the help screen */
        else
        {
            SyntaxError("unrecognized argument '%s'\n", pszArg);
            show_usage();
            return 1;
        }
    }

    gMachineDebugger = new MachineDebugger();
    gStatus = new VMStatus();
    gKeyboard = new Keyboard();
    gMouse = new Mouse();
    gVMMDev = new VMMDev();
    gDisplay = new VMDisplay();
#if defined(USE_SDL)
    /* First console, then framebuffer!! */
    gConsole = new SDLConsole();
    gFramebuffer = new SDLFramebuffer();
#elif defined(RT_OS_L4)
    gConsole = new L4Console();
    gFramebuffer = new L4Framebuffer();
#else
#error "todo"
#endif
    if (!gConsole->initialized())
        goto leave;
    gDisplay->RegisterExternalFramebuffer(gFramebuffer);

    /* start with something in the titlebar */
    gConsole->updateTitlebar();

    /*
     * Start the VM execution thread. This has to be done
     * asynchronously as powering up can take some time
     * (accessing devices such as the host DVD drive). In
     * the meantime, we have to service the SDL event loop.
     */

    RTTHREAD thread;
    rc = RTThreadCreate(&thread, VMPowerUpThread, 0, 0, RTTHREADTYPE_MAIN_WORKER, 0, "PowerUp");
    if (VBOX_FAILURE(rc))
    {
        RTPrintf("Error: Thread creation failed with %d\n", rc);
        return -1;
    }

    /* loop until the powerup processing is done */
    do
    {
#if defined(RT_OS_LINUX) && defined(USE_SDL)
        if (   machineState == VMSTATE_CREATING
            || machineState == VMSTATE_LOADING)
        {
            int event = gConsole->eventWait();

            switch (event)
            {
            case CONEVENT_USR_SCREENRESIZE:
                LogFlow(("CONEVENT_USR_SCREENRESIZE\n"));
                gFramebuffer->resize();
                /* notify the display that the resize has been completed */
                gDisplay->ResizeCompleted();
                break;

            case CONEVENT_USR_QUIT:
                RTPrintf("Error: failed to power up VM! No error text available.\n");
                goto leave;
            }
        }
        else
#endif
            RTThreadSleep(1000);
    }
    while (   machineState == VMSTATE_CREATING
           || machineState == VMSTATE_LOADING);

    if (machineState == VMSTATE_TERMINATED)
        goto leave;

    /* did the power up succeed? */
    if (machineState != VMSTATE_RUNNING)
    {
        RTPrintf("Error: failed to power up VM! No error text available (rc = 0x%x state = %d)\n", rc, machineState);
        goto leave;
    }

    gConsole->updateTitlebar();

#ifdef RT_OS_L4
    /* The L4 console provides (currently) a fixed resolution. */
    if (g_u32VRamSizeMB * _1M >=   gFramebuffer->getHostXres() 
                          * gFramebuffer->getHostYres()
                          * (gDisplay->getBitsPerPixel() / 8))
        gDisplay->SetVideoModeHint(gFramebuffer->getHostXres(), gFramebuffer->getHostYres(), 0, 0);
#endif

    /*
     * Main event loop
     */
    LogFlow(("VBoxSDL: Entering big event loop\n"));

    while (1)
    {
        int event = gConsole->eventWait();

        switch (event)
        {
        case CONEVENT_NONE:
            /* Handled internally */
            break;

        case CONEVENT_QUIT:
        case CONEVENT_USR_QUIT:
            goto leave;

        case CONEVENT_SCREENUPDATE:
            /// @todo that somehow doesn't seem to work!
            gFramebuffer->repaint();
            break;

        case CONEVENT_USR_TITLEBARUPDATE:
            gConsole->updateTitlebar();
            break;

        case CONEVENT_USR_SCREENRESIZE:
        {
            LogFlow(("CONEVENT_USR_SCREENRESIZE\n"));
            gFramebuffer->resize();
            /* notify the display that the resize has been completed */
            gDisplay->ResizeCompleted();
            break;
        }

#ifdef VBOX_SECURELABEL
        case CONEVENT_USR_SECURELABELUPDATE:
        {
           /*
             * Query the new label text
             */
            Bstr key = VBOXSDL_SECURELABEL_EXTRADATA;
            Bstr label;
            gMachine->COMGETTER(ExtraData)(key, label.asOutParam());
            Utf8Str labelUtf8 = label;
            /*
             * Now update the label
             */
            gFramebuffer->setSecureLabelText(labelUtf8.raw());
            break;
        }
#endif /* VBOX_SECURELABEL */

        }

    }

leave:
    LogFlow(("Returning from main()!\n"));

    if (pVM)
    {
        /*
         * If get here because the guest terminated using ACPI off we don't have to
         * switch off the VM because we were notified via vmstateChangeCallback()
         * that this already happened. In any other case stop the VM before killing her.
         */
        if (machineState != VMSTATE_OFF)
        {
            /* Power off VM */
            PVMREQ pReq;
            rc = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT, (PFNRT)VMR3PowerOff, 1, pVM);
        }

        /* And destroy it */
        rc = VMR3Destroy(pVM);
        AssertRC(rc);
    }

    delete gFramebuffer;
    delete gConsole;
    delete gDisplay;
    delete gKeyboard;
    delete gMouse;
    delete gStatus;
    delete gMachineDebugger;

    RTLogFlush(NULL);
    return VBOX_FAILURE (rc) ? 1 : 0;
}


Generated by  Doxygen 1.6.0   Back to index