Example #1
0
/**
 * 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;
}
Example #2
0
static void usbTestUsage(PRTSTREAM pStrm)
{
    char szExec[RTPATH_MAX];
    RTStrmPrintf(pStrm, "usage: %s [options]\n",
                 RTPathFilename(RTProcGetExecutablePath(szExec, sizeof(szExec))));
    RTStrmPrintf(pStrm, "\n");
    RTStrmPrintf(pStrm, "options: \n");


    for (unsigned i = 0; i < RT_ELEMENTS(g_aCmdOptions); i++)
    {
        const char *pszHelp;
        switch (g_aCmdOptions[i].iShort)
        {
            case 'h':
                pszHelp = "Displays this help and exit";
                break;
            case 'd':
                pszHelp = "Use the specified test device";
                break;
            default:
                pszHelp = "Option undocumented";
                break;
        }
        char szOpt[256];
        RTStrPrintf(szOpt, sizeof(szOpt), "%s, -%c", g_aCmdOptions[i].pszLong, g_aCmdOptions[i].iShort);
        RTStrmPrintf(pStrm, "  %-20s%s\n", szOpt, pszHelp);
    }
}
Example #3
0
RTR3DECL(int) RTManifestWriteFilesBuf(void **ppvBuf, size_t *pcbSize, RTDIGESTTYPE enmDigestType, PRTMANIFESTTEST paFiles, size_t cFiles)
{
    /* Validate input */
    AssertPtrReturn(ppvBuf, VERR_INVALID_POINTER);
    AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
    AssertPtrReturn(paFiles, VERR_INVALID_POINTER);
    AssertReturn(cFiles > 0, VERR_INVALID_PARAMETER);

    const char *pcszDigestType;
    switch (enmDigestType)
    {
        case RTDIGESTTYPE_CRC32:  pcszDigestType = "CRC32";  break;
        case RTDIGESTTYPE_CRC64:  pcszDigestType = "CRC64";  break;
        case RTDIGESTTYPE_MD5:    pcszDigestType = "MD5";    break;
        case RTDIGESTTYPE_SHA1:   pcszDigestType = "SHA1";   break;
        case RTDIGESTTYPE_SHA256: pcszDigestType = "SHA256"; break;
        default: return VERR_INVALID_PARAMETER;
    }

    /* Calculate the size necessary for the memory buffer. */
    size_t cbSize = 0;
    size_t cbMaxSize = 0;
    for (size_t i = 0; i < cFiles; ++i)
    {
        size_t cbTmp = strlen(RTPathFilename(paFiles[i].pszTestFile))
                     + strlen(paFiles[i].pszTestDigest)
                     + strlen(pcszDigestType)
                     + 6;
        cbMaxSize = RT_MAX(cbMaxSize, cbTmp);
        cbSize += cbTmp;
    }

    /* Create the memory buffer */
    void *pvBuf = RTMemAlloc(cbSize);
    if (!pvBuf)
        return VERR_NO_MEMORY;

    /* Allocate a temporary string buffer. */
    char *pszTmp = RTStrAlloc(cbMaxSize + 1);
    if (!pszTmp)
    {
        RTMemFree(pvBuf);
        return VERR_NO_MEMORY;
    }
    size_t cbPos = 0;

    for (size_t i = 0; i < cFiles; ++i)
    {
        size_t cch = RTStrPrintf(pszTmp, cbMaxSize + 1, "%s (%s)= %s\n", pcszDigestType, RTPathFilename(paFiles[i].pszTestFile), paFiles[i].pszTestDigest);
        memcpy(&((char*)pvBuf)[cbPos], pszTmp, cch);
        cbPos += cch;
    }
    RTStrFree(pszTmp);

    /* Results */
    *ppvBuf = pvBuf;
    *pcbSize = cbSize;

    return VINF_SUCCESS;
}
Example #4
0
/**
 * Extract the extension pack name from the tarball path.
 *
 * @returns String containing the name on success, the caller must delete it.
 *          NULL if no valid name was found or if we ran out of memory.
 * @param   pszTarball          The path to the tarball.
 */
RTCString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball)
{
    /*
     * Skip ahead to the filename part and count the number of characters
     * that matches the criteria for a mangled extension pack name.
     */
    const char *pszSrc = RTPathFilename(pszTarball);
    if (!pszSrc)
        return NULL;

    size_t off = 0;
    while (RT_C_IS_ALNUM(pszSrc[off]) || pszSrc[off] == '_')
        off++;

    /*
     * Check min and max name limits.
     */
    if (   off > VBOX_EXTPACK_NAME_MAX_LEN
        || off < VBOX_EXTPACK_NAME_MIN_LEN)
        return NULL;

    /*
     * Return the unmangled name.
     */
    return VBoxExtPackUnmangleName(pszSrc, off);
}
Example #5
0
/**
 * @callback_method_impl{FNDBGCCMD, The '.injecterror' command.}
 */
static DECLCALLBACK(int) pdmacEpFileErrorInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR pArgs, unsigned cArgs)
{
    /*
     * Validate input.
     */
    DBGC_CMDHLP_REQ_UVM_RET(pCmdHlp, pCmd, pUVM);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER);

    PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
    pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];

    /* Syntax is "read|write <filename> <status code>" */
    bool fWrite;
    if (!RTStrCmp(pArgs[0].u.pszString, "read"))
        fWrite = false;
    else if (!RTStrCmp(pArgs[0].u.pszString, "write"))
        fWrite = true;
    else
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString);

    int32_t rcToInject = (int32_t)pArgs[2].u.u64Number;
    if ((uint64_t)rcToInject != pArgs[2].u.u64Number)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "The status code '%lld' is out of range", pArgs[0].u.u64Number);

    /*
     * Search for the matching endpoint.
     */
    RTCritSectEnter(&pEpClassFile->Core.CritSect);

    PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
    while (pEpFile)
    {
        if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri)))
            break;
        pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
    }

    if (pEpFile)
    {
        /*
         * Do the job.
         */
        if (fWrite)
            ASMAtomicXchgS32(&pEpFile->rcReqWrite, rcToInject);
        else
            ASMAtomicXchgS32(&pEpFile->rcReqRead,  rcToInject);

        DBGCCmdHlpPrintf(pCmdHlp, "Injected %Rrc into '%s' for %s\n",
                         (int)rcToInject, pArgs[1].u.pszString, pArgs[0].u.pszString);
    }

    RTCritSectLeave(&pEpClassFile->Core.CritSect);

    if (!pEpFile)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString);
    return VINF_SUCCESS;
}
Example #6
0
GLboolean renderspu_SystemVBoxCreateWindow(VisualInfo *pVisInfo, GLboolean fShowIt, WindowInfo *pWinInfo)
{
    CRASSERT(pVisInfo);
    CRASSERT(pWinInfo);

    /* VirtualBox is the only frontend which support 3D right now. */
    char pszName[256];
    if (RTProcGetExecutablePath(pszName, sizeof(pszName)))
        /* Check for VirtualBox and VirtualBoxVM */
        if (RTStrNICmp(RTPathFilename(pszName), "VirtualBox", 10) != 0)
            return GL_FALSE;

    pWinInfo->visual = pVisInfo;
    pWinInfo->window = NULL;
    pWinInfo->nativeWindow = NULL;
    pWinInfo->currentCtx = NULL;

#ifdef __LP64__
    NativeNSViewRef pParentWin = (NativeNSViewRef)render_spu_parent_window_id;
#else /* __LP64__ */
    NativeNSViewRef pParentWin = (NativeNSViewRef)(uint32_t)render_spu_parent_window_id;
#endif /* __LP64__ */

    cocoaViewCreate(&pWinInfo->window, pWinInfo, pParentWin, pVisInfo->visAttribs);

    if (fShowIt)
        renderspu_SystemShowWindow(pWinInfo, fShowIt);

    return GL_TRUE;
}
RTDECL(int) RTCrX509Certificate_ReadFromFile(PRTCRX509CERTIFICATE pCertificate, const char *pszFilename, uint32_t fFlags,
                                             PCRTASN1ALLOCATORVTABLE pAllocator, PRTERRINFO pErrInfo)
{
    AssertReturn(!fFlags, VERR_INVALID_FLAGS);
    PCRTCRPEMSECTION pSectionHead;
    int rc = RTCrPemReadFile(pszFilename, 0, g_aCertificateMarkers, RT_ELEMENTS(g_aCertificateMarkers), &pSectionHead, pErrInfo);
    if (RT_SUCCESS(rc))
    {
        RTCRX509CERTIFICATE TmpCert;
        RTASN1CURSORPRIMARY PrimaryCursor;
        RTAsn1CursorInitPrimary(&PrimaryCursor, pSectionHead->pbData, (uint32_t)RT_MIN(pSectionHead->cbData, UINT32_MAX),
                                pErrInfo, pAllocator, RTASN1CURSOR_FLAGS_DER, RTPathFilename(pszFilename));
        rc = RTCrX509Certificate_DecodeAsn1(&PrimaryCursor.Cursor, 0, &TmpCert, "Cert");
        if (RT_SUCCESS(rc))
        {
            rc = RTCrX509Certificate_CheckSanity(&TmpCert, 0, pErrInfo, "Cert");
            if (RT_SUCCESS(rc))
            {
                rc = RTCrX509Certificate_Clone(pCertificate, &TmpCert, &g_RTAsn1DefaultAllocator);
                if (RT_SUCCESS(rc))
                {
                    if (pSectionHead->pNext || PrimaryCursor.Cursor.cbLeft)
                        rc = VINF_ASN1_MORE_DATA;
                }
            }
            RTCrX509Certificate_Delete(&TmpCert);
        }
        RTCrPemFreeSections(pSectionHead);
    }
    return rc;
}
Example #8
0
int main(int argc, char **argv)
{
    RTTEST hTest;
    int rc = RTTestInitAndCreate("tstRTFileGetSize-1", &hTest);
    if (rc)
        return rc;
    RTTestBanner(hTest);

    for (int i = 0; i < argc; i++)
    {
        char *pszNm = RTPathFilename(argv[i]);
        if (!pszNm)
            pszNm = argv[i];
        test1(pszNm, argv[i]);
    }

#ifdef RT_OS_WINDOWS
    test1("//./PhysicalDrive0", "//./PhysicalDrive0");
    test1("//./HarddiskVolume1", "//./HarddiskVolume1");
    test1("//./null", "//./nul");
#else
    test1("/dev/null", "/dev/null");
# ifdef RT_OS_LINUX
    test1("/dev/sda",  "/dev/sda");
    test1("/dev/sda1", "/dev/sda1");
    test1("/dev/sda5", "/dev/sda5");
# endif
#endif

    /*
     * Summary.
     */
    return RTTestSummaryAndDestroy(hTest);
}
Example #9
0
/**
 * 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;
}
Example #10
0
/** Check that the string is an absolute path to a file or print an error. */
bool checkAbsoluteFilePath(const char *pcszName, const char *pcszValue)
{
    if (RTPathFilename(pcszValue) && RTPathStartsWithRoot(pcszValue))
        return true;
    RTStrmPrintf(g_pStdErr, "%s: %s must be an absolute path of a file.\n", pcszName, pcszValue);
    return false;
}
STDMETHODIMP VFSExplorer::Exists(ComSafeArrayIn(IN_BSTR, aNames), ComSafeArrayOut(BSTR, aExists))
{
    CheckComArgSafeArrayNotNull(aNames);

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);

    com::SafeArray<IN_BSTR> sfaNames(ComSafeArrayInArg(aNames));
    std::list<BSTR> listExists;

    for (size_t a=0; a < sfaNames.size(); ++a)
    {
        std::list<VFSExplorer::Data::DirEntry>::const_iterator it;
        for (it = m->entryList.begin();
             it != m->entryList.end();
             ++it)
        {
            const VFSExplorer::Data::DirEntry &entry = (*it);
            if (entry.name == RTPathFilename(Utf8Str(sfaNames[a]).c_str()))
            {
                BSTR name;
                Bstr tmp(sfaNames[a]); /* gcc-3.3 cruft */
                tmp.cloneTo(&name);
                listExists.push_back(name);
            }
        }
    }

    com::SafeArray<BSTR> sfaExists(listExists);
    sfaExists.detachTo(ComSafeArrayOutArg(aExists));

    return S_OK;
}
/**
 * Delay inject callback.
 */
static DECLCALLBACK(int) pdmacEpFileDelayInject(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs)
{
    /*
     * Validate input.
     */
    DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, -1, cArgs == 3);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, pArgs[0].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pArgs[1].enmType == DBGCVAR_TYPE_STRING);
    DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 2, pArgs[2].enmType == DBGCVAR_TYPE_NUMBER);

    PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile;
    pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pVM->pUVM->pdm.s.apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_FILE];

    /* Syntax is "read|write <filename> <status code>" */
    bool fWrite;
    if (!RTStrCmp(pArgs[0].u.pszString, "read"))
        fWrite = false;
    else if (!RTStrCmp(pArgs[0].u.pszString, "write"))
        fWrite = true;
    else
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "invalid transfer direction '%s'", pArgs[0].u.pszString);

    uint32_t msDelay = (uint32_t)pArgs[2].u.u64Number;
    if ((uint64_t)msDelay != pArgs[2].u.u64Number)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "The delay '%lld' is out of range", pArgs[0].u.u64Number);


    /*
     * Search for the matching endpoint.
     */
    RTCritSectEnter(&pEpClassFile->Core.CritSect);

    PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpClassFile->Core.pEndpointsHead;
    while (pEpFile)
    {
        if (!RTStrCmp(pArgs[1].u.pszString, RTPathFilename(pEpFile->Core.pszUri)))
            break;
        pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEpFile->Core.pNext;
    }

    if (pEpFile)
    {
        bool fXchg = ASMAtomicCmpXchgU32(&pEpFile->msDelay, msDelay, 0);

        if (fXchg)
            DBGCCmdHlpPrintf(pCmdHlp, "Injected delay of %u ms into '%s' for %s\n",
                             msDelay, pArgs[1].u.pszString, pArgs[0].u.pszString);
        else
            DBGCCmdHlpPrintf(pCmdHlp, "Another delay for '%s' is still active, ignoring\n",
                             pArgs[1].u.pszString);
    }

    RTCritSectLeave(&pEpClassFile->Core.CritSect);

    if (!pEpFile)
        return DBGCCmdHlpFail(pCmdHlp, pCmd, "No file with name '%s' found", pArgs[1].u.pszString);
    return VINF_SUCCESS;
}
Example #13
0
/**
 * Worker that add the image file to the right place.
 *
 * @returns IPRT status code.
 * @param   pszPath             Path to the image file.
 * @param   pCfg                Configuration data.
 * @param   hLdrMod             Image handle.
 * @param   pszExtraSuff        Optional extra suffix.  Mach-O dSYM hack.
 * @param   pszUuidMapDir       Optional UUID map cache directory if the image
 *                              should be mapped by UUID.
 *                              The map is a Mac OS X debug feature supported by
 *                              the two native debuggers gdb and lldb.  Look for
 *                              descriptions of DBGFileMappedPaths in the
 *                              com.apple.DebugSymbols in the user defaults.
 */
static int rtDbgSymCacheAddImageFileWorker(const char *pszPath, PCRTDBGSYMCACHEADDCFG pCfg, RTLDRMOD hLdrMod,
                                           const char *pszExtrSuff, const char *pszUuidMapDir)
{
    /*
     * Determine which subdirectory to put the files in.
     */
    RTUUID      Uuid;
    PRTUUID     pUuid = NULL;
    int         rc;
    char        szSubDir[48];
    RTLDRFMT    enmFmt = RTLdrGetFormat(hLdrMod);
    switch (enmFmt)
    {
        case RTLDRFMT_MACHO:
        {
            rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_UUID, &Uuid, sizeof(Uuid));
            if (RT_FAILURE(rc))
                return RTMsgErrorRc(rc, "Error quering image UUID from image '%s': %Rrc", pszPath, rc);

            rc = RTUuidToStr(&Uuid, szSubDir, sizeof(szSubDir));
            if (RT_FAILURE(rc))
                return RTMsgErrorRc(rc, "Error convering UUID for image '%s' to string: %Rrc", pszPath, rc);
            pUuid = &Uuid;
            break;
        }

        case RTLDRFMT_PE:
        {
            uint32_t uTimestamp;
            rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &uTimestamp, sizeof(uTimestamp));
            if (RT_FAILURE(rc))
                return RTMsgErrorRc(rc, "Error quering timestamp from image '%s': %Rrc", pszPath, rc);

            size_t cbImage = RTLdrSize(hLdrMod);
            if (cbImage == ~(size_t)0)
                return RTMsgErrorRc(rc, "Error quering size of image '%s': %Rrc", pszPath, rc);

            RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%x", uTimestamp, cbImage);
            break;
        }

        case RTLDRFMT_AOUT:
            return RTMsgErrorRc(VERR_NOT_SUPPORTED, "Caching of a.out image has not yet been implemented: %s", pszPath);
        case RTLDRFMT_ELF:
            return RTMsgErrorRc(VERR_NOT_SUPPORTED, "Caching of ELF image has not yet been implemented: %s", pszPath);
        case RTLDRFMT_LX:
            return RTMsgErrorRc(VERR_NOT_SUPPORTED, "Caching of LX image has not yet been implemented: %s", pszPath);
        default:
            return RTMsgErrorRc(VERR_NOT_SUPPORTED, "Unknown loader format for '%s': %d", pszPath, enmFmt);
    }

    /*
     * Now add it.
     */
    return rtDbgSymCacheAddOneFile(pszPath, RTPathFilename(pszPath), pszExtrSuff,
                                   szSubDir, pUuid, pszUuidMapDir, pCfg);
}
Example #14
0
static int rtCreateTempValidateTemplate(char *pszTemplate, char **ppszX,
                                        unsigned *pcXes)
{
    /*
     * Validate input and count X'es.
     *
     * The X'es may be trailing, or they may be a cluster of 3 or more inside
     * the file name.
     */
    AssertPtr(pszTemplate);
    AssertPtr(ppszX);
    AssertPtr(pcXes);
    unsigned    cXes = 0;
    char       *pszX = strchr(pszTemplate, '\0');
    if (   pszX != pszTemplate
        && pszX[-1] != 'X')
    {
        /* look inside the file name. */
        char *pszFilename = RTPathFilename(pszTemplate);
        if (   pszFilename
            && (size_t)(pszX - pszFilename) > 3)
        {
            char *pszXEnd = pszX - 1;
            pszFilename += 3;
            do
            {
                if (    pszXEnd[-1] == 'X'
                    &&  pszXEnd[-2] == 'X'
                    &&  pszXEnd[-3] == 'X')
                {
                    pszX = pszXEnd - 3;
                    cXes = 3;
                    break;
                }
            } while (pszXEnd-- != pszFilename);
        }
    }

    /* count them */
    while (   pszX != pszTemplate
           && pszX[-1] == 'X')
    {
        pszX--;
        cXes++;
    }

    /* fail if none found. */
    if (!cXes)
    {
        AssertFailed();
        return VERR_INVALID_PARAMETER;
    }
    *ppszX = pszX;
    *pcXes = cXes;
    return VINF_SUCCESS;
}
int main(int argc, char **argv)
{
    RTEXITCODE rcExit = RTTestInitAndCreate(RTPathFilename(argv[0]),
                                            &g_hTest);
    if (rcExit != RTEXITCODE_SUCCESS)
        return rcExit;
    RTTestBanner(g_hTest);
    testAPI(g_hTest);
    return RTTestSummaryAndDestroy(g_hTest);
}
Example #16
0
/**
 * Hack to strip of the architecture subdirectory from the exec dir.
 *
 * @returns See RTPathExecDir.
 * @param   pszPath             See RTPathExecDir.
 * @param   cchPath             See RTPathExecDir.
 */
DECLINLINE(int) rtPathSolarisArchHack(char *pszPath, size_t cchPath)
{
    int rc = RTPathExecDir(pszPath, cchPath);
    if (RT_SUCCESS(rc))
    {
        const char *pszLast = RTPathFilename(pszPath);
        if (   !strcmp(pszLast, "amd64")
            || !strcmp(pszLast, "i386"))
            RTPathStripFilename(pszPath);
    }
    return rc;
}
Example #17
0
RTR3DECL(int) RTManifestWriteFilesBuf(void **ppvBuf, size_t *pcbSize, PRTMANIFESTTEST paFiles, size_t cFiles)
{
    /* Validate input */
    AssertPtrReturn(ppvBuf, VERR_INVALID_POINTER);
    AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
    AssertPtrReturn(paFiles, VERR_INVALID_POINTER);
    AssertReturn(cFiles > 0, VERR_INVALID_PARAMETER);

    /* Calculate the size necessary for the memory buffer. */
    size_t cbSize = 0;
    size_t cbMaxSize = 0;
    for (size_t i = 0; i < cFiles; ++i)
    {
        size_t cbTmp = strlen(RTPathFilename(paFiles[i].pszTestFile)) + strlen(paFiles[i].pszTestDigest) + 10;
        cbMaxSize = RT_MAX(cbMaxSize, cbTmp);
        cbSize += cbTmp;
    }

    /* Create the memory buffer */
    void *pvBuf = RTMemAlloc(cbSize);
    if (!pvBuf)
        return VERR_NO_MEMORY;

    /* Allocate a temporary string buffer. */
    char * pszTmp = RTStrAlloc(cbMaxSize + 1);
    size_t cbPos = 0;
    for (size_t i = 0; i < cFiles; ++i)
    {
        size_t cch = RTStrPrintf(pszTmp, cbMaxSize + 1, "SHA1 (%s)= %s\n", RTPathFilename(paFiles[i].pszTestFile), paFiles[i].pszTestDigest);
        memcpy(&((char*)pvBuf)[cbPos], pszTmp, cch);
        cbPos += cch;
    }
    RTStrFree(pszTmp);

    /* Results */
    *ppvBuf = pvBuf;
    *pcbSize = cbSize;

    return VINF_SUCCESS;
}
Example #18
0
void GluePrintErrorContext(const char *pcszContext, const char *pcszSourceFile, uint32_t ulLine)
{
    // pcszSourceFile comes from __FILE__ macro, which always contains the full path,
    // which we don't want to see printed:
    Utf8Str strFilename(RTPathFilename(pcszSourceFile));
    Utf8Str str = Utf8StrFmt("Context: \"%s\" at line %d of file %s\n",
                             pcszContext,
                             ulLine,
                             strFilename.c_str());
    // print and log
    RTMsgError("%s", str.c_str());
    Log(("%s", str.c_str()));
}
Example #19
0
int DnDURIList::AppendURIPath(const char *pszURI, uint32_t fFlags)
{
    AssertPtrReturn(pszURI, VERR_INVALID_POINTER);

    /** @todo Check for string termination?  */
#ifdef DEBUG_andy
    LogFlowFunc(("pszPath=%s, fFlags=0x%x\n", pszURI, fFlags));
#endif
    int rc = VINF_SUCCESS;

    /* Query the path component of a file URI. If this hasn't a
     * file scheme NULL is returned. */
    char *pszFilePath = RTUriFilePath(pszURI, URI_FILE_FORMAT_AUTO);
    if (pszFilePath)
    {
        /* Add the path to our internal file list (recursive in
         * the case of a directory). */
        size_t cbPathLen = RTPathStripTrailingSlash(pszFilePath);
        if (cbPathLen)
        {
            char *pszFileName = RTPathFilename(pszFilePath);
            if (pszFileName)
            {
                Assert(pszFileName >= pszFilePath);
                size_t cbBase = (fFlags & DNDURILIST_FLAGS_ABSOLUTE_PATHS)
                              ? 0 /* Use start of path as root. */
                              : pszFileName - pszFilePath;
                char *pszRoot = &pszFilePath[cbBase];
                m_lstRoot.append(pszRoot);
#ifdef DEBUG_andy
                LogFlowFunc(("pszFilePath=%s, pszFileName=%s, pszRoot=%s\n",
                             pszFilePath, pszFileName, pszRoot));
#endif
                rc = appendPathRecursive(pszFilePath, cbBase,
                                         fFlags);
            }
            else
                rc = VERR_NOT_FOUND;
        }
        else
            rc = VERR_INVALID_PARAMETER;

        RTStrFree(pszFilePath);
    }
    else
        rc = VERR_INVALID_PARAMETER;

    LogFlowFuncLeaveRC(rc);
    return rc;
}
Example #20
0
static int Error(const char *pszFormat, ...)
{
    char szName[RTPATH_MAX];
    if (!RTProcGetExecutablePath(szName, sizeof(szName)))
        strcpy(szName, "tstRTDigest");

    RTStrmPrintf(g_pStdErr, "%s: error: ", RTPathFilename(szName));
    va_list va;
    va_start(va, pszFormat);
    RTStrmPrintfV(g_pStdErr, pszFormat, va);
    va_end(va);

    return 1;
}
Example #21
0
RTDECL(ssize_t) RTLinuxSysFsGetLinkDestV(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va)
{
    AssertReturnStmt(cchBuf >= 2, errno = EINVAL, -1);

    /*
     * Construct the filename and read the link.
     */
    char szFilename[RTPATH_MAX];
    int rc = rtLinuxSysFsConstructPath(szFilename, sizeof(szFilename), pszFormat, va);
    if (rc == -1)
        return -1;

    char szLink[RTPATH_MAX];
    rc = readlink(szFilename, szLink, sizeof(szLink));
    if (rc == -1)
        return -1;
    if ((size_t)rc > sizeof(szLink) - 1)
    {
        errno = ERANGE;
        return -1;
    }
    szLink[rc] = '\0'; /* readlink fun. */

    /*
     * Extract the file name component and copy it into the return buffer.
     */
    size_t cchName;
    const char *pszName = RTPathFilename(szLink);
    if (pszName)
    {
        cchName = strlen(pszName); /* = &szLink[rc] - pszName; */
        if (cchName >= cchBuf)
        {
            errno = ERANGE;
            return -1;
        }
        memcpy(pszBuf, pszName, cchName + 1);
    }
    else
    {
        *pszBuf = '\0';
        cchName = 0;
    }
    return cchName;
}
static void tstDirCreateTemp(const char *pszSubTest, const char *pszTemplate, unsigned cTimes, bool fSkipXCheck)
{
    RTTestISub(pszSubTest);

    /* Allocate the result array. */
    char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *));
    RTTESTI_CHECK_RETV(papszNames != NULL);

    /* The test loop. */
    unsigned i;
    for (i = 0; i < cTimes; i++)
    {
        int rc;
        char szName[RTPATH_MAX];
        RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS);
        if (RT_FAILURE(rc))
            break;

        RTTESTI_CHECK(papszNames[i] = RTStrDup(szName));
        if (!papszNames[i])
            break;

        rc = RTDirCreateTemp(papszNames[i]);
        if (rc != VINF_SUCCESS)
        {
            RTTestIFailed("RTDirCreateTemp(%s) call #%u -> %Rrc\n", szName, i, rc);
            RTStrFree(papszNames[i]);
            papszNames[i] = NULL;
            break;
        }
        RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]);
        RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("szName   %s\nReturned %s\n", szName, papszNames[i]));
        if (!fSkipXCheck)
            RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("szName   %s\nReturned %s\n", szName, papszNames[i]));
    }

    /* cleanup */
    while (i-- > 0)
    {
        RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS);
        RTStrFree(papszNames[i]);
    }
    RTMemTmpFree(papszNames);
}
Example #23
0
RTDECL(int) RTDirOpenFiltered(PRTDIR *ppDir, const char *pszPath, RTDIRFILTER enmFilter, uint32_t fOpen)
{
    /*
     * Validate input.
     */
    AssertMsgReturn(VALID_PTR(ppDir), ("%p\n", ppDir), VERR_INVALID_POINTER);
    AssertMsgReturn(VALID_PTR(pszPath), ("%p\n", pszPath), VERR_INVALID_POINTER);
    AssertReturn(!(fOpen & ~RTDIROPEN_FLAGS_NO_SYMLINKS), VERR_INVALID_FLAGS);
    switch (enmFilter)
    {
        case RTDIRFILTER_UNIX:
        case RTDIRFILTER_UNIX_UPCASED:
            AssertMsgFailed(("%d is not implemented!\n", enmFilter));
            return VERR_NOT_IMPLEMENTED;
        case RTDIRFILTER_NONE:
        case RTDIRFILTER_WINNT:
            break;
        default:
            AssertMsgFailedReturn(("%d\n", enmFilter), VERR_INVALID_PARAMETER);
    }

    /*
     * Find the last component, i.e. where the filter criteria starts and the dir name ends.
     */
    const char *pszFilter;
    if (enmFilter == RTDIRFILTER_NONE)
        pszFilter = NULL;
    else
    {
        pszFilter = RTPathFilename(pszPath);
        if (!pszFilter) /* trailing slash => directory to read => no filter. */
            enmFilter = RTDIRFILTER_NONE;
    }

    /*
     * Call worker common with RTDirOpen which will verify the path, allocate
     * and initialize the handle, and finally call the backend.
     */
    int rc = rtDirOpenCommon(ppDir, pszPath, pszFilter, enmFilter);

    LogFlow(("RTDirOpenFiltered(%p:{%p}, %p:{%s}, %d): return %Rrc\n",
             ppDir, *ppDir, pszPath, pszPath, enmFilter, rc));
    return rc;
}
Example #24
0
/**
 * Figure file type based on name, will stat the file/dir.
 *
 * @returns File type.
 * @param   pszPath             The path to the file/dir to figure.
 */
static RTDBGSYMCACHEFILETYPE rtDbgSymCacheFigureType(const char *pszPath)
{
    const char *pszName = RTPathFilename(pszPath);

    /* Trailing slash. */
    if (!pszName)
        return RTDBGSYMCACHEFILETYPE_DIR;

    /* Wildcard means listing directory and filtering.  */
    if (strpbrk(pszName, "?*"))
        return RTDBGSYMCACHEFILETYPE_DIR_FILTER;

    /* Get object info, following links. */
    RTFSOBJINFO ObjInfo;
    int rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
    if (RT_FAILURE(rc))
        return RTDBGSYMCACHEFILETYPE_INVALID;
    return rtDbgSymCacheFigureType2(pszPath, &ObjInfo);
}
Example #25
0
void XmlFileWriter::write(const char *pcszFilename, bool fSafe)
{
    if (!fSafe)
        writeInternal(pcszFilename, fSafe);
    else
    {
        /* Empty string and directory spec must be avoid. */
        if (RTPathFilename(pcszFilename) == NULL)
            throw xml::LogicError(RT_SRC_POS);

        /* Construct both filenames first to ease error handling.  */
        char szTmpFilename[RTPATH_MAX];
        int rc = RTStrCopy(szTmpFilename, sizeof(szTmpFilename) - strlen(s_pszTmpSuff), pcszFilename);
        if (RT_FAILURE(rc))
            throw EIPRTFailure(rc, "RTStrCopy");
        strcat(szTmpFilename, s_pszTmpSuff);

        char szPrevFilename[RTPATH_MAX];
        rc = RTStrCopy(szPrevFilename, sizeof(szPrevFilename) - strlen(s_pszPrevSuff), pcszFilename);
        if (RT_FAILURE(rc))
            throw EIPRTFailure(rc, "RTStrCopy");
        strcat(szPrevFilename, s_pszPrevSuff);

        /* Write the XML document to the temporary file.  */
        writeInternal(szTmpFilename, fSafe);

        /* Make a backup of any existing file (ignore failure). */
        uint64_t cbPrevFile;
        rc = RTFileQuerySize(pcszFilename, &cbPrevFile);
        if (RT_SUCCESS(rc) && cbPrevFile >= 16)
            RTFileRename(pcszFilename, szPrevFilename, RTPATHRENAME_FLAGS_REPLACE);

        /* Commit the temporary file. Just leave the tmp file behind on failure. */
        rc = RTFileRename(szTmpFilename, pcszFilename, RTPATHRENAME_FLAGS_REPLACE);
        if (RT_FAILURE(rc))
            throw EIPRTFailure(rc, "Failed to replace '%s' with '%s'", pcszFilename, szTmpFilename);

        /* Flush the directory changes (required on linux at least). */
        RTPathStripFilename(szTmpFilename);
        rc = RTDirFlush(szTmpFilename);
        AssertMsg(RT_SUCCESS(rc) || rc == VERR_NOT_SUPPORTED || rc == VERR_NOT_IMPLEMENTED, ("%Rrc\n", rc));
    }
}
/**
 * Converts Unix attributes to Dos-style attributes.
 *
 * @returns File mode mask.
 * @param   fMode       The mode mask containing dos-style attributes only.
 * @param   pszName     The filename which this applies to (hidden check).
 * @param   cbName      The length of that filename. (optional, set 0)
 */
RTFMODE rtFsModeFromUnix(RTFMODE fMode, const char *pszName, size_t cbName)
{
    NOREF(cbName);

    fMode &= RTFS_UNIX_MASK;

    if (!(fMode & (RTFS_UNIX_IWUSR | RTFS_UNIX_IWGRP | RTFS_UNIX_IWOTH)))
        fMode |= RTFS_DOS_READONLY;
    if (RTFS_IS_DIRECTORY(fMode))
        fMode |= RTFS_DOS_DIRECTORY;
    if (!(fMode & RTFS_DOS_MASK))
        fMode |= RTFS_DOS_NT_NORMAL;
    if (!(fMode & RTFS_DOS_HIDDEN) && pszName)
    {
        pszName = RTPathFilename(pszName);
        if (pszName && *pszName == '.')
            fMode |= RTFS_DOS_HIDDEN;
    }
    return fMode;
}
Example #27
0
HRESULT VFSExplorer::exists(const std::vector<com::Utf8Str> &aNames,
                            std::vector<com::Utf8Str> &aExists)
{

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    aExists.resize(0);
    for (size_t i=0; i < aNames.size(); ++i)
    {
        std::list<VFSExplorer::Data::DirEntry>::const_iterator it;
        for (it = m->entryList.begin();
             it != m->entryList.end();
             ++it)
        {
            const VFSExplorer::Data::DirEntry &entry = (*it);
            if (entry.name == RTPathFilename(aNames[i].c_str()))
                aExists.push_back(aNames[i]);
        }
    }

    return S_OK;
}
Example #28
0
/**
 * Construct a dot svn filename for the file being rewritten.
 *
 * @returns IPRT status code.
 * @param   pState              The rewrite state (for the name).
 * @param   pszDir              The directory, including ".svn/".
 * @param   pszSuff             The filename suffix.
 * @param   pszDst              The output buffer.  RTPATH_MAX in size.
 */
static int scmSvnConstructName(PSCMRWSTATE pState, const char *pszDir, const char *pszSuff, char *pszDst)
{
    strcpy(pszDst, pState->pszFilename); /* ASSUMES sizeof(szBuf) <= sizeof(szPath) */
    RTPathStripFilename(pszDst);

    int rc = RTPathAppend(pszDst, RTPATH_MAX, pszDir);
    if (RT_SUCCESS(rc))
    {
        rc = RTPathAppend(pszDst, RTPATH_MAX, RTPathFilename(pState->pszFilename));
        if (RT_SUCCESS(rc))
        {
            size_t cchDst  = strlen(pszDst);
            size_t cchSuff = strlen(pszSuff);
            if (cchDst + cchSuff < RTPATH_MAX)
            {
                memcpy(&pszDst[cchDst], pszSuff, cchSuff + 1);
                return VINF_SUCCESS;
            }
            else
                rc = VERR_BUFFER_OVERFLOW;
        }
    }
    return rc;
}
Example #29
0
/**
 * Figure the type of a file/dir based on path and FS object info.
 *
 * @returns The type.
 * @param   pszPath             The path to the file/dir.
 * @param   pObjInfo            The object information, symlinks followed.
 */
static RTDBGSYMCACHEFILETYPE rtDbgSymCacheFigureType2(const char *pszPath, PCRTFSOBJINFO pObjInfo)
{
    const char *pszName = RTPathFilename(pszPath);
    const char *pszExt  = RTPathSuffix(pszName);
    if (pszExt)
        pszExt++;
    else
        pszExt = "";

    if (   RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode)
        || (pObjInfo->Attr.fMode & RTFS_DOS_DIRECTORY)) /** @todo OS X samba reports reparse points in /Volumes/ that we cannot resolve. */
    {
        /* Skip directories shouldn't bother with. */
        if (   !RTStrICmp(pszName, ".Trashes")
            || !RTStrICmp(pszName, ".$RESCYCLE.BIN")
            || !RTStrICmp(pszName, "System.kext") /* Usually only plugins here, so skip it. */
           )
            return RTDBGSYMCACHEFILETYPE_IGNORE;

        /* Directories can also be bundles on the mac. */
        if (!RTStrICmp(pszExt, "dSYM"))
            return RTDBGSYMCACHEFILETYPE_DEBUG_BUNDLE;

        for (unsigned i = 0; i < RT_ELEMENTS(g_apszBundleSuffixes) - 1; i++)
            if (!RTStrICmp(pszExt, &g_apszBundleSuffixes[i][1]))
                return RTDBGSYMCACHEFILETYPE_IMAGE_BUNDLE;

        return RTDBGSYMCACHEFILETYPE_DIR;
    }

    if (!RTFS_IS_FILE(pObjInfo->Attr.fMode))
        return RTDBGSYMCACHEFILETYPE_INVALID;

    /* Select image vs debug info based on extension. */
    if (   !RTStrICmp(pszExt, "pdb")
        || !RTStrICmp(pszExt, "dbg")
        || !RTStrICmp(pszExt, "sym")
        || !RTStrICmp(pszExt, "dwo")
        || !RTStrICmp(pszExt, "dwp")
        || !RTStrICmp(pszExt, "debug")
        || !RTStrICmp(pszExt, "dsym")
        || !RTStrICmp(pszExt, "dwarf")
        || !RTStrICmp(pszExt, "map")
        || !RTStrICmp(pszExt, "cv"))
        return RTDBGSYMCACHEFILETYPE_DEBUG_FILE;

    /* Filter out a bunch of files which obviously shouldn't be images. */
    if (   !RTStrICmp(pszExt, "txt")
        || !RTStrICmp(pszExt, "html")
        || !RTStrICmp(pszExt, "htm")
        || !RTStrICmp(pszExt, "rtf")
        || !RTStrICmp(pszExt, "zip")
        || !RTStrICmp(pszExt, "doc")
        || !RTStrICmp(pszExt, "gz")
        || !RTStrICmp(pszExt, "bz2")
        || !RTStrICmp(pszExt, "xz")
        || !RTStrICmp(pszExt, "kmk")
        || !RTStrICmp(pszExt, "c")
        || !RTStrICmp(pszExt, "cpp")
        || !RTStrICmp(pszExt, "h")
        || !RTStrICmp(pszExt, "m")
        || !RTStrICmp(pszExt, "mm")
        || !RTStrICmp(pszExt, "asm")
        || !RTStrICmp(pszExt, "S")
        || !RTStrICmp(pszExt, "inc")
        || !RTStrICmp(pszExt, "sh")
       )
        return RTDBGSYMCACHEFILETYPE_IGNORE;
    if (   !RTStrICmp(pszName, "Makefile")
        || !RTStrICmp(pszName, "GNUmakefile")
        || !RTStrICmp(pszName, "createsymbolfiles")
        || !RTStrICmp(pszName, "kgmacros")
       )
        return RTDBGSYMCACHEFILETYPE_IGNORE;

    return RTDBGSYMCACHEFILETYPE_IMAGE_FILE;
}
/**
 * Searches for the file in the path.
 *
 * The file is first tested without any path modification, then we walk the path
 * looking in each directory.
 *
 * @returns VBox status code.
 * @param   pszFilename     The file to search for.
 * @param   pszPath         The search path.
 * @param   pfnOpen         The open callback function.
 * @param   pvUser          User argument for the callback.
 */
static int dbgfR3AsSearchPath(const char *pszFilename, const char *pszPath, PFNDBGFR3ASSEARCHOPEN pfnOpen, void *pvUser)
{
    char szFound[RTPATH_MAX];

    /* Check the filename length. */
    size_t const    cchFilename = strlen(pszFilename);
    if (cchFilename >= sizeof(szFound))
        return VERR_FILENAME_TOO_LONG;
    const char     *pszName = RTPathFilename(pszFilename);
    if (!pszName)
        return VERR_IS_A_DIRECTORY;
    size_t const    cchName = strlen(pszName);

    /*
     * Try default location first.
     */
    memcpy(szFound, pszFilename, cchFilename + 1);
    int rc = pfnOpen(szFound, pvUser);
    if (RT_SUCCESS(rc))
        return rc;

    /*
     * Walk the search path.
     */
    const char *psz = pszPath;
    while (*psz)
    {
        /* Skip leading blanks - no directories with leading spaces, thank you. */
        while (RT_C_IS_BLANK(*psz))
            psz++;

        /* Find the end of this element. */
        const char *pszNext;
        const char *pszEnd = strchr(psz, ';');
        if (!pszEnd)
            pszEnd = pszNext = strchr(psz, '\0');
        else
            pszNext = pszEnd + 1;
        if (pszEnd != psz)
        {
            size_t const cch = pszEnd - psz;
            if (cch + 1 + cchName < sizeof(szFound))
            {
                /** @todo RTPathCompose, RTPathComposeN(). This code isn't right
                 * for 'E:' on DOS systems. It may also create unwanted double slashes. */
                memcpy(szFound, psz, cch);
                szFound[cch] = '/';
                memcpy(szFound + cch + 1, pszName, cchName + 1);
                int rc2 = pfnOpen(szFound, pvUser);
                if (RT_SUCCESS(rc2))
                    return rc2;
                if (    rc2 != rc
                    &&  (   rc == VERR_FILE_NOT_FOUND
                         || rc == VERR_OPEN_FAILED))
                    rc = rc2;
            }
        }

        /* advance */
        psz = pszNext;
    }

    /*
     * Walk the path once again, this time do a depth search.
     */
    /** @todo do a depth search using the specified path. */

    /* failed */
    return rc;
}