- Timestamp:
- Apr 16, 2000, 12:42:13 PM (25 years ago)
- Location:
- trunk/src/kernel32
- Files:
-
- 4 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: -
trunk/src/kernel32/winimagebase.h
r3398 r3404 1 /* $Id: winimagebase.h,v 1. 5 2000-04-16 04:27:38 birdExp $ */1 /* $Id: winimagebase.h,v 1.6 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)6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 7 * 8 8 * … … 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 … … 85 85 int cchFullName, const char *pszAltPath = NULL); 86 86 87 87 void setEntryPoint(ULONG startAddress) { entryPoint = startAddress; }; 88 88 89 void setTLSAddress(LPVOID dwTlsAddress) 90 void setTLSIndexAddr(LPDWORD dwTlsIndexAddr) 91 void setTLSInitSize(ULONG dwTlsSize) 92 void setTLSTotalSize(ULONG dwTlsSize) 89 void setTLSAddress(LPVOID dwTlsAddress) { tlsAddress = dwTlsAddress; }; 90 void setTLSIndexAddr(LPDWORD dwTlsIndexAddr) { tlsIndexAddr = dwTlsIndexAddr; }; 91 void setTLSInitSize(ULONG dwTlsSize) { tlsInitSize = dwTlsSize; }; 92 void setTLSTotalSize(ULONG dwTlsSize) { tlsTotalSize = dwTlsSize; }; 93 93 void setTLSCallBackAddr(PIMAGE_TLS_CALLBACK *dwTlsCallBackAddr) 94 95 96 94 { 95 tlsCallBackAddr = dwTlsCallBackAddr; 96 }; 97 97 98 void tlsAttachThread();//setup TLS structures for new thread99 void tlsDetachThread();//destroy TLS structures98 void tlsAttachThread(); //setup TLS structures for new thread 99 void tlsDetachThread(); //destroy TLS structures 100 100 101 virtual ULONGgetApi(char *name) = 0;102 virtual ULONG 101 virtual ULONG getApi(char *name) = 0; 102 virtual ULONG getApi(int ordinal) = 0; 103 103 104 104 virtual BOOL isDll() = 0; … … 106 106 static Win32ImageBase * findModule(HMODULE hModule); 107 107 108 109 108 //Add image to dependency list of this image 109 void addDependency(Win32DllBase *dll); 110 110 BOOL dependsOn(Win32DllBase *dll); 111 111 112 112 protected: 113 void tlsAlloc();//Allocate TLS index for this module114 void tlsDelete();//Destroy TLS index for this module113 void tlsAlloc(); //Allocate TLS index for this module 114 void tlsDelete(); //Destroy TLS index for this module 115 115 116 116 Win32Resource *winres; … … 119 119 120 120 char *fullpath; 121 charszModule[CCHMAXPATH];122 121 char szModule[CCHMAXPATH]; 122 char szFileName[CCHMAXPATH]; 123 123 124 124 HINSTANCE hinstance; 125 125 126 LPVOID tlsAddress;//address of TLS data127 LPDWORD tlsIndexAddr;//address of DWORD that receives the TLS index128 ULONG tlsInitSize;//size of initialized TLS memory block129 ULONG tlsTotalSize;//size of TLS memory block130 PIMAGE_TLS_CALLBACK *tlsCallBackAddr;//ptr to TLS callback array131 ULONG tlsIndex;//module TLS index126 LPVOID tlsAddress; //address of TLS data 127 LPDWORD tlsIndexAddr; //address of DWORD that receives the TLS index 128 ULONG tlsInitSize; //size of initialized TLS memory block 129 ULONG tlsTotalSize; //size of TLS memory block 130 PIMAGE_TLS_CALLBACK *tlsCallBackAddr; //ptr to TLS callback array 131 ULONG tlsIndex; //module TLS index 132 132 133 133 ULONG getPEResourceSize(ULONG id, ULONG type, ULONG lang = LANG_GETFIRST); … … 144 144 ULONG ulRVAResourceSection; 145 145 146 147 Queue 146 //linked list of dlls loaded on behalf of this executable image (dll or exe) 147 Queue loadedDlls; 148 148 private: 149 149 … … 162 162 } WINIMAGE_LOOKUP; 163 163 164 #define WINIMAGE_LOOKUPADDR(a) 164 #define WINIMAGE_LOOKUPADDR(a) (WINIMAGE_LOOKUP *)((ULONG)a + PAGE_SIZE - sizeof(WINIMAGE_LOOKUP)) 165 165 166 166 #endif //__WINIMAGEBASE_H__ -
trunk/src/kernel32/winimagepeldr.cpp
r3393 r3404 1 /* $Id: winimagepeldr.cpp,v 1.4 0 2000-04-15 21:17:06 birdExp $ */1 /* $Id: winimagepeldr.cpp,v 1.41 2000-04-16 10:42:12 sandervl Exp $ */ 2 2 3 3 /* … … 18 18 * So an instance of this type can't be used for anything but resource lookup! 19 19 * 20 * 20 21 */ 21 22 #define INCL_DOSFILEMGR /* File Manager values */ … … 77 78 char logname[CCHMAXPATH]; 78 79 79 80 81 82 83 84 85 80 sprintf(logname, "pe_%d.log", loadNr); 81 _privateLogFile = fopen(logname, "w"); 82 if(_privateLogFile == NULL) { 83 sprintf(logname, "%spe_%d.log", kernel32Path, loadNr); 84 _privateLogFile = fopen(logname, "w"); 85 } 86 dprintfGlobal(("PE LOGFILE : %s", logname)); 86 87 #endif 87 88 } … … 91 92 { 92 93 #ifdef DEBUG 93 94 95 96 94 if(_privateLogFile) { 95 fclose(_privateLogFile); 96 _privateLogFile = NULL; 97 } 97 98 #endif 98 99 } … … 113 114 strupr(szFileName); 114 115 if(isExe) { 115 116 117 118 119 120 121 122 123 124 125 126 127 128 elseOSLibDosClose(dllfile);116 if(!strchr(szFileName, '.')) { 117 strcat(szFileName,".EXE"); 118 } 119 dllfile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 120 if(dllfile == NULL) { 121 if(!strstr(szFileName, ".EXE")) { 122 strcat(szFileName,".EXE"); 123 } 124 dllfile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 125 if(dllfile == NULL) { 126 OSLibDosSearchPath(OSLIB_SEARCHENV, "PATH", szFileName, szFileName, sizeof(szFileName)); 127 } 128 } 129 else OSLibDosClose(dllfile); 129 130 } 130 131 else { 131 if (findDll(szFileName, szModule, sizeof(szModule)))132 132 findDll(szFileName, szModule, sizeof(szModule)); 133 strcpy(szFileName, szModule); 133 134 } 134 135 strcpy(szModule, OSLibStripPath(szFileName)); … … 136 137 char *dot = strstr(szModule, "."); 137 138 while(dot) { 138 139 if(newdot == NULL)break;140 139 char *newdot = strstr(dot+1, "."); 140 if(newdot == NULL) break; 141 dot = newdot; 141 142 } 142 143 if(dot) 143 144 *dot = 0; 144 145 } 145 146 //****************************************************************************** … … 148 149 { 149 150 if(memmap) 150 151 delete memmap; 151 152 152 153 if(hFile) { 153 154 154 OSLibDosClose(hFile); 155 hFile = 0; 155 156 } 156 157 157 158 if(realBaseAddress) 158 159 DosFreeMem((PVOID)realBaseAddress); 159 160 160 161 if(nameexports) 161 162 free(nameexports); 162 163 163 164 if(ordexports) 164 165 free(ordexports); 165 166 } 166 167 //****************************************************************************** … … 183 184 strcpy(szErrorModule, OSLibStripPath(szFileName)); 184 185 if(hFile == NULL) { 185 186 goto failure; 186 187 } 187 188 //read dos header 188 189 if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) { 189 190 goto failure; 190 191 } 191 192 if(OSLibDosSetFilePtr(hFile, doshdr.e_lfanew, OSLIB_SETPTR_FILE_BEGIN) == -1) { 192 193 goto failure; 193 194 } 194 195 //read signature dword 195 196 if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) { 196 197 goto failure; 197 198 } 198 199 //read pe header 199 200 if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) { 200 201 goto failure; 201 202 } 202 203 //read optional header 203 204 if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) { 204 205 goto failure; 205 206 } 206 207 if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || signature != IMAGE_NT_SIGNATURE) { 207 208 dprintf((LOG, "Not a valid PE file (probably a 16 bits windows exe/dll)!")); 208 209 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 209 210 goto failure; 210 211 } 211 212 212 213 if(oh.SizeOfImage == 0) {//just in case 213 214 oh.SizeOfImage = OSLibDosGetFileSize(hFile); 214 215 } 215 216 … … 217 218 //Allocate memory to hold the entire image 218 219 if(allocSections(reservedMem) == FALSE) { 219 220 220 dprintf((LOG, "Failed to allocate image memory, rc %d", errorState));; 221 goto failure; 221 222 } 222 223 223 224 memmap = new Win32MemMap(this, realBaseAddress, imageSize); 224 225 if(memmap == NULL || !memmap->Init(0)) { 225 226 goto failure; 226 227 } 227 228 win32file = memmap->mapViewOfFile(0, 0, 2); 228 229 229 230 if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) { 230 231 setFullPath(szFullPath); 231 232 } 232 233 233 234 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid 234 235 dprintf((LOG, "Not a valid PE file!")); 235 236 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 236 237 goto failure; 237 238 } 238 239 if(fh.Machine != IMAGE_FILE_MACHINE_I386) { 239 240 dprintf((LOG, "Doesn't run on x86 processors!")); 240 241 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szCPUErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 241 242 goto failure; 242 243 } 243 244 //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)? 244 245 if(fh.Characteristics & IMAGE_FILE_SYSTEM) { 245 246 dprintf((LOG, "Can't convert system files")); 246 247 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szExeErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 247 248 goto failure; 248 249 } 249 250 250 251 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 251 252 dprintf((LOG, "No fixups, might not run!")); 252 253 } 253 254 … … 283 284 if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL) { 284 285 dprintf((LOG, "*************************PE SECTIONS START**************************" )); 285 for (i=0; i<nSections; i++) { 286 for (i=0; i<nSections; i++) { 286 287 dprintf((LOG, "Raw data size: %x", psh[i].SizeOfRawData )); 287 288 dprintf((LOG, "Virtual Address: %x", psh[i].VirtualAddress )); … … 312 313 continue; 313 314 } 314 315 316 317 318 319 320 321 322 323 315 if(strcmp(psh[i].Name, ".tls") == 0) 316 { 317 tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS); 318 if(tlsDir) { 319 addSection(SECTION_TLS, psh[i].PointerToRawData, 320 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 321 psh[i].Misc.VirtualSize, psh[i].Characteristics); 322 } 323 continue; 324 } 324 325 325 326 if(strcmp(psh[i].Name, ".debug") == 0) { … … 330 331 continue; 331 332 } 332 333 333 if(IsImportSection(win32file, &psh[i])) 334 { 334 335 int type = SECTION_IMPORT; 335 336 dprintf((LOG, "Import Data Section" )); … … 385 386 } 386 387 dprintf((LOG, "Unknown section" )); 387 388 goto failure; 388 389 } 389 390 } 390 391 } 391 392 else { 392 393 if(GetSectionHdrByName (win32file, &sh, ".rsrc")) 393 394 { 394 395 addSection(SECTION_RESOURCE, sh.PointerToRawData, 395 396 sh.SizeOfRawData, sh.VirtualAddress + oh.ImageBase, 396 397 sh.Misc.VirtualSize, sh.Characteristics); 397 398 } 398 399 } 399 400 dprintf((LOG, "*************************PE SECTIONS END **************************" )); … … 405 406 //In case there are any gaps between sections, adjust size 406 407 if(imageSize != imageVirtEnd - oh.ImageBase) { 407 408 408 dprintf((LOG, "imageSize != imageVirtEnd - oh.ImageBase!" )); 409 imageSize = imageVirtEnd - oh.ImageBase; 409 410 } 410 411 if(imageSize < oh.SizeOfImage) { 411 412 imageSize = oh.SizeOfImage; 412 413 } 413 414 414 415 dprintf((LOG, "OS/2 base address %x", realBaseAddress )); 415 416 if(oh.AddressOfEntryPoint) { 416 417 entryPoint = realBaseAddress + oh.AddressOfEntryPoint; 417 418 } 418 419 else { 419 420 420 dprintf((LOG, "EntryPoint == NULL" )); 421 entryPoint = NULL; 421 422 } 422 423 423 424 //set memory protection flags 424 425 if(setMemFlags() == FALSE) { 425 426 426 dprintf((LOG, "Failed to set memory protection" )); 427 goto failure; 427 428 } 428 429 … … 432 433 Section *sect = findSection(SECTION_TLS); 433 434 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 435 if(sect == NULL) { 436 dprintf((LOG, "Couldn't find TLS section!!" )); 437 goto failure; 438 } 439 dprintf((LOG, "TLS Directory" )); 440 dprintf((LOG, "TLS Address of Index %x", tlsDir->AddressOfIndex )); 441 dprintf((LOG, "TLS Address of Callbacks %x", tlsDir->AddressOfCallBacks )); 442 dprintf((LOG, "TLS SizeOfZeroFill %x", tlsDir->SizeOfZeroFill )); 443 dprintf((LOG, "TLS Characteristics %x", tlsDir->Characteristics )); 444 setTLSAddress((char *)sect->realvirtaddr); 445 setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData); 446 setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill); 447 448 sect = findSectionByAddr((ULONG)tlsDir->AddressOfIndex); 449 if(sect == NULL) { 450 dprintf((LOG, "Couldn't find TLS AddressOfIndex section!!" )); 451 goto failure; 452 } 453 setTLSIndexAddr((LPDWORD)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfIndex - sect->virtaddr))); 454 455 if((ULONG)tlsDir->AddressOfCallBacks != 0) { 456 sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks); 457 if(sect == NULL) { 458 dprintf((LOG, "Couldn't find TLS AddressOfCallBacks section!!" )); 459 goto failure; 460 } 461 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfCallBacks - sect->virtaddr))); 462 } 462 463 } 463 464 464 465 if(realBaseAddress != oh.ImageBase) { 465 466 466 pFixups = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC); 467 commitPage((ULONG)pFixups, FALSE); 467 468 } 468 469 #ifdef COMMIT_ALL 469 470 for (i=0; i<nSections; i++) { 470 471 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION); 471 472 } 472 473 #else 473 474 for (i=0; i<nSections; i++) { 474 475 476 477 478 479 480 481 475 switch(section[i].type) 476 { 477 case SECTION_IMPORT: 478 case SECTION_RELOC: 479 case SECTION_EXPORT: 480 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION); 481 break; 482 } 482 483 } 483 484 #endif 484 485 if(processExports((char *)win32file) == FALSE) { 485 486 486 dprintf((LOG, "Failed to process exported apis" )); 487 goto failure; 487 488 } 488 489 } 489 490 #ifdef COMMIT_ALL 490 491 else { 491 492 commitPage((ULONG)section[0].realvirtaddr, FALSE, COMPLETE_SECTION); 492 493 } 493 494 #endif … … 502 503 // implicitly call functions depending on it. 503 504 if(GetSectionHdrByName (win32file, &sh, ".rsrc")) { 504 505 505 //get offset in resource object of directory entry 506 pResDir = (PIMAGE_RESOURCE_DIRECTORY)(sh.VirtualAddress + realBaseAddress); 506 507 ulRVAResourceSection = sh.VirtualAddress; 507 508 } … … 510 511 { 511 512 if(processImports((char *)win32file) == FALSE) { 512 513 513 dprintf((LOG, "Failed to process imports!" )); 514 goto failure; 514 515 } 515 516 } … … 518 519 failure: 519 520 if(memmap) { 520 521 521 delete memmap; 522 memmap = NULL; 522 523 } 523 524 if(hFile) { 524 525 525 OSLibDosClose(hFile); 526 hFile = 0; 526 527 } 527 528 errorState = ERROR_INTERNAL; … … 541 542 //Round down to nearest page boundary 542 543 virtAddress = virtAddress & ~0xFFF; 543 544 544 545 section = findSectionByOS2Addr(virtAddress); 545 546 if(section == NULL) { 546 547 548 549 550 551 552 553 554 555 556 557 547 size = 4096; 548 sectionsize = 4096; 549 protflags = PAG_READ|PAG_WRITE; //readonly? 550 section = findPreviousSectionByOS2Addr(virtAddress); 551 if(section == NULL) {//access to header 552 offset = 0; 553 fileoffset = virtAddress - realBaseAddress; 554 } 555 else { 556 offset = virtAddress - (section->realvirtaddr + section->virtualsize); 557 fileoffset = section->rawoffset + section->rawsize + offset; 558 } 558 559 } 559 560 else { 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 561 protflags = section->pageflags; 562 offset = virtAddress - section->realvirtaddr; 563 sectionsize = section->virtualsize - offset; 564 565 if(offset > section->rawsize || section->type == SECTION_UNINITDATA) { 566 //unintialized data (set to 0) 567 size = 0; 568 fileoffset = -1; 569 } 570 else { 571 size = section->rawsize-offset; 572 fileoffset = section->rawoffset + offset; 573 } 574 if(fWriteAccess & !(section->pageflags & PAG_WRITE)) { 575 dprintf((LOG, "Win32PeLdrImage::commitPage: No write access to 0%x!", virtAddress)); 576 return FALSE; 577 } 577 578 } 578 579 //Check range of pages with the same attributes starting at virtAddress … … 581 582 rc = DosQueryMem((PVOID)virtAddress, &range, &attr); 582 583 if(rc) { 583 584 584 dprintf((LOG, "Win32PeLdrImage::commitPage: DosQueryMem for %x returned %d", virtAddress, rc)); 585 return FALSE; 585 586 } 586 587 if(attr & PAG_COMMIT) { 587 588 588 dprintf((LOG, "Win32PeLdrImage::commitPage: Memory at 0x%x already committed!", virtAddress)); 589 return FALSE; 589 590 } 590 591 591 592 if(fPageCmd == SINGLE_PAGE) { 592 593 593 size = min(size, PAGE_SIZE); 594 sectionsize = min(sectionsize, PAGE_SIZE); 594 595 } 595 596 else 596 597 if(fPageCmd == SECTION_PAGES) { 597 598 598 size = min(size, DEFAULT_NR_PAGES*PAGE_SIZE); 599 sectionsize = min(sectionsize, DEFAULT_NR_PAGES*PAGE_SIZE); 599 600 } 600 601 size = min(size, range); … … 602 603 603 604 if(fileoffset != -1) { 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 605 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT); 606 if(rc) { 607 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 608 return FALSE; 609 } 610 611 if(DosSetFilePtr(hFile, fileoffset, FILE_BEGIN, &ulNewPos) == -1) { 612 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetFilePtr failed for 0x%x!", fileoffset)); 613 return FALSE; 614 } 615 if(DosRead(hFile, (PVOID)virtAddress, size, &ulRead)) { 616 dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed for 0x%x!", virtAddress)); 617 return FALSE; 618 } 619 if(ulRead != size) { 620 dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed to read %x (%x) bytes at %x for 0x%x!", size, ulRead, fileoffset, virtAddress)); 621 return FALSE; 622 } 623 if(realBaseAddress != oh.ImageBase) { 624 setFixups(virtAddress, sectionsize); 625 } 626 627 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags); 628 if(rc) { 629 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 630 return FALSE; 631 } 631 632 } 632 633 else { 633 634 635 636 637 638 639 640 641 642 643 644 645 634 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT); 635 if(rc) { 636 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 637 return FALSE; 638 } 639 if(realBaseAddress != oh.ImageBase) { 640 setFixups(virtAddress, sectionsize); 641 } 642 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags); 643 if(rc) { 644 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 645 return FALSE; 646 } 646 647 } 647 648 return TRUE; … … 664 665 665 666 if(virtaddress < imageVirtBase) 666 667 imageVirtBase = virtaddress; 667 668 if(virtaddress + virtsize > imageVirtEnd) 668 669 imageVirtEnd = virtaddress + virtsize; 669 670 670 671 nrsections++; … … 679 680 //SvL: We don't care where the image is loaded for resource lookup 680 681 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED && loadType == REAL_LOAD) { 681 682 return allocFixedMem(reservedMem); 682 683 } 683 684 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | flAllocMem); 684 685 if(rc) { 685 686 687 686 dprintf((LOG, "Win32PeLdrImage::allocSections, DosAllocMem returned %d", rc)); 687 errorState = rc; 688 return(FALSE); 688 689 } 689 690 realBaseAddress = baseAddress; … … 695 696 { 696 697 for(int i=0;i<nrsections;i++) { 697 698 699 698 if(section[i].type == type) { 699 return §ion[i]; 700 } 700 701 } 701 702 return NULL; … … 706 707 { 707 708 for(int i=0;i<nrsections;i++) { 708 709 710 709 if(section[i].virtaddr <= addr && section[i].virtaddr + section[i].virtualsize > addr) { 710 return §ion[i]; 711 } 711 712 } 712 713 return NULL; … … 717 718 { 718 719 for(int i=0;i<nrsections;i++) { 719 720 721 720 if(section[i].realvirtaddr <= addr && section[i].realvirtaddr + section[i].virtualsize > addr) { 721 return §ion[i]; 722 } 722 723 } 723 724 return NULL; … … 731 732 732 733 for(int i=0;i<nrsections;i++) { 733 734 735 736 737 738 734 if(section[i].realvirtaddr > addr) { 735 if(section[i].realvirtaddr < lowestAddr) { 736 lowestAddr = section[i].realvirtaddr; 737 index = i; 738 } 739 } 739 740 } 740 741 if(index == -1) 741 742 return NULL; 742 743 743 744 return §ion[index]; … … 761 762 //Allocated in peldr.dll 762 763 if(reservedMem && reservedMem == oh.ImageBase) { 763 764 764 realBaseAddress = oh.ImageBase; 765 return TRUE; 765 766 } 766 767 … … 768 769 memallocs = (ULONG *)malloc(4096*sizeof(ULONG *)); 769 770 if(memallocs == NULL) { 770 771 771 dprintf((LOG, "allocFixedMem: MALLOC FAILED for memallocs" )); 772 return FALSE; 772 773 } 773 774 774 775 if(oh.ImageBase < 512*1024*1024) { 775 776 allocFlags = 0; 776 777 } 777 778 while(TRUE) { 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 779 rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | allocFlags); 780 if(rc) break; 781 782 dprintf((LOG, "DosAllocMem returned %x", address )); 783 if(address + FALLOC_SIZE >= oh.ImageBase) { 784 if(address > oh.ImageBase) {//we've passed it! 785 DosFreeMem((PVOID)address); 786 break; 787 } 788 //found the right address 789 DosFreeMem((PVOID)address); 790 791 diff = oh.ImageBase - address; 792 if(diff) { 793 rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | allocFlags); 794 if(rc) break; 795 } 796 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | allocFlags); 797 if(rc) break; 798 799 if(diff) DosFreeMem((PVOID)address); 800 801 realBaseAddress = baseAddress; 802 break; 803 } 804 memallocs[alloccnt++] = address; 804 805 } 805 806 for(i=0;i<alloccnt;i++) { 806 807 DosFreeMem((PVOID)memallocs[i]); 807 808 } 808 809 free(memallocs); 809 810 810 811 if(realBaseAddress == 0) //Let me guess.. MS Office app? 811 812 return(FALSE); 812 813 813 814 return(TRUE); … … 827 828 // Process all the image sections 828 829 for(i=0;i<nrsections;i++) { 829 830 section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase); 830 831 } 831 832 832 833 for(i=0;i<nrsections;i++) { 833 834 834 switch(section[i].type) 835 { 835 836 case SECTION_CODE: 836 837 case (SECTION_CODE | SECTION_IMPORT): 837 838 if(section[i].flags & IMAGE_SCN_MEM_WRITE) 839 840 838 section[i].pageflags = PAG_EXECUTE | PAG_READ; 839 if(section[i].flags & IMAGE_SCN_MEM_WRITE) 840 section[i].pageflags |= PAG_WRITE; 841 break; 841 842 case SECTION_INITDATA: 842 843 case SECTION_UNINITDATA: 843 844 case SECTION_IMPORT: //TODO: read only? 844 845 845 section[i].pageflags = PAG_WRITE | PAG_READ; 846 break; 846 847 case SECTION_READONLYDATA: 847 848 case SECTION_RESOURCE: 848 849 case SECTION_TLS: 849 850 default: 850 851 852 851 section[i].pageflags = PAG_READ; 852 break; 853 } 853 854 } 854 855 return(TRUE); … … 865 866 866 867 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 867 868 return(TRUE); 868 869 } 869 870 … … 872 873 size = (size-1) & ~0xFFF; 873 874 size += PAGE_SIZE; 874 875 875 876 if(prel) { 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 877 j = 1; 878 while(prel->VirtualAddress && prel->VirtualAddress < virtAddress) { 879 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock); 880 } 881 while(prel->VirtualAddress && prel->VirtualAddress < virtAddress + size) { 882 page = (char *)((char *)prel + (ULONG)prel->VirtualAddress); 883 count = (prel->SizeOfBlock - 8)/2; 884 j++; 885 for(i=0;i<count;i++) { 886 int type = prel->TypeOffset[i] >> 12; 887 int offset = prel->TypeOffset[i] & 0xFFF; 888 int fixupsize = 0; 889 890 switch(type) 891 { 892 case IMAGE_REL_BASED_HIGHLOW: 893 fixupsize = 4; 894 break; 895 case IMAGE_REL_BASED_HIGH: 896 case IMAGE_REL_BASED_LOW: 897 fixupsize = 2; 898 break; 899 } 900 //If the fixup crosses the final page boundary, 901 //then we have to load another page 902 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size) 903 { 904 newpage = realBaseAddress + prel->VirtualAddress + offset + fixupsize; 905 newpage &= ~0xFFF; 906 907 section = findSectionByOS2Addr(newpage); 908 if(section == NULL) { 909 //should never happen 910 dprintf((LOG, "::setFixups -> section == NULL!!")); 911 return FALSE; 912 } 913 //SvL: Read page from disk 914 commitPage(newpage, FALSE, SINGLE_PAGE); 915 916 //SvL: Enable write access 917 DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ|PAG_WRITE); 918 } 919 920 switch(type) 921 { 922 case IMAGE_REL_BASED_ABSOLUTE: 923 break; //skip 924 case IMAGE_REL_BASED_HIGHLOW: 925 AddOff32Fixup(prel->VirtualAddress + offset); 926 break; 927 case IMAGE_REL_BASED_HIGH: 928 AddOff16Fixup(prel->VirtualAddress + offset, TRUE); 929 break; 930 case IMAGE_REL_BASED_LOW: 931 AddOff16Fixup(prel->VirtualAddress + offset, FALSE); 932 break; 933 case IMAGE_REL_BASED_HIGHADJ: 934 case IMAGE_REL_BASED_MIPS_JMPADDR: 935 default: 936 break; 937 } 938 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size) 939 { 940 //SvL: Restore original page protection flags 941 DosSetMem((PVOID)newpage, PAGE_SIZE, section->pageflags); 942 } 943 } 944 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock); 945 }//while 945 946 } 946 947 else { 947 948 948 dprintf((LOG, "Win32PeLdrImage::setFixups, no fixups at %x, %d", virtAddress, size)); 949 return(FALSE); 949 950 } 950 951 return(TRUE); … … 959 960 960 961 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 961 962 return(TRUE); 962 963 } 963 964 … … 981 982 break; 982 983 case IMAGE_REL_BASED_HIGH: 983 984 984 AddOff16Fixup(prel->VirtualAddress + offset, TRUE); 985 break; 985 986 case IMAGE_REL_BASED_LOW: 986 987 987 AddOff16Fixup(prel->VirtualAddress + offset, FALSE); 988 break; 988 989 case IMAGE_REL_BASED_HIGHADJ: 989 990 case IMAGE_REL_BASED_MIPS_JMPADDR: … … 1025 1026 orgaddr = *fixup; 1026 1027 if(fHighFixup) { 1027 1028 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) >> 16); 1028 1029 // dprintf((LOG, "AddOff16FixupH 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup)); 1029 1030 } 1030 1031 else { 1031 1032 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) & 0xFFFF); 1032 1033 // dprintf((LOG, "AddOff16FixupL 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup)); 1033 1034 } … … 1044 1045 if(apiaddr == 0) 1045 1046 { 1046 1047 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%u not found\n", 1047 1048 WinDll->getName(), 1048 1049 ordinal)); 1049 1050 1050 1051 1051 dprintf((LOG, "--->>> NOT FOUND!" )); 1052 *import = (ULONG)MissingApi; 1052 1053 } 1053 1054 else *import = apiaddr; … … 1064 1065 if(apiaddr == 0) 1065 1066 { 1066 1067 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%s not found\n", 1067 1068 WinDll->getName(), 1068 1069 impname)); 1069 1070 1070 1071 1071 dprintf((LOG, "--->>> NOT FOUND!" )); 1072 *import = (ULONG)MissingApi; 1072 1073 } 1073 1074 else *import = apiaddr; … … 1149 1150 1150 1151 if(nameexports == NULL) { 1151 1152 1153 1152 nameExportSize= 4096; 1153 nameexports = (NameExport *)malloc(nameExportSize); 1154 curnameexport = nameexports; 1154 1155 } 1155 1156 nsize = (ULONG)curnameexport - (ULONG)nameexports; 1156 1157 if(nsize + sizeof(NameExport) + strlen(apiname) > nameExportSize) { 1157 1158 1159 1160 1161 1162 1158 nameExportSize += 4096; 1159 char *tmp = (char *)nameexports; 1160 nameexports = (NameExport *)malloc(nameExportSize); 1161 memcpy(nameexports, tmp, nsize); 1162 curnameexport = (NameExport *)((ULONG)nameexports + nsize); 1163 free(tmp); 1163 1164 } 1164 1165 curnameexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase); … … 1169 1170 curnameexport->nlength = strlen(apiname) + 1; 1170 1171 if(curnameexport->nlength < sizeof(curnameexport->name)) 1171 1172 curnameexport->nlength = sizeof(curnameexport->name); 1172 1173 1173 1174 curnameexport = (NameExport *)((ULONG)curnameexport->name + curnameexport->nlength); … … 1178 1179 { 1179 1180 if(ordexports == NULL) { 1180 1181 1181 ordexports = (OrdExport *)malloc(nrOrdExports * sizeof(OrdExport)); 1182 curordexport = ordexports; 1182 1183 } 1183 1184 curordexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase); … … 1329 1330 if(WinDll == NULL) 1330 1331 { //not found, so load it 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1332 char modname[CCHMAXPATH]; 1333 1334 strcpy(modname, pszCurModule); 1335 //rename dll if necessary (i.e. OLE32 -> OLE32OS2) 1336 Win32DllBase::renameDll(modname); 1337 1338 if(isPEImage(modname) == FALSE) 1339 {//LX image, so let OS/2 do all the work for us 1340 APIRET rc; 1341 char szModuleFailure[CCHMAXPATH] = ""; 1342 ULONG hInstanceNewDll; 1343 1344 char *dot = strchr(modname, '.'); 1345 if(dot) { 1346 *dot = 0; 1347 } 1348 strcat(modname, ".DLL"); 1349 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), modname, (HMODULE *)&hInstanceNewDll); 1350 if(rc) { 1351 dprintf((LOG, "DosLoadModule returned %X for %s\n", rc, szModuleFailure)); 1352 sprintf(szErrorModule, "%s.DLL", szModuleFailure); 1353 errorState = rc; 1354 return(FALSE); 1355 } 1356 WinDll = (Win32PeLdrDll *)Win32DllBase::findModule(hInstanceNewDll); 1357 if(WinDll == NULL) {//shouldn't happen! 1358 dprintf((LOG, "Just loaded the dll, but can't find it anywhere?!!?")); 1359 errorState = ERROR_INTERNAL; 1360 return(FALSE); 1361 } 1362 //Mark this dll as loaded by DosLoadModule 1363 WinDll->setLoadLibrary(); 1364 WinDll->AddRef(); 1365 } 1366 else { 1367 WinDll = new Win32PeLdrDll(modname, this); 1368 1369 if(WinDll == NULL) { 1370 dprintf((LOG, "WinDll: Error allocating memory" )); 1371 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szMemErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 1372 errorState = ERROR_INTERNAL; 1373 return(FALSE); 1374 } 1375 dprintf((LOG, "**********************************************************************" )); 1376 dprintf((LOG, "********************** Loading Module *********************" )); 1377 dprintf((LOG, "**********************************************************************" )); 1378 if(WinDll->init(0) == FALSE) { 1379 dprintf((LOG, "Internal WinDll error ", WinDll->getError() )); 1380 return(FALSE); 1381 } 1381 1382 #ifdef DEBUG 1382 1383 WinDll->AddRef(getModuleName()); 1383 1384 #else 1384 1385 WinDll->AddRef(); 1385 1386 #endif 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1387 if(WinDll->attachProcess() == FALSE) { 1388 dprintf((LOG, "attachProcess failed!" )); 1389 delete WinDll; 1390 errorState = ERROR_INTERNAL; 1391 return(FALSE); 1392 } 1393 } 1394 1395 dprintf((LOG, "**********************************************************************" )); 1396 dprintf((LOG, "********************** Finished Loading Module *********************" )); 1396 1397 dprintf((LOG, "**********************************************************************" )); 1397 1398 } 1398 1399 else { 1399 1400 1401 1402 1400 if(WinDll->isLxDll() && !WinDll->isLoaded()) { 1401 //can happen with i.e. wininet 1402 //wininet depends on wsock32; when the app loads wsock32 afterwards 1403 //with LoadLibrary or as a child of another dll, we need to make 1403 1404 //sure it's loaded once with DosLoadModule 1404 1405 1406 1407 1408 1405 WinDll->loadLibrary(); 1406 } 1407 WinDll->AddRef(); 1408 1409 dprintf((LOG, "Already found ", pszCurModule)); 1409 1410 } 1410 1411 //add the dll we just loaded to dependency list for this image … … 1422 1423 section = findSectionByOS2Addr(ulCurFixup); 1423 1424 if(section == NULL) { 1424 1425 1425 dprintf((LOG, "Unable to find section for %x", ulCurFixup )); 1426 return FALSE; 1426 1427 } 1427 1428 //SvL: Read page from disk … … 1452 1453 ulCurFixup += sizeof(IMAGE_THUNK_DATA); 1453 1454 j++; 1454 1455 1456 1457 1458 1455 if((ulCurFixup & 0xfff) == 0) { 1456 commitPage(ulCurFixup & ~0xfff, FALSE, SINGLE_PAGE); 1457 DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE, PAG_READ|PAG_WRITE); 1458 nrPages++; 1459 } 1459 1460 } 1460 1461 //SvL: And restore original protection flags … … 1485 1486 if(apilen < 4) 1486 1487 { 1487 1488 1489 1490 1491 } 1492 else 1488 *(ULONG *)tmp = 0; 1489 strcpy(tmp, name); 1490 apiname = tmp; 1491 apilen = 4; 1492 } 1493 else apiname = name; 1493 1494 1494 1495 curexport = nameexports; … … 1498 1499 *(ULONG *)curexport->name == *(ULONG *)apiname) 1499 1500 { 1500 1501 1501 if(strcmp(curexport->name, apiname) == 0) 1502 return(curexport->virtaddr); 1502 1503 } 1503 1504 curexport = (NameExport *)((ULONG)curexport->name + curexport->nlength); … … 1515 1516 curexport = ordexports; 1516 1517 for(i=0;i<nrOrdExports;i++) { 1517 1518 1519 1518 if(curexport->ordinal == ordinal) 1519 return(curexport->virtaddr); 1520 curexport++; 1520 1521 } 1521 1522 //Name exports also contain an ordinal, so check this 1522 1523 nexport = nameexports; 1523 1524 for(i=0;i<nrNameExports;i++) { 1524 1525 1526 1527 1525 if(nexport->ordinal == ordinal) 1526 return(nexport->virtaddr); 1527 1528 nexport = (NameExport *)((ULONG)nexport->name + nexport->nlength); 1528 1529 } 1529 1530 return(0); … … 1554 1555 1555 1556 if( r != MBID_IGNORE ) 1556 1557 ExitProcess(987); 1557 1558 1558 1559 fIgnore = TRUE; -
trunk/src/kernel32/wprocess.cpp
r3402 r3404 1 /* $Id: wprocess.cpp,v 1.7 8 2000-04-16 07:07:01 birdExp $ */1 /* $Id: wprocess.cpp,v 1.79 2000-04-16 10:42:13 sandervl Exp $ */ 2 2 3 3 /* … … 12 12 * 13 13 */ 14 15 16 17 /*******************************************************************************18 * Header Files *19 *******************************************************************************/20 14 #include <odin.h> 21 15 #include <odinwrap.h> … … 55 49 56 50 57 /****************************************************************************** 58 * Global Variables * 59 ******************************************************************************/ 51 //****************************************************************************** 52 //****************************************************************************** 60 53 BOOL fFreeLibrary = FALSE; 61 54 BOOL fIsOS2Image = FALSE; //TRUE -> Odin32 OS/2 application (not converted!) … … 69 62 static THDB *threadList = 0; 70 63 static VMutex threadListMutex; 71 72 73 74 64 //****************************************************************************** 75 65 //****************************************************************************** … … 365 355 VOID WIN32API ExitProcess(DWORD exitcode) 366 356 { 367 dprintf(("KERNEL32: ExitProcess %d\n", exitcode));368 dprintf(("KERNEL32: ExitProcess FS = %x\n", GetFS()));357 dprintf(("KERNEL32: ExitProcess %d\n", exitcode)); 358 dprintf(("KERNEL32: ExitProcess FS = %x\n", GetFS())); 369 359 370 360 SetOS2ExceptionChain(-1); … … 425 415 } 426 416 /******************************************************************************/ 427 //****************************************************************************** 428 HINSTANCE16 WIN32API LoadLibrary16(LPCTSTR lpszLibFile) 429 { 430 dprintf(("ERROR: LoadLibrary16 %s, not implemented", lpszLibFile)); 431 return 0; 432 } 433 //****************************************************************************** 434 //****************************************************************************** 435 VOID WIN32API FreeLibrary16(HINSTANCE16 hinstance) 436 { 437 dprintf(("ERROR: FreeLibrary16 %x, not implemented", hinstance)); 438 } 439 //****************************************************************************** 440 //****************************************************************************** 441 FARPROC WIN32API GetProcAddress16(HMODULE hModule, LPCSTR lpszProc) 442 { 443 dprintf(("ERROR: GetProcAddress16 %x %x, not implemented", hModule, lpszProc)); 444 return 0; 445 } 446 //****************************************************************************** 447 417 /******************************************************************************/ 448 418 /** 449 419 * LoadLibraryA can be used to map a DLL module into the calling process's … … 676 646 lpszLibFile, hFile, dwFlags)); 677 647 SetLastError(ERROR_INVALID_PARAMETER); 648 return NULL; 678 649 } 679 650 … … 990 961 //****************************************************************************** 991 962 //****************************************************************************** 963 HINSTANCE16 WIN32API LoadLibrary16(LPCTSTR lpszLibFile) 964 { 965 dprintf(("ERROR: LoadLibrary16 %s, not implemented", lpszLibFile)); 966 return 0; 967 } 968 //****************************************************************************** 969 //****************************************************************************** 970 VOID WIN32API FreeLibrary16(HINSTANCE16 hinstance) 971 { 972 dprintf(("ERROR: FreeLibrary16 %x, not implemented", hinstance)); 973 } 974 //****************************************************************************** 975 //****************************************************************************** 976 FARPROC WIN32API GetProcAddress16(HMODULE hModule, LPCSTR lpszProc) 977 { 978 dprintf(("ERROR: GetProcAddress16 %x %x, not implemented", hModule, lpszProc)); 979 return 0; 980 } 981 //****************************************************************************** 982 //****************************************************************************** 992 983 LPCSTR WIN32API GetCommandLineA() 993 984 { … … 1000 991 cmdline = O32_GetCommandLine(); 1001 992 1002 dprintf(("KERNEL32: GetCommandLine %s\n", cmdline));1003 dprintf(("KERNEL32: FS = %x\n", GetFS()));993 dprintf(("KERNEL32: GetCommandLine %s\n", cmdline)); 994 dprintf(("KERNEL32: FS = %x\n", GetFS())); 1004 995 return(cmdline); 1005 996 } … … 1011 1002 char *asciicmdline = NULL; 1012 1003 1013 dprintf(("KERNEL32: FS = %x\n", GetFS()));1004 dprintf(("KERNEL32: FS = %x\n", GetFS())); 1014 1005 1015 1006 if(UnicodeCmdLine) … … 1026 1017 UnicodeCmdLine = (WCHAR *)malloc(strlen(asciicmdline)*2 + 2); 1027 1018 AsciiToUnicode(asciicmdline, UnicodeCmdLine); 1028 dprintf(("KERNEL32: OS2GetCommandLineW: %s\n", asciicmdline));1019 dprintf(("KERNEL32: OS2GetCommandLineW: %s\n", asciicmdline)); 1029 1020 return(UnicodeCmdLine); 1030 1021 } 1031 dprintf(("KERNEL32: OS2GetCommandLineW: asciicmdline == NULL\n"));1022 dprintf(("KERNEL32: OS2GetCommandLineW: asciicmdline == NULL\n")); 1032 1023 return NULL; 1033 1024 } … … 1070 1061 DWORD rc; 1071 1062 1072 dprintf(("KERNEL32: OSLibGetModuleFileNameW\n"));1063 dprintf(("KERNEL32: OSLibGetModuleFileNameW\n")); 1073 1064 rc = GetModuleFileNameA(hModule, asciifilename, nSize); 1074 1065 if(rc) AsciiToUnicode(asciifilename, lpFileName); … … 1121 1112 } 1122 1113 1123 dprintf(("KERNEL32: GetModuleHandle %s returned %X\n", lpszModule, hMod));1114 dprintf(("KERNEL32: GetModuleHandle %s returned %X\n", lpszModule, hMod)); 1124 1115 return(hMod); 1125 1116 } … … 1133 1124 astring = UnicodeToAsciiString((LPWSTR)arg1); 1134 1125 rc = GetModuleHandleA(astring); 1135 dprintf(("KERNEL32: OS2GetModuleHandleW %s returned %X\n", astring, rc));1126 dprintf(("KERNEL32: OS2GetModuleHandleW %s returned %X\n", astring, rc)); 1136 1127 FreeAsciiString(astring); 1137 1128 return(rc); … … 1203 1194 sprintf(cmdline, "PE.EXE %s", lpCommandLine); 1204 1195 } 1205 dprintf(("KERNEL32: CreateProcess %s\n", cmdline));1196 dprintf(("KERNEL32: CreateProcess %s\n", cmdline)); 1206 1197 rc = O32_CreateProcess("PE.EXE", (LPCSTR)cmdline,lpProcessAttributes, 1207 1198 lpThreadAttributes, bInheritHandles, dwCreationFlags, … … 1229 1220 1230 1221 if(lpProcessInfo) 1231 dprintf(("KERNEL32: CreateProcess returned %d hPro:%x hThr:%x pid:%x tid:%x\n",1222 dprintf(("KERNEL32: CreateProcess returned %d hPro:%x hThr:%x pid:%x tid:%x\n", 1232 1223 rc, lpProcessInfo->hProcess, lpProcessInfo->hThread, 1233 1224 lpProcessInfo->dwProcessId,lpProcessInfo->dwThreadId)); 1234 1225 else 1235 dprintf(("KERNEL32: CreateProcess returned %d\n", rc));1226 dprintf(("KERNEL32: CreateProcess returned %d\n", rc)); 1236 1227 return(rc); 1237 1228 } … … 1296 1287 ULONG ulAPIOrdinal; 1297 1288 1298 winmod = Win32ImageBase::findModule(hModule); 1289 if(hModule == 0 || hModule == -1 || (WinExe && hModule == WinExe->getInstanceHandle())) { 1290 winmod = WinExe; 1291 } 1292 else winmod = (Win32ImageBase *)Win32DllBase::findModule((HINSTANCE)hModule); 1293 1299 1294 if(winmod) { 1300 1295 ulAPIOrdinal = (ULONG)lpszProc; … … 1310 1305 proc = O32_GetProcAddress(hModule, lpszProc); 1311 1306 if(HIWORD(lpszProc)) 1312 dprintf(("KERNEL32: GetProcAddress %s from %X returned %X\n", lpszProc, hModule, proc));1313 else dprintf(("KERNEL32: GetProcAddress %x from %X returned %X\n", lpszProc, hModule, proc));1307 dprintf(("KERNEL32: GetProcAddress %s from %X returned %X\n", lpszProc, hModule, proc)); 1308 else dprintf(("KERNEL32: GetProcAddress %x from %X returned %X\n", lpszProc, hModule, proc)); 1314 1309 return(proc); 1315 1310 }
Note:
See TracChangeset
for help on using the changeset viewer.