Changeset 2867
- Timestamp:
- Nov 11, 2006, 10:33:17 AM (19 years ago)
- Location:
- trunk/kLdr
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdr.h
r2861 r2867 855 855 #define KLDRDYLD_LOAD_FLAGS_RECURSIVE_INIT 0x00000004 856 856 /** We're loading the executable module. 857 * Internal flag which will be rejected by kLdrDyldLoad.*/857 * @internal */ 858 858 #define KLDRDYLD_LOAD_FLAGS_EXECUTABLE 0x40000000 859 859 /** @} */ -
trunk/kLdr/kLdrDyld.c
r2866 r2867 94 94 char g_szkLdrDyldError[1024]; 95 95 96 /** The Library search path. */97 char kLdrDyldLibraryPath[4096];98 99 96 /** The default flags. */ 100 97 uint32_t kLdrDyldFlags = 0; 101 98 /** The default search method. */ 102 99 KLDRDYLDSEARCH kLdrDyldSearch = KLDRDYLD_SEARCH_INVALID; 103 /** The default DLL prefix. */104 char kLdrDyldDefPrefix[16];105 /** The default DLL suffix. */106 char kLdrDyldDefSuffix[16];107 100 108 101 … … 236 229 void kldrDoDyldLoadExe(PKLDREXEARGS pArgs) 237 230 { 238 void *pvStack = NULL;239 size_t cbStack = 0;240 PKLDRDYLDMOD pExe = NULL;231 void *pvStack; 232 size_t cbStack; 233 PKLDRDYLDMOD pExe; 241 234 int rc; 242 235 243 236 /* 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). 245 238 */ 246 239 kLdrDyldFlags = pArgs->fFlags; 247 240 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'; 251 249 252 250 g_fBootstrapping = 1; -
trunk/kLdr/kLdrDyldFind.c
r2843 r2867 30 30 * Header Files * 31 31 *******************************************************************************/ 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 32 53 #include <kLdr.h> 33 54 #include "kLdrHlp.h" 34 55 #include "kLdrInternal.h" 35 56 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 */ 83 char kLdrDyldPath[8192]; 84 /** The kLdr application directory. 85 * This is initialized when the executable is 'loaded' or by a kLdr user. 86 */ 87 char 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 */ 91 char 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 */ 95 char 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 */ 106 char 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 */ 111 char 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 */ 116 char 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 */ 121 char 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 */ 130 char 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 */ 135 char 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 */ 140 char 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 */ 146 char 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 */ 157 char kLdrDyldUnixLibraryPath[8192]; 158 /** The Common Unix system library path. */ 159 char 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 *******************************************************************************/ 169 static int kldrDyldFindDoSearch(const char *pszName, const char *pszPrefix, const char *pszSuffix, 170 KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRRDR ppRdr); 171 static int kldrDyldFindTryOpen(const char *pszFilename, PPKLDRRDR ppRdr); 172 static int kldrDyldFindTryOpenPath(const char *pchPath, size_t cchPath, const char *pszName, const char *pszPrefix, 173 const char *pszSuffix, PPKLDRRDR ppRdr); 174 static 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 */ 183 int 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 36 256 37 257 /** 38 258 * Locates and opens a module using the specified search method. 39 259 * 40 * @returns 0 and *pp Rdron success, non-zero OS specific error on failure.260 * @returns 0 and *ppMod on success, non-zero OS specific error on failure. 41 261 * 42 262 * @param pszName Partial or complete name, it's specific to the search method to determin which. … … 50 270 KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRDYLDMOD ppMod) 51 271 { 272 int rc; 273 PKLDRRDR pRdr = NULL; 274 52 275 *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; 54 332 } 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 */ 348 static 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 */ 461 static 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 */ 481 static 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 */ 499 static 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 55 505 56 506 … … 70 520 KLDRDYLDSEARCH enmSearch, unsigned fFlags, PPKLDRDYLDMOD ppMod) 71 521 { 522 523 int rc; 524 unsigned fOS2LibpathStrict; 72 525 *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; 74 736 } 75 737 -
trunk/kLdr/kLdrHlp.c
r2861 r2867 385 385 * Get an environment variable. 386 386 * 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. 388 391 * @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 */ 395 int kldrHlpGetEnv(const char *pszVar, char *pszVal, size_t cchVal) 396 396 { 397 397 #ifdef __OS2__ 398 398 PSZ pszValue = NULL; 399 int rc = DosScanEnv((PCSZ)pszVar, &pszValue); 399 int rc; 400 401 *pszVal = '\0'; 402 rc = DosScanEnv((PCSZ)pszVar, &pszValue); 400 403 if (!rc) 401 404 { 402 405 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) 411 412 { 412 413 kLdrHlpMemCopy(pszVal, pszValue, *pcchVal); 413 414 pszVal[*pcchVal - 1] = '\0'; 414 rc = ERROR_BUFFER_OVERFLOW;415 *pcchVal = cch + 1;416 415 } 417 416 } 418 else419 {420 rc = ERROR_BUFFER_OVERFLOW;421 *pcchVal = cch + 1;422 }423 417 } 424 418 else 425 { 426 if (pszVal) 427 *pszVal = '\0'; 428 *pcchVal = 0; 429 } 430 419 rc = KLDR_ERR_SYMBOL_NOT_FOUND; 431 420 return rc; 432 421 433 422 #elif defined(__WIN__) 434 423 DWORD cch; 424 435 425 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) 440 428 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(); 449 436 450 437 #else … … 458 445 * 459 446 * @returns 0 and *pcb on success. 460 * Some non-zero OS or kLdr status code on failure.447 * @returns On failure see kldrHlpGetEnv. 461 448 * @param pszVar The name of the variable. 462 449 * @param pcb Where to put the value. … … 472 459 473 460 *pcb = 0; 474 rc = kldrHlpGetEnv(pszVar, szVal, &cchVal);461 rc = kldrHlpGetEnv(pszVar, szVal, cchVal); 475 462 if (rc) 476 463 return rc; … … 602 589 603 590 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 */ 599 int 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 604 616 605 617 /** -
trunk/kLdr/kLdrHlp.h
r2861 r2867 156 156 void kldrHlpFree(void *pv); 157 157 158 int kldrHlpGetEnv(const char *pszVar, char *pszVal, size_t *pcchVal);158 int kldrHlpGetEnv(const char *pszVar, char *pszVal, size_t cchVal); 159 159 int kldrHlpGetEnvUZ(const char *pszVar, size_t *pcb); 160 160 char *kldrHlpGetFilename(const char *pszFilename); 161 char *kldrHlpGetSuff(const char *pszFilename); 161 162 char *kldrHlpGetExt(const char *pszFilename); 163 int kldrHlpIsFilenameOnly(const char *pszFilename); 162 164 void kldrHlpExit(int rc); 163 165 void kldrHlpSleep(unsigned cMillies); -
trunk/kLdr/kLdrInternal.h
r2858 r2867 399 399 extern char g_szkLdrDyldError[1024]; 400 400 401 /** The Library search path. */ 402 extern char kLdrDyldLibraryPath[4096]; 401 extern char kLdrDyldPath[8192]; 402 extern char kLdrDyldDefPrefix[16]; 403 extern char kLdrDyldDefSuffix[16]; 403 404 404 405
Note:
See TracChangeset
for help on using the changeset viewer.