- Timestamp:
- Apr 15, 2000, 11:08:37 PM (25 years ago)
- Location:
- trunk/src/kernel32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/winimagebase.cpp
r3390 r3391 1 /* $Id: winimagebase.cpp,v 1.1 3 2000-04-15 16:32:35 sandervlExp $ */1 /* $Id: winimagebase.cpp,v 1.14 2000-04-15 21:08:36 bird Exp $ */ 2 2 3 3 /* 4 4 * Win32 PE Image base class 5 5 * 6 * Copyright 1998- 1999Sander van Leeuwen (sandervl@xs4all.nl)7 * Copyright 1998 Knut St. Osmundsen6 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl) 7 * Copyright 1998-2000 Knut St. Osmundsen (knut.stange.osmundsen@pmsc.no) 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 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> 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 */ 35 34 #include "oslibmisc.h" 36 35 #include "oslibdos.h" 37 36 #include "initterm.h" 38 #include "directory.h"39 37 #include <win\virtual.h> 40 41 #define DBG_LOCALLOG DBG_winimagebase 38 #include "directory.h" /* InternalGet<Windows/System>Directory. */ 39 #include <os2newapi.h> /* DosQueryHeaderInfo. */ 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(); … … 133 133 } 134 134 //****************************************************************************** 135 //****************************************************************************** 136 void Win32ImageBase::findDll(char *szFileName, char *szFullName, int cchFullFileName) 137 { 138 char modname[CCHMAXPATH]; 139 HFILE dllfile; 140 char *imagepath; 141 142 strcpy(szFullName, szFileName); 143 strupr(szFullName); 144 if(!strchr(szFullName, (int)'.')) { 145 strcat(szFullName,".DLL"); 146 } 147 148 //search order: 149 //1) exe dir 150 //2) current dir 151 //3) windows system dir (kernel32 path) 152 //4) windows dir 153 //5) path 154 strcpy(modname, WinExe->getFullPath()); 155 //remove file name from full path 156 imagepath = modname + strlen(modname) - 1; 157 while(*imagepath != '\\') imagepath--; 158 imagepath[1] = 0; 159 strcat(modname, szFullName); 160 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 161 if(dllfile == NULL) { 162 strcpy(modname, szFullName); 163 dllfile = OSLibDosOpen(szFullName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 164 if(dllfile == NULL) { 165 strcpy(modname, InternalGetSystemDirectoryA()); 166 strcat(modname, "\\"); 167 strcat(modname, szFullName); 168 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 169 if(dllfile == NULL) { 170 strcpy(modname, InternalGetWindowsDirectoryA()); 171 strcat(modname, "\\"); 172 strcat(modname, szFullName); 173 dllfile = OSLibDosOpen(modname, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 174 if(dllfile == NULL) { 175 OSLibDosSearchPath(OSLIB_SEARCHENV, "PATH", szFullName, modname, sizeof(modname)); 176 } 177 } 178 } 179 } 180 strcpy(szFullName, modname); 181 if(dllfile) OSLibDosClose(dllfile); 135 /** 136 * Finds a executable module (or really any file) using the DLL search order. 137 * The search order used is: 138 * 1. The directory from which the application loaded. 139 * 2. The current directory. 140 * 3. System directory. (GetSystemDirectory returns its path) 141 * (Windows NT/2k directory name: SYSTEM32) 142 * 4. (Windows NT/2k: The 16-bit Windows system directory. There 143 * is no function that obtains the path of this directory. 144 * (Directory name: SYSTEM) 145 * THIS IS NOT SEARCHED BY ODIN.) 146 * 5. The Windows directory. (GetWindowsDirectory returns its path) 147 * 6. The Directories listed in the PATH environment variable. 148 * 7. The Directories listed in the BEGINLIBPATH. 149 * 8. The Directories listed in the LIBPATH. 150 * 9. The Directories listed in the ENDLIBPATH. 151 * 152 * @returns Success indicator. TRUE: found FALSE: not found. 153 * Note! pszFullname will normally contain the contents of 154 * pszFilename upon return, there is one case FALSE case when 155 * pszFullname will be empty upon return. That's when the buffer 156 * isn't large enough to hold the content of pszFilename including 157 * an extention. 158 * So, please check for the return value! 159 * @param pszFilename File to find. This name should not have a path! 160 * If it don't contains an '.', ".DLL" is appended to 161 * the name. 162 * @param pszFullname Pointer to output buffer, this will hold the 163 * filename upon return. 164 * @param cchFullname Size of the buffer pointer to by pszFullname. 165 * (A length of at least CCHMAXPATH is recommended.) 166 * 167 * @status Completely implemented. 168 * @author Sander van Leeuwen (sandervl@xs4all.nl) 169 * knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 170 * @remark 171 */ 172 BOOL Win32ImageBase::findDll(const char *pszFileName, char *pszFullName, int cchFullName) 173 { 174 BOOL fRet = FALSE; /* Return value. (Pessimistic attitude! Init it to FALSE...) */ 175 char * psz; /* General string pointer. */ 176 int cchFileName; /* Length of the normalized filename (after ".DLL" is added). */ 177 struct localvars /* local variables which are to big to fit onto the stack. */ 178 { 179 char szPath[1024]; /* Path buffer. Used to store pathlists. 1024 should be enough */ 180 /* for LIBPATH (which at least had a limit of ca. 750 chars). */ 181 char sz[CCHMAXPATH]; /* Filename/path buffer. (Normally used to build filenames */ 182 /* which are passed in as search experessions to DosFindFirst.) */ 183 FILEFINDBUF3 findbuf3; /* DosFindFirst buffer. */ 184 } * plv; 185 int iPath; /* Current path or pathlist being examined. This is the loop */ 186 /* variable looping on the FINDDLL_* defines. */ 187 188 /* These defines sets the order the paths and pathlists are examined. */ 189 #define FINDDLL_EXECUTABLEDIR 1 190 #define FINDDLL_CURRENTDIR 2 191 #define FINDDLL_SYSTEM32DIR 3 192 #define FINDDLL_SYSTEM16DIR 4 193 #define FINDDLL_WINDIR 5 194 #define FINDDLL_PATH 6 195 #define FINDDLL_BEGINLIBPATH 7 196 #define FINDDLL_LIBPATH 8 197 #define FINDDLL_ENDLIBPATH 9 198 #define FINDDLL_FIRST FINDDLL_EXECUTABLEDIR 199 #define FINDDLL_LAST FINDDLL_ENDLIBPATH 200 201 202 /** @sketch 203 * Copy the filename to be found to the outputbuffer, and add .DLL if not '.' 204 * is found in the name. This has two reasons: 205 * 1) When searching paths we simply append the buffer contents to the path 206 * being examined. 207 * 2) The buffer will at least return the passed in filename. 208 */ 209 psz = strchr(pszFileName, '.'); 210 cchFileName = strlen(pszFileName) + (psz ? 0 : 4); 211 if (cchFileName >= cchFullName) 212 { 213 dassert(cchFileName < cchFullName, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 214 "cchFileName (%d) >= cchFullName (%d)", 215 pszFileName, pszFullName, cchFullName, cchFileName, cchFullName)); 216 *pszFullName = '\0'; 217 return FALSE; 218 } 219 strcpy(pszFullName, pszFileName); 220 if (psz == NULL) 221 strcpy(pszFullName + cchFileName - 4, ".DLL"); 222 223 224 /** @sketch 225 * Allocate memory for local variables. 226 */ 227 plv = (struct localvars *)malloc(sizeof(*plv)); 228 if (!plv) 229 { 230 dassert(plv, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 231 "malloc failed allocating %d bytes of memory for local variables.", 232 pszFileName, pszFullName, cchFullName, sizeof(*plv))); 233 return FALSE; 234 } 235 236 237 /** @sketch 238 * Loop thru the paths and pathlists searching them for the filename. 239 */ 240 for (iPath = FINDDLL_FIRST; iPath <= FINDDLL_LAST; iPath++) 241 { 242 APIRET rc; /* Returncode from OS/2 APIs. */ 243 const char * pszPath; /* Pointer to the path being examined. */ 244 245 /** @sketch 246 * Get the path/dir to examin. (This is determined by the value if iPath.) 247 */ 248 switch (iPath) 249 { 250 case FINDDLL_EXECUTABLEDIR: 251 //ASSUMES: getFullPath allways returns a fully qualified path, ie. with at least one backslash. 252 // and that all slashes are backslashes! 253 pszPath = strcpy(plv->szPath, WinExe->getFullPath()); 254 psz = strrchr(plv->szPath, '\\'); 255 dassert(psz, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 256 "WinExe->getFullPath returned a path not fully qualified: %s", 257 pszFileName, pszFullName, cchFullName, pszPath)); 258 if (psz) 259 *psz = '\0'; 260 else 261 continue; 262 break; 263 264 case FINDDLL_CURRENTDIR: 265 pszPath = "."; 266 break; 267 268 case FINDDLL_SYSTEM32DIR: 269 pszPath = InternalGetSystemDirectoryA(); 270 break; 271 272 case FINDDLL_SYSTEM16DIR: 273 #if 1 274 continue; /* Skip this index */ 275 #else 276 pszPath = InternalGetWindowsDirectoryA(); 277 strcpy(plv->sz2, InternalGetWindowsDirectoryA()); 278 strcat(plv->sz2, "\SYSTEM"); 279 break; 280 #endif 281 282 case FINDDLL_WINDIR: 283 pszPath = InternalGetWindowsDirectoryA(); 284 break; 285 286 case FINDDLL_PATH: 287 pszPath = getenv("PATH"); 288 break; 289 290 case FINDDLL_BEGINLIBPATH: 291 rc = DosQueryExtLIBPATH(plv->szPath, BEGIN_LIBPATH); 292 if (rc != NO_ERROR) 293 { 294 dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 295 "DosQueryExtLIBPATH failed with rc=%d, iPath=%d", 296 pszFileName, pszFullName, cchFullName, rc, iPath)); 297 continue; 298 } 299 pszPath = plv->szPath; 300 break; 301 302 case FINDDLL_LIBPATH: 303 rc = DosQueryHeaderInfo(NULLHANDLE, 0, plv->szPath, sizeof(plv->szPath), QHINF_LIBPATH); 304 if (rc != NO_ERROR) 305 { 306 dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 307 "DosQueryHeaderInfo failed with rc=%d, iPath=%d", 308 pszFileName, pszFullName, cchFullName, rc, iPath)); 309 continue; 310 } 311 pszPath = plv->szPath; 312 break; 313 314 case FINDDLL_ENDLIBPATH: 315 rc = DosQueryExtLIBPATH(plv->szPath, END_LIBPATH); 316 if (rc != NO_ERROR) 317 { 318 dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 319 "DosQueryExtLIBPATH failed with rc=%d, iPath=%d", 320 pszFileName, pszFullName, cchFullName, rc, iPath)); 321 continue; 322 } 323 pszPath = plv->szPath; 324 break; 325 326 default: /* !internalerror! */ 327 goto end; 328 } 329 330 /** @sketch 331 * pszPath is now set to the pathlist to be searched. 332 * So we'll loop thru all the paths in the list. 333 */ 334 while (pszPath != NULL && *pszPath != '\0') 335 { 336 HDIR hDir; /* Find handle used when calling FindFirst. */ 337 ULONG culFiles; /* Number of files to find / found. */ 338 char * pszNext; /* Pointer to the next pathlist path */ 339 int cch; /* Length of path (including the slash after the slash is added). */ 340 341 /** @sketch 342 * Find the end of the path. 343 * Copy the path into the plv->sz buffer. 344 * Set pszNext. 345 */ 346 pszNext = strchr(pszPath, ';'); 347 if (pszNext != NULL) 348 { 349 cch = pszNext - pszPath; 350 pszNext++; 351 } 352 else 353 cch = strlen(pszPath); 354 355 if (cch + cchFileName + 1 >= sizeof(plv->sz)) /* assertion */ 356 { 357 dassert(cch + cchFileName + 1 < sizeof(plv->sz), ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 358 "cch (%d) + cchFileName (%d) + 1 < sizeof(plv->sz) (%d) - paths too long!, iPath=%d", 359 pszFileName, pszFullName, cchFullName, cch, cchFileName, sizeof(plv->sz), iPath)); 360 pszPath = pszNext; 361 continue; 362 } 363 memcpy(plv->sz, pszPath, cch); //arg! Someone made strncpy not work as supposed! 364 365 366 /** @sketch 367 * Add a '\\' and the filename (pszFullname) to the path; 368 * then we'll have a fullpath. 369 */ 370 plv->sz[cch++] = '\\'; 371 strcpy(&plv->sz[cch], pszFullName); 372 373 374 /** @sketch 375 * Use DosFindFirst to check if the file exists. 376 * IF the file exists THEN 377 * Query Fullpath using OS/2 API. 378 * IF unsuccessfull THEN return relative name. 379 * Check that the fullname buffer is large enough. 380 * Copy the filename found to the fullname buffer. 381 * ENDIF 382 * goto end 383 * ENDIF 384 */ 385 hDir = HDIR_CREATE; 386 culFiles = 1; 387 rc = DosFindFirst(plv->sz, &hDir, FILE_NORMAL, 388 &plv->findbuf3, sizeof(plv->findbuf3), 389 &culFiles, FIL_STANDARD); 390 DosFindClose(hDir); 391 if (culFiles >= 1 && rc == NO_ERROR) 392 { 393 /* Return full path - we'll currently return a relative path. */ 394 rc = DosQueryPathInfo(plv->sz, FIL_QUERYFULLNAME, pszFullName, cchFullName); 395 fRet = rc == NO_ERROR; 396 if (!fRet) 397 { 398 /* Return a relative path - probably better that failing... */ 399 dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 400 "rc = %d", 401 pszFileName, pszFullName, cchFullName, rc)); 402 403 if (cch + cchFileName + 1 <= cchFullName) 404 { 405 strcpy(pszFullName, plv->sz); 406 strcpy(pszFullName + cch, plv->findbuf3.achName); 407 fRet = TRUE; 408 } 409 else 410 { 411 dassert(cch + cchFileName + 1 > cchFullName, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): " 412 "cch (%d) + cchFileName (%d) + 1 < cchFullName (%d); %s", 413 pszFileName, pszFullName, cchFullName, cch, cchFileName, cchFullName, plv->sz)); 414 } 415 } 416 goto end; 417 } 418 419 pszPath = pszNext; 420 } 421 } /* for iPath */ 422 423 424 end: 425 /* 426 * Cleanup: free local variables. 427 */ 428 free(plv); 429 return fRet; 182 430 } 183 431 //****************************************************************************** … … 197 445 int nSections, i; 198 446 199 findDll(szFileName, filename, sizeof(filename)); 447 if (!findDll(szFileName, filename, sizeof(filename))) 448 { 449 dprintf(("KERNEL32:Win32ImageBase::isPEImage(%s) findDll failed to find the file.\n", 450 szFileName, rc)); 451 return FALSE; 452 } 453 200 454 rc = DosOpen(filename, /* File path name */ 201 455 &win32handle, /* File handle */ -
trunk/src/kernel32/winimagebase.h
r3375 r3391 1 /* $Id: winimagebase.h,v 1. 2 2000-04-14 22:35:28 sandervlExp $ */1 /* $Id: winimagebase.h,v 1.3 2000-04-15 21:08:37 bird Exp $ */ 2 2 3 3 /* … … 65 65 char *getFullPath() { return fullpath; }; 66 66 67 char *getModuleName(){ return szModule; };67 char *getModuleName() { return szModule; }; 68 68 69 69 virtual HRSRC findResourceA(LPCSTR lpszName, LPSTR lpszType, ULONG lang = LANG_GETFIRST); … … 73 73 virtual BOOL enumResourceNamesA(HMODULE hmod, LPCTSTR lpszType, ENUMRESNAMEPROCA lpEnumFunc, LONG lParam); 74 74 virtual BOOL enumResourceNamesW(HMODULE hmod, LPCWSTR lpszType, ENUMRESNAMEPROCW lpEnumFunc, LONG lParam); 75 virtual BOOL enumResourceTypesA(HMODULE hmod, ENUMRESTYPEPROCA lpEnumFunc, 75 virtual BOOL enumResourceTypesA(HMODULE hmod, ENUMRESTYPEPROCA lpEnumFunc, 76 76 LONG lParam); 77 virtual BOOL enumResourceTypesW(HMODULE hmod, ENUMRESTYPEPROCW lpEnumFunc, 77 virtual BOOL enumResourceTypesW(HMODULE hmod, ENUMRESTYPEPROCW lpEnumFunc, 78 78 LONG lParam); 79 79 … … 82 82 83 83 static BOOL isPEImage(char *szFileName); 84 static void findDll(char *szFileName, char *szFullName, int cchFullFileName);84 static BOOL findDll(const char *pszFileName, char *pszFullName, int cchFullName); 85 85 86 86 void setEntryPoint(ULONG startAddress) { entryPoint = startAddress; }; 87 87 88 void setTLSAddress(LPVOID dwTlsAddress) 89 void setTLSIndexAddr(LPDWORD dwTlsIndexAddr) 90 void setTLSInitSize(ULONG dwTlsSize) 91 void setTLSTotalSize(ULONG dwTlsSize) 88 void setTLSAddress(LPVOID dwTlsAddress) { tlsAddress = dwTlsAddress; }; 89 void setTLSIndexAddr(LPDWORD dwTlsIndexAddr) { tlsIndexAddr = dwTlsIndexAddr; }; 90 void setTLSInitSize(ULONG dwTlsSize) { tlsInitSize = dwTlsSize; }; 91 void setTLSTotalSize(ULONG dwTlsSize) { tlsTotalSize = dwTlsSize; }; 92 92 void setTLSCallBackAddr(PIMAGE_TLS_CALLBACK *dwTlsCallBackAddr) 93 94 95 93 { 94 tlsCallBackAddr = dwTlsCallBackAddr; 95 }; 96 96 97 void tlsAttachThread();//setup TLS structures for new thread98 void tlsDetachThread();//destroy TLS structures97 void tlsAttachThread(); //setup TLS structures for new thread 98 void tlsDetachThread(); //destroy TLS structures 99 99 100 virtual 100 virtual ULONG getApi(char *name) = 0; 101 101 virtual ULONG getApi(int ordinal) = 0; 102 102 … … 105 105 static Win32ImageBase * findModule(HMODULE hModule); 106 106 107 108 107 //Add image to dependency list of this image 108 void addDependency(Win32DllBase *dll); 109 109 BOOL dependsOn(Win32DllBase *dll); 110 110 111 111 protected: 112 void tlsAlloc();//Allocate TLS index for this module113 void tlsDelete();//Destroy TLS index for this module112 void tlsAlloc(); //Allocate TLS index for this module 113 void tlsDelete(); //Destroy TLS index for this module 114 114 115 115 Win32Resource *winres; … … 118 118 119 119 char *fullpath; 120 charszModule[CCHMAXPATH];121 120 char szModule[CCHMAXPATH]; 121 char szFileName[CCHMAXPATH]; 122 122 123 123 HINSTANCE hinstance; 124 124 125 LPVOID tlsAddress;//address of TLS data126 LPDWORD tlsIndexAddr;//address of DWORD that receives the TLS index127 ULONG tlsInitSize;//size of initialized TLS memory block128 ULONG tlsTotalSize;//size of TLS memory block129 PIMAGE_TLS_CALLBACK *tlsCallBackAddr;//ptr to TLS callback array130 ULONG tlsIndex;//module TLS index125 LPVOID tlsAddress; //address of TLS data 126 LPDWORD tlsIndexAddr; //address of DWORD that receives the TLS index 127 ULONG tlsInitSize; //size of initialized TLS memory block 128 ULONG tlsTotalSize; //size of TLS memory block 129 PIMAGE_TLS_CALLBACK *tlsCallBackAddr; //ptr to TLS callback array 130 ULONG tlsIndex; //module TLS index 131 131 132 132 ULONG getPEResourceSize(ULONG id, ULONG type, ULONG lang = LANG_GETFIRST); … … 143 143 ULONG ulRVAResourceSection; 144 144 145 146 Queue 145 //linked list of dlls loaded on behalf of this executable image (dll or exe) 146 Queue loadedDlls; 147 147 private: 148 148 … … 161 161 } WINIMAGE_LOOKUP; 162 162 163 #define WINIMAGE_LOOKUPADDR(a) 163 #define WINIMAGE_LOOKUPADDR(a) (WINIMAGE_LOOKUP *)((ULONG)a + PAGE_SIZE - sizeof(WINIMAGE_LOOKUP)) 164 164 165 165 #endif //__WINIMAGEBASE_H__
Note:
See TracChangeset
for help on using the changeset viewer.