diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
---|---|---|
committer | <> | 2014-05-08 15:03:54 +0000 |
commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Runtime/tools | |
parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
download | VirtualBox-master.tar.gz |
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Runtime/tools')
-rw-r--r-- | src/VBox/Runtime/tools/Makefile.kmk | 12 | ||||
-rw-r--r-- | src/VBox/Runtime/tools/RTGzip.cpp | 566 | ||||
-rw-r--r-- | src/VBox/Runtime/tools/RTLdrFlt.cpp | 78 | ||||
-rw-r--r-- | src/VBox/Runtime/tools/RTManifest.cpp | 2 | ||||
-rw-r--r-- | src/VBox/Runtime/tools/RTNtDbgHelp.cpp | 380 | ||||
-rw-r--r-- | src/VBox/Runtime/tools/RTRm.cpp | 45 | ||||
-rw-r--r-- | src/VBox/Runtime/tools/RTTar.cpp | 2 |
7 files changed, 910 insertions, 175 deletions
diff --git a/src/VBox/Runtime/tools/Makefile.kmk b/src/VBox/Runtime/tools/Makefile.kmk index 42f24d56..63b93c7f 100644 --- a/src/VBox/Runtime/tools/Makefile.kmk +++ b/src/VBox/Runtime/tools/Makefile.kmk @@ -4,7 +4,7 @@ # # -# Copyright (C) 2006-2012 Oracle Corporation +# Copyright (C) 2006-2013 Oracle Corporation # # This file is part of VirtualBox Open Source Edition (OSE), as # available from http://www.virtualbox.org. This file is free software; @@ -36,6 +36,11 @@ bldRTManifest_SOURCES = RTManifest.cpp ifndef VBOX_ONLY_EXTPACKS_USE_IMPLIBS # RTManifest is a tool for creating and verifying manifest files. + PROGRAMS += RTRm + RTRm_TEMPLATE = VBOXR3TSTEXE + RTRm_SOURCES = RTRm.cpp + + # RTManifest is a tool for creating and verifying manifest files. PROGRAMS += RTManifest RTManifest_TEMPLATE = VBOXR3TSTEXE RTManifest_SOURCES = RTManifest.cpp @@ -60,6 +65,11 @@ ifndef VBOX_ONLY_EXTPACKS_USE_IMPLIBS RTTar_TEMPLATE = VBOXR3TSTEXE RTTar_SOURCES = RTTar.cpp + # RTNtDbgHelp - our tar clone (for testing the tar/gzip/gunzip streaming code) + PROGRAMS.win += RTNtDbgHelp + RTNtDbgHelp_TEMPLATE = VBOXR3TSTEXE + RTNtDbgHelp_SOURCES = RTNtDbgHelp.cpp + endif # !VBOX_ONLY_EXTPACKS_USE_IMPLIBS include $(FILE_KBUILD_SUB_FOOTER) diff --git a/src/VBox/Runtime/tools/RTGzip.cpp b/src/VBox/Runtime/tools/RTGzip.cpp index a30c5871..aedb7d9d 100644 --- a/src/VBox/Runtime/tools/RTGzip.cpp +++ b/src/VBox/Runtime/tools/RTGzip.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -36,15 +36,54 @@ #include <iprt/initterm.h> #include <iprt/message.h> #include <iprt/param.h> +#include <iprt/path.h> #include <iprt/stream.h> #include <iprt/string.h> #include <iprt/vfs.h> #include <iprt/zip.h> -static bool isStdHandleATty(int fd) +/******************************************************************************* +* Structures and Typedefs * +*******************************************************************************/ +/** + * Gzip command options. + */ +typedef struct RTGZIPCMDOPTS { - /** @todo IPRT is missing this */ + bool fAscii; + bool fStdOut; + bool fDecompress; + bool fForce; + bool fKeep; + bool fList; + bool fName; + bool fQuiet; + bool fRecursive; + const char *pszSuff; + bool fTest; + unsigned uLevel; + /** The current output filename (for deletion). */ + char szOutput[RTPATH_MAX]; + /** The current input filename (for deletion and messages). */ + const char *pszInput; +} RTGZIPCMDOPTS; +/** Pointer to GZIP options. */ +typedef RTGZIPCMDOPTS *PRTGZIPCMDOPTS; +/** Pointer to const GZIP options. */ +typedef RTGZIPCMDOPTS const *PCRTGZIPCMDOPTS; + + + +/** + * Checks if the given standard handle is a TTY. + * + * @returns true / false + * @param enmStdHandle The standard handle. + */ +static bool gzipIsStdHandleATty(RTHANDLESTD enmStdHandle) +{ + /** @todo Add isatty() to IPRT. */ return false; } @@ -53,163 +92,334 @@ static bool isStdHandleATty(int fd) * Pushes data from the input to the output I/O streams. * * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE. - * @param hVfsIn The input I/O stream. - * @param hVfsOut The input I/O stream. + * @param hVfsSrc The source I/O stream. + * @param hVfsDst The destination I/O stream. */ -static RTEXITCODE gzipPush(RTVFSIOSTREAM hVfsIn, RTVFSIOSTREAM hVfsOut) +static RTEXITCODE gzipPush(RTVFSIOSTREAM hVfsSrc, RTVFSIOSTREAM hVfsDst) { for (;;) { uint8_t abBuf[_64K]; size_t cbRead; - int rc = RTVfsIoStrmRead(hVfsIn, abBuf, sizeof(abBuf), true /*fBlocking*/, &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(hVfsOut, abBuf, cbRead, true /*fBlocking*/, NULL /*cbWritten*/); + rc = RTVfsIoStrmWrite(hVfsDst, abBuf, cbRead, true /*fBlocking*/, NULL /*cbWritten*/); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsIoStrmWrite failed: %Rrc", rc); } } -static RTEXITCODE gzipCompress(RTVFSIOSTREAM hVfsIn, RTVFSIOSTREAM hVfsOut) -{ - return RTMsgErrorExit(RTEXITCODE_FAILURE, "Compression is not yet implemented, sorry."); -} - -static RTEXITCODE gzipCompressFile(const char *pszFile, bool fStdOut, bool fForce, PRTVFSIOSTREAM phVfsStdOut) +/** + * 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) { - return RTMsgErrorExit(RTEXITCODE_FAILURE, "Compression is not yet implemented, sorry."); -} + /* + * Push bytes, flush and close the streams. + */ + RTEXITCODE rcExit = gzipPush(*phVfsSrc, *phVfsDst); + RTVfsIoStrmRelease(*phVfsSrc); + *phVfsSrc = NIL_RTVFSIOSTREAM; -static RTEXITCODE gzipDecompress(RTVFSIOSTREAM hVfsIn, RTVFSIOSTREAM hVfsOut) -{ - RTEXITCODE rcExit; - RTVFSIOSTREAM hVfsGunzip; - int rc = RTZipGzipDecompressIoStream(hVfsIn, 0 /*fFlags*/, &hVfsGunzip); - if (RT_SUCCESS(rc)) + int rc = RTVfsIoStrmFlush(*phVfsDst); + if (RT_FAILURE(rc)) + 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) { - rcExit = gzipPush(hVfsGunzip, hVfsOut); - RTVfsIoStrmRelease(hVfsGunzip); + 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); + } } - else - rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTZipGzipDecompressIoStream failed: %Rrc", rc); + return rcExit; } /** - * Handles a file on the command line. + * Compresses one stream to another. * - * @returns exit code. - * @param pszFile The file to handle. - * @param fStdOut Whether to output to standard output or not. - * @param fForce Whether to output to or input from terminals. - * @param phVfsStdOut Pointer to the standard out handle. - * (input/output) + * @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 gzipDecompressFile(const char *pszFile, bool fStdOut, bool fForce, PRTVFSIOSTREAM phVfsStdOut) +static RTEXITCODE gzipCompressFile(PRTVFSIOSTREAM phVfsSrc, PCRTGZIPCMDOPTS pOpts, PRTVFSIOSTREAM phVfsDst) { /* - * Open the specified input file. + * Attach the ompressor to the output stream. */ - const char *pszError; - RTVFSIOSTREAM hVfsIn; - int rc = RTVfsChainOpenIoStream(pszFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsIn, &pszError); + RTVFSIOSTREAM hVfsGzip; + int rc = RTZipGzipCompressIoStream(*phVfsDst, 0 /*fFlags*/, pOpts->uLevel, &hVfsGzip); 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 RTMsgErrorExit(RTEXITCODE_FAILURE, "RTZipGzipCompressIoStream failed: %Rrc", rc); + uint32_t cRefs = RTVfsIoStrmRelease(*phVfsDst); + Assert(cRefs > 0); + *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) +{ /* - * Output the output file. + * Attach the decompressor to the input stream. */ - RTVFSIOSTREAM hVfsOut; - char szFinal[RTPATH_MAX]; - if (fStdOut) + RTVFSIOSTREAM hVfsGunzip; + int rc = RTZipGzipDecompressIoStream(*phVfsSrc, 0 /*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; +} + + +/** + * Decompresses 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 gzipDecompressFile(PRTVFSIOSTREAM phVfsSrc, PCRTGZIPCMDOPTS pOpts, PRTVFSIOSTREAM phVfsDst) +{ + RTEXITCODE rcExit = gzipSetupDecompressor(phVfsSrc); + if (rcExit == RTEXITCODE_SUCCESS) + rcExit = gzipPushFlushAndClose(phVfsSrc, pOpts, phVfsDst); + return rcExit; +} + + +/** + * 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) { - if (*phVfsStdOut == NIL_RTVFSIOSTREAM) + for (;;) { - rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, 0 /*fOpen*/, true /*fLeaveOpen*/, phVfsStdOut); + 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, "Failed to set up standard out: %Rrc", rc); + return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsIoStrmRead failed: %Rrc", rc); + if (rc == VINF_EOF && cbRead == 0) + return RTEXITCODE_SUCCESS; } - hVfsOut = *phVfsStdOut; - szFinal[0] = '\0'; - } - else - { - rc = RTStrCopy(szFinal, sizeof(szFinal), pszFile); - /** @todo remove the extension? Or are we supposed - * to get the org name from the gzip stream? */ - return RTMsgErrorExit(RTEXITCODE_FAILURE, "Decompressing to file is not implemented"); } + return rcExit; +} - /* - * Do the decompressing, then flush and close the output stream (unless - * it is stdout). - */ - RTEXITCODE rcExit = gzipDecompress(hVfsIn, hVfsOut); - RTVfsIoStrmRelease(hVfsIn); - rc = RTVfsIoStrmFlush(hVfsOut); - if (RT_FAILURE(rc)) - rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to flush the output file: %Rrc", rc); - RTVfsIoStrmRelease(hVfsOut); - /* - * Remove the input file, if that's the desire of the caller, or - * remove the output file on decompression failure. - */ - if (!fStdOut) +static RTEXITCODE gzipListFile(PRTVFSIOSTREAM phVfsSrc, PCRTGZIPCMDOPTS pOpts) +{ + return RTMsgErrorExit(RTEXITCODE_FAILURE, "Listing has not been implemented"); +} + + +/** + * 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) { - if (rcExit == RTEXITCODE_SUCCESS) + 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) { - rc = RTFileDelete(pszFile); - if (RT_FAILURE(rc)) - rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileDelete failed with %rc: '%s'", rc, pszFile); + /** @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 { - /* should we do this? */ - rc = RTFileDelete(szFinal); + rc = RTStrCat(pOpts->szOutput, sizeof(pOpts->szOutput), pOpts->pszSuff); if (RT_FAILURE(rc)) - RTMsgError("RTFileDelete failed with %rc: '%s'", rc, pszFile); + 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 rcExit; + return RTEXITCODE_SUCCESS; } -static RTEXITCODE gzipTestFile(const char *pszFile, bool fForce) +/** + * 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) { - return RTMsgErrorExit(RTEXITCODE_FAILURE, "Testiong has not been implemented"); -} + 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; -static RTEXITCODE gzipListFile(const char *pszFile, bool fForce) -{ - return RTMsgErrorExit(RTEXITCODE_FAILURE, "Listing has not been implemented"); } -int main(int argc, char **argv) +/** + * 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) { - int rc = RTR3InitExe(argc, &argv, 0); - if (RT_FAILURE(rc)) - return RTMsgInitFailure(rc); /* * Parse the command line. @@ -222,6 +432,7 @@ int main(int argc, char **argv) { "--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 }, @@ -243,73 +454,83 @@ int main(int argc, char **argv) { "--best", '9', RTGETOPT_REQ_NOTHING } }; - bool fAscii = false; - bool fStdOut = false; - bool fDecompress = false; - bool fForce = false; - bool fList = false; - bool fName = true; - bool fQuiet = false; - bool fRecursive = false; - const char *pszSuff = ".gz"; - bool fTest = false; - unsigned uLevel = 6; + 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; - rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, - RTGETOPTINIT_FLAGS_OPTS_FIRST); + 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; - rc = RTGetOpt(&GetState, &ValueUnion); - switch (rc) + 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; -#if 0 - rc = RTVfsFileFromRTFile(1, - RTFILE_O_WRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE, - true /*fLeaveOpen*/, - &hVfsOut); - - - if (!fForce && isStdHandleATty(fDecompress ? 0 : 1)) - return RTMsgErrorExit(RTEXITCODE_SYNTAX, - "Yeah, right. I'm not %s any compressed data %s the terminal without --force.\n", - fDecompress ? "reading" : "writing", - fDecompress ? "from" : "to"); -#else - rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "reading from standard input has not yet been implemented"); -#endif - return rcExit; - } - + ValueUnion.psz = "-"; + Opts.fStdOut = true; + /* Fall thru. */ case VINF_GETOPT_NOT_OPTION: { - if (!*pszSuff && !fStdOut) + if (!*Opts.pszSuff && !Opts.fStdOut) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --suffix option specified an empty string"); - if (!fStdOut && RTVfsChainIsSpec(ValueUnion.psz)) + if (!Opts.fStdOut && RTVfsChainIsSpec(ValueUnion.psz)) return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Must use standard out with VFS chain specifications"); - - RTEXITCODE rcExit2; - if (fList) - rcExit2 = gzipListFile(ValueUnion.psz, fForce); - else if (fTest) - rcExit2 = gzipTestFile(ValueUnion.psz, fForce); - else if (fDecompress) - rcExit2 = gzipDecompressFile(ValueUnion.psz, fStdOut, fForce, &hVfsStdOut); - else - rcExit2 = gzipCompressFile(ValueUnion.psz, fStdOut, fForce, &hVfsStdOut); + 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; @@ -317,27 +538,31 @@ int main(int argc, char **argv) break; } - case 'a': fAscii = true; break; - case 'c': fStdOut = true; break; - case 'd': fDecompress = true; break; - case 'f': fForce = true; break; - case 'l': fList = true; break; - case 'n': fName = false; break; - case 'N': fName = true; break; - case 'q': fQuiet = true; break; - case 'r': fRecursive = true; break; - case 'S': pszSuff = ValueUnion.psz; break; - case 't': fTest = true; break; - case 'v': fQuiet = false; break; - case '1': uLevel = 1; break; - case '2': uLevel = 2; break; - case '3': uLevel = 3; break; - case '4': uLevel = 4; break; - case '5': uLevel = 5; break; - case '6': uLevel = 6; break; - case '7': uLevel = 7; break; - case '8': uLevel = 8; break; - case '9': uLevel = 9; 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"); @@ -350,8 +575,17 @@ int main(int argc, char **argv) return RTEXITCODE_SUCCESS; default: - return RTGetOptPrintError(rc, &ValueUnion); + return RTGetOptPrintError(chOpt, &ValueUnion); } } } + +int main(int argc, char **argv) +{ + int rc = RTR3InitExe(argc, &argv, 0); + if (RT_FAILURE(rc)) + return RTMsgInitFailure(rc); + return RTZipGzipCmd(argc, argv); +} + diff --git a/src/VBox/Runtime/tools/RTLdrFlt.cpp b/src/VBox/Runtime/tools/RTLdrFlt.cpp index 2f56c3b1..bae231fb 100644 --- a/src/VBox/Runtime/tools/RTLdrFlt.cpp +++ b/src/VBox/Runtime/tools/RTLdrFlt.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -129,19 +129,39 @@ int main(int argc, char **argv) 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 }, - { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, + { "--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; @@ -156,18 +176,46 @@ int main(int argc, char **argv) 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" @@ -176,7 +224,7 @@ int main(int argc, char **argv) return RTEXITCODE_SUCCESS; case 'V': - RTPrintf("$Revision: 78250 $\n"); + RTPrintf("$Revision: 87101 $\n"); return RTEXITCODE_SUCCESS; case VINF_GETOPT_NOT_OPTION: @@ -189,8 +237,26 @@ int main(int argc, char **argv) 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; - rc = RTDbgModCreateFromImage(&hMod, pszModule, NULL, 0 /*fFlags*/); + 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); @@ -339,7 +405,7 @@ int main(int argc, char **argv) */ RTDBGLINE Line; RTINTPTR offLine; - rc = RTDbgAsLineByAddr(hDbgAs, u64Address, &offLine, &Line); + rc = RTDbgAsLineByAddr(hDbgAs, u64Address, &offLine, &Line, NULL); if (RT_SUCCESS(rc)) RTStrmPrintf(pOutput, " %Rbn(%u)", Line.szFilename, Line.uLineNo); diff --git a/src/VBox/Runtime/tools/RTManifest.cpp b/src/VBox/Runtime/tools/RTManifest.cpp index ba67df46..828204d0 100644 --- a/src/VBox/Runtime/tools/RTManifest.cpp +++ b/src/VBox/Runtime/tools/RTManifest.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Runtime/tools/RTNtDbgHelp.cpp b/src/VBox/Runtime/tools/RTNtDbgHelp.cpp new file mode 100644 index 00000000..c20864bf --- /dev/null +++ b/src/VBox/Runtime/tools/RTNtDbgHelp.cpp @@ -0,0 +1,380 @@ +/* $Id: RTNtDbgHelp.cpp $ */ +/** @file + * IPRT - RTNtDbgHelp - Tool for working/exploring DbgHelp.dll. + */ + +/* + * Copyright (C) 2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + + +/******************************************************************************* +* Header Files * +*******************************************************************************/ +#include <Windows.h> +#include <Dbghelp.h> + +#include <iprt/alloca.h> +#include <iprt/dir.h> +#include <iprt/file.h> +#include <iprt/getopt.h> +#include <iprt/env.h> +#include <iprt/initterm.h> +#include <iprt/list.h> +#include <iprt/mem.h> +#include <iprt/message.h> +#include <iprt/path.h> +#include <iprt/stream.h> +#include <iprt/string.h> +#include <iprt/err.h> + +#include <iprt/win/lazy-dbghelp.h> + +#include <iprt/ldrlazy.h> + + +/******************************************************************************* +* Structures and Typedefs * +*******************************************************************************/ +/** + * Debug module record. + * + * Used for dumping the whole context. + */ +typedef struct RTNTDBGHELPMOD +{ + /** The list bits. */ + RTLISTNODE ListEntry; + /** The module address. */ + uint64_t uModAddr; + /** Pointer to the name part of szFullName. */ + char *pszName; + /** The module name. */ + char szFullName[1]; +} RTNTDBGHELPMOD; +/** Pointer to a debug module. */ +typedef RTNTDBGHELPMOD *PRTNTDBGHELPMOD; + + +/******************************************************************************* +* Global Variables * +*******************************************************************************/ +/** Verbosity level. */ +static int g_iOptVerbose = 1; + +/** Fake process handle. */ +static HANDLE g_hFake = (HANDLE)0x1234567; +/** Number of modules in the list. */ +static uint32_t g_cModules = 0; +/** Module list. */ +static RTLISTANCHOR g_ModuleList; +/** Set when initialized, clear until then. Lazy init on first operation. */ +static bool g_fInitialized = false; + +/** The current address register. */ +static uint64_t g_uCurAddress = 0; + + + +/** + * For debug/verbose output. + * + * @param iMin The minimum verbosity level for this message. + * @param pszFormat The format string. + * @param ... The arguments referenced in the format string. + */ +static void infoPrintf(int iMin, const char *pszFormat, ...) +{ + if (g_iOptVerbose >= iMin) + { + va_list va; + va_start(va, pszFormat); + RTPrintf("info: "); + RTPrintfV(pszFormat, va); + va_end(va); + } +} + +static BOOL CALLBACK symDebugCallback64(HANDLE hProcess, ULONG uAction, ULONG64 ullData, ULONG64 ullUserCtx) +{ + NOREF(hProcess); NOREF(ullUserCtx); + switch (uAction) + { + case CBA_DEBUG_INFO: + { + const char *pszMsg = (const char *)(uintptr_t)ullData; + size_t cchMsg = strlen(pszMsg); + if (cchMsg > 0 && pszMsg[cchMsg - 1] == '\n') + RTPrintf("cba_debug_info: %s", pszMsg); + else + RTPrintf("cba_debug_info: %s\n", pszMsg); + return TRUE; + } + + case CBA_DEFERRED_SYMBOL_LOAD_CANCEL: + return FALSE; + + case CBA_EVENT: + return FALSE; + + default: + RTPrintf("cba_???: uAction=%#x ullData=%#llx\n", uAction, ullData); + break; + } + + return FALSE; +} + +/** + * Lazy initialization. + * @returns Exit code with any relevant complaints printed. + */ +static RTEXITCODE ensureInitialized(void) +{ + if (!g_fInitialized) + { + if (!SymInitialize(g_hFake, NULL, FALSE)) + return RTMsgErrorExit(RTEXITCODE_FAILURE, "SymInitialied failed: %u\n", GetLastError()); + if (!SymRegisterCallback64(g_hFake, symDebugCallback64, 0)) + return RTMsgErrorExit(RTEXITCODE_FAILURE, "SymRegisterCallback64 failed: %u\n", GetLastError()); + g_fInitialized = true; + infoPrintf(2, "SymInitialized(,,)\n"); + } + return RTEXITCODE_SUCCESS; +} + + +/** + * Loads the given module, the address is either automatic or a previously given + * one. + * + * @returns Exit code with any relevant complaints printed. + * @param pszFile The file to load. + */ +static RTEXITCODE loadModule(const char *pszFile) +{ + RTEXITCODE rcExit = ensureInitialized(); + if (rcExit != RTEXITCODE_SUCCESS) + return rcExit; + + uint64_t uModAddrReq = g_uCurAddress == 0 ? UINT64_C(0x1000000) * g_cModules : g_uCurAddress; + uint64_t uModAddrGot = SymLoadModuleEx(g_hFake, NULL /*hFile*/, pszFile, NULL /*pszModuleName*/, + uModAddrReq, 0, NULL /*pData*/, 0 /*fFlags*/); + if (uModAddrGot == 0) + return RTMsgErrorExit(RTEXITCODE_FAILURE, "SymLoadModuleEx failed: %u\n", GetLastError()); + + size_t cbFullName = strlen(pszFile) + 1; + PRTNTDBGHELPMOD pMod = (PRTNTDBGHELPMOD)RTMemAlloc(RT_OFFSETOF(RTNTDBGHELPMOD, szFullName[cbFullName + 1])); + memcpy(pMod->szFullName, pszFile, cbFullName); + pMod->pszName = RTPathFilename(pMod->szFullName); + pMod->uModAddr = uModAddrGot; + RTListAppend(&g_ModuleList, &pMod->ListEntry); + infoPrintf(1, "%#018x %s\n", pMod->uModAddr, pMod->pszName); + + return RTEXITCODE_SUCCESS; +} + + +/** + * Translates SYM_TYPE to string. + * + * @returns String. + * @param enmType The symbol type value. + */ +static const char *symTypeName(SYM_TYPE enmType) +{ + switch (enmType) + { + case SymCoff: return "SymCoff"; + case SymCv: return "SymCv"; + case SymPdb: return "SymPdb"; + case SymExport: return "SymExport"; + case SymDeferred: return "SymDeferred"; + case SymSym: return "SymSym"; + case SymDia: return "SymDia"; + case SymVirtual: return "SymVirtual"; + } + static char s_szBuf[32]; + RTStrPrintf(s_szBuf, sizeof(s_szBuf), "Unknown-%#x", enmType); + return s_szBuf; +} + + +/** + * Symbol enumeration callback. + * + * @returns TRUE (continue enum). + * @param pSymInfo The symbol info. + * @param cbSymbol The symbol length (calculated). + * @param pvUser NULL. + */ +static BOOL CALLBACK dumpSymbolCallback(PSYMBOL_INFO pSymInfo, ULONG cbSymbol, PVOID pvUser) +{ + NOREF(pvUser); + RTPrintf(" %#018x LB %#07x %s\n", pSymInfo->Address, cbSymbol, pSymInfo->Name); + return TRUE; +} + +/** + * Dumps all info. + * @returns Exit code with any relevant complaints printed. + */ +static RTEXITCODE dumpAll(void) +{ + RTEXITCODE rcExit = RTEXITCODE_SUCCESS; + PRTNTDBGHELPMOD pMod; + RTListForEach(&g_ModuleList, pMod, RTNTDBGHELPMOD, ListEntry) + { + RTPrintf("*** %#018x - %s ***\n", pMod->uModAddr, pMod->szFullName); + + static const int8_t s_acbVariations[] = { 0, -4, -8, -12, -16, -20, -24, -28, -32, 4, 8, 12, 16, 20, 24, 28, 32 }; + unsigned iVariation = 0; + union + { + IMAGEHLP_MODULE64 ModInfo; + uint8_t abPadding[sizeof(IMAGEHLP_MODULE64) + 64]; + } u; + + BOOL fRc; + do + { + RT_ZERO(u.ModInfo); + u.ModInfo.SizeOfStruct = sizeof(u.ModInfo) + s_acbVariations[iVariation++]; + fRc = SymGetModuleInfo64(g_hFake, pMod->uModAddr, &u.ModInfo); + } while (!fRc && GetLastError() == ERROR_INVALID_PARAMETER && iVariation < RT_ELEMENTS(s_acbVariations)); + + if (fRc) + { + RTPrintf(" BaseOfImage = %#018llx\n", u.ModInfo.BaseOfImage); + RTPrintf(" ImageSize = %#010x\n", u.ModInfo.ImageSize); + RTPrintf(" TimeDateStamp = %#010x\n", u.ModInfo.TimeDateStamp); + RTPrintf(" CheckSum = %#010x\n", u.ModInfo.CheckSum); + RTPrintf(" NumSyms = %#010x (%u)\n", u.ModInfo.NumSyms, u.ModInfo.NumSyms); + RTPrintf(" SymType = %s\n", symTypeName(u.ModInfo.SymType)); + RTPrintf(" ModuleName = %.32s\n", u.ModInfo.ModuleName); + RTPrintf(" ImageName = %.256s\n", u.ModInfo.ImageName); + RTPrintf(" LoadedImageName = %.256s\n", u.ModInfo.LoadedImageName); + RTPrintf(" LoadedPdbName = %.256s\n", u.ModInfo.LoadedPdbName); + RTPrintf(" CVSig = %#010x\n", u.ModInfo.CVSig); + /** @todo CVData. */ + RTPrintf(" PdbSig = %#010x\n", u.ModInfo.PdbSig); + RTPrintf(" PdbSig70 = %RTuuid\n", &u.ModInfo.PdbSig70); + RTPrintf(" PdbAge = %#010x\n", u.ModInfo.PdbAge); + RTPrintf(" PdbUnmatched = %RTbool\n", u.ModInfo.PdbUnmatched); + RTPrintf(" DbgUnmatched = %RTbool\n", u.ModInfo.DbgUnmatched); + RTPrintf(" LineNumbers = %RTbool\n", u.ModInfo.LineNumbers); + RTPrintf(" GlobalSymbols = %RTbool\n", u.ModInfo.GlobalSymbols); + RTPrintf(" TypeInfo = %RTbool\n", u.ModInfo.TypeInfo); + RTPrintf(" SourceIndexed = %RTbool\n", u.ModInfo.SourceIndexed); + RTPrintf(" Publics = %RTbool\n", u.ModInfo.Publics); + } + else + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "SymGetModuleInfo64 failed: %u\n", GetLastError()); + + if (!SymEnumSymbols(g_hFake, pMod->uModAddr, NULL, dumpSymbolCallback, NULL)) + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "SymEnumSymbols failed: %u\n", GetLastError()); + + } + return rcExit; +} + + +int main(int argc, char **argv) +{ + int rc = RTR3InitExe(argc, &argv, 0 /*fFlags*/); + if (RT_FAILURE(rc)) + return RTMsgInitFailure(rc); + + RTListInit(&g_ModuleList); + + /* + * Parse options. + */ + static const RTGETOPTDEF s_aOptions[] = + { + { "--dump-all", 'd', RTGETOPT_REQ_NOTHING }, + { "--load", 'l', RTGETOPT_REQ_STRING }, + { "--set-address", 'a', RTGETOPT_REQ_UINT64 }, +#define OPT_SET_DEBUG_INFO 0x1000 + { "--set-debug-info", OPT_SET_DEBUG_INFO, RTGETOPT_REQ_NOTHING }, + { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, + { "--quiet", 'q', RTGETOPT_REQ_NOTHING }, + }; + + RTEXITCODE rcExit = RTEXITCODE_SUCCESS; + const char *pszOutput = "-"; + + int ch; + RTGETOPTUNION ValueUnion; + RTGETOPTSTATE GetState; + RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, + RTGETOPTINIT_FLAGS_OPTS_FIRST); + while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0) + { + switch (ch) + { + case 'v': + g_iOptVerbose++; + break; + + case 'q': + g_iOptVerbose++; + break; + + case 'l': + rcExit = loadModule(ValueUnion.psz); + break; + + case 'a': + g_uCurAddress = ValueUnion.u64; + break; + + case 'd': + rcExit = dumpAll(); + break; + + case OPT_SET_DEBUG_INFO: + rcExit = ensureInitialized(); + if (rcExit == RTEXITCODE_SUCCESS && !SymSetOptions(SymGetOptions() | SYMOPT_DEBUG)) + rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "SymSetOptions failed: %u\n", GetLastError()); + break; + + + case 'V': + RTPrintf("$Revision: 85818 $"); + break; + + case 'h': + RTPrintf("usage: %s [-v|--verbose] [-q|--quiet] [--set-debug-info] [-a <addr>] [-l <file>] [-d] [...]\n" + " or: %s [-V|--version]\n" + " or: %s [-h|--help]\n", + argv[0], argv[0], argv[0]); + return RTEXITCODE_SUCCESS; + + case VINF_GETOPT_NOT_OPTION: + default: + return RTGetOptPrintError(ch, &ValueUnion); + } + if (rcExit != RTEXITCODE_SUCCESS) + break; + } + return rcExit; +} + diff --git a/src/VBox/Runtime/tools/RTRm.cpp b/src/VBox/Runtime/tools/RTRm.cpp new file mode 100644 index 00000000..3ae187f7 --- /dev/null +++ b/src/VBox/Runtime/tools/RTRm.cpp @@ -0,0 +1,45 @@ +/* $Id: RTRm.cpp $ */ +/** @file + * IPRT - Remove Directory Entries Utility. + */ + +/* + * Copyright (C) 2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + + +/******************************************************************************* +* Header Files * +*******************************************************************************/ +#include <iprt/path.h> +#include <iprt/err.h> +#include <iprt/initterm.h> +#include <iprt/message.h> + + +int main(int argc, char **argv) +{ + int rc = RTR3InitExe(argc, &argv, 0); + if (RT_FAILURE(rc)) + return RTMsgInitFailure(rc); + return RTPathRmCmd(argc, argv); +} + + diff --git a/src/VBox/Runtime/tools/RTTar.cpp b/src/VBox/Runtime/tools/RTTar.cpp index d204db2b..784dfe9b 100644 --- a/src/VBox/Runtime/tools/RTTar.cpp +++ b/src/VBox/Runtime/tools/RTTar.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; |