Ignore:
Timestamp:
Nov 11, 2006, 10:33:17 AM (19 years ago)
Author:
bird
Message:

top half of the filesearching is done.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdrDyldFind.c

    r2843 r2867  
    3030*   Header Files                                                               *
    3131*******************************************************************************/
     32#ifdef __OS2__
     33# define INCL_BASE
     34# define INCL_ERRORS
     35# include <os2.h>
     36# ifndef LIBPATHSTRICT
     37#  define LIBPATHSTRICT 3
     38# endif
     39  extern APIRET DosQueryHeaderInfo(HMODULE hmod, ULONG ulIndex, PVOID pvBuffer, ULONG cbBuffer, ULONG ulSubFunction);
     40# define QHINF_EXEINFO       1 /* NE exeinfo. */
     41# define QHINF_READRSRCTBL   2 /* Reads from the resource table. */
     42# define QHINF_READFILE      3 /* Reads from the executable file. */
     43# define QHINF_LIBPATHLENGTH 4 /* Gets the libpath length. */
     44# define QHINF_LIBPATH       5 /* Gets the entire libpath. */
     45# define QHINF_FIXENTRY      6 /* NE only */
     46# define QHINF_STE           7 /* NE only */
     47# define QHINF_MAPSEL        8 /* NE only */
     48
     49#elif defined(__WIN__)
     50# include <Windows.h>
     51#endif
     52
    3253#include <kLdr.h>
    3354#include "kLdrHlp.h"
    3455#include "kLdrInternal.h"
    3556
     57/*******************************************************************************
     58*   Defined Constants And Macros                                               *
     59*******************************************************************************/
     60/** @def KLDRDYLDFIND_STRICT
     61 * Define KLDRDYLDFIND_STRICT to enabled strict checks in kLdrDyldFind. */
     62#define KLDRDYLDFIND_STRICT 1
     63
     64/** @def KLDRDYLDFIND_ASSERT
     65 * Assert that an expression is true when KLDRDYLDFIND_STRICT is defined.
     66 */
     67#ifdef KLDRDYLDFIND_STRICT
     68# define KLDRDYLDFIND_ASSERT(expr)  kldrHlpAssert(expr)
     69#else
     70# define KLDRDYLDFIND_ASSERT(expr)  do {} while (0)
     71#endif
     72
     73
     74/*******************************************************************************
     75*   Global Variables                                                           *
     76*******************************************************************************/
     77/** @name The kLdr search method parameters.
     78 * @{ */
     79/** The kLdr DLL search path.
     80 * During initialization the KLDR_LIBRARY_PATH env.var. and the path in the
     81 * executable stub is appended. Both ';' and ':' can be used as separators.
     82 */
     83char            kLdrDyldPath[8192];
     84/** The kLdr application directory.
     85 * This is initialized when the executable is 'loaded' or by a kLdr user.
     86 */
     87char            kLdrDyldAppDir[260];
     88/** The default kLdr DLL prefix.
     89 * This is initialized with the KLDR_DEF_PREFIX env.var. + the prefix in the executable stub.
     90 */
     91char            kLdrDyldDefPrefix[16];
     92/** The default kLdr DLL suffix.
     93 * This is initialized with the KLDR_DEF_SUFFIX env.var. + the prefix in the executable stub.
     94 */
     95char            kLdrDyldDefSuffix[16];
     96/** @} */
     97
     98
     99/** @name The OS/2 search method parameters.
     100 * @{
     101 */
     102/** The OS/2 LIBPATH.
     103 * This is queried from the os2krnl on OS/2, while on other systems initialized using
     104 * the KLDR_OS2_LIBPATH env.var.
     105 */
     106char            kLdrDyldOS2Libpath[2048];
     107/** The OS/2 LIBPATHSTRICT ("T" or '\0').
     108 * This is queried from the os2krnl on OS/2, while on other systems initialized using
     109 * the KLDR_OS2_LIBPATHSTRICT env.var.
     110 */
     111char            kLdrDyldOS2LibpathStrict[8];
     112/** The OS/2 BEGINLIBPATH.
     113 * This is queried from the os2krnl on OS/2, while on other systems initialized using
     114 * the KLDR_OS2_BEGINLIBPATH env.var.
     115 */
     116char            kLdrDyldOS2BeginLibpath[2048];
     117/** The OS/2 ENDLIBPATH.
     118 * This is queried from the os2krnl on OS/2, while on other systems initialized using
     119 * the KLDR_OS2_ENDLIBPATH env.var.
     120 */
     121char            kLdrDyldOS2EndLibpath[2048];
     122/** @} */
     123
     124
     125/** @name The Windows search method parameters.
     126 * @{ */
     127/** The Windows application directory.
     128 * This is initialized when the executable is 'loaded' or by a kLdr user.
     129 */
     130char            kLdrDyldWindowsAppDir[260];
     131/** The Windows system directory.
     132 * This is queried from the Win32/64 subsystem on Windows, while on other systems
     133 * initialized using the KLDR_WINDOWS_SYSTEM_DIR env.var.
     134 */
     135char            kLdrDyldWindowsSystemDir[260];
     136/** The Windows directory.
     137 * This is queried from the Win32/64 subsystem on Windows, while on other systems
     138 * initialized using the KLDR_WINDOWS_DIR env.var.
     139 */
     140char            kLdrDyldWindowsDir[260];
     141/** The Windows path.
     142 * This is queried from the PATH env.var. on Windows, while on other systems
     143 * initialized using the KLDR_WINDOWS_PATH env.var. and falling back on
     144 * the PATH env.var. if it wasn't found.
     145 */
     146char            kLdrDyldWindowsPath[8192];
     147/** @} */
     148
     149
     150/** @name The Common Unix search method parameters.
     151 * @{
     152 */
     153/** The Common Unix library path.
     154 * Initialized from the env.var. KLDR_UNIX_LIBRARY_PATH or LD_LIBRARY_PATH or the
     155 * former wasn't found.
     156 */
     157char            kLdrDyldUnixLibraryPath[8192];
     158/** The Common Unix system library path. */
     159char            kLdrDyldUnixSystemLibraryPath[1024] = "/lib;/usr/lib";
     160/** @} */
     161
     162/** @todo Deal with DT_RUNPATH and DT_RPATH. */
     163/** @todo ld.so.cache? */
     164
     165
     166/*******************************************************************************
     167*   Internal Functions                                                         *
     168*******************************************************************************/
     169static int kldrDyldFindDoSearch(const char *pszName, const char *pszPrefix, const char *pszSuffix,
     170                                KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRRDR ppRdr);
     171static int kldrDyldFindTryOpen(const char *pszFilename, PPKLDRRDR ppRdr);
     172static int kldrDyldFindTryOpenPath(const char *pchPath, size_t cchPath, const char *pszName, const char *pszPrefix,
     173                                   const char *pszSuffix, PPKLDRRDR ppRdr);
     174static int kldrDyldFindEnumeratePath(const char *pszSearchPath, const char *pszName, const char *pszPrefix,
     175                                     const char *pszSuffix, PPKLDRRDR ppRdr);
     176
     177
     178/**
     179 * Initializes the find paths.
     180 *
     181 * @returns 0 on success, non-zero on failure.
     182 */
     183int kldrDyldFindInit(void)
     184{
     185    size_t  cch;
     186    int     rc;
     187    char    szTmp[sizeof(kLdrDyldDefSuffix)];
     188
     189    /*
     190     * The kLdr search parameters.
     191     */
     192    rc = kldrHlpGetEnv("KLDR_LIBRARY_PATH", kLdrDyldPath, sizeof(kLdrDyldPath));
     193    if (rc)
     194        kLdrDyldPath[0] = '\0';
     195
     196    rc = kldrHlpGetEnv("KLDR_DEF_PREFIX", szTmp, sizeof(szTmp));
     197    if (!rc)
     198        kLdrHlpMemCopy(kLdrDyldDefPrefix, szTmp, sizeof(szTmp));
     199
     200    rc = kldrHlpGetEnv("KLDR_DEF_SUFFIX", szTmp, sizeof(szTmp));
     201    if (!rc)
     202        kLdrHlpMemCopy(kLdrDyldDefSuffix, szTmp, sizeof(szTmp));
     203
     204    /*
     205     * The OS/2 search parameters.
     206     */
     207#ifdef __OS2__
     208    rc = DosQueryHeaderInfo(NULLHANDLE, 0, kLdrDyldOS2Libpath, sizeof(kLdrDyldOS2Libpath), QHINF_LIBPATH);
     209    if (rc)
     210        return rc;
     211    rc = DosQueryExtLIBPATH(kLdrDyldOS2LibpathStrict, LIBPATHSTRICT);
     212    if (rc)
     213        kLdrDyldOS2LibpathStrict[0] = '\0';
     214    rc = DosQueryExtLIBPATH(kLdrDyldOS2BeginLibpath, BEGIN_LIBPATH);
     215    if (rc)
     216        kLdrDyldOS2BeginLibpath[0] = '\0';
     217    rc = DosQueryExtLIBPATH(kLdrDyldOS2EndLibpath, END_LIBPATH);
     218    if (rc)
     219        kLdrDyldOS2EndLibpath[0] = '\0';
     220
     221#else
     222    kldrHlpGetEnv("KLDR_OS2_LIBPATH", kLdrDyldOS2Libpath, sizeof(kLdrDyldOS2Libpath));
     223    kldrHlpGetEnv("KLDR_OS2_LIBPATHSTRICT", kLdrDyldOS2LibpathStrict, sizeof(kLdrDyldOS2LibpathStrict));
     224    kldrHlpGetEnv("KLDR_OS2_BEGINLIBPATH", kLdrDyldOS2BeginLibpath, sizeof(kLdrDyldOS2BeginLibpath));
     225    kldrHlpGetEnv("KLDR_OS2_ENDLIBPATH", kLdrDyldOS2EndLibpath, sizeof(kLdrDyldOS2EndLibpath));
     226#endif
     227
     228    /*
     229     * The windows search parameters.
     230     */
     231#if defined(__WIN__)
     232    cch = GetSystemDirectory(kLdrDyldWindowsSystemDir, sizeof(kLdrDyldWindowsSystemDir));
     233    if (cch >= sizeof(kLdrDyldWindowsSystemDir))
     234        return (rc = GetLastError()) ? rc : -1;
     235    cch = GetWindowsDirectory(kLdrDyldWindowsDir, sizeof(kLdrDyldWindowsDir));
     236    if (cch >= sizeof(kLdrDyldWindowsDir))
     237        return (rc = GetLastError()) ? rc : -1;
     238    kldrHlpGetEnv("PATH", kLdrDyldWindowsPath, sizeof(kLdrDyldWindowsPath));
     239#else
     240    kldrHlpGetEnv("KLDR_WINDOWS_SYSTEM_DIR", kLdrDyldWindowsSystemDir, sizeof(kLdrDyldWindowsSystemDir));
     241    kldrHlpGetEnv("KLDR_WINDOWS_DIR", kLdrDyldWindowsDir, sizeof(kLdrDyldWindowsDir));
     242    kldrHlpGetEnv("KLDR_WINDOWS_PATH", kLdrDyldWindowsPath, sizeof(kLdrDyldWindowsPath));
     243#endif
     244
     245    /*
     246     * The Unix search parameters.
     247     */
     248    rc = kldrHlpGetEnv("KLDR_UNIX_LIBRARY_PATH", kLdrDyldUnixLibraryPath, sizeof(kLdrDyldUnixLibraryPath));
     249    if (rc)
     250        kldrHlpGetEnv("LD_LIBRARY_PATH", kLdrDyldUnixLibraryPath, sizeof(kLdrDyldUnixLibraryPath));
     251
     252    (void)cch;
     253    return 0;
     254}
     255
    36256
    37257/**
    38258 * Locates and opens a module using the specified search method.
    39259 *
    40  * @returns 0 and *ppRdr on success, non-zero OS specific error on failure.
     260 * @returns 0 and *ppMod on success, non-zero OS specific error on failure.
    41261 *
    42262 * @param   pszName         Partial or complete name, it's specific to the search method to determin which.
     
    50270                          KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRDYLDMOD ppMod)
    51271{
     272    int rc;
     273    PKLDRRDR pRdr = NULL;
     274
    52275    *ppMod = NULL;
    53     return -1;
     276
     277    /*
     278     * If this isn't just a filename, we the caller has specified a file
     279     * that should be opened directly and not a module name to be searched for.
     280     */
     281    if (!kldrHlpIsFilenameOnly(pszName))
     282        rc = kldrDyldFindTryOpen(pszName, &pRdr);
     283    else
     284        rc = kldrDyldFindDoSearch(pszName, pszPrefix, pszSuffix, enmSearch, fFlags, &pRdr);
     285    if (!rc)
     286    {
     287#ifdef KLDRDYLDFIND_STRICT
     288        /* Sanity check of kldrDyldFindExistingModule. */
     289        if (fFlags & KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE)
     290        {
     291            const char     *pszFilename = kLdrRdrName(pRdr);
     292            const size_t    cchFilename = kLdrHlpStrLen(pszFilename);
     293            PKLDRDYLDMOD    pCur;
     294            for (pCur = kLdrDyldHead; pCur; pCur = pCur->Load.pNext)
     295                KLDRDYLDFIND_ASSERT(    pCur->pMod->cchFilename != cchFilename
     296                                    ||  kLdrHlpMemComp(pCur->pMod->pszFilename, pszFilename, cchFilename));
     297        }
     298#endif
     299
     300        /*
     301         * Check for matching non-global modules that should be promoted.
     302         */
     303        if (!(fFlags & KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE))
     304        {
     305            const char     *pszFilename = kLdrRdrName(pRdr);
     306            const size_t    cchFilename = kLdrHlpStrLen(pszFilename);
     307            PKLDRDYLDMOD    pCur;
     308            for (pCur = kLdrDyldHead; pCur; pCur = pCur->Load.pNext)
     309            {
     310                if (    !pCur->fGlobalOrSpecific
     311                    &&  pCur->pMod->cchFilename == cchFilename
     312                    &&  !kLdrHlpMemComp(pCur->pMod->pszFilename, pszFilename, cchFilename))
     313                {
     314                    kLdrRdrClose(pRdr);
     315                    kldrDyldModMarkGlobal(pCur);
     316                    *ppMod = pCur;
     317                    return 0;
     318                }
     319                KLDRDYLDFIND_ASSERT(    pCur->pMod->cchFilename != cchFilename
     320                                    ||  kLdrHlpMemComp(pCur->pMod->pszFilename, pszFilename, cchFilename));
     321            }
     322        }
     323
     324        /*
     325         * Create a new module.
     326         */
     327        rc = kldrDyldModCreate(pRdr, ppMod);
     328        if (rc)
     329            kLdrRdrClose(pRdr);
     330    }
     331    return rc;
    54332}
     333
     334
     335/**
     336 * Searches for a file using the specified method.
     337 *
     338 * @returns 0 on success and *ppMod pointing to the new module.
     339 * @returns KLDR_ERR_MODULE_NOT_FOUND if the specified file couldn't be opened.
     340 * @returns non-zero kLdr or OS specific status code on other failures.
     341 * @param   pszName     The name.
     342 * @param   pszPrefix   The prefix, optional.
     343 * @param   pszSuffix   The suffix, optional.
     344 * @param   enmSearch   The search method.
     345 * @param   fFlags      The load/search flags.
     346 * @param   ppRdr       Where to store the pointer to the file provider instance on success.
     347 */
     348static int kldrDyldFindDoSearch(const char *pszName, const char *pszPrefix, const char *pszSuffix,
     349                                KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRRDR ppRdr)
     350{
     351    int rc;
     352
     353    /*
     354     * Fixup search method alias.
     355     */
     356    if (enmSearch == KLDRDYLD_SEARCH_HOST)
     357        enmSearch = KLDRDYLD_SEARCH_KLDR; /** @todo find more suitable place for this. */
     358
     359    /*
     360     * Apply the specified search method.
     361     */
     362    switch (enmSearch)
     363    {
     364        case KLDRDYLD_SEARCH_KLDR:
     365        {
     366            if (!pszPrefix && kLdrDyldDefPrefix[0])
     367                pszPrefix = kLdrDyldDefPrefix;
     368            if (!pszSuffix && kLdrDyldDefSuffix[0])
     369                pszSuffix = kLdrDyldDefSuffix;
     370
     371            if (kLdrDyldAppDir[0] != '\0')
     372            {
     373                rc = kldrDyldFindTryOpenPath(kLdrDyldAppDir, kLdrHlpStrLen(kLdrDyldAppDir),
     374                                             pszName, pszPrefix, pszSuffix, ppRdr);
     375                if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     376                    break;
     377            }
     378            rc = kldrDyldFindTryOpenPath(".", 1, pszName, pszPrefix, pszSuffix, ppRdr);
     379            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     380                break;
     381            rc = kldrDyldFindEnumeratePath(kLdrDyldPath, pszName, pszPrefix, pszSuffix, ppRdr);
     382            break;
     383        }
     384
     385        case KLDRDYLD_SEARCH_OS2:
     386        {
     387            if (!pszSuffix)
     388                pszSuffix = ".dll";
     389
     390            rc = kldrDyldFindEnumeratePath(kLdrDyldOS2BeginLibpath, pszName, pszPrefix, pszSuffix, ppRdr);
     391            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     392                break;
     393            rc = kldrDyldFindEnumeratePath(kLdrDyldOS2Libpath, pszName, pszPrefix, pszSuffix, ppRdr);
     394            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     395                break;
     396            rc = kldrDyldFindEnumeratePath(kLdrDyldOS2EndLibpath, pszName, pszPrefix, pszSuffix, ppRdr);
     397            break;
     398        }
     399
     400        case KLDRDYLD_SEARCH_WINDOWS:
     401        case KLDRDYLD_SEARCH_WINDOWS_ALTERED:
     402        {
     403            if (!pszSuffix)
     404                pszSuffix = ".dll";
     405
     406            rc = kldrDyldFindTryOpenPath(kLdrDyldWindowsAppDir, kLdrHlpStrLen(kLdrDyldWindowsAppDir),
     407                                         pszName, pszPrefix, pszSuffix, ppRdr);
     408            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     409                break;
     410            if (enmSearch == KLDRDYLD_SEARCH_WINDOWS_ALTERED)
     411            {
     412                rc = kldrDyldFindTryOpenPath(".", 1, pszName, pszPrefix, pszSuffix, ppRdr);
     413                if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     414                    break;
     415            }
     416            rc = kldrDyldFindTryOpenPath(kLdrDyldWindowsSystemDir, kLdrHlpStrLen(kLdrDyldWindowsSystemDir),
     417                                         pszName, pszPrefix, pszSuffix, ppRdr);
     418            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     419                break;
     420            rc = kldrDyldFindTryOpenPath(kLdrDyldWindowsDir, kLdrHlpStrLen(kLdrDyldWindowsDir),
     421                                         pszName, pszPrefix, pszSuffix, ppRdr);
     422            if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     423                break;
     424            if (enmSearch == KLDRDYLD_SEARCH_WINDOWS)
     425            {
     426                rc = kldrDyldFindTryOpenPath(".", 1, pszName, pszPrefix, pszSuffix, ppRdr);
     427                if (rc != KLDR_ERR_MODULE_NOT_FOUND)
     428                    break;
     429            }
     430            rc = kldrDyldFindEnumeratePath(kLdrDyldWindowsPath, pszName, pszPrefix, pszSuffix, ppRdr);
     431            break;
     432        }
     433
     434        case KLDRDYLD_SEARCH_UNIX_COMMON:
     435        {
     436            rc = kldrDyldFindEnumeratePath(kLdrDyldUnixLibraryPath, pszName, pszPrefix, pszSuffix, ppRdr);
     437            if (rc == KLDR_ERR_MODULE_NOT_FOUND)
     438                break;
     439            rc = kldrDyldFindEnumeratePath(kLdrDyldUnixSystemLibraryPath, pszName, pszPrefix, pszSuffix, ppRdr);
     440            break;
     441        }
     442
     443        default:
     444            KLDRDYLDFIND_ASSERT(!"invalid search method");
     445            return KLDR_ERR_INVALID_PARAMETER;
     446
     447    }
     448    return rc;
     449}
     450
     451
     452/**
     453 * Try open the specfied file.
     454 *
     455 * @returns 0 on success and *ppMod pointing to the new module.
     456 * @returns KLDR_ERR_MODULE_NOT_FOUND if the specified file couldn't be opened.
     457 * @returns non-zero kLdr or OS specific status code on other failures.
     458 * @param   pszFilename     The filename.
     459 * @param   ppRdr           Where to store the pointer to the new module.
     460 */
     461static int kldrDyldFindTryOpen(const char *pszFilename, PPKLDRRDR ppRdr)
     462{
     463    return KLDR_ERR_MODULE_NOT_FOUND;
     464}
     465
     466
     467/**
     468 * Composes a filename from the specified directory path,
     469 * prefix (optional), name and suffix (optional, will try with and without).
     470 *
     471 * @param   pchPath     The directory path - this doesn't have to be null terminated.
     472 * @param   cchPath     The length of the path.
     473 * @param   pszName     The base name.
     474 * @param   pszPrefix   The prefix to use. (optional)
     475 * @param   pszSuffix   The suffix to use. (optional)
     476 *                      Will try without first if the name contains a suffix already.
     477 * @param   ppRdr       See kldrDyldFindTryOpen.
     478 *
     479 * @returns See kldrDyldFindTryOpen
     480 */
     481static int kldrDyldFindTryOpenPath(const char *pchPath, size_t cchPath, const char *pszName, const char *pszPrefix,
     482                                   const char *pszSuffix, PPKLDRRDR ppRdr)
     483{
     484    return KLDR_ERR_MODULE_NOT_FOUND;
     485}
     486
     487
     488/**
     489 * Enumerates the specfied path.
     490 *
     491 * @returns Any return code from the kldrDyldFindTryOpenPath() which isn't KLDR_ERR_MODULE_NOT_FOUND.
     492 * @returns KLDR_ERR_MODULE_NOT_FOUND if the end of the search path was reached.
     493 * @param   pszSearchPath   The search path to enumeare.
     494 * @param   pszName         The pszName argument for kldrDyldFindTryOpenPath.
     495 * @param   pszPrefix       The pszPrefix argument for kldrDyldFindTryOpenPath.
     496 * @param   pszSuffix       The pszSuffix argument for kldrDyldFindTryOpenPath.
     497 * @param   ppRdr           The ppRdr argument for kldrDyldFindTryOpenPath.
     498 */
     499static int kldrDyldFindEnumeratePath(const char *pszSearchPath, const char *pszName, const char *pszPrefix,
     500                                     const char *pszSuffix, PPKLDRRDR ppRdr)
     501{
     502    return KLDR_ERR_MODULE_NOT_FOUND;
     503}
     504
    55505
    56506
     
    70520                               KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRDYLDMOD ppMod)
    71521{
     522
     523    int rc;
     524    unsigned fOS2LibpathStrict;
    72525    *ppMod = NULL;
    73     return -1;
     526
     527    /*
     528     * Don't bother if no modules are loaded yet.
     529     */
     530    if (!kLdrDyldHead)
     531        return KLDR_ERR_MODULE_NOT_FOUND;
     532
     533    /*
     534     * Fixup search method alias.
     535     */
     536    if (enmSearch == KLDRDYLD_SEARCH_HOST)
     537        enmSearch = KLDRDYLD_SEARCH_KLDR; /** @todo find more suitable place for this. */
     538
     539    /*
     540     * If this isn't just a filename, the caller has specified a file
     541     * that should be opened directly and not a module name to be searched for.
     542     *
     543     * In order to do the right thing we'll have to open the file and get the
     544     * correct filename for it.
     545     *
     546     * The OS/2 libpath strict method require us to find the correct DLL first.
     547     */
     548    fOS2LibpathStrict = 0;
     549    if (    !kldrHlpIsFilenameOnly(pszName)
     550        ||  (fOS2LibpathStrict = (   enmSearch == KLDRDYLD_SEARCH_OS2
     551                                  && kLdrDyldOS2LibpathStrict[0] == 'T')
     552            )
     553       )
     554    {
     555        PKLDRRDR pRdr;
     556        if (fOS2LibpathStrict)
     557            rc = kldrDyldFindDoSearch(pszName, pszPrefix, pszSuffix, enmSearch, fFlags, &pRdr);
     558        else
     559            rc = kldrDyldFindTryOpen(pszName, &pRdr);
     560        if (!rc)
     561        {
     562            /* do a filename based search. */
     563            const char     *pszFilename = kLdrRdrName(pRdr);
     564            const size_t    cchFilename = kLdrHlpStrLen(pszFilename);
     565            PKLDRDYLDMOD    pCur;
     566            rc = KLDR_ERR_MODULE_NOT_FOUND;
     567            for (pCur = kLdrDyldHead; pCur; pCur = pCur->Load.pNext)
     568            {
     569                if (    pCur->pMod->cchFilename == cchFilename
     570                    &&  !kLdrHlpMemComp(pCur->pMod->pszFilename, pszFilename, cchFilename))
     571                {
     572                    *ppMod = pCur;
     573                    rc = 0;
     574                    break;
     575                }
     576            }
     577            kLdrRdrClose(pRdr);
     578        }
     579    }
     580    else
     581    {
     582        /*
     583         * Get default prefix and suffix.
     584         */
     585        rc = 0;
     586        switch (enmSearch)
     587        {
     588            case KLDRDYLD_SEARCH_KLDR:
     589                if (!pszPrefix && kLdrDyldDefPrefix[0])
     590                    pszPrefix = kLdrDyldDefPrefix;
     591                if (!pszSuffix && kLdrDyldDefSuffix[0])
     592                    pszSuffix = kLdrDyldDefSuffix;
     593                break;
     594
     595            case KLDRDYLD_SEARCH_OS2:
     596                if (!pszSuffix)
     597                    pszSuffix = ".dll";
     598                break;
     599
     600            case KLDRDYLD_SEARCH_WINDOWS:
     601            case KLDRDYLD_SEARCH_WINDOWS_ALTERED:
     602                if (!pszSuffix)
     603                    pszSuffix = ".dll";
     604
     605            case KLDRDYLD_SEARCH_UNIX_COMMON:
     606                break;
     607
     608            default:
     609                KLDRDYLDFIND_ASSERT(!"invalid search method");
     610                rc = KLDR_ERR_INVALID_PARAMETER;
     611                break;
     612        }
     613        if (!rc)
     614        {
     615            const size_t    cchName = kLdrHlpStrLen(pszName);
     616            const size_t    cchPrefix = pszPrefix ? kLdrHlpStrLen(pszPrefix) : 0;
     617            const size_t    cchSuffix = pszSuffix ? kLdrHlpStrLen(pszSuffix) : 0;
     618            const char     *pszNameSuffix = kldrHlpGetSuff(pszName);
     619            PKLDRDYLDMOD    pCur = kLdrDyldHead;
     620
     621            /*
     622             * Some of the methods are case insensitive (ASCII), others are case sensitive.
     623             * To avoid having todo indirect calls to the compare functions here, we split
     624             * ways even if it means a lot of duplicate code.
     625             */
     626            if (   enmSearch == KLDRDYLD_SEARCH_OS2
     627                || enmSearch == KLDRDYLD_SEARCH_WINDOWS
     628                || enmSearch == KLDRDYLD_SEARCH_WINDOWS_ALTERED)
     629            {
     630                const unsigned fNameHasSuffix = pszNameSuffix
     631                                             && kLdrHlpStrLen(pszNameSuffix) == cchSuffix
     632                                             && kLdrHlpMemIComp(pszNameSuffix, pszName + cchName - cchSuffix, cchSuffix);
     633                for (; pCur; pCur = pCur->Load.pNext)
     634                {
     635                    /* match global / specific */
     636                    if (    !pCur->fGlobalOrSpecific
     637                        &&  !(fFlags & KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE))
     638                        continue;
     639
     640                    /* match name */
     641                    if (    pCur->pMod->cchName == cchName
     642                        &&  !kLdrHlpMemIComp(pCur->pMod->pszName, pszName, cchName))
     643                        break;
     644                    if (cchPrefix)
     645                    {
     646                        if (    pCur->pMod->cchName == cchName + cchPrefix
     647                            &&  !kLdrHlpMemIComp(pCur->pMod->pszName, pszPrefix, cchPrefix)
     648                            &&  !kLdrHlpMemIComp(pCur->pMod->pszName + cchPrefix, pszName, cchName))
     649                        break;
     650                    }
     651                    if (cchSuffix)
     652                    {
     653                        if (    pCur->pMod->cchName == cchName + cchSuffix
     654                            &&  !kLdrHlpMemIComp(pCur->pMod->pszName + cchName, pszSuffix, cchSuffix)
     655                            &&  !kLdrHlpMemIComp(pCur->pMod->pszName, pszName, cchName))
     656                        break;
     657                        if (    fNameHasSuffix
     658                            &&  pCur->pMod->cchName == cchName - cchSuffix
     659                            &&  !kLdrHlpMemIComp(pCur->pMod->pszName, pszName, cchName - cchSuffix))
     660                        break;
     661                        if (cchPrefix)
     662                        {
     663                            if (    pCur->pMod->cchName == cchName + cchPrefix + cchSuffix
     664                                &&  !kLdrHlpMemIComp(pCur->pMod->pszName, pszPrefix, cchPrefix)
     665                                &&  !kLdrHlpMemIComp(pCur->pMod->pszName + cchPrefix, pszName, cchName)
     666                                &&  !kLdrHlpMemIComp(pCur->pMod->pszName + cchPrefix + cchName, pszSuffix, cchSuffix))
     667                            break;
     668                            if (    fNameHasSuffix
     669                                &&  pCur->pMod->cchName == cchName + cchPrefix - cchSuffix
     670                                &&  !kLdrHlpMemIComp(pCur->pMod->pszName, pszPrefix, cchPrefix)
     671                                &&  !kLdrHlpMemIComp(pCur->pMod->pszName + cchPrefix, pszName, cchName - cchSuffix))
     672                            break;
     673                        }
     674                    }
     675                }
     676            }
     677            else
     678            {
     679                const unsigned fNameHasSuffix = pszNameSuffix
     680                                             && kLdrHlpStrLen(pszNameSuffix) == cchSuffix
     681                                             && kLdrHlpMemComp(pszNameSuffix, pszName + cchName - cchSuffix, cchSuffix);
     682                for (; pCur; pCur = pCur->Load.pNext)
     683                {
     684                    /* match global / specific */
     685                    if (    !pCur->fGlobalOrSpecific
     686                        &&  !(fFlags & KLDRYDLD_LOAD_FLAGS_SPECIFIC_MODULE))
     687                        continue;
     688
     689                    /* match name */
     690                    if (    pCur->pMod->cchName == cchName
     691                        &&  !kLdrHlpMemComp(pCur->pMod->pszName, pszName, cchName))
     692                        break;
     693                    if (cchPrefix)
     694                    {
     695                        if (    pCur->pMod->cchName == cchName + cchPrefix
     696                            &&  !kLdrHlpMemComp(pCur->pMod->pszName, pszPrefix, cchPrefix)
     697                            &&  !kLdrHlpMemComp(pCur->pMod->pszName + cchPrefix, pszName, cchName))
     698                        break;
     699                    }
     700                    if (cchSuffix)
     701                    {
     702                        if (    pCur->pMod->cchName == cchName + cchSuffix
     703                            &&  !kLdrHlpMemComp(pCur->pMod->pszName + cchName, pszSuffix, cchSuffix)
     704                            &&  !kLdrHlpMemComp(pCur->pMod->pszName, pszName, cchName))
     705                        break;
     706                        if (    fNameHasSuffix
     707                            &&  pCur->pMod->cchName == cchName - cchSuffix
     708                            &&  !kLdrHlpMemComp(pCur->pMod->pszName, pszName, cchName - cchSuffix))
     709                        break;
     710                        if (cchPrefix)
     711                        {
     712                            if (    pCur->pMod->cchName == cchName + cchPrefix + cchSuffix
     713                                &&  !kLdrHlpMemComp(pCur->pMod->pszName, pszPrefix, cchPrefix)
     714                                &&  !kLdrHlpMemComp(pCur->pMod->pszName + cchPrefix, pszName, cchName)
     715                                &&  !kLdrHlpMemComp(pCur->pMod->pszName + cchPrefix + cchName, pszSuffix, cchSuffix))
     716                            break;
     717                            if (    pCur->pMod->cchName == cchName + cchPrefix - cchSuffix
     718                                &&  !kLdrHlpMemComp(pCur->pMod->pszName, pszPrefix, cchPrefix)
     719                                &&  !kLdrHlpMemComp(pCur->pMod->pszName + cchPrefix, pszName, cchName - cchSuffix))
     720                            break;
     721                        }
     722                    }
     723                }
     724            }
     725            if (pCur)
     726            {
     727                *ppMod = pCur;
     728                rc = 0;
     729            }
     730            else
     731                rc = KLDR_ERR_MODULE_NOT_FOUND;
     732        }
     733    }
     734
     735    return rc;
    74736}
    75737
Note: See TracChangeset for help on using the changeset viewer.