static RTEXITCODE rtZipUnzipCmdListCallback(PRTZIPUNZIPCMDOPS pOpts, RTVFSOBJ hVfsObj, const char *pszName, RTEXITCODE rcExit, PRTFOFF pcBytes) { RT_NOREF_PV(pOpts); /* * Query all the information. */ RTFSOBJINFO UnixInfo; int rc = RTVfsObjQueryInfo(hVfsObj, &UnixInfo, RTFSOBJATTRADD_UNIX); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsObjQueryInfo returned %Rrc on '%s'", rc, pszName); RTTIME time; if (!RTTimeExplode(&time, &UnixInfo.ModificationTime)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Cannot explode time on '%s'", pszName); RTPrintf("%9RU64 %04d-%02d-%02d %02d:%02d %s\n", UnixInfo.cbObject, time.i32Year, time.u8Month, time.u8MonthDay, time.u8Hour, time.u8Minute, pszName); *pcBytes = UnixInfo.cbObject; return rcExit; }
static RTEXITCODE tstRTPipe4Child(const char *pszPipe) { int rc = RTR3InitExeNoArguments(0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); int64_t iNative; rc = RTStrToInt64Full(pszPipe, 10, &iNative); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrToUInt64Full(%s) -> %Rrc\n", pszPipe, rc); RTPIPE hPipe; rc = RTPipeFromNative(&hPipe, (RTHCINTPTR)iNative, RTPIPE_N_WRITE); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeFromNative(,%s,WRITE) -> %Rrc\n", pszPipe, rc); rc = RTPipeWriteBlocking(hPipe, g_szTest4Message, sizeof(g_szTest4Message) - 1, NULL); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeWriteBlocking() -> %Rrc\n", rc); rc = RTPipeClose(hPipe); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeClose() -> %Rrc\n", rc); return RTEXITCODE_SUCCESS; }
/** * Opens the input archive specified by the options. * * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE + printed message. * @param pOpts The options. * @param phVfsFss Where to return the UNZIP filesystem stream handle. */ static RTEXITCODE rtZipUnzipCmdOpenInputArchive(PRTZIPUNZIPCMDOPS pOpts, PRTVFSFSSTREAM phVfsFss) { /* * Open the input file. */ RTVFSIOSTREAM hVfsIos; const char *pszError; int rc = RTVfsChainOpenIoStream(pOpts->pszFile, RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN, &hVfsIos, &pszError); if (RT_FAILURE(rc)) { if (pszError && *pszError) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsChainOpenIoStream failed with rc=%Rrc:\n" " '%s'\n", " %*s^\n", rc, pOpts->pszFile, pszError - pOpts->pszFile, ""); return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed with %Rrc opening the input archive '%s'", rc, pOpts->pszFile); } rc = RTZipPkzipFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, phVfsFss); RTVfsIoStrmRelease(hVfsIos); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open pkzip filesystem stream: %Rrc", rc); return RTEXITCODE_SUCCESS; }
/** * Adds a directory. * * @returns IPRT status code (fully bitched). * @param pszPath The directory path. * @param pCfg The configuration. */ static int rtDbgSymCacheAddDir(const char *pszPath, PCRTDBGSYMCACHEADDCFG pCfg) { /* * Set up the path buffer, stripping any filter. */ char szPath[RTPATH_MAX]; int rc = RTStrCopy(szPath, sizeof(szPath) - 2, pszPath); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Path too long: '%s'", pszPath); size_t cchPath = strlen(pszPath); if (!cchPath) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Path empty: '%s'", pszPath); if (pCfg->pszFilter) szPath[cchPath - strlen(pCfg->pszFilter)] = '\0'; cchPath = RTPathStripTrailingSlash(szPath); if (!RTPATH_IS_SEP(pszPath[cchPath - 1])) { szPath[cchPath++] = RTPATH_SLASH; szPath[cchPath] = '\0'; } /* * Let the worker do the rest. */ RTDIRENTRYEX DirEntry; return rtDbgSymCacheAddDirWorker(szPath, cchPath, &DirEntry, pCfg); }
/** * Loads the modules. * * @returns RTEXITCODE_SUCCESS on success. */ static RTEXITCODE LoadModules(void) { for (uint32_t i = 0; i < RT_ELEMENTS(g_aModules); i++) { if (g_aModules[i].fPreload) { char szPath[RTPATH_MAX]; int rc = RTPathAppPrivateArch(szPath, sizeof(szPath)); if (RT_SUCCESS(rc)) rc = RTPathAppend(szPath, sizeof(szPath), g_aModules[i].pszName); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAppPrivateArch or RTPathAppend returned %Rrc", rc); void *pvImageBase; RTERRINFOSTATIC ErrInfo; RTErrInfoInitStatic(&ErrInfo); rc = SUPR3LoadModule(szPath, g_aModules[i].pszName, &g_aModules[i].pvImageBase, &ErrInfo.Core); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "SUPR3LoadModule failed for %s (%s): %s (rc=%Rrc)", g_aModules[i].pszName, szPath, ErrInfo.Core.pszMsg, rc); if (g_cVerbose >= 1) RTMsgInfo("Loaded '%s' ('%s') at %p\n", szPath, g_aModules[i].pszName, g_aModules[i].pvImageBase); } } RTStrmFlush(g_pStdOut); return RTEXITCODE_SUCCESS; }
/** * Opens the input file. * * @returns Command exit, error messages written using RTMsg*. * * @param pszFile The input filename. * @param pOpts The options, szOutput will be filled in by this * function on success. * @param phVfsIos Where to return the input stream handle. */ static RTEXITCODE gzipOpenInput(const char *pszFile, PRTGZIPCMDOPTS pOpts, PRTVFSIOSTREAM phVfsIos) { int rc; pOpts->pszInput = pszFile; if (!strcmp(pszFile, "-")) { if ( !pOpts->fForce && pOpts->fDecompress && gzipIsStdHandleATty(RTHANDLESTD_OUTPUT)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Yeah, right. I'm not reading any compressed data from the terminal without --force.\n"); rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_INPUT, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE, true /*fLeaveOpen*/, phVfsIos); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening standard input: %Rrc", rc); } else { uint32_t offError = 0; RTERRINFOSTATIC ErrInfo; rc = RTVfsChainOpenIoStream(pszFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, phVfsIos, &offError, RTErrInfoInitStatic(&ErrInfo)); if (RT_FAILURE(rc)) return RTVfsChainMsgErrorExitFailure("RTVfsChainOpenIoStream", pszFile, rc, offError, &ErrInfo.Core); } return RTEXITCODE_SUCCESS; }
/** * Handler for the 'display-all' command. */ static RTEXITCODE cmdDisplayAll(int argc, char **argv) { if (argc != 1) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "the display-all command takes no arguments\n"); if (!CertEnumSystemStoreLocation(0, NULL /*pvArg*/, displaySystemStoreLocation)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "CertEnumSystemStoreLocation failed: %s\n", errorToString(GetLastError())); return RTEXITCODE_SUCCESS; }
int main(int argc, char **argv) { RTR3InitExeNoArguments(0); if (argc != 1) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "This utility takes no arguments\n"); NOREF(argv); int rc = SUPR3Uninstall(); if (RT_SUCCESS(rc)) { RTMsgInfo("uninstalled successfully"); return RTEXITCODE_SUCCESS; } return RTMsgErrorExit(RTEXITCODE_FAILURE, "uninstallation failed. rc=%Rrc", rc); }
static RTEXITCODE rtZipUnzipCmdExtractCallback(PRTZIPUNZIPCMDOPS pOpts, RTVFSOBJ hVfsObj, const char *pszName, RTEXITCODE rcExit, PRTFOFF pcBytes) { if (pOpts->fVerbose) RTPrintf("%s\n", pszName); /* * Query all the information. */ RTFSOBJINFO UnixInfo; int rc = RTVfsObjQueryInfo(hVfsObj, &UnixInfo, RTFSOBJATTRADD_UNIX); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsObjQueryInfo returned %Rrc on '%s'", rc, pszName); *pcBytes = UnixInfo.cbObject; char szDst[RTPATH_MAX]; rc = RTPathJoin(szDst, sizeof(szDst), pOpts->pszDirectory ? pOpts->pszDirectory : ".", pszName); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Failed to construct destination path for: %Rrc", pszName, rc); /* * Extract according to the type. */ switch (UnixInfo.Attr.fMode & RTFS_TYPE_MASK) { case RTFS_TYPE_FILE: return rtZipUnzipCmdExtractFile(pOpts, hVfsObj, rcExit, szDst, &UnixInfo); case RTFS_TYPE_DIRECTORY: rc = RTDirCreateFullPath(szDst, UnixInfo.Attr.fMode & RTFS_UNIX_ALL_ACCESS_PERMS); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error creating directory: %Rrc", szDst, rc); break; default: return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Unknown file type.", pszName); } if (!pOpts->fNoModTimeDirectories) { rc = RTPathSetTimesEx(szDst, NULL, &UnixInfo.ModificationTime, NULL, NULL, RTPATH_F_ON_LINK); if (RT_FAILURE(rc) && rc != VERR_NOT_SUPPORTED && rc != VERR_NS_SYMLINK_SET_TIME) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error changing modification time: %Rrc.", pszName, rc); } return rcExit; }
/** * Adds a file or directory. * * @returns Program exit code. * @param pszPath The user supplied path to the file or directory. * @param pszCache The path to the cache. * @param fRecursive Whether to process directories recursively. * @param fOverwriteOnConflict Whether to overwrite existing cache entry on * conflict, or just leave it. */ static RTEXITCODE rtDbgSymCacheAddFileOrDir(const char *pszPath, const char *pszCache, bool fRecursive, bool fOverwriteOnConflict) { RT_NOREF1(fOverwriteOnConflict); RTDBGSYMCACHEADDCFG Cfg; Cfg.fRecursive = fRecursive; Cfg.pszCache = pszCache; Cfg.pszFilter = NULL; int rc; RTDBGSYMCACHEFILETYPE enmType = rtDbgSymCacheFigureType(pszPath); switch (enmType) { default: case RTDBGSYMCACHEFILETYPE_INVALID: return RTMsgErrorExit(RTEXITCODE_FAILURE, "Invalid: '%s'", pszPath); case RTDBGSYMCACHEFILETYPE_DIR_FILTER: Cfg.pszFilter = RTPathFilename(pszPath); /* fall thru */ case RTDBGSYMCACHEFILETYPE_DIR: rc = rtDbgSymCacheAddDir(pszPath, &Cfg); break; case RTDBGSYMCACHEFILETYPE_DEBUG_FILE: rc = rtDbgSymCacheAddDebugFile(pszPath, &Cfg); break; case RTDBGSYMCACHEFILETYPE_IMAGE_FILE: rc = rtDbgSymCacheAddImageFile(pszPath, NULL /*pszExtraSuff*/, RTDBG_CACHE_UUID_MAP_DIR_IMAGES, &Cfg); break; case RTDBGSYMCACHEFILETYPE_DEBUG_BUNDLE: case RTDBGSYMCACHEFILETYPE_IMAGE_BUNDLE: { size_t cchPath = strlen(pszPath); size_t cchFilename = strlen(RTPathFilename(pszPath)); char szPathBuf[RTPATH_MAX]; if (cchPath < sizeof(szPathBuf)) { memcpy(szPathBuf, pszPath, cchPath + 1); if (enmType == RTDBGSYMCACHEFILETYPE_DEBUG_BUNDLE) rc = rtDbgSymCacheAddDebugBundle(szPathBuf, cchPath - cchFilename, cchFilename, &Cfg); else { RTDIRENTRYEX DirEntry; rc = rtDbgSymCacheAddImageBundle(szPathBuf, cchPath - cchFilename, cchFilename, &DirEntry, &Cfg); } } else rc = RTMsgErrorRc(VERR_FILENAME_TOO_LONG, "Filename too long: '%s'", pszPath); break; } case RTDBGSYMCACHEFILETYPE_IGNORE: rc = RTMsgErrorRc(VERR_INVALID_PARAMETER, "Invalid file: '%s'", pszPath); break; } return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; }
/** * Attach a decompressor to the given source stream, replacing and releasing the * input handle with the decompressor. * * @returns Exit code. * @param phVfsSrc The input stream. Replaced on success. */ static RTEXITCODE gzipSetupDecompressor(PRTVFSIOSTREAM phVfsSrc) { /* * Attach the decompressor to the input stream. */ uint32_t fFlags = 0; fFlags |= RTZIPGZIPDECOMP_F_ALLOW_ZLIB_HDR; RTVFSIOSTREAM hVfsGunzip; int rc = RTZipGzipDecompressIoStream(*phVfsSrc, fFlags, &hVfsGunzip); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTZipGzipDecompressIoStream failed: %Rrc", rc); uint32_t cRefs = RTVfsIoStrmRelease(*phVfsSrc); Assert(cRefs > 0); RT_NOREF_PV(cRefs); *phVfsSrc = hVfsGunzip; #if 0 /* This is a good place for testing stuff. */ rc = RTVfsCreateReadAheadForIoStream(*phVfsSrc, 0, 16, _4K+1, &hVfsGunzip); AssertRC(rc); if (RT_SUCCESS(rc)) { uint32_t cRefs = RTVfsIoStrmRelease(*phVfsSrc); Assert(cRefs > 0); *phVfsSrc = hVfsGunzip; } #endif return RTEXITCODE_SUCCESS; }
/** * Pushes data from the input to the output I/O streams. * * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE. * @param hVfsSrc The source I/O stream. * @param hVfsDst The destination I/O stream. */ static RTEXITCODE gzipPush(RTVFSIOSTREAM hVfsSrc, RTVFSIOSTREAM hVfsDst) { for (;;) { uint8_t abBuf[_64K]; size_t cbRead; int rc = RTVfsIoStrmRead(hVfsSrc, abBuf, sizeof(abBuf), true /*fBlocking*/, &cbRead); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsIoStrmRead failed: %Rrc", rc); if (rc == VINF_EOF && cbRead == 0) return RTEXITCODE_SUCCESS; rc = RTVfsIoStrmWrite(hVfsDst, abBuf, cbRead, true /*fBlocking*/, NULL /*cbWritten*/); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsIoStrmWrite failed: %Rrc", rc); } }
/** * Opens the output file. * * @returns Command exit, error messages written using RTMsg*. * * @param pszFile The input filename. * @param pOpts The options, szOutput will be filled in by this * function on success. * @param phVfsIos Where to return the output stream handle. * * @remarks This is actually not quite the way we need to do things. * * First of all, we need a GZIP file system stream for a real GZIP * implementation, since there may be more than one file in the gzipped * file. * * Second, we need to open the output files as we encounter files in the input * file system stream. The gzip format contains timestamp and usually a * filename, the default is to use this name (see the --no-name * option). */ static RTEXITCODE gzipOpenOutput(const char *pszFile, PRTGZIPCMDOPTS pOpts, PRTVFSIOSTREAM phVfsIos) { int rc; if (!strcmp(pszFile, "-") || pOpts->fStdOut) { strcpy(pOpts->szOutput, "-"); if ( !pOpts->fForce && !pOpts->fDecompress && gzipIsStdHandleATty(RTHANDLESTD_OUTPUT)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Yeah, right. I'm not writing any compressed data to the terminal without --force.\n"); rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, RTFILE_O_WRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE, true /*fLeaveOpen*/, phVfsIos); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening standard output: %Rrc", rc); } else { Assert(!RTVfsChainIsSpec(pszFile)); /* Construct an output filename. */ rc = RTStrCopy(pOpts->szOutput, sizeof(pOpts->szOutput), pszFile); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error constructing output filename: %Rrc", rc); if (pOpts->fDecompress) { /** @todo take filename from archive? */ size_t cchSuff = strlen(pOpts->pszSuff); Assert(cchSuff > 0); size_t cch = strlen(pOpts->szOutput); if ( cch <= cchSuff || strcmp(&pOpts->szOutput[cch - cchSuff], pOpts->pszSuff)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Input file does not end with: '%s'", pOpts->pszSuff); pOpts->szOutput[cch - cchSuff] = '\0'; if (!RTPathFilename(pOpts->szOutput)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error constructing output filename: Input file name is all suffix."); } else { rc = RTStrCat(pOpts->szOutput, sizeof(pOpts->szOutput), pOpts->pszSuff); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error constructing output filename: %Rrc", rc); } /* Open the output file. */ uint32_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_WRITE; if (pOpts->fForce) fOpen |= RTFILE_O_CREATE_REPLACE; else fOpen |= RTFILE_O_CREATE; rc = RTVfsIoStrmOpenNormal(pOpts->szOutput, fOpen, phVfsIos); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening output file '%s': %Rrc", pOpts->szOutput, rc); } return RTEXITCODE_SUCCESS; }
/** @todo Get rid of this and VBoxServiceArgUInt32() as soon as we have RTOpt handling. */ int VBoxServiceArgString(int argc, char **argv, const char *psz, int *pi, char *pszBuf, size_t cbBuf) { AssertPtrReturn(pszBuf, VERR_INVALID_POINTER); AssertPtrReturn(cbBuf, VERR_INVALID_PARAMETER); if (*psz == ':' || *psz == '=') psz++; if (!*psz) { if (*pi + 1 >= argc) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing string for the '%s' argument\n", argv[*pi]); psz = argv[++*pi]; } if (!RTStrPrintf(pszBuf, cbBuf, "%s", psz)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "String for '%s' argument too big\n", argv[*pi]); return 0; }
/** * Extracts a file. */ static RTEXITCODE rtZipUnzipCmdExtractFile(PRTZIPUNZIPCMDOPS pOpts, RTVFSOBJ hVfsObj, RTEXITCODE rcExit, const char *pszDst, PCRTFSOBJINFO pUnixInfo) { /* * Open the destination file and create a stream object for it. */ uint32_t fOpen = RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_ACCESS_ATTR_DEFAULT | (pUnixInfo->Attr.fMode << RTFILE_O_CREATE_MODE_SHIFT); RTFILE hFile; int rc = RTFileOpen(&hFile, pszDst, fOpen); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error creating file: %Rrc", pszDst, rc); RTVFSIOSTREAM hVfsIosDst; rc = RTVfsIoStrmFromRTFile(hFile, fOpen, true /*fLeaveOpen*/, &hVfsIosDst); if (RT_SUCCESS(rc)) { /* * Pump the data thru. */ RTVFSIOSTREAM hVfsIosSrc = RTVfsObjToIoStream(hVfsObj); rc = RTVfsUtilPumpIoStreams(hVfsIosSrc, hVfsIosDst, (uint32_t)RT_MIN(pUnixInfo->cbObject, _1M)); if (RT_SUCCESS(rc)) { /* * Correct the file mode and other attributes. */ if (!pOpts->fNoModTimeFiles) { rc = RTFileSetTimes(hFile, NULL, &pUnixInfo->ModificationTime, NULL, NULL); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error setting times: %Rrc", pszDst, rc); } } else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error writing out file: %Rrc", pszDst, rc); RTVfsIoStrmRelease(hVfsIosSrc); RTVfsIoStrmRelease(hVfsIosDst); } else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "%s: Error creating I/O stream for file: %Rrc", pszDst, rc); return rcExit; }
/** * Gets a 32-bit value argument. * @todo Get rid of this and VBoxServiceArgString() as soon as we have RTOpt handling. * * @returns 0 on success, non-zero exit code on error. * @param argc The argument count. * @param argv The argument vector * @param psz Where in *pi to start looking for the value argument. * @param pi Where to find and perhaps update the argument index. * @param pu32 Where to store the 32-bit value. * @param u32Min The minimum value. * @param u32Max The maximum value. */ int VBoxServiceArgUInt32(int argc, char **argv, const char *psz, int *pi, uint32_t *pu32, uint32_t u32Min, uint32_t u32Max) { if (*psz == ':' || *psz == '=') psz++; if (!*psz) { if (*pi + 1 >= argc) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing value for the '%s' argument\n", argv[*pi]); psz = argv[++*pi]; } char *pszNext; int rc = RTStrToUInt32Ex(psz, &pszNext, 0, pu32); if (RT_FAILURE(rc) || *pszNext) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Failed to convert interval '%s' to a number\n", psz); if (*pu32 < u32Min || *pu32 > u32Max) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The timesync interval of %RU32 seconds is out of range [%RU32..%RU32]\n", *pu32, u32Min, u32Max); return 0; }
/** * Pushes the bytes from the input to the output stream, flushes the output * stream and closes both of them. * * On failure, we will delete the output file, if it's a file. The input file * may be deleted, if we're not told to keep it (--keep, --to-stdout). * * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE. * @param phVfsSrc The input stream. Set to NIL if closed. * @param pOpts The options. * @param phVfsDst The output stream. Set to NIL if closed. */ static RTEXITCODE gzipPushFlushAndClose(PRTVFSIOSTREAM phVfsSrc, PCRTGZIPCMDOPTS pOpts, PRTVFSIOSTREAM phVfsDst) { /* * Push bytes, flush and close the streams. */ RTEXITCODE rcExit = gzipPush(*phVfsSrc, *phVfsDst); RTVfsIoStrmRelease(*phVfsSrc); *phVfsSrc = NIL_RTVFSIOSTREAM; int rc = RTVfsIoStrmFlush(*phVfsDst); if (RT_FAILURE(rc) && rc != VERR_INVALID_PARAMETER) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to flush the output file: %Rrc", rc); RTVfsIoStrmRelease(*phVfsDst); *phVfsDst = NIL_RTVFSIOSTREAM; /* * Do the cleaning up, if needed. Remove the input file, if that's the * desire of the user, or remove the output file on failure. */ if (!pOpts->fStdOut) { if (rcExit == RTEXITCODE_SUCCESS) { if (!pOpts->fKeep) { rc = RTFileDelete(pOpts->pszInput); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to delete '%s': %Rrc", pOpts->pszInput, rc); } } else { rc = RTFileDelete(pOpts->szOutput); if (RT_FAILURE(rc)) RTMsgError("Failed to delete '%s': %Rrc", pOpts->szOutput, rc); } } return rcExit; }
/** * Opens the input file. * * @returns Command exit, error messages written using RTMsg*. * * @param pszFile The input filename. * @param pOpts The options, szOutput will be filled in by this * function on success. * @param phVfsIos Where to return the input stream handle. */ static RTEXITCODE gzipOpenInput(const char *pszFile, PRTGZIPCMDOPTS pOpts, PRTVFSIOSTREAM phVfsIos) { int rc; pOpts->pszInput = pszFile; if (!strcmp(pszFile, "-")) { if ( !pOpts->fForce && pOpts->fDecompress && gzipIsStdHandleATty(RTHANDLESTD_OUTPUT)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Yeah, right. I'm not reading any compressed data from the terminal without --force.\n"); rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_INPUT, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE, true /*fLeaveOpen*/, phVfsIos); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening standard input: %Rrc", rc); } else { const char *pszError; rc = RTVfsChainOpenIoStream(pszFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, phVfsIos, &pszError); if (RT_FAILURE(rc)) { if (pszError && *pszError) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsChainOpenIoStream failed with rc=%Rrc:\n" " '%s'\n" " %*s^\n", rc, pszFile, pszError - pszFile, ""); return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsChainOpenIoStream failed with rc=%Rrc: '%s'", rc, pszFile); } } return RTEXITCODE_SUCCESS; }
/** * 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) { RTR3InitExeNoArguments(0); if (argc != 1) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "This utility takes no arguments"); NOREF(argv); int rc = SUPR3Install(); if (RT_SUCCESS(rc)) { if (rc == VINF_SUCCESS) RTMsgInfo("Installed successfully!"); else if (rc == VINF_ALREADY_INITIALIZED) RTMsgInfo("Already loaded."); else if (rc == VWRN_ALREADY_EXISTS) RTMsgInfo("Service already existed; started successfully."); else RTMsgInfo("Unexpected status: %Rrc", rc); return RTEXITCODE_SUCCESS; } return RTMsgErrorExit(RTEXITCODE_FAILURE, "installation failed. rc=%Rrc", rc); }
static RTEXITCODE gzipDecompress(RTVFSIOSTREAM hVfsIn, RTVFSIOSTREAM hVfsOut) { RTEXITCODE rcExit; RTVFSIOSTREAM hVfsGunzip; int rc = RTZipGzipDecompressIoStream(hVfsIn, 0 /*fFlags*/, &hVfsGunzip); if (RT_SUCCESS(rc)) { rcExit = gzipPush(hVfsGunzip, hVfsOut); RTVfsIoStrmRelease(hVfsGunzip); } else rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTZipGzipDecompressIoStream failed: %Rrc", rc); return rcExit; }
/** * errorSyntax for RTGetOpt users. * * @returns RTEXITCODE_SYNTAX. * * @param fCategory The usage category of the command. * @param fSubCategory The usage sub-category of the command. * @param rc The RTGetOpt return code. * @param pValueUnion The value union. */ RTEXITCODE errorGetOptEx(USAGECATEGORY fCategory, uint32_t fSubCategory, int rc, union RTGETOPTUNION const *pValueUnion) { /* * Check if it is an unhandled standard option. */ if (rc == 'V') { RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision()); return RTEXITCODE_SUCCESS; } if (rc == 'h') { showLogo(g_pStdErr); #ifndef VBOX_ONLY_DOCS if (g_fInternalMode) printUsageInternal(fCategory, g_pStdOut); else printUsage(fCategory, fSubCategory, g_pStdOut); #endif return RTEXITCODE_SUCCESS; } /* * General failure. */ showLogo(g_pStdErr); // show logo even if suppressed #ifndef VBOX_ONLY_DOCS if (g_fInternalMode) printUsageInternal(fCategory, g_pStdErr); else printUsage(fCategory, fSubCategory, g_pStdErr); #endif /* !VBOX_ONLY_DOCS */ if (rc == VINF_GETOPT_NOT_OPTION) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid parameter '%s'", pValueUnion->psz); if (rc > 0) { if (RT_C_IS_PRINT(rc)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid option -%c", rc); return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid option case %i", rc); } if (rc == VERR_GETOPT_UNKNOWN_OPTION) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option: %s", pValueUnion->psz); if (rc == VERR_GETOPT_INVALID_ARGUMENT_FORMAT) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Invalid argument format: %s", pValueUnion->psz); if (pValueUnion->pDef) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "%s: %Rrs", pValueUnion->pDef->pszLong, rc); return RTMsgErrorExit(RTEXITCODE_SYNTAX, "%Rrs", rc); }
/** * Compresses one stream to another. * * @returns Exit code. * @param phVfsSrc The input stream. Set to NIL if closed. * @param pOpts The options. * @param phVfsDst The output stream. Set to NIL if closed. */ static RTEXITCODE gzipCompressFile(PRTVFSIOSTREAM phVfsSrc, PCRTGZIPCMDOPTS pOpts, PRTVFSIOSTREAM phVfsDst) { /* * Attach the ompressor to the output stream. */ RTVFSIOSTREAM hVfsGzip; int rc = RTZipGzipCompressIoStream(*phVfsDst, 0 /*fFlags*/, pOpts->uLevel, &hVfsGzip); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTZipGzipCompressIoStream failed: %Rrc", rc); uint32_t cRefs = RTVfsIoStrmRelease(*phVfsDst); Assert(cRefs > 0); RT_NOREF_PV(cRefs); *phVfsDst = hVfsGzip; return gzipPushFlushAndClose(phVfsSrc, pOpts, phVfsDst); }
/** * Attach a decompressor to the given source stream, replacing and releasing the * input handle with the decompressor. * * @returns Exit code. * @param phVfsSrc The input stream. Replaced on success. */ static RTEXITCODE gzipSetupDecompressor(PRTVFSIOSTREAM phVfsSrc) { /* * Attach the decompressor to the input stream. */ uint32_t fFlags = 0; fFlags |= RTZIPGZIPDECOMP_F_ALLOW_ZLIB_HDR; RTVFSIOSTREAM hVfsGunzip; int rc = RTZipGzipDecompressIoStream(*phVfsSrc, fFlags, &hVfsGunzip); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTZipGzipDecompressIoStream failed: %Rrc", rc); uint32_t cRefs = RTVfsIoStrmRelease(*phVfsSrc); Assert(cRefs > 0); *phVfsSrc = hVfsGunzip; return RTEXITCODE_SUCCESS; }
/** * For testing the archive (todo). * * @returns Exit code. * @param phVfsSrc The input stream. Set to NIL if closed. * @param pOpts The options. */ static RTEXITCODE gzipTestFile(PRTVFSIOSTREAM phVfsSrc, PCRTGZIPCMDOPTS pOpts) { /* * Read the whole stream. */ RTEXITCODE rcExit = gzipSetupDecompressor(phVfsSrc); if (rcExit == RTEXITCODE_SUCCESS) { for (;;) { uint8_t abBuf[_64K]; size_t cbRead; int rc = RTVfsIoStrmRead(*phVfsSrc, abBuf, sizeof(abBuf), true /*fBlocking*/, &cbRead); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsIoStrmRead failed: %Rrc", rc); if (rc == VINF_EOF && cbRead == 0) return RTEXITCODE_SUCCESS; } } return rcExit; }
static RTEXITCODE tstRTPipe5Child(const char *pszPipe) { int rc = RTR3InitExeNoArguments(0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); int64_t iNative; rc = RTStrToInt64Full(pszPipe, 10, &iNative); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrToUInt64Full(%s) -> %Rrc\n", pszPipe, rc); RTPIPE hPipe; rc = RTPipeFromNative(&hPipe, (RTHCINTPTR)iNative, RTPIPE_N_READ); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeFromNative(,%s,READ) -> %Rrc\n", pszPipe, rc); /// char szTmp[1024]; size_t cbRead = 0; rc = RTPipeReadBlocking(hPipe, szTmp, sizeof(szTmp) - 1, &cbRead); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeReadBlocking() -> %Rrc\n", rc); szTmp[cbRead] = '\0'; size_t cbRead2; char szTmp2[4]; rc = RTPipeReadBlocking(hPipe, szTmp2, sizeof(szTmp2), &cbRead2); if (rc != VERR_BROKEN_PIPE) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeReadBlocking() -> %Rrc instead of VERR_BROKEN_PIPE\n", rc); rc = RTPipeClose(hPipe); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeClose() -> %Rrc\n", rc); if (memcmp(szTmp, g_szTest5Message, sizeof(g_szTest5Message))) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Message mismatch.\n:Expected '%s'\nGot '%s'\n", g_szTest5Message, szTmp); return RTEXITCODE_SUCCESS; }
/** * 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; }
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) { int rc = RTR3InitExe(argc, &argv, 0); if (RT_FAILURE(rc)) return RTMsgInitFailure(rc); /* * The first argument is a command. Figure out which and call its handler. */ static const struct { const char *pszCommand; RTEXITCODE (*pfnHandler)(int argc, char **argv); bool fNoArgs; } s_aHandlers[] = { { "cpuvendor", handlerCpuVendor, true }, { "cpuname", handlerCpuName, true }, { "cpurevision", handlerCpuRevision, true }, { "cpuhwvirt", handlerCpuHwVirt, true }, { "nestedpaging", handlerCpuNestedPaging, true }, { "longmode", handlerCpuLongMode, true }, { "memsize", handlerMemSize, true }, { "report", handlerReport, true } }; if (argc < 2) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "expected command as the first argument"); for (unsigned i = 0; i < RT_ELEMENTS(s_aHandlers); i++) { if (!strcmp(argv[1], s_aHandlers[i].pszCommand)) { if ( s_aHandlers[i].fNoArgs && argc != 2) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "the command '%s' does not take any arguments", argv[1]); return s_aHandlers[i].pfnHandler(argc - 1, argv + 1); } } /* * Help or version query? */ for (int i = 1; i < argc; i++) if ( !strcmp(argv[i], "--help") || !strcmp(argv[i], "-h") || !strcmp(argv[i], "-?") || !strcmp(argv[i], "help") ) { RTPrintf("usage: %s <cmd> [cmd specific args]\n" "\n" "commands:\n", argv[0]); for (unsigned j = 0; j < RT_ELEMENTS(s_aHandlers); j++) RTPrintf(" %s\n", s_aHandlers[j].pszCommand); return RTEXITCODE_FAILURE; } else if ( !strcmp(argv[i], "--version") || !strcmp(argv[i], "-V") ) { RTPrintf("%sr%u", RTBldCfgVersion(), RTBldCfgRevision()); return argc == 2 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; } /* * Syntax error. */ return RTMsgErrorExit(RTEXITCODE_SYNTAX, "unknown command '%s'", argv[1]); }