Logo Search packages:      
Sourcecode: virtualbox-ose version File versions  Download package

int kldrDyldFindExistingModule ( const char *  pszName,
const char *  pszPrefix,
const char *  pszSuffix,
KLDRDYLDSEARCH  enmSearch,
unsigned  fFlags,
PPKLDRDYLDMOD  ppMod 
)

Locates an already open module using the specified search method.

Returns:
0 and *ppMod on success, non-zero OS specific error on failure.
Parameters:
pszName Partial or complete name, it's specific to the search method to determin which.
pszPrefix Prefix than can be used when searching.
pszSuffix Suffix than can be used when searching.
enmSearch The file search method to apply.
fFlags Search flags.
ppMod Where to store the file provider instance on success.

Definition at line 901 of file kLdrDyldFind.c.

References KLDRMOD::cchFilename, KLDRMOD::cchName, KLDRDYLDMOD::fGlobalOrSpecific, KLDR_ERR_MODULE_NOT_FOUND, KLDRDYLD_SEARCH_OS2, KLDRDYLD_SEARCH_WINDOWS, KLDRDYLD_SEARCH_WINDOWS_ALTERED, kldrDyldFindDoDllSearch(), kldrDyldFindGetDefaults(), kldrDyldFindTryOpen(), kLdrDyldHead, kLdrDyldOS2LibpathStrict, KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE, KSIZE, KLDRDYLDMOD::Load, NULL, KLDRDYLDMOD::pMod, KLDRDYLDMOD::pNext, KLDRMOD::pszFilename, and KLDRMOD::pszName.

Referenced by kldrDyldDoFindByName(), kldrDyldDoLoad(), and kldrDyldGetPrerequisite().

{

    int rc;
    unsigned fOS2LibpathStrict;
    *ppMod = NULL;

    /*
     * Don't bother if no modules are loaded yet.
     */
    if (!kLdrDyldHead)
        return KLDR_ERR_MODULE_NOT_FOUND;

    /*
     * Defaults.
     */
    rc = kldrDyldFindGetDefaults(&enmSearch, &pszPrefix, &pszSuffix, pszName, fFlags);
    if (rc)
        return rc;

    /*
     * If this isn't just a filename, the caller has specified a file
     * that should be opened directly and not a module name to be searched for.
     *
     * In order to do the right thing we'll have to open the file and get the
     * correct filename for it.
     *
     * The OS/2 libpath strict method require us to find the correct DLL first.
     */
    fOS2LibpathStrict = 0;
    if (    !kHlpIsFilenameOnly(pszName)
        ||  (fOS2LibpathStrict = (   enmSearch == KLDRDYLD_SEARCH_OS2
                                  && kLdrDyldOS2LibpathStrict[0] == 'T')
            )
       )
    {
        PKRDR pRdr;
        if (fOS2LibpathStrict)
            rc = kldrDyldFindDoDllSearch(pszName, pszPrefix, pszSuffix, enmSearch, fFlags, &pRdr);
        else
            rc = kldrDyldFindTryOpen(pszName, &pRdr);
        if (!rc)
        {
            /* do a filename based search. */
            const char     *pszFilename = kRdrName(pRdr);
            const KSIZE     cchFilename = kHlpStrLen(pszFilename);
            PKLDRDYLDMOD    pCur;
            rc = KLDR_ERR_MODULE_NOT_FOUND;
            for (pCur = kLdrDyldHead; pCur; pCur = pCur->Load.pNext)
            {
                if (    pCur->pMod->cchFilename == cchFilename
                    &&  !kHlpMemComp(pCur->pMod->pszFilename, pszFilename, cchFilename))
                {
                    *ppMod = pCur;
                    rc = 0;
                    break;
                }
            }
            kRdrClose(pRdr);
        }
    }
    else
    {
        const KSIZE     cchName = kHlpStrLen(pszName);
        const KSIZE     cchPrefix = pszPrefix ? kHlpStrLen(pszPrefix) : 0;
        const KSIZE     cchSuffix = pszSuffix ? kHlpStrLen(pszSuffix) : 0;
        const char     *pszNameSuffix = kHlpGetSuff(pszName);
        PKLDRDYLDMOD    pCur = kLdrDyldHead;

        /*
         * Some of the methods are case insensitive (ASCII), others are case sensitive.
         * To avoid having todo indirect calls to the compare functions here, we split
         * ways even if it means a lot of duplicate code.
         */
        if (   enmSearch == KLDRDYLD_SEARCH_OS2
            || enmSearch == KLDRDYLD_SEARCH_WINDOWS
            || enmSearch == KLDRDYLD_SEARCH_WINDOWS_ALTERED)
        {
            const unsigned fNameHasSuffix = pszNameSuffix
                                         && kHlpStrLen(pszNameSuffix) == cchSuffix
                                         && !kHlpMemICompAscii(pszNameSuffix, pszName + cchName - cchSuffix, cchSuffix);
            for (; pCur; pCur = pCur->Load.pNext)
            {
                /* match global / specific */
                if (    !pCur->fGlobalOrSpecific
                    &&  !(fFlags & KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE))
                    continue;

                /* match name */
                if (    pCur->pMod->cchName == cchName
                    &&  !kHlpMemICompAscii(pCur->pMod->pszName, pszName, cchName))
                    break;
                if (cchPrefix)
                {
                    if (    pCur->pMod->cchName == cchName + cchPrefix
                        &&  !kHlpMemICompAscii(pCur->pMod->pszName, pszPrefix, cchPrefix)
                        &&  !kHlpMemICompAscii(pCur->pMod->pszName + cchPrefix, pszName, cchName))
                    break;
                }
                if (cchSuffix)
                {
                    if (    pCur->pMod->cchName == cchName + cchSuffix
                        &&  !kHlpMemICompAscii(pCur->pMod->pszName + cchName, pszSuffix, cchSuffix)
                        &&  !kHlpMemICompAscii(pCur->pMod->pszName, pszName, cchName))
                    break;
                    if (    fNameHasSuffix
                        &&  pCur->pMod->cchName == cchName - cchSuffix
                        &&  !kHlpMemICompAscii(pCur->pMod->pszName, pszName, cchName - cchSuffix))
                    break;
                    if (cchPrefix)
                    {
                        if (    pCur->pMod->cchName == cchName + cchPrefix + cchSuffix
                            &&  !kHlpMemICompAscii(pCur->pMod->pszName, pszPrefix, cchPrefix)
                            &&  !kHlpMemICompAscii(pCur->pMod->pszName + cchPrefix, pszName, cchName)
                            &&  !kHlpMemICompAscii(pCur->pMod->pszName + cchPrefix + cchName, pszSuffix, cchSuffix))
                        break;
                        if (    fNameHasSuffix
                            &&  pCur->pMod->cchName == cchName + cchPrefix - cchSuffix
                            &&  !kHlpMemICompAscii(pCur->pMod->pszName, pszPrefix, cchPrefix)
                            &&  !kHlpMemICompAscii(pCur->pMod->pszName + cchPrefix, pszName, cchName - cchSuffix))
                        break;
                    }
                }
            }
        }
        else
        {
            const unsigned fNameHasSuffix = pszNameSuffix
                                         && kHlpStrLen(pszNameSuffix) == cchSuffix
                                         && kHlpMemComp(pszNameSuffix, pszName + cchName - cchSuffix, cchSuffix);
            for (; pCur; pCur = pCur->Load.pNext)
            {
                /* match global / specific */
                if (    !pCur->fGlobalOrSpecific
                    &&  !(fFlags & KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE))
                    continue;

                /* match name */
                if (    pCur->pMod->cchName == cchName
                    &&  !kHlpMemComp(pCur->pMod->pszName, pszName, cchName))
                    break;
                if (cchPrefix)
                {
                    if (    pCur->pMod->cchName == cchName + cchPrefix
                        &&  !kHlpMemComp(pCur->pMod->pszName, pszPrefix, cchPrefix)
                        &&  !kHlpMemComp(pCur->pMod->pszName + cchPrefix, pszName, cchName))
                    break;
                }
                if (cchSuffix)
                {
                    if (    pCur->pMod->cchName == cchName + cchSuffix
                        &&  !kHlpMemComp(pCur->pMod->pszName + cchName, pszSuffix, cchSuffix)
                        &&  !kHlpMemComp(pCur->pMod->pszName, pszName, cchName))
                    break;
                    if (    fNameHasSuffix
                        &&  pCur->pMod->cchName == cchName - cchSuffix
                        &&  !kHlpMemComp(pCur->pMod->pszName, pszName, cchName - cchSuffix))
                    break;
                    if (cchPrefix)
                    {
                        if (    pCur->pMod->cchName == cchName + cchPrefix + cchSuffix
                            &&  !kHlpMemComp(pCur->pMod->pszName, pszPrefix, cchPrefix)
                            &&  !kHlpMemComp(pCur->pMod->pszName + cchPrefix, pszName, cchName)
                            &&  !kHlpMemComp(pCur->pMod->pszName + cchPrefix + cchName, pszSuffix, cchSuffix))
                        break;
                        if (    pCur->pMod->cchName == cchName + cchPrefix - cchSuffix
                            &&  !kHlpMemComp(pCur->pMod->pszName, pszPrefix, cchPrefix)
                            &&  !kHlpMemComp(pCur->pMod->pszName + cchPrefix, pszName, cchName - cchSuffix))
                        break;
                    }
                }
            }
        }

        /* search result. */
        if (pCur)
        {
            *ppMod = pCur;
            rc = 0;
        }
        else
            rc = KLDR_ERR_MODULE_NOT_FOUND;
    }

    return rc;
}


Generated by  Doxygen 1.6.0   Back to index