- Timestamp:
- Apr 16, 2000, 12:42:13 PM (26 years ago)
- Location:
- trunk/src/kernel32
- Files:
-
- 4 edited
-
winimagebase.cpp (modified) (6 diffs)
-
winimagebase.h (modified) (8 diffs)
-
winimagepeldr.cpp (modified) (47 diffs)
-
wprocess.cpp (modified) (18 diffs)
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 if(loadedDlls.getItem(item) == (ULONG)image) {118 ret = TRUE;119 break;120 } 121 item = loadedDlls.getNext(item);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 void setEntryPoint(ULONG startAddress) { entryPoint = startAddress; };87 void setEntryPoint(ULONG startAddress) { entryPoint = startAddress; }; 88 88 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; };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 tlsCallBackAddr = dwTlsCallBackAddr;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 getApi(int ordinal) = 0;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 //Add image to dependency list of this image109 void addDependency(Win32DllBase *dll);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 char szFileName[CCHMAXPATH];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 //linked list of dlls loaded on behalf of this executable image (dll or exe)147 Queue loadedDlls;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) (WINIMAGE_LOOKUP *)((ULONG)a + PAGE_SIZE - sizeof(WINIMAGE_LOOKUP))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 sprintf(logname, "pe_%d.log", loadNr);80 _privateLogFile = fopen(logname, "w");81 if(_privateLogFile == NULL) {82 sprintf(logname, "%spe_%d.log", kernel32Path, loadNr);83 _privateLogFile = fopen(logname, "w");84 }85 dprintfGlobal(("PE LOGFILE : %s", logname));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 if(_privateLogFile) {94 fclose(_privateLogFile);95 _privateLogFile = NULL;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 if(!strchr(szFileName, '.')) {116 strcat(szFileName,".EXE");117 }118 dllfile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);119 if(dllfile == NULL) {120 if(!strstr(szFileName, ".EXE")) {121 strcat(szFileName,".EXE");122 }123 dllfile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);124 if(dllfile == NULL) {125 OSLibDosSearchPath(OSLIB_SEARCHENV, "PATH", szFileName, szFileName, sizeof(szFileName));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 strcpy(szFileName, szModule);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 char *newdot = strstr(dot+1, ".");139 if(newdot == NULL)break;140 dot = newdot;139 char *newdot = strstr(dot+1, "."); 140 if(newdot == NULL) break; 141 dot = newdot; 141 142 } 142 143 if(dot) 143 *dot = 0;144 *dot = 0; 144 145 } 145 146 //****************************************************************************** … … 148 149 { 149 150 if(memmap) 150 delete memmap;151 delete memmap; 151 152 152 153 if(hFile) { 153 OSLibDosClose(hFile);154 hFile = 0;154 OSLibDosClose(hFile); 155 hFile = 0; 155 156 } 156 157 157 158 if(realBaseAddress) 158 DosFreeMem((PVOID)realBaseAddress);159 DosFreeMem((PVOID)realBaseAddress); 159 160 160 161 if(nameexports) 161 free(nameexports);162 free(nameexports); 162 163 163 164 if(ordexports) 164 free(ordexports);165 free(ordexports); 165 166 } 166 167 //****************************************************************************** … … 183 184 strcpy(szErrorModule, OSLibStripPath(szFileName)); 184 185 if(hFile == NULL) { 185 goto failure;186 goto failure; 186 187 } 187 188 //read dos header 188 189 if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) { 189 goto failure;190 goto failure; 190 191 } 191 192 if(OSLibDosSetFilePtr(hFile, doshdr.e_lfanew, OSLIB_SETPTR_FILE_BEGIN) == -1) { 192 goto failure;193 goto failure; 193 194 } 194 195 //read signature dword 195 196 if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) { 196 goto failure;197 goto failure; 197 198 } 198 199 //read pe header 199 200 if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) { 200 goto failure;201 goto failure; 201 202 } 202 203 //read optional header 203 204 if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) { 204 goto failure;205 goto failure; 205 206 } 206 207 if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || signature != IMAGE_NT_SIGNATURE) { 207 dprintf((LOG, "Not a valid PE file (probably a 16 bits windows exe/dll)!"));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 goto failure;210 goto failure; 210 211 } 211 212 212 213 if(oh.SizeOfImage == 0) {//just in case 213 oh.SizeOfImage = OSLibDosGetFileSize(hFile);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 dprintf((LOG, "Failed to allocate image memory, rc %d", errorState));;220 goto failure;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 goto failure;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 setFullPath(szFullPath);231 setFullPath(szFullPath); 231 232 } 232 233 233 234 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid 234 dprintf((LOG, "Not a valid PE file!"));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 goto failure;237 goto failure; 237 238 } 238 239 if(fh.Machine != IMAGE_FILE_MACHINE_I386) { 239 dprintf((LOG, "Doesn't run on x86 processors!"));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 goto failure;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 dprintf((LOG, "Can't convert system files"));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 goto failure;248 goto failure; 248 249 } 249 250 250 251 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 251 dprintf((LOG, "No fixups, might not run!"));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 if(strcmp(psh[i].Name, ".tls") == 0)315 {316 tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS);317 if(tlsDir) {318 addSection(SECTION_TLS, psh[i].PointerToRawData,319 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,320 psh[i].Misc.VirtualSize, psh[i].Characteristics);321 }322 continue;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 if(IsImportSection(win32file, &psh[i]))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 goto failure;388 goto failure; 388 389 } 389 390 } 390 391 } 391 392 else { 392 if(GetSectionHdrByName (win32file, &sh, ".rsrc"))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 dprintf((LOG, "imageSize != imageVirtEnd - oh.ImageBase!" ));408 imageSize = imageVirtEnd - oh.ImageBase;408 dprintf((LOG, "imageSize != imageVirtEnd - oh.ImageBase!" )); 409 imageSize = imageVirtEnd - oh.ImageBase; 409 410 } 410 411 if(imageSize < oh.SizeOfImage) { 411 imageSize = oh.SizeOfImage;412 imageSize = oh.SizeOfImage; 412 413 } 413 414 414 415 dprintf((LOG, "OS/2 base address %x", realBaseAddress )); 415 416 if(oh.AddressOfEntryPoint) { 416 entryPoint = realBaseAddress + oh.AddressOfEntryPoint;417 entryPoint = realBaseAddress + oh.AddressOfEntryPoint; 417 418 } 418 419 else { 419 dprintf((LOG, "EntryPoint == NULL" ));420 entryPoint = NULL;420 dprintf((LOG, "EntryPoint == NULL" )); 421 entryPoint = NULL; 421 422 } 422 423 423 424 //set memory protection flags 424 425 if(setMemFlags() == FALSE) { 425 dprintf((LOG, "Failed to set memory protection" ));426 goto failure;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 if(sect == NULL) {435 dprintf((LOG, "Couldn't find TLS section!!" ));436 goto failure;437 }438 dprintf((LOG, "TLS Directory" ));439 dprintf((LOG, "TLS Address of Index %x", tlsDir->AddressOfIndex ));440 dprintf((LOG, "TLS Address of Callbacks %x", tlsDir->AddressOfCallBacks ));441 dprintf((LOG, "TLS SizeOfZeroFill %x", tlsDir->SizeOfZeroFill ));442 dprintf((LOG, "TLS Characteristics %x", tlsDir->Characteristics ));443 setTLSAddress((char *)sect->realvirtaddr);444 setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData);445 setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill);446 447 sect = findSectionByAddr((ULONG)tlsDir->AddressOfIndex);448 if(sect == NULL) {449 dprintf((LOG, "Couldn't find TLS AddressOfIndex section!!" ));450 goto failure;451 }452 setTLSIndexAddr((LPDWORD)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfIndex - sect->virtaddr)));453 454 if((ULONG)tlsDir->AddressOfCallBacks != 0) {455 sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks);456 if(sect == NULL) {457 dprintf((LOG, "Couldn't find TLS AddressOfCallBacks section!!" ));458 goto failure;459 }460 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfCallBacks - sect->virtaddr)));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 pFixups = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC);466 commitPage((ULONG)pFixups, FALSE);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 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION);471 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION); 471 472 } 472 473 #else 473 474 for (i=0; i<nSections; i++) { 474 switch(section[i].type)475 {476 case SECTION_IMPORT:477 case SECTION_RELOC:478 case SECTION_EXPORT:479 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION);480 break;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 dprintf((LOG, "Failed to process exported apis" ));486 goto failure;486 dprintf((LOG, "Failed to process exported apis" )); 487 goto failure; 487 488 } 488 489 } 489 490 #ifdef COMMIT_ALL 490 491 else { 491 commitPage((ULONG)section[0].realvirtaddr, FALSE, COMPLETE_SECTION);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 //get offset in resource object of directory entry505 pResDir = (PIMAGE_RESOURCE_DIRECTORY)(sh.VirtualAddress + realBaseAddress);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 dprintf((LOG, "Failed to process imports!" ));513 goto failure;513 dprintf((LOG, "Failed to process imports!" )); 514 goto failure; 514 515 } 515 516 } … … 518 519 failure: 519 520 if(memmap) { 520 delete memmap;521 memmap = NULL;521 delete memmap; 522 memmap = NULL; 522 523 } 523 524 if(hFile) { 524 OSLibDosClose(hFile);525 hFile = 0;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 size = 4096;547 sectionsize = 4096;548 protflags = PAG_READ|PAG_WRITE; //readonly?549 section = findPreviousSectionByOS2Addr(virtAddress);550 if(section == NULL) {//access to header551 offset = 0;552 fileoffset = virtAddress - realBaseAddress;553 }554 else {555 offset = virtAddress - (section->realvirtaddr + section->virtualsize);556 fileoffset = section->rawoffset + section->rawsize + offset;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 protflags = section->pageflags;561 offset = virtAddress - section->realvirtaddr;562 sectionsize = section->virtualsize - offset;563 564 if(offset > section->rawsize || section->type == SECTION_UNINITDATA) {565 //unintialized data (set to 0)566 size = 0;567 fileoffset = -1;568 }569 else {570 size = section->rawsize-offset;571 fileoffset = section->rawoffset + offset;572 }573 if(fWriteAccess & !(section->pageflags & PAG_WRITE)) {574 dprintf((LOG, "Win32PeLdrImage::commitPage: No write access to 0%x!", virtAddress));575 return FALSE;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 dprintf((LOG, "Win32PeLdrImage::commitPage: DosQueryMem for %x returned %d", virtAddress, rc));584 return FALSE;584 dprintf((LOG, "Win32PeLdrImage::commitPage: DosQueryMem for %x returned %d", virtAddress, rc)); 585 return FALSE; 585 586 } 586 587 if(attr & PAG_COMMIT) { 587 dprintf((LOG, "Win32PeLdrImage::commitPage: Memory at 0x%x already committed!", virtAddress));588 return FALSE;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 size = min(size, PAGE_SIZE);593 sectionsize = min(sectionsize, PAGE_SIZE);593 size = min(size, PAGE_SIZE); 594 sectionsize = min(sectionsize, PAGE_SIZE); 594 595 } 595 596 else 596 597 if(fPageCmd == SECTION_PAGES) { 597 size = min(size, DEFAULT_NR_PAGES*PAGE_SIZE);598 sectionsize = min(sectionsize, DEFAULT_NR_PAGES*PAGE_SIZE);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 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);605 if(rc) {606 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));607 return FALSE;608 }609 610 if(DosSetFilePtr(hFile, fileoffset, FILE_BEGIN, &ulNewPos) == -1) {611 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetFilePtr failed for 0x%x!", fileoffset));612 return FALSE;613 }614 if(DosRead(hFile, (PVOID)virtAddress, size, &ulRead)) {615 dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed for 0x%x!", virtAddress));616 return FALSE;617 }618 if(ulRead != size) {619 dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed to read %x (%x) bytes at %x for 0x%x!", size, ulRead, fileoffset, virtAddress));620 return FALSE;621 }622 if(realBaseAddress != oh.ImageBase) {623 setFixups(virtAddress, sectionsize);624 }625 626 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);627 if(rc) {628 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));629 return FALSE;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 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);634 if(rc) {635 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));636 return FALSE;637 }638 if(realBaseAddress != oh.ImageBase) {639 setFixups(virtAddress, sectionsize);640 }641 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);642 if(rc) {643 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));644 return FALSE;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 imageVirtBase = virtaddress;667 imageVirtBase = virtaddress; 667 668 if(virtaddress + virtsize > imageVirtEnd) 668 imageVirtEnd = virtaddress + virtsize;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 return allocFixedMem(reservedMem);682 return allocFixedMem(reservedMem); 682 683 } 683 684 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | flAllocMem); 684 685 if(rc) { 685 dprintf((LOG, "Win32PeLdrImage::allocSections, DosAllocMem returned %d", rc));686 errorState = rc;687 return(FALSE);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 if(section[i].type == type) {698 return §ion[i];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 if(section[i].virtaddr <= addr && section[i].virtaddr + section[i].virtualsize > addr) {709 return §ion[i];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 if(section[i].realvirtaddr <= addr && section[i].realvirtaddr + section[i].virtualsize > addr) {720 return §ion[i];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 if(section[i].realvirtaddr > addr) {734 if(section[i].realvirtaddr < lowestAddr) {735 lowestAddr = section[i].realvirtaddr;736 index = i;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 return NULL;742 return NULL; 742 743 743 744 return §ion[index]; … … 761 762 //Allocated in peldr.dll 762 763 if(reservedMem && reservedMem == oh.ImageBase) { 763 realBaseAddress = oh.ImageBase;764 return TRUE;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 dprintf((LOG, "allocFixedMem: MALLOC FAILED for memallocs" ));771 return FALSE;771 dprintf((LOG, "allocFixedMem: MALLOC FAILED for memallocs" )); 772 return FALSE; 772 773 } 773 774 774 775 if(oh.ImageBase < 512*1024*1024) { 775 allocFlags = 0;776 allocFlags = 0; 776 777 } 777 778 while(TRUE) { 778 rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | allocFlags);779 if(rc) break;780 781 dprintf((LOG, "DosAllocMem returned %x", address ));782 if(address + FALLOC_SIZE >= oh.ImageBase) {783 if(address > oh.ImageBase) {//we've passed it!784 DosFreeMem((PVOID)address);785 break;786 }787 //found the right address788 DosFreeMem((PVOID)address);789 790 diff = oh.ImageBase - address;791 if(diff) {792 rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | allocFlags);793 if(rc) break;794 }795 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | allocFlags);796 if(rc) break;797 798 if(diff) DosFreeMem((PVOID)address);799 800 realBaseAddress = baseAddress;801 break;802 }803 memallocs[alloccnt++] = address;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 DosFreeMem((PVOID)memallocs[i]);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 return(FALSE);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 section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase);830 section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase); 830 831 } 831 832 832 833 for(i=0;i<nrsections;i++) { 833 switch(section[i].type)834 {834 switch(section[i].type) 835 { 835 836 case SECTION_CODE: 836 837 case (SECTION_CODE | SECTION_IMPORT): 837 section[i].pageflags = PAG_EXECUTE | PAG_READ;838 if(section[i].flags & IMAGE_SCN_MEM_WRITE) 839 section[i].pageflags |= PAG_WRITE;840 break;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 section[i].pageflags = PAG_WRITE | PAG_READ;845 break;845 section[i].pageflags = PAG_WRITE | PAG_READ; 846 break; 846 847 case SECTION_READONLYDATA: 847 848 case SECTION_RESOURCE: 848 case SECTION_TLS:849 case SECTION_TLS: 849 850 default: 850 section[i].pageflags = PAG_READ;851 break;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 return(TRUE);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 j = 1;877 while(prel->VirtualAddress && prel->VirtualAddress < virtAddress) {878 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);879 }880 while(prel->VirtualAddress && prel->VirtualAddress < virtAddress + size) {881 page = (char *)((char *)prel + (ULONG)prel->VirtualAddress);882 count = (prel->SizeOfBlock - 8)/2;883 j++;884 for(i=0;i<count;i++) {885 int type = prel->TypeOffset[i] >> 12;886 int offset = prel->TypeOffset[i] & 0xFFF;887 int fixupsize = 0;888 889 switch(type)890 {891 case IMAGE_REL_BASED_HIGHLOW:892 fixupsize = 4;893 break;894 case IMAGE_REL_BASED_HIGH:895 case IMAGE_REL_BASED_LOW:896 fixupsize = 2;897 break;898 }899 //If the fixup crosses the final page boundary,900 //then we have to load another page901 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)902 {903 newpage = realBaseAddress + prel->VirtualAddress + offset + fixupsize;904 newpage &= ~0xFFF;905 906 section = findSectionByOS2Addr(newpage);907 if(section == NULL) {908 //should never happen909 dprintf((LOG, "::setFixups -> section == NULL!!"));910 return FALSE;911 }912 //SvL: Read page from disk913 commitPage(newpage, FALSE, SINGLE_PAGE);914 915 //SvL: Enable write access916 DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ|PAG_WRITE);917 }918 919 switch(type)920 {921 case IMAGE_REL_BASED_ABSOLUTE:922 break; //skip923 case IMAGE_REL_BASED_HIGHLOW:924 AddOff32Fixup(prel->VirtualAddress + offset);925 break;926 case IMAGE_REL_BASED_HIGH:927 AddOff16Fixup(prel->VirtualAddress + offset, TRUE);928 break;929 case IMAGE_REL_BASED_LOW:930 AddOff16Fixup(prel->VirtualAddress + offset, FALSE);931 break;932 case IMAGE_REL_BASED_HIGHADJ:933 case IMAGE_REL_BASED_MIPS_JMPADDR:934 default:935 break;936 }937 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)938 {939 //SvL: Restore original page protection flags940 DosSetMem((PVOID)newpage, PAGE_SIZE, section->pageflags);941 }942 }943 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);944 }//while877 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 dprintf((LOG, "Win32PeLdrImage::setFixups, no fixups at %x, %d", virtAddress, size));948 return(FALSE);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 return(TRUE);962 return(TRUE); 962 963 } 963 964 … … 981 982 break; 982 983 case IMAGE_REL_BASED_HIGH: 983 AddOff16Fixup(prel->VirtualAddress + offset, TRUE);984 break;984 AddOff16Fixup(prel->VirtualAddress + offset, TRUE); 985 break; 985 986 case IMAGE_REL_BASED_LOW: 986 AddOff16Fixup(prel->VirtualAddress + offset, FALSE);987 break;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 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) >> 16);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 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) & 0xFFFF);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 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%u not found\n",1047 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%u not found\n", 1047 1048 WinDll->getName(), 1048 1049 ordinal)); 1049 1050 1050 dprintf((LOG, "--->>> NOT FOUND!" ));1051 *import = (ULONG)MissingApi;1051 dprintf((LOG, "--->>> NOT FOUND!" )); 1052 *import = (ULONG)MissingApi; 1052 1053 } 1053 1054 else *import = apiaddr; … … 1064 1065 if(apiaddr == 0) 1065 1066 { 1066 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%s not found\n",1067 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%s not found\n", 1067 1068 WinDll->getName(), 1068 1069 impname)); 1069 1070 1070 dprintf((LOG, "--->>> NOT FOUND!" ));1071 *import = (ULONG)MissingApi;1071 dprintf((LOG, "--->>> NOT FOUND!" )); 1072 *import = (ULONG)MissingApi; 1072 1073 } 1073 1074 else *import = apiaddr; … … 1149 1150 1150 1151 if(nameexports == NULL) { 1151 nameExportSize= 4096;1152 nameexports = (NameExport *)malloc(nameExportSize);1153 curnameexport = nameexports;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 nameExportSize += 4096;1158 char *tmp = (char *)nameexports;1159 nameexports = (NameExport *)malloc(nameExportSize);1160 memcpy(nameexports, tmp, nsize);1161 curnameexport = (NameExport *)((ULONG)nameexports + nsize);1162 free(tmp);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 curnameexport->nlength = sizeof(curnameexport->name);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 ordexports = (OrdExport *)malloc(nrOrdExports * sizeof(OrdExport));1181 curordexport = ordexports;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 char modname[CCHMAXPATH];1332 1333 strcpy(modname, pszCurModule);1334 //rename dll if necessary (i.e. OLE32 -> OLE32OS2)1335 Win32DllBase::renameDll(modname);1336 1337 if(isPEImage(modname) == FALSE)1338 {//LX image, so let OS/2 do all the work for us1339 APIRET rc;1340 char szModuleFailure[CCHMAXPATH] = "";1341 ULONG hInstanceNewDll;1342 1343 char *dot = strchr(modname, '.');1344 if(dot) {1345 *dot = 0;1346 }1347 strcat(modname, ".DLL");1348 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), modname, (HMODULE *)&hInstanceNewDll);1349 if(rc) {1350 dprintf((LOG, "DosLoadModule returned %X for %s\n", rc, szModuleFailure));1351 sprintf(szErrorModule, "%s.DLL", szModuleFailure);1352 errorState = rc;1353 return(FALSE);1354 }1355 WinDll = (Win32PeLdrDll *)Win32DllBase::findModule(hInstanceNewDll);1356 if(WinDll == NULL) {//shouldn't happen!1357 dprintf((LOG, "Just loaded the dll, but can't find it anywhere?!!?"));1358 errorState = ERROR_INTERNAL;1359 return(FALSE);1360 }1361 //Mark this dll as loaded by DosLoadModule1362 WinDll->setLoadLibrary();1363 WinDll->AddRef();1364 }1365 else {1366 WinDll = new Win32PeLdrDll(modname, this);1367 1368 if(WinDll == NULL) {1369 dprintf((LOG, "WinDll: Error allocating memory" ));1370 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szMemErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);1371 errorState = ERROR_INTERNAL;1372 return(FALSE);1373 }1374 dprintf((LOG, "**********************************************************************" ));1375 dprintf((LOG, "********************** Loading Module *********************" ));1376 dprintf((LOG, "**********************************************************************" ));1377 if(WinDll->init(0) == FALSE) {1378 dprintf((LOG, "Internal WinDll error ", WinDll->getError() ));1379 return(FALSE);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 WinDll->AddRef(getModuleName());1383 WinDll->AddRef(getModuleName()); 1383 1384 #else 1384 WinDll->AddRef();1385 WinDll->AddRef(); 1385 1386 #endif 1386 if(WinDll->attachProcess() == FALSE) {1387 dprintf((LOG, "attachProcess failed!" ));1388 delete WinDll;1389 errorState = ERROR_INTERNAL;1390 return(FALSE);1391 }1392 }1393 1394 dprintf((LOG, "**********************************************************************" ));1395 dprintf((LOG, "********************** Finished Loading Module *********************" ));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 if(WinDll->isLxDll() && !WinDll->isLoaded()) {1400 //can happen with i.e. wininet1401 //wininet depends on wsock32; when the app loads wsock32 afterwards1402 //with LoadLibrary or as a child of another dll, we need to make1400 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 WinDll->loadLibrary();1405 }1406 WinDll->AddRef();1407 1408 dprintf((LOG, "Already found ", pszCurModule));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 dprintf((LOG, "Unable to find section for %x", ulCurFixup ));1425 return FALSE;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 if((ulCurFixup & 0xfff) == 0) {1455 commitPage(ulCurFixup & ~0xfff, FALSE, SINGLE_PAGE);1456 DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE, PAG_READ|PAG_WRITE);1457 nrPages++;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 *(ULONG *)tmp = 0;1488 strcpy(tmp, name);1489 apiname = tmp;1490 apilen = 4;1491 } 1492 else apiname = name;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 if(strcmp(curexport->name, apiname) == 0)1501 return(curexport->virtaddr);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 if(curexport->ordinal == ordinal)1518 return(curexport->virtaddr);1519 curexport++;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 if(nexport->ordinal == ordinal)1525 return(nexport->virtaddr);1526 1527 nexport = (NameExport *)((ULONG)nexport->name + nexport->nlength);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 ExitProcess(987);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.
