Changeset 3404 for trunk/src/kernel32/winimagebase.cpp
- Timestamp:
- Apr 16, 2000, 12:42:13 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/winimagebase.cpp
r3399 r3404 1 /* $Id: winimagebase.cpp,v 1.1 7 2000-04-16 06:47:22 birdExp $ */1 /* $Id: winimagebase.cpp,v 1.18 2000-04-16 10:42:12 sandervl Exp $ */ 2 2 3 3 /* 4 4 * Win32 PE Image base class 5 5 * 6 * Copyright 1998- 2000Sander van Leeuwen (sandervl@xs4all.nl)7 * Copyright 1998 -2000 Knut St. Osmundsen (knut.stange.osmundsen@pmsc.no)6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 * Copyright 1998 Knut St. Osmundsen 8 8 * 9 9 * Project Odin Software License can be found in LICENSE.TXT … … 11 11 */ 12 12 13 #define INCL_DOSFILEMGR /* File Manager values */ 14 #define INCL_DOSMODULEMGR /* DOS Module manager */ 15 #define INCL_DOSERRORS /* DOS Error values */ 16 #define INCL_DOSPROCESS /* DOS Process values */ 17 #define INCL_DOSMISC /* DOS Miscellanous values */ 18 #define INCL_WIN /* All Win API */ 19 #define INCL_BASE /* All Dos API */ 20 #include <os2wrap.h> /* Odin32 OS/2 API wrappers. */ 21 22 #include <stdio.h> /* C Library Standard I/O */ 23 #include <string.h> /* C Library string operations */ 24 #include <stdlib.h> /* C Library Standard stuff */ 25 26 #include <misc.h> /* Odin32 Miscellaneous definitions, debug stuff*/ 27 #include <win32type.h> /* Odin32 Common types and definition. */ 28 #include "winimagebase.h" /* Odin32 Executable Image Base Class */ 29 #include "windllbase.h" /* Odin32 Dll Base Class */ 30 #include "winexebase.h" /* Odin32 Exe Base Class */ 31 #include <pefile.h> /* Odin32 PE definitions */ 32 #include <unicode.h> /* Odin32 Unicode conversion */ 33 #include <winres.h> /* Odin32 Resource Class */ 13 #define INCL_DOSFILEMGR /* File Manager values */ 14 #define INCL_DOSMODULEMGR 15 #define INCL_DOSERRORS /* DOS Error values */ 16 #define INCL_DOSPROCESS /* DOS Process values */ 17 #define INCL_DOSMISC /* DOS Miscellanous values */ 18 #define INCL_WIN 19 #define INCL_BASE 20 #include <os2wrap.h> //Odin32 OS/2 api wrappers 21 22 #include <stdio.h> 23 #include <string.h> 24 #include <stdlib.h> 25 26 #include <assert.h> 27 #include <misc.h> 28 #include <win32type.h> 29 #include <winimagebase.h> 30 #include <windllbase.h> 31 #include <winexebase.h> 32 #include <pefile.h> 33 #include <unicode.h> 34 #include <winres.h> 34 35 #include "oslibmisc.h" 35 36 #include "oslibdos.h" 36 37 #include "initterm.h" 38 #include "directory.h" 37 39 #include <win\virtual.h> 38 #include "directory.h" /* InternalGet<Windows/System>Directory. */ 39 #include <os2newapi.h> /* DosQueryHeaderInfo. */ 40 41 #define DBG_LOCALLOG DBG_winimagebase 40 41 #define DBG_LOCALLOG DBG_winimagebase 42 42 #include "dbglocal.h" 43 43 … … 115 115 item = loadedDlls.Head(); 116 116 while(item) { 117 118 119 120 } 121 117 if(loadedDlls.getItem(item) == (ULONG)image) { 118 ret = TRUE; 119 break; 120 } 121 item = loadedDlls.getNext(item); 122 122 } 123 123 dlllistmutex.leave(); … … 132 132 return 0x40000; //NT 4 133 133 } 134 135 136 /** 137 * Finds a executable module (or really any file) using the DLL search order. 138 * The search order used is: 139 * 1. The directory from which the application loaded. 140 * 2. The current directory. 141 * 3. System directory. (GetSystemDirectory returns its path) 142 * (Windows NT/2k directory name: SYSTEM32) 143 * 4. (Windows NT/2k: The 16-bit Windows system directory. There 144 * is no function that obtains the path of this directory. 145 * (Directory name: SYSTEM) 146 * THIS IS NOT SEARCHED BY ODIN.) 147 * 5. The Windows directory. (GetWindowsDirectory returns its path) 148 * 6. The Directories listed in the PATH environment variable. 149 * 7. The Directories listed in the BEGINLIBPATH. 150 * 8. The Directories listed in the LIBPATH. 151 * 9. The Directories listed in the ENDLIBPATH. 152 * 153 * @returns Success indicator. TRUE: found FALSE: not found. 154 * Note! pszFullname will normally contain the contents of 155 * pszFilename upon return, there is one case FALSE case when 156 * pszFullname will be empty upon return. That's when the buffer 157 * isn't large enough to hold the content of pszFilename including 158 * an extention. 159 * So, please check for the return value! 160 * @param pszFilename File to find. This name should not have a path! 161 * If it don't contains an '.', ".DLL" is appended to 162 * the name. 163 * @param pszFullname Pointer to output buffer, this will hold the 164 * a fully qualified, uppercased, filename upon 165 * successful return. 166 * @param cchFullname Size of the buffer pointer to by pszFullname. 167 * (A length of at least CCHMAXPATH is recommended.) 168 * @parm pszAltPath Pointer to alternate first executable path. This 169 * will include a filename or at least a backslash at 170 * the end. 171 * If this is NULL (which is it by default) the 172 * executable path is used. If this is specified, 173 * this path is used instead. This is intented used 174 * to implement the LoadLibraryEx flag 175 * LOAD_WITH_ALTERED_SEARCH_PATH. 176 * 177 * @status Completely implemented. 178 * @author Sander van Leeuwen (sandervl@xs4all.nl) 179 * knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 180 * @remark 181 */ 182 BOOL Win32ImageBase::findDll(const char *pszFileName, 183 char *pszFullName, int cchFullName, 184 const char *pszAltPath /*=NULL*/) 185 { 186 BOOL fRet = FALSE; /* Return value. (Pessimistic attitude! Init it to FALSE...) */ 187 char * psz; /* General string pointer. */ 188 int cchFileName; /* Length of the normalized filename (after ".DLL" is added). */ 189 struct localvars /* local variables which are to big to fit onto the stack. */ 190 { 191 char szPath[1024]; /* Path buffer. Used to store pathlists. 1024 should be enough */ 192 /* for LIBPATH (which at least had a limit of ca. 750 chars). */ 193 char sz[CCHMAXPATH]; /* Filename/path buffer. (Normally used to build filenames */ 194 /* which are passed in as search experessions to DosFindFirst.) */ 195 FILEFINDBUF3 findbuf3; /* DosFindFirst buffer. */ 196 } * plv; 197 int iPath; /* Current path or pathlist being examined. This is the loop */ 198 /* variable looping on the FINDDLL_* defines. */ 199 200 /* These defines sets the order the paths and pathlists are examined. */ 201 #define FINDDLL_EXECUTABLEDIR 1 202 #define FINDDLL_CURRENTDIR 2 203 #define FINDDLL_SYSTEM32DIR 3 204 #define FINDDLL_SYSTEM16DIR 4 205 #define FINDDLL_WINDIR 5 206 #define FINDDLL_PATH 6 207 #define FINDDLL_BEGINLIBPATH 7 208 #define FINDDLL_LIBPATH 8 209 #define FINDDLL_ENDLIBPATH 9 210 #define FINDDLL_FIRST FINDDLL_EXECUTABLEDIR 211 #define FINDDLL_LAST FINDDLL_ENDLIBPATH 212 213 214 /** @sketch 215 * Copy the filename to be found to the outputbuffer, and add .DLL if not '.' 216 * is found in the name. This has two reasons: 217 * 1) When searching paths we simply append the buffer contents to the path 218 * being examined. 219 * 2) The buffer will at least return the passed in filename. 220 */ 221 psz = strchr(pszFileName, '.'); 222 cchFileName = strlen(pszFileName) + (psz ? 0 : 4); 223 if (cchFileName >= cchFullName) 224 { 225 dassert(cchFileName < cchFullName, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 226 "cchFileName (%d) >= cchFullName (%d)", 227 pszFileName, pszFullName, cchFullName, cchFileName, cchFullName)); 228 *pszFullName = '\0'; 229 return FALSE; 230 } 231 strcpy(pszFullName, pszFileName); 232 if (psz == NULL) 233 strcpy(pszFullName + cchFileName - 4, ".DLL"); 234 235 236 /** @sketch 237 * Allocate memory for local variables. 238 */ 239 plv = (struct localvars *)malloc(sizeof(*plv)); 240 if (!plv) 241 { 242 dassert(plv, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 243 "malloc failed allocating %d bytes of memory for local variables.", 244 pszFileName, pszFullName, cchFullName, sizeof(*plv))); 245 return FALSE; 246 } 247 248 249 /** @sketch 250 * Loop thru the paths and pathlists searching them for the filename. 251 */ 252 for (iPath = FINDDLL_FIRST; iPath <= FINDDLL_LAST; iPath++) 253 { 254 APIRET rc; /* Returncode from OS/2 APIs. */ 255 const char * pszPath; /* Pointer to the path being examined. */ 256 257 /** @sketch 258 * Get the path/dir to examin. (This is determined by the value if iPath.) 259 */ 260 switch (iPath) 261 { 262 case FINDDLL_EXECUTABLEDIR: 263 if (pszAltPath) 264 pszPath = strcpy(plv->szPath, pszAltPath); 265 else 266 { 267 /* ASSUMES: getFullPath allways returns a fully qualified 268 * path, ie. with at least one backslash. and that all 269 * slashes are backslashes! 270 */ 271 if (!WinExe) continue; 272 pszPath = strcpy(plv->szPath, WinExe->getFullPath()); 273 } 274 psz = strrchr(plv->szPath, '\\'); 275 dassert(psz, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 276 "WinExe->getFullPath returned a path not fully qualified: %s", 277 pszFileName, pszFullName, cchFullName, pszPath)); 278 if (psz) 279 *psz = '\0'; 280 else 281 continue; 282 break; 283 284 case FINDDLL_CURRENTDIR: 285 pszPath = "."; 286 break; 287 288 case FINDDLL_SYSTEM32DIR: 289 pszPath = InternalGetSystemDirectoryA(); 290 break; 291 292 case FINDDLL_SYSTEM16DIR: 293 #if 1 294 continue; /* Skip this index */ 295 #else 296 pszPath = InternalGetWindowsDirectoryA(); 297 strcpy(plv->sz2, InternalGetWindowsDirectoryA()); 298 strcat(plv->sz2, "\SYSTEM"); 299 break; 300 #endif 301 302 case FINDDLL_WINDIR: 303 pszPath = InternalGetWindowsDirectoryA(); 304 break; 305 306 case FINDDLL_PATH: 307 pszPath = getenv("PATH"); 308 break; 309 310 case FINDDLL_BEGINLIBPATH: 311 rc = DosQueryExtLIBPATH(plv->szPath, BEGIN_LIBPATH); 312 if (rc != NO_ERROR) 313 { 314 dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 315 "DosQueryExtLIBPATH failed with rc=%d, iPath=%d", 316 pszFileName, pszFullName, cchFullName, rc, iPath)); 317 continue; 318 } 319 pszPath = plv->szPath; 320 break; 321 322 case FINDDLL_LIBPATH: 323 rc = DosQueryHeaderInfo(NULLHANDLE, 0, plv->szPath, sizeof(plv->szPath), QHINF_LIBPATH); 324 if (rc != NO_ERROR) 325 { 326 dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 327 "DosQueryHeaderInfo failed with rc=%d, iPath=%d", 328 pszFileName, pszFullName, cchFullName, rc, iPath)); 329 continue; 330 } 331 pszPath = plv->szPath; 332 break; 333 334 case FINDDLL_ENDLIBPATH: 335 rc = DosQueryExtLIBPATH(plv->szPath, END_LIBPATH); 336 if (rc != NO_ERROR) 337 { 338 dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 339 "DosQueryExtLIBPATH failed with rc=%d, iPath=%d", 340 pszFileName, pszFullName, cchFullName, rc, iPath)); 341 continue; 342 } 343 pszPath = plv->szPath; 344 break; 345 346 default: /* !internalerror! */ 347 goto end; 348 } 349 350 351 /** @sketch 352 * pszPath is now set to the pathlist to be searched. 353 * So we'll loop thru all the paths in the list. 354 */ 355 while (pszPath != NULL && *pszPath != '\0') 356 { 357 HDIR hDir; /* Find handle used when calling FindFirst. */ 358 ULONG culFiles; /* Number of files to find / found. */ 359 char * pszNext; /* Pointer to the next pathlist path */ 360 int cch; /* Length of path (including the slash after the slash is added). */ 361 362 /** @sketch 363 * Find the end of the path. 364 * Copy the path into the plv->sz buffer. 365 * Set pszNext. 366 */ 367 pszNext = strchr(pszPath, ';'); 368 if (pszNext != NULL) 369 { 370 cch = pszNext - pszPath; 371 pszNext++; 372 } 373 else 374 cch = strlen(pszPath); 375 376 if (cch + cchFileName + 1 >= sizeof(plv->sz)) /* assertion */ 377 { 378 dassert(cch + cchFileName + 1 < sizeof(plv->sz), ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 379 "cch (%d) + cchFileName (%d) + 1 < sizeof(plv->sz) (%d) - paths too long!, iPath=%d", 380 pszFileName, pszFullName, cchFullName, cch, cchFileName, sizeof(plv->sz), iPath)); 381 pszPath = pszNext; 382 continue; 383 } 384 memcpy(plv->sz, pszPath, cch); //arg! Someone made strncpy not work as supposed! 385 386 387 /** @sketch 388 * Add a '\\' and the filename (pszFullname) to the path; 389 * then we'll have a fullpath. 390 */ 391 plv->sz[cch++] = '\\'; 392 strcpy(&plv->sz[cch], pszFullName); 393 394 395 /** @sketch 396 * Use DosFindFirst to check if the file exists. 397 * IF the file exists THEN 398 * Query Fullpath using OS/2 API. 399 * IF unsuccessful THEN return relative name. 400 * Check that the fullname buffer is large enough. 401 * Copy the filename found to the fullname buffer. 402 * ENDIF 403 * IF successful THEN uppercase the fullname buffer. 404 * goto end 405 * ENDIF 406 */ 407 hDir = HDIR_CREATE; 408 culFiles = 1; 409 rc = DosFindFirst(plv->sz, &hDir, FILE_NORMAL, 410 &plv->findbuf3, sizeof(plv->findbuf3), 411 &culFiles, FIL_STANDARD); 412 DosFindClose(hDir); 413 if (culFiles >= 1 && rc == NO_ERROR) 414 { 415 /* Return full path - we'll currently return a relative path. */ 416 rc = DosQueryPathInfo(plv->sz, FIL_QUERYFULLNAME, pszFullName, cchFullName); 417 fRet = rc == NO_ERROR; 418 if (!fRet) 419 { 420 /* Return a relative path - probably better that failing... */ 421 dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 422 "rc = %d", 423 pszFileName, pszFullName, cchFullName, rc)); 424 425 if (cch + cchFileName + 1 <= cchFullName) 426 { 427 strcpy(pszFullName, plv->sz); 428 strcpy(pszFullName + cch, plv->findbuf3.achName); 429 fRet = TRUE; 430 } 431 else 432 { 433 dassert(cch + cchFileName + 1 > cchFullName, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 434 "cch (%d) + cchFileName (%d) + 1 < cchFullName (%d); %s", 435 pszFileName, pszFullName, cchFullName, cch, cchFileName, cchFullName, plv->sz)); 436 } 437 } 438 if (fRet) strupr(pszFullName); 439 goto end; 440 } 441 442 pszPath = pszNext; 443 } 444 } /* for iPath */ 445 446 447 end: 448 /* 449 * Cleanup: free local variables. 450 */ 451 free(plv); 452 return fRet; 453 } 454 455 456 //****************************************************************************** 457 //****************************************************************************** 458 /** 459 * Checks if a file is a PE executable image valid to be executed on this machine. 460 * @returns FALSE if not PE image. 461 * > 0 if valid PE image. 462 * 1 DLL 463 * 2 EXE 464 * @param szFilename Pointer to filename 465 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 466 * @remark Should not call findDll! 467 */ 134 //****************************************************************************** 135 //****************************************************************************** 136 BOOL Win32ImageBase::findDll(const char *szFileName, char *szFullName, 137 int cchFullFileName, const char *pszAltPath) 138 { 139 char modname[CCHMAXPATH]; 140 HFILE dllfile = NULL; 141 char *imagepath; 142 143 strcpy(szFullName, szFileName); 144 strupr(szFullName); 145 if(!strchr(szFullName, (int)'.')) { 146 strcat(szFullName,".DLL"); 147 } 148 149 //search order: 150 //1) exe dir 151 //2) current dir 152 //3) windows system dir (kernel32 path) 153 //4) windows dir 154 //5) path 155 if(WinExe) { 156 strcpy(modname, WinExe->getFullPath()); 157 //remove file name from full path 158 imagepath = modname + strlen(modname) - 1; 159 while(*imagepath != '\\') imagepath--; 160 imagepath[1] = 0; 161 strcat(modname, szFullName); 162 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 163 } 164 if(dllfile == NULL) { 165 strcpy(modname, szFullName); 166 dllfile = OSLibDosOpen(szFullName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 167 if(dllfile == NULL) { 168 strcpy(modname, InternalGetSystemDirectoryA()); 169 strcat(modname, "\\"); 170 strcat(modname, szFullName); 171 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 172 if(dllfile == NULL) { 173 strcpy(modname, InternalGetWindowsDirectoryA()); 174 strcat(modname, "\\"); 175 strcat(modname, szFullName); 176 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 177 if(dllfile == NULL) { 178 if(OSLibDosSearchPath(OSLIB_SEARCHENV, "PATH", szFullName, modname, sizeof(modname)) == 0) { 179 return FALSE; 180 } 181 } 182 } 183 } 184 } 185 strcpy(szFullName, modname); 186 if(dllfile) OSLibDosClose(dllfile); 187 return TRUE; 188 } 189 //****************************************************************************** 190 //****************************************************************************** 468 191 BOOL Win32ImageBase::isPEImage(char *szFileName) 469 192 { … … 486 209 return FALSE; 487 210 } 488 489 211 rc = DosOpen(filename, /* File path name */ 490 212 &win32handle, /* File handle */ … … 550 272 } 551 273 DosClose(win32handle); 552 return (fh.Characteristics & IMAGE_FILE_DLL ? 1 : 2);274 return(TRUE); 553 275 554 276 failure:
Note:
See TracChangeset
for help on using the changeset viewer.