/** * Formats a type using a registered callback handler. * * This will handle %R[type]. * * @returns The number of bytes formatted. * @param pfnOutput Pointer to output function. * @param pvArgOutput Argument for the output function. * @param ppszFormat Pointer to the format string pointer. Advance this till the char * after the format specifier. * @param pArgs Pointer to the argument list. Use this to fetch the arguments. * @param cchWidth Format Width. -1 if not specified. * @param cchPrecision Format Precision. -1 if not specified. * @param fFlags Flags (RTSTR_NTFS_*). * @param chArgSize The argument size specifier, 'l' or 'L'. */ DECLHIDDEN(size_t) rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs, int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize) { size_t cch; int32_t i; char const *pszTypeEnd; char const *pszType; char ch; void *pvValue = va_arg(*pArgs, void *); NOREF(chArgSize); /* * Parse out the type. */ pszType = *ppszFormat + 2; *ppszFormat = pszType; Assert(pszType[-1] == '['); Assert(pszType[-2] == 'R'); pszTypeEnd = pszType; while ((ch = *pszTypeEnd) != ']') { AssertReturn(ch != '\0', 0); AssertReturn(ch != '%', 0); AssertReturn(ch != '[', 0); pszTypeEnd++; } *ppszFormat = pszTypeEnd + 1; /* * Locate the entry and call the handler. */ rtstrFormatTypeReadLock(); i = rtstrFormatTypeLookup(pszType, pszTypeEnd - pszType); if (RT_LIKELY(i >= 0)) { #ifdef IN_RC PFNRTSTRFORMATTYPE pfnHandler = (PFNRTSTRFORMATTYPE)((intptr_t)&g_aTypes[0] + g_aTypes[i].offHandler); #else PFNRTSTRFORMATTYPE pfnHandler = g_aTypes[i].pfnHandler; #endif void *pvUser = ASMAtomicReadPtr(&g_aTypes[i].pvUser); rtstrFormatTypeReadUnlock(); cch = pfnHandler(pfnOutput, pvArgOutput, g_aTypes[i].szType, pvValue, cchWidth, cchPrecision, fFlags, pvUser); } else { rtstrFormatTypeReadUnlock(); cch = pfnOutput(pvArgOutput, RT_STR_TUPLE("<missing:%R[")); cch += pfnOutput(pvArgOutput, pszType, pszTypeEnd - pszType); cch += pfnOutput(pvArgOutput, RT_STR_TUPLE("]>")); } return cch; }
int CollectorLinux::getDiskListByFs(const char *pszPath, DiskList& listUsage, DiskList& listLoad) { FILE *mtab = setmntent("/etc/mtab", "r"); if (mtab) { struct mntent *mntent; while ((mntent = getmntent(mtab))) { /* Skip rootfs entry, there must be another root mount. */ if (strcmp(mntent->mnt_fsname, "rootfs") == 0) continue; if (strcmp(pszPath, mntent->mnt_dir) == 0) { char szDevName[128]; char szFsName[1024]; /* Try to resolve symbolic link if necessary. Yes, we access the file system here! */ int rc = RTPathReal(mntent->mnt_fsname, szFsName, sizeof(szFsName)); if (RT_FAILURE(rc)) continue; /* something got wrong, just ignore this path */ /* check against the actual mtab entry, NOT the real path as /dev/mapper/xyz is * often a symlink to something else */ if (!strncmp(mntent->mnt_fsname, RT_STR_TUPLE("/dev/mapper"))) { /* LVM */ getDiskName(szDevName, sizeof(szDevName), mntent->mnt_fsname, false /*=fTrimDigits*/); addVolumeDependencies(szDevName, listUsage); listLoad = listUsage; } else if (!strncmp(szFsName, RT_STR_TUPLE("/dev/md"))) { /* Software RAID */ getDiskName(szDevName, sizeof(szDevName), szFsName, false /*=fTrimDigits*/); listUsage.push_back(RTCString(szDevName)); addRaidDisks(szDevName, listLoad); } else { /* Plain disk partition. Trim the trailing digits to get the drive name */ getDiskName(szDevName, sizeof(szDevName), szFsName, true /*=fTrimDigits*/); listUsage.push_back(RTCString(szDevName)); listLoad.push_back(RTCString(szDevName)); } if (listUsage.empty() || listLoad.empty()) { LogRel(("Failed to retrive disk info: getDiskName(%s) --> %s\n", mntent->mnt_fsname, szDevName)); } break; } } endmntent(mtab); } return VINF_SUCCESS; }
RTR3DECL(int) RTHttpUseSystemProxySettings(RTHTTP hHttp) { PRTHTTPINTERNAL pHttpInt = hHttp; RTHTTP_VALID_RETURN(pHttpInt); /* * Very limited right now, just enought to make it work for ourselves. */ char szProxy[_1K]; int rc = RTEnvGetEx(RTENV_DEFAULT, "http_proxy", szProxy, sizeof(szProxy), NULL); if (RT_SUCCESS(rc)) { int rcCurl; if (!strncmp(szProxy, RT_STR_TUPLE("http://"))) { rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_PROXY, &szProxy[sizeof("http://") - 1]); if (CURL_FAILED(rcCurl)) return VERR_INVALID_PARAMETER; rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_PROXYPORT, 80); if (CURL_FAILED(rcCurl)) return VERR_INVALID_PARAMETER; } else { rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_PROXY, &szProxy[sizeof("http://") - 1]); if (CURL_FAILED(rcCurl)) return VERR_INVALID_PARAMETER; } } else if (rc == VERR_ENV_VAR_NOT_FOUND) rc = VINF_SUCCESS; return rc; }
void CollectorLinux::addVolumeDependencies(const char *pcszVolume, DiskList& listDisks) { char szVolInfo[RTPATH_MAX]; int rc = RTPathAppPrivateArch(szVolInfo, sizeof(szVolInfo) - sizeof("/" VBOXVOLINFO_NAME " ") - strlen(pcszVolume)); if (RT_FAILURE(rc)) { LogRel(("VolInfo: Failed to get program path, rc=%Rrc\n", rc)); return; } strcat(szVolInfo, "/" VBOXVOLINFO_NAME " "); strcat(szVolInfo, pcszVolume); FILE *fp = popen(szVolInfo, "r"); if (fp) { char szBuf[128]; while (fgets(szBuf, sizeof(szBuf), fp)) if (strncmp(szBuf, RT_STR_TUPLE("dm-"))) listDisks.push_back(RTCString(trimTrailingDigits(szBuf))); else listDisks.push_back(RTCString(trimNewline(szBuf))); pclose(fp); } else listDisks.push_back(RTCString(pcszVolume)); }
RTDECL(int) RTSystemQueryAvailableRam(uint64_t *pcb) { AssertPtrReturn(pcb, VERR_INVALID_POINTER); FILE *pFile = fopen("/proc/meminfo", "r"); if (pFile) { int rc = VERR_NOT_FOUND; uint64_t cbTotal = 0; uint64_t cbFree = 0; uint64_t cbBuffers = 0; uint64_t cbCached = 0; char sz[256]; while (fgets(sz, sizeof(sz), pFile)) { if (!strncmp(sz, RT_STR_TUPLE("MemTotal:"))) rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("MemTotal:")]), NULL, 0, &cbTotal); else if (!strncmp(sz, RT_STR_TUPLE("MemFree:"))) rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("MemFree:")]), NULL, 0, &cbFree); else if (!strncmp(sz, RT_STR_TUPLE("Buffers:"))) rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("Buffers:")]), NULL, 0, &cbBuffers); else if (!strncmp(sz, RT_STR_TUPLE("Cached:"))) rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("Cached:")]), NULL, 0, &cbCached); if (RT_FAILURE(rc)) break; } fclose(pFile); if (RT_SUCCESS(rc)) { *pcb = (cbFree + cbBuffers + cbCached) * _1K; return VINF_SUCCESS; } } /* * Fallback (e.g. /proc not mapped) to sysinfo. Less accurat because there * is no information about the cached memory. 'Cached:' from above is only * accessible through proc :-( */ struct sysinfo info; int rc = sysinfo(&info); if (rc == 0) { *pcb = ((uint64_t)info.freeram + info.bufferram) * info.mem_unit; return VINF_SUCCESS; } return RTErrConvertFromErrno(errno); }
int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list) { char szDefaultIface[256]; int rc = getDefaultIfaceName(szDefaultIface); if (RT_FAILURE(rc)) { Log(("NetIfList: Failed to find default interface.\n")); szDefaultIface[0] = 0; } int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock >= 0) { FILE *fp = fopen("/proc/net/dev", "r"); if (fp) { char buf[256]; while (fgets(buf, sizeof(buf), fp)) { char *pszEndOfName = strchr(buf, ':'); if (!pszEndOfName) continue; *pszEndOfName = 0; int iFirstNonWS = strspn(buf, " "); char *pszName = buf+iFirstNonWS; NETIFINFO Info; RT_ZERO(Info); rc = getInterfaceInfo(sock, pszName, &Info); if (RT_FAILURE(rc)) break; if (Info.enmMediumType == NETIF_T_ETHERNET) { ComObjPtr<HostNetworkInterface> IfObj; IfObj.createObject(); HostNetworkInterfaceType_T enmType; if (strncmp(pszName, RT_STR_TUPLE("vboxnet"))) enmType = HostNetworkInterfaceType_Bridged; else enmType = HostNetworkInterfaceType_HostOnly; if (SUCCEEDED(IfObj->init(Bstr(pszName), enmType, &Info))) { if (strcmp(pszName, szDefaultIface) == 0) list.push_front(IfObj); else list.push_back(IfObj); } } } fclose(fp); } close(sock); } else rc = VERR_INTERNAL_ERROR; return rc; }
/** * Checkes for logger prefixes and selects the right logger. * * @returns Target logger. * @param ppsz Pointer to the string pointer. */ static PRTLOGGER dbgfR3LogResolvedLogger(const char **ppsz) { PRTLOGGER pLogger; const char *psz = *ppsz; if (!strncmp(psz, RT_STR_TUPLE("release:"))) { *ppsz += sizeof("release:") - 1; pLogger = RTLogRelGetDefaultInstance(); } else { if (!strncmp(psz, RT_STR_TUPLE("debug:"))) *ppsz += sizeof("debug:") - 1; pLogger = RTLogDefaultInstance(); } return pLogger; }
/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */ static DECLCALLBACK(int) rtDbgModDeferredDbg_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol, PRTDBGSYMBOL pSymInfo) { int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/); if (RT_SUCCESS(rc)) rc = pMod->pDbgVt->pfnSymbolByName(pMod, pszSymbol, cchSymbol, pSymInfo); else { PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv; if ( cchSymbol == sizeof("DeferredStart") - 1 && !memcmp(pszSymbol, RT_STR_TUPLE("DeferredStart"))) rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo); else if ( cchSymbol == sizeof("DeferredLast") - 1 && !memcmp(pszSymbol, RT_STR_TUPLE("DeferredLast"))) rc = rtDbgModDeferredDbgSymInfo_Last(pThis, pSymInfo); else rc = VERR_SYMBOL_NOT_FOUND; } return rc; }
/** * Adds a debug file to the cache. * * @returns IPRT status code * @param pszPath The path to the debug file in question. * @param pCfg The configuration. */ static int rtDbgSymCacheAddDebugFile(const char *pszPath, PCRTDBGSYMCACHEADDCFG pCfg) { /* * Need to extract an identifier of sorts here in order to put them in * the right place in the cache. Currently only implemnted for Mach-O * files since these use executable containers. * * We take a look at the file header in hope to figure out what to do * with the file. */ RTFILE hFile; int rc = RTFileOpen(&hFile, pszPath, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); if (RT_FAILURE(rc)) return RTMsgErrorRc(rc, "Error opening '%s': %Rrc", pszPath, rc); union { uint64_t au64[16]; uint32_t au32[16]; uint16_t au16[32]; uint8_t ab[64]; } uBuf; rc = RTFileRead(hFile, &uBuf, sizeof(uBuf), NULL); if (RT_SUCCESS(rc)) { /* * Look for magics and call workers. */ if (!memcmp(uBuf.ab, RT_STR_TUPLE("Microsoft C/C++ MSF 7.00"))) rc = rtDbgSymCacheAddDebugPdb(pszPath, pCfg, hFile); else if ( uBuf.au32[0] == IMAGE_FAT_SIGNATURE || uBuf.au32[0] == IMAGE_FAT_SIGNATURE_OE || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE_OE || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE_OE) rc = rtDbgSymCacheAddDebugMachO(pszPath, pCfg); else rc = RTMsgErrorRc(VERR_INVALID_MAGIC, "Unsupported debug file '%s' magic: %#010x", pszPath, uBuf.au32[0]); } else rc = RTMsgErrorRc(rc, "Error reading '%s': %Rrc", pszPath, rc); /* close the file. */ int rc2 = RTFileClose(hFile); if (RT_FAILURE(rc2)) { RTMsgError("Error closing '%s': %Rrc", pszPath, rc2); if (RT_SUCCESS(rc)) rc = rc2; } return rc; }
/** * Internal worker that picks the processor speed in MHz from /proc/cpuinfo. * * @returns CPU frequency. */ static uint32_t rtMpLinuxGetFrequency(RTCPUID idCpu) { FILE *pFile = fopen("/proc/cpuinfo", "r"); if (!pFile) return 0; char sz[256]; RTCPUID idCpuFound = NIL_RTCPUID; uint32_t Frequency = 0; while (fgets(sz, sizeof(sz), pFile)) { char *psz; if ( !strncmp(sz, RT_STR_TUPLE("processor")) && (sz[10] == ' ' || sz[10] == '\t' || sz[10] == ':') && (psz = strchr(sz, ':'))) { psz += 2; int64_t iCpu; int rc = RTStrToInt64Ex(psz, NULL, 0, &iCpu); if (RT_SUCCESS(rc)) idCpuFound = iCpu; } else if ( idCpu == idCpuFound && !strncmp(sz, RT_STR_TUPLE("cpu MHz")) && (sz[10] == ' ' || sz[10] == '\t' || sz[10] == ':') && (psz = strchr(sz, ':'))) { psz += 2; int64_t v; int rc = RTStrToInt64Ex(psz, &psz, 0, &v); if (RT_SUCCESS(rc)) { Frequency = v; break; } } } fclose(pFile); return Frequency; }
static USBDEVICESTATE solarisDetermineUSBDeviceState(PUSBDEVICE pDevice, di_node_t Node) { char *pszDriverName = di_driver_name(Node); /* Not possible unless a user explicitly unbinds the default driver. */ if (!pszDriverName) return USBDEVICESTATE_UNUSED; if (!strncmp(pszDriverName, RT_STR_TUPLE(VBOXUSB_DRIVER_NAME))) return USBDEVICESTATE_HELD_BY_PROXY; NOREF(pDevice); return USBDEVICESTATE_USED_BY_HOST_CAPTURABLE; }
/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */ static DECLCALLBACK(int) rtDbgModDeferredDbg_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo) { int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/); if (RT_SUCCESS(rc)) rc = pMod->pDbgVt->pfnSegmentByIndex(pMod, iSeg, pSegInfo); else if (iSeg == 0) { PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv; pSegInfo->Address = 0; pSegInfo->uRva = 0; pSegInfo->cb = pThis->cbImage; pSegInfo->fFlags = 0; pSegInfo->iSeg = 0; memcpy(pSegInfo->szName, RT_STR_TUPLE("LATER")); rc = VINF_SUCCESS; } else rc = VERR_DBG_INVALID_SEGMENT_INDEX; return rc; }
RTDECL(int) RTUriFilePathEx(const char *pszUri, uint32_t fPathStyle, char **ppszPath, size_t cbPath, size_t *pcchPath) { /* * Validate and adjust input. */ if (pcchPath) { AssertPtrReturn(pcchPath, VERR_INVALID_POINTER); *pcchPath = ~(size_t)0; } AssertPtrReturn(ppszPath, VERR_INVALID_POINTER); AssertReturn(!(fPathStyle & ~RTPATH_STR_F_STYLE_MASK) && fPathStyle != RTPATH_STR_F_STYLE_RESERVED, VERR_INVALID_FLAGS); if (fPathStyle == RTPATH_STR_F_STYLE_HOST) fPathStyle = RTPATH_STYLE; AssertPtrReturn(pszUri, VERR_INVALID_POINTER); /* * Check that this is a file URI. */ if (RTStrNICmp(pszUri, RT_STR_TUPLE("file:")) == 0) { /* likely */ } else return VERR_URI_NOT_FILE_SCHEME; /* * We may have a number of variations here, mostly thanks to * various windows software. First the canonical variations: * - file:///C:/Windows/System32/kernel32.dll * - file:///C|/Windows/System32/kernel32.dll * - file:///C:%5CWindows%5CSystem32%5Ckernel32.dll * - file://localhost/C:%5CWindows%5CSystem32%5Ckernel32.dll * - file://cifsserver.dev/systemshare%5CWindows%5CSystem32%5Ckernel32.dll * - file://cifsserver.dev:139/systemshare%5CWindows%5CSystem32%5Ckernel32.dll (not quite sure here, but whatever) * * Legacy variant without any slashes after the schema: * - file:C:/Windows/System32/kernel32.dll * - file:C|/Windows/System32%5Ckernel32.dll * - file:~/.bashrc * \--path-/ * * Legacy variant with exactly one slashes after the schema: * - file:/C:/Windows/System32%5Ckernel32.dll * - file:/C|/Windows/System32/kernel32.dll * - file:/usr/bin/env * \---path---/ * * Legacy variant with two slashes after the schema and an unescaped DOS path: * - file://C:/Windows/System32\kernel32.dll (**) * - file://C|/Windows/System32\kernel32.dll * \---path---------------------/ * -- authority, with ':' as non-working port separator * * Legacy variant with exactly four slashes after the schema and an unescaped DOS path. * - file:////C:/Windows\System32\user32.dll * * Legacy variant with four or more slashes after the schema and an unescaped UNC path: * - file:////cifsserver.dev/systemshare/System32%\kernel32.dll * - file://///cifsserver.dev/systemshare/System32\kernel32.dll * \---path--------------------------------------------/ * * The the two unescaped variants shouldn't be handed to rtUriParse, which * is good as we cannot actually handle the one marked by (**). So, handle * those two special when parsing. */ RTURIPARSED Parsed; int rc; size_t cSlashes = 0; while (pszUri[5 + cSlashes] == '/') cSlashes++; if ( (cSlashes == 2 || cSlashes == 4) && RT_C_IS_ALPHA(pszUri[5 + cSlashes]) && (pszUri[5 + cSlashes + 1] == ':' || pszUri[5 + cSlashes + 1] == '|')) { RT_ZERO(Parsed); /* RTURIPARSED_F_CONTAINS_ESCAPED_CHARS is now clear. */ Parsed.offPath = 5 + cSlashes; Parsed.cchPath = strlen(&pszUri[Parsed.offPath]); rc = RTStrValidateEncoding(&pszUri[Parsed.offPath]); } else if (cSlashes >= 4) { RT_ZERO(Parsed); Parsed.fFlags = cSlashes > 4 ? RTURIPARSED_F_CONTAINS_ESCAPED_CHARS : 0; Parsed.offPath = 5 + cSlashes - 2; Parsed.cchPath = strlen(&pszUri[Parsed.offPath]); rc = RTStrValidateEncoding(&pszUri[Parsed.offPath]); } else rc = rtUriParse(pszUri, &Parsed); if (RT_SUCCESS(rc)) { /* * Ignore localhost as hostname (it's implicit). */ static char const s_szLocalhost[] = "localhost"; if ( Parsed.cchAuthorityHost == sizeof(s_szLocalhost) - 1U && RTStrNICmp(&pszUri[Parsed.offAuthorityHost], RT_STR_TUPLE(s_szLocalhost)) == 0) { Parsed.cchAuthorityHost = 0; Parsed.cchAuthority = 0; } /* * Ignore leading path slash/separator if we detect a DOS drive letter * and we don't have a host name. */ if ( Parsed.cchPath >= 3 && Parsed.cchAuthorityHost == 0 && pszUri[Parsed.offPath] == '/' /* Leading path slash/separator. */ && ( pszUri[Parsed.offPath + 2] == ':' /* Colon after drive letter. */ || pszUri[Parsed.offPath + 2] == '|') /* Colon alternative. */ && RT_C_IS_ALPHA(pszUri[Parsed.offPath + 1]) ) /* Drive letter. */ { Parsed.offPath++; Parsed.cchPath--; } /* * Calculate the size of the encoded result. * * Since we're happily returning "C:/Windows/System32/kernel.dll" * style paths when the caller requested UNIX style paths, we will * return straight UNC paths too ("//cifsserver/share/dir/file"). */ size_t cchDecodedHost = 0; size_t cbResult; if (Parsed.fFlags & RTURIPARSED_F_CONTAINS_ESCAPED_CHARS) { cchDecodedHost = rtUriCalcDecodedLength(&pszUri[Parsed.offAuthorityHost], Parsed.cchAuthorityHost); cbResult = cchDecodedHost + rtUriCalcDecodedLength(&pszUri[Parsed.offPath], Parsed.cchPath) + 1; } else { cchDecodedHost = 0; cbResult = Parsed.cchAuthorityHost + Parsed.cchPath + 1; } if (pcchPath) *pcchPath = cbResult - 1; if (cbResult > 1) { /* * Prepare the necessary buffer space for the result. */ char *pszDst; char *pszFreeMe = NULL; if (!cbPath || *ppszPath == NULL) { cbPath = RT_MAX(cbPath, cbResult); *ppszPath = pszFreeMe = pszDst = RTStrAlloc(cbPath); AssertReturn(pszDst, VERR_NO_STR_MEMORY); } else if (cbResult <= cbPath) pszDst = *ppszPath; else return VERR_BUFFER_OVERFLOW; /* * Compose the result. */ if (Parsed.fFlags & RTURIPARSED_F_CONTAINS_ESCAPED_CHARS) { rc = rtUriDecodeIntoBuffer(&pszUri[Parsed.offAuthorityHost],Parsed.cchAuthorityHost, pszDst, cchDecodedHost + 1); Assert(RT_SUCCESS(rc) && strlen(pszDst) == cchDecodedHost); if (RT_SUCCESS(rc)) rc = rtUriDecodeIntoBuffer(&pszUri[Parsed.offPath], Parsed.cchPath, &pszDst[cchDecodedHost], cbResult - cchDecodedHost); Assert(RT_SUCCESS(rc) && strlen(pszDst) == cbResult - 1); } else { memcpy(pszDst, &pszUri[Parsed.offAuthorityHost], Parsed.cchAuthorityHost); memcpy(&pszDst[Parsed.cchAuthorityHost], &pszUri[Parsed.offPath], Parsed.cchPath); pszDst[cbResult - 1] = '\0'; } if (RT_SUCCESS(rc)) { /* * Convert colon DOS driver letter colon alternative. * We do this regardless of the desired path style. */ if ( RT_C_IS_ALPHA(pszDst[0]) && pszDst[1] == '|') pszDst[1] = ':'; /* * Fix slashes. */ if (fPathStyle == RTPATH_STR_F_STYLE_DOS) RTPathChangeToDosSlashes(pszDst, true); else if (fPathStyle == RTPATH_STR_F_STYLE_UNIX) RTPathChangeToUnixSlashes(pszDst, true); /** @todo not quite sure how this actually makes sense... */ else AssertFailed(); return rc; } /* bail out */ RTStrFree(pszFreeMe); } else rc = VERR_PATH_ZERO_LENGTH; } return 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 }
/********************************************************************************************************************************* * Header Files * *********************************************************************************************************************************/ #include "internal/iprt.h" #include <iprt/crypto/store.h> #include <iprt/assert.h> #include <iprt/err.h> #include <iprt/crypto/pem.h> /********************************************************************************************************************************* * Global Variables * *********************************************************************************************************************************/ static RTCRPEMMARKERWORD const g_aWords_Certificate[] = { { RT_STR_TUPLE("CERTIFICATE") } }; /** X509 Certificate markers. */ static RTCRPEMMARKER const g_aCertificateMarkers[] = { { g_aWords_Certificate, RT_ELEMENTS(g_aWords_Certificate) } }; #if 0 RTDECL(int) RTCrX509Certificates_ReadFromFile(const char *pszFilename, uint32_t fFlags, PRTCRX509CERTIFICATES pCertificates, PRTERRINFO pErrInfo) { AssertReturn(!fFlags, VERR_INVALID_FLAGS); PCRTCRPEMSECTION pSectionHead; int rc = RTCrPemReadFile(pszFilename, 0, g_aCertificateMarkers, RT_ELEMENTS(g_aCertificateMarkers), &pSectionHead, pErrInfo); if (RT_SUCCESS(rc)) { pCertificates->Allocation
/** * Corrects the casing of the final component * * @returns * @param pClient . * @param pszFullPath . * @param pszStartComponent . */ static int vbsfCorrectCasing(SHFLCLIENTDATA *pClient, char *pszFullPath, char *pszStartComponent) { Log2(("vbsfCorrectCasing: %s %s\n", pszFullPath, pszStartComponent)); AssertReturn((uintptr_t)pszFullPath < (uintptr_t)pszStartComponent - 1U, VERR_INTERNAL_ERROR_2); AssertReturn(pszStartComponent[-1] == RTPATH_DELIMITER, VERR_INTERNAL_ERROR_5); /* * Allocate a buffer that can hold really long file name entries as well as * the initial search pattern. */ size_t cchComponent = strlen(pszStartComponent); size_t cchParentDir = pszStartComponent - pszFullPath; size_t cchFullPath = cchParentDir + cchComponent; Assert(strlen(pszFullPath) == cchFullPath); size_t cbDirEntry = 4096; if (cchFullPath + 4 > cbDirEntry - RT_OFFSETOF(RTDIRENTRYEX, szName)) cbDirEntry = RT_OFFSETOF(RTDIRENTRYEX, szName) + cchFullPath + 4; PRTDIRENTRYEX pDirEntry = (PRTDIRENTRYEX)RTMemAlloc(cbDirEntry); if (pDirEntry == NULL) return VERR_NO_MEMORY; /* * Construct the search criteria in the szName member of pDirEntry. */ /** @todo This is quite inefficient, especially for directories with many * files. If any of the typically case sensitive host systems start * supporting opendir wildcard filters, it would make sense to build * one here with '?' for case foldable charaters. */ /** @todo Use RTDirOpen here and drop the whole uncessary path copying? */ int rc = RTPathJoinEx(pDirEntry->szName, cbDirEntry - RT_OFFSETOF(RTDIRENTRYEX, szName), pszFullPath, cchParentDir, RT_STR_TUPLE("*")); AssertRC(rc); if (RT_SUCCESS(rc)) { RTDIR hSearch = NULL; rc = RTDirOpenFiltered(&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT, 0 /*fFlags*/); if (RT_SUCCESS(rc)) { for (;;) { size_t cbDirEntrySize = cbDirEntry; rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient)); if (rc == VERR_NO_MORE_FILES) break; if ( rc != VINF_SUCCESS && rc != VWRN_NO_DIRENT_INFO) { if ( rc == VERR_NO_TRANSLATION || rc == VERR_INVALID_UTF8_ENCODING) continue; AssertMsgFailed(("%Rrc\n", rc)); break; } Log2(("vbsfCorrectCasing: found %s\n", &pDirEntry->szName[0])); if ( pDirEntry->cbName == cchComponent && !RTStrICmp(pszStartComponent, &pDirEntry->szName[0])) { Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent)); strcpy(pszStartComponent, &pDirEntry->szName[0]); rc = VINF_SUCCESS; break; } } RTDirClose(hSearch); } } if (RT_FAILURE(rc)) Log(("vbsfCorrectCasing %s failed with %Rrc\n", pszStartComponent, rc)); RTMemFree(pDirEntry); return rc; }
RTDECL(int) RTDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags) { int rc; /* * Validate input. */ AssertPtrReturn(pDir, VERR_INVALID_POINTER); AssertReturn(pDir->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE); AssertPtrReturn(pDirEntry, VERR_INVALID_POINTER); AssertReturn(enmAdditionalAttribs >= RTFSOBJATTRADD_NOTHING && enmAdditionalAttribs <= RTFSOBJATTRADD_LAST, VERR_INVALID_PARAMETER); AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); size_t cbDirEntry = sizeof(*pDirEntry); if (pcbDirEntry) { cbDirEntry = *pcbDirEntry; AssertMsgReturn(cbDirEntry >= RT_UOFFSETOF(RTDIRENTRYEX, szName[2]), ("Invalid *pcbDirEntry=%d (min %d)\n", *pcbDirEntry, RT_OFFSETOF(RTDIRENTRYEX, szName[2])), VERR_INVALID_PARAMETER); } /* * Fetch data? */ if (!pDir->fDataUnread) { rc = rtDirNtFetchMore(pDir); if (RT_FAILURE(rc)) return rc; } /* * Convert the filename to UTF-8. */ rc = rtDirNtConvertCurName(pDir); if (RT_FAILURE(rc)) return rc; /* * Check if we've got enough space to return the data. */ const char *pszName = pDir->pszName; const size_t cchName = pDir->cchName; const size_t cbRequired = RT_OFFSETOF(RTDIRENTRYEX, szName[1]) + cchName; if (pcbDirEntry) *pcbDirEntry = cbRequired; if (cbRequired > cbDirEntry) return VERR_BUFFER_OVERFLOW; /* * Setup the returned data. */ PFILE_BOTH_DIR_INFORMATION pBoth = pDir->uCurData.pBoth; pDirEntry->cbName = (uint16_t)cchName; Assert(pDirEntry->cbName == cchName); memcpy(pDirEntry->szName, pszName, cchName + 1); memset(pDirEntry->wszShortName, 0, sizeof(pDirEntry->wszShortName)); #ifdef IPRT_WITH_NT_PATH_PASSTHRU if (pDir->enmInfoClass != FileMaximumInformation) #endif { uint8_t cbShort = pBoth->ShortNameLength; if (cbShort > 0) { AssertStmt(cbShort < sizeof(pDirEntry->wszShortName), cbShort = sizeof(pDirEntry->wszShortName) - 2); memcpy(pDirEntry->wszShortName, pBoth->ShortName, cbShort); pDirEntry->cwcShortName = cbShort / 2; } else pDirEntry->cwcShortName = 0; pDirEntry->Info.cbObject = pBoth->EndOfFile.QuadPart; pDirEntry->Info.cbAllocated = pBoth->AllocationSize.QuadPart; Assert(sizeof(uint64_t) == sizeof(pBoth->CreationTime)); RTTimeSpecSetNtTime(&pDirEntry->Info.BirthTime, pBoth->CreationTime.QuadPart); RTTimeSpecSetNtTime(&pDirEntry->Info.AccessTime, pBoth->LastAccessTime.QuadPart); RTTimeSpecSetNtTime(&pDirEntry->Info.ModificationTime, pBoth->LastWriteTime.QuadPart); RTTimeSpecSetNtTime(&pDirEntry->Info.ChangeTime, pBoth->ChangeTime.QuadPart); pDirEntry->Info.Attr.fMode = rtFsModeFromDos((pBoth->FileAttributes << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_NT, pszName, cchName); } #ifdef IPRT_WITH_NT_PATH_PASSTHRU else { pDirEntry->cwcShortName = 0; pDirEntry->Info.cbObject = 0; pDirEntry->Info.cbAllocated = 0; RTTimeSpecSetNtTime(&pDirEntry->Info.BirthTime, 0); RTTimeSpecSetNtTime(&pDirEntry->Info.AccessTime, 0); RTTimeSpecSetNtTime(&pDirEntry->Info.ModificationTime, 0); RTTimeSpecSetNtTime(&pDirEntry->Info.ChangeTime, 0); if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length, RT_STR_TUPLE("Directory"))) pDirEntry->Info.Attr.fMode = RTFS_DOS_DIRECTORY | RTFS_TYPE_DIRECTORY | 0777; else if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length, RT_STR_TUPLE("SymbolicLink"))) pDirEntry->Info.Attr.fMode = RTFS_DOS_NT_REPARSE_POINT | RTFS_TYPE_SYMLINK | 0777; else if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length, RT_STR_TUPLE("Device"))) pDirEntry->Info.Attr.fMode = RTFS_DOS_NT_DEVICE | RTFS_TYPE_DEV_CHAR | 0666; else pDirEntry->Info.Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_FILE | 0666; } #endif /* * Requested attributes (we cannot provide anything actually). */ switch (enmAdditionalAttribs) { case RTFSOBJATTRADD_EASIZE: pDirEntry->Info.Attr.enmAdditional = RTFSOBJATTRADD_EASIZE; #ifdef IPRT_WITH_NT_PATH_PASSTHRU if (pDir->enmInfoClass == FileMaximumInformation) pDirEntry->Info.Attr.u.EASize.cb = 0; else #endif pDirEntry->Info.Attr.u.EASize.cb = pBoth->EaSize; break; case RTFSOBJATTRADD_UNIX: pDirEntry->Info.Attr.enmAdditional = RTFSOBJATTRADD_UNIX; pDirEntry->Info.Attr.u.Unix.uid = ~0U; pDirEntry->Info.Attr.u.Unix.gid = ~0U; pDirEntry->Info.Attr.u.Unix.cHardlinks = 1; pDirEntry->Info.Attr.u.Unix.INodeIdDevice = 0; /** @todo Use the volume serial number (see GetFileInformationByHandle). */ pDirEntry->Info.Attr.u.Unix.INodeId = 0; /** @todo Use the fileid (see GetFileInformationByHandle). */ pDirEntry->Info.Attr.u.Unix.fFlags = 0; pDirEntry->Info.Attr.u.Unix.GenerationId = 0; pDirEntry->Info.Attr.u.Unix.Device = 0; break; case RTFSOBJATTRADD_NOTHING: pDirEntry->Info.Attr.enmAdditional = RTFSOBJATTRADD_NOTHING; break; case RTFSOBJATTRADD_UNIX_OWNER: pDirEntry->Info.Attr.enmAdditional = RTFSOBJATTRADD_UNIX_OWNER; pDirEntry->Info.Attr.u.UnixOwner.uid = ~0U; pDirEntry->Info.Attr.u.UnixOwner.szName[0] = '\0'; /** @todo return something sensible here. */ break; case RTFSOBJATTRADD_UNIX_GROUP: pDirEntry->Info.Attr.enmAdditional = RTFSOBJATTRADD_UNIX_GROUP; pDirEntry->Info.Attr.u.UnixGroup.gid = ~0U; pDirEntry->Info.Attr.u.UnixGroup.szName[0] = '\0'; break; default: AssertMsgFailed(("Impossible!\n")); return VERR_INTERNAL_ERROR; } /* * Follow links if requested. */ if ( (fFlags & RTPATH_F_FOLLOW_LINK) && RTFS_IS_SYMLINK(fFlags)) { /** @todo Symlinks: Find[First|Next]FileW will return info about the link, so RTPATH_F_FOLLOW_LINK is not handled correctly. */ } /* * Finally advance the buffer. */ return rtDirNtAdvanceBuffer(pDir); }
RTDECL(int) RTDirRead(PRTDIR pDir, PRTDIRENTRY pDirEntry, size_t *pcbDirEntry) { int rc; /* * Validate input. */ AssertPtrReturn(pDir, VERR_INVALID_POINTER); AssertReturn(pDir->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE); AssertPtrReturn(pDirEntry, VERR_INVALID_POINTER); size_t cbDirEntry = sizeof(*pDirEntry); if (pcbDirEntry) { cbDirEntry = *pcbDirEntry; AssertMsgReturn(cbDirEntry >= RT_UOFFSETOF(RTDIRENTRY, szName[2]), ("Invalid *pcbDirEntry=%d (min %d)\n", *pcbDirEntry, RT_OFFSETOF(RTDIRENTRY, szName[2])), VERR_INVALID_PARAMETER); } /* * Fetch data? */ if (!pDir->fDataUnread) { rc = rtDirNtFetchMore(pDir); if (RT_FAILURE(rc)) return rc; } /* * Convert the filename to UTF-8. */ rc = rtDirNtConvertCurName(pDir); if (RT_FAILURE(rc)) return rc; /* * Check if we've got enough space to return the data. */ const char *pszName = pDir->pszName; const size_t cchName = pDir->cchName; const size_t cbRequired = RT_OFFSETOF(RTDIRENTRY, szName[1]) + cchName; if (pcbDirEntry) *pcbDirEntry = cbRequired; if (cbRequired > cbDirEntry) return VERR_BUFFER_OVERFLOW; /* * Setup the returned data. */ pDirEntry->cbName = (uint16_t)cchName; Assert(pDirEntry->cbName == cchName); memcpy(pDirEntry->szName, pszName, cchName + 1); pDirEntry->INodeId = pDir->enmInfoClass == FileIdBothDirectoryInformation ? pDir->uCurData.pBothId->FileId.QuadPart : 0; #ifdef IPRT_WITH_NT_PATH_PASSTHRU if (pDir->enmInfoClass != FileMaximumInformation) #endif { switch ( pDir->uCurData.pBoth->FileAttributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY)) { default: AssertFailed(); case 0: pDirEntry->enmType = RTDIRENTRYTYPE_FILE; break; case FILE_ATTRIBUTE_DIRECTORY: pDirEntry->enmType = RTDIRENTRYTYPE_DIRECTORY; break; case FILE_ATTRIBUTE_REPARSE_POINT: case FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY: pDirEntry->enmType = RTDIRENTRYTYPE_SYMLINK; break; } } #ifdef IPRT_WITH_NT_PATH_PASSTHRU else { pDirEntry->enmType = RTDIRENTRYTYPE_UNKNOWN; if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length, RT_STR_TUPLE("Directory"))) pDirEntry->enmType = RTDIRENTRYTYPE_DIRECTORY; else if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length, RT_STR_TUPLE("SymbolicLink"))) pDirEntry->enmType = RTDIRENTRYTYPE_SYMLINK; } #endif return rtDirNtAdvanceBuffer(pDir); }
/** * One test iteration with one file. * * The test is very simple, we load the file three times * into two different regions. The first two into each of the * regions the for compare usage. The third is loaded into one * and then relocated between the two and other locations a few times. * * @returns number of errors. * @param pszFilename The file to load the mess with. */ static int testLdrOne(const char *pszFilename) { int cErrors = 0; size_t cbImage = 0; struct Load { RTLDRMOD hLdrMod; void *pvBits; size_t cbBits; const char *pszName; } aLoads[6] = { { NULL, NULL, 0, "foo" }, { NULL, NULL, 0, "bar" }, { NULL, NULL, 0, "foobar" }, { NULL, NULL, 0, "kLdr-foo" }, { NULL, NULL, 0, "kLdr-bar" }, { NULL, NULL, 0, "kLdr-foobar" } }; unsigned i; int rc; /* * Load them. */ for (i = 0; i < RT_ELEMENTS(aLoads); i++) { if (!strncmp(aLoads[i].pszName, RT_STR_TUPLE("kLdr-"))) rc = RTLdrOpenkLdr(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); else rc = RTLdrOpen(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to open '%s'/%d, rc=%Rrc. aborting test.\n", pszFilename, i, rc); Assert(aLoads[i].hLdrMod == NIL_RTLDRMOD); cErrors++; break; } /* size it */ size_t cb = RTLdrSize(aLoads[i].hLdrMod); if (cbImage && cb != cbImage) { RTPrintf("tstLdr-4: Size mismatch '%s'/%d. aborting test.\n", pszFilename, i); cErrors++; break; } aLoads[i].cbBits = cbImage = cb; /* Allocate bits. */ aLoads[i].pvBits = RTMemExecAlloc(cb); if (!aLoads[i].pvBits) { RTPrintf("tstLdr-4: Out of memory '%s'/%d cbImage=%d. aborting test.\n", pszFilename, i, cbImage); cErrors++; break; } /* Get the bits. */ rc = RTLdrGetBits(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, testGetImport, NULL); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to get bits for '%s'/%d, rc=%Rrc. aborting test\n", pszFilename, i, rc); cErrors++; break; } } /* * Execute the code. */ if (!cErrors) { for (i = 0; i < RT_ELEMENTS(aLoads); i += 1) { /* get the pointer. */ RTUINTPTR Value; rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, UINT32_MAX, "DisasmTest1", &Value); if (rc == VERR_SYMBOL_NOT_FOUND) rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, UINT32_MAX, "_DisasmTest1", &Value); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to get symbol \"DisasmTest1\" from load #%d: %Rrc\n", i, rc); cErrors++; break; } DECLCALLBACKPTR(int, pfnDisasmTest1)(void) = (DECLCALLBACKPTR(int, RT_NOTHING)(void))(uintptr_t)Value; /* eeeh. */ RTPrintf("tstLdr-4: pfnDisasmTest1=%p / add-symbol-file %s %#x\n", pfnDisasmTest1, pszFilename, aLoads[i].pvBits); /* call the test function. */ rc = pfnDisasmTest1(); if (rc) { RTPrintf("tstLdr-4: load #%d Test1 -> %#x\n", i, rc); cErrors++; } } } /* * Clean up. */ for (i = 0; i < RT_ELEMENTS(aLoads); i++) { if (aLoads[i].pvBits) RTMemExecFree(aLoads[i].pvBits, aLoads[i].cbBits); if (aLoads[i].hLdrMod) { rc = RTLdrClose(aLoads[i].hLdrMod); if (RT_FAILURE(rc)) { RTPrintf("tstLdr-4: Failed to close '%s' i=%d, rc=%Rrc.\n", pszFilename, i, rc); cErrors++; } } } return cErrors; }
static int solarisWalkDeviceNode(di_node_t Node, void *pvArg) { PUSBDEVICELIST pList = (PUSBDEVICELIST)pvArg; AssertPtrReturn(pList, DI_WALK_TERMINATE); /* * Check if it's a USB device in the first place. */ bool fUSBDevice = false; char *pszCompatNames = NULL; int cCompatNames = di_compatible_names(Node, &pszCompatNames); for (int i = 0; i < cCompatNames; i++, pszCompatNames += strlen(pszCompatNames) + 1) if (!strncmp(pszCompatNames, RT_STR_TUPLE("usb"))) { fUSBDevice = true; break; } if (!fUSBDevice) return DI_WALK_CONTINUE; /* * Check if it's a device node or interface. */ int *pInt = NULL; char *pStr = NULL; int rc = DI_WALK_CONTINUE; if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "interface", &pInt) < 0) { /* It's a device node. */ char *pszDevicePath = di_devfs_path(Node); PUSBDEVICE pCur = (PUSBDEVICE)RTMemAllocZ(sizeof(*pCur)); if (!pCur) { LogRel(("USBService: failed to allocate %d bytes for PUSBDEVICE.\n", sizeof(*pCur))); return DI_WALK_TERMINATE; } bool fValidDevice = false; do { AssertBreak(pszDevicePath); char *pszDriverName = di_driver_name(Node); /* * Skip hubs */ if ( pszDriverName && !strcmp(pszDriverName, "hubd")) { break; } /* * Mandatory. * snv_85 and above have usb-dev-descriptor node properties, but older one's do not. * So if we cannot obtain the entire device descriptor, we try falling back to the * individual properties (those must not fail, if it does we drop the device). */ uchar_t *pDevData = NULL; int cbProp = di_prop_lookup_bytes(DDI_DEV_T_ANY, Node, "usb-dev-descriptor", &pDevData); if ( cbProp > 0 && pDevData) { usb_dev_descr_t *pDeviceDescriptor = (usb_dev_descr_t *)pDevData; pCur->bDeviceClass = pDeviceDescriptor->bDeviceClass; pCur->bDeviceSubClass = pDeviceDescriptor->bDeviceSubClass; pCur->bDeviceProtocol = pDeviceDescriptor->bDeviceProtocol; pCur->idVendor = pDeviceDescriptor->idVendor; pCur->idProduct = pDeviceDescriptor->idProduct; pCur->bcdDevice = pDeviceDescriptor->bcdDevice; pCur->bcdUSB = pDeviceDescriptor->bcdUSB; pCur->bNumConfigurations = pDeviceDescriptor->bNumConfigurations; pCur->fPartialDescriptor = false; } else { AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-vendor-id", &pInt) > 0); pCur->idVendor = (uint16_t)*pInt; AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-product-id", &pInt) > 0); pCur->idProduct = (uint16_t)*pInt; AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-revision-id", &pInt) > 0); pCur->bcdDevice = (uint16_t)*pInt; AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-release", &pInt) > 0); pCur->bcdUSB = (uint16_t)*pInt; pCur->fPartialDescriptor = true; } char *pszPortAddr = di_bus_addr(Node); if (pszPortAddr) pCur->bPort = RTStrToUInt8(pszPortAddr); /* Bus & Port are mixed up (kernel driver/userland) */ else pCur->bPort = 0; char szBuf[PATH_MAX + 48]; RTStrPrintf(szBuf, sizeof(szBuf), "%#x:%#x:%d:%s", pCur->idVendor, pCur->idProduct, pCur->bcdDevice, pszDevicePath); pCur->pszAddress = RTStrDup(szBuf); AssertBreak(pCur->pszAddress); pCur->pszDevicePath = RTStrDup(pszDevicePath); AssertBreak(pCur->pszDevicePath); pCur->pszBackend = RTStrDup("host"); AssertBreak(pCur->pszBackend); /* * Optional (some devices don't have all these) */ char *pszCopy; if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-product-name", &pStr) > 0) { pCur->pszProduct = pszCopy = RTStrDup(pStr); USBLibPurgeEncoding(pszCopy); } if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-vendor-name", &pStr) > 0) { pCur->pszManufacturer = pszCopy = RTStrDup(pStr); USBLibPurgeEncoding(pszCopy); } if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-serialno", &pStr) > 0) { pCur->pszSerialNumber = pszCopy = RTStrDup(pStr); USBLibPurgeEncoding(pszCopy); } if (pCur->bcdUSB == 0x300) pCur->enmSpeed = USBDEVICESPEED_SUPER; else if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "low-speed", &pInt) >= 0) pCur->enmSpeed = USBDEVICESPEED_LOW; else if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "high-speed", &pInt) >= 0) pCur->enmSpeed = USBDEVICESPEED_HIGH; else pCur->enmSpeed = USBDEVICESPEED_FULL; /* Determine state of the USB device. */ pCur->enmState = solarisDetermineUSBDeviceState(pCur, Node); /* * Valid device, add it to the list. */ fValidDevice = true; pCur->pPrev = pList->pTail; if (pList->pTail) pList->pTail = pList->pTail->pNext = pCur; else pList->pTail = pList->pHead = pCur; rc = DI_WALK_CONTINUE; } while (0); di_devfs_path_free(pszDevicePath); if (!fValidDevice) solarisFreeUSBDevice(pCur); } return rc; }
/** * Resolves imported functions, esp. system calls from NTDLL. * * This crap is necessary because there are sandboxing products out there that * will mess with system calls we make, just like any other wannabe userland * rootkit. Kudos to microsoft for not providing a generic system call hook API * in the kernel mode, which I guess is what forcing these kind of products to * do ugly userland hacks that doesn't really hold water. */ DECLHIDDEN(void) supR3HardenedWinInitImports(void) { /* * Find the DLLs we will be needing first (forwarders). */ for (uint32_t iDll = 0; iDll < RT_ELEMENTS(g_aSupNtImpDlls); iDll++) { supR3HardenedFindOrLoadModule(&g_aSupNtImpDlls[iDll]); if (g_aSupNtImpDlls[iDll].pbImageBase) supR3HardenedParseModule(&g_aSupNtImpDlls[iDll]); } /* * Resolve the functions. */ for (uint32_t iDll = 0; iDll < RT_ELEMENTS(g_aSupNtImpDlls); iDll++) for (uint32_t i = 0; i < g_aSupNtImpDlls[iDll].cImports; i++) { const char *pszForwarder = supR3HardenedResolveImport(&g_aSupNtImpDlls[iDll], &g_aSupNtImpDlls[iDll].paImports[i], false); if (pszForwarder) { const char *pszDot = strchr(pszForwarder, '.'); size_t cchDllName = pszDot - pszForwarder; SUPHNTIMPFUNC Tmp = g_aSupNtImpDlls[iDll].paImports[i]; Tmp.pszName = pszDot + 1; if (cchDllName == sizeof("ntdll") - 1 && RTStrNICmp(pszForwarder, RT_STR_TUPLE("ntdll")) == 0) supR3HardenedResolveImport(&g_aSupNtImpDlls[0], &Tmp, false); else if (cchDllName == sizeof("kernelbase") - 1 && RTStrNICmp(pszForwarder, RT_STR_TUPLE("kernelbase")) == 0) supR3HardenedResolveImport(&g_aSupNtImpDlls[1], &Tmp, false); else SUPHNTIMP_ERROR(false, 18, "supR3HardenedWinInitImports", kSupInitOp_Misc, VERR_MODULE_NOT_FOUND, "%ls: Failed to resolve forwarder '%s'.", g_aSupNtImpDlls[iDll].pwszName, pszForwarder); } } /* * Do system calls directly. */ supR3HardenedWinInitSyscalls(false); /* * Use the on disk image to avoid export table patching. Currently * ignoring errors here as can live normally without this step. */ for (uint32_t iDll = 0; iDll < RT_ELEMENTS(g_aSupNtImpDlls); iDll++) if (g_aSupNtImpDlls[iDll].cPatchedExports > 0) { PSUPHNTLDRCACHEENTRY pLdrEntry; int rc = supHardNtLdrCacheOpen(g_aSupNtImpDlls[iDll].pszName, &pLdrEntry); if (RT_SUCCESS(rc)) { uint8_t *pbBits; rc = supHardNtLdrCacheEntryGetBits(pLdrEntry, &pbBits, (uintptr_t)g_aSupNtImpDlls[iDll].pbImageBase, NULL, NULL, NULL /*pErrInfo*/); if (RT_SUCCESS(rc)) for (uint32_t i = 0; i < g_aSupNtImpDlls[iDll].cImports; i++) { RTLDRADDR uValue; rc = RTLdrGetSymbolEx(pLdrEntry->hLdrMod, pbBits, (uintptr_t)g_aSupNtImpDlls[iDll].pbImageBase, UINT32_MAX, g_aSupNtImpDlls[iDll].paImports[i].pszName, &uValue); if (RT_SUCCESS(rc)) *g_aSupNtImpDlls[iDll].paImports[i].ppfnImport = (PFNRT)(uintptr_t)uValue; } } } #if 0 /* Win7/32 ntdll!LdrpDebugFlags. */ *(uint8_t *)&g_aSupNtImpDlls[0].pbImageBase[0xdd770] = 0x3; #endif }
/** * @callback_method_impl{FNRTSTRFORMATTYPE, vmsetcpu} */ static DECLCALLBACK(size_t) vmmFormatTypeVmCpuSet(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char *pszType, void const *pvValue, int cchWidth, int cchPrecision, unsigned fFlags, void *pvUser) { NOREF(pszType); NOREF(cchWidth); NOREF(cchPrecision); NOREF(fFlags); PCVMCPUSET pSet = (PCVMCPUSET)pvValue; uint32_t cCpus = 0; uint32_t iCpu = RT_ELEMENTS(pSet->au32Bitmap) * 32; while (iCpu--) if (VMCPUSET_IS_PRESENT(pSet, iCpu)) cCpus++; char szTmp[32]; AssertCompile(RT_ELEMENTS(pSet->au32Bitmap) * 32 < 999); if (cCpus == 1) { iCpu = RT_ELEMENTS(pSet->au32Bitmap) * 32; while (iCpu--) if (VMCPUSET_IS_PRESENT(pSet, iCpu)) { szTmp[0] = 'c'; szTmp[1] = 'p'; szTmp[2] = 'u'; return pfnOutput(pvArgOutput, szTmp, 3 + vmmFormatTypeShortNumber(&szTmp[3], iCpu)); } cCpus = 0; } if (cCpus == 0) return pfnOutput(pvArgOutput, RT_STR_TUPLE("<empty>")); if (cCpus == RT_ELEMENTS(pSet->au32Bitmap) * 32) return pfnOutput(pvArgOutput, RT_STR_TUPLE("<full>")); /* * Print cpus that are present: {1,2,7,9 ... } */ size_t cchRet = pfnOutput(pvArgOutput, "{", 1); cCpus = 0; iCpu = 0; while (iCpu < RT_ELEMENTS(pSet->au32Bitmap) * 32) { if (VMCPUSET_IS_PRESENT(pSet, iCpu)) { /* Output the first cpu number. */ int off = 0; if (cCpus != 0) szTmp[off++] = ','; off += vmmFormatTypeShortNumber(&szTmp[off], iCpu); /* Check for sequence. */ uint32_t const iStart = ++iCpu; while ( iCpu < RT_ELEMENTS(pSet->au32Bitmap) * 32 && VMCPUSET_IS_PRESENT(pSet, iCpu)) iCpu++; if (iCpu != iStart) { szTmp[off++] = '-'; off += vmmFormatTypeShortNumber(&szTmp[off], iCpu); } /* Terminate and output. */ szTmp[off] = '\0'; cchRet += pfnOutput(pvArgOutput, szTmp, off); } iCpu++; } cchRet += pfnOutput(pvArgOutput, "}", 1); NOREF(pvUser); return cchRet; }
int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list) { int rc = VINF_SUCCESS; size_t cbNeeded; char *pBuf, *pNext; int aiMib[6]; unsigned short u16DefaultIface = 0; /* initialized to shut up gcc */ /* Get the index of the interface associated with default route. */ rc = getDefaultIfaceIndex(&u16DefaultIface); if (RT_FAILURE(rc)) return rc; aiMib[0] = CTL_NET; aiMib[1] = PF_ROUTE; aiMib[2] = 0; aiMib[3] = 0; /* address family */ aiMib[4] = NET_RT_IFLIST; aiMib[5] = 0; if (sysctl(aiMib, 6, NULL, &cbNeeded, NULL, 0) < 0) { Log(("NetIfList: Failed to get estimate for list size (errno=%d).\n", errno)); return RTErrConvertFromErrno(errno); } if ((pBuf = (char*)RTMemAlloc(cbNeeded)) == NULL) return VERR_NO_MEMORY; if (sysctl(aiMib, 6, pBuf, &cbNeeded, NULL, 0) < 0) { RTMemFree(pBuf); Log(("NetIfList: Failed to retrieve interface table (errno=%d).\n", errno)); return RTErrConvertFromErrno(errno); } int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock < 0) { RTMemFree(pBuf); Log(("NetIfList: socket() -> %d\n", errno)); return RTErrConvertFromErrno(errno); } PDARWINETHERNIC pNIC; PDARWINETHERNIC pEtherNICs = DarwinGetEthernetControllers(); char *pEnd = pBuf + cbNeeded; for (pNext = pBuf; pNext < pEnd;) { struct if_msghdr *pIfMsg = (struct if_msghdr *)pNext; if (pIfMsg->ifm_type != RTM_IFINFO) { Log(("NetIfList: Got message %u while expecting %u.\n", pIfMsg->ifm_type, RTM_IFINFO)); rc = VERR_INTERNAL_ERROR; break; } struct sockaddr_dl *pSdl = (struct sockaddr_dl *)(pIfMsg + 1); size_t cbNameLen = pSdl->sdl_nlen + 1; Assert(pSdl->sdl_nlen < sizeof(pNIC->szBSDName)); for (pNIC = pEtherNICs; pNIC; pNIC = pNIC->pNext) if ( !strncmp(pSdl->sdl_data, pNIC->szBSDName, pSdl->sdl_nlen) && pNIC->szBSDName[pSdl->sdl_nlen] == '\0') { cbNameLen = strlen(pNIC->szName) + 1; break; } PNETIFINFO pNew = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen])); if (!pNew) { rc = VERR_NO_MEMORY; break; } memcpy(pNew->MACAddress.au8, LLADDR(pSdl), sizeof(pNew->MACAddress.au8)); pNew->enmMediumType = NETIF_T_ETHERNET; Assert(sizeof(pNew->szShortName) > pSdl->sdl_nlen); memcpy(pNew->szShortName, pSdl->sdl_data, RT_MIN(pSdl->sdl_nlen, sizeof(pNew->szShortName) - 1)); /* * If we found the adapter in the list returned by * DarwinGetEthernetControllers() copy the name and UUID from there. */ if (pNIC) { memcpy(pNew->szName, pNIC->szName, cbNameLen); pNew->Uuid = pNIC->Uuid; } else { memcpy(pNew->szName, pSdl->sdl_data, pSdl->sdl_nlen); /* Generate UUID from name and MAC address. */ RTUUID uuid; RTUuidClear(&uuid); memcpy(&uuid, pNew->szShortName, RT_MIN(cbNameLen, sizeof(uuid))); uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; memcpy(uuid.Gen.au8Node, pNew->MACAddress.au8, sizeof(uuid.Gen.au8Node)); pNew->Uuid = uuid; } pNext += pIfMsg->ifm_msglen; while (pNext < pEnd) { struct ifa_msghdr *pIfAddrMsg = (struct ifa_msghdr *)pNext; if (pIfAddrMsg->ifam_type != RTM_NEWADDR) break; extractAddressesToNetInfo(pIfAddrMsg->ifam_addrs, (char *)(pIfAddrMsg + 1), pIfAddrMsg->ifam_msglen + (char *)pIfAddrMsg, pNew); pNext += pIfAddrMsg->ifam_msglen; } if (pSdl->sdl_type == IFT_ETHER) { struct ifreq IfReq; RTStrCopy(IfReq.ifr_name, sizeof(IfReq.ifr_name), pNew->szShortName); if (ioctl(sock, SIOCGIFFLAGS, &IfReq) < 0) { Log(("NetIfList: ioctl(SIOCGIFFLAGS) -> %d\n", errno)); pNew->enmStatus = NETIF_S_UNKNOWN; } else pNew->enmStatus = (IfReq.ifr_flags & IFF_UP) ? NETIF_S_UP : NETIF_S_DOWN; HostNetworkInterfaceType_T enmType; if (strncmp(pNew->szName, RT_STR_TUPLE("vboxnet"))) enmType = HostNetworkInterfaceType_Bridged; else enmType = HostNetworkInterfaceType_HostOnly; ComObjPtr<HostNetworkInterface> IfObj; IfObj.createObject(); if (SUCCEEDED(IfObj->init(Bstr(pNew->szName), enmType, pNew))) { /* Make sure the default interface gets to the beginning. */ if (pIfMsg->ifm_index == u16DefaultIface) list.push_front(IfObj); else list.push_back(IfObj); } } RTMemFree(pNew); } for (pNIC = pEtherNICs; pNIC;) { void *pvFree = pNIC; pNIC = pNIC->pNext; RTMemFree(pvFree); } close(sock); RTMemFree(pBuf); return rc; }
// static void ParsedIntervalFilter_base::parse (const char *aFilter, ParsedIntervalFilter_base *that) { // initially null and valid that->mNull = true; that->mValid = true; that->mErrorPosition = 0; if (!aFilter || strncmp(aFilter, RT_STR_TUPLE("int:")) != 0) return; that->mNull = false; size_t len = strlen (aFilter); Mode mode = Single; // what's expected next size_t start = 4, end = 4; size_t err = 0; // less than 4 indicates success do { end = strcspn(aFilter + start, ",-"); end += start; char delim = aFilter[end]; if (delim == '-') { if (mode == End) { err = end; break; } else mode = Start; } // skip spaces around numbers size_t s = start; while (s < end && aFilter[s] == ' ') ++s; size_t e = end - 1; while (e > s && aFilter[e] == ' ') --e; ++e; that->parseValue(aFilter, s, e, mode); if (!that->mValid) return; if (mode == Start) mode = End; else if (mode == End) mode = Single; start = end + 1; } while (start <= len); if (err >= 4) { that->mValid = false; that->mErrorPosition = err; } }
int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted, SUPINITOP *penmWhat, PRTERRINFO pErrInfo) { /* * Make sure the image verifier is fully initialized. */ int rc = suplibOsHardenedVerifyInit(); if (RT_FAILURE(rc)) return RTErrInfoSetF(pErrInfo, rc, "suplibOsHardenedVerifyInit failed: %Rrc", rc); /* * Done if of pre-inited. */ if (fPreInited) { #if defined(VBOX_WITH_HARDENING) && !defined(IN_SUP_HARDENED_R3) # ifdef IN_SUP_R3_STATIC return VERR_NOT_SUPPORTED; # else return VINF_SUCCESS; # endif #else return VINF_SUCCESS; #endif } /* * Try open the device. */ #ifndef IN_SUP_HARDENED_R3 uint32_t cTry = 0; #endif HANDLE hDevice; for (;;) { IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; static const WCHAR s_wszName[] = L"\\Device\\VBoxDrvU"; UNICODE_STRING NtName; NtName.Buffer = (PWSTR)s_wszName; NtName.Length = sizeof(s_wszName) - sizeof(WCHAR) * (fUnrestricted ? 2 : 1); NtName.MaximumLength = NtName.Length; OBJECT_ATTRIBUTES ObjAttr; InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/); hDevice = RTNT_INVALID_HANDLE_VALUE; NTSTATUS rcNt = NtCreateFile(&hDevice, GENERIC_READ | GENERIC_WRITE, /* No SYNCHRONIZE. */ &ObjAttr, &Ios, NULL /* Allocation Size*/, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE, /* No FILE_SYNCHRONOUS_IO_NONALERT! */ NULL /*EaBuffer*/, 0 /*EaLength*/); if (NT_SUCCESS(rcNt)) rcNt = Ios.Status; if (NT_SUCCESS(rcNt)) { /* * We're good. */ pThis->hDevice = hDevice; pThis->fUnrestricted = fUnrestricted; return VINF_SUCCESS; } #ifndef IN_SUP_HARDENED_R3 /* * Failed to open, try starting the service and reopen the device * exactly once. */ if (cTry == 0 && !NT_SUCCESS(rcNt)) { cTry++; suplibOsStartService(); continue; } #endif /* * Translate the error code. */ switch (rcNt) { /** @todo someone must test what is actually returned. */ case STATUS_DEVICE_DOES_NOT_EXIST: case STATUS_DEVICE_NOT_CONNECTED: //case ERROR_BAD_DEVICE: case STATUS_DEVICE_REMOVED: //case ERROR_DEVICE_NOT_AVAILABLE: rc = VERR_VM_DRIVER_LOAD_ERROR; break; case STATUS_OBJECT_PATH_NOT_FOUND: case STATUS_NO_SUCH_DEVICE: case STATUS_NO_SUCH_FILE: case STATUS_OBJECT_NAME_NOT_FOUND: rc = VERR_VM_DRIVER_NOT_INSTALLED; break; case STATUS_ACCESS_DENIED: case STATUS_SHARING_VIOLATION: rc = VERR_VM_DRIVER_NOT_ACCESSIBLE; break; case STATUS_UNSUCCESSFUL: rc = VERR_SUPLIB_NT_PROCESS_UNTRUSTED_0; break; case STATUS_TRUST_FAILURE: rc = VERR_SUPLIB_NT_PROCESS_UNTRUSTED_1; break; case STATUS_TOO_LATE: rc = VERR_SUPDRV_HARDENING_EVIL_HANDLE; break; default: if (SUP_NT_STATUS_IS_VBOX(rcNt)) /* See VBoxDrvNtErr2NtStatus. */ rc = SUP_NT_STATUS_TO_VBOX(rcNt); else rc = VERR_VM_DRIVER_OPEN_ERROR; break; } #ifdef IN_SUP_HARDENED_R3 /* * Get more details from VBoxDrvErrorInfo if present. */ if (pErrInfo && pErrInfo->cbMsg > 32) { /* Prefix. */ size_t cchPrefix; const char *pszDefine = RTErrGetDefine(rc); if (strncmp(pszDefine, RT_STR_TUPLE("Unknown"))) cchPrefix = RTStrPrintf(pErrInfo->pszMsg, pErrInfo->cbMsg / 2, "Integrity error (%#x/%s): ", rcNt, pszDefine); else cchPrefix = RTStrPrintf(pErrInfo->pszMsg, pErrInfo->cbMsg / 2, "Integrity error (%#x/%d): ", rcNt, rc); /* Get error info. */ supR3HardenedWinReadErrorInfoDevice(pErrInfo->pszMsg + cchPrefix, pErrInfo->cbMsg - cchPrefix, ""); if (pErrInfo->pszMsg[cchPrefix] != '\0') { pErrInfo->fFlags |= RTERRINFO_FLAGS_SET; pErrInfo->rc = rc; *penmWhat = kSupInitOp_Integrity; } else pErrInfo->pszMsg[0] = '\0'; } #endif return rc; } }
} /* * Not one of ours. */ LeaveCriticalSection(&g_CritSect); return CloseHandle(hObject); } /** Replacement functions. */ static const MSIHACKREPLACEMENT g_aReplaceFunctions[] = { { RT_STR_TUPLE("CreateFileA"), NULL, (uintptr_t)MsiHack_Kernel32_CreateFileA }, { RT_STR_TUPLE("CreateFileW"), NULL, (uintptr_t)MsiHack_Kernel32_CreateFileW }, { RT_STR_TUPLE("ReadFile"), NULL, (uintptr_t)MsiHack_Kernel32_ReadFile }, { RT_STR_TUPLE("ReadFileEx"), NULL, (uintptr_t)MsiHack_Kernel32_ReadFileEx }, { RT_STR_TUPLE("SetFilePointer"), NULL, (uintptr_t)MsiHack_Kernel32_SetFilePointer }, { RT_STR_TUPLE("SetFilePointerEx"), NULL, (uintptr_t)MsiHack_Kernel32_SetFilePointerEx }, { RT_STR_TUPLE("DuplicateHandle"), NULL, (uintptr_t)MsiHack_Kernel32_DuplicateHandle }, { RT_STR_TUPLE("CloseHandle"), NULL, (uintptr_t)MsiHack_Kernel32_CloseHandle }, }; /** * Patches the import table of the given DLL. * * @returns true on success, false on failure.
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); RTDIGESTTYPE enmDigestType = RTDIGESTTYPE_INVALID; const char *pszDigestType = "NotSpecified"; enum { kMethod_Full, kMethod_Block, kMethod_File, kMethod_CVAS } enmMethod = kMethod_Block; uint64_t offStart = 0; uint64_t cbMax = UINT64_MAX; bool fTestcase = false; static const RTGETOPTDEF s_aOptions[] = { { "--type", 't', RTGETOPT_REQ_STRING }, { "--method", 'm', RTGETOPT_REQ_STRING }, { "--help", 'h', RTGETOPT_REQ_NOTHING }, { "--length", 'l', RTGETOPT_REQ_UINT64 }, { "--offset", 'o', RTGETOPT_REQ_UINT64 }, { "--testcase", 'x', RTGETOPT_REQ_NOTHING }, }; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 't': if (!RTStrICmp(ValueUnion.psz, "crc32")) { pszDigestType = "CRC32"; enmDigestType = RTDIGESTTYPE_CRC32; } else if (!RTStrICmp(ValueUnion.psz, "crc64")) { pszDigestType = "CRC64"; enmDigestType = RTDIGESTTYPE_CRC64; } else if (!RTStrICmp(ValueUnion.psz, "md2")) { pszDigestType = "MD2"; enmDigestType = RTDIGESTTYPE_MD2; } else if (!RTStrICmp(ValueUnion.psz, "md5")) { pszDigestType = "MD5"; enmDigestType = RTDIGESTTYPE_MD5; } else if (!RTStrICmp(ValueUnion.psz, "sha1")) { pszDigestType = "SHA-1"; enmDigestType = RTDIGESTTYPE_SHA1; } else if (!RTStrICmp(ValueUnion.psz, "sha224")) { pszDigestType = "SHA-224"; enmDigestType = RTDIGESTTYPE_SHA224; } else if (!RTStrICmp(ValueUnion.psz, "sha256")) { pszDigestType = "SHA-256"; enmDigestType = RTDIGESTTYPE_SHA256; } else if (!RTStrICmp(ValueUnion.psz, "sha384")) { pszDigestType = "SHA-384"; enmDigestType = RTDIGESTTYPE_SHA384; } else if (!RTStrICmp(ValueUnion.psz, "sha512")) { pszDigestType = "SHA-512"; enmDigestType = RTDIGESTTYPE_SHA512; } else if (!RTStrICmp(ValueUnion.psz, "sha512/224")) { pszDigestType = "SHA-512/224"; enmDigestType = RTDIGESTTYPE_SHA512T224; } else if (!RTStrICmp(ValueUnion.psz, "sha512/256")) { pszDigestType = "SHA-512/256"; enmDigestType = RTDIGESTTYPE_SHA512T256; } else { Error("Invalid digest type: %s\n", ValueUnion.psz); return 1; } break; case 'm': if (!RTStrICmp(ValueUnion.psz, "full")) enmMethod = kMethod_Full; else if (!RTStrICmp(ValueUnion.psz, "block")) enmMethod = kMethod_Block; else if (!RTStrICmp(ValueUnion.psz, "file")) enmMethod = kMethod_File; else if (!RTStrICmp(ValueUnion.psz, "cvas")) enmMethod = kMethod_CVAS; else { Error("Invalid digest method: %s\n", ValueUnion.psz); return 1; } break; case 'l': cbMax = ValueUnion.u64; break; case 'o': offStart = ValueUnion.u64; break; case 'x': fTestcase = true; break; case 'h': RTPrintf("usage: tstRTDigest -t <digest-type> [-o <offset>] [-l <length>] [-x] file [file2 [..]]\n"); return 1; case VINF_GETOPT_NOT_OPTION: { if (enmDigestType == RTDIGESTTYPE_INVALID) return Error("No digest type was specified\n"); switch (enmMethod) { case kMethod_Full: return Error("Full file method is not implemented\n"); case kMethod_File: if (offStart != 0 || cbMax != UINT64_MAX) return Error("The -l and -o options do not work with the 'file' method."); switch (enmDigestType) { case RTDIGESTTYPE_SHA1: { char *pszDigest; int rc = RTSha1DigestFromFile(ValueUnion.psz, &pszDigest, NULL, NULL); if (RT_FAILURE(rc)) return Error("RTSha1Digest(%s,) -> %Rrc\n", ValueUnion.psz, rc); RTPrintf("%s %s\n", pszDigest, ValueUnion.psz); RTStrFree(pszDigest); break; } case RTDIGESTTYPE_SHA256: { char *pszDigest; int rc = RTSha256DigestFromFile(ValueUnion.psz, &pszDigest, NULL, NULL); if (RT_FAILURE(rc)) return Error("RTSha256Digest(%s,) -> %Rrc\n", ValueUnion.psz, rc); RTPrintf("%s %s\n", pszDigest, ValueUnion.psz); RTStrFree(pszDigest); break; } default: return Error("The file method isn't implemented for this digest\n"); } break; case kMethod_Block: { RTFILE hFile; int rc = RTFileOpen(&hFile, ValueUnion.psz, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); if (RT_FAILURE(rc)) return Error("RTFileOpen(,%s,) -> %Rrc\n", ValueUnion.psz, rc); if (offStart != 0) { rc = RTFileSeek(hFile, offStart, RTFILE_SEEK_BEGIN, NULL); if (RT_FAILURE(rc)) return Error("RTFileSeek(%s,%ull) -> %Rrc\n", ValueUnion.psz, offStart, rc); } uint64_t cbMaxLeft = cbMax; size_t cbRead; uint8_t abBuf[_64K]; char *pszDigest = (char *)&abBuf[0]; switch (enmDigestType) { case RTDIGESTTYPE_CRC32: { uint32_t uCRC32 = RTCrc32Start(); for (;;) { rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft); if (RT_FAILURE(rc) || !cbRead) break; uCRC32 = RTCrc32Process(uCRC32, abBuf, cbRead); } uCRC32 = RTCrc32Finish(uCRC32); RTStrPrintf(pszDigest, sizeof(abBuf), "%08RX32", uCRC32); break; } case RTDIGESTTYPE_CRC64: { uint64_t uCRC64 = RTCrc64Start(); for (;;) { rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft); if (RT_FAILURE(rc) || !cbRead) break; uCRC64 = RTCrc64Process(uCRC64, abBuf, cbRead); } uCRC64 = RTCrc64Finish(uCRC64); RTStrPrintf(pszDigest, sizeof(abBuf), "%016RX64", uCRC64); break; } case RTDIGESTTYPE_MD2: { RTMD2CONTEXT Ctx; RTMd2Init(&Ctx); for (;;) { rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft); if (RT_FAILURE(rc) || !cbRead) break; RTMd2Update(&Ctx, abBuf, cbRead); } uint8_t abDigest[RTMD2_HASH_SIZE]; RTMd2Final(&Ctx, abDigest); RTMd2ToString(abDigest, pszDigest, sizeof(abBuf)); break; } case RTDIGESTTYPE_MD5: { RTMD5CONTEXT Ctx; RTMd5Init(&Ctx); for (;;) { rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft); if (RT_FAILURE(rc) || !cbRead) break; RTMd5Update(&Ctx, abBuf, cbRead); } uint8_t abDigest[RTMD5HASHSIZE]; RTMd5Final(abDigest, &Ctx); RTMd5ToString(abDigest, pszDigest, sizeof(abBuf)); break; } case RTDIGESTTYPE_SHA1: { RTSHA1CONTEXT Ctx; RTSha1Init(&Ctx); for (;;) { rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft); if (RT_FAILURE(rc) || !cbRead) break; RTSha1Update(&Ctx, abBuf, cbRead); } uint8_t abDigest[RTSHA1_HASH_SIZE]; RTSha1Final(&Ctx, abDigest); RTSha1ToString(abDigest, pszDigest, sizeof(abBuf)); break; } case RTDIGESTTYPE_SHA256: { RTSHA256CONTEXT Ctx; RTSha256Init(&Ctx); for (;;) { rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft); if (RT_FAILURE(rc) || !cbRead) break; RTSha256Update(&Ctx, abBuf, cbRead); } uint8_t abDigest[RTSHA256_HASH_SIZE]; RTSha256Final(&Ctx, abDigest); RTSha256ToString(abDigest, pszDigest, sizeof(abBuf)); break; } case RTDIGESTTYPE_SHA512: { RTSHA512CONTEXT Ctx; RTSha512Init(&Ctx); for (;;) { rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft); if (RT_FAILURE(rc) || !cbRead) break; RTSha512Update(&Ctx, abBuf, cbRead); } uint8_t abDigest[RTSHA512_HASH_SIZE]; RTSha512Final(&Ctx, abDigest); RTSha512ToString(abDigest, pszDigest, sizeof(abBuf)); break; } default: return Error("Internal error #1\n"); } RTFileClose(hFile); if (RT_FAILURE(rc) && rc != VERR_EOF) { RTPrintf("Partial: %s %s\n", pszDigest, ValueUnion.psz); return Error("RTFileRead(%s) -> %Rrc\n", ValueUnion.psz, rc); } if (!fTestcase) RTPrintf("%s %s\n", pszDigest, ValueUnion.psz); else if (offStart) RTPrintf(" { &g_abRandom72KB[%#4llx], %5llu, \"%s\", \"%s %llu bytes @%llu\" },\n", offStart, cbMax - cbMaxLeft, pszDigest, pszDigestType, offStart, cbMax - cbMaxLeft); else RTPrintf(" { &g_abRandom72KB[0], %5llu, \"%s\", \"%s %llu bytes\" },\n", cbMax - cbMaxLeft, pszDigest, pszDigestType, cbMax - cbMaxLeft); break; } /* * Process a SHS response file: * http://csrc.nist.gov/groups/STM/cavp/index.html#03 */ case kMethod_CVAS: { RTCRDIGEST hDigest; int rc = RTCrDigestCreateByType(&hDigest, enmDigestType); if (RT_FAILURE(rc)) return Error("Failed to create digest calculator for %s: %Rrc", pszDigestType, rc); uint32_t const cbDigest = RTCrDigestGetHashSize(hDigest); if (!cbDigest || cbDigest >= _1K) return Error("Unexpected hash size: %#x\n", cbDigest); PRTSTREAM pFile; rc = RTStrmOpen(ValueUnion.psz, "r", &pFile); if (RT_FAILURE(rc)) return Error("Failed to open CVAS file '%s': %Rrc", ValueUnion.psz, rc); /* * Parse the input file. * ASSUME order: Len, Msg, MD. */ static char s_szLine[_256K]; char *psz; uint32_t cPassed = 0; uint32_t cErrors = 0; uint32_t iLine = 1; for (;;) { psz = MyGetNextSignificantLine(pFile, s_szLine, sizeof(s_szLine), &iLine, &rc); if (!psz) break; /* Skip [L = 20] stuff. */ if (*psz == '[') continue; /* Message length. */ uint64_t cMessageBits; if (RTStrNICmp(psz, RT_STR_TUPLE("Len ="))) return Error("%s(%d): Expected 'Len =' found '%.10s...'", ValueUnion.psz, iLine, psz); psz = RTStrStripL(psz + 5); rc = RTStrToUInt64Full(psz, 0, &cMessageBits); if (rc != VINF_SUCCESS) return Error("%s(%d): Error parsing length '%s': %Rrc\n", ValueUnion.psz, iLine, psz, rc); /* The message text. */ psz = MyGetNextSignificantLine(pFile, s_szLine, sizeof(s_szLine), &iLine, &rc); if (!psz) return Error("%s(%d): Expected message text not EOF.", ValueUnion.psz, iLine); if (RTStrNICmp(psz, RT_STR_TUPLE("Msg ="))) return Error("%s(%d): Expected 'Msg =' found '%.10s...'", ValueUnion.psz, iLine, psz); psz = RTStrStripL(psz + 5); size_t const cbMessage = (cMessageBits + 7) / 8; static uint8_t s_abMessage[sizeof(s_szLine) / 2]; if (cbMessage > 0) { rc = RTStrConvertHexBytes(psz, s_abMessage, cbMessage, 0 /*fFlags*/); if (rc != VINF_SUCCESS) return Error("%s(%d): Error parsing message '%.10s...': %Rrc\n", ValueUnion.psz, iLine, psz, rc); } /* The message digest. */ psz = MyGetNextSignificantLine(pFile, s_szLine, sizeof(s_szLine), &iLine, &rc); if (!psz) return Error("%s(%d): Expected message digest not EOF.", ValueUnion.psz, iLine); if (RTStrNICmp(psz, RT_STR_TUPLE("MD ="))) return Error("%s(%d): Expected 'MD =' found '%.10s...'", ValueUnion.psz, iLine, psz); psz = RTStrStripL(psz + 4); static uint8_t s_abExpectedDigest[_1K]; rc = RTStrConvertHexBytes(psz, s_abExpectedDigest, cbDigest, 0 /*fFlags*/); if (rc != VINF_SUCCESS) return Error("%s(%d): Error parsing message digest '%.10s...': %Rrc\n", ValueUnion.psz, iLine, psz, rc); /* * Do the testing. */ rc = RTCrDigestReset(hDigest); if (rc != VINF_SUCCESS) return Error("RTCrDigestReset failed: %Rrc", rc); rc = RTCrDigestUpdate(hDigest, s_abMessage, cbMessage); if (rc != VINF_SUCCESS) return Error("RTCrDigestUpdate failed: %Rrc", rc); static uint8_t s_abActualDigest[_1K]; rc = RTCrDigestFinal(hDigest, s_abActualDigest, cbDigest); if (rc != VINF_SUCCESS) return Error("RTCrDigestFinal failed: %Rrc", rc); if (memcmp(s_abActualDigest, s_abExpectedDigest, cbDigest) == 0) cPassed++; else { Error("%s(%d): Message digest mismatch. Expected %.*RThxs, got %.*RThxs.", ValueUnion.psz, iLine, cbDigest, s_abExpectedDigest, cbDigest, s_abActualDigest); cErrors++; } } RTStrmClose(pFile); if (cErrors > 0) return Error("Failed: %u error%s (%u passed)", cErrors, cErrors == 1 ? "" : "s", cPassed); RTPrintf("Passed %u test%s.\n", cPassed, cPassed == 1 ? "" : "s"); if (RT_FAILURE(rc)) return Error("Failed: %Rrc", rc); break; } default: return Error("Internal error #2\n"); } break; } default: return RTGetOptPrintError(ch, &ValueUnion); } } return 0; }
* Global Variables * *********************************************************************************************************************************/ /** * VMM trace point group translation table. */ static const struct { /** The group name. */ const char *pszName; /** The name length. */ uint32_t cchName; /** The mask. */ uint32_t fMask; } g_aVmmTpGroups[] = { { RT_STR_TUPLE("em"), VMMTPGROUP_EM }, { RT_STR_TUPLE("hm"), VMMTPGROUP_HM }, { RT_STR_TUPLE("tm"), VMMTPGROUP_TM }, }; /** * Initializes the tracing. * * @returns VBox status code * @param pVM The cross context VM structure. * @param cbEntry The trace entry size. * @param cEntries The number of entries. */ static int dbgfR3TraceEnable(PVM pVM, uint32_t cbEntry, uint32_t cEntries) {
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 bool fUserSession = false; #ifdef VBOX_WITH_GUEST_CONTROL /* * Check if we're the specially spawned VBoxService.exe process that * handles a guest control session. */ if ( argc >= 2 && !RTStrICmp(argv[1], "guestsession")) fUserSession = true; #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. */ if (fUserSession) rc = VbglR3InitUser(); else 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 && !RTStrICmp(argv[1], "pagefusion")) return VBoxServicePageSharingWorkerChild(); #endif #ifdef VBOX_WITH_GUEST_CONTROL /* * Check if we're the specially spawned VBoxService.exe process that * handles a guest control session. */ if (fUserSession) return VBoxServiceControlSessionForkInit(argc, argv); #endif /* * 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, RT_STR_TUPLE("enable-"))) 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, RT_STR_TUPLE("disable-"))) 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, RT_STR_TUPLE("only-"))) 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, g_szLogFile, sizeof(g_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(g_szLogFile) ? g_szLogFile : NULL); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create release log \"%s\", rc=%Rrc\n", strlen(g_szLogFile) ? g_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.\n", g_pszProgName); return RTEXITCODE_FAILURE; } VBoxServiceError("CreateMutex failed with last error %u! Terminating.\n", 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 */, false /* fRespawn */, NULL /* pcRespawn */); 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; }
RTDECL(int) RTCrStoreCreateSnapshotById(PRTCRSTORE phStore, RTCRSTOREID enmStoreId, PRTERRINFO pErrInfo) { AssertReturn(enmStoreId > RTCRSTOREID_INVALID && enmStoreId < RTCRSTOREID_END, VERR_INVALID_PARAMETER); /* * Create an empty in-memory store. */ RTCRSTORE hStore; uint32_t cExpected = enmStoreId == RTCRSTOREID_SYSTEM_TRUSTED_CAS_AND_CERTIFICATES ? 256 : 0; int rc = RTCrStoreCreateInMem(&hStore, cExpected); if (RT_SUCCESS(rc)) { *phStore = hStore; /* * Add system certificates if part of the given store ID. */ bool fFound = false; rc = VINF_SUCCESS; if (enmStoreId == RTCRSTOREID_SYSTEM_TRUSTED_CAS_AND_CERTIFICATES) { for (uint32_t i = 0; i < RT_ELEMENTS(g_apszSystemPemFiles); i++) if (RTFileExists(g_apszSystemPemFiles[i])) { fFound = true; int rc2 = RTCrStoreCertAddFromFile(hStore, RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR, g_apszSystemPemFiles[i], pErrInfo); if (RT_FAILURE(rc2)) rc = -rc2; } /* * If we didn't find any of the certificate collection files, go hunting * for directories containing PEM/CRT files with single certificates. */ if (!fFound) for (uint32_t i = 0; i < RT_ELEMENTS(g_apszSystemPemDirs); i++) if (RTDirExists(g_apszSystemPemDirs[i])) { static RTSTRTUPLE const s_aSuffixes[] = { { RT_STR_TUPLE(".crt") }, { RT_STR_TUPLE(".pem") }, { RT_STR_TUPLE(".PEM") }, { RT_STR_TUPLE(".CRT") }, }; fFound = true; int rc2 = RTCrStoreCertAddFromDir(hStore, RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR, g_apszSystemPemDirs[i], &s_aSuffixes[0], RT_ELEMENTS(s_aSuffixes), pErrInfo); if (RT_FAILURE(rc2)) rc = -rc2; } } } else RTErrInfoAdd(pErrInfo, rc, " RTCrStoreCreateInMem failed"); return rc; }