static char *MyGetNextSignificantLine(PRTSTREAM pFile, char *pszBuf, size_t cbBuf, uint32_t *piLine, int *prc) { for (;;) { *pszBuf = '\0'; int rc = RTStrmGetLine(pFile, pszBuf, cbBuf); if (RT_FAILURE(rc)) { if (rc != VERR_EOF) { Error("Read error: %Rrc", rc); *prc = rc; return NULL; } if (!*pszBuf) return NULL; } *piLine += 1; /* Significant? */ char *pszStart = RTStrStrip(pszBuf); if (*pszStart && *pszStart != '#') return pszStart; } }
/** * Executes the VMMDEV_TESTING_CMD_VALUE_REG command when the data is ready. * * @param pDevIns The PDM device instance. * @param pThis The instance VMMDev data. */ static void vmmdevTestingCmdExec_ValueReg(PPDMDEVINS pDevIns, VMMDevState *pThis) { char *pszRegNm = strchr(pThis->TestingData.String.sz, ':'); if (pszRegNm) { *pszRegNm++ = '\0'; pszRegNm = RTStrStrip(pszRegNm); } char *pszValueNm = RTStrStrip(pThis->TestingData.String.sz); size_t const cchValueNm = strlen(pszValueNm); if (cchValueNm && pszRegNm && *pszRegNm) { PUVM pUVM = PDMDevHlpGetUVM(pDevIns); PVM pVM = PDMDevHlpGetVM(pDevIns); VMCPUID idCpu = VMMGetCpuId(pVM); uint64_t u64Value; int rc2 = DBGFR3RegNmQueryU64(pUVM, idCpu, pszRegNm, &u64Value); if (RT_SUCCESS(rc2)) { const char *pszWarn = rc2 == VINF_DBGF_TRUNCATED_REGISTER ? " truncated" : ""; #if 1 /*!RTTestValue format*/ char szFormat[128], szValue[128]; RTStrPrintf(szFormat, sizeof(szFormat), "%%VR{%s}", pszRegNm); rc2 = DBGFR3RegPrintf(pUVM, idCpu, szValue, sizeof(szValue), szFormat); if (RT_SUCCESS(rc2)) VMMDEV_TESTING_OUTPUT(("testing: VALUE '%s'%*s: %16s {reg=%s}%s\n", pszValueNm, (ssize_t)cchValueNm - 12 > 48 ? 0 : 48 - ((ssize_t)cchValueNm - 12), "", szValue, pszRegNm, pszWarn)); else #endif VMMDEV_TESTING_OUTPUT(("testing: VALUE '%s'%*s: %'9llu (%#llx) [0] {reg=%s}%s\n", pszValueNm, (ssize_t)cchValueNm - 12 > 48 ? 0 : 48 - ((ssize_t)cchValueNm - 12), "", u64Value, u64Value, pszRegNm, pszWarn)); } else VMMDEV_TESTING_OUTPUT(("testing: error querying register '%s' for value '%s': %Rrc\n", pszRegNm, pszValueNm, rc2)); } else VMMDEV_TESTING_OUTPUT(("testing: malformed register value '%s'/'%s'\n", pszValueNm, pszRegNm)); }
RTDECL(int) RTMpGetDescription(RTCPUID idCpu, char *pszBuf, size_t cbBuf) { /* * Check that the specified cpu is valid & online. */ if (idCpu != NIL_RTCPUID && !RTMpIsCpuOnline(idCpu)) return RTMpIsCpuPossible(idCpu) ? VERR_CPU_OFFLINE : VERR_CPU_NOT_FOUND; /* * Construct the description string in a temporary buffer. */ char szString[4*4*3+1]; RT_ZERO(szString); #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) if (!ASMHasCpuId()) return rtMpGetDescriptionUnknown(pszBuf, cbBuf); uint32_t uMax; uint32_t uEBX, uECX, uEDX; ASMCpuId(0x80000000, &uMax, &uEBX, &uECX, &uEDX); if (uMax >= 0x80000002) { ASMCpuId(0x80000002, &szString[0 + 0], &szString[0 + 4], &szString[0 + 8], &szString[0 + 12]); if (uMax >= 0x80000003) ASMCpuId(0x80000003, &szString[16 + 0], &szString[16 + 4], &szString[16 + 8], &szString[16 + 12]); if (uMax >= 0x80000004) ASMCpuId(0x80000004, &szString[32 + 0], &szString[32 + 4], &szString[32 + 8], &szString[32 + 12]); } else { ASMCpuId(0x00000000, &uMax, &uEBX, &uECX, &uEDX); ((uint32_t *)&szString[0])[0] = uEBX; ((uint32_t *)&szString[0])[1] = uEDX; ((uint32_t *)&szString[0])[2] = uECX; } #else # error "PORTME or use RTMpGetDescription-generic-stub.cpp." #endif /* * Copy it out into the buffer supplied by the caller. */ char *pszSrc = RTStrStrip(szString); size_t cchSrc = strlen(pszSrc); if (cchSrc >= cbBuf) return VERR_BUFFER_OVERFLOW; memcpy(pszBuf, pszSrc, cchSrc + 1); return VINF_SUCCESS; }
/** * Reads an ACK or NACK. * * @returns S_OK on ACK, E_FAIL+setError() on failure or NACK. * @param pState The teleporter source state. * @param pszWhich Which ACK is this this? * @param pszNAckMsg Optional NACK message. * * @remarks the setError laziness forces this to be a Console member. */ HRESULT Console::teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, const char *pszNAckMsg /*= NULL*/) { char szMsg[256]; int vrc = teleporterTcpReadLine(pState, szMsg, sizeof(szMsg)); if (RT_FAILURE(vrc)) return setError(E_FAIL, tr("Failed reading ACK(%s): %Rrc"), pszWhich, vrc); if (!strcmp(szMsg, "ACK")) return S_OK; if (!strncmp(szMsg, "NACK=", sizeof("NACK=") - 1)) { char *pszMsgText = strchr(szMsg, ';'); if (pszMsgText) *pszMsgText++ = '\0'; int32_t vrc2; vrc = RTStrToInt32Full(&szMsg[sizeof("NACK=") - 1], 10, &vrc2); if (vrc == VINF_SUCCESS) { /* * Well formed NACK, transform it into an error. */ if (pszNAckMsg) { LogRel(("Teleporter: %s: NACK=%Rrc (%d)\n", pszWhich, vrc2, vrc2)); return setError(E_FAIL, pszNAckMsg); } if (pszMsgText) { pszMsgText = RTStrStrip(pszMsgText); for (size_t off = 0; pszMsgText[off]; off++) if (pszMsgText[off] == '\r') pszMsgText[off] = '\n'; LogRel(("Teleporter: %s: NACK=%Rrc (%d) - '%s'\n", pszWhich, vrc2, vrc2, pszMsgText)); if (strlen(pszMsgText) > 4) return setError(E_FAIL, "%s", pszMsgText); return setError(E_FAIL, "NACK(%s) - %Rrc (%d) '%s'", pszWhich, vrc2, vrc2, pszMsgText); } return setError(E_FAIL, "NACK(%s) - %Rrc (%d)", pszWhich, vrc2, vrc2); } if (pszMsgText) pszMsgText[-1] = ';'; } return setError(E_FAIL, tr("%s: Expected ACK or NACK, got '%s'"), pszWhich, szMsg); }
/** Print the CPU name, if available. */ static RTEXITCODE handlerCpuName(int argc, char **argv) { NOREF(argc); NOREF(argv); char szTmp[1024]; int rc = RTMpGetDescription(NIL_RTCPUID, szTmp, sizeof(szTmp)); if (RT_SUCCESS(rc)) { int cch = RTPrintf("%s\n", RTStrStrip(szTmp)); return cch > 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; } return RTEXITCODE_FAILURE; }
/** * Finds the svn binary, updating g_szSvnPath and g_enmSvnVersion. */ static void scmSvnFindSvnBinary(PSCMRWSTATE pState) { /* Already been called? */ if (g_szSvnPath[0] != '\0') return; /* * Locate it. */ /** @todo code page fun... */ #ifdef RT_OS_WINDOWS const char *pszEnvVar = RTEnvGet("Path"); #else const char *pszEnvVar = RTEnvGet("PATH"); #endif if (pszEnvVar) { #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) int rc = RTPathTraverseList(pszEnvVar, ';', scmSvnFindSvnBinaryCallback, g_szSvnPath, (void *)sizeof(g_szSvnPath)); #else int rc = RTPathTraverseList(pszEnvVar, ':', scmSvnFindSvnBinaryCallback, g_szSvnPath, (void *)sizeof(g_szSvnPath)); #endif if (RT_FAILURE(rc)) strcpy(g_szSvnPath, "svn"); } else strcpy(g_szSvnPath, "svn"); /* * Check the version. */ const char *apszArgs[] = { g_szSvnPath, "--version", "--quiet", NULL }; char *pszVersion; int rc = scmSvnRunAndGetOutput(pState, apszArgs, false, &pszVersion); if (RT_SUCCESS(rc)) { char *pszStripped = RTStrStrip(pszVersion); if (RTStrVersionCompare(pszVersion, "1.7") >= 0) g_enmSvnVersion = kScmSvnVersion_1_7; else if (RTStrVersionCompare(pszVersion, "1.6") >= 0) g_enmSvnVersion = kScmSvnVersion_1_6; else g_enmSvnVersion = kScmSvnVersion_Ancient; RTStrFree(pszVersion); } else g_enmSvnVersion = kScmSvnVersion_Ancient; }
/** * Init once for the path conversion code. * * @returns IPRT status code. * @param pvUser1 Unused. * @param pvUser2 Unused. */ static DECLCALLBACK(int32_t) rtPathConvInitOnce(void *pvUser) { /* * Read the environment variable, no mercy on misconfigs here except that * empty values are quietly ignored. (We use a temp buffer for stripping.) */ char *pszEnvValue = NULL; char szEnvValue[sizeof(g_szFsCodeset)]; int rc = RTEnvGetEx(RTENV_DEFAULT, RTPATH_CODESET_ENV_VAR, szEnvValue, sizeof(szEnvValue), NULL); if (rc != VERR_ENV_VAR_NOT_FOUND && RT_FAILURE(rc)) return rc; if (RT_SUCCESS(rc)) pszEnvValue = RTStrStrip(szEnvValue); if (pszEnvValue && *pszEnvValue) { g_fPassthruUtf8 = rtPathConvInitIsUtf8(pszEnvValue); g_enmFsToUtf8Idx = RTSTRICONV_FS_TO_UTF8; g_enmUtf8ToFsIdx = RTSTRICONV_UTF8_TO_FS; strcpy(g_szFsCodeset, pszEnvValue); } else { const char *pszCodeset = rtStrGetLocaleCodeset(); size_t cchCodeset = pszCodeset ? strlen(pszCodeset) : sizeof(g_szFsCodeset); if (cchCodeset >= sizeof(g_szFsCodeset)) /* This shouldn't happen, but we'll manage. */ g_szFsCodeset[0] = '\0'; else { memcpy(g_szFsCodeset, pszCodeset, cchCodeset + 1); pszCodeset = g_szFsCodeset; } g_fPassthruUtf8 = rtPathConvInitIsUtf8(pszCodeset); g_enmFsToUtf8Idx = RTSTRICONV_LOCALE_TO_UTF8; g_enmUtf8ToFsIdx = RTSTRICONV_UTF8_TO_LOCALE; } NOREF(pvUser); return VINF_SUCCESS; }
RTDECL(int) RTManifestReadStandardEx(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, char *pszErr, size_t cbErr) { /* * Validate input. */ AssertPtrNull(pszErr); if (pszErr && cbErr) *pszErr = '\0'; RTMANIFESTINT *pThis = hManifest; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTMANIFEST_MAGIC, VERR_INVALID_HANDLE); /* * Process the stream line by line. */ uint32_t iLine = 0; for (;;) { /* * Read a line from the input stream. */ iLine++; char szLine[RTPATH_MAX + RTSHA512_DIGEST_LEN + 32]; int rc = rtManifestReadLine(hVfsIos, szLine, sizeof(szLine)); if (RT_FAILURE(rc)) { if (rc == VERR_EOF) return VINF_SUCCESS; RTStrPrintf(pszErr, cbErr, "Error reading line #%u: %Rrc", iLine, rc); return rc; } if (rc != VINF_SUCCESS) { RTStrPrintf(pszErr, cbErr, "Line number %u is too long", iLine); return VERR_OUT_OF_RANGE; } /* * Strip it and skip if empty. */ char *psz = RTStrStrip(szLine); if (!*psz) continue; /* * Read the attribute name. */ const char * const pszAttr = psz; do psz++; while (!RT_C_IS_BLANK(*psz) && *psz); if (*psz) *psz++ = '\0'; /* * The entry name is enclosed in parenthesis and followed by a '='. */ psz = RTStrStripL(psz); if (*psz != '(') { RTStrPrintf(pszErr, cbErr, "Expected '(' after %zu on line %u", psz - szLine, iLine); return VERR_PARSE_ERROR; } const char * const pszName = ++psz; while (*psz) { if (*psz == ')') { char *psz2 = RTStrStripL(psz + 1); if (*psz2 == '=') { *psz = '\0'; psz = psz2; break; } } psz++; } if (*psz != '=') { RTStrPrintf(pszErr, cbErr, "Expected ')=' at %zu on line %u", psz - szLine, iLine); return VERR_PARSE_ERROR; } /* * The value. */ psz = RTStrStrip(psz + 1); const char * const pszValue = psz; if (!*psz) { RTStrPrintf(pszErr, cbErr, "Expected value at %zu on line %u", psz - szLine, iLine); return VERR_PARSE_ERROR; } /* * Detect attribute type and sanity check the value. */ uint32_t fType = RTMANIFEST_ATTR_UNKNOWN; static const struct { const char *pszAttr; uint32_t fType; unsigned cBits; unsigned uBase; } s_aDecAttrs[] = { { "SIZE", RTMANIFEST_ATTR_SIZE, 64, 10} }; for (unsigned i = 0; i < RT_ELEMENTS(s_aDecAttrs); i++) if (!strcmp(s_aDecAttrs[i].pszAttr, pszAttr)) { fType = s_aDecAttrs[i].fType; rc = RTStrToUInt64Full(pszValue, s_aDecAttrs[i].uBase, NULL); if (rc != VINF_SUCCESS) { RTStrPrintf(pszErr, cbErr, "Malformed value ('%s') at %zu on line %u: %Rrc", pszValue, psz - szLine, iLine, rc); return VERR_PARSE_ERROR; } break; } if (fType == RTMANIFEST_ATTR_UNKNOWN) { static const struct { const char *pszAttr; uint32_t fType; unsigned cchHex; } s_aHexAttrs[] = { { "MD5", RTMANIFEST_ATTR_MD5, RTMD5_DIGEST_LEN }, { "SHA1", RTMANIFEST_ATTR_SHA1, RTSHA1_DIGEST_LEN }, { "SHA256", RTMANIFEST_ATTR_SHA256, RTSHA256_DIGEST_LEN }, { "SHA512", RTMANIFEST_ATTR_SHA512, RTSHA512_DIGEST_LEN } }; for (unsigned i = 0; i < RT_ELEMENTS(s_aHexAttrs); i++) if (!strcmp(s_aHexAttrs[i].pszAttr, pszAttr)) { fType = s_aHexAttrs[i].fType; for (unsigned off = 0; off < s_aHexAttrs[i].cchHex; off++) if (!RT_C_IS_XDIGIT(pszValue[off])) { RTStrPrintf(pszErr, cbErr, "Expected hex digit at %zu on line %u (value '%s', pos %u)", pszValue - szLine + off, iLine, pszValue, off); return VERR_PARSE_ERROR; } break; } } /* * Finally, add it. */ rc = RTManifestEntrySetAttr(hManifest, pszName, pszAttr, pszValue, fType); if (RT_FAILURE(rc)) { RTStrPrintf(pszErr, cbErr, "RTManifestEntrySetAttr(,'%s','%s', '%s', %#x) failed on line %u: %Rrc", pszName, pszAttr, pszValue, fType, iLine, rc); return rc; } } }
/** * Generates a kind of report of the hardware, software and whatever else we * think might be useful to know about the testbox. */ static RTEXITCODE handlerReport(int argc, char **argv) { NOREF(argc); NOREF(argv); #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) /* * For now, a simple CPUID dump. Need to figure out how to share code * like this with other bits, putting it in IPRT. */ RTPrintf("CPUID Dump\n" "Leaf eax ebx ecx edx\n" "---------------------------------------------\n"); static uint32_t const s_auRanges[] = { UINT32_C(0x00000000), UINT32_C(0x80000000), UINT32_C(0x80860000), UINT32_C(0xc0000000), UINT32_C(0x40000000), }; for (uint32_t iRange = 0; iRange < RT_ELEMENTS(s_auRanges); iRange++) { uint32_t const uFirst = s_auRanges[iRange]; uint32_t uEax, uEbx, uEcx, uEdx; ASMCpuIdExSlow(uFirst, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx); if (uEax >= uFirst && uEax < uFirst + 100) { uint32_t const cLeafs = RT_MIN(uEax - uFirst + 1, 32); for (uint32_t iLeaf = 0; iLeaf < cLeafs; iLeaf++) { uint32_t uLeaf = uFirst + iLeaf; ASMCpuIdExSlow(uLeaf, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx); /* Clear APIC IDs to avoid submitting new reports all the time. */ if (uLeaf == 1) uEbx &= UINT32_C(0x00ffffff); if (uLeaf == 0xb) uEdx = 0; if (uLeaf == 0x8000001e) uEax = 0; /* Clear some other node/cpu/core/thread ids. */ if (uLeaf == 0x8000001e) { uEbx &= UINT32_C(0xffffff00); uEcx &= UINT32_C(0xffffff00); } RTPrintf("%08x: %08x %08x %08x %08x\n", uLeaf, uEax, uEbx, uEcx, uEdx); } } } RTPrintf("\n"); /* * DMI info. */ RTPrintf("DMI Info\n" "--------\n"); static const struct { const char *pszName; RTSYSDMISTR enmDmiStr; } s_aDmiStrings[] = { { "Product Name", RTSYSDMISTR_PRODUCT_NAME }, { "Product version", RTSYSDMISTR_PRODUCT_VERSION }, { "Product UUID", RTSYSDMISTR_PRODUCT_UUID }, { "Product Serial", RTSYSDMISTR_PRODUCT_SERIAL }, { "System Manufacturer", RTSYSDMISTR_MANUFACTURER }, }; for (uint32_t iDmiString = 0; iDmiString < RT_ELEMENTS(s_aDmiStrings); iDmiString++) { char szTmp[4096]; RT_ZERO(szTmp); int rc = RTSystemQueryDmiString(s_aDmiStrings[iDmiString].enmDmiStr, szTmp, sizeof(szTmp) - 1); if (RT_SUCCESS(rc)) RTPrintf("%25s: %s\n", s_aDmiStrings[iDmiString].pszName, RTStrStrip(szTmp)); else RTPrintf("%25s: %s [rc=%Rrc]\n", s_aDmiStrings[iDmiString].pszName, RTStrStrip(szTmp), rc); } RTPrintf("\n"); #else #endif /* * Dump the environment. */ RTPrintf("Environment\n" "-----------\n"); RTENV hEnv; int rc = RTEnvClone(&hEnv, RTENV_DEFAULT); if (RT_SUCCESS(rc)) { uint32_t cVars = RTEnvCountEx(hEnv); for (uint32_t iVar = 0; iVar < cVars; iVar++) { char szVar[1024]; char szValue[16384]; rc = RTEnvGetByIndexEx(hEnv, iVar, szVar, sizeof(szVar), szValue, sizeof(szValue)); /* zap the value of variables that are subject to change. */ if ( (RT_SUCCESS(rc) || rc == VERR_BUFFER_OVERFLOW) && ( !strcmp(szVar, "TESTBOX_SCRIPT_REV") || !strcmp(szVar, "TESTBOX_ID") || !strcmp(szVar, "TESTBOX_SCRATCH_SIZE") || !strcmp(szVar, "TESTBOX_TIMEOUT") || !strcmp(szVar, "TESTBOX_TIMEOUT_ABS") || !strcmp(szVar, "TESTBOX_TEST_SET_ID") ) ) strcpy(szValue, "<volatile>"); if (RT_SUCCESS(rc)) RTPrintf("%25s=%s\n", szVar, szValue); else if (rc == VERR_BUFFER_OVERFLOW) RTPrintf("%25s=%s [VERR_BUFFER_OVERFLOW]\n", szVar, szValue); else RTPrintf("rc=%Rrc\n", rc); } RTEnvDestroy(hEnv); } /** @todo enumerate volumes and whatnot. */ int cch = RTPrintf("\n"); return cch > 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; }
RTR3DECL(int) RTManifestVerifyFilesBuf(void *pvBuf, size_t cbSize, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed) { /* Validate input */ AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); AssertReturn(cbSize > 0, VERR_INVALID_PARAMETER); AssertPtrReturn(paTests, VERR_INVALID_POINTER); AssertReturn(cTests > 0, VERR_INVALID_PARAMETER); AssertPtrNullReturn(piFailed, VERR_INVALID_POINTER); int rc = VINF_SUCCESS; PRTMANIFESTFILEENTRY paFiles = (PRTMANIFESTFILEENTRY)RTMemTmpAllocZ(sizeof(RTMANIFESTFILEENTRY) * cTests); if (!paFiles) return VERR_NO_MEMORY; /* Fill our compare list */ for (size_t i = 0; i < cTests; ++i) paFiles[i].pTestPattern = &paTests[i]; char *pcBuf = (char*)pvBuf; size_t cbRead = 0; /* Parse the manifest file line by line */ for (;;) { if (cbRead >= cbSize) break; size_t cch = rtManifestIndexOfCharInBuf(pcBuf, cbSize - cbRead, '\n') + 1; /* Skip empty lines (UNIX/DOS format) */ if ( ( cch == 1 && pcBuf[0] == '\n') || ( cch == 2 && pcBuf[0] == '\r' && pcBuf[1] == '\n')) { pcBuf += cch; cbRead += cch; continue; } /** @todo r=bird: * -# Better deal with this EOF line platform dependency * -# The SHA1 and SHA256 tests should probably include a blank space check. * -# If there is a specific order to the elements in the string, it would be * good if the delimiter searching checked for it. * -# Deal with filenames containing delimiter characters. */ /* Check for the digest algorithm */ if ( cch < 4 || ( !( pcBuf[0] == 'S' && pcBuf[1] == 'H' && pcBuf[2] == 'A' && pcBuf[3] == '1') && !( pcBuf[0] == 'S' && pcBuf[1] == 'H' && pcBuf[2] == 'A' && pcBuf[3] == '2' && pcBuf[4] == '5' && pcBuf[5] == '6') ) ) { /* Digest unsupported */ rc = VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE; break; } /* Try to find the filename */ char *pszNameStart = rtManifestPosOfCharInBuf(pcBuf, cch, '('); if (!pszNameStart) { rc = VERR_MANIFEST_WRONG_FILE_FORMAT; break; } char *pszNameEnd = rtManifestPosOfCharInBuf(pcBuf, cch, ')'); if (!pszNameEnd) { rc = VERR_MANIFEST_WRONG_FILE_FORMAT; break; } /* Copy the filename part */ size_t cchName = pszNameEnd - pszNameStart - 1; char *pszName = (char *)RTMemTmpAlloc(cchName + 1); if (!pszName) { rc = VERR_NO_MEMORY; break; } memcpy(pszName, pszNameStart + 1, cchName); pszName[cchName] = '\0'; /* Try to find the digest sum */ char *pszDigestStart = rtManifestPosOfCharInBuf(pcBuf, cch, '=') + 1; if (!pszDigestStart) { RTMemTmpFree(pszName); rc = VERR_MANIFEST_WRONG_FILE_FORMAT; break; } char *pszDigestEnd = rtManifestPosOfCharInBuf(pcBuf, cch, '\r'); if (!pszDigestEnd) pszDigestEnd = rtManifestPosOfCharInBuf(pcBuf, cch, '\n'); if (!pszDigestEnd) { RTMemTmpFree(pszName); rc = VERR_MANIFEST_WRONG_FILE_FORMAT; break; } /* Copy the digest part */ size_t cchDigest = pszDigestEnd - pszDigestStart - 1; char *pszDigest = (char *)RTMemTmpAlloc(cchDigest + 1); if (!pszDigest) { RTMemTmpFree(pszName); rc = VERR_NO_MEMORY; break; } memcpy(pszDigest, pszDigestStart + 1, cchDigest); pszDigest[cchDigest] = '\0'; /* Check our file list against the extracted data */ bool fFound = false; for (size_t i = 0; i < cTests; ++i) { /** @todo r=bird: Using RTStrStr here looks bogus. */ if (RTStrStr(paFiles[i].pTestPattern->pszTestFile, RTStrStrip(pszName)) != NULL) { /* Add the data of the manifest file to the file list */ paFiles[i].pszManifestFile = RTStrDup(RTStrStrip(pszName)); paFiles[i].pszManifestDigest = RTStrDup(RTStrStrip(pszDigest)); fFound = true; break; } } RTMemTmpFree(pszName); RTMemTmpFree(pszDigest); if (!fFound) { /* There have to be an entry in the file list */ rc = VERR_MANIFEST_FILE_MISMATCH; break; } pcBuf += cch; cbRead += cch; } if ( rc == VINF_SUCCESS || rc == VERR_EOF) { rc = VINF_SUCCESS; for (size_t i = 0; i < cTests; ++i) { /* If there is an entry in the file list, which hasn't an * equivalent in the manifest file, its an error. */ if ( !paFiles[i].pszManifestFile || !paFiles[i].pszManifestDigest) { rc = VERR_MANIFEST_FILE_MISMATCH; break; } /* Do the manifest SHA digest match against the actual digest? */ if (RTStrICmp(paFiles[i].pszManifestDigest, paFiles[i].pTestPattern->pszTestDigest)) { if (piFailed) *piFailed = i; rc = VERR_MANIFEST_DIGEST_MISMATCH; break; } } } /* Cleanup */ for (size_t i = 0; i < cTests; ++i) { if (paFiles[i].pszManifestFile) RTStrFree(paFiles[i].pszManifestFile); if (paFiles[i].pszManifestDigest) RTStrFree(paFiles[i].pszManifestDigest); } RTMemTmpFree(paFiles); RTPrintf("rc = %Rrc\n", rc); return rc; }
static int scriptCommand(PVM pVM, const char *pszIn, size_t cch) { NOREF(cch); int rc = VINF_SUCCESS; char *psz = RTStrDup(pszIn); char *pszEqual = strchr(psz, '='); if (pszEqual) { /* * var = value */ *pszEqual = '\0'; RTStrStripR(psz); char *pszValue = RTStrStrip(pszEqual + 1); /* variables */ static struct { const char *pszVar; int (*pfnHandler)(PVM pVM, char *pszVar, char *pszValue, void *pvUser); PFNRT pvUser; } aVars[] = { { "eax", scriptGPReg, (PFNRT)CPUMSetGuestEAX }, { "ebx", scriptGPReg, (PFNRT)CPUMSetGuestEBX }, { "ecx", scriptGPReg, (PFNRT)CPUMSetGuestECX }, { "edx", scriptGPReg, (PFNRT)CPUMSetGuestEDX }, { "esp", scriptGPReg, (PFNRT)CPUMSetGuestESP }, { "ebp", scriptGPReg, (PFNRT)CPUMSetGuestEBP }, { "esi", scriptGPReg, (PFNRT)CPUMSetGuestESI }, { "edi", scriptGPReg, (PFNRT)CPUMSetGuestEDI }, { "efl", scriptGPReg, (PFNRT)CPUMSetGuestEFlags }, { "eip", scriptGPReg, (PFNRT)CPUMSetGuestEIP }, { "ss", scriptSelReg, (PFNRT)CPUMSetGuestSS }, { "cs", scriptSelReg, (PFNRT)CPUMSetGuestCS }, { "ds", scriptSelReg, (PFNRT)CPUMSetGuestDS }, { "es", scriptSelReg, (PFNRT)CPUMSetGuestES }, { "fs", scriptSelReg, (PFNRT)CPUMSetGuestFS }, { "gs", scriptSelReg, (PFNRT)CPUMSetGuestGS }, { "cr0", scriptSysReg, (PFNRT)CPUMSetGuestCR0 }, { "cr2", scriptSysReg, (PFNRT)CPUMSetGuestCR2 }, { "cr3", scriptSysReg, (PFNRT)CPUMSetGuestCR3 }, { "cr4", scriptSysReg, (PFNRT)CPUMSetGuestCR4 }, { "ldtr",scriptSelReg, (PFNRT)CPUMSetGuestLDTR }, { "tr", scriptSelReg, (PFNRT)CPUMSetGuestTR }, { "idtr",scriptDtrReg, (PFNRT)CPUMSetGuestIDTR }, { "gdtr",scriptDtrReg, (PFNRT)CPUMSetGuestGDTR } }; rc = -1; for (unsigned i = 0; i < RT_ELEMENTS(aVars); i++) { if (!strcmp(psz, aVars[i].pszVar)) { rc = aVars[i].pfnHandler(pVM, psz, pszValue, (void*)(uintptr_t)aVars[i].pvUser); break; } } } RTStrFree(psz); return rc; }