VBoxAboutDlg::VBoxAboutDlg(QWidget *pParent, const QString &strVersion) : QIWithRetranslateUI2<QIDialog>(pParent, Qt::CustomizeWindowHint | Qt::WindowTitleHint) , m_strVersion(strVersion) { /* Delete dialog on close: */ setAttribute(Qt::WA_DeleteOnClose); /* Choose default image: */ QString strPath(":/about.png"); /* Branding: Use a custom about splash picture if set: */ QString strSplash = vboxGlobal().brandingGetKey("UI/AboutSplash"); if (vboxGlobal().brandingIsActive() && !strSplash.isEmpty()) { char szExecPath[1024]; RTPathExecDir(szExecPath, 1024); QString strTmpPath = QString("%1/%2").arg(szExecPath).arg(strSplash); if (QFile::exists(strTmpPath)) strPath = strTmpPath; } /* Assign image: */ m_bgImage.load(strPath); /* Translate: */ retranslateUi(); }
RTDECL(int) RTPathSharedLibs(char *pszPath, size_t cchPath) { #if !defined(RT_OS_WINDOWS) && defined(RTPATH_SHARED_LIBS) return RTStrCopy(pszPath, cchPath, RTPATH_SHARED_LIBS); #else return RTPathExecDir(pszPath, cchPath); #endif }
RTDECL(int) RTPathAppPrivateArch(char *pszPath, size_t cchPath) { #if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE_ARCH) return RTStrCopy(pszPath, cchPath, RTPATH_APP_PRIVATE_ARCH); #else return RTPathExecDir(pszPath, cchPath); #endif }
bool RTCALL VBoxOglIs3DAccelerationSupported(void) { if (RTEnvExist("VBOX_CROGL_FORCE_SUPPORTED")) { LogRel(("VBOX_CROGL_FORCE_SUPPORTED is specified, skipping 3D test, and treating as supported\n")); return true; } static char pszVBoxPath[RTPATH_MAX]; const char *papszArgs[4] = { NULL, "-test", "3D", NULL}; int rc; RTPROCESS Process; RTPROCSTATUS ProcStatus; uint64_t StartTS; rc = RTPathExecDir(pszVBoxPath, RTPATH_MAX); AssertRCReturn(rc, false); #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) rc = RTPathAppend(pszVBoxPath, RTPATH_MAX, "VBoxTestOGL.exe"); #else rc = RTPathAppend(pszVBoxPath, RTPATH_MAX, "VBoxTestOGL"); #endif papszArgs[0] = pszVBoxPath; /* argv[0] */ AssertRCReturn(rc, false); rc = RTProcCreate(pszVBoxPath, papszArgs, RTENV_DEFAULT, 0, &Process); if (RT_FAILURE(rc)) return false; StartTS = RTTimeMilliTS(); while (1) { rc = RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus); if (rc != VERR_PROCESS_RUNNING) break; #ifndef DEBUG_misha if (RTTimeMilliTS() - StartTS > 30*1000 /* 30 sec */) { RTProcTerminate(Process); RTThreadSleep(100); RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus); return false; } #endif RTThreadSleep(100); } if (RT_SUCCESS(rc)) { if ((ProcStatus.enmReason==RTPROCEXITREASON_NORMAL) && (ProcStatus.iStatus==0)) { return true; } } return false; }
RTDECL(int) RTPathAppPrivateNoArch(char *pszPath, size_t cchPath) { #if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE) return RTStrCopy(pszPath, cchPath, RTPATH_APP_PRIVATE); #elif defined(RT_OS_SOLARIS) return rtPathSolarisArchHack(pszPath, cchPath); #else return RTPathExecDir(pszPath, cchPath); #endif }
/** * Hack to strip of the architecture subdirectory from the exec dir. * * @returns See RTPathExecDir. * @param pszPath See RTPathExecDir. * @param cchPath See RTPathExecDir. */ DECLINLINE(int) rtPathSolarisArchHack(char *pszPath, size_t cchPath) { int rc = RTPathExecDir(pszPath, cchPath); if (RT_SUCCESS(rc)) { const char *pszLast = RTPathFilename(pszPath); if ( !strcmp(pszLast, "amd64") || !strcmp(pszLast, "i386")) RTPathStripFilename(pszPath); } return rc; }
static void test1(RTTEST hTest, const char *pszBaseDir) { char szPath1[RTPATH_MAX]; char szPath2[RTPATH_MAX]; /* * Making some assumptions about how we are executed from to start with... */ RTTestISub("Negative RTSymlinkRead, Exists & IsDangling"); char szExecDir[RTPATH_MAX]; RTTESTI_CHECK_RC_OK_RETV(RTPathExecDir(szExecDir, sizeof(szExecDir))); size_t cchExecDir = strlen(szExecDir); RTTESTI_CHECK(RTDirExists(szExecDir)); char szExecFile[RTPATH_MAX]; RTTESTI_CHECK_RETV(RTProcGetExecutablePath(szExecFile, sizeof(szExecFile)) != NULL); size_t cchExecFile = strlen(szExecFile); RTTESTI_CHECK(RTFileExists(szExecFile)); RTTESTI_CHECK(!RTSymlinkExists(szExecFile)); RTTESTI_CHECK(!RTSymlinkExists(szExecDir)); RTTESTI_CHECK(!RTSymlinkIsDangling(szExecFile)); RTTESTI_CHECK(!RTSymlinkIsDangling(szExecDir)); RTTESTI_CHECK(!RTSymlinkExists("/")); RTTESTI_CHECK(!RTSymlinkIsDangling("/")); RTTESTI_CHECK(!RTSymlinkExists("/some/non-existing/directory/name/iprt")); RTTESTI_CHECK(!RTSymlinkExists("/some/non-existing/directory/name/iprt/")); RTTESTI_CHECK(!RTSymlinkIsDangling("/some/non-existing/directory/name/iprt")); RTTESTI_CHECK(!RTSymlinkIsDangling("/some/non-existing/directory/name/iprt/")); RTTESTI_CHECK_RC(RTSymlinkRead(szExecFile, szPath1, sizeof(szPath1), 0), VERR_NOT_SYMLINK); RTTESTI_CHECK_RC(RTSymlinkRead(szExecDir, szPath1, sizeof(szPath1), 0), VERR_NOT_SYMLINK); /* * Do some symlinking. ASSUME they are supported on the test file system. */ RTTestISub("Basics"); RTTESTI_CHECK_RETV(RTDirExists(pszBaseDir)); test1Worker(hTest, pszBaseDir, szExecFile, RTSYMLINKTYPE_FILE, false /*fDangling*/); test1Worker(hTest, pszBaseDir, szExecDir, RTSYMLINKTYPE_DIR, false /*fDangling*/); test1Worker(hTest, pszBaseDir, szExecFile, RTSYMLINKTYPE_UNKNOWN, false /*fDangling*/); test1Worker(hTest, pszBaseDir, szExecDir, RTSYMLINKTYPE_UNKNOWN, false /*fDangling*/); /* * Create a few dangling links. */ RTTestISub("Dangling links"); test1Worker(hTest, pszBaseDir, "../dangle/dangle", RTSYMLINKTYPE_FILE, true /*fDangling*/); test1Worker(hTest, pszBaseDir, "../dangle/dangle", RTSYMLINKTYPE_DIR, true /*fDangling*/); test1Worker(hTest, pszBaseDir, "../dangle/dangle", RTSYMLINKTYPE_UNKNOWN, true /*fDangling*/); test1Worker(hTest, pszBaseDir, "../dangle/dangle/", RTSYMLINKTYPE_UNKNOWN, true /*fDangling*/); }
RTDECL(int) RTPathAppPrivateArchTop(char *pszPath, size_t cchPath) { #if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE_ARCH_TOP) return RTStrCopy(pszPath, cchPath, RTPATH_APP_PRIVATE_ARCH_TOP); #elif !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE_ARCH) return RTStrCopy(pszPath, cchPath, RTPATH_APP_PRIVATE_ARCH); #elif defined(RT_OS_SOLARIS) return rtPathSolarisArchHack(pszPath, cchPath); #else int rc = RTPathExecDir(pszPath, cchPath); return rc; #endif }
/** * Creates the service. * * @returns 0 on success. * @returns -1 on failure. */ static int suplibOsUpdateService(void) { /* * Assume it didn't exist, so we'll create the service. */ SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG); DWORD LastError = GetLastError(); NOREF(LastError); AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed LastError=%Rwa\n", LastError)); if (hSMgr) { SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_CHANGE_CONFIG); if (hService) { char szDriver[RTPATH_MAX]; int rc = RTPathExecDir(szDriver, sizeof(szDriver) - sizeof("\\VBoxDrv.sys")); if (RT_SUCCESS(rc)) { strcat(szDriver, "\\VBoxDrv.sys"); SC_LOCK hLock = LockServiceDatabase(hSMgr); if (ChangeServiceConfig(hService, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szDriver, NULL, NULL, NULL, NULL, NULL, NULL)) { UnlockServiceDatabase(hLock); CloseServiceHandle(hService); CloseServiceHandle(hSMgr); return 0; } else { DWORD LastError = GetLastError(); NOREF(LastError); AssertMsgFailed(("ChangeServiceConfig failed LastError=%Rwa\n", LastError)); } } UnlockServiceDatabase(hLock); CloseServiceHandle(hService); } else { DWORD LastError = GetLastError(); NOREF(LastError); AssertMsgFailed(("OpenService failed LastError=%Rwa\n", LastError)); } CloseServiceHandle(hSMgr); } return -1; }
bool is3DAccelerationSupported() { static char pszVBoxPath[RTPATH_MAX]; const char *papszArgs[4] = { NULL, "-test", "3D", NULL}; int rc; RTPROCESS Process; RTPROCSTATUS ProcStatus; uint64_t StartTS; rc = RTPathExecDir(pszVBoxPath, RTPATH_MAX); AssertRCReturn(rc, false); #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) rc = RTPathAppend(pszVBoxPath, RTPATH_MAX, "VBoxTestOGL.exe"); #else rc = RTPathAppend(pszVBoxPath, RTPATH_MAX, "VBoxTestOGL"); #endif papszArgs[0] = pszVBoxPath; /* argv[0] */ AssertRCReturn(rc, false); rc = RTProcCreate(pszVBoxPath, papszArgs, RTENV_DEFAULT, 0, &Process); if (RT_FAILURE(rc)) return false; StartTS = RTTimeMilliTS(); while (1) { rc = RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus); if (rc != VERR_PROCESS_RUNNING) break; if (RTTimeMilliTS() - StartTS > 30*1000 /* 30 sec */) { RTProcTerminate(Process); RTThreadSleep(100); RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus); return false; } RTThreadSleep(100); } if (RT_SUCCESS(rc)) { if ((ProcStatus.enmReason==RTPROCEXITREASON_NORMAL) && (ProcStatus.iStatus==0)) { return true; } } return false; }
VBoxAboutDlg::VBoxAboutDlg(QWidget *pParent, const QString &strVersion) : QIWithRetranslateUI2<QIDialog>(pParent) , m_strVersion(strVersion) { /* Delete dialog on close: */ setAttribute(Qt::WA_DeleteOnClose); /* Choose default image: */ QString strPath(":/about.png"); /* Branding: Use a custom about splash picture if set: */ QString strSplash = vboxGlobal().brandingGetKey("UI/AboutSplash"); if (vboxGlobal().brandingIsActive() && !strSplash.isEmpty()) { char szExecPath[1024]; RTPathExecDir(szExecPath, 1024); QString strTmpPath = QString("%1/%2").arg(szExecPath).arg(strSplash); if (QFile::exists(strTmpPath)) strPath = strTmpPath; } /* Load image: */ QIcon icon = UIIconPool::iconSet(strPath); m_size = icon.availableSizes().first(); m_pixmap = icon.pixmap(m_size); /* Create main layout: */ QVBoxLayout *pMainLayout = new QVBoxLayout(this); /* Create label for version text: */ m_pLabel = new QLabel(); pMainLayout->addWidget(m_pLabel); QPalette palette; /* Branding: Set a different text color (because splash also could be white), * otherwise use white as default color: */ QString strColor = vboxGlobal().brandingGetKey("UI/AboutTextColor"); if (!strColor.isEmpty()) palette.setColor(QPalette::WindowText, QColor(strColor).name()); else palette.setColor(QPalette::WindowText, Qt::black); m_pLabel->setPalette(palette); m_pLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); m_pLabel->setFont(font()); pMainLayout->setAlignment(m_pLabel, Qt::AlignRight | Qt::AlignBottom); /* Translate: */ retranslateUi(); }
/** * Creates the service. * * @returns VBox status code. * @retval VWRN_ALREADY_EXISTS if it already exists. */ static int suplibOsCreateService(void) { /* * Assume it didn't exist, so we'll create the service. */ int rc; SC_HANDLE hSMgrCreate = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG); DWORD dwErr = GetLastError(); AssertMsg(hSMgrCreate, ("OpenSCManager(,,create) failed dwErr=%d\n", dwErr)); if (hSMgrCreate != NULL) { char szDriver[RTPATH_MAX]; rc = RTPathExecDir(szDriver, sizeof(szDriver) - sizeof("\\VBoxDrv.sys")); if (RT_SUCCESS(rc)) { strcat(szDriver, "\\VBoxDrv.sys"); SC_HANDLE hService = CreateService(hSMgrCreate, SERVICE_NAME, "VBox Support Driver", SERVICE_QUERY_STATUS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szDriver, NULL, NULL, NULL, NULL, NULL); dwErr = GetLastError(); if (hService) { CloseServiceHandle(hService); rc = VINF_SUCCESS; } else if (dwErr == ERROR_SERVICE_EXISTS) rc = VWRN_ALREADY_EXISTS; else { AssertMsgFailed(("CreateService failed! dwErr=%Rwa szDriver=%s\n", dwErr, szDriver)); rc = RTErrConvertFromWin32(dwErr); } } CloseServiceHandle(hSMgrCreate); } else rc = RTErrConvertFromWin32(GetLastError()); return rc; }
/** * Creates the service. * * @returns 0 on success. * @returns < 0 on failure. */ int usblibOsCreateService(void) { /* * Assume it didn't exist, so we'll create the service. */ SC_HANDLE hSMgrCreate = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG); DWORD dwLastError = GetLastError(); int rc = RTErrConvertFromWin32(dwLastError); AssertMsg(hSMgrCreate, ("OpenSCManager(,,create) failed rc=%d\n", dwLastError)); if (hSMgrCreate) { char szDriver[RTPATH_MAX]; int rc = RTPathExecDir(szDriver, sizeof(szDriver) - sizeof("\\VBoxUSBMon.sys")); if (RT_SUCCESS(rc)) { strcat(szDriver, "\\VBoxUSBMon.sys"); RTPrintf("Creating USB monitor driver service with path %s ...\n", szDriver); SC_HANDLE hService = CreateService(hSMgrCreate, SERVICE_NAME, "VBox USB Monitor Driver", SERVICE_QUERY_STATUS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szDriver, NULL, NULL, NULL, NULL, NULL); DWORD dwLastError = GetLastError(); if (dwLastError == ERROR_SERVICE_EXISTS) { RTPrintf("USB monitor driver service already exists, skipping creation.\n"); rc = usblibOsChangeService(szDriver); } else { AssertMsg(hService, ("CreateService failed! LastError=%Rwa, szDriver=%s\n", dwLastError, szDriver)); rc = RTErrConvertFromWin32(dwLastError); if (hService != NULL) CloseServiceHandle(hService); } } CloseServiceHandle(hSMgrCreate); } return rc; }
HRESULT SystemProperties::i_setDefaultAdditionsISO(const com::Utf8Str &aPath) { com::Utf8Str path(aPath); if (path.isEmpty()) { char strTemp[RTPATH_MAX]; int vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp)); AssertRC(vrc); Utf8Str strSrc1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso"); vrc = RTPathExecDir(strTemp, sizeof(strTemp)); AssertRC(vrc); Utf8Str strSrc2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso"); vrc = RTPathUserHome(strTemp, sizeof(strTemp)); AssertRC(vrc); Utf8Str strSrc3 = Utf8StrFmt("%s/VBoxGuestAdditions_%s.iso", strTemp, VirtualBox::i_getVersionNormalized().c_str()); /* Check the standard image locations */ if (RTFileExists(strSrc1.c_str())) path = strSrc1; else if (RTFileExists(strSrc2.c_str())) path = strSrc2; else if (RTFileExists(strSrc3.c_str())) path = strSrc3; else return setError(E_FAIL, tr("Cannot determine default Guest Additions ISO location. Most likely they are not available")); } if (!RTPathStartsWithRoot(path.c_str())) return setError(E_INVALIDARG, tr("Given default machine Guest Additions ISO file '%s' is not fully qualified"), path.c_str()); if (!RTFileExists(path.c_str())) return setError(E_INVALIDARG, tr("Given default machine Guest Additions ISO file '%s' does not exist"), path.c_str()); m->strDefaultAdditionsISO = path; return S_OK; }
int NetIfAdpCtlOut(const char * pcszName, const char * pcszCmd, char *pszBuffer, size_t cBufSize) { char szAdpCtl[RTPATH_MAX]; int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " ") - strlen(pcszCmd)); if (RT_FAILURE(rc)) { LogRel(("NetIfAdpCtlOut: Failed to get program path, rc=%Rrc\n", rc)); return VERR_INVALID_PARAMETER; } strcat(szAdpCtl, "/" VBOXNETADPCTL_NAME " "); if (pcszName && strlen(pcszName) <= RTPATH_MAX - strlen(szAdpCtl) - 1 - strlen(pcszCmd)) { strcat(szAdpCtl, pcszName); strcat(szAdpCtl, " "); strcat(szAdpCtl, pcszCmd); } else { LogRel(("NetIfAdpCtlOut: Command line is too long: %s%s %s\n", szAdpCtl, pcszName, pcszCmd)); return VERR_INVALID_PARAMETER; } if (strlen(szAdpCtl) < RTPATH_MAX - sizeof(" 2>&1")) strcat(szAdpCtl, " 2>&1"); FILE *fp = popen(szAdpCtl, "r"); if (fp) { if (fgets(pszBuffer, (int)cBufSize, fp)) { if (!strncmp(VBOXNETADPCTL_NAME ":", pszBuffer, sizeof(VBOXNETADPCTL_NAME))) { LogRel(("NetIfAdpCtlOut: %s", pszBuffer)); rc = VERR_INTERNAL_ERROR; } } else { LogRel(("NetIfAdpCtlOut: No output from " VBOXNETADPCTL_NAME)); rc = VERR_INTERNAL_ERROR; } pclose(fp); } return rc; }
int main(int argc, char **argv) { int cErrors = 0; RTR3InitExe(argc, &argv, 0); /* * Sanity check. */ int rc = DisasmTest1(); if (rc) { RTPrintf("tstLdr-4: FATAL ERROR - DisasmTest1 is buggy: rc=%#x\n", rc); return 1; } /* * Execute the test. */ char szPath[RTPATH_MAX]; rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/tstLdrObjR0.r0")); if (RT_SUCCESS(rc)) { strcat(szPath, "/tstLdrObjR0.r0"); RTPrintf("tstLdr-4: TESTING '%s'...\n", szPath); cErrors += testLdrOne(szPath); } else { RTPrintf("tstLdr-4: RTPathExecDir -> %Rrc\n", rc); cErrors++; } /* * Test result summary. */ if (!cErrors) RTPrintf("tstLdr-4: SUCCESS\n"); else RTPrintf("tstLdr-4: FAILURE - %d errors\n", cErrors); return !!cErrors; }
static int NetIfAdpCtl(const char * pcszIfName, const char *pszAddr, const char *pszOption, const char *pszMask) { const char *args[] = { NULL, pcszIfName, pszAddr, pszOption, pszMask, NULL }; char szAdpCtl[RTPATH_MAX]; int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME)); if (RT_FAILURE(rc)) { LogRel(("NetIfAdpCtl: failed to get program path, rc=%Rrc.\n", rc)); return rc; } strcat(szAdpCtl, "/" VBOXNETADPCTL_NAME); args[0] = szAdpCtl; if (!RTPathExists(szAdpCtl)) { LogRel(("NetIfAdpCtl: path %s does not exist. Failed to run " VBOXNETADPCTL_NAME " helper.\n", szAdpCtl)); return VERR_FILE_NOT_FOUND; } RTPROCESS pid; rc = RTProcCreate(szAdpCtl, args, RTENV_DEFAULT, 0, &pid); if (RT_SUCCESS(rc)) { RTPROCSTATUS Status; rc = RTProcWait(pid, 0, &Status); if ( RT_SUCCESS(rc) && Status.iStatus == 0 && Status.enmReason == RTPROCEXITREASON_NORMAL) return VINF_SUCCESS; } else LogRel(("NetIfAdpCtl: failed to create process for %.\n", szAdpCtl)); return rc; }
int main(int argc, char **argv) { #ifndef VBOX RTPrintf("tstSup: SKIPPED\n"); return 0; #else /* * Init. */ RTTEST hTest; int rc = RTTestInitAndCreate("tstR0ThreadPreemption", &hTest); if (rc) return rc; RTTestBanner(hTest); PSUPDRVSESSION pSession; rc = SUPR3Init(&pSession); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); } char szPath[RTPATH_MAX]; rc = RTPathExecDir(szPath, sizeof(szPath)); if (RT_SUCCESS(rc)) rc = RTPathAppend(szPath, sizeof(szPath), "tstR0ThreadPreemption.r0"); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "Failed constructing .r0 filename (rc=%Rrc)", rc); return RTTestSummaryAndDestroy(hTest); } void *pvImageBase; rc = SUPR3LoadServiceModule(szPath, "tstR0ThreadPreemption", "TSTR0ThreadPreemptionSrvReqHandler", &pvImageBase); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "SUPR3LoadServiceModule(%s,,,) failed with rc=%Rrc\n", szPath, rc); return RTTestSummaryAndDestroy(hTest); } /* test request */ struct { SUPR0SERVICEREQHDR Hdr; char szMsg[256]; } Req; /* * Sanity checks. */ RTTestSub(hTest, "Sanity"); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1, TSTR0THREADPREMEPTION_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); RTTESTI_CHECK_MSG(Req.szMsg[0] == '\0', ("%s", Req.szMsg)); if (Req.szMsg[0] != '\0') return RTTestSummaryAndDestroy(hTest); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1, TSTR0THREADPREMEPTION_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1), ("%s", Req.szMsg)); if (strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42") - 1)) return RTTestSummaryAndDestroy(hTest); /* * Basic tests, bail out on failure. */ RTTestSub(hTest, "Basics"); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1, TSTR0THREADPREMEPTION_BASIC, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); if (Req.szMsg[0] == '!') { RTTestIFailed("%s", &Req.szMsg[1]); return RTTestSummaryAndDestroy(hTest); } if (Req.szMsg[0]) RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg); /* * Stay in ring-0 until preemption is pending. */ RTThreadSleep(250); /** @todo fix GIP initialization? */ RTTestSub(hTest, "Pending Preemption"); for (int i = 0; ; i++) { Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1, TSTR0THREADPREMEPTION_IS_PENDING, 0, &Req.Hdr), VINF_SUCCESS); if ( strcmp(Req.szMsg, "cLoops=1\n") || i >= 64) { if (Req.szMsg[0] == '!') RTTestIFailed("%s", &Req.szMsg[1]); else if (Req.szMsg[0]) RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg); break; } if ((i % 3) == 0) RTThreadYield(); } /* * Test nested RTThreadPreemptDisable calls. */ RTTestSub(hTest, "Nested"); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0ThreadPreemption", sizeof("tstR0ThreadPreemption") - 1, TSTR0THREADPREMEPTION_NESTED, 0, &Req.Hdr), VINF_SUCCESS); if (Req.szMsg[0] == '!') RTTestIFailed("%s", &Req.szMsg[1]); else if (Req.szMsg[0]) RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg); /* * Done. */ return RTTestSummaryAndDestroy(hTest); #endif }
int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox, IHostNetworkInterface **aHostNetworkInterface, IProgress **aProgress, const char *pcszName) { #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) /* create a progress object */ ComObjPtr<Progress> progress; progress.createObject(); ComPtr<IHost> host; HRESULT hrc = pVirtualBox->COMGETTER(Host)(host.asOutParam()); if (SUCCEEDED(hrc)) { hrc = progress->init(pVirtualBox, host, Bstr("Creating host only network interface").raw(), FALSE /* aCancelable */); if (SUCCEEDED(hrc)) { progress.queryInterfaceTo(aProgress); char szAdpCtl[RTPATH_MAX]; int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add")); if (RT_FAILURE(rc)) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to get program path, rc=%Rrc\n", rc); return rc; } strcat(szAdpCtl, "/" VBOXNETADPCTL_NAME " "); if (pcszName && strlen(pcszName) <= RTPATH_MAX - strlen(szAdpCtl) - sizeof(" add")) { strcat(szAdpCtl, pcszName); strcat(szAdpCtl, " add"); } else strcat(szAdpCtl, "add"); if (strlen(szAdpCtl) < RTPATH_MAX - sizeof(" 2>&1")) strcat(szAdpCtl, " 2>&1"); FILE *fp = popen(szAdpCtl, "r"); if (fp) { char szBuf[128]; /* We are not interested in long error messages. */ if (fgets(szBuf, sizeof(szBuf), fp)) { /* Remove trailing new line characters. */ char *pLast = szBuf + strlen(szBuf) - 1; if (pLast >= szBuf && *pLast == '\n') *pLast = 0; if (!strncmp(VBOXNETADPCTL_NAME ":", szBuf, sizeof(VBOXNETADPCTL_NAME))) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "%s", szBuf); pclose(fp); return E_FAIL; } size_t cbNameLen = strlen(szBuf) + 1; PNETIFINFO pInfo = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen])); if (!pInfo) rc = VERR_NO_MEMORY; else { strcpy(pInfo->szShortName, szBuf); strcpy(pInfo->szName, szBuf); rc = NetIfGetConfigByName(pInfo); if (RT_FAILURE(rc)) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to get config info for %s (as reported by '" VBOXNETADPCTL_NAME " add')\n", szBuf); } else { Bstr IfName(szBuf); /* create a new uninitialized host interface object */ ComObjPtr<HostNetworkInterface> iface; iface.createObject(); iface->init(IfName, HostNetworkInterfaceType_HostOnly, pInfo); iface->i_setVirtualBox(pVirtualBox); iface.queryInterfaceTo(aHostNetworkInterface); } RTMemFree(pInfo); } if ((rc = pclose(fp)) != 0) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to execute '" VBOXNETADPCTL_NAME " add' (exit status: %d)", rc); rc = VERR_INTERNAL_ERROR; } } else { /* Failed to add an interface */ rc = VERR_PERMISSION_DENIED; progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to execute '" VBOXNETADPCTL_NAME " add' (exit status: %d). Check permissions!", rc); pclose(fp); } } if (RT_SUCCESS(rc)) progress->i_notifyComplete(rc); else hrc = E_FAIL; } } return hrc; #else NOREF(pVirtualBox); NOREF(aHostNetworkInterface); NOREF(aProgress); NOREF(pcszName); return VERR_NOT_IMPLEMENTED; #endif }
int main(int argc, char **argv) { int rcRet = 0; int i; int rc; int cIterations = argc > 1 ? RTStrToUInt32(argv[1]) : 32; if (cIterations == 0) cIterations = 64; /* * Init. */ RTR3InitExe(argc, &argv, 0); PSUPDRVSESSION pSession; rc = SUPR3Init(&pSession); rcRet += rc != 0; RTPrintf("tstInt: SUPR3Init -> rc=%Rrc\n", rc); char szFile[RTPATH_MAX]; if (!rc) { rc = RTPathExecDir(szFile, sizeof(szFile) - sizeof("/VMMR0.r0")); } char szAbsFile[RTPATH_MAX]; if (RT_SUCCESS(rc)) { strcat(szFile, "/VMMR0.r0"); rc = RTPathAbs(szFile, szAbsFile, sizeof(szAbsFile)); } if (RT_SUCCESS(rc)) { /* * Load VMM code. */ rc = SUPR3LoadVMM(szAbsFile); if (RT_SUCCESS(rc)) { /* * Create a fake 'VM'. */ PVMR0 pVMR0 = NIL_RTR0PTR; PVM pVM = NULL; const unsigned cPages = RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT; PSUPPAGE paPages = (PSUPPAGE)RTMemAllocZ(cPages * sizeof(SUPPAGE)); if (paPages) rc = SUPR3LowAlloc(cPages, (void **)&pVM, &pVMR0, &paPages[0]); else rc = VERR_NO_MEMORY; if (RT_SUCCESS(rc)) { pVM->pVMRC = 0; pVM->pVMR3 = pVM; pVM->pVMR0 = pVMR0; pVM->paVMPagesR3 = paPages; pVM->pSession = pSession; pVM->enmVMState = VMSTATE_CREATED; rc = SUPR3SetVMForFastIOCtl(pVMR0); if (!rc) { /* * Call VMM code with invalid function. */ for (i = cIterations; i > 0; i--) { rc = SUPR3CallVMMR0(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, NULL); if (rc != VINF_SUCCESS) { RTPrintf("tstInt: SUPR3CallVMMR0 -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i); rcRet++; break; } } RTPrintf("tstInt: Performed SUPR3CallVMMR0 %d times (rc=%Rrc)\n", cIterations, rc); /* * The fast path. */ if (rc == VINF_SUCCESS) { RTTimeNanoTS(); uint64_t StartTS = RTTimeNanoTS(); uint64_t StartTick = ASMReadTSC(); uint64_t MinTicks = UINT64_MAX; for (i = 0; i < 1000000; i++) { uint64_t OneStartTick = ASMReadTSC(); rc = SUPR3CallVMMR0Fast(pVMR0, VMMR0_DO_NOP, 0); uint64_t Ticks = ASMReadTSC() - OneStartTick; if (Ticks < MinTicks) MinTicks = Ticks; if (RT_UNLIKELY(rc != VINF_SUCCESS)) { RTPrintf("tstInt: SUPR3CallVMMR0Fast -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i); rcRet++; break; } } uint64_t Ticks = ASMReadTSC() - StartTick; uint64_t NanoSecs = RTTimeNanoTS() - StartTS; RTPrintf("tstInt: SUPR3CallVMMR0Fast - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n", i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks); /* * The ordinary path. */ RTTimeNanoTS(); StartTS = RTTimeNanoTS(); StartTick = ASMReadTSC(); MinTicks = UINT64_MAX; for (i = 0; i < 1000000; i++) { uint64_t OneStartTick = ASMReadTSC(); rc = SUPR3CallVMMR0Ex(pVMR0, NIL_VMCPUID, VMMR0_DO_SLOW_NOP, 0, NULL); uint64_t OneTicks = ASMReadTSC() - OneStartTick; if (OneTicks < MinTicks) MinTicks = OneTicks; if (RT_UNLIKELY(rc != VINF_SUCCESS)) { RTPrintf("tstInt: SUPR3CallVMMR0Ex -> rc=%Rrc i=%d Expected VINF_SUCCESS!\n", rc, i); rcRet++; break; } } Ticks = ASMReadTSC() - StartTick; NanoSecs = RTTimeNanoTS() - StartTS; RTPrintf("tstInt: SUPR3CallVMMR0Ex - %d iterations in %llu ns / %llu ticks. %llu ns / %#llu ticks per iteration. Min %llu ticks.\n", i, NanoSecs, Ticks, NanoSecs / i, Ticks / i, MinTicks); } } else { RTPrintf("tstInt: SUPR3SetVMForFastIOCtl failed: %Rrc\n", rc); rcRet++; } } else { RTPrintf("tstInt: SUPR3ContAlloc(%#zx,,) failed\n", sizeof(*pVM)); rcRet++; } /* * Unload VMM. */ rc = SUPR3UnloadVMM(); if (rc) { RTPrintf("tstInt: SUPR3UnloadVMM failed with rc=%Rrc\n", rc); rcRet++; } } else { RTPrintf("tstInt: SUPR3LoadVMM failed with rc=%Rrc\n", rc); rcRet++; } /* * Terminate. */ rc = SUPR3Term(false /*fForced*/); rcRet += rc != 0; RTPrintf("tstInt: SUPR3Term -> rc=%Rrc\n", rc); }
int main (int argc, char **argv) { #ifndef VBOX RTPrintf("tstSup: SKIPPED\n"); return 0; #else /* * Init. */ RTTEST hTest; int rc = RTTestInitAndCreate("tstRTR0DbgKrnlInfo", &hTest); if (rc) return rc; RTTestBanner(hTest); uint8_t *pbPage = (uint8_t *)RTTestGuardedAllocTail(hTest, PAGE_SIZE); if (!pbPage) { RTTestFailed(hTest, "RTTestGuardedAllocTail failed with rc=%Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); } PSUPDRVSESSION pSession; rc = SUPR3Init(&pSession); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); } char szPath[RTPATH_MAX]; rc = RTPathExecDir(szPath, sizeof(szPath)); if (RT_SUCCESS(rc)) rc = RTPathAppend(szPath, sizeof(szPath), "tstRTR0DbgKrnlInfo.r0"); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "Failed constructing .r0 filename (rc=%Rrc)", rc); return RTTestSummaryAndDestroy(hTest); } void *pvImageBase; rc = SUPR3LoadServiceModule(szPath, "tstRTR0DbgKrnlInfo", "TSTR0DbgKrnlInfoSrvReqHandler", &pvImageBase); if (RT_FAILURE(rc)) { RTTestFailed(hTest, "SUPR3LoadServiceModule(%s,,,) failed with rc=%Rrc\n", szPath, rc); return RTTestSummaryAndDestroy(hTest); } /* test request */ struct { SUPR0SERVICEREQHDR Hdr; char szMsg[256]; } Req; /* * Sanity checks. */ RTTestSub(hTest, "Sanity"); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1, TSTRTR0DBGKRNLINFO_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); RTTESTI_CHECK_MSG(Req.szMsg[0] == '\0', ("%s", Req.szMsg)); if (Req.szMsg[0] != '\0') return RTTestSummaryAndDestroy(hTest); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1, TSTRTR0DBGKRNLINFO_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")), ("%s", Req.szMsg)); if (strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42"))) return RTTestSummaryAndDestroy(hTest); /* * Basic tests, bail out on failure. */ RTTestSub(hTest, "Basics"); Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC; Req.Hdr.cbReq = sizeof(Req); Req.szMsg[0] = '\0'; RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1, TSTRTR0DBGKRNLINFO_BASIC, 0, &Req.Hdr), VINF_SUCCESS); if (RT_FAILURE(rc)) return RTTestSummaryAndDestroy(hTest); if (Req.szMsg[0] == '!') { RTTestIFailed("%s", &Req.szMsg[1]); return RTTestSummaryAndDestroy(hTest); } if (Req.szMsg[0]) RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg); /* * Done. */ return RTTestSummaryAndDestroy(hTest); #endif }
int main() { char szPath[RTPATH_MAX]; /* * Init RT+Test. */ RTTEST hTest; int rc = RTTestInitAndCreate("tstRTPath", &hTest); if (rc) return rc; RTTestBanner(hTest); /* * RTPathExecDir, RTPathUserHome and RTProcGetExecutablePath. */ RTTestSub(hTest, "RTPathExecDir"); RTTESTI_CHECK_RC(rc = RTPathExecDir(szPath, sizeof(szPath)), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTestIPrintf(RTTESTLVL_INFO, "ExecDir={%s}\n", szPath); RTTestSub(hTest, "RTProcGetExecutablePath"); if (RTProcGetExecutablePath(szPath, sizeof(szPath)) == szPath) RTTestIPrintf(RTTESTLVL_INFO, "ExecutableName={%s}\n", szPath); else RTTestIFailed("RTProcGetExecutablePath -> NULL"); RTTestSub(hTest, "RTPathUserHome"); RTTESTI_CHECK_RC(rc = RTPathUserHome(szPath, sizeof(szPath)), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTestIPrintf(RTTESTLVL_INFO, "UserHome={%s}\n", szPath); RTTestSub(hTest, "RTPathUserDocuments"); RTTESTI_CHECK_RC(rc = RTPathUserDocuments(szPath, sizeof(szPath)), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTestIPrintf(RTTESTLVL_INFO, "UserDocuments={%s}\n", szPath); RTTestSub(hTest, "RTPathTemp"); RTTESTI_CHECK_RC(rc = RTPathTemp(szPath, sizeof(szPath)), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTestIPrintf(RTTESTLVL_INFO, "PathTemp={%s}\n", szPath); size_t cch = strlen(szPath); RTTESTI_CHECK_RC(RTPathTemp(szPath, cch), VERR_BUFFER_OVERFLOW); RTTESTI_CHECK_RC(RTPathTemp(szPath, cch+1), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathTemp(szPath, cch+2), VINF_SUCCESS); /* * RTPathAbsEx */ RTTestSub(hTest, "RTPathAbsEx"); static const struct { const char *pcszInputBase; const char *pcszInputPath; int rc; const char *pcszOutput; } s_aRTPathAbsExTests[] = { #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) { NULL, "", VERR_INVALID_PARAMETER, NULL }, { NULL, ".", VINF_SUCCESS, "%p" }, { NULL, "\\", VINF_SUCCESS, "%d\\" }, { NULL, "\\..", VINF_SUCCESS, "%d\\" }, { NULL, "/absolute/..", VINF_SUCCESS, "%d\\" }, { NULL, "/absolute\\\\../..", VINF_SUCCESS, "%d\\" }, { NULL, "/absolute//../path\\", VINF_SUCCESS, "%d\\path" }, { NULL, "/absolute/../../path", VINF_SUCCESS, "%d\\path" }, { NULL, "relative/../dir\\.\\.\\.\\file.txt", VINF_SUCCESS, "%p\\dir\\file.txt" }, { NULL, "\\data\\", VINF_SUCCESS, "%d\\data" }, { "relative_base/dir\\", "\\from_root", VINF_SUCCESS, "%d\\from_root" }, { "relative_base/dir/", "relative_also", VINF_SUCCESS, "%p\\relative_base\\dir\\relative_also" }, #else { NULL, "", VERR_INVALID_PARAMETER, NULL }, { NULL, ".", VINF_SUCCESS, "%p" }, { NULL, "/", VINF_SUCCESS, "/" }, { NULL, "/..", VINF_SUCCESS, "/" }, { NULL, "/absolute/..", VINF_SUCCESS, "/" }, { NULL, "/absolute\\\\../..", VINF_SUCCESS, "/" }, { NULL, "/absolute//../path/", VINF_SUCCESS, "/path" }, { NULL, "/absolute/../../path", VINF_SUCCESS, "/path" }, { NULL, "relative/../dir/./././file.txt", VINF_SUCCESS, "%p/dir/file.txt" }, { NULL, "relative/../dir\\.\\.\\.\\file.txt", VINF_SUCCESS, "%p/dir\\.\\.\\.\\file.txt" }, /* linux-specific */ { NULL, "/data/", VINF_SUCCESS, "/data" }, { "relative_base/dir/", "/from_root", VINF_SUCCESS, "/from_root" }, { "relative_base/dir/", "relative_also", VINF_SUCCESS, "%p/relative_base/dir/relative_also" }, #endif #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) { NULL, "C:\\", VINF_SUCCESS, "C:\\" }, { "C:\\", "..", VINF_SUCCESS, "C:\\" }, { "C:\\temp", "..", VINF_SUCCESS, "C:\\" }, { "C:\\VirtualBox/Machines", "..\\VirtualBox.xml", VINF_SUCCESS, "C:\\VirtualBox\\VirtualBox.xml" }, { "C:\\MustDie", "\\from_root/dir/..", VINF_SUCCESS, "C:\\from_root" }, { "C:\\temp", "D:\\data", VINF_SUCCESS, "D:\\data" }, { NULL, "\\\\server\\..\\share", VINF_SUCCESS, "\\\\server\\..\\share" /* kind of strange */ }, { NULL, "\\\\server/", VINF_SUCCESS, "\\\\server" }, { NULL, "\\\\", VINF_SUCCESS, "\\\\" }, { NULL, "\\\\\\something", VINF_SUCCESS, "\\\\\\something" /* kind of strange */ }, { "\\\\server\\share_as_base", "/from_root", VINF_SUCCESS, "\\\\server\\from_root" }, { "\\\\just_server", "/from_root", VINF_SUCCESS, "\\\\just_server\\from_root" }, { "\\\\server\\share_as_base", "relative\\data", VINF_SUCCESS, "\\\\server\\share_as_base\\relative\\data" }, { "base", "\\\\?\\UNC\\relative/edwef/..", VINF_SUCCESS, "\\\\?\\UNC\\relative" }, { "\\\\?\\UNC\\base", "/from_root", VERR_INVALID_NAME, NULL }, #else { "/temp", "..", VINF_SUCCESS, "/" }, { "/VirtualBox/Machines", "../VirtualBox.xml", VINF_SUCCESS, "/VirtualBox/VirtualBox.xml" }, { "/MustDie", "/from_root/dir/..", VINF_SUCCESS, "/from_root" }, { "\\temp", "\\data", VINF_SUCCESS, "%p/\\temp/\\data" }, #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_aRTPathAbsExTests); ++ i) { rc = RTPathAbsEx(s_aRTPathAbsExTests[i].pcszInputBase, s_aRTPathAbsExTests[i].pcszInputPath, szPath, sizeof(szPath)); if (rc != s_aRTPathAbsExTests[i].rc) { RTTestIFailed("unexpected result code!\n" " input base: '%s'\n" " input path: '%s'\n" " output: '%s'\n" " rc: %Rrc\n" " expected rc: %Rrc", s_aRTPathAbsExTests[i].pcszInputBase, s_aRTPathAbsExTests[i].pcszInputPath, szPath, rc, s_aRTPathAbsExTests[i].rc); continue; } char szTmp[RTPATH_MAX]; char *pszExpected = NULL; if (s_aRTPathAbsExTests[i].pcszOutput != NULL) { if (s_aRTPathAbsExTests[i].pcszOutput[0] == '%') { RTTESTI_CHECK_RC(rc = RTPathGetCurrent(szTmp, sizeof(szTmp)), VINF_SUCCESS); if (RT_FAILURE(rc)) break; pszExpected = szTmp; if (s_aRTPathAbsExTests[i].pcszOutput[1] == 'p') { cch = strlen(szTmp); if (cch + strlen(s_aRTPathAbsExTests[i].pcszOutput) - 2 <= sizeof(szTmp)) strcpy(szTmp + cch, s_aRTPathAbsExTests[i].pcszOutput + 2); } #if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS) else if (s_aRTPathAbsExTests[i].pcszOutput[1] == 'd') { if (2 + strlen(s_aRTPathAbsExTests[i].pcszOutput) - 2 <= sizeof(szTmp)) strcpy(szTmp + 2, s_aRTPathAbsExTests[i].pcszOutput + 2); } #endif } else { strcpy(szTmp, s_aRTPathAbsExTests[i].pcszOutput); pszExpected = szTmp; } if (strcmp(szPath, pszExpected)) { RTTestIFailed("Unexpected result\n" " input base: '%s'\n" " input path: '%s'\n" " output: '%s'\n" " expected: '%s'", s_aRTPathAbsExTests[i].pcszInputBase, s_aRTPathAbsExTests[i].pcszInputPath, szPath, s_aRTPathAbsExTests[i].pcszOutput); } } } /* * RTPathStripFilename */ RTTestSub(hTest, "RTPathStripFilename"); static const char *s_apszStripFilenameTests[] = { "/usr/include///", "/usr/include//", "/usr/include/", "/usr/include", "/usr/include", "/usr", "/usr", "/", "usr", ".", #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) "c:/windows", "c:/", "c:/", "c:/", "D:", "D:", "C:\\OS2\\DLLS", "C:\\OS2", #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_apszStripFilenameTests); i += 2) { const char *pszInput = s_apszStripFilenameTests[i]; const char *pszExpect = s_apszStripFilenameTests[i + 1]; strcpy(szPath, pszInput); RTPathStripFilename(szPath); if (strcmp(szPath, pszExpect)) { RTTestIFailed("Unexpected result\n" " input: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, szPath, pszExpect); } } /* * RTPathAppend. */ RTTestSub(hTest, "RTPathAppend"); static const char *s_apszAppendTests[] = { /* base append result */ "/", "", "/", "", "/", "/", "/", "/", "/", "/x", "", "/x", "/x", "/", "/x/", "/", "x", "/x", "dir", "file", "dir/file", "dir", "/file", "dir/file", "dir", "//file", "dir/file", "dir", "///file", "dir/file", "dir/", "/file", "dir/file", "dir/", "//file", "dir/file", "dir/", "///file", "dir/file", "dir//", "file", "dir/file", "dir//", "/file", "dir/file", "dir//", "//file", "dir/file", "dir///", "///file", "dir/file", "/bin/testcase", "foo.r0", "/bin/testcase/foo.r0", #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) "/", "\\", "/", "\\", "/", "\\", "\\\\srv\\shr", "dir//", "\\\\srv\\shr/dir//", "\\\\srv\\shr", "dir//file", "\\\\srv\\shr/dir//file", "\\\\srv\\shr", "//dir//", "\\\\srv\\shr/dir//", "\\\\srv\\shr", "/\\dir//", "\\\\srv\\shr\\dir//", "\\\\", "not-srv/not-shr/file", "\\not-srv/not-shr/file", "C:", "autoexec.bat", "C:autoexec.bat", "C:", "/autoexec.bat", "C:/autoexec.bat", "C:", "\\autoexec.bat", "C:\\autoexec.bat", "C:\\", "/autoexec.bat", "C:\\autoexec.bat", "C:\\\\", "autoexec.bat", "C:\\autoexec.bat", "E:\\bin\\testcase", "foo.r0", "E:\\bin\\testcase/foo.r0", #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_apszAppendTests); i += 3) { const char *pszInput = s_apszAppendTests[i]; const char *pszAppend = s_apszAppendTests[i + 1]; const char *pszExpect = s_apszAppendTests[i + 2]; strcpy(szPath, pszInput); RTTESTI_CHECK_RC(rc = RTPathAppend(szPath, sizeof(szPath), pszAppend), VINF_SUCCESS); if (RT_FAILURE(rc)) continue; if (strcmp(szPath, pszExpect)) { RTTestIFailed("Unexpected result\n" " input: '%s'\n" " append: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, pszAppend, szPath, pszExpect); } else { size_t const cchResult = strlen(szPath); strcpy(szPath, pszInput); RTTESTI_CHECK_RC(rc = RTPathAppend(szPath, cchResult + 2, pszAppend), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || !strcmp(szPath, pszExpect)); strcpy(szPath, pszInput); RTTESTI_CHECK_RC(rc = RTPathAppend(szPath, cchResult + 1, pszAppend), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || !strcmp(szPath, pszExpect)); if (strlen(pszInput) < cchResult) { strcpy(szPath, pszInput); RTTESTI_CHECK_RC(RTPathAppend(szPath, cchResult, pszAppend), VERR_BUFFER_OVERFLOW); } } } /* * RTPathJoin - reuse the append tests. */ RTTestSub(hTest, "RTPathJoin"); for (unsigned i = 0; i < RT_ELEMENTS(s_apszAppendTests); i += 3) { const char *pszInput = s_apszAppendTests[i]; const char *pszAppend = s_apszAppendTests[i + 1]; const char *pszExpect = s_apszAppendTests[i + 2]; memset(szPath, 'a', sizeof(szPath)); szPath[sizeof(szPath) - 1] = '\0'; RTTESTI_CHECK_RC(rc = RTPathJoin(szPath, sizeof(szPath), pszInput, pszAppend), VINF_SUCCESS); if (RT_FAILURE(rc)) continue; if (strcmp(szPath, pszExpect)) { RTTestIFailed("Unexpected result\n" " input: '%s'\n" " append: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, pszAppend, szPath, pszExpect); } else { size_t const cchResult = strlen(szPath); memset(szPath, 'a', sizeof(szPath)); szPath[sizeof(szPath) - 1] = '\0'; RTTESTI_CHECK_RC(rc = RTPathJoin(szPath, cchResult + 2, pszInput, pszAppend), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || !strcmp(szPath, pszExpect)); memset(szPath, 'a', sizeof(szPath)); szPath[sizeof(szPath) - 1] = '\0'; RTTESTI_CHECK_RC(rc = RTPathJoin(szPath, cchResult + 1, pszInput, pszAppend), VINF_SUCCESS); RTTESTI_CHECK(RT_FAILURE(rc) || !strcmp(szPath, pszExpect)); RTTESTI_CHECK_RC(rc = RTPathJoin(szPath, cchResult, pszInput, pszAppend), VERR_BUFFER_OVERFLOW); } } /* * RTPathJoinA - reuse the append tests. */ RTTestSub(hTest, "RTPathJoinA"); for (unsigned i = 0; i < RT_ELEMENTS(s_apszAppendTests); i += 3) { const char *pszInput = s_apszAppendTests[i]; const char *pszAppend = s_apszAppendTests[i + 1]; const char *pszExpect = s_apszAppendTests[i + 2]; char *pszPathDst; RTTESTI_CHECK(pszPathDst = RTPathJoinA(pszInput, pszAppend)); if (!pszPathDst) continue; if (strcmp(pszPathDst, pszExpect)) { RTTestIFailed("Unexpected result\n" " input: '%s'\n" " append: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, pszAppend, pszPathDst, pszExpect); } RTStrFree(pszPathDst); } /* * RTPathStripTrailingSlash */ static const char *s_apszStripTrailingSlash[] = { /* input result */ "/", "/", "//", "/", "////////////////////", "/", "/tmp", "/tmp", "/tmp////////////////", "/tmp", "tmp", "tmp", "tmp////////////////", "tmp", "./", ".", #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) "////////////////////", "/", "D:", "D:", "D:/", "D:/", "D:\\", "D:\\", "D:\\/\\", "D:\\", "D:/\\/\\", "D:/", "C:/Temp", "D:/Temp", "C:/Temp/", "D:/Temp/", "C:/Temp\\/", "D:/Temp", #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_apszStripTrailingSlash); i += 2) { const char *pszInput = s_apszStripTrailingSlash[i]; const char *pszExpect = s_apszStripTrailingSlash[i + 1]; strcpy(szPath, pszInput); cch = RTPathStripTrailingSlash(szPath); if (strcmp(szPath, pszExpect)) RTTestIFailed("Unexpected result\n" " input: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, szPath, pszExpect); else RTTESTI_CHECK(cch == strlen(szPath)); } /* * RTPathCountComponents */ RTTestSub(hTest, "RTPathCountComponents"); RTTESTI_CHECK(RTPathCountComponents("") == 0); RTTESTI_CHECK(RTPathCountComponents("/") == 1); RTTESTI_CHECK(RTPathCountComponents("//") == 1); RTTESTI_CHECK(RTPathCountComponents("//////////////") == 1); RTTESTI_CHECK(RTPathCountComponents("//////////////bin") == 2); RTTESTI_CHECK(RTPathCountComponents("//////////////bin/") == 2); RTTESTI_CHECK(RTPathCountComponents("//////////////bin/////") == 2); RTTESTI_CHECK(RTPathCountComponents("..") == 1); RTTESTI_CHECK(RTPathCountComponents("../") == 1); RTTESTI_CHECK(RTPathCountComponents("../..") == 2); RTTESTI_CHECK(RTPathCountComponents("../../") == 2); #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) RTTESTI_CHECK(RTPathCountComponents("d:") == 1); RTTESTI_CHECK(RTPathCountComponents("d:/") == 1); RTTESTI_CHECK(RTPathCountComponents("d:/\\") == 1); RTTESTI_CHECK(RTPathCountComponents("d:\\") == 1); RTTESTI_CHECK(RTPathCountComponents("c:\\config.sys") == 2); RTTESTI_CHECK(RTPathCountComponents("c:\\windows") == 2); RTTESTI_CHECK(RTPathCountComponents("c:\\windows\\") == 2); RTTESTI_CHECK(RTPathCountComponents("c:\\windows\\system32") == 3); RTTESTI_CHECK(RTPathCountComponents("//./C$") == 1); RTTESTI_CHECK(RTPathCountComponents("\\\\.\\C$") == 1); RTTESTI_CHECK(RTPathCountComponents("/\\.\\C$") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/share") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/share/") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/share\\") == 1); RTTESTI_CHECK(RTPathCountComponents("//myserver/share\\x") == 2); RTTESTI_CHECK(RTPathCountComponents("//myserver/share\\x\\y") == 3); RTTESTI_CHECK(RTPathCountComponents("//myserver/share\\x\\y\\") == 3); #endif /* * RTPathCopyComponents */ struct { const char *pszSrc; size_t cComponents; const char *pszResult; } s_aCopyComponents[] = { { "", 0, "" }, { "", 5, "" }, { "/", 0, "" }, { "/", 1, "/" }, { "/", 2, "/" }, { "/usr/bin/sed", 0, "" }, { "/usr/bin/sed", 1, "/" }, { "/usr/bin/sed", 2, "/usr/" }, { "/usr/bin/sed", 3, "/usr/bin/" }, { "/usr/bin/sed", 4, "/usr/bin/sed" }, { "/usr/bin/sed", 5, "/usr/bin/sed" }, { "/usr/bin/sed", 6, "/usr/bin/sed" }, { "/usr///bin/sed", 2, "/usr///" }, }; for (unsigned i = 0; i < RT_ELEMENTS(s_aCopyComponents); i++) { const char *pszInput = s_aCopyComponents[i].pszSrc; size_t cComponents = s_aCopyComponents[i].cComponents; const char *pszResult = s_aCopyComponents[i].pszResult; memset(szPath, 'a', sizeof(szPath)); rc = RTPathCopyComponents(szPath, sizeof(szPath), pszInput, cComponents); RTTESTI_CHECK_RC(rc, VINF_SUCCESS); if (RT_SUCCESS(rc) && strcmp(szPath, pszResult)) RTTestIFailed("Unexpected result\n" " input: '%s' cComponents=%u\n" " output: '%s'\n" "expected: '%s'", pszInput, cComponents, szPath, pszResult); else if (RT_SUCCESS(rc)) { RTTESTI_CHECK_RC(RTPathCopyComponents(szPath, strlen(pszResult) + 1, pszInput, cComponents), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathCopyComponents(szPath, strlen(pszResult), pszInput, cComponents), VERR_BUFFER_OVERFLOW); } } /* * RTPathStripExt */ RTTestSub(hTest, "RTPathStripExt"); struct { const char *pszSrc; const char *pszResult; } s_aStripExt[] = { { "filename.ext", "filename" }, { "filename.ext1.ext2.ext3", "filename.ext1.ext2" }, { "filename..ext", "filename." }, { "filename.ext.", "filename.ext" }, /** @todo This is a bit weird/wrong, but not half as weird as the way Windows+OS/2 deals with a trailing dots. */ }; for (unsigned i = 0; i < RT_ELEMENTS(s_aStripExt); i++) { const char *pszInput = s_aStripExt[i].pszSrc; const char *pszResult = s_aStripExt[i].pszResult; strcpy(szPath, pszInput); RTPathStripExt(szPath); if (strcmp(szPath, pszResult)) RTTestIFailed("Unexpected result\n" " input: '%s'\n" " output: '%s'\n" "expected: '%s'", pszInput, szPath, pszResult); } /* * RTPathCalcRelative */ RTTestSub(hTest, "RTPathCalcRelative"); struct { const char *pszFrom; const char *pszTo; int rc; const char *pszExpected; } s_aRelPath[] = { { "/home/test.ext", "/home/test2.ext", VINF_SUCCESS, "test2.ext"}, { "/dir/test.ext", "/dir/dir2/test2.ext", VINF_SUCCESS, "dir2/test2.ext"}, { "/dir/dir2/test.ext", "/dir/test2.ext", VINF_SUCCESS, "../test2.ext"}, { "/dir/dir2/test.ext", "/dir/dir3/test2.ext", VINF_SUCCESS, "../dir3/test2.ext"}, #if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS) { "\\\\server\\share\\test.ext", "\\\\server\\share2\\test2.ext", VERR_NOT_SUPPORTED, ""}, { "c:\\dir\\test.ext", "f:\\dir\\test.ext", VERR_NOT_SUPPORTED, ""} #endif }; for (unsigned i = 0; i < RT_ELEMENTS(s_aRelPath); i++) { const char *pszFrom = s_aRelPath[i].pszFrom; const char *pszTo = s_aRelPath[i].pszTo; rc = RTPathCalcRelative(szPath, sizeof(szPath), pszFrom, pszTo); if (rc != s_aRelPath[i].rc) RTTestIFailed("Unexpected return code\n" " got: %Rrc\n" "expected: %Rrc", rc, s_aRelPath[i].rc); else if ( RT_SUCCESS(rc) && strcmp(szPath, s_aRelPath[i].pszExpected)) RTTestIFailed("Unexpected result\n" " from: '%s'\n" " to: '%s'\n" " output: '%s'\n" "expected: '%s'", pszFrom, pszTo, szPath, s_aRelPath[i].pszExpected); } /* * Summary. */ return RTTestSummaryAndDestroy(hTest); }
/** * @copydoc RTPathExecDir */ DECLHIDDEN(int) supR3HardenedPathExecDir(char *pszPath, size_t cchPath) { return RTPathExecDir(pszPath, cchPath); }
int VBoxNetBaseService::tryGoOnline(void) { /* * Open the session, load ring-0 and issue the request. */ int rc = SUPR3Init(&m->m_pSession); if (RT_FAILURE(rc)) { m->m_pSession = NIL_RTR0PTR; LogRel(("VBoxNetBaseService: SUPR3Init -> %Rrc\n", rc)); return rc; } char szPath[RTPATH_MAX]; rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/VMMR0.r0")); if (RT_FAILURE(rc)) { LogRel(("VBoxNetBaseService: RTPathExecDir -> %Rrc\n", rc)); return rc; } rc = SUPR3LoadVMM(strcat(szPath, "/VMMR0.r0")); if (RT_FAILURE(rc)) { LogRel(("VBoxNetBaseService: SUPR3LoadVMM(\"%s\") -> %Rrc\n", szPath, rc)); return rc; } /* * Create the open request. */ PINTNETBUF pBuf; INTNETOPENREQ OpenReq; OpenReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; OpenReq.Hdr.cbReq = sizeof(OpenReq); OpenReq.pSession = m->m_pSession; RTStrCopy(OpenReq.szNetwork, sizeof(OpenReq.szNetwork), m->m_NetworkName.c_str()); OpenReq.szNetwork[sizeof(OpenReq.szNetwork) - 1] = '\0'; RTStrCopy(OpenReq.szTrunk, sizeof(OpenReq.szTrunk), m->m_TrunkName.c_str()); OpenReq.szTrunk[sizeof(OpenReq.szTrunk) - 1] = '\0'; OpenReq.enmTrunkType = m->m_enmTrunkType; OpenReq.fFlags = 0; /** @todo check this */ OpenReq.cbSend = m->m_cbSendBuf; OpenReq.cbRecv = m->m_cbRecvBuf; OpenReq.hIf = INTNET_HANDLE_INVALID; /* * Issue the request. */ Log2(("attempting to open/create network \"%s\"...\n", OpenReq.szNetwork)); rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_OPEN, 0, &OpenReq.Hdr); if (RT_FAILURE(rc)) { Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_OPEN,) failed, rc=%Rrc\n", rc)); return rc; } m->m_hIf = OpenReq.hIf; Log2(("successfully opened/created \"%s\" - hIf=%#x\n", OpenReq.szNetwork, m->m_hIf)); /* * Get the ring-3 address of the shared interface buffer. */ INTNETIFGETBUFFERPTRSREQ GetBufferPtrsReq; GetBufferPtrsReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; GetBufferPtrsReq.Hdr.cbReq = sizeof(GetBufferPtrsReq); GetBufferPtrsReq.pSession = m->m_pSession; GetBufferPtrsReq.hIf = m->m_hIf; GetBufferPtrsReq.pRing3Buf = NULL; GetBufferPtrsReq.pRing0Buf = NIL_RTR0PTR; rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS, 0, &GetBufferPtrsReq.Hdr); if (RT_FAILURE(rc)) { Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS,) failed, rc=%Rrc\n", rc)); return rc; } pBuf = GetBufferPtrsReq.pRing3Buf; Log2(("pBuf=%p cbBuf=%d cbSend=%d cbRecv=%d\n", pBuf, pBuf->cbBuf, pBuf->cbSend, pBuf->cbRecv)); m->m_pIfBuf = pBuf; /* * Activate the interface. */ INTNETIFSETACTIVEREQ ActiveReq; ActiveReq.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; ActiveReq.Hdr.cbReq = sizeof(ActiveReq); ActiveReq.pSession = m->m_pSession; ActiveReq.hIf = m->m_hIf; ActiveReq.fActive = true; rc = SUPR3CallVMMR0Ex(NIL_RTR0PTR, NIL_VMCPUID, VMMR0_DO_INTNET_IF_SET_ACTIVE, 0, &ActiveReq.Hdr); if (RT_SUCCESS(rc)) return 0; /* bail out */ Log2(("VBoxNetBaseService: SUPR3CallVMMR0Ex(,VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,) failed, rc=%Rrc\n", rc)); /* ignore this error */ return VINF_SUCCESS; }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); if (argc == 1) { char szPath[RTPATH_MAX]; int rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/..")); if (RT_FAILURE(rc)) { RTPrintf("fatal error: RTPathExecDir -> %Rrc\n", rc); return 1; } rc = RTPathSetCurrent(strcat(szPath, "/..")); if (RT_FAILURE(rc)) { RTPrintf("fatal error: RTPathSetCurrent -> %Rrc\n", rc); return 1; } Process("testcase/tst*", "testcase"); Process("tst*", "."); } else { char szDir[RTPATH_MAX]; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { /* case '':... */ default: RTPrintf("syntax error: Option '%s' is not recognized\n", argv[i]); return 1; } } else { size_t cch = strlen(argv[i]); if (cch >= sizeof(szDir)) { RTPrintf("syntax error: '%s' is too long!\n", argv[i]); return 1; } memcpy(szDir, argv[i], cch + 1); char *pszFilename = RTPathFilename(szDir); if (!pszFilename) { RTPrintf("syntax error: '%s' does not include a file name or file name mask!\n", argv[i]); return 1; } RTPathStripFilename(szDir); Process(argv[i], szDir); } } } RTPrintf("\n" "********************\n" "*** PASSED: %u\n" "*** FAILED: %u\n" "*** SKIPPED: %u\n" "*** TOTAL: %u\n", g_cPasses, g_cFailures, g_cSkipped, g_cPasses + g_cFailures + g_cSkipped); return !!g_cFailures; }