/** * Handles the osdmsg sub-command. * * @returns Suitable exit code. * @param pArgs The handler arguments. * @param pDebugger Pointer to the debugger interface. */ static RTEXITCODE handleDebugVM_OSDmesg(HandlerArg *pArgs, IMachineDebugger *pDebugger) { /* * Parse argument. */ uint32_t uMaxMessages = 0; RTGETOPTSTATE GetState; RTGETOPTUNION ValueUnion; static const RTGETOPTDEF s_aOptions[] = { { "--lines", 'n', RTGETOPT_REQ_UINT32 }, }; int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST); AssertRCReturn(rc, RTEXITCODE_FAILURE); while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0) switch (rc) { case 'n': uMaxMessages = ValueUnion.u32; break; default: return errorGetOpt(rc, &ValueUnion); } /* * Do it. */ com::Bstr bstrDmesg; CHECK_ERROR2I_RET(pDebugger, QueryOSKernelLog(uMaxMessages, bstrDmesg.asOutParam()), RTEXITCODE_FAILURE); RTPrintf("%ls\n", bstrDmesg.raw()); return RTEXITCODE_SUCCESS; }
/** * Handle the 'delete' action. * * @returns 0 or 1. * @param argc The action argument count. * @param argv The action argument vector. */ static int supSvcWinDelete(int argc, char **argv) { /* * Parse the arguments. */ bool fVerbose = false; static const RTGETOPTDEF s_aOptions[] = { { "--verbose", 'v', RTGETOPT_REQ_NOTHING } }; int ch; RTGETOPTUNION Value; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((ch = RTGetOpt(&GetState, &Value))) switch (ch) { case 'v': fVerbose = true; break; case VINF_GETOPT_NOT_OPTION: return supSvcDisplayTooManyArgsError("delete", argc, argv, iArg); default: return supSvcDisplayGetOptError("delete", ch, argc, argv, iArg, &Value); } /* * Create the service. */ int rc = 1; SC_HANDLE hSvc = supSvcWinOpenService("delete", SERVICE_CHANGE_CONFIG, DELETE, 1, ERROR_SERVICE_DOES_NOT_EXIST); if (hSvc) { if (DeleteService(hSvc)) { RTPrintf("Successfully deleted the %s service.\n", SUPSVC_SERVICE_NAME); rc = 0; } else supSvcDisplayError("delete - DeleteService failed, err=%d.\n", GetLastError()); CloseServiceHandle(hSvc); } else if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { if (fVerbose) RTPrintf("The service %s was not installed, nothing to be done.", SUPSVC_SERVICE_NAME); else RTPrintf("Successfully deleted the %s service.\n", SUPSVC_SERVICE_NAME); rc = 0; } return rc; }
/** * Handles the inject sub-command. * * @returns Suitable exit code. * @param pArgs The handler arguments. * @param pDebugger Pointer to the debugger interface. */ static RTEXITCODE handleDebugVM_DumpVMCore(HandlerArg *pArgs, IMachineDebugger *pDebugger) { /* * Parse arguments. */ const char *pszFilename = NULL; const char *pszCompression = NULL; RTGETOPTSTATE GetState; RTGETOPTUNION ValueUnion; static const RTGETOPTDEF s_aOptions[] = { { "--filename", 'f', RTGETOPT_REQ_STRING }, { "--compression", 'c', RTGETOPT_REQ_STRING } }; int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/); AssertRCReturn(rc, RTEXITCODE_FAILURE); while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0) { switch (rc) { case 'c': if (pszCompression) return errorSyntax("The --compression option has already been given"); pszCompression = ValueUnion.psz; break; case 'f': if (pszFilename) return errorSyntax("The --filename option has already been given"); pszFilename = ValueUnion.psz; break; default: return errorGetOpt(rc, &ValueUnion); } } if (!pszFilename) return errorSyntax("The --filename option is required"); /* * Make the filename absolute before handing it on to the API. */ char szAbsFilename[RTPATH_MAX]; rc = RTPathAbs(pszFilename, szAbsFilename, sizeof(szAbsFilename)); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAbs failed on '%s': %Rrc", pszFilename, rc); com::Bstr bstrFilename(szAbsFilename); com::Bstr bstrCompression(pszCompression); CHECK_ERROR2I_RET(pDebugger, DumpGuestCore(bstrFilename.raw(), bstrCompression.raw()), RTEXITCODE_FAILURE); return RTEXITCODE_SUCCESS; }
int main(int argc, char *argv[]) { /* * Init IPRT and globals. */ int rc = RTTestInitAndCreate("UsbTest", &g_hTest); if (rc) return rc; /* * Default values. */ const char *pszDevice = NULL; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aCmdOptions, RT_ELEMENTS(g_aCmdOptions), 1, 0 /* fFlags */); while ((rc = RTGetOpt(&GetState, &ValueUnion))) { switch (rc) { case 'h': usbTestUsage(g_pStdOut); return RTEXITCODE_SUCCESS; case 'd': pszDevice = ValueUnion.psz; break; default: return RTGetOptPrintError(rc, &ValueUnion); } } /* * Start testing. */ RTTestBanner(g_hTest); /* Find the first test device if none was given. */ if (!pszDevice) pszDevice = usbTestFindDevice(); if (pszDevice) usbTestExec(pszDevice); else { RTTestPrintf(g_hTest, RTTESTLVL_FAILURE, "Failed to find a test device\n"); RTTestErrorInc(g_hTest); } RTEXITCODE rcExit = RTTestSummaryAndDestroy(g_hTest); return rcExit; }
int main(int argc, char **argv) { int rc = RTTestInitAndCreate("tstIntNetR0", &g_hTest); if (rc) return rc; /* * Parse the arguments. */ static RTGETOPTDEF const s_aOptions[] = { { "--recv-buffer", 'r', RTGETOPT_REQ_UINT32 }, { "--send-buffer", 's', RTGETOPT_REQ_UINT32 }, { "--transfer-size", 'l', RTGETOPT_REQ_UINT32 }, }; uint32_t cbSend = 1536*2 + 4; uint32_t cbRecv = 0x8000; int ch; RTGETOPTUNION Value; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((ch = RTGetOpt(&GetState, &Value))) switch (ch) { case 'l': g_cbTransfer = Value.u32; break; case 'r': cbRecv = Value.u32; break; case 's': cbSend = Value.u32; break; default: return RTGetOptPrintError(ch, &Value); } /* * Do the testing and report summary. */ TSTSTATE This; RT_ZERO(This); doTest(&This, cbRecv, cbSend); return RTTestSummaryAndDestroy(g_hTest); }
/** * Handles the info sub-command. * * @returns Suitable exit code. * @param pArgs The handler arguments. * @param pDebugger Pointer to the debugger interface. */ static RTEXITCODE handleDebugVM_Info(HandlerArg *pArgs, IMachineDebugger *pDebugger) { /* * Parse arguments. */ const char *pszInfo = NULL; const char *pszArgs = NULL; RTGETOPTSTATE GetState; RTGETOPTUNION ValueUnion; int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, NULL, 0, 2, RTGETOPTINIT_FLAGS_OPTS_FIRST); AssertRCReturn(rc, RTEXITCODE_FAILURE); while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0) { switch (rc) { case VINF_GETOPT_NOT_OPTION: if (!pszInfo) pszInfo = ValueUnion.psz; else if (!pszArgs) pszArgs = ValueUnion.psz; else return errorTooManyParameters(&pArgs->argv[GetState.iNext - 1]); break; default: return errorGetOpt(rc, &ValueUnion); } } if (!pszInfo) return errorSyntax("Must specify info item to display"); /* * Do the work. */ com::Bstr bstrName(pszInfo); com::Bstr bstrArgs(pszArgs); com::Bstr bstrInfo; CHECK_ERROR2I_RET(pDebugger, Info(bstrName.raw(), bstrArgs.raw(), bstrInfo.asOutParam()), RTEXITCODE_FAILURE); RTPrintf("%ls", bstrInfo.raw()); return RTEXITCODE_SUCCESS; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Create a HTTP client instance. */ RTHTTP hHttp; rc = RTHttpCreate(&hHttp); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTHttpCreate failed: %Rrc", rc); /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--output", 'o', RTGETOPT_REQ_STRING }, { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, }; RTEXITCODE rcExit = RTEXITCODE_SUCCESS; const char *pszOutput = NULL; unsigned uVerbosityLevel = 1; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); while ((rc = RTGetOpt(&GetState, &ValueUnion))) { switch (rc) { case 'o': pszOutput = ValueUnion.psz; break; case 'q': uVerbosityLevel--; break; case 'v': uVerbosityLevel++; break; case 'h': RTPrintf("Usage: %s [options] URL0 [URL1 [...]]\n" "\n" "Options:\n" " -o,--output=file\n" " Output file. If not given, the file is displayed on stdout.\n" " -q, --quiet\n" " -v, --verbose\n" " Controls the verbosity level.\n" " -h, -?, --help\n" " Display this help text and exit successfully.\n" " -V, --version\n" " Display the revision and exit successfully.\n" , RTPathFilename(argv[0])); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("$Revision: 102641 $\n"); return RTEXITCODE_SUCCESS; case VINF_GETOPT_NOT_OPTION: { int rcHttp; if (pszOutput && strcmp("-", pszOutput)) { if (uVerbosityLevel > 0) RTStrmPrintf(g_pStdErr, "Fetching '%s' into '%s'...\n", ValueUnion.psz, pszOutput); rcHttp = RTHttpGetFile(hHttp, ValueUnion.psz, pszOutput); } else { if (uVerbosityLevel > 0) RTStrmPrintf(g_pStdErr, "Fetching '%s'...\n", ValueUnion.psz); void *pvResp; size_t cbResp; rcHttp = RTHttpGetBinary(hHttp, ValueUnion.psz, &pvResp, &cbResp); if (RT_SUCCESS(rcHttp)) { RTVFSIOSTREAM hVfsIos; rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, 0, true /*fLeaveOpen*/, &hVfsIos); if (RT_SUCCESS(rc)) { rc = RTVfsIoStrmWrite(hVfsIos, pvResp, cbResp, true /*fBlocking*/, NULL); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error writing to stdout: %Rrc", rc); RTVfsIoStrmRelease(hVfsIos); } else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening stdout: %Rrc", rc); RTHttpFreeResponse(pvResp); } } if (RT_FAILURE(rcHttp)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Error %Rrc getting '%s'", rcHttp, ValueUnion.psz); break; } default: return RTGetOptPrintError(rc, &ValueUnion); } } return rcExit; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Create an empty address space that we can load modules and stuff into * as we parse the parameters. */ RTDBGAS hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTUINTPTR_MAX, ""); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDBgAsCreate -> %Rrc", rc); /* * Create a debugging configuration instance to work with so that we can * make use of (i.e. test) path searching and such. */ RTDBGCFG hDbgCfg; rc = RTDbgCfgCreate(&hDbgCfg, "IPRT", true /*fNativePaths*/); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgCfgCreate -> %Rrc", rc); /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--input", 'i', RTGETOPT_REQ_STRING }, { "--local-file", 'l', RTGETOPT_REQ_NOTHING }, { "--cache-file", 'c', RTGETOPT_REQ_NOTHING }, { "--pe-image", 'p', RTGETOPT_REQ_NOTHING }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, { "--x86", '8', RTGETOPT_REQ_NOTHING }, { "--amd64", '6', RTGETOPT_REQ_NOTHING }, { "--whatever", '*', RTGETOPT_REQ_NOTHING }, }; PRTSTREAM pInput = g_pStdIn; PRTSTREAM pOutput = g_pStdOut; unsigned cVerbosityLevel = 0; enum { kOpenMethod_FromImage, kOpenMethod_FromPeImage } enmOpenMethod = kOpenMethod_FromImage; bool fCacheFile = false; RTLDRARCH enmArch = RTLDRARCH_WHATEVER; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((rc = RTGetOpt(&GetState, &ValueUnion))) { switch (rc) { case 'i': rc = RTStrmOpen(ValueUnion.psz, "r", &pInput); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open '%s' for reading: %Rrc", ValueUnion.psz, rc); break; case 'c': fCacheFile = true; break; case 'l': fCacheFile = false; break; case 'p': enmOpenMethod = kOpenMethod_FromPeImage; break; case 'v': cVerbosityLevel++; break; case '8': enmArch = RTLDRARCH_X86_32; break; case '6': enmArch = RTLDRARCH_AMD64; break; case '*': enmArch = RTLDRARCH_WHATEVER; break; case 'h': RTPrintf("Usage: %s [options] <module> <address> [<module> <address> [..]]\n" "\n" "Options:\n" " -i,--input=file\n" " Specify a input file instead of standard input.\n" " --pe-image\n" " Use RTDbgModCreateFromPeImage to open the file." " -v, --verbose\n" " Display the address space before doing the filtering.\n" " --amd64,--x86,--whatever\n" " Selects the desired architecture.\n" " -h, -?, --help\n" " Display this help text and exit successfully.\n" " -V, --version\n" " Display the revision and exit successfully.\n" , RTPathFilename(argv[0])); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("$Revision$\n"); return RTEXITCODE_SUCCESS; case VINF_GETOPT_NOT_OPTION: { /* <module> <address> */ const char *pszModule = ValueUnion.psz; rc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX); if (RT_FAILURE(rc)) return RTGetOptPrintError(rc, &ValueUnion); uint64_t u64Address = ValueUnion.u64; uint32_t cbImage = 0; uint32_t uTimestamp = 0; if (fCacheFile) { rc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX); if (RT_FAILURE(rc)) return RTGetOptPrintError(rc, &ValueUnion); cbImage = ValueUnion.u32; rc = RTGetOptFetchValue(&GetState, &ValueUnion, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX); if (RT_FAILURE(rc)) return RTGetOptPrintError(rc, &ValueUnion); uTimestamp = ValueUnion.u32; } RTDBGMOD hMod; if (enmOpenMethod == kOpenMethod_FromImage) rc = RTDbgModCreateFromImage(&hMod, pszModule, NULL, enmArch, hDbgCfg); else rc = RTDbgModCreateFromPeImage(&hMod, pszModule, NULL, NIL_RTLDRMOD, cbImage, uTimestamp, hDbgCfg); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgModCreateFromImage(,%s,,) -> %Rrc", pszModule, rc); rc = RTDbgAsModuleLink(hDbgAs, hMod, u64Address, 0 /* fFlags */); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgAsModuleLink(,%s,%llx,) -> %Rrc", pszModule, u64Address, rc); break; } default: return RTGetOptPrintError(rc, &ValueUnion); } } /* * Display the address space. */ if (cVerbosityLevel) { RTPrintf("*** Address Space Dump ***\n"); uint32_t cModules = RTDbgAsModuleCount(hDbgAs); for (uint32_t iModule = 0; iModule < cModules; iModule++) { RTDBGMOD hDbgMod = RTDbgAsModuleByIndex(hDbgAs, iModule); RTPrintf("Module #%u: %s\n", iModule, RTDbgModName(hDbgMod)); RTDBGASMAPINFO aMappings[128]; uint32_t cMappings = RT_ELEMENTS(aMappings); rc = RTDbgAsModuleQueryMapByIndex(hDbgAs, iModule, &aMappings[0], &cMappings, 0 /*fFlags*/); if (RT_SUCCESS(rc)) { for (uint32_t iMapping = 0; iMapping < cMappings; iMapping++) { if (aMappings[iMapping].iSeg == NIL_RTDBGSEGIDX) RTPrintf(" mapping #%u: %RTptr-%RTptr\n", iMapping, aMappings[iMapping].Address, aMappings[iMapping].Address + RTDbgModImageSize(hDbgMod) - 1); else { RTDBGSEGMENT SegInfo; rc = RTDbgModSegmentByIndex(hDbgMod, aMappings[iMapping].iSeg, &SegInfo); if (RT_SUCCESS(rc)) RTPrintf(" mapping #%u: %RTptr-%RTptr (segment #%u - '%s')", iMapping, aMappings[iMapping].Address, aMappings[iMapping].Address + SegInfo.cb, SegInfo.iSeg, SegInfo.szName); else RTPrintf(" mapping #%u: %RTptr-???????? (segment #%u)", iMapping, aMappings[iMapping].Address); } if (cVerbosityLevel > 1) { uint32_t cSymbols = RTDbgModSymbolCount(hDbgMod); RTPrintf(" %u symbols\n", cSymbols); for (uint32_t iSymbol = 0; iSymbol < cSymbols; iSymbol++) { RTDBGSYMBOL SymInfo; rc = RTDbgModSymbolByOrdinal(hDbgMod, iSymbol, &SymInfo); if (RT_SUCCESS(rc)) RTPrintf(" #%04u at %08x:%RTptr %05llx %s\n", SymInfo.iOrdinal, SymInfo.iSeg, SymInfo.offSeg, (uint64_t)SymInfo.cb, SymInfo.szName); } } } } else RTMsgError("RTDbgAsModuleQueryMapByIndex failed: %Rrc", rc); RTDbgModRelease(hDbgMod); } RTPrintf("*** End of Address Space Dump ***\n"); } /* * Read text from standard input and see if there is anything we can translate. */ for (;;) { /* Get a line. */ char szLine[_64K]; rc = RTStrmGetLine(pInput, szLine, sizeof(szLine)); if (rc == VERR_EOF) break; if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrmGetLine() -> %Rrc\n", rc); /* * Search the line for potential addresses and replace them with * symbols+offset. */ const char *pszStart = szLine; const char *psz = szLine; char ch; while ((ch = *psz) != '\0') { size_t cchAddress; uint64_t u64Address; if ( ( ch == '0' && (psz[1] == 'x' || psz[1] == 'X') && TryParseAddress(psz, &cchAddress, &u64Address)) || ( RT_C_IS_XDIGIT(ch) && TryParseAddress(psz, &cchAddress, &u64Address)) ) { /* Print. */ psz += cchAddress; if (pszStart != psz) RTStrmWrite(pOutput, pszStart, psz - pszStart); pszStart = psz; /* Try get the module. */ RTUINTPTR uAddr; RTDBGSEGIDX iSeg; RTDBGMOD hDbgMod; rc = RTDbgAsModuleByAddr(hDbgAs, u64Address, &hDbgMod, &uAddr, &iSeg); if (RT_SUCCESS(rc)) { if (iSeg != UINT32_MAX) RTStrmPrintf(pOutput, "=[%s:%u", RTDbgModName(hDbgMod), iSeg); else RTStrmPrintf(pOutput, "=[%s", RTDbgModName(hDbgMod), iSeg); /* * Do we have symbols? */ RTDBGSYMBOL Symbol; RTINTPTR offSym; rc = RTDbgAsSymbolByAddr(hDbgAs, u64Address, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, &offSym, &Symbol, NULL); if (RT_SUCCESS(rc)) { if (!offSym) RTStrmPrintf(pOutput, "!%s", Symbol.szName); else if (offSym > 0) RTStrmPrintf(pOutput, "!%s+%#llx", Symbol.szName, offSym); else RTStrmPrintf(pOutput, "!%s-%#llx", Symbol.szName, -offSym); } else RTStrmPrintf(pOutput, "+%#llx", u64Address - uAddr); /* * Do we have line numbers? */ RTDBGLINE Line; RTINTPTR offLine; rc = RTDbgAsLineByAddr(hDbgAs, u64Address, &offLine, &Line, NULL); if (RT_SUCCESS(rc)) RTStrmPrintf(pOutput, " %Rbn(%u)", Line.szFilename, Line.uLineNo); RTStrmPrintf(pOutput, "]"); RTDbgModRelease(hDbgMod); } } else psz++; } if (pszStart != psz) RTStrmWrite(pOutput, pszStart, psz - pszStart); RTStrmPutCh(pOutput, '\n'); } return RTEXITCODE_SUCCESS; }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); enum { kDigestType_NotSpecified, kDigestType_CRC32, kDigestType_CRC64, kDigestType_MD5, kDigestType_SHA1, kDigestType_SHA256, kDigestType_SHA512 } enmDigestType = kDigestType_NotSpecified; enum { kMethod_Full, kMethod_Block, kMethod_File } enmMethod = kMethod_Block; static const RTGETOPTDEF s_aOptions[] = { { "--type", 't', RTGETOPT_REQ_STRING }, { "--method", 'm', RTGETOPT_REQ_STRING }, { "--help", 'h', RTGETOPT_REQ_NOTHING }, }; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 't': if (!RTStrICmp(ValueUnion.psz, "crc32")) enmDigestType = kDigestType_CRC32; else if (!RTStrICmp(ValueUnion.psz, "crc64")) enmDigestType = kDigestType_CRC64; else if (!RTStrICmp(ValueUnion.psz, "md5")) enmDigestType = kDigestType_MD5; else if (!RTStrICmp(ValueUnion.psz, "sha1")) enmDigestType = kDigestType_SHA1; else if (!RTStrICmp(ValueUnion.psz, "sha256")) enmDigestType = kDigestType_SHA256; else if (!RTStrICmp(ValueUnion.psz, "sha512")) enmDigestType = kDigestType_SHA512; 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 { Error("Invalid digest method: %s\n", ValueUnion.psz); return 1; } break; case 'h': RTPrintf("syntax: tstRTDigest -t <digest-type> file [file2 [..]]\n"); return 1; case VINF_GETOPT_NOT_OPTION: { if (enmDigestType == kDigestType_NotSpecified) 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: switch (enmDigestType) { case kDigestType_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 kDigestType_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); size_t cbRead; uint8_t abBuf[_64K]; char *pszDigest = (char *)&abBuf[0]; switch (enmDigestType) { case kDigestType_CRC32: { uint32_t uCRC32 = RTCrc32Start(); for (;;) { rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead); if (RT_FAILURE(rc) || !cbRead) break; uCRC32 = RTCrc32Process(uCRC32, abBuf, cbRead); } uCRC32 = RTCrc32Finish(uCRC32); RTStrPrintf(pszDigest, sizeof(abBuf), "%08RX32", uCRC32); break; } case kDigestType_CRC64: { uint64_t uCRC64 = RTCrc64Start(); for (;;) { rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead); if (RT_FAILURE(rc) || !cbRead) break; uCRC64 = RTCrc64Process(uCRC64, abBuf, cbRead); } uCRC64 = RTCrc64Finish(uCRC64); RTStrPrintf(pszDigest, sizeof(abBuf), "%016RX64", uCRC64); break; } case kDigestType_MD5: { RTMD5CONTEXT Ctx; RTMd5Init(&Ctx); for (;;) { rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead); if (RT_FAILURE(rc) || !cbRead) break; RTMd5Update(&Ctx, abBuf, cbRead); } uint8_t abDigest[RTMD5HASHSIZE]; RTMd5Final(abDigest, &Ctx); RTMd5ToString(abDigest, pszDigest, sizeof(abBuf)); break; } case kDigestType_SHA1: { RTSHA1CONTEXT Ctx; RTSha1Init(&Ctx); for (;;) { rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead); 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 kDigestType_SHA256: { RTSHA256CONTEXT Ctx; RTSha256Init(&Ctx); for (;;) { rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead); 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 kDigestType_SHA512: { RTSHA512CONTEXT Ctx; RTSha512Init(&Ctx); for (;;) { rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead); 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); } RTPrintf("%s %s\n", pszDigest, ValueUnion.psz); break; } default: return Error("Internal error #2\n"); } break; } default: return RTGetOptPrintError(ch, &ValueUnion); } } return 0; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Parse arguments up to the command and pass it on to the command handlers. */ typedef enum { VCUACTION_ADD_TRUSTED_PUBLISHER = 1000, VCUACTION_REMOVE_TRUSTED_PUBLISHER, VCUACTION_DISPLAY_ALL, VCUACTION_END } VCUACTION; static const RTGETOPTDEF s_aOptions[] = { { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, { "add-trusted-publisher", VCUACTION_ADD_TRUSTED_PUBLISHER, RTGETOPT_REQ_NOTHING }, { "remove-trusted-publisher", VCUACTION_REMOVE_TRUSTED_PUBLISHER, RTGETOPT_REQ_NOTHING }, { "display-all", VCUACTION_DISPLAY_ALL, RTGETOPT_REQ_NOTHING }, }; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((rc = RTGetOpt(&GetState, &ValueUnion))) { switch (rc) { case 'v': g_cVerbosityLevel++; break; case 'q': if (g_cVerbosityLevel > 0) g_cVerbosityLevel--; break; case 'h': showUsage(argv[0]); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); return RTEXITCODE_SUCCESS; case VCUACTION_ADD_TRUSTED_PUBLISHER: return cmdAddTrustedPublisher(argc - GetState.iNext + 1, argv + GetState.iNext - 1); case VCUACTION_REMOVE_TRUSTED_PUBLISHER: return cmdRemoveTrustedPublisher(argc - GetState.iNext + 1, argv + GetState.iNext - 1); case VCUACTION_DISPLAY_ALL: return cmdDisplayAll(argc - GetState.iNext + 1, argv + GetState.iNext - 1); default: return RTGetOptPrintError(rc, &ValueUnion); } } RTMsgError("Missing command..."); showUsage(argv[0]); return RTEXITCODE_SYNTAX; }
int main() { RTTEST hTest; int rc = RTTestInitAndCreate("tstRTGetOpt", &hTest); if (rc) return rc; RTGETOPTSTATE GetState; RTGETOPTUNION Val; #define CHECK(expr) do { if (!(expr)) { RTTestIFailed("error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); } } while (0) #define CHECK2(expr, fmt) \ do { \ if (!(expr)) { \ RTTestIFailed("error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); \ RTTestIFailureDetails fmt; \ } \ } while (0) #define CHECK_pDef(paOpts, i) \ CHECK2(Val.pDef == &(paOpts)[(i)], ("Got #%d (%p) expected #%d\n", (int)(Val.pDef - &(paOpts)[0]), Val.pDef, i)); #define CHECK_GETOPT(expr, chRet, iInc) \ do { \ const int iPrev = GetState.iNext; \ const int rcGetOpt = (expr); \ CHECK2(rcGetOpt == (chRet), ("got %d, expected %d\n", rcGetOpt, (chRet))); \ CHECK2(GetState.iNext == (iInc) + iPrev, ("iNext=%d expected %d\n", GetState.iNext, (iInc) + iPrev)); \ GetState.iNext = (iInc) + iPrev; \ } while (0) #define CHECK_GETOPT_STR(expr, chRet, iInc, str) \ do { \ const int iPrev = GetState.iNext; \ const int rcGetOpt = (expr); \ CHECK2(rcGetOpt == (chRet), ("got %d, expected %d\n", rcGetOpt, (chRet))); \ CHECK2(GetState.iNext == (iInc) + iPrev, ("iNext=%d expected %d\n", GetState.iNext, (iInc) + iPrev)); \ CHECK2(VALID_PTR(Val.psz) && !strcmp(Val.psz, (str)), ("got %s, expected %s\n", Val.psz, (str))); \ GetState.iNext = (iInc) + iPrev; \ } while (0) /* * The basics. */ RTTestSub(hTest, "Basics"); static const RTGETOPTDEF s_aOpts2[] = { { "--optwithstring", 's', RTGETOPT_REQ_STRING }, { "--optwithint", 'i', RTGETOPT_REQ_INT32 }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, { NULL, 'q', RTGETOPT_REQ_NOTHING }, { "--quiet", 384, RTGETOPT_REQ_NOTHING }, { "-novalue", 385, RTGETOPT_REQ_NOTHING }, { "-startvm", 386, RTGETOPT_REQ_STRING }, { "nodash", 387, RTGETOPT_REQ_NOTHING }, { "nodashval", 388, RTGETOPT_REQ_STRING }, { "--gateway", 'g', RTGETOPT_REQ_IPV4ADDR }, { "--mac", 'm', RTGETOPT_REQ_MACADDR }, { "--strindex", 400, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX }, { "strindex", 400, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX }, { "--intindex", 401, RTGETOPT_REQ_INT32 | RTGETOPT_FLAG_INDEX }, { "--macindex", 402, RTGETOPT_REQ_MACADDR | RTGETOPT_FLAG_INDEX }, { "--indexnovalue", 403, RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_INDEX }, { "--macindexnegative", 404, RTGETOPT_REQ_NOTHING }, { "--twovalues", 405, RTGETOPT_REQ_STRING }, { "--twovaluesindex", 406, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX }, { "--threevalues", 407, RTGETOPT_REQ_UINT32 }, { "--boolean", 408, RTGETOPT_REQ_BOOL_ONOFF }, { "--booleanindex", 409, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX }, }; const char *argv2[] = { "-s", "string1", "-sstring2", "-s:string3", "-s=string4", "-s:", "-s=", "--optwithstring", "string5", "--optwithstring:string6", "--optwithstring=string7", "--optwithstring:", "--optwithstring=", "-i", "-42", "-i:-42", "-i=-42", "--optwithint", "42", "--optwithint:42", "--optwithint=42", "-v", "--verbose", "-q", "--quiet", "-novalue", "-startvm", "myvm", "nodash", "nodashval", "string9", "filename1", "-q", "filename2", "-vqi999", "-g192.168.1.1", "-m08:0:27:00:ab:f3", "--mac:1:::::c", "--strindex786", "string10", "--strindex786:string11", "--strindex786=string12", "strindex687", "string13", "strindex687:string14", "strindex687=string15", "strindex688:", "strindex689=", "--intindex137", "1000", "--macindex138", "08:0:27:00:ab:f3", "--indexnovalue1", "--macindexnegative", "--twovalues", "firstvalue", "secondvalue", "--twovalues:firstvalue", "secondvalue", "--twovaluesindex4", "1", "0xA", "--twovaluesindex5=2", "0xB", "--threevalues", "1", "0xC", "thirdvalue", /* bool on/off */ "--boolean", "on", "--boolean", "off", "--boolean", "invalid", "--booleanindex2", "on", "--booleanindex7", "off", "--booleanindex9", "invalid", /* standard options */ "--help", "-help", "-?", "-h", "--version", "-version", "-V", /* done */ NULL }; int argc2 = (int)RT_ELEMENTS(argv2) - 1; CHECK(RT_SUCCESS(RTGetOptInit(&GetState, argc2, (char **)argv2, &s_aOpts2[0], RT_ELEMENTS(s_aOpts2), 0, 0 /* fFlags */))); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 2); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string1")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string2")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string3")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string4")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 2); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string5")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string6")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string7")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "")); CHECK(GetState.uIndex == UINT32_MAX); /* -i */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); /* --optwithint */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); CHECK(Val.i32 == 42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == 42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == 42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'v', 1); CHECK_pDef(s_aOpts2, 2); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'v', 1); CHECK_pDef(s_aOpts2, 2); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 1); CHECK_pDef(s_aOpts2, 3); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 384, 1); CHECK_pDef(s_aOpts2, 4); /* -novalue / -startvm (single dash long options) */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 385, 1); CHECK_pDef(s_aOpts2, 5); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 386, 2); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "myvm")); /* no-dash options */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 387, 1); CHECK_pDef(s_aOpts2, 7); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 388, 2); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string9")); /* non-option, option, non-option */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1); CHECK(Val.psz && !strcmp(Val.psz, "filename1")); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 1); CHECK_pDef(s_aOpts2, 3); CHECK_GETOPT(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1); CHECK(Val.psz && !strcmp(Val.psz, "filename2")); /* compress short options */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'v', 0); CHECK_pDef(s_aOpts2, 2); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 0); CHECK_pDef(s_aOpts2, 3); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == 999); /* IPv4 */ RTTestSub(hTest, "RTGetOpt - IPv4"); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'g', 1); CHECK(Val.IPv4Addr.u == RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8(192,168,1,1)))); /* Ethernet MAC address. */ RTTestSub(hTest, "RTGetOpt - MAC Address"); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'm', 1); CHECK( Val.MacAddr.au8[0] == 0x08 && Val.MacAddr.au8[1] == 0x00 && Val.MacAddr.au8[2] == 0x27 && Val.MacAddr.au8[3] == 0x00 && Val.MacAddr.au8[4] == 0xab && Val.MacAddr.au8[5] == 0xf3); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'm', 1); CHECK( Val.MacAddr.au8[0] == 0x01 && Val.MacAddr.au8[1] == 0x00 && Val.MacAddr.au8[2] == 0x00 && Val.MacAddr.au8[3] == 0x00 && Val.MacAddr.au8[4] == 0x00 && Val.MacAddr.au8[5] == 0x0c); /* string with indexed argument */ RTTestSub(hTest, "RTGetOpt - Option w/ Index"); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 2); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string10")); CHECK(GetState.uIndex == 786); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string11")); CHECK(GetState.uIndex == 786); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string12")); CHECK(GetState.uIndex == 786); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 2); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string13")); CHECK(GetState.uIndex == 687); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string14")); CHECK(GetState.uIndex == 687); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string15")); CHECK(GetState.uIndex == 687); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "")); CHECK(GetState.uIndex == 688); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "")); CHECK(GetState.uIndex == 689); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 401, 2); CHECK(Val.i32 == 1000); CHECK(GetState.uIndex == 137); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 402, 2); CHECK( Val.MacAddr.au8[0] == 0x08 && Val.MacAddr.au8[1] == 0x00 && Val.MacAddr.au8[2] == 0x27 && Val.MacAddr.au8[3] == 0x00 && Val.MacAddr.au8[4] == 0xab && Val.MacAddr.au8[5] == 0xf3); CHECK(GetState.uIndex == 138); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 403, 1); CHECK(GetState.uIndex == 1); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 404, 1); CHECK(GetState.uIndex == UINT32_MAX); /* RTGetOptFetchValue tests */ RTTestSub(hTest, "RTGetOptFetchValue"); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 405, 2); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "firstvalue")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "secondvalue")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 405, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "firstvalue")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "secondvalue")); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 406, 2); CHECK(Val.u32 == 1); CHECK(GetState.uIndex == 4); CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_UINT32), VINF_SUCCESS, 1); CHECK(Val.u32 == 10); CHECK(GetState.uIndex == 4); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 406, 1); CHECK(Val.u32 == 2); CHECK(GetState.uIndex == 5); CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_UINT32), VINF_SUCCESS, 1); CHECK(Val.u32 == 11); CHECK(GetState.uIndex == 5); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 407, 2); CHECK(Val.u32 == 1); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_UINT32), VINF_SUCCESS, 1); CHECK(Val.u32 == 12); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "thirdvalue")); CHECK(GetState.uIndex == UINT32_MAX); /* bool on/off tests */ RTTestSub(hTest, "RTGetOpt - bool on/off"); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 408, 2); CHECK(Val.f); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 408, 2); CHECK(!Val.f); CHECK_GETOPT(RTGetOpt(&GetState, &Val), VERR_GETOPT_UNKNOWN_OPTION, 2); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "invalid")); /* bool on/off with indexed argument */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 409, 2); CHECK(Val.f); CHECK(GetState.uIndex == 2); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 409, 2); CHECK(!Val.f); CHECK(GetState.uIndex == 7); CHECK_GETOPT(RTGetOpt(&GetState, &Val), VERR_GETOPT_UNKNOWN_OPTION, 2); CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "invalid")); /* standard options. */ RTTestSub(hTest, "Standard options"); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1); /* the end */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0); CHECK(Val.pDef == NULL); CHECK(argc2 == GetState.iNext); /* * Options first. */ RTTestSub(hTest, "Options first"); const char *argv3[] = { "foo1", "-s", "string1", "foo2", "--optwithstring", "string2", "foo3", "-i", "-42", "foo4", "-i:-42", "-i=-42", "foo5", "foo6", "foo7", "-i:-42", "-i=-42", "foo8", "--twovalues", "firstvalue", "secondvalue", "foo9", "--twovalues:firstvalue", "secondvalue", "foo10", "--", "--optwithstring", "foo11", "foo12", /* done */ NULL }; int argc3 = (int)RT_ELEMENTS(argv3) - 1; CHECK(RT_SUCCESS(RTGetOptInit(&GetState, argc3, (char **)argv3, &s_aOpts2[0], RT_ELEMENTS(s_aOpts2), 0, RTGETOPTINIT_FLAGS_OPTS_FIRST))); /* -s */ CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string1"); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string2"); CHECK(GetState.uIndex == UINT32_MAX); /* -i */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); /* --twovalues */ CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 2, "firstvalue"); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue"); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 1, "firstvalue"); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue"); CHECK(GetState.uIndex == UINT32_MAX); /* -- */ CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 2, "foo1"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo2"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo3"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo4"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo5"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo6"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo7"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo8"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo9"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo10"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "--optwithstring"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo11"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo12"); /* the end */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0); CHECK(Val.pDef == NULL); CHECK(argc3 == GetState.iNext); /* * Options first, part 2: No dash-dash. */ const char *argv4[] = { "foo1", "-s", "string1", "foo2", "--optwithstring", "string2", "foo3", "-i", "-42", "foo4", "-i:-42", "-i=-42", "foo5", "foo6", "foo7", "-i:-42", "-i=-42", "foo8", "--twovalues", "firstvalue", "secondvalue", "foo9", "--twovalues:firstvalue", "secondvalue", "foo10", "foo11", "foo12", /* done */ NULL }; int argc4 = (int)RT_ELEMENTS(argv4) - 1; CHECK(RT_SUCCESS(RTGetOptInit(&GetState, argc4, (char **)argv4, &s_aOpts2[0], RT_ELEMENTS(s_aOpts2), 0, RTGETOPTINIT_FLAGS_OPTS_FIRST))); /* -s */ CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string1"); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string2"); CHECK(GetState.uIndex == UINT32_MAX); /* -i */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); CHECK(Val.i32 == -42); /* --twovalues */ CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 2, "firstvalue"); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue"); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 1, "firstvalue"); CHECK(GetState.uIndex == UINT32_MAX); CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue"); CHECK(GetState.uIndex == UINT32_MAX); /* -- */ CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo1"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo2"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo3"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo4"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo5"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo6"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo7"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo8"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo9"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo10"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo11"); CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo12"); /* the end */ CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0); CHECK(Val.pDef == NULL); CHECK(argc4 == GetState.iNext); /* * Summary. */ return RTTestSummaryAndDestroy(hTest); }
/** * Handles the log sub-command. * * @returns Suitable exit code. * @param pArgs The handler arguments. * @param pDebugger Pointer to the debugger interface. * @param pszSubCmd The sub command. */ static RTEXITCODE handleDebugVM_LogXXXX(HandlerArg *pArgs, IMachineDebugger *pDebugger, const char *pszSubCmd) { /* * Parse arguments. */ bool fRelease = false; com::Utf8Str strSettings; RTGETOPTSTATE GetState; RTGETOPTUNION ValueUnion; /* * NB: don't use short options to prevent log specifications like * "-drv_foo" from being interpreted as options. */ # define DEBUGVM_LOG_DEBUG (VINF_GETOPT_NOT_OPTION + 'd') # define DEBUGVM_LOG_RELEASE (VINF_GETOPT_NOT_OPTION + 'r') static const RTGETOPTDEF s_aOptions[] = { { "--debug", DEBUGVM_LOG_DEBUG, RTGETOPT_REQ_NOTHING }, { "--release", DEBUGVM_LOG_RELEASE, RTGETOPT_REQ_NOTHING } }; int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST); AssertRCReturn(rc, RTEXITCODE_FAILURE); while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0) { switch (rc) { case DEBUGVM_LOG_RELEASE: fRelease = true; break; case DEBUGVM_LOG_DEBUG: fRelease = false; break; /* Because log strings can start with "-" (like "-all+dev_foo") * we have to take everything we got as a setting and apply it. * IPRT will take care of the validation afterwards. */ default: if (strSettings.length() == 0) strSettings = ValueUnion.psz; else { strSettings.append(' '); strSettings.append(ValueUnion.psz); } break; } } if (fRelease) { com::Utf8Str strTmp(strSettings); strSettings = "release: "; strSettings.append(strTmp); } com::Bstr bstrSettings(strSettings); if (!strcmp(pszSubCmd, "log")) CHECK_ERROR2I_RET(pDebugger, ModifyLogGroups(bstrSettings.raw()), RTEXITCODE_FAILURE); else if (!strcmp(pszSubCmd, "logdest")) CHECK_ERROR2I_RET(pDebugger, ModifyLogDestinations(bstrSettings.raw()), RTEXITCODE_FAILURE); else if (!strcmp(pszSubCmd, "logflags")) CHECK_ERROR2I_RET(pDebugger, ModifyLogFlags(bstrSettings.raw()), RTEXITCODE_FAILURE); else AssertFailedReturn(RTEXITCODE_FAILURE); return RTEXITCODE_SUCCESS; }
/** * A mini GZIP program. * * @returns Program exit code. * * @param cArgs The number of arguments. * @param papszArgs The argument vector. (Note that this may be * reordered, so the memory must be writable.) */ RTEXITCODE RTZipGzipCmd(unsigned cArgs, char **papszArgs) { /* * Parse the command line. */ static const RTGETOPTDEF s_aOptions[] = { { "--ascii", 'a', RTGETOPT_REQ_NOTHING }, { "--stdout", 'c', RTGETOPT_REQ_NOTHING }, { "--to-stdout", 'c', RTGETOPT_REQ_NOTHING }, { "--decompress", 'd', RTGETOPT_REQ_NOTHING }, { "--uncompress", 'd', RTGETOPT_REQ_NOTHING }, { "--force", 'f', RTGETOPT_REQ_NOTHING }, { "--keep", 'k', RTGETOPT_REQ_NOTHING }, { "--list", 'l', RTGETOPT_REQ_NOTHING }, { "--no-name", 'n', RTGETOPT_REQ_NOTHING }, { "--name", 'N', RTGETOPT_REQ_NOTHING }, { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, { "--recursive", 'r', RTGETOPT_REQ_NOTHING }, { "--suffix", 'S', RTGETOPT_REQ_STRING }, { "--test", 't', RTGETOPT_REQ_NOTHING }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, { "--fast", '1', RTGETOPT_REQ_NOTHING }, { "-1", '1', RTGETOPT_REQ_NOTHING }, { "-2", '2', RTGETOPT_REQ_NOTHING }, { "-3", '3', RTGETOPT_REQ_NOTHING }, { "-4", '4', RTGETOPT_REQ_NOTHING }, { "-5", '5', RTGETOPT_REQ_NOTHING }, { "-6", '6', RTGETOPT_REQ_NOTHING }, { "-7", '7', RTGETOPT_REQ_NOTHING }, { "-8", '8', RTGETOPT_REQ_NOTHING }, { "-9", '9', RTGETOPT_REQ_NOTHING }, { "--best", '9', RTGETOPT_REQ_NOTHING } }; RTGZIPCMDOPTS Opts; Opts.fAscii = false; Opts.fStdOut = false; Opts.fDecompress = false; Opts.fForce = false; Opts.fKeep = false; Opts.fList = false; Opts.fName = true; Opts.fQuiet = false; Opts.fRecursive = false; Opts.pszSuff = ".gz"; Opts.fTest = false; Opts.uLevel = 6; RTEXITCODE rcExit = RTEXITCODE_SUCCESS; unsigned cProcessed = 0; //RTVFSIOSTREAM hVfsStdOut= NIL_RTVFSIOSTREAM; RTGETOPTSTATE GetState; int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "RTGetOptInit: %Rrc", rc); for (;;) { RTGETOPTUNION ValueUnion; int chOpt = RTGetOpt(&GetState, &ValueUnion); switch (chOpt) { case 0: /* * If we've processed any files we're done. Otherwise take * input from stdin and write the output to stdout. */ if (cProcessed > 0) return rcExit; ValueUnion.psz = "-"; Opts.fStdOut = true; /* Fall thru. */ case VINF_GETOPT_NOT_OPTION: { if (!*Opts.pszSuff && !Opts.fStdOut) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --suffix option specified an empty string"); if (!Opts.fStdOut && RTVfsChainIsSpec(ValueUnion.psz)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Must use standard out with VFS chain specifications"); if (Opts.fName) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --name option has not yet been implemented. Use --no-name."); if (Opts.fAscii) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --ascii option has not yet been implemented."); if (Opts.fRecursive) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --recursive option has not yet been implemented."); /* Open the input file. */ RTVFSIOSTREAM hVfsSrc; RTEXITCODE rcExit2 = gzipOpenInput(ValueUnion.psz, &Opts, &hVfsSrc); if (rcExit2 == RTEXITCODE_SUCCESS) { if (Opts.fList) rcExit2 = gzipListFile(&hVfsSrc, &Opts); else if (Opts.fTest) rcExit2 = gzipTestFile(&hVfsSrc, &Opts); else { RTVFSIOSTREAM hVfsDst; rcExit2 = gzipOpenOutput(ValueUnion.psz, &Opts, &hVfsDst); if (rcExit2 == RTEXITCODE_SUCCESS) { if (Opts.fDecompress) rcExit2 = gzipDecompressFile(&hVfsSrc, &Opts, &hVfsDst); else rcExit2 = gzipCompressFile(&hVfsSrc, &Opts, &hVfsDst); RTVfsIoStrmRelease(hVfsDst); } } RTVfsIoStrmRelease(hVfsSrc); } if (rcExit2 != RTEXITCODE_SUCCESS) rcExit = rcExit2; cProcessed++; break; } case 'a': Opts.fAscii = true; break; case 'c': Opts.fStdOut = true; Opts.fKeep = true; break; case 'd': Opts.fDecompress = true; break; case 'f': Opts.fForce = true; break; case 'k': Opts.fKeep = true; break; case 'l': Opts.fList = true; break; case 'n': Opts.fName = false; break; case 'N': Opts.fName = true; break; case 'q': Opts.fQuiet = true; break; case 'r': Opts.fRecursive = true; break; case 'S': Opts.pszSuff = ValueUnion.psz; break; case 't': Opts.fTest = true; break; case 'v': Opts.fQuiet = false; break; case '1': Opts.uLevel = 1; break; case '2': Opts.uLevel = 2; break; case '3': Opts.uLevel = 3; break; case '4': Opts.uLevel = 4; break; case '5': Opts.uLevel = 5; break; case '6': Opts.uLevel = 6; break; case '7': Opts.uLevel = 7; break; case '8': Opts.uLevel = 8; break; case '9': Opts.uLevel = 9; break; case 'h': RTPrintf("Usage: to be written\nOption dump:\n"); for (unsigned i = 0; i < RT_ELEMENTS(s_aOptions); i++) RTPrintf(" -%c,%s\n", s_aOptions[i].iShort, s_aOptions[i].pszLong); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); return RTEXITCODE_SUCCESS; default: return RTGetOptPrintError(chOpt, &ValueUnion); } } }
static int vboxNetNATLogInit(int argc, char **argv) { size_t cch; int rc; char szHome[RTPATH_MAX]; rc = com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome), false); if (RT_FAILURE(rc)) return rc; const char *pcszNetwork = NULL; // XXX: This duplicates information from VBoxNetBaseService.cpp. // Perhaps option definitions should be exported as public static // member of VBoxNetBaseService? static const RTGETOPTDEF s_aOptions[] = { { "--network", 'n', RTGETOPT_REQ_STRING } }; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); RTGETOPTUNION ValueUnion; int ch; while ((ch = RTGetOpt(&GetState, &ValueUnion))) { if (ch == 'n') { pcszNetwork = ValueUnion.psz; break; } } if (pcszNetwork == NULL) return VERR_MISSING; char szNetwork[RTPATH_MAX]; rc = RTStrCopy(szNetwork, sizeof(szNetwork), pcszNetwork); if (RT_FAILURE(rc)) return rc; // sanitize network name to be usable as a path component for (char *p = szNetwork; *p != '\0'; ++p) { if (RTPATH_IS_SEP(*p)) *p = '_'; } char szLogFile[RTPATH_MAX]; cch = RTStrPrintf(szLogFile, sizeof(szLogFile), "%s%c%s.log", szHome, RTPATH_DELIMITER, szNetwork); if (cch >= sizeof(szLogFile)) { return VERR_BUFFER_OVERFLOW; } // sanitize network name some more to be usable as environment variable for (char *p = szNetwork; *p != '\0'; ++p) { if (*p != '_' && (*p < '0' || '9' < *p) && (*p < 'a' || 'z' < *p) && (*p < 'A' || 'Z' < *p)) { *p = '_'; } } char szEnvVarBase[128]; cch = RTStrPrintf(szEnvVarBase, sizeof(szEnvVarBase), "VBOXNET_%s_RELEASE_LOG", szNetwork); if (cch >= sizeof(szEnvVarBase)) return VERR_BUFFER_OVERFLOW; char szError[RTPATH_MAX + 128]; rc = com::VBoxLogRelCreate("NAT Network", szLogFile, RTLOGFLAGS_PREFIX_TIME_PROG, "all all.restrict -default.restrict", szEnvVarBase, RTLOGDEST_FILE, 32768 /* cMaxEntriesPerGroup */, 0 /* cHistory */, 0 /* uHistoryFileTime */, 0 /* uHistoryFileSize */, szError, sizeof(szError)); return rc; }
int main(int argc, char **argv) { RTTEST hTest; RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, 0 /*fRtInit*/, "tstSupTscDelta", &hTest); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; /* * Parse args */ static const RTGETOPTDEF g_aOptions[] = { { "--iterations", 'i', RTGETOPT_REQ_INT32 }, { "--delay", 'd', RTGETOPT_REQ_INT32 }, }; uint32_t cIterations = 0; /* Currently 0 so that it doesn't upset testing. */ uint32_t cMsSleepBetweenIterations = 10; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'd': cMsSleepBetweenIterations = ValueUnion.u32; break; case 'i': cIterations = ValueUnion.u32; break; default: return RTGetOptPrintError(ch, &ValueUnion); } } if (!cIterations) return RTTestSkipAndDestroy(hTest, "Nothing to do. The --iterations argument is 0 or not given."); /* * Init */ PSUPDRVSESSION pSession = NIL_RTR0PTR; int rc = SUPR3Init(&pSession); if (RT_SUCCESS(rc)) { PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage; if (pGip) { if (pGip->enmUseTscDelta < SUPGIPUSETSCDELTA_PRACTICALLY_ZERO) return RTTestSkipAndDestroy(hTest, "No deltas to play with: enmUseTscDelta=%d\n", pGip->enmUseTscDelta); /* * Init stats. */ struct { int64_t iLowest; int64_t iHighest; int64_t iTotal; uint64_t uAbsMin; uint64_t uAbsMax; uint64_t uAbsTotal; } aCpuStats[RTCPUSET_MAX_CPUS]; RT_ZERO(aCpuStats); for (uint32_t i = 0; i < pGip->cCpus; i++) { aCpuStats[i].iLowest = INT64_MAX; aCpuStats[i].iHighest = INT64_MIN; aCpuStats[i].uAbsMin = UINT64_MAX; } /* * Do the work. */ for (uint32_t iIteration = 0; ; iIteration++) { /* * Display the current deltas and gather statistics. */ RTPrintf("tstSupTscDelta: Iteration #%u results:", iIteration); for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++) { int64_t iTscDelta = pGip->aCPUs[iCpu].i64TSCDelta; /* print */ if ((iCpu % 4) == 0) RTPrintf("\ntstSupTscDelta:"); if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE) RTPrintf(" %02x: offline ", iCpu); else if (iTscDelta != INT64_MAX) RTPrintf(" %02x: %-12lld", iCpu, iTscDelta); else RTPrintf(" %02x: INT64_MAX ", iCpu); /* stats */ if ( iTscDelta != INT64_MAX && pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE) { if (aCpuStats[iCpu].iLowest > iTscDelta) aCpuStats[iCpu].iLowest = iTscDelta; if (aCpuStats[iCpu].iHighest < iTscDelta) aCpuStats[iCpu].iHighest = iTscDelta; aCpuStats[iCpu].iTotal += iTscDelta; uint64_t uAbsTscDelta = iTscDelta >= 0 ? (uint64_t)iTscDelta : (uint64_t)-iTscDelta; if (aCpuStats[iCpu].uAbsMin > uAbsTscDelta) aCpuStats[iCpu].uAbsMin = uAbsTscDelta; if (aCpuStats[iCpu].uAbsMax < uAbsTscDelta) aCpuStats[iCpu].uAbsMax = uAbsTscDelta; aCpuStats[iCpu].uAbsTotal += uAbsTscDelta; } } if (((pGip->cCpus - 1) % 4) != 0) RTPrintf("\n"); /* * Done? */ if (iIteration + 1 >= cIterations) break; /* * Force a new measurement. */ RTThreadSleep(cMsSleepBetweenIterations); for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++) if (pGip->aCPUs[iCpu].enmState == SUPGIPCPUSTATE_ONLINE) { rc = SUPR3TscDeltaMeasure(pGip->aCPUs[iCpu].idCpu, false /*fAsync*/, true /*fForce*/, 64, 16 /*ms*/); if (RT_FAILURE(rc)) RTTestFailed(hTest, "SUPR3TscDeltaMeasure failed on %#x: %Rrc", pGip->aCPUs[iCpu].idCpu, rc); } } /* * Display statistics that we've gathered. */ RTPrintf("tstSupTscDelta: Results:\n"); int64_t iLowest = INT64_MAX; int64_t iHighest = INT64_MIN; int64_t iTotal = 0; uint32_t cTotal = 0; for (uint32_t iCpu = 0; iCpu < pGip->cCpus; iCpu++) { if (pGip->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_ONLINE) RTPrintf("tstSupTscDelta: %02x: offline\n", iCpu); else { RTPrintf("tstSupTscDelta: %02x: lowest=%-12lld highest=%-12lld average=%-12lld spread=%-12lld\n", iCpu, aCpuStats[iCpu].iLowest, aCpuStats[iCpu].iHighest, aCpuStats[iCpu].iTotal / cIterations, aCpuStats[iCpu].iHighest - aCpuStats[iCpu].iLowest); RTPrintf( "tstSupTscDelta: absmin=%-12llu absmax=%-12llu absavg=%-12llu idCpu=%#4x idApic=%#4x\n", aCpuStats[iCpu].uAbsMin, aCpuStats[iCpu].uAbsMax, aCpuStats[iCpu].uAbsTotal / cIterations, pGip->aCPUs[iCpu].idCpu, pGip->aCPUs[iCpu].idApic); if (iLowest > aCpuStats[iCpu].iLowest) iLowest = aCpuStats[iCpu].iLowest; if (iHighest < aCpuStats[iCpu].iHighest) iHighest = aCpuStats[iCpu].iHighest; iTotal += aCpuStats[iCpu].iHighest; cTotal += cIterations; } } RTPrintf("tstSupTscDelta: all: lowest=%-12lld highest=%-12lld average=%-12lld spread=%-12lld\n", iLowest, iHighest, iTotal / cTotal, iHighest - iLowest); } else RTTestFailed(hTest, "g_pSUPGlobalInfoPage is NULL"); SUPR3Term(false /*fForced*/); } else RTTestFailed(hTest, "SUPR3Init failed: %Rrc", rc); return RTTestSummaryAndDestroy(hTest); }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); const char * const argv0 = RTPathFilename(argv[0]); /* options */ uint64_t uAddress = 0; uint64_t uHighlightAddr = UINT64_MAX; ASMSTYLE enmStyle = kAsmStyle_Default; UNDEFOPHANDLING enmUndefOp = kUndefOp_Fail; bool fListing = true; DISCPUMODE enmCpuMode = DISCPUMODE_32BIT; RTFOFF off = 0; RTFOFF cbMax = _1G; bool fHexBytes = false; /* * Parse arguments. */ static const RTGETOPTDEF g_aOptions[] = { { "--address", 'a', RTGETOPT_REQ_UINT64 }, { "--cpumode", 'c', RTGETOPT_REQ_UINT32 }, { "--bytes", 'b', RTGETOPT_REQ_INT64 }, { "--listing", 'l', RTGETOPT_REQ_NOTHING }, { "--no-listing", 'L', RTGETOPT_REQ_NOTHING }, { "--offset", 'o', RTGETOPT_REQ_INT64 }, { "--style", 's', RTGETOPT_REQ_STRING }, { "--undef-op", 'u', RTGETOPT_REQ_STRING }, { "--hex-bytes", 'x', RTGETOPT_REQ_NOTHING }, }; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); while ( (ch = RTGetOpt(&GetState, &ValueUnion)) && ch != VINF_GETOPT_NOT_OPTION) { switch (ch) { case 'a': uAddress = ValueUnion.u64; break; case 'b': cbMax = ValueUnion.i64; break; case 'c': if (ValueUnion.u32 == 16) enmCpuMode = DISCPUMODE_16BIT; else if (ValueUnion.u32 == 32) enmCpuMode = DISCPUMODE_32BIT; else if (ValueUnion.u32 == 64) enmCpuMode = DISCPUMODE_64BIT; else { RTStrmPrintf(g_pStdErr, "%s: Invalid CPU mode value %RU32\n", argv0, ValueUnion.u32); return 1; } break; case 'h': return Usage(argv0); case 'l': fListing = true; break; case 'L': fListing = false; break; case 'o': off = ValueUnion.i64; break; case 's': if (!strcmp(ValueUnion.psz, "default")) enmStyle = kAsmStyle_Default; else if (!strcmp(ValueUnion.psz, "yasm")) enmStyle = kAsmStyle_yasm; else if (!strcmp(ValueUnion.psz, "masm")) { enmStyle = kAsmStyle_masm; RTStrmPrintf(g_pStdErr, "%s: masm style isn't implemented yet\n", argv0); return 1; } else { RTStrmPrintf(g_pStdErr, "%s: unknown assembly style: %s\n", argv0, ValueUnion.psz); return 1; } break; case 'u': if (!strcmp(ValueUnion.psz, "fail")) enmUndefOp = kUndefOp_Fail; else if (!strcmp(ValueUnion.psz, "all")) enmUndefOp = kUndefOp_All; else if (!strcmp(ValueUnion.psz, "db")) enmUndefOp = kUndefOp_DefineByte; else { RTStrmPrintf(g_pStdErr, "%s: unknown undefined opcode handling method: %s\n", argv0, ValueUnion.psz); return 1; } break; case 'x': fHexBytes = true; break; case 'V': RTPrintf("$Revision: $\n"); return 0; default: return RTGetOptPrintError(ch, &ValueUnion); } } int iArg = GetState.iNext - 1; /** @todo Not pretty, add RTGetOptInit flag for this. */ if (iArg >= argc) return Usage(argv0); int rc = VINF_SUCCESS; if (fHexBytes) { /* * Convert the remaining arguments from a hex byte string into * a buffer that we disassemble. */ size_t cb = 0; uint8_t *pb = NULL; for ( ; iArg < argc; iArg++) { char ch2; const char *psz = argv[iArg]; while (*psz) { /** @todo this stuff belongs in IPRT, same stuff as mac address reading. Could be reused for IPv6 with a different item size.*/ /* skip white space, and for the benefit of linux panics '<' and '>'. */ while (RT_C_IS_SPACE(ch2 = *psz) || ch2 == '<' || ch2 == '>' || ch2 == ',' || ch2 == ';') { if (ch2 == '<') uHighlightAddr = uAddress + cb; psz++; } if (ch2 == '0' && (psz[1] == 'x' || psz[1] == 'X')) { psz += 2; ch2 = *psz; } if (!ch2) break; /* one digit followed by a space or EOS, or two digits. */ int iNum = HexDigitToNum(*psz++); if (iNum == -1) return 1; if (!RT_C_IS_SPACE(ch2 = *psz) && ch2 != '\0' && ch2 != '>' && ch2 != ',' && ch2 != ';') { int iDigit = HexDigitToNum(*psz++); if (iDigit == -1) return 1; iNum = iNum * 16 + iDigit; } /* add the byte */ if (!(cb % 4 /*64*/)) { pb = (uint8_t *)RTMemRealloc(pb, cb + 64); if (!pb) { RTPrintf("%s: error: RTMemRealloc failed\n", argv[0]); return 1; } } pb[cb++] = (uint8_t)iNum; } } /* * Disassemble it. */ rc = MyDisasmBlock(argv0, enmCpuMode, uAddress, uHighlightAddr, pb, cb, enmStyle, fListing, enmUndefOp); } else { /* * Process the files. */ for ( ; iArg < argc; iArg++) { /* * Read the file into memory. */ void *pvFile; size_t cbFile; rc = RTFileReadAllEx(argv[iArg], off, cbMax, RTFILE_RDALL_O_DENY_NONE, &pvFile, &cbFile); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "%s: %s: %Rrc\n", argv0, argv[iArg], rc); break; } /* * Disassemble it. */ rc = MyDisasmBlock(argv0, enmCpuMode, uAddress, uHighlightAddr, (uint8_t *)pvFile, cbFile, enmStyle, fListing, enmUndefOp); if (RT_FAILURE(rc)) break; } } return RT_SUCCESS(rc) ? 0 : 1; }
int main(int argc, char **argv) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * Parse arguments. */ static RTGETOPTDEF const s_aOptions[] = { { "--manifest", 'm', RTGETOPT_REQ_STRING }, { "--java", 'j', RTGETOPT_REQ_NOTHING }, { "--chdir", 'C', RTGETOPT_REQ_STRING }, { "--attribute", 'a', RTGETOPT_REQ_STRING }, { "--verify", 'v', RTGETOPT_REQ_NOTHING }, }; bool fVerify = false; bool fStdFormat = true; const char *pszManifest = NULL; const char *pszChDir = NULL; uint32_t fAttr = RTMANIFEST_ATTR_UNKNOWN; RTGETOPTSTATE GetState; rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc", rc); RTGETOPTUNION ValueUnion; while ( (rc = RTGetOpt(&GetState, &ValueUnion)) != 0 && rc != VINF_GETOPT_NOT_OPTION) { switch (rc) { case 'a': { static struct { const char *pszAttr; uint32_t fAttr; } s_aAttributes[] = { { "size", RTMANIFEST_ATTR_SIZE }, { "md5", RTMANIFEST_ATTR_MD5 }, { "sha1", RTMANIFEST_ATTR_SHA1 }, { "sha256", RTMANIFEST_ATTR_SHA256 }, { "sha512", RTMANIFEST_ATTR_SHA512 } }; uint32_t fThisAttr = RTMANIFEST_ATTR_UNKNOWN; for (unsigned i = 0; i < RT_ELEMENTS(s_aAttributes); i++) if (!RTStrICmp(s_aAttributes[i].pszAttr, ValueUnion.psz)) { fThisAttr = s_aAttributes[i].fAttr; break; } if (fThisAttr == RTMANIFEST_ATTR_UNKNOWN) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown attribute type '%s'", ValueUnion.psz); if (fAttr == RTMANIFEST_ATTR_UNKNOWN) fAttr = fThisAttr; else fAttr |= fThisAttr; break; } case 'j': fStdFormat = false; break; case 'm': if (pszManifest) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Only one manifest can be specified"); pszManifest = ValueUnion.psz; break; case 'v': fVerify = true; break; case 'C': if (pszChDir) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Only one directory change can be specified"); pszChDir = ValueUnion.psz; break; case 'h': RTPrintf("Usage: %s [--manifest <file>] [--chdir <dir>] [--attribute <attrib-name> [..]] <files>\n" " or %s --verify [--manifest <file>] [--chdir <dir>]\n" "\n" "attrib-name: size, md5, sha1, sha256 or sha512\n" , RTProcShortName(), RTProcShortName()); return RTEXITCODE_SUCCESS; case 'V': RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); return RTEXITCODE_SUCCESS; default: return RTGetOptPrintError(rc, &ValueUnion); } } /* * Take action. */ RTEXITCODE rcExit; if (!fVerify) { if (rc != VINF_GETOPT_NOT_OPTION) RTMsgWarning("No files specified, the manifest will be empty."); if (fAttr == RTMANIFEST_ATTR_UNKNOWN) fAttr = RTMANIFEST_ATTR_SIZE | RTMANIFEST_ATTR_MD5 | RTMANIFEST_ATTR_SHA1 | RTMANIFEST_ATTR_SHA256 | RTMANIFEST_ATTR_SHA512; rcExit = rtManifestDoCreate(pszManifest, fStdFormat, pszChDir, fAttr, &GetState, &ValueUnion, rc); } else { if (rc == VINF_GETOPT_NOT_OPTION) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No files should be specified when verifying a manifest (--verfiy), " "only a manifest via the --manifest option"); if (fAttr != RTMANIFEST_ATTR_UNKNOWN) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --attribute (-a) option does not combine with --verify (-v)"); rcExit = rtManifestDoVerify(pszManifest, fStdFormat, pszChDir); } return rcExit; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/) { LPCTSTR lpCmdLine = GetCommandLine(); /* this line necessary for _ATL_MIN_CRT */ /* * Need to parse the command line before initializing the VBox runtime. */ TCHAR szTokens[] = _T("-/"); LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens); while (lpszToken != NULL) { if (WordCmpI(lpszToken, _T("Embedding")) == 0) { /* %HOMEDRIVE%%HOMEPATH% */ wchar_t wszHome[RTPATH_MAX]; DWORD cEnv = GetEnvironmentVariable(L"HOMEDRIVE", &wszHome[0], RTPATH_MAX); if (cEnv && cEnv < RTPATH_MAX) { DWORD cwc = cEnv; /* doesn't include NUL */ cEnv = GetEnvironmentVariable(L"HOMEPATH", &wszHome[cEnv], RTPATH_MAX - cwc); if (cEnv && cEnv < RTPATH_MAX - cwc) { /* If this fails there is nothing we can do. Ignore. */ SetCurrentDirectory(wszHome); } } } lpszToken = FindOneOf(lpszToken, szTokens); } /* * Initialize the VBox runtime without loading * the support driver. */ int argc = __argc; char **argv = __argv; RTR3InitExe(argc, &argv, 0); /* Note that all options are given lowercase/camel case/uppercase to * approximate case insensitive matching, which RTGetOpt doesn't offer. */ static const RTGETOPTDEF s_aOptions[] = { { "--embedding", 'e', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "-embedding", 'e', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "/embedding", 'e', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "--unregserver", 'u', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "-unregserver", 'u', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "/unregserver", 'u', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "--regserver", 'r', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "-regserver", 'r', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "/regserver", 'r', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "--reregserver", 'f', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "-reregserver", 'f', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "/reregserver", 'f', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, { "--helper", 'H', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "-helper", 'H', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "/helper", 'H', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "--logfile", 'F', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "-logfile", 'F', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "/logfile", 'F', RTGETOPT_REQ_STRING | RTGETOPT_FLAG_ICASE }, { "--logrotate", 'R', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "-logrotate", 'R', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "/logrotate", 'R', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "--logsize", 'S', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_ICASE }, { "-logsize", 'S', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_ICASE }, { "/logsize", 'S', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_ICASE }, { "--loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "-loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, { "/loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, }; bool fRun = true; bool fRegister = false; bool fUnregister = false; const char *pszPipeName = NULL; const char *pszLogFile = NULL; uint32_t cHistory = 10; // enable log rotation, 10 files uint32_t uHistoryFileTime = RT_SEC_1DAY; // max 1 day per file uint64_t uHistoryFileSize = 100 * _1M; // max 100MB per file RTGETOPTSTATE GetOptState; int vrc = RTGetOptInit(&GetOptState, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/); AssertRC(vrc); RTGETOPTUNION ValueUnion; while ((vrc = RTGetOpt(&GetOptState, &ValueUnion))) { switch (vrc) { case 'e': /* already handled above */ break; case 'u': fUnregister = true; fRun = false; break; case 'r': fRegister = true; fRun = false; break; case 'f': fUnregister = true; fRegister = true; fRun = false; break; case 'H': pszPipeName = ValueUnion.psz; if (!pszPipeName) pszPipeName = ""; fRun = false; break; case 'F': pszLogFile = ValueUnion.psz; break; case 'R': cHistory = ValueUnion.u32; break; case 'S': uHistoryFileSize = ValueUnion.u64; break; case 'I': uHistoryFileTime = ValueUnion.u32; break; case 'h': { TCHAR txt[]= L"Options:\n\n" L"/RegServer:\tregister COM out-of-proc server\n" L"/UnregServer:\tunregister COM out-of-proc server\n" L"/ReregServer:\tunregister and register COM server\n" L"no options:\trun the server"; TCHAR title[]=_T("Usage"); fRun = false; MessageBox(NULL, txt, title, MB_OK); return 0; } case 'V': { char *psz = NULL; RTStrAPrintf(&psz, "%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); PRTUTF16 txt = NULL; RTStrToUtf16(psz, &txt); TCHAR title[]=_T("Version"); fRun = false; MessageBox(NULL, txt, title, MB_OK); RTStrFree(psz); RTUtf16Free(txt); return 0; } default: /** @todo this assumes that stderr is visible, which is not * true for standard Windows applications. */ /* continue on command line errors... */ RTGetOptPrintError(vrc, &ValueUnion); } } /* Only create the log file when running VBoxSVC normally, but not when * registering/unregistering or calling the helper functionality. */ if (fRun) { if (!pszLogFile) { char szLogFile[RTPATH_MAX]; vrc = com::GetVBoxUserHomeDirectory(szLogFile, sizeof(szLogFile)); if (RT_SUCCESS(vrc)) vrc = RTPathAppend(szLogFile, sizeof(szLogFile), "VBoxSVC.log"); if (RT_SUCCESS(vrc)) pszLogFile = RTStrDup(szLogFile); } char szError[RTPATH_MAX + 128]; vrc = com::VBoxLogRelCreate("COM Server", pszLogFile, RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG, "all", "VBOXSVC_RELEASE_LOG", RTLOGDEST_FILE, UINT32_MAX /* cMaxEntriesPerGroup */, cHistory, uHistoryFileTime, uHistoryFileSize, szError, sizeof(szError)); if (RT_FAILURE(vrc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "failed to open release log (%s, %Rrc)", szError, vrc); } int nRet = 0; HRESULT hRes = com::Initialize(); _ASSERTE(SUCCEEDED(hRes)); _Module.Init(ObjectMap, hInstance, &LIBID_VirtualBox); _Module.dwThreadID = GetCurrentThreadId(); if (!fRun) { if (fUnregister) { _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, FALSE); nRet = _Module.UnregisterServer(TRUE); } if (fRegister) { _Module.UpdateRegistryFromResource(IDR_VIRTUALBOX, TRUE); nRet = _Module.RegisterServer(TRUE); } if (pszPipeName) { Log(("SVCMAIN: Processing Helper request (cmdline=\"%s\")...\n", pszPipeName)); if (!*pszPipeName) vrc = VERR_INVALID_PARAMETER; if (RT_SUCCESS(vrc)) { /* do the helper job */ SVCHlpServer server; vrc = server.open(pszPipeName); if (RT_SUCCESS(vrc)) vrc = server.run(); } if (RT_FAILURE(vrc)) { Log(("SVCMAIN: Failed to process Helper request (%Rrc).", vrc)); nRet = 1; } } } else { _Module.StartMonitor(); #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED) hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED); _ASSERTE(SUCCEEDED(hRes)); hRes = CoResumeClassObjects(); #else hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE); #endif _ASSERTE(SUCCEEDED(hRes)); MSG msg; while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg); _Module.RevokeClassObjects(); Sleep(dwPause); //wait for any threads to finish } _Module.Term(); com::Shutdown(); Log(("SVCMAIN: Returning, COM server process ends.\n")); return nRet; }
int main(int argc, char **argv) { int rc = 0; RTR3InitExe(argc, &argv, 0); if(argc < 2) { #ifdef VBOX_WITH_CROGL /* backwards compatibility: check 3D */ rc = vboxCheck3DAccelerationSupported(); #endif } else { static const RTGETOPTDEF s_aOptionDefs[] = { { "--test", 't', RTGETOPT_REQ_STRING }, { "-test", 't', RTGETOPT_REQ_STRING }, #ifdef VBOXGLTEST_WITH_LOGGING { "--log", 'l', RTGETOPT_REQ_STRING }, #endif }; RTGETOPTSTATE State; rc = RTGetOptInit(&State, argc-1, argv+1, &s_aOptionDefs[0], RT_ELEMENTS(s_aOptionDefs), 0, 0); AssertRCReturn(rc, 49); #ifdef VBOX_WITH_VIDEOHWACCEL bool bTest2D = false; #endif #ifdef VBOX_WITH_CROGL bool bTest3D = false; #endif #ifdef VBOXGLTEST_WITH_LOGGING bool bLog = false; bool bLogSuffix = false; const char * pLog = NULL; #endif for (;;) { RTGETOPTUNION Val; rc = RTGetOpt(&State, &Val); if (!rc) break; switch (rc) { case 't': #ifdef VBOX_WITH_CROGL if (!strcmp(Val.psz, "3D") || !strcmp(Val.psz, "3d")) { bTest3D = true; rc = 0; break; } #endif #ifdef VBOX_WITH_VIDEOHWACCEL if (!strcmp(Val.psz, "2D") || !strcmp(Val.psz, "2d")) { bTest2D = true; rc = 0; break; } #endif rc = 1; break; #ifdef VBOXGLTEST_WITH_LOGGING case 'l': bLog = true; pLog = Val.psz; rc = 0; break; #endif case 'h': RTPrintf(VBOX_PRODUCT " Helper for testing 2D/3D OpenGL capabilities %u.%u.%u\n" "(C) 2009-" VBOX_C_YEAR " " VBOX_VENDOR "\n" "All rights reserved.\n" "\n" "Parameters:\n" #ifdef VBOX_WITH_VIDEOHWACCEL " --test 2D test for 2D (video) OpenGL capabilities\n" #endif #ifdef VBOX_WITH_CROGL " --test 3D test for 3D OpenGL capabilities\n" #endif #ifdef VBOXGLTEST_WITH_LOGGING " --log <log_file_name> log the GL test result to the given file\n" "\n" "Logging can alternatively be enabled by specifying the VBOXGLTEST_LOG=<log_file_name> env variable\n" #endif "\n", RTBldCfgVersionMajor(), RTBldCfgVersionMinor(), RTBldCfgVersionBuild()); break; case 'V': RTPrintf("$Revision: $\n"); return 0; case VERR_GETOPT_UNKNOWN_OPTION: case VINF_GETOPT_NOT_OPTION: rc = 1; default: /* complain? RTGetOptPrintError(rc, &Val); */ break; } if (rc) break; } if(!rc) { #ifdef VBOXGLTEST_WITH_LOGGING if(!bLog) { /* check the VBOXGLTEST_LOG env var */ pLog = RTEnvGet("VBOXGLTEST_LOG"); if(pLog) bLog = true; bLogSuffix = true; } if(bLog) rc = vboxInitLogging(pLog, bLogSuffix); else #endif rc = vboxInitQuietMode(); #ifdef VBOX_WITH_CROGL if(!rc && bTest3D) rc = vboxCheck3DAccelerationSupported(); #endif #ifdef VBOX_WITH_VIDEOHWACCEL if(!rc && bTest2D) rc = vboxCheck2DVideoAccelerationSupported(); #endif } } /*RTR3Term();*/ return rc; }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); /* * Parse args */ static const RTGETOPTDEF g_aOptions[] = { { "--iterations", 'i', RTGETOPT_REQ_INT32 }, { "--hex", 'h', RTGETOPT_REQ_NOTHING }, { "--decimal", 'd', RTGETOPT_REQ_NOTHING }, { "--spin", 's', RTGETOPT_REQ_NOTHING } }; uint32_t cIterations = 40; bool fHex = true; bool fSpin = false; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'i': cIterations = ValueUnion.u32; break; case 'd': fHex = false; break; case 'h': fHex = true; break; case 's': fSpin = true; break; default: return RTGetOptPrintError(ch, &ValueUnion); } } /* * Init */ PSUPDRVSESSION pSession = NIL_RTR0PTR; int rc = SUPR3Init(&pSession); if (RT_SUCCESS(rc)) { if (g_pSUPGlobalInfoPage) { RTPrintf("tstGIP-2: u32UpdateHz=%RU32 u32UpdateIntervalNS=%RU32 u64NanoTSLastUpdateHz=%RX64 u32Mode=%d (%s) u32Version=%#x\n", g_pSUPGlobalInfoPage->u32UpdateHz, g_pSUPGlobalInfoPage->u32UpdateIntervalNS, g_pSUPGlobalInfoPage->u64NanoTSLastUpdateHz, g_pSUPGlobalInfoPage->u32Mode, g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_SYNC_TSC ? "sync" : g_pSUPGlobalInfoPage->u32Mode == SUPGIPMODE_ASYNC_TSC ? "async" : "???", g_pSUPGlobalInfoPage->u32Version); RTPrintf(fHex ? "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz TSC Interval History...\n" : "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz TSC Interval History...\n"); static SUPGIPCPU s_aaCPUs[2][RT_ELEMENTS(g_pSUPGlobalInfoPage->aCPUs)]; for (uint32_t i = 0; i < cIterations; i++) { /* copy the data */ memcpy(&s_aaCPUs[i & 1][0], &g_pSUPGlobalInfoPage->aCPUs[0], sizeof(g_pSUPGlobalInfoPage->aCPUs)); /* display it & find something to spin on. */ uint32_t u32TransactionId = 0; uint32_t volatile *pu32TransactionId = NULL; for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_pSUPGlobalInfoPage->aCPUs); iCpu++) if ( g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz > 0 && g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz != _4G + 1) { PSUPGIPCPU pPrevCpu = &s_aaCPUs[!(i & 1)][iCpu]; PSUPGIPCPU pCpu = &s_aaCPUs[i & 1][iCpu]; RTPrintf(fHex ? "tstGIP-2: %4d/%d: %016llx %09llx %016llx %08x %d %08x %15llu %08x %08x %08x %08x %08x %08x %08x %08x (%d)\n" : "tstGIP-2: %4d/%d: %016llu %09llu %016llu %010u %d %010u %15llu %08x %08x %08x %08x %08x %08x %08x %08x (%d)\n", i, iCpu, pCpu->u64NanoTS, i ? pCpu->u64NanoTS - pPrevCpu->u64NanoTS : 0, pCpu->u64TSC, pCpu->u32UpdateIntervalTSC, pCpu->iTSCHistoryHead, pCpu->u32TransactionId, pCpu->u64CpuHz, pCpu->au32TSCHistory[0], pCpu->au32TSCHistory[1], pCpu->au32TSCHistory[2], pCpu->au32TSCHistory[3], pCpu->au32TSCHistory[4], pCpu->au32TSCHistory[5], pCpu->au32TSCHistory[6], pCpu->au32TSCHistory[7], pCpu->cErrors); if (!pu32TransactionId) { pu32TransactionId = &g_pSUPGlobalInfoPage->aCPUs[iCpu].u32TransactionId; u32TransactionId = pCpu->u32TransactionId; } } /* wait a bit / spin */ if (!fSpin) RTThreadSleep(9); else while (u32TransactionId == *pu32TransactionId) /* nop */; } } else { RTPrintf("tstGIP-2: g_pSUPGlobalInfoPage is NULL\n"); rc = -1; } SUPR3Term(false /*fForced*/); } else RTPrintf("tstGIP-2: SUPR3Init failed: %Rrc\n", rc); return !!rc; }
/** * Handles the getregisters sub-command. * * @returns Suitable exit code. * @param pArgs The handler arguments. * @param pDebugger Pointer to the debugger interface. */ static RTEXITCODE handleDebugVM_GetRegisters(HandlerArg *pArgs, IMachineDebugger *pDebugger) { /* * We take a list of register names (case insensitive). If 'all' is * encountered we'll dump all registers. */ ULONG idCpu = 0; unsigned cRegisters = 0; RTGETOPTSTATE GetState; RTGETOPTUNION ValueUnion; static const RTGETOPTDEF s_aOptions[] = { { "--cpu", 'c', RTGETOPT_REQ_UINT32 }, }; int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST); AssertRCReturn(rc, RTEXITCODE_FAILURE); while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0) { switch (rc) { case 'c': idCpu = ValueUnion.u32; break; case VINF_GETOPT_NOT_OPTION: if (!RTStrICmp(ValueUnion.psz, "all")) { com::SafeArray<BSTR> aBstrNames; com::SafeArray<BSTR> aBstrValues; CHECK_ERROR2I_RET(pDebugger, GetRegisters(idCpu, ComSafeArrayAsOutParam(aBstrNames), ComSafeArrayAsOutParam(aBstrValues)), RTEXITCODE_FAILURE); Assert(aBstrNames.size() == aBstrValues.size()); size_t cchMaxName = 8; for (size_t i = 0; i < aBstrNames.size(); i++) { size_t cchName = RTUtf16Len(aBstrNames[i]); if (cchName > cchMaxName) cchMaxName = cchName; } for (size_t i = 0; i < aBstrNames.size(); i++) RTPrintf("%-*ls = %ls\n", cchMaxName, aBstrNames[i], aBstrValues[i]); } else { com::Bstr bstrName = ValueUnion.psz; com::Bstr bstrValue; CHECK_ERROR2I_RET(pDebugger, GetRegister(idCpu, bstrName.raw(), bstrValue.asOutParam()), RTEXITCODE_FAILURE); RTPrintf("%s = %ls\n", ValueUnion.psz, bstrValue.raw()); } cRegisters++; break; default: return errorGetOpt(rc, &ValueUnion); } } if (!cRegisters) return errorSyntax("The getregisters sub-command takes at least one register name"); return RTEXITCODE_SUCCESS; }
/** * Handles the statistics sub-command. * * @returns Suitable exit code. * @param pArgs The handler arguments. * @param pDebugger Pointer to the debugger interface. */ static RTEXITCODE handleDebugVM_Statistics(HandlerArg *pArgs, IMachineDebugger *pDebugger) { /* * Parse arguments. */ bool fWithDescriptions = false; const char *pszPattern = NULL; /* all */ bool fReset = false; RTGETOPTSTATE GetState; RTGETOPTUNION ValueUnion; static const RTGETOPTDEF s_aOptions[] = { { "--descriptions", 'd', RTGETOPT_REQ_NOTHING }, { "--pattern", 'p', RTGETOPT_REQ_STRING }, { "--reset", 'r', RTGETOPT_REQ_NOTHING }, }; int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/); AssertRCReturn(rc, RTEXITCODE_FAILURE); while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0) { switch (rc) { case 'd': fWithDescriptions = true; break; case 'p': if (pszPattern) return errorSyntax("Multiple --pattern options are not permitted"); pszPattern = ValueUnion.psz; break; case 'r': fReset = true; break; default: return errorGetOpt(rc, &ValueUnion); } } if (fReset && fWithDescriptions) return errorSyntax("The --reset and --descriptions options does not mix"); /* * Execute the order. */ com::Bstr bstrPattern(pszPattern); if (fReset) CHECK_ERROR2I_RET(pDebugger, ResetStats(bstrPattern.raw()), RTEXITCODE_FAILURE); else { com::Bstr bstrStats; CHECK_ERROR2I_RET(pDebugger, GetStats(bstrPattern.raw(), fWithDescriptions, bstrStats.asOutParam()), RTEXITCODE_FAILURE); /* if (fFormatted) { big mess } else */ RTPrintf("%ls\n", bstrStats.raw()); } return RTEXITCODE_SUCCESS; }
/** * Entry point. */ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp) { RT_NOREF1(envp); /* * Init runtime and the test environment. */ RTTEST hTest; RTEXITCODE rcExit = RTTestInitExAndCreate(argc, &argv, RTR3INIT_FLAGS_SUPLIB, "tstVMM", &hTest); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--cpus", 'c', RTGETOPT_REQ_UINT8 }, { "--test", 't', RTGETOPT_REQ_STRING }, { "--stat", 's', RTGETOPT_REQ_NOTHING }, }; enum { kTstVMMTest_VMM, kTstVMMTest_TM, kTstVMMTest_MSRs, kTstVMMTest_KnownMSRs, kTstVMMTest_MSRExperiments } enmTestOpt = kTstVMMTest_VMM; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'c': g_cCpus = ValueUnion.u8; break; case 't': if (!strcmp("vmm", ValueUnion.psz)) enmTestOpt = kTstVMMTest_VMM; else if (!strcmp("tm", ValueUnion.psz)) enmTestOpt = kTstVMMTest_TM; else if (!strcmp("msr", ValueUnion.psz) || !strcmp("msrs", ValueUnion.psz)) enmTestOpt = kTstVMMTest_MSRs; else if (!strcmp("known-msr", ValueUnion.psz) || !strcmp("known-msrs", ValueUnion.psz)) enmTestOpt = kTstVMMTest_KnownMSRs; else if (!strcmp("msr-experiments", ValueUnion.psz)) enmTestOpt = kTstVMMTest_MSRExperiments; else { RTPrintf("tstVMM: unknown test: '%s'\n", ValueUnion.psz); return 1; } break; case 's': g_fStat = true; break; case 'h': RTPrintf("usage: tstVMM [--cpus|-c cpus] [-s] [--test <vmm|tm|msrs|known-msrs>]\n"); return 1; case 'V': RTPrintf("$Revision$\n"); return 0; default: return RTGetOptPrintError(ch, &ValueUnion); } } /* * Create the test VM. */ RTPrintf(TESTCASE ": Initializing...\n"); PVM pVM; PUVM pUVM; int rc = VMR3Create(g_cCpus, NULL, NULL, NULL, tstVMMConfigConstructor, NULL, &pVM, &pUVM); if (RT_SUCCESS(rc)) { PDMR3LdrEnumModules(pVM, tstVMMLdrEnum, NULL); RTStrmFlush(g_pStdOut); RTThreadSleep(256); /* * Do the requested testing. */ switch (enmTestOpt) { case kTstVMMTest_VMM: { RTTestSub(hTest, "VMM"); rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ANY, (PFNRT)VMMDoTest, 1, pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc); if (g_fStat) STAMR3Dump(pUVM, "*"); break; } case kTstVMMTest_TM: { RTTestSub(hTest, "TM"); for (VMCPUID idCpu = 1; idCpu < g_cCpus; idCpu++) { rc = VMR3ReqCallNoWaitU(pUVM, idCpu, (PFNRT)tstTMWorker, 2, pVM, hTest); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMR3ReqCall failed: rc=%Rrc\n", rc); } rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)tstTMWorker, 2, pVM, hTest); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc); if (g_fStat) STAMR3Dump(pUVM, "*"); break; } case kTstVMMTest_MSRs: { RTTestSub(hTest, "MSRs"); if (g_cCpus == 1) { rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoBruteForceMsrs, 1, pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoBruteForceMsrs failed: rc=%Rrc\n", rc); } else RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n"); break; } case kTstVMMTest_KnownMSRs: { RTTestSub(hTest, "Known MSRs"); if (g_cCpus == 1) { rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoKnownMsrs, 1, pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoKnownMsrs failed: rc=%Rrc\n", rc); } else RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n"); break; } case kTstVMMTest_MSRExperiments: { RTTestSub(hTest, "MSR Experiments"); if (g_cCpus == 1) { rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoMsrExperiments, 1, pVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMMDoMsrExperiments failed: rc=%Rrc\n", rc); } else RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n"); break; } } /* * Cleanup. */ rc = VMR3PowerOff(pUVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMR3PowerOff failed: rc=%Rrc\n", rc); rc = VMR3Destroy(pUVM); if (RT_FAILURE(rc)) RTTestFailed(hTest, "VMR3Destroy failed: rc=%Rrc\n", rc); VMR3ReleaseUVM(pUVM); } else RTTestFailed(hTest, "VMR3Create failed: rc=%Rrc\n", rc); return RTTestSummaryAndDestroy(hTest); }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); /* * Parse args */ static const RTGETOPTDEF g_aOptions[] = { { "--iterations", 'i', RTGETOPT_REQ_INT32 }, { "--hex", 'h', RTGETOPT_REQ_NOTHING }, { "--decimal", 'd', RTGETOPT_REQ_NOTHING }, { "--spin", 's', RTGETOPT_REQ_NOTHING }, { "--reference", 'r', RTGETOPT_REQ_UINT64 }, /* reference value of CpuHz, display the * CpuHz deviation in a separate column. */ }; uint32_t cIterations = 40; bool fHex = true; bool fSpin = false; int ch; uint64_t uCpuHzRef = 0; uint64_t uCpuHzOverallDeviation = 0; int64_t iCpuHzMaxDeviation = 0; int32_t cCpuHzOverallDevCnt = 0; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'i': cIterations = ValueUnion.u32; break; case 'd': fHex = false; break; case 'h': fHex = true; break; case 's': fSpin = true; break; case 'r': uCpuHzRef = ValueUnion.u64; break; default: return RTGetOptPrintError(ch, &ValueUnion); } } /* * Init */ PSUPDRVSESSION pSession = NIL_RTR0PTR; int rc = SUPR3Init(&pSession); if (RT_SUCCESS(rc)) { if (g_pSUPGlobalInfoPage) { RTPrintf("tstGIP-2: cCpus=%d u32UpdateHz=%RU32 u32UpdateIntervalNS=%RU32 u64NanoTSLastUpdateHz=%RX64 u64CpuHz=%RU64 uCpuHzRef=%RU64 u32Mode=%d (%s) u32Version=%#x\n", g_pSUPGlobalInfoPage->cCpus, g_pSUPGlobalInfoPage->u32UpdateHz, g_pSUPGlobalInfoPage->u32UpdateIntervalNS, g_pSUPGlobalInfoPage->u64NanoTSLastUpdateHz, g_pSUPGlobalInfoPage->u64CpuHz, uCpuHzRef, g_pSUPGlobalInfoPage->u32Mode, SUPGetGIPModeName(g_pSUPGlobalInfoPage), g_pSUPGlobalInfoPage->u32Version); RTPrintf(fHex ? "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz %sTSC Interval History...\n" : "tstGIP-2: it: u64NanoTS delta u64TSC UpIntTSC H TransId CpuHz %sTSC Interval History...\n", uCpuHzRef ? " CpuHz deviation " : ""); static SUPGIPCPU s_aaCPUs[2][256]; for (uint32_t i = 0; i < cIterations; i++) { /* copy the data */ memcpy(&s_aaCPUs[i & 1][0], &g_pSUPGlobalInfoPage->aCPUs[0], g_pSUPGlobalInfoPage->cCpus * sizeof(g_pSUPGlobalInfoPage->aCPUs[0])); /* display it & find something to spin on. */ uint32_t u32TransactionId = 0; uint32_t volatile *pu32TransactionId = NULL; for (unsigned iCpu = 0; iCpu < g_pSUPGlobalInfoPage->cCpus; iCpu++) if ( g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz > 0 && g_pSUPGlobalInfoPage->aCPUs[iCpu].u64CpuHz != _4G + 1) { char szCpuHzDeviation[32]; PSUPGIPCPU pPrevCpu = &s_aaCPUs[!(i & 1)][iCpu]; PSUPGIPCPU pCpu = &s_aaCPUs[i & 1][iCpu]; if (uCpuHzRef) { int64_t iCpuHzDeviation = pCpu->u64CpuHz - uCpuHzRef; uint64_t uCpuHzDeviation = RT_ABS(iCpuHzDeviation); if (uCpuHzDeviation > 999999999) RTStrPrintf(szCpuHzDeviation, sizeof(szCpuHzDeviation), "%17s ", "?"); else { /* Wait until the history validation code takes effect. */ if (pCpu->u32TransactionId > 23 + (8 * 2) + 1) { if (RT_ABS(iCpuHzDeviation) > RT_ABS(iCpuHzMaxDeviation)) iCpuHzMaxDeviation = iCpuHzDeviation; uCpuHzOverallDeviation += uCpuHzDeviation; cCpuHzOverallDevCnt++; } uint32_t uPct = (uint32_t)(uCpuHzDeviation * 100000 / uCpuHzRef + 5); RTStrPrintf(szCpuHzDeviation, sizeof(szCpuHzDeviation), "%10RI64%3d.%02d%% ", iCpuHzDeviation, uPct / 1000, (uPct % 1000) / 10); } } else szCpuHzDeviation[0] = '\0'; RTPrintf(fHex ? "tstGIP-2: %4d/%d: %016llx %09llx %016llx %08x %d %08x %15llu %s%08x %08x %08x %08x %08x %08x %08x %08x (%d)\n" : "tstGIP-2: %4d/%d: %016llu %09llu %016llu %010u %d %010u %15llu %s%08x %08x %08x %08x %08x %08x %08x %08x (%d)\n", i, iCpu, pCpu->u64NanoTS, i ? pCpu->u64NanoTS - pPrevCpu->u64NanoTS : 0, pCpu->u64TSC, pCpu->u32UpdateIntervalTSC, pCpu->iTSCHistoryHead, pCpu->u32TransactionId, pCpu->u64CpuHz, szCpuHzDeviation, pCpu->au32TSCHistory[0], pCpu->au32TSCHistory[1], pCpu->au32TSCHistory[2], pCpu->au32TSCHistory[3], pCpu->au32TSCHistory[4], pCpu->au32TSCHistory[5], pCpu->au32TSCHistory[6], pCpu->au32TSCHistory[7], pCpu->cErrors); if (!pu32TransactionId) { pu32TransactionId = &g_pSUPGlobalInfoPage->aCPUs[iCpu].u32TransactionId; u32TransactionId = pCpu->u32TransactionId; } } /* wait a bit / spin */ if (!fSpin) RTThreadSleep(9); else { if (pu32TransactionId) { uint32_t uTmp; while ( u32TransactionId == (uTmp = *pu32TransactionId) || (uTmp & 1)) ASMNopPause(); } else RTThreadSleep(1); } } /* * Display TSC deltas. * * First iterative over the APIC ID array to get mostly consistent CPUID to APIC ID mapping. * Then iterate over the offline CPUs. It is possible that there's a race between the online/offline * states between the two iterations, but that cannot be helped from ring-3 anyway and not a biggie. */ RTPrintf("tstGIP-2: TSC deltas:\n"); RTPrintf("tstGIP-2: idApic: i64TSCDelta\n"); for (unsigned i = 0; i < RT_ELEMENTS(g_pSUPGlobalInfoPage->aiCpuFromApicId); i++) { uint16_t iCpu = g_pSUPGlobalInfoPage->aiCpuFromApicId[i]; if (iCpu != UINT16_MAX) { RTPrintf("tstGIP-2: %7d: %lld\n", g_pSUPGlobalInfoPage->aCPUs[iCpu].idApic, g_pSUPGlobalInfoPage->aCPUs[iCpu].i64TSCDelta); } } for (unsigned iCpu = 0; iCpu < g_pSUPGlobalInfoPage->cCpus; iCpu++) if (g_pSUPGlobalInfoPage->aCPUs[iCpu].idApic == UINT16_MAX) RTPrintf("tstGIP-2: offline: %lld\n", g_pSUPGlobalInfoPage->aCPUs[iCpu].i64TSCDelta); RTPrintf("tstGIP-2: enmUseTscDelta=%d fGetGipCpu=%#x\n", g_pSUPGlobalInfoPage->enmUseTscDelta, g_pSUPGlobalInfoPage->fGetGipCpu); if ( uCpuHzRef && cCpuHzOverallDevCnt) { uint32_t uPct = (uint32_t)(uCpuHzOverallDeviation * 100000 / cCpuHzOverallDevCnt / uCpuHzRef + 5); RTPrintf("tstGIP-2: Average CpuHz deviation: %d.%02d%%\n", uPct / 1000, (uPct % 1000) / 10); uint32_t uMaxPct = (uint32_t)(RT_ABS(iCpuHzMaxDeviation) * 100000 / uCpuHzRef + 5); RTPrintf("tstGIP-2: Maximum CpuHz deviation: %d.%02d%% (%RI64 ticks)\n", uMaxPct / 1000, (uMaxPct % 1000) / 10, iCpuHzMaxDeviation); } } else { RTPrintf("tstGIP-2: g_pSUPGlobalInfoPage is NULL\n"); rc = -1; } SUPR3Term(false /*fForced*/); } else RTPrintf("tstGIP-2: SUPR3Init failed: %Rrc\n", rc); return !!rc; }
/** * Handles the setregisters sub-command. * * @returns Suitable exit code. * @param pArgs The handler arguments. * @param pDebugger Pointer to the debugger interface. */ static RTEXITCODE handleDebugVM_SetRegisters(HandlerArg *pArgs, IMachineDebugger *pDebugger) { /* * We take a list of register assignments, that is register=value. */ ULONG idCpu = 0; com::SafeArray<IN_BSTR> aBstrNames; com::SafeArray<IN_BSTR> aBstrValues; RTGETOPTSTATE GetState; RTGETOPTUNION ValueUnion; static const RTGETOPTDEF s_aOptions[] = { { "--cpu", 'c', RTGETOPT_REQ_UINT32 }, }; int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, RTGETOPTINIT_FLAGS_OPTS_FIRST); AssertRCReturn(rc, RTEXITCODE_FAILURE); while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0) { switch (rc) { case 'c': idCpu = ValueUnion.u32; break; case VINF_GETOPT_NOT_OPTION: { const char *pszEqual = strchr(ValueUnion.psz, '='); if (!pszEqual) return errorSyntax("setregisters expects input on the form 'register=value' got '%s'", ValueUnion.psz); try { com::Bstr bstrName(ValueUnion.psz, pszEqual - ValueUnion.psz); com::Bstr bstrValue(pszEqual + 1); if ( !aBstrNames.push_back(bstrName.raw()) || !aBstrValues.push_back(bstrValue.raw())) throw std::bad_alloc(); } catch (std::bad_alloc) { RTMsgError("Out of memory\n"); return RTEXITCODE_FAILURE; } break; } default: return errorGetOpt(rc, &ValueUnion); } } if (!aBstrNames.size()) return errorSyntax("The setregisters sub-command takes at least one register name"); /* * If it is only one register, use the single register method just so * we expose it and can test it from the command line. */ if (aBstrNames.size() == 1) { CHECK_ERROR2I_RET(pDebugger, SetRegister(idCpu, aBstrNames[0], aBstrValues[0]), RTEXITCODE_FAILURE); RTPrintf("Successfully set %ls\n", aBstrNames[0]); } else { CHECK_ERROR2I_RET(pDebugger, SetRegisters(idCpu, ComSafeArrayAsInParam(aBstrNames), ComSafeArrayAsInParam(aBstrValues)), RTEXITCODE_FAILURE); RTPrintf("Successfully set %u registers\n", aBstrNames.size()); } return RTEXITCODE_SUCCESS; }
RTDECL(RTEXITCODE) RTZipUnzipCmd(unsigned cArgs, char **papszArgs) { /* * Parse the command line. */ static const RTGETOPTDEF s_aOptions[] = { /* options */ { NULL, 'c', RTGETOPT_REQ_NOTHING }, /* extract files to stdout/stderr */ { NULL, 'd', RTGETOPT_REQ_STRING }, /* extract files to this directory */ { NULL, 'l', RTGETOPT_REQ_NOTHING }, /* list archive files (short format) */ { NULL, 'p', RTGETOPT_REQ_NOTHING }, /* extract files to stdout */ { NULL, 't', RTGETOPT_REQ_NOTHING }, /* test archive files */ { NULL, 'v', RTGETOPT_REQ_NOTHING }, /* verbose */ /* modifiers */ { NULL, 'a', RTGETOPT_REQ_NOTHING }, /* convert text files */ { NULL, 'b', RTGETOPT_REQ_NOTHING }, /* no conversion, treat as binary */ { NULL, 'D', RTGETOPT_REQ_NOTHING }, /* don't restore timestamps for directories (and files) */ }; RTGETOPTSTATE GetState; int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOpt failed: %Rrc", rc); RTZIPUNZIPCMDOPS Opts; RT_ZERO(Opts); RTGETOPTUNION ValueUnion; while ( (rc = RTGetOpt(&GetState, &ValueUnion)) != 0 && rc != VINF_GETOPT_NOT_OPTION) { switch (rc) { case 'd': if (Opts.pszDirectory) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "You may only specify -d once"); Opts.pszDirectory = ValueUnion.psz; break; case 'D': if (!Opts.fNoModTimeDirectories) Opts.fNoModTimeDirectories = true; /* -D */ else Opts.fNoModTimeFiles = true; /* -DD */ break; case 'l': case 't': /* treat 'test' like 'list' */ if (Opts.iOperation) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Conflicting unzip operation (%s already set, now %s)", Opts.pszOperation, ValueUnion.pDef->pszLong); Opts.iOperation = rc; Opts.pszOperation = ValueUnion.pDef->pszLong; break; case 'v': Opts.fVerbose = true; break; default: Opts.pszFile = ValueUnion.psz; return RTGetOptPrintError(rc, &ValueUnion); } } if (rc == VINF_GETOPT_NOT_OPTION) { Assert((unsigned)GetState.iNext - 1 <= cArgs); Opts.pszFile = papszArgs[GetState.iNext - 1]; if ((unsigned)GetState.iNext <= cArgs) { Opts.papszFiles = (const char * const *)&papszArgs[GetState.iNext]; Opts.cFiles = cArgs - GetState.iNext; } } RTFOFF cBytes = 0; uint32_t cFiles = 0; switch (Opts.iOperation) { case 'l': { RTPrintf(" Length Date Time Name\n" "--------- ---------- ----- ----\n"); RTEXITCODE rcExit = rtZipUnzipDoWithMembers(&Opts, rtZipUnzipCmdListCallback, &cFiles, &cBytes); RTPrintf("--------- -------\n" "%9RU64 %u file%s\n", cBytes, cFiles, cFiles != 1 ? "s" : ""); return rcExit; } default: return rtZipUnzipDoWithMembers(&Opts, rtZipUnzipCmdExtractCallback, &cFiles, &cBytes); } return RTEXITCODE_SUCCESS; }
/** * Handles the show sub-command. * * @returns Suitable exit code. * @param pArgs The handler arguments. * @param pDebugger Pointer to the debugger interface. */ static RTEXITCODE handleDebugVM_Show(HandlerArg *pArgs, IMachineDebugger *pDebugger) { /* * Parse arguments and what to show. Order dependent. */ uint32_t fFlags = DEBUGVM_SHOW_FLAGS_HUMAN_READABLE; RTGETOPTSTATE GetState; RTGETOPTUNION ValueUnion; static const RTGETOPTDEF s_aOptions[] = { { "--human-readable", 'H', RTGETOPT_REQ_NOTHING }, { "--sh-export", 'e', RTGETOPT_REQ_NOTHING }, { "--sh-eval", 'E', RTGETOPT_REQ_NOTHING }, { "--cmd-set", 's', RTGETOPT_REQ_NOTHING }, }; int rc = RTGetOptInit(&GetState, pArgs->argc, pArgs->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 2, 0 /*fFlags*/); AssertRCReturn(rc, RTEXITCODE_FAILURE); while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0) { switch (rc) { case 'H': fFlags = (fFlags & ~DEBUGVM_SHOW_FLAGS_FMT_MASK) | DEBUGVM_SHOW_FLAGS_HUMAN_READABLE; break; case 'e': fFlags = (fFlags & ~DEBUGVM_SHOW_FLAGS_FMT_MASK) | DEBUGVM_SHOW_FLAGS_SH_EXPORT; break; case 'E': fFlags = (fFlags & ~DEBUGVM_SHOW_FLAGS_FMT_MASK) | DEBUGVM_SHOW_FLAGS_SH_EVAL; break; case 's': fFlags = (fFlags & ~DEBUGVM_SHOW_FLAGS_FMT_MASK) | DEBUGVM_SHOW_FLAGS_CMD_SET; break; case VINF_GETOPT_NOT_OPTION: { RTEXITCODE rcExit; if (!strcmp(ValueUnion.psz, "log-settings")) { rcExit = handleDebugVM_Show_LogDbgSettings(pDebugger, fFlags); if (rcExit == RTEXITCODE_SUCCESS) rcExit = handleDebugVM_Show_LogRelSettings(pDebugger, fFlags); } else if (!strcmp(ValueUnion.psz, "logdbg-settings")) rcExit = handleDebugVM_Show_LogDbgSettings(pDebugger, fFlags); else if (!strcmp(ValueUnion.psz, "logrel-settings")) rcExit = handleDebugVM_Show_LogRelSettings(pDebugger, fFlags); else rcExit = errorSyntax("The show sub-command has no idea what '%s' might be", ValueUnion.psz); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; break; } default: return errorGetOpt(rc, &ValueUnion); } } return RTEXITCODE_SUCCESS; }
int main(int argc, char **argv) { RTEXITCODE rcExit = RTTestInitAndCreate("tstRTPrfIO", &g_hTest); if (rcExit != RTEXITCODE_SUCCESS) return rcExit; RTTestBanner(g_hTest); /* * Parse arguments */ static const RTGETOPTDEF s_aOptions[] = { { "--test-dir", 'd', RTGETOPT_REQ_STRING }, }; bool fFileOpenCloseTest = true; bool fFileWriteByteTest = true; bool fPathQueryInfoTest = true; //bool fFileTests = true; //bool fDirTests = true; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'd': g_pszTestDir = ValueUnion.psz; break; case 'V': RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "$Revision$\n"); return RTTestSummaryAndDestroy(g_hTest); case 'h': RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "usage: testname [-d <testdir>]\n"); return RTTestSummaryAndDestroy(g_hTest); default: RTTestFailed(g_hTest, "invalid argument"); RTGetOptPrintError(ch, &ValueUnion); return RTTestSummaryAndDestroy(g_hTest); } } /* * Set up and check the prerequisites. */ RTTESTI_CHECK_RC(RTPathJoin(g_szTestFile1, sizeof(g_szTestFile1), g_pszTestDir, "tstRTPrfIO-TestFile1"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathJoin(g_szTestDir1, sizeof(g_szTestDir1), g_pszTestDir, "tstRTPrfIO-TestDir1"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathJoin(g_szNotExitingFile, sizeof(g_szNotExitingFile), g_pszTestDir, "tstRTPrfIO-nonexistent-file"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathJoin(g_szNotExitingDir, sizeof(g_szNotExitingDir), g_pszTestDir, "tstRTPrfIO-nonexistent-dir"), VINF_SUCCESS); RTTESTI_CHECK_RC(RTPathJoin(g_szNotExitingDirFile, sizeof(g_szNotExitingDirFile), g_szNotExitingDir, "nonexistent-file"), VINF_SUCCESS); RTTESTI_CHECK(RTDirExists(g_pszTestDir)); if (RTPathExists(g_szTestDir1)) RTTestFailed(g_hTest, "The primary test directory (%s) already exist, please remove it", g_szTestDir1); if (RTPathExists(g_szTestFile1)) RTTestFailed(g_hTest, "The primary test file (%s) already exist, please remove it", g_szTestFile1); if (RTPathExists(g_szNotExitingFile)) RTTestFailed(g_hTest, "'%s' exists, remove it", g_szNotExitingFile); if (RTPathExists(g_szNotExitingDir)) RTTestFailed(g_hTest, "'%s' exists, remove it", g_szNotExitingDir); if (RTPathExists(g_szNotExitingDirFile)) RTTestFailed(g_hTest, "'%s' exists, remove it", g_szNotExitingDirFile); /* * Do the testing. */ if (RTTestIErrorCount() == 0) { #if 1 if (fPathQueryInfoTest) benchmarkPathQueryInfo(); if (fFileOpenCloseTest) benchmarkFileOpenClose(); #endif if (fFileWriteByteTest) benchmarkFileWriteByte(); //if (fFileTests) // benchmarkFile(); //if (fDirTests) // benchmarkDir(); /* * Cleanup. */ RTFileDelete(g_szTestFile1); RTDirRemoveRecursive(g_szTestDir1, 0); RTTESTI_CHECK(RTDirExists(g_pszTestDir)); RTTESTI_CHECK(!RTPathExists(g_szTestDir1)); RTTESTI_CHECK(!RTPathExists(g_szTestFile1)); } return RTTestSummaryAndDestroy(g_hTest); }
/** * Handles the 'add' command. * * @returns Program exit code. * @param pszArg0 The program name. * @param cArgs The number of arguments to the 'add' command. * @param papszArgs The argument vector, starting after 'add'. */ static RTEXITCODE rtDbgSymCacheCmdAdd(const char *pszArg0, int cArgs, char **papszArgs) { /* * Parse the command line. */ static RTGETOPTDEF const s_aOptions[] = { { "--recursive", 'R', RTGETOPT_REQ_NOTHING }, { "--no-recursive", 'n', RTGETOPT_REQ_NOTHING }, { "--overwrite-on-conflict", 'o', RTGETOPT_REQ_NOTHING }, }; const char *pszCache = NULL; bool fRecursive = false; bool fOverwriteOnConflict = false; RTGETOPTSTATE State; int rc = RTGetOptInit(&State, cArgs, papszArgs, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_OPTS_FIRST); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc", rc); uint32_t cAdded = 0; RTGETOPTUNION ValueUnion; int chOpt; while ((chOpt = RTGetOpt(&State, &ValueUnion)) != 0) { switch (chOpt) { case 'R': fRecursive = true; break; case 'n': fRecursive = false; break; case 'o': fOverwriteOnConflict = true; break; case VINF_GETOPT_NOT_OPTION: /* The first non-option is a cache directory. */ if (!pszCache) { pszCache = ValueUnion.psz; if (!RTPathExists(pszCache)) { rc = RTDirCreate(pszCache, 0755, RTDIRCREATE_FLAGS_NOT_CONTENT_INDEXED_NOT_CRITICAL); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Error creating cache directory '%s': %Rrc", pszCache, rc); } else if (!RTDirExists(pszCache)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Specified cache directory is not a directory: '%s'", pszCache); } /* Subsequent non-options are files to be added to the cache. */ else { RTEXITCODE rcExit = rtDbgSymCacheAddFileOrDir(ValueUnion.psz, pszCache, fRecursive, fOverwriteOnConflict); if (rcExit != RTEXITCODE_FAILURE) return rcExit; } break; case 'h': return rtDbgSymCacheUsage(pszArg0, "add"); case 'V': return rtDbgSymCacheVersion(); default: return RTGetOptPrintError(chOpt, &ValueUnion); } } if (!pszCache) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No cache directory or files to add were specified."); return RTEXITCODE_SUCCESS; }
/** * Handler for the 'add-trusted-publisher' command. */ static RTEXITCODE cmdAddTrustedPublisher(int argc, char **argv) { /* * Parse arguments. */ static const RTGETOPTDEF s_aOptions[] = { { "--root", 'r', RTGETOPT_REQ_STRING }, }; const char *pszRootCert = NULL; const char *pszTrustedCert = NULL; int rc; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0); while ((rc = RTGetOpt(&GetState, &ValueUnion))) { switch (rc) { case 'h': RTPrintf("Usage: VBoxCertUtil add-trusted-publisher [--root <root-cert>] <trusted-cert>\n"); break; case 'V': RTPrintf("%sr%d\n", RTBldCfgVersion(), RTBldCfgRevision()); return RTEXITCODE_SUCCESS; case 'r': if (pszRootCert) return RTMsgErrorExit(RTEXITCODE_SUCCESS, "You've already specified '%s' as root certificate.", pszRootCert); pszRootCert = ValueUnion.psz; break; case VINF_GETOPT_NOT_OPTION: if (pszTrustedCert) return RTMsgErrorExit(RTEXITCODE_SUCCESS, "You've already specified '%s' as trusted certificate.", pszRootCert); pszTrustedCert = ValueUnion.psz; break; default: return RTGetOptPrintError(rc, &ValueUnion); } } if (!pszTrustedCert) return RTMsgErrorExit(RTEXITCODE_SUCCESS, "No trusted certificate specified."); /* * Do the job. */ /** @todo The root-cert part needs to be made more flexible. */ if ( pszRootCert && !addCertToStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, "Root", pszRootCert, CERT_STORE_ADD_NEW)) return RTEXITCODE_FAILURE; if (!addCertToStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, "TrustedPublisher", pszTrustedCert, CERT_STORE_ADD_NEW)) return RTEXITCODE_FAILURE; if (g_cVerbosityLevel > 0) { if (pszRootCert) RTMsgInfo("Successfully added '%s' as root and '%s' as trusted publisher", pszRootCert, pszTrustedCert); else RTMsgInfo("Successfully added '%s' as trusted publisher", pszTrustedCert); } return RTEXITCODE_SUCCESS; }