Changeset 2867


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

top half of the filesearching is done.

Location:
trunk/kLdr
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdr.h

    r2861 r2867  
    855855#define KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT      0x00000004
    856856/** We're loading the executable module.
    857  * Internal flag which will be rejected by kLdrDyldLoad. */
     857 * @internal */
    858858#define KLDRDYLD_LOAD_FLAGS_EXECUTABLE          0x40000000
    859859/** @} */
  • trunk/kLdr/kLdrDyld.c

    r2866 r2867  
    9494char            g_szkLdrDyldError[1024];
    9595
    96 /** The Library search path. */
    97 char            kLdrDyldLibraryPath[4096];
    98 
    9996/** The default flags. */
    10097uint32_t        kLdrDyldFlags = 0;
    10198/** The default search method. */
    10299KLDRDYLDSEARCH  kLdrDyldSearch = KLDRDYLD_SEARCH_INVALID;
    103 /** The default DLL prefix. */
    104 char            kLdrDyldDefPrefix[16];
    105 /** The default DLL suffix. */
    106 char            kLdrDyldDefSuffix[16];
    107100
    108101
     
    236229void kldrDoDyldLoadExe(PKLDREXEARGS pArgs)
    237230{
    238     void *pvStack = NULL;
    239     size_t cbStack = 0;
    240     PKLDRDYLDMOD pExe = NULL;
     231    void *pvStack;
     232    size_t cbStack;
     233    PKLDRDYLDMOD pExe;
    241234    int rc;
    242235
    243236    /*
    244      * Copy the arguments into the globals and do loader init.
     237     * Copy the arguments into the globals and do loader init (probably already initialized).
    245238     */
    246239    kLdrDyldFlags = pArgs->fFlags;
    247240    kLdrDyldSearch = pArgs->enmSearch;
    248     kLdrHlpMemCopy(kLdrDyldDefPrefix, pArgs->szDefPrefix, KLDR_MIN(sizeof(pArgs->szDefPrefix), sizeof(kLdrDyldDefPrefix)));
    249     kLdrHlpMemCopy(kLdrDyldDefSuffix, pArgs->szDefSuffix, KLDR_MIN(sizeof(pArgs->szDefSuffix), sizeof(kLdrDyldDefSuffix)));
    250     kLdrHlpMemCopy(kLdrDyldLibraryPath, pArgs->szLibPath, KLDR_MIN(sizeof(pArgs->szLibPath), sizeof(kLdrDyldLibraryPath)));
     241    if (pArgs->szDefPrefix[0] != '\0')
     242        kLdrHlpMemCopy(kLdrDyldDefPrefix, pArgs->szDefPrefix, KLDR_MIN(sizeof(pArgs->szDefPrefix), sizeof(kLdrDyldDefPrefix)));
     243    if (pArgs->szDefSuffix[0] != '\0')
     244        kLdrHlpMemCopy(kLdrDyldDefSuffix, pArgs->szDefSuffix, KLDR_MIN(sizeof(pArgs->szDefSuffix), sizeof(kLdrDyldDefSuffix)));
     245    /* append */ /** @todo create a function for doing this, an exposed api preferably. */
     246    cbStack = sizeof(kLdrDyldPath) - kLdrHlpStrLen(kLdrDyldPath); /* borrow cbStack for a itty bit. */
     247    kLdrHlpMemCopy(kLdrDyldPath, pArgs->szLibPath, KLDR_MIN(sizeof(pArgs->szLibPath), cbStack));
     248    kLdrDyldPath[sizeof(kLdrDyldPath) - 1] = '\0';
    251249
    252250    g_fBootstrapping = 1;
  • 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
  • trunk/kLdr/kLdrHlp.c

    r2861 r2867  
    385385 * Get an environment variable.
    386386 *
    387  * @returns 0 on success, on failure an OS specific status code is returned.
     387 * @returns 0 on success.
     388 * @returns KLDR_ERR_BUFFER_OVERFLOW on if the buffer is too small (it'll be partially filled).
     389 * @returns KLDR_ERR_SYMBOL_NOT_FOUND if not found. (Yeah, abusing the status code, but it's only internally...)
     390 * @returns OS specfic status code on other error.
    388391 * @param   pszVar      The variable name.
    389  * @param   pszVal      Where to store the value. NULL is allowed if *pcchVal is 0.
    390  * @param   pcchVal     On input the size of the buffer pointed to by pszVal.
    391  *                      On output this contains the string length on success, while on
    392  *                      failure (including buffer overflow) the require buffer size.
    393  *                      If the variable wasn't found, it's set to 0.
    394  */
    395 int     kldrHlpGetEnv(const char *pszVar, char *pszVal, size_t *pcchVal)
     392 * @param   pszVal      Where to store the value.
     393 * @param   cchVal      The size of the buffer pointed to by pszVal.
     394 */
     395int     kldrHlpGetEnv(const char *pszVar, char *pszVal, size_t cchVal)
    396396{
    397397#ifdef __OS2__
    398398    PSZ pszValue = NULL;
    399     int rc = DosScanEnv((PCSZ)pszVar, &pszValue);
     399    int rc;
     400
     401    *pszVal = '\0';
     402    rc = DosScanEnv((PCSZ)pszVar, &pszValue);
    400403    if (!rc)
    401404    {
    402405        size_t cch = kLdrHlpStrLen(pszValue);
    403         if (pszVal)
    404         {
    405             if (*pcchVal > cch)
    406             {
    407                 kLdrHlpMemCopy(pszVal, pszValue, cch + 1);
    408                 *pcchVal = cch;
    409             }
    410             else if (*pcchVal)
     406        if (cchVal > cch)
     407            kLdrHlpMemCopy(pszVal, pszValue, cch + 1);
     408        else
     409        {
     410            rc = KLDR_ERR_BUFFER_OVERFLOW;
     411            if (cchVal > 1)
    411412            {
    412413                kLdrHlpMemCopy(pszVal, pszValue, *pcchVal);
    413414                pszVal[*pcchVal - 1] = '\0';
    414                 rc = ERROR_BUFFER_OVERFLOW;
    415                 *pcchVal = cch + 1;
    416415            }
    417416        }
    418         else
    419         {
    420             rc = ERROR_BUFFER_OVERFLOW;
    421             *pcchVal = cch + 1;
    422         }
    423417    }
    424418    else
    425     {
    426         if (pszVal)
    427             *pszVal = '\0';
    428         *pcchVal = 0;
    429     }
    430 
     419        rc = KLDR_ERR_SYMBOL_NOT_FOUND;
    431420    return rc;
    432421
    433422#elif defined(__WIN__)
    434423    DWORD cch;
     424
    435425    SetLastError(0);
    436     cch = GetEnvironmentVariable(pszVar, pszVal, *pcchVal);
    437     if (cch)
    438     {
    439         *pcchVal = cch;
     426    cch = GetEnvironmentVariable(pszVar, pszVal, cchVal);
     427    if (cch < cchVal)
    440428        return 0;
    441     }
    442     if (!GetLastError() == ERROR_ENVVAR_NOT_FOUND)
    443     {
    444         *pcchVal = 0;
    445         return ERROR_ENVVAR_NOT_FOUND;
    446     }
    447     *pcchVal = cch;
    448     return ERROR_BUFFER_OVERFLOW;
     429
     430    *pszVal = '\0';
     431    if (cch >= cchVal)
     432        return KLDR_ERR_BUFFER_OVERFLOW;
     433    if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
     434        return KLDR_ERR_SYMBOL_NOT_FOUND;
     435    return GetLastError();
    449436
    450437#else
     
    458445 *
    459446 * @returns 0 and *pcb on success.
    460  *          Some non-zero OS or kLdr status code on failure.
     447 * @returns On failure see kldrHlpGetEnv.
    461448 * @param   pszVar  The name of the variable.
    462449 * @param   pcb     Where to put the value.
     
    472459
    473460    *pcb = 0;
    474     rc = kldrHlpGetEnv(pszVar, szVal,  &cchVal);
     461    rc = kldrHlpGetEnv(pszVar, szVal, cchVal);
    475462    if (rc)
    476463        return rc;
     
    602589
    603590
     591/**
     592 * Checks if this is only a filename or if it contains any kind
     593 * of drive, directory, or server specs.
     594 *
     595 * @returns 1 if this is a filename only.
     596 * @returns 0 of it's isn't only a filename.
     597 * @param   pszFilename     The filename to parse.
     598 */
     599int kldrHlpIsFilenameOnly(const char *pszFilename)
     600{
     601    const char *pszLast = NULL;
     602    for (;;)
     603    {
     604        const char ch = *pszFilename++;
     605#if defined(__OS2__) || defined(__WIN__)
     606        if (ch == '/' || ch == '\\' || ch == ':')
     607#else
     608        if (ch == '/')
     609#endif
     610            return 0;
     611        if (!ch)
     612            return 1;
     613    }
     614}
     615
    604616
    605617/**
  • trunk/kLdr/kLdrHlp.h

    r2861 r2867  
    156156void    kldrHlpFree(void *pv);
    157157
    158 int     kldrHlpGetEnv(const char *pszVar, char *pszVal, size_t *pcchVal);
     158int     kldrHlpGetEnv(const char *pszVar, char *pszVal, size_t cchVal);
    159159int     kldrHlpGetEnvUZ(const char *pszVar, size_t *pcb);
    160160char   *kldrHlpGetFilename(const char *pszFilename);
     161char   *kldrHlpGetSuff(const char *pszFilename);
    161162char   *kldrHlpGetExt(const char *pszFilename);
     163int     kldrHlpIsFilenameOnly(const char *pszFilename);
    162164void    kldrHlpExit(int rc);
    163165void    kldrHlpSleep(unsigned cMillies);
  • trunk/kLdr/kLdrInternal.h

    r2858 r2867  
    399399extern char             g_szkLdrDyldError[1024];
    400400
    401 /** The Library search path. */
    402 extern char             kLdrDyldLibraryPath[4096];
     401extern char             kLdrDyldPath[8192];
     402extern char             kLdrDyldDefPrefix[16];
     403extern char             kLdrDyldDefSuffix[16];
    403404
    404405
Note: See TracChangeset for help on using the changeset viewer.