void UIMachineWindow::retranslateUi() { /* Compose window-title prefix: */ m_strWindowTitlePrefix = VBOX_PRODUCT; #ifdef VBOX_BLEEDING_EDGE m_strWindowTitlePrefix += UIMachineWindow::tr(" EXPERIMENTAL build %1r%2 - %3") .arg(RTBldCfgVersion()) .arg(RTBldCfgRevisionStr()) .arg(VBOX_BLEEDING_EDGE); #endif /* VBOX_BLEEDING_EDGE */ /* Update appearance of the window-title: */ updateAppearanceOf(UIVisualElement_WindowTitle); }
/** * Main function */ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { /* Do not use a global namespace ("Global\\") for mutex name here, will blow up NT4 compatibility! */ HANDLE hMutexAppRunning = CreateMutex(NULL, FALSE, "VBoxTray"); if ( hMutexAppRunning != NULL && GetLastError() == ERROR_ALREADY_EXISTS) { /* Close the mutex for this application instance. */ CloseHandle (hMutexAppRunning); hMutexAppRunning = NULL; return 0; } LogRel(("VBoxTray: %s r%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr())); int rc = RTR3Init(); if (RT_SUCCESS(rc)) { rc = VbglR3Init(); if (RT_SUCCESS(rc)) rc = vboxTrayOpenBaseDriver(); } if (RT_SUCCESS(rc)) { /* Save instance handle. */ ghInstance = hInstance; hlpReportStatus(VBoxGuestFacilityStatus_Init); rc = vboxTrayCreateToolWindow(); if (RT_SUCCESS(rc)) { rc = vboxTraySetupSeamless(); if (RT_SUCCESS(rc)) { Log(("VBoxTray: Init successful\n")); rc = vboxTrayServiceMain(); if (RT_SUCCESS(rc)) hlpReportStatus(VBoxGuestFacilityStatus_Terminating); vboxTrayShutdownSeamless(); } vboxTrayDestroyToolWindow(); } if (RT_SUCCESS(rc)) hlpReportStatus(VBoxGuestFacilityStatus_Terminated); } if (RT_FAILURE(rc)) { LogRel(("VBoxTray: Error while starting, rc=%Rrc\n", rc)); hlpReportStatus(VBoxGuestFacilityStatus_Failed); } LogRel(("VBoxTray: Ended\n")); vboxTrayCloseBaseDriver(); /* Release instance mutex. */ if (hMutexAppRunning != NULL) { CloseHandle(hMutexAppRunning); hMutexAppRunning = NULL; } VbglR3Term(); return RT_SUCCESS(rc) ? 0 : 1; }
int main(int argc, char **argv) { RTEXITCODE rcExit; /* * Init globals and such. */ int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); g_pszProgName = RTPathFilename(argv[0]); #ifdef DEBUG rc = RTCritSectInit(&g_csLog); AssertRC(rc); #endif #ifdef VBOXSERVICE_TOOLBOX /* * Run toolbox code before all other stuff since these things are simpler * shell/file/text utility like programs that just happens to be inside * VBoxService and shouldn't be subject to /dev/vboxguest, pid-files and * global mutex restrictions. */ if (VBoxServiceToolboxMain(argc, argv, &rcExit)) return rcExit; #endif /* * Connect to the kernel part before daemonizing so we can fail and * complain if there is some kind of problem. We need to initialize the * guest lib *before* we do the pre-init just in case one of services needs * do to some initial stuff with it. */ VBoxServiceVerbose(2, "Calling VbgR3Init()\n"); rc = VbglR3Init(); if (RT_FAILURE(rc)) { if (rc == VERR_ACCESS_DENIED) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Insufficient privileges to start %s! Please start with Administrator/root privileges!\n", g_pszProgName); return RTMsgErrorExit(RTEXITCODE_FAILURE, "VbglR3Init failed with rc=%Rrc\n", rc); } #ifdef RT_OS_WINDOWS /* * Check if we're the specially spawned VBoxService.exe process that * handles page fusion. This saves an extra executable. */ if ( argc == 2 && !strcmp(argv[1], "--pagefusionfork")) return VBoxServicePageSharingInitFork(); #endif char szLogFile[RTPATH_MAX + 128] = ""; /* * Parse the arguments. * * Note! This code predates RTGetOpt, thus the manual parsing. */ bool fDaemonize = true; bool fDaemonized = false; for (int i = 1; i < argc; i++) { const char *psz = argv[i]; if (*psz != '-') return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown argument '%s'\n", psz); psz++; /* translate long argument to short */ if (*psz == '-') { psz++; size_t cch = strlen(psz); #define MATCHES(strconst) ( cch == sizeof(strconst) - 1 \ && !memcmp(psz, strconst, sizeof(strconst) - 1) ) if (MATCHES("foreground")) psz = "f"; else if (MATCHES("verbose")) psz = "v"; else if (MATCHES("version")) psz = "V"; else if (MATCHES("help")) psz = "h"; else if (MATCHES("interval")) psz = "i"; #ifdef RT_OS_WINDOWS else if (MATCHES("register")) psz = "r"; else if (MATCHES("unregister")) psz = "u"; #endif else if (MATCHES("logfile")) psz = "l"; else if (MATCHES("daemonized")) { fDaemonized = true; continue; } else { bool fFound = false; if (cch > sizeof("enable-") && !memcmp(psz, "enable-", sizeof("enable-") - 1)) for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++) if ((fFound = !RTStrICmp(psz + sizeof("enable-") - 1, g_aServices[j].pDesc->pszName))) g_aServices[j].fEnabled = true; if (cch > sizeof("disable-") && !memcmp(psz, "disable-", sizeof("disable-") - 1)) for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++) if ((fFound = !RTStrICmp(psz + sizeof("disable-") - 1, g_aServices[j].pDesc->pszName))) g_aServices[j].fEnabled = false; if (cch > sizeof("only-") && !memcmp(psz, "only-", sizeof("only-") - 1)) for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) { g_aServices[j].fEnabled = !RTStrICmp(psz + sizeof("only-") - 1, g_aServices[j].pDesc->pszName); if (g_aServices[j].fEnabled) fFound = true; } if (!fFound) { rcExit = vboxServiceLazyPreInit(); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++) { rc = g_aServices[j].pDesc->pfnOption(NULL, argc, argv, &i); fFound = rc == VINF_SUCCESS; if (fFound) break; if (rc != -1) return rc; } } if (!fFound) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option '%s'\n", argv[i]); continue; } #undef MATCHES } /* handle the string of short options. */ do { switch (*psz) { case 'i': rc = VBoxServiceArgUInt32(argc, argv, psz + 1, &i, &g_DefaultInterval, 1, (UINT32_MAX / 1000) - 1); if (rc) return rc; psz = NULL; break; case 'f': fDaemonize = false; break; case 'v': g_cVerbosity++; break; case 'V': RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); return RTEXITCODE_SUCCESS; case 'h': case '?': return vboxServiceUsage(); #ifdef RT_OS_WINDOWS case 'r': return VBoxServiceWinInstall(); case 'u': return VBoxServiceWinUninstall(); #endif case 'l': { rc = VBoxServiceArgString(argc, argv, psz + 1, &i, szLogFile, sizeof(szLogFile)); if (rc) return rc; psz = NULL; break; } default: { rcExit = vboxServiceLazyPreInit(); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; bool fFound = false; for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) { rc = g_aServices[j].pDesc->pfnOption(&psz, argc, argv, &i); fFound = rc == VINF_SUCCESS; if (fFound) break; if (rc != -1) return rc; } if (!fFound) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option '%c' (%s)\n", *psz, argv[i]); break; } } } while (psz && *++psz); } /* Check that at least one service is enabled. */ if (vboxServiceCountEnabledServices() == 0) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "At least one service must be enabled\n"); rc = VBoxServiceLogCreate(strlen(szLogFile) ? szLogFile : NULL); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create release log (%s, %Rrc)", strlen(szLogFile) ? szLogFile : "<None>", rc); /* Call pre-init if we didn't do it already. */ rcExit = vboxServiceLazyPreInit(); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; #ifdef RT_OS_WINDOWS /* * Make sure only one instance of VBoxService runs at a time. Create a * global mutex for that. * * Note! The \\Global\ namespace was introduced with Win2K, thus the * version check. * Note! If the mutex exists CreateMutex will open it and set last error to * ERROR_ALREADY_EXISTS. */ OSVERSIONINFOEX OSInfoEx; RT_ZERO(OSInfoEx); OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); SetLastError(NO_ERROR); HANDLE hMutexAppRunning; if ( GetVersionEx((LPOSVERSIONINFO)&OSInfoEx) && OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT && OSInfoEx.dwMajorVersion >= 5 /* NT 5.0 a.k.a W2K */) hMutexAppRunning = CreateMutex(NULL, FALSE, "Global\\" VBOXSERVICE_NAME); else hMutexAppRunning = CreateMutex(NULL, FALSE, VBOXSERVICE_NAME); if (hMutexAppRunning == NULL) { DWORD dwErr = GetLastError(); if ( dwErr == ERROR_ALREADY_EXISTS || dwErr == ERROR_ACCESS_DENIED) { VBoxServiceError("%s is already running! Terminating.", g_pszProgName); return RTEXITCODE_FAILURE; } VBoxServiceError("CreateMutex failed with last error %u! Terminating", GetLastError()); return RTEXITCODE_FAILURE; } #else /* !RT_OS_WINDOWS */ /** @todo Add PID file creation here? */ #endif /* !RT_OS_WINDOWS */ VBoxServiceVerbose(0, "%s r%s started. Verbose level = %d\n", RTBldCfgVersion(), RTBldCfgRevisionStr(), g_cVerbosity); /* * Daemonize if requested. */ if (fDaemonize && !fDaemonized) { #ifdef RT_OS_WINDOWS VBoxServiceVerbose(2, "Starting service dispatcher ...\n"); rcExit = VBoxServiceWinEnterCtrlDispatcher(); #else VBoxServiceVerbose(1, "Daemonizing...\n"); rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */); if (RT_FAILURE(rc)) return VBoxServiceError("Daemon failed: %Rrc\n", rc); /* in-child */ #endif } #ifdef RT_OS_WINDOWS else #endif { /* * Windows: We're running the service as a console application now. Start the * services, enter the main thread's run loop and stop them again * when it returns. * * POSIX: This is used for both daemons and console runs. Start all services * and return immediately. */ #ifdef RT_OS_WINDOWS # ifndef RT_OS_NT4 /* Install console control handler. */ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)VBoxServiceConsoleControlHandler, TRUE /* Add handler */)) { VBoxServiceError("Unable to add console control handler, error=%ld\n", GetLastError()); /* Just skip this error, not critical. */ } # endif /* !RT_OS_NT4 */ #endif /* RT_OS_WINDOWS */ rc = VBoxServiceStartServices(); rcExit = RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; if (RT_SUCCESS(rc)) VBoxServiceMainWait(); #ifdef RT_OS_WINDOWS # ifndef RT_OS_NT4 /* Uninstall console control handler. */ if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)NULL, FALSE /* Remove handler */)) { VBoxServiceError("Unable to remove console control handler, error=%ld\n", GetLastError()); /* Just skip this error, not critical. */ } # endif /* !RT_OS_NT4 */ #else /* !RT_OS_WINDOWS */ /* On Windows - since we're running as a console application - we already stopped all services * through the console control handler. So only do the stopping of services here on other platforms * where the break/shutdown/whatever signal was just received. */ VBoxServiceStopServices(); #endif /* RT_OS_WINDOWS */ } VBoxServiceReportStatus(VBoxGuestFacilityStatus_Terminated); #ifdef RT_OS_WINDOWS /* * Cleanup mutex. */ CloseHandle(hMutexAppRunning); #endif VBoxServiceVerbose(0, "Ended.\n"); #ifdef DEBUG RTCritSectDelete(&g_csLog); //RTMemTrackerDumpAllToStdOut(); #endif VBoxServiceLogDestroy(); return rcExit; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/) { LPCTSTR lpCmdLine = GetCommandLine(); /* this line necessary for _ATL_MIN_CRT */ /* * Need to parse the command line before initializing the VBox runtime. */ TCHAR szTokens[] = _T("-/"); LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens); while (lpszToken != NULL) { if (WordCmpI(lpszToken, _T("Embedding")) == 0) { /* %HOMEDRIVE%%HOMEPATH% */ wchar_t wszHome[RTPATH_MAX]; DWORD cEnv = GetEnvironmentVariable(L"HOMEDRIVE", &wszHome[0], RTPATH_MAX); if (cEnv && cEnv < RTPATH_MAX) { DWORD cwc = cEnv; /* doesn't include NUL */ cEnv = GetEnvironmentVariable(L"HOMEPATH", &wszHome[cEnv], RTPATH_MAX - cwc); if (cEnv && cEnv < RTPATH_MAX - cwc) { /* If this fails there is nothing we can do. Ignore. */ SetCurrentDirectory(wszHome); } } } lpszToken = FindOneOf(lpszToken, szTokens); } /* * Initialize the VBox runtime without loading * the support driver. */ int argc = __argc; char **argv = __argv; RTR3InitExe(argc, &argv, 0); /* Note that all options are given lowercase/camel case/uppercase to * approximate case insensitive matching, which RTGetOpt doesn't offer. */ static const RTGETOPTDEF s_aOptions[] = { { "--embedding", 'e', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "-embedding", 'e', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "/embedding", 'e', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "--unregserver", 'u', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "-unregserver", 'u', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "/unregserver", 'u', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "--regserver", 'r', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "-regserver", 'r', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "/regserver", 'r', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "--reregserver", 'f', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "-reregserver", 'f', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "/reregserver", 'f', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "--helper", 'H', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "-helper", 'H', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "/helper", 'H', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "--logfile", 'F', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "-logfile", 'F', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "/logfile", 'F', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "--logrotate", 'R', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "-logrotate", 'R', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "/logrotate", 'R', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "--logsize", 'S', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_ICASE }, { "-logsize", 'S', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_ICASE }, { "/logsize", 'S', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_ICASE }, { "--loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "-loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "/loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, }; bool fRun = true; bool fRegister = false; bool fUnregister = false; const char *pszPipeName = NULL; const char *pszLogFile = NULL; uint32_t cHistory = 10; // enable log rotation, 10 files uint32_t uHistoryFileTime = RT_SEC_1DAY; // max 1 day per file uint64_t uHistoryFileSize = 100 * _1M; // max 100MB per file RTGETOPTSTATE GetOptState; int vrc = RTGetOptInit(&GetOptState, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/); AssertRC(vrc); RTGETOPTUNION ValueUnion; while ((vrc = RTGetOpt(&GetOptState, &ValueUnion))) { switch (vrc) { case 'e': /* already handled above */ break; case 'u': fUnregister = true; fRun = false; break; case 'r': fRegister = true; fRun = false; break; case 'f': fUnregister = true; fRegister = true; fRun = false; break; case 'H': pszPipeName = ValueUnion.psz; if (!pszPipeName) pszPipeName = ""; fRun = false; break; case 'F': pszLogFile = ValueUnion.psz; break; case 'R': cHistory = ValueUnion.u32; break; case 'S': uHistoryFileSize = ValueUnion.u64; break; case 'I': uHistoryFileTime = ValueUnion.u32; break; case 'h': { TCHAR txt[]= L"Options:\n\n" L"/RegServer:\tregister COM out-of-proc server\n" L"/UnregServer:\tunregister COM out-of-proc server\n" L"/ReregServer:\tunregister and register COM server\n" L"no options:\trun the server"; TCHAR title[]=_T("Usage"); fRun = false; MessageBox(NULL, txt, title, MB_OK); return 0; } case 'V': { char *psz = NULL; RTStrAPrintf(&psz, "%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); PRTUTF16 txt = NULL; RTStrToUtf16(psz, &txt); TCHAR title[]=_T("Version"); fRun = false; MessageBox(NULL, txt, title, MB_OK); RTStrFree(psz); RTUtf16Free(txt); return 0; } default: /** @todo this assumes that stderr is visible, which is not * true for standard Windows applications. */ /* continue on command line errors... */ RTGetOptPrintError(vrc, &ValueUnion); } } /* Only create the log file when running VBoxSVC normally, but not when * registering/unregistering or calling the helper functionality. */ if (fRun) { if (!pszLogFile) { char szLogFile[RTPATH_MAX]; vrc = com::GetVBoxUserHomeDirectory(szLogFile, sizeof(szLogFile)); if (RT_SUCCESS(vrc)) vrc = RTPathAppend(szLogFile, sizeof(szLogFile), "VBoxSVC.log"); if (RT_SUCCESS(vrc)) pszLogFile = RTStrDup(szLogFile); } char szError[RTPATH_MAX + 128]; vrc = com::VBoxLogRelCreate("COM Server", pszLogFile, RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG, "all", "VBOXSVC_RELEASE_LOG", RTLOGDEST_FILE, UINT32_MAX /* cMaxEntriesPerGroup */, cHistory, uHistoryFileTime, uHistoryFileSize, szError, sizeof(szError)); if (RT_FAILURE(vrc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "failed to open release log (%s, %Rrc)", szError, vrc); } int nRet = 0; HRESULT hRes = com::Initialize(); _ASSERTE(SUCCEEDED(hRes)); _Module.Init(ObjectMap, hInstance, &LIBID_VirtualBox); _Module.dwThreadID = GetCurrentThreadId(); if (!fRun) { if (fUnregister) { _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, FALSE); nRet = _Module.UnregisterServer(TRUE); } if (fRegister) { _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, TRUE); nRet = _Module.RegisterServer(TRUE); } if (pszPipeName) { Log(("SVCMAIN: Processing Helper request (cmdline=\"%s\")...\n", pszPipeName)); if (!*pszPipeName) vrc = VERR_INVALID_PARAMETER; if (RT_SUCCESS(vrc)) { /* do the helper job */ SVCHlpServer server; vrc = server.open(pszPipeName); if (RT_SUCCESS(vrc)) vrc = server.run(); } if (RT_FAILURE(vrc)) { Log(("SVCMAIN: Failed to process Helper request (%Rrc).", vrc)); nRet = 1; } } } else { _Module.StartMonitor(); #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED) hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED); _ASSERTE(SUCCEEDED(hRes)); hRes = CoResumeClassObjects(); #else hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE); #endif _ASSERTE(SUCCEEDED(hRes)); MSG msg; while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg); _Module.RevokeClassObjects(); Sleep(dwPause); //wait for any threads to finish } _Module.Term(); com::Shutdown(); Log(("SVCMAIN: Returning, COM server process ends.\n")); return nRet; }
/** * Release logger callback. * * @return IPRT status code. * @param pLoggerRelease * @param enmPhase * @param pfnLog */ static void VBoxServiceLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog) { /* Some introductory information. */ static RTTIMESPEC s_TimeSpec; char szTmp[256]; if (enmPhase == RTLOGPHASE_BEGIN) RTTimeNow(&s_TimeSpec); RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp)); switch (enmPhase) { case RTLOGPHASE_BEGIN: { pfnLog(pLoggerRelease, "VBoxService %s r%s (verbosity: %d) %s (%s %s) release log\n" "Log opened %s\n", RTBldCfgVersion(), RTBldCfgRevisionStr(), g_cVerbosity, VBOX_BUILD_TARGET, __DATE__, __TIME__, szTmp); int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pLoggerRelease, "OS Product: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pLoggerRelease, "OS Release: %s\n", szTmp); vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp)); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pLoggerRelease, "OS Version: %s\n", szTmp); if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) pfnLog(pLoggerRelease, "OS Service Pack: %s\n", szTmp); /* the package type is interesting for Linux distributions */ char szExecName[RTPATH_MAX]; char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName)); pfnLog(pLoggerRelease, "Executable: %s\n" "Process ID: %u\n" "Package type: %s" #ifdef VBOX_OSE " (OSE)" #endif "\n", pszExecName ? pszExecName : "unknown", RTProcSelf(), VBOX_PACKAGE_STRING); break; } case RTLOGPHASE_PREROTATE: pfnLog(pLoggerRelease, "Log rotated - Log started %s\n", szTmp); break; case RTLOGPHASE_POSTROTATE: pfnLog(pLoggerRelease, "Log continuation - Log started %s\n", szTmp); break; case RTLOGPHASE_END: pfnLog(pLoggerRelease, "End of log file - Log started %s\n", szTmp); break; default: /* nothing */ ; } }
/** * Parses the options. * * @returns RTEXITCODE_SUCCESS on success. * @param argc Argument count . * @param argv Argument vector. * @param pfExit Set to @c true if we should exit. */ static RTEXITCODE ParseOptions(int argc, char **argv, bool *pfExit) { /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--only", 'o', RTGETOPT_REQ_STRING }, { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, { "--lock" , 'l', RTGETOPT_REQ_NOTHING }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, }; bool fAll = true; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /* fFlags */); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch(ch) { case 'o': { uint32_t i; if (fAll) { fAll = false; for (i = 0; i < RT_ELEMENTS(g_aModules); i++) g_aModules[i].fPreload = false; } i = RT_ELEMENTS(g_aModules); while (i-- > 0) if (!strcmp(ValueUnion.psz, g_aModules[i].pszName)) { g_aModules[i].fPreload = true; break; } if (i > RT_ELEMENTS(g_aModules)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "No known module '%s'", ValueUnion.psz); break; } case 'v': g_cVerbose++; break; case 'q': g_cVerbose = 0; break; case 'l': g_fLockDown = true; break; case 'h': RTPrintf(VBOX_PRODUCT " VMM ring-0 Module Preloader Version " VBOX_VERSION_STRING "(C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\n" "All rights reserved.\n" "\n" "Usage: VBoxVMMPreload [-hlqvV] [-o|--only <mod>]\n" "\n"); *pfExit = true; return RTEXITCODE_SUCCESS; case 'V': RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); *pfExit = true; return RTEXITCODE_SUCCESS; default: return RTGetOptPrintError(ch, &ValueUnion); } } return RTEXITCODE_SUCCESS; }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB); /* * Options are mandatory. */ if (argc <= 1) return usage(); /* * Parse the options. */ static const RTGETOPTDEF s_aOptions[] = { { "--flags", 'f', RTGETOPT_REQ_STRING }, { "--groups", 'g', RTGETOPT_REQ_STRING }, { "--dest", 'd', RTGETOPT_REQ_STRING }, { "--what", 'o', RTGETOPT_REQ_STRING }, { "--which", 'l', RTGETOPT_REQ_STRING }, }; const char *pszFlags = ""; const char *pszGroups = ""; const char *pszDest = ""; SUPLOGGER enmWhich = SUPLOGGER_DEBUG; enum { kSupLoggerCtl_Set, kSupLoggerCtl_Create, kSupLoggerCtl_Destroy } enmWhat = kSupLoggerCtl_Set; int ch; int i = 1; RTGETOPTUNION Val; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &Val))) { switch (ch) { case 'f': pszFlags = Val.psz; break; case 'g': pszGroups = Val.psz; break; case 'd': pszDest = Val.psz; break; case 'o': if (!strcmp(Val.psz, "set")) enmWhat = kSupLoggerCtl_Set; else if (!strcmp(Val.psz, "create")) enmWhat = kSupLoggerCtl_Create; else if (!strcmp(Val.psz, "destroy")) enmWhat = kSupLoggerCtl_Destroy; else { RTStrmPrintf(g_pStdErr, "SUPLoggerCtl: error: Unknown operation '%s'.\n", Val.psz); return 1; } break; case 'l': if (!strcmp(Val.psz, "debug")) enmWhich = SUPLOGGER_DEBUG; else if (!strcmp(Val.psz, "release")) enmWhich = SUPLOGGER_RELEASE; else { RTStrmPrintf(g_pStdErr, "SUPLoggerCtl: error: Unknown logger '%s'.\n", Val.psz); return 1; } break; case 'h': return usage(); case 'V': RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); return 0; case VINF_GETOPT_NOT_OPTION: RTStrmPrintf(g_pStdErr, "SUPLoggerCtl: error: Unexpected argument '%s'.\n", Val.psz); return 1; default: return RTGetOptPrintError(ch, &Val); } } /* * Do the requested job. */ int rc; switch (enmWhat) { case kSupLoggerCtl_Set: rc = SUPR3LoggerSettings(enmWhich, pszFlags, pszGroups, pszDest); break; case kSupLoggerCtl_Create: rc = SUPR3LoggerCreate(enmWhich, pszFlags, pszGroups, pszDest); break; case kSupLoggerCtl_Destroy: rc = SUPR3LoggerDestroy(enmWhich); break; default: rc = VERR_INTERNAL_ERROR; break; } if (RT_SUCCESS(rc)) RTPrintf("SUPLoggerCtl: Success\n"); else RTStrmPrintf(g_pStdErr, "SUPLoggerCtl: error: rc=%Rrc\n", rc); return RT_SUCCESS(rc) ? 0 : 1; }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--iterations", 'i', RTGETOPT_REQ_UINT32 }, { "--num-pages", 'n', RTGETOPT_REQ_UINT32 }, { "--page-at-a-time", 'c', RTGETOPT_REQ_UINT32 }, { "--page-file", 'f', RTGETOPT_REQ_STRING }, { "--offset", 'o', RTGETOPT_REQ_UINT64 }, }; const char *pszPageFile = NULL; uint64_t offPageFile = 0; uint32_t cIterations = 1; uint32_t cPagesAtATime = 1; RTGETOPTUNION Val; RTGETOPTSTATE State; int rc = RTGetOptInit(&State, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, 0); AssertRCReturn(rc, 1); while ((rc = RTGetOpt(&State, &Val))) { switch (rc) { case 'n': g_cPages = Val.u32; if (g_cPages * PAGE_SIZE * 4 / (PAGE_SIZE * 4) != g_cPages) return Error("The specified page count is too high: %#x (%#llx bytes)\n", g_cPages, (uint64_t)g_cPages * PAGE_SHIFT); if (g_cPages < 1) return Error("The specified page count is too low: %#x\n", g_cPages); break; case 'i': cIterations = Val.u32; if (cIterations < 1) return Error("The number of iterations must be 1 or higher\n"); break; case 'c': cPagesAtATime = Val.u32; if (cPagesAtATime < 1 || cPagesAtATime > 10240) return Error("The specified pages-at-a-time count is out of range: %#x\n", cPagesAtATime); break; case 'f': pszPageFile = Val.psz; break; case 'o': offPageFile = Val.u64; break; case 'O': offPageFile = Val.u64 * PAGE_SIZE; break; case 'h': RTPrintf("syntax: tstCompressionBenchmark [options]\n" "\n" "Options:\n" " -h, --help\n" " Show this help page\n" " -i, --iterations <num>\n" " The number of iterations.\n" " -n, --num-pages <pages>\n" " The number of pages.\n" " -c, --pages-at-a-time <pages>\n" " Number of pages at a time.\n" " -f, --page-file <filename>\n" " File or device to read the page from. The default\n" " is to generate some garbage.\n" " -o, --offset <file-offset>\n" " Offset into the page file to start reading at.\n"); return 0; case 'V': RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); return 0; default: return RTGetOptPrintError(rc, &Val); } } g_cbPages = g_cPages * PAGE_SIZE; uint64_t cbTotal = (uint64_t)g_cPages * PAGE_SIZE * cIterations; uint64_t cbTotalKB = cbTotal / _1K; if (cbTotal / cIterations != g_cbPages) return Error("cPages * cIterations -> overflow\n"); /* * Gather the test memory. */ if (pszPageFile) { size_t cbFile; rc = RTFileReadAllEx(pszPageFile, offPageFile, g_cbPages, RTFILE_RDALL_O_DENY_NONE, (void **)&g_pabSrc, &cbFile); if (RT_FAILURE(rc)) return Error("Error reading %zu bytes from %s at %llu: %Rrc\n", g_cbPages, pszPageFile, offPageFile, rc); if (cbFile != g_cbPages) return Error("Error reading %zu bytes from %s at %llu: got %zu bytes\n", g_cbPages, pszPageFile, offPageFile, cbFile); } else { g_pabSrc = (uint8_t *)RTMemAlloc(g_cbPages); if (g_pabSrc) { /* Just fill it with something - warn about the low quality of the something. */ RTPrintf("tstCompressionBenchmark: WARNING! No input file was specified so the source\n" "buffer will be filled with generated data of questionable quality.\n"); #ifdef RT_OS_LINUX RTPrintf("To get real RAM on linux: sudo dd if=/dev/mem ... \n"); #endif uint8_t *pb = g_pabSrc; uint8_t *pbEnd = &g_pabSrc[g_cbPages]; for (; pb != pbEnd; pb += 16) { char szTmp[17]; RTStrPrintf(szTmp, sizeof(szTmp), "aaaa%08Xzzzz", (uint32_t)(uintptr_t)pb); memcpy(pb, szTmp, 16); } } } g_pabDecompr = (uint8_t *)RTMemAlloc(g_cbPages); g_cbComprAlloc = RT_MAX(g_cbPages * 2, 256 * PAGE_SIZE); g_pabCompr = (uint8_t *)RTMemAlloc(g_cbComprAlloc); if (!g_pabSrc || !g_pabDecompr || !g_pabCompr) return Error("failed to allocate memory buffers (g_cPages=%#x)\n", g_cPages); /* * Double loop compressing and uncompressing the data, where the outer does * the specified number of iterations while the inner applies the different * compression algorithms. */ struct { /** The time spent decompressing. */ uint64_t cNanoDecompr; /** The time spent compressing. */ uint64_t cNanoCompr; /** The size of the compressed data. */ uint64_t cbCompr; /** First error. */ int rc; /** The compression style: block or stream. */ bool fBlock; /** Compression type. */ RTZIPTYPE enmType; /** Compression level. */ RTZIPLEVEL enmLevel; /** Method name. */ const char *pszName; } aTests[] = { { 0, 0, 0, VINF_SUCCESS, false, RTZIPTYPE_STORE, RTZIPLEVEL_DEFAULT, "RTZip/Store" }, { 0, 0, 0, VINF_SUCCESS, false, RTZIPTYPE_LZF, RTZIPLEVEL_DEFAULT, "RTZip/LZF" }, /* { 0, 0, 0, VINF_SUCCESS, false, RTZIPTYPE_ZLIB, RTZIPLEVEL_DEFAULT, "RTZip/zlib" }, - slow plus it randomly hits VERR_GENERAL_FAILURE atm. */ { 0, 0, 0, VINF_SUCCESS, true, RTZIPTYPE_STORE, RTZIPLEVEL_DEFAULT, "RTZipBlock/Store" }, { 0, 0, 0, VINF_SUCCESS, true, RTZIPTYPE_LZF, RTZIPLEVEL_DEFAULT, "RTZipBlock/LZF" }, { 0, 0, 0, VINF_SUCCESS, true, RTZIPTYPE_LZJB, RTZIPLEVEL_DEFAULT, "RTZipBlock/LZJB" }, { 0, 0, 0, VINF_SUCCESS, true, RTZIPTYPE_LZO, RTZIPLEVEL_DEFAULT, "RTZipBlock/LZO" }, }; RTPrintf("tstCompressionBenchmark: TESTING.."); for (uint32_t i = 0; i < cIterations; i++) { for (uint32_t j = 0; j < RT_ELEMENTS(aTests); j++) { if (RT_FAILURE(aTests[j].rc)) continue; memset(g_pabCompr, 0xaa, g_cbComprAlloc); memset(g_pabDecompr, 0xcc, g_cbPages); g_cbCompr = 0; g_offComprIn = 0; RTPrintf("."); RTStrmFlush(g_pStdOut); /* * Compress it. */ uint64_t NanoTS = RTTimeNanoTS(); if (aTests[j].fBlock) { size_t cbLeft = g_cbComprAlloc; uint8_t const *pbSrcPage = g_pabSrc; uint8_t *pbDstPage = g_pabCompr; for (size_t iPage = 0; iPage < g_cPages; iPage += cPagesAtATime) { AssertBreakStmt(cbLeft > PAGE_SIZE * 4, aTests[j].rc = rc = VERR_BUFFER_OVERFLOW); uint32_t *pcb = (uint32_t *)pbDstPage; pbDstPage += sizeof(uint32_t); cbLeft -= sizeof(uint32_t); size_t cbSrc = RT_MIN(g_cPages - iPage, cPagesAtATime) * PAGE_SIZE; size_t cbDst; rc = RTZipBlockCompress(aTests[j].enmType, aTests[j].enmLevel, 0 /*fFlags*/, pbSrcPage, cbSrc, pbDstPage, cbLeft, &cbDst); if (RT_FAILURE(rc)) { Error("RTZipBlockCompress failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc); aTests[j].rc = rc; break; } *pcb = (uint32_t)cbDst; cbLeft -= cbDst; pbDstPage += cbDst; pbSrcPage += cbSrc; } if (RT_FAILURE(rc)) continue; g_cbCompr = pbDstPage - g_pabCompr; } else { PRTZIPCOMP pZipComp; rc = RTZipCompCreate(&pZipComp, NULL, ComprOutCallback, aTests[j].enmType, aTests[j].enmLevel); if (RT_FAILURE(rc)) { Error("Failed to create the compressor for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc); aTests[j].rc = rc; continue; } uint8_t const *pbSrcPage = g_pabSrc; for (size_t iPage = 0; iPage < g_cPages; iPage += cPagesAtATime) { size_t cb = RT_MIN(g_cPages - iPage, cPagesAtATime) * PAGE_SIZE; rc = RTZipCompress(pZipComp, pbSrcPage, cb); if (RT_FAILURE(rc)) { Error("RTZipCompress failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc); aTests[j].rc = rc; break; } pbSrcPage += cb; } if (RT_FAILURE(rc)) continue; rc = RTZipCompFinish(pZipComp); if (RT_FAILURE(rc)) { Error("RTZipCompFinish failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc); aTests[j].rc = rc; break; } RTZipCompDestroy(pZipComp); } NanoTS = RTTimeNanoTS() - NanoTS; aTests[j].cbCompr += g_cbCompr; aTests[j].cNanoCompr += NanoTS; /* * Decompress it. */ NanoTS = RTTimeNanoTS(); if (aTests[j].fBlock) { uint8_t const *pbSrcPage = g_pabCompr; size_t cbLeft = g_cbCompr; uint8_t *pbDstPage = g_pabDecompr; for (size_t iPage = 0; iPage < g_cPages; iPage += cPagesAtATime) { size_t cbDst = RT_MIN(g_cPages - iPage, cPagesAtATime) * PAGE_SIZE; size_t cbSrc = *(uint32_t *)pbSrcPage; pbSrcPage += sizeof(uint32_t); cbLeft -= sizeof(uint32_t); rc = RTZipBlockDecompress(aTests[j].enmType, 0 /*fFlags*/, pbSrcPage, cbSrc, &cbSrc, pbDstPage, cbDst, &cbDst); if (RT_FAILURE(rc)) { Error("RTZipBlockDecompress failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc); aTests[j].rc = rc; break; } pbDstPage += cbDst; cbLeft -= cbSrc; pbSrcPage += cbSrc; } if (RT_FAILURE(rc)) continue; } else { PRTZIPDECOMP pZipDecomp; rc = RTZipDecompCreate(&pZipDecomp, NULL, DecomprInCallback); if (RT_FAILURE(rc)) { Error("Failed to create the decompressor for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc); aTests[j].rc = rc; continue; } uint8_t *pbDstPage = g_pabDecompr; for (size_t iPage = 0; iPage < g_cPages; iPage += cPagesAtATime) { size_t cb = RT_MIN(g_cPages - iPage, cPagesAtATime) * PAGE_SIZE; rc = RTZipDecompress(pZipDecomp, pbDstPage, cb, NULL); if (RT_FAILURE(rc)) { Error("RTZipDecompress failed for '%s' (#%u): %Rrc\n", aTests[j].pszName, j, rc); aTests[j].rc = rc; break; } pbDstPage += cb; } RTZipDecompDestroy(pZipDecomp); if (RT_FAILURE(rc)) continue; } NanoTS = RTTimeNanoTS() - NanoTS; aTests[j].cNanoDecompr += NanoTS; if (memcmp(g_pabDecompr, g_pabSrc, g_cbPages)) { Error("The compressed data doesn't match the source for '%s' (%#u)\n", aTests[j].pszName, j); aTests[j].rc = VERR_BAD_EXE_FORMAT; continue; } } } if (RT_SUCCESS(rc)) RTPrintf("\n"); /* * Report the results. */ rc = 0; RTPrintf("tstCompressionBenchmark: BEGIN RESULTS\n"); RTPrintf("%-20s Compression Decompression\n", ""); RTPrintf("%-20s In Out Ratio Size In Out\n", "Method"); RTPrintf("%.20s-----------------------------------------------------------------------------------------\n", "---------------------------------------------"); for (uint32_t j = 0; j < RT_ELEMENTS(aTests); j++) { if (RT_SUCCESS(aTests[j].rc)) { unsigned uComprSpeedIn = (unsigned)(cbTotalKB / (long double)aTests[j].cNanoCompr * 1000000000.0); unsigned uComprSpeedOut = (unsigned)(aTests[j].cbCompr / (long double)aTests[j].cNanoCompr * 1000000000.0 / 1024); unsigned uRatio = (unsigned)(aTests[j].cbCompr / cIterations * 100 / g_cbPages); unsigned uDecomprSpeedIn = (unsigned)(aTests[j].cbCompr / (long double)aTests[j].cNanoDecompr * 1000000000.0 / 1024); unsigned uDecomprSpeedOut = (unsigned)(cbTotalKB / (long double)aTests[j].cNanoDecompr * 1000000000.0); RTPrintf("%-20s %'9u KB/s %'9u KB/s %3u%% %'11llu bytes %'9u KB/s %'9u KB/s", aTests[j].pszName, uComprSpeedIn, uComprSpeedOut, uRatio, aTests[j].cbCompr / cIterations, uDecomprSpeedIn, uDecomprSpeedOut); #if 0 RTPrintf(" [%'14llu / %'14llu ns]\n", aTests[j].cNanoCompr / cIterations, aTests[j].cNanoDecompr / cIterations); #else RTPrintf("\n"); #endif } else { RTPrintf("%-20s: %Rrc\n", aTests[j].pszName, aTests[j].rc); rc = 1; } } if (pszPageFile) RTPrintf("Input: %'10zu pages from '%s' starting at offset %'lld (%#llx)\n" " %'11zu bytes\n", g_cPages, pszPageFile, offPageFile, offPageFile, g_cbPages); else RTPrintf("Input: %'10zu pages of generated rubbish %'11zu bytes\n", g_cPages, g_cbPages); /* * Count zero pages in the data set. */ size_t cZeroPages = 0; for (size_t iPage = 0; iPage < g_cPages; iPage++) { if (!ASMMemIsAllU32(&g_pabSrc[iPage * PAGE_SIZE], PAGE_SIZE, 0)) cZeroPages++; } RTPrintf(" %'10zu zero pages (%u %%)\n", cZeroPages, cZeroPages * 100 / g_cPages); /* * A little extension to the test, benchmark relevant CRCs. */ RTPrintf("\n" "tstCompressionBenchmark: Hash/CRC - All In One\n"); tstBenchmarkCRCsAllInOne(g_pabSrc, g_cbPages); RTPrintf("\n" "tstCompressionBenchmark: Hash/CRC - Page by Page\n"); tstBenchmarkCRCsPageByPage(g_pabSrc, g_cbPages); RTPrintf("\n" "tstCompressionBenchmark: Hash/CRC - Zero Page Digest\n"); static uint8_t s_abZeroPg[PAGE_SIZE]; RT_ZERO(s_abZeroPg); tstBenchmarkCRCsAllInOne(s_abZeroPg, PAGE_SIZE); RTPrintf("\n" "tstCompressionBenchmark: Hash/CRC - Zero Half Page Digest\n"); tstBenchmarkCRCsAllInOne(s_abZeroPg, PAGE_SIZE / 2); RTPrintf("tstCompressionBenchmark: END RESULTS\n"); return rc; }
/** * The main loop for the VBoxClient daemon. * @todo Clean up for readability. */ int main(int argc, char *argv[]) { bool fDaemonise = true, fRespawn = true; int rc; const char *pcszFileName; /* Initialise our runtime before all else. */ rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* This should never be called twice in one process - in fact one Display * object should probably never be used from multiple threads anyway. */ if (!XInitThreads()) VBClFatalError(("Failed to initialize X11 threads\n")); /* Get our file name for error output. */ pcszFileName = RTPathFilename(argv[0]); if (!pcszFileName) pcszFileName = "VBoxClient"; /* Parse our option(s) */ /** @todo Use RTGetOpt() if the arguments become more complex. */ for (int i = 1; i < argc; ++i) { rc = VERR_INVALID_PARAMETER; if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--nodaemon")) { /* If the user is running in "no daemon" mode anyway, send critical * logging to stdout as well. */ PRTLOGGER pReleaseLog = RTLogRelGetDefaultInstance(); if (pReleaseLog) rc = RTLogDestinations(pReleaseLog, "stdout"); if (pReleaseLog && RT_FAILURE(rc)) RTPrintf("%s: failed to redivert error output, rc=%Rrc\n", pcszFileName, rc); fDaemonise = false; } else if (!strcmp(argv[i], "--no-respawn")) { fRespawn = false; } else if (!strcmp(argv[i], "--clipboard")) { if (g_pService) break; g_pService = VBClGetClipboardService(); } else if (!strcmp(argv[i], "--display")) { if (g_pService) break; g_pService = VBClGetDisplayService(); } else if (!strcmp(argv[i], "--seamless")) { if (g_pService) break; g_pService = VBClGetSeamlessService(); } else if (!strcmp(argv[i], "--checkhostversion")) { if (g_pService) break; g_pService = VBClGetHostVersionService(); } #ifdef VBOX_WITH_DRAG_AND_DROP else if (!strcmp(argv[i], "--draganddrop")) { if (g_pService) break; g_pService = VBClGetDragAndDropService(); } #endif /* VBOX_WITH_DRAG_AND_DROP */ else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { vboxClientUsage(pcszFileName); return 0; } else if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) { RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); return 0; } else { RTPrintf("%s: unrecognized option `%s'\n", pcszFileName, argv[i]); RTPrintf("Try `%s --help' for more information\n", pcszFileName); return 1; } rc = VINF_SUCCESS; } if (RT_FAILURE(rc) || !g_pService) { vboxClientUsage(pcszFileName); return 1; } rc = RTCritSectInit(&g_critSect); if (RT_FAILURE(rc)) VBClFatalError(("Initialising critical section: %Rrc\n", rc)); rc = RTPathUserHome(g_szPidFile, sizeof(g_szPidFile)); if (RT_FAILURE(rc)) VBClFatalError(("Getting home directory for pid-file: %Rrc\n", rc)); rc = RTPathAppend(g_szPidFile, sizeof(g_szPidFile), (*g_pService)->getPidFilePath()); if (RT_FAILURE(rc)) VBClFatalError(("Creating pid-file path: %Rrc\n", rc)); if (fDaemonise) rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */, fRespawn, &cRespawn); if (RT_FAILURE(rc)) VBClFatalError(("Daemonizing: %Rrc\n", rc)); if (g_szPidFile[0]) rc = VbglR3PidFile(g_szPidFile, &g_hPidFile); if (rc == VERR_FILE_LOCK_VIOLATION) /* Already running. */ return 0; if (RT_FAILURE(rc)) VBClFatalError(("Creating pid-file: %Rrc\n", rc)); /* Set signal handlers to clean up on exit. */ vboxClientSetSignalHandlers(); #ifndef VBOXCLIENT_WITHOUT_X11 /* Set an X11 error handler, so that we don't die when we get unavoidable * errors. */ XSetErrorHandler(vboxClientXLibErrorHandler); /* Set an X11 I/O error handler, so that we can shutdown properly on * fatal errors. */ XSetIOErrorHandler(vboxClientXLibIOErrorHandler); #endif rc = (*g_pService)->init(g_pService); if (RT_FAILURE(rc)) VBClFatalError(("Initialising service: %Rrc\n", rc)); rc = (*g_pService)->run(g_pService, fDaemonise); if (RT_FAILURE(rc)) VBClFatalError(("Service main loop failed: %Rrc\n", rc)); VBClCleanUp(); return 0; }
/** * Initializes pam_vbox. * * @return IPRT status code. * @param hPAM PAM handle. */ static int pam_vbox_init(pam_handle_t *hPAM) { #ifdef DEBUG g_pam_handle = hPAM; /* hack for getting assertion text */ #endif /* Don't make assertions panic because the PAM stack + * the current logon module won't work anymore (or just restart). * This could result in not able to log into the system anymore. */ RTAssertSetMayPanic(false); pam_vbox_log(hPAM, "pam_vbox: %sr%s, running on %s\n", RTBldCfgVersion(), RTBldCfgRevisionStr(), RTBldCfgTargetArch()); int rc = RTR3InitDll(0); if (RT_FAILURE(rc)) { pam_vbox_error(hPAM, "pam_vbox_init: could not init runtime! rc=%Rrc. Aborting\n", rc); return PAM_SUCCESS; /* Jump out as early as we can to not mess around. */ } pam_vbox_log(hPAM, "pam_vbox_init: runtime initialized\n"); if (RT_SUCCESS(rc)) { rc = VbglR3InitUser(); if (RT_FAILURE(rc)) { switch(rc) { case VERR_ACCESS_DENIED: pam_vbox_error(hPAM, "pam_vbox_init: access is denied to guest driver! Please make sure you run with sufficient rights. Aborting\n"); break; case VERR_FILE_NOT_FOUND: pam_vbox_error(hPAM, "pam_vbox_init: guest driver not found! Guest Additions installed? Aborting\n"); break; default: pam_vbox_error(hPAM, "pam_vbox_init: could not init VbglR3 library! rc=%Rrc. Aborting\n", rc); break; } } pam_vbox_log(hPAM, "pam_vbox_init: guest lib initialized\n"); } if (RT_SUCCESS(rc)) { char *rhost = NULL; char *tty = NULL; char *prompt = NULL; #ifdef RT_OS_SOLARIS pam_get_item(hPAM, PAM_RHOST, (void**) &rhost); pam_get_item(hPAM, PAM_TTY, (void**) &tty); pam_get_item(hPAM, PAM_USER_PROMPT, (void**) &prompt); #else pam_get_item(hPAM, PAM_RHOST, (const void**) &rhost); pam_get_item(hPAM, PAM_TTY, (const void**) &tty); pam_get_item(hPAM, PAM_USER_PROMPT, (const void**) &prompt); #endif pam_vbox_log(hPAM, "pam_vbox_init: rhost=%s, tty=%s, prompt=%s\n", rhost ? rhost : "<none>", tty ? tty : "<none>", prompt ? prompt : "<none>"); } return rc; }