VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/main.cpp@ 43138

Last change on this file since 43138 was 42665, checked in by vboxsync, 12 years ago

VirtualBox(GUI): Added --warp-pct <pct> factor for debugging purposes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.3 KB
Line 
1/* $Id: main.cpp 42665 2012-08-07 14:55:09Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * The main() function
6 */
7
8/*
9 * Copyright (C) 2006-2009 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20#ifdef VBOX_WITH_PRECOMPILED_HEADERS
21#include "precomp.h"
22#ifdef Q_WS_MAC
23# include "UICocoaApplication.h"
24#endif /* Q_WS_MAC */
25#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
26#include "VBoxGlobal.h"
27#include "UIMessageCenter.h"
28#include "UISelectorWindow.h"
29#include "VBoxUtils.h"
30#ifdef Q_WS_MAC
31# include "UICocoaApplication.h"
32#endif
33
34#ifdef Q_WS_X11
35#include <QFontDatabase>
36#include <iprt/env.h>
37#endif
38
39#include <QCleanlooksStyle>
40#include <QPlastiqueStyle>
41#include <QMessageBox>
42#include <QLocale>
43#include <QTranslator>
44
45#ifdef Q_WS_X11
46# include <X11/Xlib.h>
47#endif
48
49#include <iprt/buildconfig.h>
50#include <iprt/err.h>
51#include <iprt/initterm.h>
52#include <iprt/process.h>
53#include <iprt/stream.h>
54#include <VBox/err.h>
55#include <VBox/version.h>
56#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
57
58#ifdef VBOX_WITH_HARDENING
59# include <VBox/sup.h>
60#endif
61
62#ifdef RT_OS_LINUX
63# include <unistd.h>
64#endif
65
66#include <cstdio>
67
68/* XXX Temporarily. Don't rely on the user to hack the Makefile himself! */
69QString g_QStrHintLinuxNoMemory = QApplication::tr(
70 "This error means that the kernel driver was either not able to "
71 "allocate enough memory or that some mapping operation failed."
72 );
73
74QString g_QStrHintLinuxNoDriver = QApplication::tr(
75 "The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or "
76 "there is a permission problem with /dev/vboxdrv. Please reinstall the kernel "
77 "module by executing<br/><br/>"
78 " <font color=blue>'/etc/init.d/vboxdrv setup'</font><br/><br/>"
79 "as root. If it is available in your distribution, you should install the "
80 "DKMS package first. This package keeps track of Linux kernel changes and "
81 "recompiles the vboxdrv kernel module if necessary."
82 );
83
84QString g_QStrHintOtherWrongDriverVersion = QApplication::tr(
85 "The VirtualBox kernel modules do not match this version of "
86 "VirtualBox. The installation of VirtualBox was apparently not "
87 "successful. Please try completely uninstalling and reinstalling "
88 "VirtualBox."
89 );
90
91QString g_QStrHintLinuxWrongDriverVersion = QApplication::tr(
92 "The VirtualBox kernel modules do not match this version of "
93 "VirtualBox. The installation of VirtualBox was apparently not "
94 "successful. Executing<br/><br/>"
95 " <font color=blue>'/etc/init.d/vboxdrv setup'</font><br/><br/>"
96 "may correct this. Make sure that you do not mix the "
97 "OSE version and the PUEL version of VirtualBox."
98 );
99
100QString g_QStrHintOtherNoDriver = QApplication::tr(
101 "Make sure the kernel module has been loaded successfully."
102 );
103
104/* I hope this isn't (C), (TM) or (R) Microsoft support ;-) */
105QString g_QStrHintReinstall = QApplication::tr(
106 "Please try reinstalling VirtualBox."
107 );
108
109#if defined(DEBUG) && defined(Q_WS_X11) && defined(RT_OS_LINUX)
110
111#include <signal.h>
112#include <execinfo.h>
113
114/* get REG_EIP from ucontext.h */
115#ifndef __USE_GNU
116#define __USE_GNU
117#endif
118#include <ucontext.h>
119#ifdef RT_ARCH_AMD64
120# define REG_PC REG_RIP
121#else
122# define REG_PC REG_EIP
123#endif
124
125
126
127/**
128 * the signal handler that prints out a backtrace of the call stack.
129 * the code is taken from http://www.linuxjournal.com/article/6391.
130 */
131void bt_sighandler (int sig, siginfo_t *info, void *secret) {
132
133 void *trace[16];
134 char **messages = (char **)NULL;
135 int i, trace_size = 0;
136 ucontext_t *uc = (ucontext_t *)secret;
137
138 /* Do something useful with siginfo_t */
139 if (sig == SIGSEGV)
140 Log (("GUI: Got signal %d, faulty address is %p, from %p\n",
141 sig, info->si_addr, uc->uc_mcontext.gregs[REG_PC]));
142 else
143 Log (("GUI: Got signal %d\n", sig));
144
145 trace_size = backtrace (trace, 16);
146 /* overwrite sigaction with caller's address */
147 trace[1] = (void *) uc->uc_mcontext.gregs [REG_PC];
148
149 messages = backtrace_symbols (trace, trace_size);
150 /* skip first stack frame (points here) */
151 Log (("GUI: [bt] Execution path:\n"));
152 for (i = 1; i < trace_size; ++i)
153 Log (("GUI: [bt] %s\n", messages[i]));
154
155 exit (0);
156}
157
158#endif /* DEBUG && X11 && LINUX*/
159
160#if defined(RT_OS_DARWIN)
161# include <dlfcn.h>
162# include <sys/mman.h>
163# include <iprt/asm.h>
164# include <iprt/system.h>
165
166/** Really ugly hack to shut up a silly check in AppKit. */
167static void ShutUpAppKit(void)
168{
169 /* Check for Snow Leopard or higher */
170 char szInfo[64];
171 int rc = RTSystemQueryOSInfo (RTSYSOSINFO_RELEASE, szInfo, sizeof(szInfo));
172 if ( RT_SUCCESS (rc)
173 && szInfo[0] == '1') /* higher than 1x.x.x */
174 {
175 /*
176 * Find issetguid() and make it always return 0 by modifying the code.
177 */
178 void *addr = dlsym(RTLD_DEFAULT, "issetugid");
179 int rc = mprotect((void *)((uintptr_t)addr & ~(uintptr_t)0xfff), 0x2000, PROT_WRITE|PROT_READ|PROT_EXEC);
180 if (!rc)
181 ASMAtomicWriteU32((volatile uint32_t *)addr, 0xccc3c031); /* xor eax, eax; ret; int3 */
182 }
183}
184#endif /* DARWIN */
185
186static void QtMessageOutput (QtMsgType type, const char *msg)
187{
188#ifndef Q_WS_X11
189 NOREF(msg);
190#endif
191 switch (type)
192 {
193 case QtDebugMsg:
194 Log (("Qt DEBUG: %s\n", msg));
195 break;
196 case QtWarningMsg:
197 Log (("Qt WARNING: %s\n", msg));
198#ifdef Q_WS_X11
199 /* Needed for instance for the message ``cannot connect to X server'' */
200 RTStrmPrintf(g_pStdErr, "Qt WARNING: %s\n", msg);
201#endif
202 break;
203 case QtCriticalMsg:
204 Log (("Qt CRITICAL: %s\n", msg));
205#ifdef Q_WS_X11
206 /* Needed for instance for the message ``cannot connect to X server'' */
207 RTStrmPrintf(g_pStdErr, "Qt CRITICAL: %s\n", msg);
208#endif
209 break;
210 case QtFatalMsg:
211 Log (("Qt FATAL: %s\n", msg));
212#ifdef Q_WS_X11
213 RTStrmPrintf(g_pStdErr, "Qt FATAL: %s\n", msg);
214#endif
215 }
216}
217
218/**
219 * Show all available command line parameters.
220 */
221static void showHelp()
222{
223 QString mode = "", dflt = "";
224#ifdef VBOX_GUI_USE_SDL
225 mode += "sdl";
226#endif
227#ifdef VBOX_GUI_USE_QIMAGE
228 if (!mode.isEmpty())
229 mode += "|";
230 mode += "image";
231#endif
232#ifdef VBOX_GUI_USE_DDRAW
233 if (!mode.isEmpty())
234 mode += "|";
235 mode += "ddraw";
236#endif
237#ifdef VBOX_GUI_USE_QUARTZ2D
238 if (!mode.isEmpty())
239 mode += "|";
240 mode += "quartz2d";
241#endif
242#if defined (Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
243 dflt = "quartz2d";
244#elif (defined (Q_WS_WIN32) || defined (Q_WS_PM)) && defined (VBOX_GUI_USE_QIMAGE)
245 dflt = "image";
246#elif defined (Q_WS_X11) && defined (VBOX_GUI_USE_SDL)
247 dflt = "sdl";
248#else
249 dflt = "image";
250#endif
251
252 RTPrintf(VBOX_PRODUCT " Manager %s\n"
253 "(C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
254 "All rights reserved.\n"
255 "\n"
256 "Usage:\n"
257 " --startvm <vmname|UUID> start a VM by specifying its UUID or name\n"
258 " --seamless switch to seamless mode during startup\n"
259 " --fullscreen switch to fullscreen mode during startup\n"
260 " --rmode %-18s select different render mode (default is %s)\n"
261 " --no-startvm-errormsgbox do not show a message box for VM start errors\n"
262# ifdef VBOX_GUI_WITH_PIDFILE
263 " --pidfile <file> create a pidfile file when a VM is up and running\n"
264# endif
265# ifdef VBOX_WITH_DEBUGGER_GUI
266 " --dbg enable the GUI debug menu\n"
267 " --debug like --dbg and show debug windows at VM startup\n"
268 " --debug-command-line like --dbg and show command line window at VM startup\n"
269 " --debug-statistics like --dbg and show statistics window at VM startup\n"
270 " --no-debug disable the GUI debug menu and debug windows\n"
271 " --start-paused start the VM in the paused state\n"
272 " --start-running start the VM running (for overriding --debug*)\n"
273 "\n"
274# endif
275 "Expert options:\n"
276 " --disable-patm disable code patching (ignored by AMD-V/VT-x)\n"
277 " --disable-csam disable code scanning (ignored by AMD-V/VT-x)\n"
278 " --recompile-supervisor recompiled execution of supervisor code (*)\n"
279 " --recompile-user recompiled execution of user code (*)\n"
280 " --recompile-all recompiled execution of all code, with disabled\n"
281 " code patching and scanning\n"
282 " --warp-pct <pct> time warp factor, 100%% (= 1.0) = normal speed\n"
283 " (*) For AMD-V/VT-x setups the effect is --recompile-all.\n"
284 "\n"
285# ifdef VBOX_WITH_DEBUGGER_GUI
286 "The following environment (and extra data) variables are evaluated:\n"
287 " VBOX_GUI_DBG_ENABLED (GUI/Dbg/Enabled)\n"
288 " enable the GUI debug menu if set\n"
289 " VBOX_GUI_DBG_AUTO_SHOW (GUI/Dbg/AutoShow)\n"
290 " show debug windows at VM startup\n"
291 " VBOX_GUI_NO_DEBUGGER disable the GUI debug menu and debug windows\n"
292# endif
293 "\n",
294 RTBldCfgVersion(),
295 mode.toLatin1().constData(),
296 dflt.toLatin1().constData());
297 /** @todo Show this as a dialog on windows. */
298}
299
300extern "C" DECLEXPORT(int) TrustedMain (int argc, char **argv, char ** /*envp*/)
301{
302 LogFlowFuncEnter();
303# if defined(RT_OS_DARWIN)
304 ShutUpAppKit();
305# endif
306
307 for (int i=0; i<argc; i++)
308 if ( !strcmp(argv[i], "-h")
309 || !strcmp(argv[i], "-?")
310 || !strcmp(argv[i], "-help")
311 || !strcmp(argv[i], "--help"))
312 {
313 showHelp();
314 return 0;
315 }
316
317#if defined(DEBUG) && defined(Q_WS_X11) && defined(RT_OS_LINUX)
318 /* install our signal handler to backtrace the call stack */
319 struct sigaction sa;
320 sa.sa_sigaction = bt_sighandler;
321 sigemptyset (&sa.sa_mask);
322 sa.sa_flags = SA_RESTART | SA_SIGINFO;
323 sigaction (SIGSEGV, &sa, NULL);
324 sigaction (SIGBUS, &sa, NULL);
325 sigaction (SIGUSR1, &sa, NULL);
326#endif
327
328#ifdef QT_MAC_USE_COCOA
329 /* Instantiate our NSApplication derivative before QApplication
330 * forces NSApplication to be instantiated. */
331 UICocoaApplication::instance();
332#endif
333
334 qInstallMsgHandler (QtMessageOutput);
335
336 int rc = 1; /* failure */
337
338 /* scope the QApplication variable */
339 {
340#ifdef Q_WS_X11
341 /* Qt has a complex algorithm for selecting the right visual which
342 * doesn't always seem to work. So we naively choose a visual - the
343 * default one - ourselves and pass that to Qt. This means that we
344 * also have to open the display ourselves.
345 * We check the Qt parameter list and handle Qt's -display argument
346 * ourselves, since we open the display connection. We also check the
347 * to see if the user has passed Qt's -visual parameter, and if so we
348 * assume that the user wants Qt to handle visual selection after all,
349 * and don't supply a visual. */
350 char *pszDisplay = NULL;
351 bool useDefaultVisual = true;
352 for (int i = 0; i < argc; ++i)
353 {
354 if (!::strcmp(argv[i], "-display") && (i + 1 < argc))
355 /* What if it isn't? Rely on QApplication to complain? */
356 {
357 pszDisplay = argv[i + 1];
358 ++i;
359 }
360 else if (!::strcmp(argv[i], "-visual"))
361 useDefaultVisual = false;
362 }
363 Display *pDisplay = XOpenDisplay(pszDisplay);
364 if (!pDisplay)
365 {
366 RTPrintf(pszDisplay ? "Failed to open the X11 display \"%s\"!\n"
367 : "Failed to open the X11 display!\n",
368 pszDisplay);
369 return 0;
370 }
371 Visual *pVisual = useDefaultVisual
372 ? DefaultVisual(pDisplay, DefaultScreen(pDisplay))
373 : NULL;
374 /* Now create the application object */
375 QApplication a (pDisplay, argc, argv, (Qt::HANDLE) pVisual);
376#else /* Q_WS_X11 */
377 QApplication a (argc, argv);
378#endif /* Q_WS_X11 */
379
380 /* Qt4.3 version has the QProcess bug which freezing the application
381 * for 30 seconds. This bug is internally used at initialization of
382 * Cleanlooks style. So we have to change this style to another one.
383 * See http://trolltech.com/developer/task-tracker/index_html?id=179200&method=entry
384 * for details. */
385 if (VBoxGlobal::qtRTVersionString().startsWith ("4.3") &&
386 qobject_cast <QCleanlooksStyle*> (QApplication::style()))
387 QApplication::setStyle (new QPlastiqueStyle);
388
389#ifdef Q_OS_SOLARIS
390 /* Use plastique look 'n feel for Solaris instead of the default motif (Qt 4.7.x) */
391 QApplication::setStyle (new QPlastiqueStyle);
392#endif
393
394#ifdef Q_WS_X11
395 /* This patch is not used for now on Solaris & OpenSolaris because
396 * there is no anti-aliasing enabled by default, Qt4 to be rebuilt. */
397#ifndef Q_OS_SOLARIS
398 /* Cause Qt4 has the conflict with fontconfig application as a result
399 * sometimes substituting some fonts with non scaleable-anti-aliased
400 * bitmap font we are reseting substitutes for the current application
401 * font family if it is non scaleable-anti-aliased. */
402 QFontDatabase fontDataBase;
403
404 QString currentFamily (QApplication::font().family());
405 bool isCurrentScaleable = fontDataBase.isScalable (currentFamily);
406
407 /*
408 LogFlowFunc (("Font: Current family is '%s'. It is %s.\n",
409 currentFamily.toLatin1().constData(),
410 isCurrentScaleable ? "scalable" : "not scalable"));
411 QStringList subFamilies (QFont::substitutes (currentFamily));
412 foreach (QString sub, subFamilies)
413 {
414 bool isSubScalable = fontDataBase.isScalable (sub);
415 LogFlowFunc (("Font: Substitute family is '%s'. It is %s.\n",
416 sub.toLatin1().constData(),
417 isSubScalable ? "scalable" : "not scalable"));
418 }
419 */
420
421 QString subFamily (QFont::substitute (currentFamily));
422 bool isSubScaleable = fontDataBase.isScalable (subFamily);
423
424 if (isCurrentScaleable && !isSubScaleable)
425 QFont::removeSubstitution (currentFamily);
426#endif /* Q_OS_SOLARIS */
427#endif
428
429#ifdef Q_WS_WIN
430 /* Drag in the sound drivers and DLLs early to get rid of the delay taking
431 * place when the main menu bar (or any action from that menu bar) is
432 * activated for the first time. This delay is especially annoying if it
433 * happens when the VM is executing in real mode (which gives 100% CPU
434 * load and slows down the load process that happens on the main GUI
435 * thread to several seconds). */
436 PlaySound (NULL, NULL, 0);
437#endif
438
439#ifdef Q_WS_MAC
440 ::darwinDisableIconsInMenus();
441#endif /* Q_WS_MAC */
442
443#ifdef Q_WS_X11
444 /* version check (major.minor are sensitive, fix number is ignored) */
445 if (VBoxGlobal::qtRTVersion() < (VBoxGlobal::qtCTVersion() & 0xFFFF00))
446 {
447 QString msg =
448 QApplication::tr ("Executable <b>%1</b> requires Qt %2.x, found Qt %3.")
449 .arg (qAppName())
450 .arg (VBoxGlobal::qtCTVersionString().section ('.', 0, 1))
451 .arg (VBoxGlobal::qtRTVersionString());
452 QMessageBox::critical (
453 0, QApplication::tr ("Incompatible Qt Library Error"),
454 msg, QMessageBox::Abort, 0);
455 qFatal ("%s", msg.toAscii().constData());
456 }
457#endif
458
459 /* load a translation based on the current locale */
460 VBoxGlobal::loadLanguage();
461
462 do
463 {
464 if (!vboxGlobal().isValid())
465 break;
466
467
468 if (vboxGlobal().processArgs())
469 return 0;
470
471 msgCenter().checkForMountedWrongUSB();
472
473 VBoxGlobalSettings settings = vboxGlobal().settings();
474 /* Process known keys */
475 bool noSelector = settings.isFeatureActive ("noSelector");
476
477 if (vboxGlobal().isVMConsoleProcess())
478 {
479#ifdef VBOX_GUI_WITH_SYSTRAY
480 if (vboxGlobal().trayIconInstall())
481 {
482 /* Nothing to do here yet. */
483 }
484#endif
485 if (vboxGlobal().startMachine (vboxGlobal().managedVMUuid()))
486 {
487 vboxGlobal().setMainWindow (vboxGlobal().vmWindow());
488 rc = a.exec();
489 }
490 }
491 else if (noSelector)
492 {
493 msgCenter().cannotRunInSelectorMode();
494 }
495 else
496 {
497#ifdef VBOX_BLEEDING_EDGE
498 msgCenter().showBEBWarning();
499#else
500# ifndef DEBUG
501 /* Check for BETA version */
502 QString vboxVersion (vboxGlobal().virtualBox().GetVersion());
503 if (vboxVersion.contains ("BETA"))
504 {
505 /* Allow to prevent this message */
506 QString str = vboxGlobal().virtualBox().
507 GetExtraData(GUI_PreventBetaWarning);
508 if (str != vboxVersion)
509 msgCenter().showBETAWarning();
510 }
511# endif
512#endif
513
514 vboxGlobal().setMainWindow (&vboxGlobal().selectorWnd());
515#ifdef VBOX_GUI_WITH_SYSTRAY
516 if (vboxGlobal().trayIconInstall())
517 {
518 /* Nothing to do here yet. */
519 }
520
521 if (false == vboxGlobal().isTrayMenu())
522 {
523#endif
524 vboxGlobal().selectorWnd().show();
525#ifdef VBOX_WITH_REGISTRATION_REQUEST
526 vboxGlobal().showRegistrationDialog (false /* aForce */);
527#endif
528#ifdef VBOX_GUI_WITH_SYSTRAY
529 }
530
531 do
532 {
533#endif
534 rc = a.exec();
535#ifdef VBOX_GUI_WITH_SYSTRAY
536 } while (vboxGlobal().isTrayMenu());
537#endif
538 }
539 }
540 while (0);
541 }
542
543 LogFlowFunc (("rc=%d\n", rc));
544 LogFlowFuncLeave();
545
546 return rc;
547}
548
549#ifndef VBOX_WITH_HARDENING
550
551int main (int argc, char **argv, char **envp)
552{
553 /* Initialize VBox Runtime. Initialize the SUPLib as well only if we
554 * are really about to start a VM. Don't do this if we are only starting
555 * the selector window. */
556 bool fInitSUPLib = false;
557 for (int i = 1; i < argc; i++)
558 {
559 /* NOTE: the check here must match the corresponding check for the
560 * options to start a VM in hardenedmain.cpp and VBoxGlobal.cpp exactly,
561 * otherwise there will be weird error messages. */
562 if ( !::strcmp(argv[i], "--startvm")
563 || !::strcmp(argv[i], "-startvm"))
564 {
565 fInitSUPLib = true;
566 break;
567 }
568 }
569
570 int rc = RTR3InitExe(argc, &argv, fInitSUPLib ? RTR3INIT_FLAGS_SUPLIB : 0);
571 if (RT_FAILURE(rc))
572 {
573 QApplication a (argc, &argv[0]);
574#ifdef Q_OS_SOLARIS
575 /* Use plastique look 'n feel for Solaris instead of the default motif (Qt 4.7.x) */
576 QApplication::setStyle (new QPlastiqueStyle);
577#endif
578 QString msgTitle = QApplication::tr ("VirtualBox - Runtime Error");
579 QString msgText = "<html>";
580
581 switch (rc)
582 {
583 case VERR_VM_DRIVER_NOT_INSTALLED:
584 case VERR_VM_DRIVER_LOAD_ERROR:
585 msgText += QApplication::tr (
586 "<b>Cannot access the kernel driver!</b><br/><br/>");
587# ifdef RT_OS_LINUX
588 msgText += g_QStrHintLinuxNoDriver;
589# else
590 msgText += g_QStrHintOtherNoDriver;
591# endif
592 break;
593# ifdef RT_OS_LINUX
594 case VERR_NO_MEMORY:
595 msgText += g_QStrHintLinuxNoMemory;
596 break;
597# endif
598 case VERR_VM_DRIVER_NOT_ACCESSIBLE:
599 msgText += QApplication::tr ("Kernel driver not accessible");
600 break;
601 case VERR_VM_DRIVER_VERSION_MISMATCH:
602# ifdef RT_OS_LINUX
603 msgText += g_QStrHintLinuxWrongDriverVersion;
604# else
605 msgText += g_QStrHintOtherWrongDriverVersion;
606# endif
607 break;
608 default:
609 msgText += QApplication::tr (
610 "Unknown error %2 during initialization of the Runtime"
611 ).arg (rc);
612 break;
613 }
614 msgText += "</html>";
615 QMessageBox::critical (
616 0, /* parent */
617 msgTitle,
618 msgText,
619 QMessageBox::Abort, /* button0 */
620 0); /* button1 */
621 return 1;
622 }
623
624 return TrustedMain (argc, argv, envp);
625}
626
627#else /* VBOX_WITH_HARDENING */
628
629/**
630 * Hardened main failed, report the error without any unnecessary fuzz.
631 *
632 * @remarks Do not call IPRT here unless really required, it might not be
633 * initialized.
634 */
635extern "C" DECLEXPORT(void) TrustedError (const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va)
636{
637# if defined(RT_OS_DARWIN)
638 ShutUpAppKit();
639# endif
640
641 /*
642 * Init the Qt application object. This is a bit hackish as we
643 * don't have the argument vector handy.
644 */
645 int argc = 0;
646 char *argv[2] = { NULL, NULL };
647 QApplication a (argc, &argv[0]);
648
649 /*
650 * Compose and show the error message.
651 */
652 QString msgTitle = QApplication::tr ("VirtualBox - Error In %1").arg (pszWhere);
653
654 char msgBuf[1024];
655 vsprintf (msgBuf, pszMsgFmt, va);
656
657 QString msgText = QApplication::tr (
658 "<html><b>%1 (rc=%2)</b><br/><br/>").arg (msgBuf).arg (rc);
659 switch (enmWhat)
660 {
661 case kSupInitOp_Driver:
662# ifdef RT_OS_LINUX
663 msgText += g_QStrHintLinuxNoDriver;
664# else
665 msgText += g_QStrHintOtherNoDriver;
666# endif
667 break;
668# ifdef RT_OS_LINUX
669 case kSupInitOp_IPRT:
670 if (rc == VERR_NO_MEMORY)
671 msgText += g_QStrHintLinuxNoMemory;
672 else
673# endif
674 if (rc == VERR_VM_DRIVER_VERSION_MISMATCH)
675# ifdef RT_OS_LINUX
676 msgText += g_QStrHintLinuxWrongDriverVersion;
677# else
678 msgText += g_QStrHintOtherWrongDriverVersion;
679# endif
680 else
681 msgText += g_QStrHintReinstall;
682 break;
683 case kSupInitOp_Integrity:
684 case kSupInitOp_RootCheck:
685 msgText += g_QStrHintReinstall;
686 break;
687 default:
688 /* no hints here */
689 break;
690 }
691 msgText += "</html>";
692
693# ifdef RT_OS_LINUX
694 sleep(2);
695# endif
696 QMessageBox::critical (
697 0, /* parent */
698 msgTitle, /* title */
699 msgText, /* text */
700 QMessageBox::Abort, /* button0 */
701 0); /* button1 */
702 qFatal ("%s", msgText.toAscii().constData());
703}
704
705#endif /* VBOX_WITH_HARDENING */
706
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use