- Timestamp:
- Nov 22, 1999, 9:35:52 PM (26 years ago)
- Location:
- trunk/src/kernel32
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/HandleManager.cpp
r1713 r1811 1 /* $Id: HandleManager.cpp,v 1.2 5 1999-11-12 14:57:13sandervl Exp $ */1 /* $Id: HandleManager.cpp,v 1.26 1999-11-22 20:35:49 sandervl Exp $ */ 2 2 3 3 /* … … 1563 1563 if (-1 == iIndex) /* error ? */ 1564 1564 { 1565 SetLastError(ERROR_INVALID_HANDLE); /* set win32 error information */ 1566 return WAIT_FAILED; /* signal failure */ 1565 dprintf(("KERNEL32: HandleManager:HMWaitForSingleObject(%08xh) passed on to Open32.\n", 1566 hObject)); 1567 1568 // maybe handles from CreateProcess() ... 1569 dwResult = O32_WaitForSingleObject(hObject, dwTimeout); 1570 return (dwResult); 1567 1571 } 1568 1572 -
trunk/src/kernel32/exceptions.cpp
r1741 r1811 1 /* $Id: exceptions.cpp,v 1. 29 1999-11-14 17:25:04sandervl Exp $ */1 /* $Id: exceptions.cpp,v 1.30 1999-11-22 20:35:49 sandervl Exp $ */ 2 2 3 3 /* … … 938 938 PVOID p) 939 939 { 940 dprintfException(pERepRec, pERegRec, pCtxRec, p);941 942 940 /* Access violation at a known location */ 943 941 switch(pERepRec->ExceptionNum) … … 950 948 case XCPT_FLOAT_STACK_CHECK: 951 949 case XCPT_FLOAT_UNDERFLOW: 950 dprintfException(pERepRec, pERegRec, pCtxRec, p); 952 951 dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception\n")); 953 952 if(fIsOS2Image == FALSE) //Only for real win32 apps … … 971 970 case XCPT_PROCESS_TERMINATE: 972 971 case XCPT_ASYNC_PROCESS_TERMINATE: 972 dprintfException(pERepRec, pERegRec, pCtxRec, p); 973 973 SetExceptionChain((ULONG)-1); 974 974 return (XCPT_CONTINUE_SEARCH); … … 1021 1021 case XCPT_IN_PAGE_ERROR: 1022 1022 CrashAndBurn: 1023 dprintfException(pERepRec, pERegRec, pCtxRec, p); 1023 1024 if(fIsOS2Image == FALSE) //Only for real win32 apps 1024 1025 { … … 1051 1052 1052 1053 default: //non-continuable exceptions 1054 dprintfException(pERepRec, pERegRec, pCtxRec, p); 1053 1055 return (XCPT_CONTINUE_SEARCH); 1054 1056 } -
trunk/src/kernel32/hmopen32.cpp
r1727 r1811 1 /* $Id: hmopen32.cpp,v 1.1 3 1999-11-13 18:50:22sandervl Exp $ */1 /* $Id: hmopen32.cpp,v 1.14 1999-11-22 20:35:49 sandervl Exp $ */ 2 2 3 3 /* … … 284 284 285 285 #if 1 286 Win32MemMap *map;287 DWORD offset;288 289 //SvL: DosRead doesn't like writing to memory addresses returned by290 // DosAliasMem -> search for original memory mapped pointer and use291 // that one292 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_READ);293 if(map) {294 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);295 DWORD nrpages = nNumberOfBytesToRead/4096;296 if(offset & 0xfff)297 nrpages++;298 else299 if(nNumberOfBytesToRead & 0xfff)300 nrpages++;301 302 map->commitPage(offset & ~0xfff, TRUE, nrpages);303 }304 else lpRealBuf = (LPVOID)lpBuffer;305 306 286 bRC = O32_ReadFile(pHMHandleData->hHMHandle, 307 (PVOID)lp RealBuf,287 (PVOID)lpBuffer, 308 288 nNumberOfBytesToRead, 309 289 lpNumberOfBytesRead, -
trunk/src/kernel32/initterm.cpp
r1768 r1811 1 /* $Id: initterm.cpp,v 1.2 5 1999-11-18 09:20:08 birdExp $ */1 /* $Id: initterm.cpp,v 1.26 1999-11-22 20:35:50 sandervl Exp $ */ 2 2 3 3 /* … … 45 45 #include "directory.h" 46 46 #include "hmdevio.h" 47 #include <windllbase.h> 47 48 48 49 /*-------------------------------------------------------------------*/ … … 138 139 InitDirectories(); 139 140 RegisterDevices(); 141 Win32DllBase::setDefaultRenaming(); 140 142 break; 141 143 } -
trunk/src/kernel32/makefile
r1769 r1811 1 # $Id: makefile,v 1.5 8 1999-11-18 09:20:29 birdExp $1 # $Id: makefile,v 1.59 1999-11-22 20:35:50 sandervl Exp $ 2 2 3 3 # … … 340 340 341 341 virtual.obj: virtual.cpp $(PDWIN32_INCLUDE)\win\virtual.h $(PDWIN32_INCLUDE)\handlemanager.h mmap.h 342 mmap.obj: mmap.cpp mmap.h $(PDWIN32_INCLUDE)\vmutex.h oslibdos.h $(PDWIN32_INCLUDE)\heapshared.h 342 mmap.obj: mmap.cpp mmap.h $(PDWIN32_INCLUDE)\vmutex.h oslibdos.h $(PDWIN32_INCLUDE)\heapshared.h $(PDWIN32_INCLUDE)\winimagepeldr.h 343 343 344 344 pefile.OBJ: pefile.cpp $(PDWIN32_INCLUDE)\pefile.h $(PDWIN32_INCLUDE)\winres.h -
trunk/src/kernel32/mmap.cpp
r1687 r1811 1 /* $Id: mmap.cpp,v 1.2 2 1999-11-10 14:16:01sandervl Exp $ */1 /* $Id: mmap.cpp,v 1.23 1999-11-22 20:35:50 sandervl Exp $ */ 2 2 3 3 /* … … 29 29 #include "mmap.h" 30 30 #include "oslibdos.h" 31 #include <winimagepeldr.h> 31 32 32 33 //Global DLL Data … … 42 43 //****************************************************************************** 43 44 Win32MemMap::Win32MemMap(HFILE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName) 44 : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0) 45 : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0), image(0) 45 46 { 46 47 globalmapMutex.enter(); … … 60 61 } 61 62 else lpszMapName = NULL; 63 } 64 //****************************************************************************** 65 //Map constructor used for executable image maps (only used internally) 66 //****************************************************************************** 67 Win32MemMap::Win32MemMap(Win32PeLdrImage *pImage, ULONG baseAddress, ULONG size) 68 : nrMappings(0), pMapping(NULL), mMapAccess(0), referenced(0) 69 { 70 globalmapMutex.enter(); 71 next = memmaps; 72 memmaps = this; 73 globalmapMutex.leave(); 74 75 hMemFile = -1; 76 77 mSize = size; 78 mProtFlags = PAGE_READWRITE; 79 mProcessId = GetCurrentProcess(); 80 81 pMapping = (LPVOID)baseAddress; 82 83 image = pImage; 84 lpszMapName= NULL; 62 85 } 63 86 //****************************************************************************** … … 107 130 free(lpszMapName); 108 131 } 109 if(pMapping ) {132 if(pMapping && !image) { 110 133 if(lpszMapName) { 111 134 OSLibDosFreeMem(pMapping); … … 154 177 // mapMutex.enter(); 155 178 179 if(image) { 180 return image->commitPage(pageAddr, fWriteAccess); 181 } 156 182 newProt = mProtFlags & (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY); 157 183 … … 199 225 goto fail; 200 226 } 201 if(mProtFlags & PAGE_READONLY) {227 if(mProtFlags != PAGE_READWRITE) { 202 228 if(VirtualProtect((LPVOID)pageAddr, memInfo.RegionSize, newProt, &oldProt) == FALSE) { 203 229 goto fail; … … 211 237 goto fail; 212 238 } 213 if(VirtualAlloc((LPVOID)pageAddr, memInfo.RegionSize, MEM_COMMIT, newProt) == FALSE) { 214 goto fail; 239 if(!(memInfo.State & MEM_COMMIT)) 240 {//if it's already committed, then the app tried to write to it 241 if(VirtualAlloc((LPVOID)pageAddr, memInfo.RegionSize, MEM_COMMIT, newProt) == FALSE) 242 goto fail; 215 243 } 216 244 } … … 282 310 #endif 283 311 284 if(nrMappings == 0) {//if not mapped, reserve/commit entire view 312 //Memory has already been allocated for executable image maps (only used internally) 313 if(!pMapping && nrMappings == 0) {//if not mapped, reserve/commit entire view 285 314 //SvL: Always read/write access or else ReadFile will crash once we 286 315 // start committing pages. … … 332 361 ULONG nrBytesWritten, size; 333 362 int i; 363 364 if(image) //no flushing for image maps 365 return TRUE; 334 366 335 367 dprintf(("Win32MemMap::flushView: %x %x", lpvBase, cbFlush)); … … 447 479 nextmap = map->next; 448 480 if(map->getProcessId() == processId) { 449 CloseHandle(memmaps->hMemMap); 481 //Delete map directly for executable images (only used internally) 482 if(map->getImage()) { 483 delete map; 484 } 485 else CloseHandle(memmaps->hMemMap); 450 486 } 451 487 else { … … 492 528 } 493 529 494 if(OSLibDosAliasMem(viewaddr, size, &pMapView, accessAttr) != OSLIB_NOERROR) { 495 dprintf(("new OSLibDosAliasMem FAILED")); 496 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 497 errorState = 1; 498 return; 530 //view == memory mapping for executable images (only used internally) 531 if(map->getImage()) { 532 pMapView = map->getMappingAddr(); 533 } 534 else { 535 if(OSLibDosAliasMem(viewaddr, size, &pMapView, accessAttr) != OSLIB_NOERROR) { 536 dprintf(("new OSLibDosAliasMem FAILED")); 537 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 538 errorState = 1; 539 return; 540 } 499 541 } 500 542 … … 530 572 mParentMap->flushView(mOffset, mSize); 531 573 532 OSLibDosFreeMem(pMapView); 574 //Don't free memory for executable image map views (only used internally) 575 if(!mParentMap->getImage()) 576 OSLibDosFreeMem(pMapView); 533 577 534 578 globalviewMutex.enter(); -
trunk/src/kernel32/mmap.h
r1687 r1811 1 /* $Id: mmap.h,v 1.1 1 1999-11-10 14:16:01sandervl Exp $ */1 /* $Id: mmap.h,v 1.12 1999-11-22 20:35:50 sandervl Exp $ */ 2 2 3 3 /* … … 28 28 29 29 class Win32MemMapView; 30 class Win32PeLdrImage; 30 31 31 32 //****************************************************************************** … … 35 36 public: 36 37 Win32MemMap(HFILE hfile, ULONG size, ULONG fdwProtect, LPSTR lpszName); 38 //Use by PE loader image class only: 39 Win32MemMap(Win32PeLdrImage *pImage, ULONG lpImageMem, ULONG size); 37 40 ~Win32MemMap(); 38 41 … … 47 50 LPVOID getMappingAddr() { return pMapping; }; 48 51 DWORD getProcessId() { return mProcessId;}; 52 Win32PeLdrImage *getImage() { return image; }; 53 54 BOOL isImageMap() { return image != NULL; }; 49 55 50 56 void AddRef() { ++referenced; }; … … 93 99 94 100 VMutex mapMutex; 101 102 Win32PeLdrImage *image; 95 103 96 104 private: -
trunk/src/kernel32/oslibdos.cpp
r1710 r1811 1 /* $Id: oslibdos.cpp,v 1. 8 1999-11-12 11:38:40 sandervl Exp $ */1 /* $Id: oslibdos.cpp,v 1.9 1999-11-22 20:35:50 sandervl Exp $ */ 2 2 3 3 /* … … 26 26 27 27 //****************************************************************************** 28 //TODO: Assumes entire memory range has the same protection flags! 29 //TODO: Check if this works for code aliases... 28 30 //****************************************************************************** 29 31 DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl) 30 32 { 31 return DosAliasMem(pb, cb, ppbAlias, fl); 33 DWORD rc; 34 DWORD attr; 35 DWORD size = cb; 36 37 cb = (cb-1) & ~0xfff; 38 cb+= PAGE_SIZE; 39 40 rc = DosQueryMem(pb, &size, &attr); 41 if(rc) { 42 dprintf(("OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc)); 43 return rc; 44 } 45 size = (size-1) & ~0xfff; 46 size+= PAGE_SIZE; 47 if(size != cb) { 48 dprintf(("ERROR: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb)); 49 return 5; 50 } 51 attr &= (PAG_READ|PAG_WRITE|PAG_EXECUTE|PAG_GUARD|PAG_DEFAULT); 52 if(attr != fl) { 53 rc = DosSetMem(pb, size, fl); 54 if(rc) { 55 dprintf(("OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc)); 56 attr = fl; 57 //just continue for now 58 //return rc; 59 } 60 } 61 rc = DosAliasMem(pb, cb, ppbAlias, 2); 62 if(rc) { 63 dprintf(("OSLibDosAliasMem: DosAliasMem %x %x return %d", pb, cb, rc)); 64 return rc; 65 } 66 if(attr != fl) { 67 rc = DosSetMem(pb, size, attr); 68 if(rc) { 69 dprintf(("OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc)); 70 return rc; 71 } 72 } 73 return 0; 32 74 } 33 75 //****************************************************************************** -
trunk/src/kernel32/oslibdos.h
r1710 r1811 1 /* $Id: oslibdos.h,v 1. 7 1999-11-12 11:38:40 sandervl Exp $ */1 /* $Id: oslibdos.h,v 1.8 1999-11-22 20:35:50 sandervl Exp $ */ 2 2 3 3 /* … … 94 94 DWORD OSLibDosSetFilePtr2(DWORD hFile, DWORD offset, DWORD method); 95 95 96 #ifndef PAGE_SIZE 97 #define PAGE_SIZE 4096 96 98 #endif 99 100 #endif -
trunk/src/kernel32/pefile.cpp
r956 r1811 1 /* $Id: pefile.cpp,v 1. 5 1999-09-15 23:38:01 sandervl Exp $ */1 /* $Id: pefile.cpp,v 1.6 1999-11-22 20:35:51 sandervl Exp $ */ 2 2 3 3 /* … … 12 12 #include <string.h> 13 13 #include <stdlib.h> 14 #ifdef __WATCOMC__15 #include <mem.h>16 #endif17 14 #include <win32type.h> 18 15 #include <pefile.h> … … 73 70 } 74 71 75 return (LPVOID)(((ULONG)lpFile + (ULONG)(poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress - 76 sh.VirtualAddress) + (ULONG)sh.PointerToRawData)); 72 return (LPVOID)((ULONG)lpFile + poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress); 77 73 } 78 74 //****************************************************************************** … … 149 145 return FALSE; 150 146 } 151 //******************************************************************************152 //******************************************************************************153 int GetNumberOfResources(LPVOID lpFile)154 {155 PIMAGE_RESOURCE_DIRECTORY prdRoot, prdType;156 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;157 int nCnt=0, i, j, id;158 char *resname;159 160 if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY)ImageDirectoryOffset161 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)162 return 0;163 164 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));165 166 for (i=0; i<prdRoot->NumberOfNamedEntries+prdRoot->NumberOfIdEntries; i++)167 {168 prdType = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)prdRoot + (ULONG)prde->u2.OffsetToData);169 170 if(i<prdRoot->NumberOfNamedEntries) {171 //SvL: 30-10-'97, high bit is set, so clear to get real offset172 prde->u1.Name &= ~0x80000000;173 for(j=0;j<MAX_RES;j++) {174 resname = UnicodeToFixedAsciiString(*(WCHAR *)((ULONG)prdRoot + (ULONG)prde->u1.Name), (WCHAR *)((ULONG)prdRoot + (ULONG)prde->u1.Name + sizeof(WCHAR))); // first word = string length175 if(strcmp(resname, ResTypes[j]) == 0)176 break;177 }178 if(j == MAX_RES) {179 //SvL: 30-10-'97, not found = custom resource type (correct?)180 id = NTRT_RCDATA;181 }182 else id = j;183 }184 else id = prde->u1.Id;185 186 prdType = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)prdType ^ 0x80000000);187 188 if(id == NTRT_STRING) {189 //String tables can contain up to 16 individual resources!190 nCnt += prdType->NumberOfNamedEntries*16 + prdType->NumberOfIdEntries*16;191 }192 else {193 //Only icon groups are stored as resources in the LX file194 //Icon groups contain one or more icons195 if(id != NTRT_ICON)196 nCnt += prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;197 }198 prde++;199 }200 201 return nCnt;202 }203 147 /** Get Section Header for the given RVA - returns boolean according to the result 204 148 * -
trunk/src/kernel32/profile.cpp
r1663 r1811 1 /* $Id: profile.cpp,v 1.2 0 1999-11-09 14:19:46sandervl Exp $ */1 /* $Id: profile.cpp,v 1.21 1999-11-22 20:35:51 sandervl Exp $ */ 2 2 3 3 /* … … 715 715 else 716 716 { 717 ret = PROFILE_GetSection( PROFILE_OdinProfile, section, (char*)buffer, len, TRUE, FALSE );717 ret = PROFILE_GetSection( PROFILE_OdinProfile, section, (char*)buffer, len, TRUE, FALSE ); 718 718 } 719 719 LeaveCriticalSection( &PROFILE_CritSect ); … … 963 963 fclose( f ); 964 964 strncpy(PROFILE_OdinIniUsed,p,MAX_PATHNAME_LEN-1); 965 } else 965 } 966 else 966 967 { 967 968 HINSTANCE hInstance = LoadLibraryA("KERNEL32.DLL"); -
trunk/src/kernel32/profile.h
r1663 r1811 1 /* $Id: profile.h,v 1. 4 1999-11-09 14:19:46sandervl Exp $ */1 /* $Id: profile.h,v 1.5 1999-11-22 20:35:51 sandervl Exp $ */ 2 2 /* 3 3 * Profile header for initterm … … 24 24 LPCSTR def_val, LPSTR buffer, 25 25 UINT len); 26 27 int ODIN_EXTERN(PROFILE_SetOdinIniString)(LPCSTR section_name, LPCSTR key_name, 28 LPCSTR value); 29 26 30 #endif -
trunk/src/kernel32/virtual.cpp
r1687 r1811 1 /* $Id: virtual.cpp,v 1.2 2 1999-11-10 14:16:01sandervl Exp $ */1 /* $Id: virtual.cpp,v 1.23 1999-11-22 20:35:52 sandervl Exp $ */ 2 2 3 3 /* … … 501 501 ULONG offset = ((ULONG)lpvAddress & 0xFFF); 502 502 npages = (cbSize >> 12); 503 if(cbSize & 0xFFF + offset) { 503 504 if( (cbSize & 0xFFF) + offset > 0 ) { 505 npages++; 506 } 507 508 if( (cbSize & 0xFFF) + offset >= 4096 ) { 504 509 npages++; 505 510 } -
trunk/src/kernel32/windllbase.cpp
r1670 r1811 1 /* $Id: windllbase.cpp,v 1. 4 1999-11-09 19:22:32 sandervl Exp $ */1 /* $Id: windllbase.cpp,v 1.5 1999-11-22 20:35:52 sandervl Exp $ */ 2 2 3 3 /* … … 274 274 } 275 275 //****************************************************************************** 276 //Add renaming profile strings for ole32 & netapi32 to odin.ini if they aren't 277 //already there 278 //****************************************************************************** 279 void Win32DllBase::setDefaultRenaming() 280 { 281 char renameddll[CCHMAXPATH]; 282 283 if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "", renameddll, 284 sizeof(renameddll)-1) <= 1) 285 { 286 ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "OLE32", "OLE32OS2"); 287 ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "OLE32OS2", "OLE32"); 288 } 289 if(ODIN_PROFILE_GetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "", renameddll, 290 sizeof(renameddll)-1) <= 1) 291 { 292 ODIN_PROFILE_SetOdinIniString(DLLRENAMEWIN_SECTION, "NETAPI32", "WNETAP32"); 293 ODIN_PROFILE_SetOdinIniString(DLLRENAMEOS2_SECTION, "WNETAP32", "NETAPI32"); 294 } 295 } 296 //****************************************************************************** 276 297 //rename dll if necessary: 277 298 // Win32 to OS/2 : (i.e. OLE32 -> OLE32OS2) -
trunk/src/kernel32/winimagepeldr.cpp
r1720 r1811 1 /* $Id: winimagepeldr.cpp,v 1.1 3 1999-11-13 15:41:11sandervl Exp $ */1 /* $Id: winimagepeldr.cpp,v 1.14 1999-11-22 20:35:52 sandervl Exp $ */ 2 2 3 3 /* … … 45 45 #include <win\virtual.h> 46 46 #include "oslibdos.h" 47 #include "mmap.h" 47 48 48 49 char szErrorTitle[] = "Odin"; … … 74 75 imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0), 75 76 nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL), 76 fImgMapping(0)77 memmap(NULL), pFixups(NULL) 77 78 { 78 79 HFILE dllfile; … … 120 121 Win32PeLdrImage::~Win32PeLdrImage() 121 122 { 123 if(memmap) 124 delete memmap; 125 126 if(hFile) { 127 OSLibDosClose(hFile); 128 hFile = 0; 129 } 130 122 131 if(realBaseAddress) 123 132 DosFreeMem((PVOID)realBaseAddress); … … 128 137 if(ordexports) 129 138 free(ordexports); 130 131 //SvL: Only happens for images that aren't really loaded (RSRC_LOAD)132 if(fImgMapping) CloseHandle(fImgMapping);133 fImgMapping = 0;134 139 } 135 140 //****************************************************************************** … … 137 142 BOOL Win32PeLdrImage::init(ULONG reservedMem) 138 143 { 139 LPVOID win32file 140 ULONG filesize, ulRead ;144 LPVOID win32file = NULL; 145 ULONG filesize, ulRead, ulNewPos; 141 146 PIMAGE_SECTION_HEADER psh; 142 147 IMAGE_SECTION_HEADER sh; … … 144 149 int nSections, i; 145 150 char szFullPath[CCHMAXPATH] = ""; 146 147 fImgMapping = VIRTUAL_MapFileA(szFileName, &win32file); 148 149 if (fImgMapping == -1) { 150 strcpy(szErrorModule, OSLibStripPath(szFileName)); 151 IMAGE_DOS_HEADER doshdr; 152 ULONG signature; 153 154 hFile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 155 156 //default error: 157 strcpy(szErrorModule, OSLibStripPath(szFileName)); 158 if(hFile == NULL) { 151 159 goto failure; 152 160 } 153 154 if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) { 155 setFullPath(szFullPath); 156 } 157 158 if(GetPEFileHeader (win32file, &fh) == FALSE) { 161 //read dos header 162 if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) { 163 goto failure; 164 } 165 if(OSLibDosSetFilePtr(hFile, doshdr.e_lfanew, OSLIB_SETPTR_FILE_BEGIN) == -1) { 166 goto failure; 167 } 168 //read signature dword 169 if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) { 170 goto failure; 171 } 172 //read pe header 173 if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) { 174 goto failure; 175 } 176 //read optional header 177 if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) { 178 goto failure; 179 } 180 if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || signature != IMAGE_NT_SIGNATURE) { 159 181 fout << "Not a valid PE file (probably a 16 bits windows exe/dll)!" << endl; 160 182 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 161 183 goto failure; 184 } 185 186 if(oh.SizeOfImage == 0) {//just in case 187 oh.SizeOfImage = OSLibDosGetFileSize(hFile); 188 } 189 190 imageSize = oh.SizeOfImage; 191 //Allocate memory told hold the entire image 192 if(allocSections(reservedMem) == FALSE) { 193 fout << "Failed to allocate image memory, rc " << errorState << endl; 194 goto failure; 195 } 196 197 memmap = new Win32MemMap(this, realBaseAddress, imageSize); 198 if(memmap == NULL || !memmap->Init(0)) { 199 strcpy(szErrorModule, OSLibStripPath(szFileName)); 200 goto failure; 201 } 202 win32file = memmap->mapViewOfFile(0, 0, 2); 203 204 if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) { 205 setFullPath(szFullPath); 162 206 } 163 207 … … 183 227 } 184 228 185 GetPEOptionalHeader (win32file, &oh);186 229 fout << "PE file : " << szFileName << endl; 187 230 fout << "PE Optional header: " << endl; … … 200 243 fout << "FileAlignment : " << oh.FileAlignment << endl; 201 244 fout << "Subsystem : " << oh.Subsystem << endl; 245 fout << "Image Size : " << oh.SizeOfImage << endl; 246 fout << "Header Size : " << oh.SizeOfHeaders << endl; 247 248 //get header page 249 commitPage(realBaseAddress, FALSE); 202 250 203 251 nSections = NR_SECTIONS(win32file); … … 205 253 if(loadType == REAL_LOAD) 206 254 { 255 imageSize = 0; 207 256 if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL) { 208 257 fout << endl << "*************************PE SECTIONS START**************************" << endl; … … 215 264 if(strcmp(psh[i].Name, ".reloc") == 0) { 216 265 fout << ".reloc" << endl << endl; 217 addSection(SECTION_RELOC, (char *)win32file+psh[i].PointerToRawData,266 addSection(SECTION_RELOC, psh[i].PointerToRawData, 218 267 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 219 268 psh[i].Misc.VirtualSize); … … 222 271 if(strcmp(psh[i].Name, ".edata") == 0) { 223 272 fout << ".edata" << endl << endl; 224 addSection(SECTION_EXPORT, (char *)win32file+psh[i].PointerToRawData,273 addSection(SECTION_EXPORT, psh[i].PointerToRawData, 225 274 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 226 275 psh[i].Misc.VirtualSize); … … 229 278 if(strcmp(psh[i].Name, ".rsrc") == 0) { 230 279 fout << ".rsrc" << endl << endl; 231 addSection(SECTION_RESOURCE, (char *)win32file+psh[i].PointerToRawData,280 addSection(SECTION_RESOURCE, psh[i].PointerToRawData, 232 281 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 233 282 psh[i].Misc.VirtualSize); … … 243 292 fout << "TLS SizeOfZeroFill " << hex(tlsDir->SizeOfZeroFill) << endl; 244 293 fout << "TLS Characteristics " << hex(tlsDir->Characteristics) << endl; 245 addSection(SECTION_TLS, (char *)win32file+psh[i].PointerToRawData,294 addSection(SECTION_TLS, psh[i].PointerToRawData, 246 295 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 247 296 psh[i].Misc.VirtualSize); … … 252 301 if(strcmp(psh[i].Name, ".debug") == 0) { 253 302 fout << ".rdebug" << endl << endl; 254 addSection(SECTION_DEBUG, (char *)win32file+psh[i].PointerToRawData,303 addSection(SECTION_DEBUG, psh[i].PointerToRawData, 255 304 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 256 305 psh[i].Misc.VirtualSize); … … 265 314 type |= SECTION_CODE; 266 315 } 267 addSection(type, (char *)win32file+psh[i].PointerToRawData,316 addSection(type, psh[i].PointerToRawData, 268 317 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 269 318 psh[i].Misc.VirtualSize); … … 278 327 { 279 328 fout << "Code Section" << endl << endl; 280 addSection(SECTION_CODE, (char *)win32file+psh[i].PointerToRawData,329 addSection(SECTION_CODE, psh[i].PointerToRawData, 281 330 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 282 331 psh[i].Misc.VirtualSize); … … 285 334 if(!(psh[i].Characteristics & IMAGE_SCN_MEM_WRITE)) { //read only data section 286 335 fout << "Read Only Data Section" << endl << endl; 287 addSection(SECTION_READONLYDATA, (char *)win32file+psh[i].PointerToRawData,336 addSection(SECTION_READONLYDATA, psh[i].PointerToRawData, 288 337 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 289 338 psh[i].Misc.VirtualSize); … … 292 341 if(psh[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) { 293 342 fout << "Uninitialized Data Section" << endl << endl; 294 addSection(SECTION_UNINITDATA, (char *)win32file+psh[i].PointerToRawData,343 addSection(SECTION_UNINITDATA, psh[i].PointerToRawData, 295 344 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 296 345 psh[i].Misc.VirtualSize); … … 299 348 if(psh[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) { 300 349 fout << "Initialized Data Section" << endl << endl; 301 addSection(SECTION_INITDATA, (char *)win32file+psh[i].PointerToRawData,350 addSection(SECTION_INITDATA, psh[i].PointerToRawData, 302 351 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 303 352 psh[i].Misc.VirtualSize); … … 306 355 if(psh[i].Characteristics & (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ)) { 307 356 fout << "Other Section, stored as read/write uninit data" << endl << endl; 308 addSection(SECTION_UNINITDATA, (char *)win32file+psh[i].PointerToRawData,357 addSection(SECTION_UNINITDATA, psh[i].PointerToRawData, 309 358 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 310 359 psh[i].Misc.VirtualSize); … … 319 368 if(GetSectionHdrByName (win32file, &sh, ".rsrc")) 320 369 { 321 addSection(SECTION_RESOURCE, (char *)win32file+sh.PointerToRawData,370 addSection(SECTION_RESOURCE, sh.PointerToRawData, 322 371 sh.SizeOfRawData, sh.VirtualAddress + oh.ImageBase, 323 372 sh.Misc.VirtualSize); … … 335 384 imageSize = imageVirtEnd - oh.ImageBase; 336 385 } 337 if( allocSections(reservedMem) == FALSE) {338 fout << "Failed to allocate image memory, rc " << errorState << endl;339 goto failure;340 } 386 if(imageSize < oh.SizeOfImage) { 387 imageSize = oh.SizeOfImage; 388 } 389 341 390 fout << "OS/2 base address " << realBaseAddress << endl; 342 if(storeSections((char *)win32file) == FALSE) {343 fout << "Failed to store sections, rc " << errorState << endl;344 goto failure;345 }346 391 if(oh.AddressOfEntryPoint) { 347 392 entryPoint = realBaseAddress + oh.AddressOfEntryPoint; … … 350 395 fout << "EntryPoint == NULL" << endl; 351 396 entryPoint = NULL; 397 } 398 399 //set memory protection flags 400 if(setMemFlags() == FALSE) { 401 fout << "Failed to set memory protection" << endl; 402 goto failure; 352 403 } 353 404 … … 361 412 goto failure; 362 413 } 363 setTLSAddress((char *) (sect->realvirtaddr + (tlsDir->StartAddressOfRawData - sect->virtaddr)));414 setTLSAddress((char *)sect->realvirtaddr); 364 415 setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData); 365 416 setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill); … … 381 432 382 433 if(realBaseAddress != oh.ImageBase) { 383 if(setFixups((PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC)) == FALSE) { 384 fout << "Failed to set fixups" << endl; 385 goto failure; 386 } 434 pFixups = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC); 435 commitPage((ULONG)pFixups, FALSE); 387 436 } 388 437 if(fh.Characteristics & IMAGE_FILE_DLL) { … … 394 443 } 395 444 445 for (i=0; i<nSections; i++) { 446 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION); 447 } 448 396 449 //SvL: Use pointer to image header as module handle now. Some apps needs this 397 450 hinstance = (HINSTANCE)realBaseAddress; … … 413 466 } 414 467 415 //set final memory protection flags (storeSections sets them to read/write)416 if(setMemFlags() == FALSE) {417 fout << "Failed to set memory protection" << endl;418 goto failure;419 }420 CloseHandle(fImgMapping);421 fImgMapping = 0;422 423 468 return(TRUE); 424 469 failure: 425 if(fImgMapping) CloseHandle(fImgMapping); 426 fImgMapping = 0; 470 if(memmap) { 471 delete memmap; 472 memmap = NULL; 473 } 474 if(hFile) { 475 OSLibDosClose(hFile); 476 hFile = 0; 477 } 427 478 errorState = ERROR_INTERNAL; 428 479 return FALSE; 429 480 } 430 481 //****************************************************************************** 431 //****************************************************************************** 432 void Win32PeLdrImage::addSection(ULONG type, char *rawdata, ULONG rawsize, ULONG virtaddress, ULONG virtsize) 482 //commits image page(s) when an access violation exception is dispatched 483 //virtAddress = address of exception (rounded down to page boundary) 484 //****************************************************************************** 485 BOOL Win32PeLdrImage::commitPage(ULONG virtAddress, BOOL fWriteAccess, int fPageCmd) 486 { 487 Section *section; 488 ULONG offset, size, sectionsize, protflags, fileoffset, range, attr; 489 ULONG ulNewPos, ulRead; 490 APIRET rc; 491 492 rc = DosQueryMem((PVOID)virtAddress, &range, &attr); 493 if(rc) { 494 dprintf(("Win32PeLdrImage::commitPage: DosQueryMem returned %d", rc)); 495 return FALSE; 496 } 497 if(attr & PAG_COMMIT) { 498 dprintf(("Win32PeLdrImage::commitPage: Memory at 0x%x already committed!", virtAddress)); 499 return FALSE; 500 } 501 502 section = findSectionByOS2Addr(virtAddress); 503 if(section == NULL) { 504 size = 4096; 505 sectionsize = 4096; 506 protflags = PAG_READ|PAG_WRITE; //readonly? 507 section = findPreviousSectionByOS2Addr(virtAddress); 508 if(section == NULL) {//access to header 509 fileoffset = virtAddress - realBaseAddress; 510 } 511 else { 512 offset = virtAddress - (section->realvirtaddr + section->virtualsize); 513 fileoffset = section->rawoffset + section->rawsize + offset; 514 } 515 } 516 else { 517 protflags = section->pageflags; 518 offset = virtAddress - section->realvirtaddr; 519 sectionsize = section->virtualsize - offset; 520 if(offset > section->rawsize) { 521 //unintialized data (set to 0) 522 size = 0; 523 fileoffset = -1; 524 } 525 else { 526 size = section->rawsize-offset; 527 fileoffset = section->rawoffset + offset; 528 } 529 if(fWriteAccess & !(section->pageflags & PAG_WRITE)) { 530 dprintf(("Win32PeLdrImage::commitPage: No write access to 0%x!", virtAddress)); 531 return FALSE; 532 } 533 } 534 if(fPageCmd == SINGLE_PAGE) { 535 size = min(size, PAGE_SIZE); 536 sectionsize = min(sectionsize, PAGE_SIZE); 537 } 538 else 539 if(fPageCmd == SECTION_PAGES) { 540 size = min(size, DEFAULT_NR_PAGES*PAGE_SIZE); 541 sectionsize = min(sectionsize, DEFAULT_NR_PAGES*PAGE_SIZE); 542 } 543 size = min(size, range); 544 sectionsize = min(sectionsize, range); 545 546 if(fileoffset != -1) { 547 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT); 548 if(rc) { 549 dprintf(("Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 550 return FALSE; 551 } 552 553 if(DosSetFilePtr(hFile, fileoffset, FILE_BEGIN, &ulNewPos) == -1) { 554 dprintf(("Win32PeLdrImage::commitPage: DosSetFilePtr failed for 0x%x!", fileoffset)); 555 return FALSE; 556 } 557 if(DosRead(hFile, (PVOID)virtAddress, size, &ulRead)) { 558 dprintf(("Win32PeLdrImage::commitPage: DosRead failed for 0x%x!", virtAddress)); 559 return FALSE; 560 } 561 if(ulRead != size) { 562 dprintf(("Win32PeLdrImage::commitPage: DosRead failed to read %x (%x) bytes for 0x%x!", size, ulRead, virtAddress)); 563 return FALSE; 564 } 565 if(realBaseAddress != oh.ImageBase) { 566 setFixups(virtAddress, sectionsize); 567 } 568 569 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags); 570 if(rc) { 571 dprintf(("Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 572 return FALSE; 573 } 574 } 575 else { 576 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT); 577 if(rc) { 578 dprintf(("Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 579 return FALSE; 580 } 581 if(realBaseAddress != oh.ImageBase) { 582 setFixups(virtAddress, sectionsize); 583 } 584 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags); 585 if(rc) { 586 dprintf(("Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 587 return FALSE; 588 } 589 } 590 return TRUE; 591 } 592 //****************************************************************************** 593 //****************************************************************************** 594 void Win32PeLdrImage::addSection(ULONG type, ULONG rawoffset, ULONG rawsize, ULONG virtaddress, ULONG virtsize) 433 595 { 434 596 virtsize = max(rawsize, virtsize); 435 597 598 section[nrsections].rawoffset = rawoffset; 436 599 section[nrsections].type = type; 437 section[nrsections].rawdata = rawdata;438 600 section[nrsections].rawsize = rawsize; 439 601 section[nrsections].virtaddr = virtaddress; … … 458 620 459 621 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 460 fout << "No fixups, might not run!" << endl;461 622 return allocFixedMem(reservedMem); 462 623 } 463 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | flAllocMem);624 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | flAllocMem); 464 625 if(rc) { 626 dprintf(("Win32PeLdrImage::allocSections, DosAllocMem returned %d", rc)); 465 627 errorState = rc; 466 628 return(FALSE); … … 490 652 } 491 653 return NULL; 654 } 655 //****************************************************************************** 656 //****************************************************************************** 657 Section *Win32PeLdrImage::findSectionByOS2Addr(ULONG addr) 658 { 659 for(int i=0;i<nrsections;i++) { 660 if(section[i].realvirtaddr <= addr && section[i].realvirtaddr + section[i].virtualsize > addr) { 661 return §ion[i]; 662 } 663 } 664 return NULL; 665 } 666 //****************************************************************************** 667 //****************************************************************************** 668 Section *Win32PeLdrImage::findPreviousSectionByOS2Addr(ULONG addr) 669 { 670 ULONG lowestAddr = 0xffffffff; 671 ULONG index = -1; 672 673 for(int i=0;i<nrsections;i++) { 674 if(section[i].realvirtaddr > addr) { 675 if(section[i].realvirtaddr < lowestAddr) { 676 lowestAddr = section[i].realvirtaddr; 677 index = i; 678 } 679 } 680 } 681 if(index == -1) 682 return NULL; 683 684 return §ion[index]; 492 685 } 493 686 //****************************************************************************** … … 503 696 ULONG diff, i, baseAddress; 504 697 APIRET rc; 698 BOOL allocFlags = flAllocMem; 505 699 506 700 realBaseAddress = 0; … … 521 715 } 522 716 717 if(oh.ImageBase < 512*1024*124) { 718 allocFlags = 0; 719 } 523 720 while(TRUE) { 524 rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | flAllocMem);721 rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | allocFlags); 525 722 if(rc) break; 526 723 … … 536 733 diff = oh.ImageBase - address; 537 734 if(diff) { 538 rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | flAllocMem);735 rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | allocFlags); 539 736 if(rc) break; 540 737 } 541 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | flAllocMem);738 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | allocFlags); 542 739 if(rc) break; 543 740 … … 561 758 //****************************************************************************** 562 759 //****************************************************************************** 563 BOOL Win32PeLdrImage::s toreSections(char *win32file)760 BOOL Win32PeLdrImage::setMemFlags() 564 761 { 565 762 int i; 566 APIRET rc;567 ULONG pagFlags = PAG_COMMIT;568 ULONG headersize;569 763 WINIMAGE_LOOKUP *imgLookup; 570 764 571 //Commit memory for image header572 headersize = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) +573 sizeof(IMAGE_SECTION_HEADER) * fh.NumberOfSections;574 575 if(headersize + sizeof(WINIMAGE_LOOKUP) < PAGE_SIZE) {576 headersize = PAGE_SIZE;577 }578 else {//ooops, just in case this doesn't work579 fout << "ERROR: storeSections: header too big!!!!!! Fatal error" << endl;580 return FALSE;581 }582 583 rc = DosSetMem((PVOID)realBaseAddress, headersize, pagFlags | PAG_WRITE | PAG_READ);584 if(rc) {585 fout << "DosSetMem failed for Image header! " << rc << endl;586 return FALSE;587 }588 // Store the NT header at the load addr589 memcpy((char *)realBaseAddress, win32file, sizeof(IMAGE_DOS_HEADER));590 memcpy((char *)PE_HEADER(realBaseAddress), PE_HEADER(win32file), sizeof(IMAGE_NT_HEADERS));591 memcpy(PE_SECTIONS(realBaseAddress), PE_SECTIONS(win32file),592 sizeof(IMAGE_SECTION_HEADER) * fh.NumberOfSections );593 594 765 imgLookup = WINIMAGE_LOOKUPADDR(realBaseAddress); 595 imgLookup->image = this; 596 #ifdef DEBUG 597 imgLookup->magic = MAGIC_WINIMAGE; 598 #endif 766 imgLookup->magic1 = MAGIC_WINIMAGE; 767 imgLookup->image = this; 768 imgLookup->magic2 = MAGIC_WINIMAGE; 599 769 600 770 // Process all the image sections … … 602 772 section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase); 603 773 } 774 604 775 for(i=0;i<nrsections;i++) { 605 pagFlags = PAG_COMMIT;606 switch(section[i].type){776 switch(section[i].type) 777 { 607 778 case SECTION_CODE: 608 779 case (SECTION_CODE | SECTION_IMPORT): 609 case SECTION_INITDATA: 610 case SECTION_UNINITDATA: 611 case SECTION_IMPORT: 612 case SECTION_READONLYDATA: 613 case SECTION_RESOURCE: 614 case SECTION_TLS: 615 pagFlags |= PAG_WRITE | PAG_READ; 616 break; 617 case SECTION_EXPORT: 618 case SECTION_DEBUG: 619 case SECTION_RELOC: 620 pagFlags = 0; //don't commit 621 break; 622 } 623 if(pagFlags == 0) continue; //debug or export section 624 625 rc = DosSetMem((PVOID)section[i].realvirtaddr, section[i].virtualsize, pagFlags); 626 if(rc) { 627 errorState = rc; 628 return(FALSE); 629 } 630 if(section[i].type != SECTION_UNINITDATA) { 631 assert(section[i].rawdata); 632 memcpy((char *)section[i].realvirtaddr, section[i].rawdata, section[i].rawsize); 633 } 634 } 635 return(TRUE); 636 } 637 //****************************************************************************** 638 //****************************************************************************** 639 BOOL Win32PeLdrImage::setMemFlags() 640 { 641 int i; 642 APIRET rc; 643 ULONG pagFlags = 0; 644 645 for(i=0;i<nrsections;i++) { 646 pagFlags = 0; 647 switch(section[i].type) { 648 case SECTION_CODE: 649 case (SECTION_CODE | SECTION_IMPORT): 650 pagFlags |= PAG_EXECUTE | PAG_READ; 780 section[i].pageflags = PAG_EXECUTE | PAG_READ; 651 781 break; 652 782 case SECTION_INITDATA: 653 783 case SECTION_UNINITDATA: 654 784 case SECTION_IMPORT: //TODO: read only? 655 pagFlags |= PAG_WRITE | PAG_READ;785 section[i].pageflags = PAG_WRITE | PAG_READ; 656 786 break; 657 787 case SECTION_READONLYDATA: 658 788 case SECTION_RESOURCE: 659 789 case SECTION_TLS: 660 pagFlags |= PAG_READ; 790 default: 791 section[i].pageflags = PAG_READ; 661 792 break; 662 default:663 continue;664 793 } 665 rc = DosSetMem((PVOID)section[i].realvirtaddr, section[i].virtualsize, pagFlags); 666 if(rc) { 667 errorState = rc; 668 return(FALSE); 669 } 794 } 795 return(TRUE); 796 } 797 //****************************************************************************** 798 //****************************************************************************** 799 BOOL Win32PeLdrImage::setFixups(ULONG virtAddress, ULONG size) 800 { 801 int i, j; 802 char *page; 803 ULONG count, newpage; 804 Section *section; 805 PIMAGE_BASE_RELOCATION prel = pFixups; 806 807 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 808 return(TRUE); 809 } 810 811 virtAddress -= realBaseAddress; 812 813 if(prel) { 814 j = 1; 815 while(prel->VirtualAddress && prel->VirtualAddress < virtAddress) { 816 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock); 817 } 818 while(prel->VirtualAddress && prel->VirtualAddress < virtAddress + size) { 819 page = (char *)((char *)prel + (ULONG)prel->VirtualAddress); 820 count = (prel->SizeOfBlock - 8)/2; 821 j++; 822 for(i=0;i<count;i++) { 823 int type = prel->TypeOffset[i] >> 12; 824 int offset = prel->TypeOffset[i] & 0xFFF; 825 int fixupsize = 0; 826 827 switch(type) 828 { 829 case IMAGE_REL_BASED_HIGHLOW: 830 fixupsize = 4; 831 break; 832 case IMAGE_REL_BASED_HIGH: 833 case IMAGE_REL_BASED_LOW: 834 fixupsize = 2; 835 break; 836 } 837 //If the fixup crosses the final page boundary, 838 //then we have to load another page 839 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size) 840 { 841 newpage = realBaseAddress + prel->VirtualAddress + offset + fixupsize; 842 newpage &= ~0xFFF; 843 844 section = findSectionByOS2Addr(newpage); 845 if(section == NULL) { 846 //should never happen 847 dprintf(("::setFixups -> section == NULL!!")); 848 return FALSE; 849 } 850 //SvL: Read page from disk 851 commitPage(newpage, TRUE, SINGLE_PAGE); 852 853 //SvL: Enable write access 854 DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ|PAG_WRITE); 855 } 856 857 switch(type) 858 { 859 case IMAGE_REL_BASED_ABSOLUTE: 860 break; //skip 861 case IMAGE_REL_BASED_HIGHLOW: 862 AddOff32Fixup(prel->VirtualAddress + offset); 863 break; 864 case IMAGE_REL_BASED_HIGH: 865 AddOff16Fixup(prel->VirtualAddress + offset, TRUE); 866 break; 867 case IMAGE_REL_BASED_LOW: 868 AddOff16Fixup(prel->VirtualAddress + offset, FALSE); 869 break; 870 case IMAGE_REL_BASED_HIGHADJ: 871 case IMAGE_REL_BASED_MIPS_JMPADDR: 872 default: 873 break; 874 } 875 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size) 876 { 877 //SvL: Restore original page protection flags 878 DosSetMem((PVOID)newpage, PAGE_SIZE, section->pageflags); 879 } 880 881 } 882 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock); 883 }//while 884 } 885 else { 886 dprintf(("Win32PeLdrImage::setFixups, no fixups at %x, %d", virtAddress, size)); 887 return(FALSE); 670 888 } 671 889 return(TRUE); … … 680 898 681 899 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 682 return(TRUE);900 return(TRUE); 683 901 } 684 902 … … 701 919 case IMAGE_REL_BASED_HIGHLOW: 702 920 //// fout << "address " << offset << " type " << type << endl; 703 AddOff32Fixup(oh.ImageBase + 704 prel->VirtualAddress + offset); 921 AddOff32Fixup(prel->VirtualAddress + offset); 705 922 break; 706 923 case IMAGE_REL_BASED_HIGH: 707 AddOff16Fixup( oh.ImageBase +prel->VirtualAddress + offset, TRUE);924 AddOff16Fixup(prel->VirtualAddress + offset, TRUE); 708 925 break; 709 926 case IMAGE_REL_BASED_LOW: 710 AddOff16Fixup( oh.ImageBase +prel->VirtualAddress + offset, FALSE);927 AddOff16Fixup(prel->VirtualAddress + offset, FALSE); 711 928 break; 712 929 case IMAGE_REL_BASED_HIGHADJ: … … 734 951 ULONG *fixup; 735 952 736 fixup = (ULONG *)(fixupaddr - oh.ImageBase+ realBaseAddress);953 fixup = (ULONG *)(fixupaddr + realBaseAddress); 737 954 orgaddr = *fixup; 738 955 *fixup = realBaseAddress + (*fixup - oh.ImageBase); … … 745 962 USHORT *fixup; 746 963 747 fixup = (USHORT *)(fixupaddr - oh.ImageBase+ realBaseAddress);964 fixup = (USHORT *)(fixupaddr + realBaseAddress); 748 965 orgaddr = *fixup; 749 966 if(fHighFixup) { … … 761 978 ULONG apiaddr; 762 979 763 import = (ULONG *) (impaddr - oh.ImageBase + realBaseAddress);980 import = (ULONG *)impaddr; 764 981 apiaddr = WinDll->getApi(ordinal); 765 982 if(apiaddr == 0) 766 983 { 767 dprintf(("KERNEL32:Win32PeLdrImage - %s.%u not found\n",768 WinDll->getName(),769 ordinal));984 dprintf(("KERNEL32:Win32PeLdrImage - %s.%u not found\n", 985 WinDll->getName(), 986 ordinal)); 770 987 771 988 fout << "--->>> NOT FOUND!" << endl; … … 781 998 ULONG apiaddr; 782 999 783 import = (ULONG *) (impaddr - oh.ImageBase + realBaseAddress);1000 import = (ULONG *)impaddr; 784 1001 apiaddr = WinDll->getApi(impname); 785 1002 if(apiaddr == 0) 786 1003 { 787 dprintf(("KERNEL32:Win32PeLdrImage - %s.%s not found\n",788 WinDll->getName(),789 impname));1004 dprintf(("KERNEL32:Win32PeLdrImage - %s.%s not found\n", 1005 WinDll->getName(), 1006 impname)); 790 1007 791 1008 fout << "--->>> NOT FOUND!" << endl; … … 810 1027 811 1028 fout << "Exported Functions: " << endl; 812 ptrOrd = (USHORT *)((ULONG)ped->AddressOfNameOrdinals - 813 (ULONG)sh.VirtualAddress + 814 (ULONG)sh.PointerToRawData + (ULONG)win32file); 815 ptrNames = (ULONG *)((ULONG)ped->AddressOfNames - 816 (ULONG)sh.VirtualAddress + 817 (ULONG)sh.PointerToRawData + (ULONG)win32file); 818 ptrAddress = (ULONG *)((ULONG)ped->AddressOfFunctions - 819 (ULONG)sh.VirtualAddress + 820 (ULONG)sh.PointerToRawData + (ULONG)win32file); 1029 ptrOrd = (USHORT *)((ULONG)ped->AddressOfNameOrdinals + 1030 (ULONG)win32file); 1031 ptrNames = (ULONG *)((ULONG)ped->AddressOfNames + 1032 (ULONG)win32file); 1033 ptrAddress = (ULONG *)((ULONG)ped->AddressOfFunctions + 1034 (ULONG)win32file); 821 1035 nrOrdExports = ped->NumberOfFunctions; 822 1036 nrNameExports = ped->NumberOfNames; … … 826 1040 for(i=0;i<ped->NumberOfNames;i++) { 827 1041 ord = ptrOrd[i] + ped->Base; 828 name = (char *)((ULONG)ptrNames[i] - (ULONG)sh.VirtualAddress + 829 (ULONG)sh.PointerToRawData + (ULONG)win32file); 1042 name = (char *)((ULONG)ptrNames[i] + (ULONG)win32file); 830 1043 RVAExport = ptrAddress[ptrOrd[i]]; 831 1044 #ifdef FORWARDERS … … 833 1046 #endif 834 1047 //points to code (virtual address relative to oh.ImageBase 835 fout << "address 0x"; 836 fout.setf(ios::hex, ios::basefield); 1048 AddNameExport(oh.ImageBase + RVAExport, name, ord); 1049 fout << "address 0x"; 1050 fout.setf(ios::hex, ios::basefield); 837 1051 fout << RVAExport; 838 fout.setf(ios::dec, ios::basefield); 839 fout << " " << name << "@" << ord << endl; 840 AddNameExport(oh.ImageBase + RVAExport, name, ord); 1052 fout.setf(ios::dec, ios::basefield); 1053 fout << " " << name << "@" << ord << endl; 841 1054 #ifdef FORWARDERS 842 1055 843 1056 } 844 1057 else {//forwarder 845 char *forward = (char *)((ULONG)RVAExport - 846 (ULONG)sh.VirtualAddress + 847 (ULONG)sh.PointerToRawData + 848 (ULONG)win32file); 1058 char *forward = (char *)((ULONG)RVAExport + (ULONG)win32file); 849 1059 fout << RVAExport << " " << name << " @" << ord << " is forwarder to " << (int)forward << endl; 850 1060 } … … 868 1078 } 869 1079 else {//forwarder or empty 870 char *forward = (char *)((ULONG)RVAExport - 871 (ULONG)sh.VirtualAddress + 872 (ULONG)sh.PointerToRawData + 873 (ULONG)win32file); 1080 char *forward = (char *)((ULONG)RVAExport + (ULONG)win32file); 874 1081 fout << "ord " << ord << " at 0x"; 875 1082 fout.setf(ios::hex, ios::basefield); 876 1083 fout << RVAExport << " is forwarder to 0x" << (int)forward << endl; 877 1084 fout.setf(ios::dec, ios::basefield); 878 1085 } 879 1086 #endif … … 939 1146 IMAGE_SECTION_HEADER shExtra = {0}; 940 1147 PIMAGE_OPTIONAL_HEADER pOH; 941 int i,j ;1148 int i,j, nrPages; 942 1149 BOOL fBorland = 0; 943 1150 int cModules; … … 949 1156 int Size; 950 1157 Win32PeLdrDll *WinDll; 1158 Section *section; 951 1159 952 1160 /* "algorithm:" … … 975 1183 //test RVA inside ID-Section 976 1184 if (pID[i].Name >= shID.VirtualAddress && pID[i].Name < shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData)) { 977 pszTmp = (char*)(pID[i].Name - shID.VirtualAddress + shID.PointerToRawData+ (ULONG)win32file);1185 pszTmp = (char*)(pID[i].Name + (ULONG)win32file); 978 1186 } 979 1187 else { … … 983 1191 return FALSE; 984 1192 } 985 pszTmp = (char*)(pID[i].Name - shExtra.VirtualAddress + shExtra.PointerToRawData+ (ULONG)win32file);1193 pszTmp = (char*)(pID[i].Name + (ULONG)win32file); 986 1194 } 987 1195 Size += strlen(pszTmp) + 1; … … 997 1205 //test RVA inside ID-Section 998 1206 if (pID[i].Name >= shID.VirtualAddress && pID[i].Name < shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData)) { 999 pszTmp = (char*)(pID[i].Name - shID.VirtualAddress + shID.PointerToRawData+ (ULONG)win32file);1207 pszTmp = (char*)(pID[i].Name + (ULONG)win32file); 1000 1208 } 1001 1209 else { … … 1009 1217 } 1010 1218 } 1011 pszTmp = (char*)(pID[i].Name - shExtra.VirtualAddress + shExtra.PointerToRawData+ (ULONG)win32file);1219 pszTmp = (char*)(pID[i].Name + (ULONG)win32file); 1012 1220 } 1013 1221 … … 1041 1249 } 1042 1250 //light borland-style test 1043 if (pID[i].u.OriginalFirstThunk == 0 || fBorland) 1044 pulImport = (ULONG*)pID[i].FirstThunk; 1251 if (pID[i].u.OriginalFirstThunk == 0 || fBorland) { 1252 pulImport = (ULONG*)pID[i].FirstThunk; 1253 } 1045 1254 else pulImport = (ULONG*)pID[i].u.OriginalFirstThunk; 1046 1255 … … 1131 1340 WinDll->AddRef(); 1132 1341 1133 pulImport = (PULONG)((ULONG)pulImport - shExtra.VirtualAddress + (ULONG)win32file + shExtra.PointerToRawData);1342 pulImport = (PULONG)((ULONG)pulImport + (ULONG)win32file); 1134 1343 j = 0; 1135 ulCurFixup = (ULONG)pID[i].FirstThunk + pOH->ImageBase; 1344 ulCurFixup = (ULONG)pID[i].FirstThunk + (ULONG)win32file; 1345 1346 section = findSectionByOS2Addr(ulCurFixup); 1347 if(section == NULL) { 1348 fout.setf(ios::hex, ios::basefield); 1349 fout << "Unable to find section for " << ulCurFixup << endl; 1350 return FALSE; 1351 } 1352 //SvL: Read page from disk 1353 commitPage(ulCurFixup & ~0xfff, FALSE, SINGLE_PAGE); 1354 //SvL: Enable write access 1355 DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE, PAG_READ|PAG_WRITE); 1356 nrPages = 1; 1357 1136 1358 while (pulImport[j] != 0) { 1137 1359 if (pulImport[j] & IMAGE_ORDINAL_FLAG) { //ordinal … … 1151 1373 } 1152 1374 //KSO - Aug 6 1998 1:15am:this eases comparing... 1153 char *pszFunctionName = (char*)(pulImport[j] + (ULONG)win32file + shExtra.PointerToRawData - shExtra.VirtualAddress +2);1375 char *pszFunctionName = (char*)(pulImport[j] + (ULONG)win32file + 2); 1154 1376 fout.setf(ios::hex, ios::basefield); 1155 1377 fout << "0x" << ulCurFixup << " Imported function " << pszFunctionName << endl; … … 1157 1379 StoreImportByName(WinDll, pszFunctionName, ulCurFixup); 1158 1380 } 1159 1381 ulCurFixup += sizeof(IMAGE_THUNK_DATA); 1160 1382 j++; 1383 if((ulCurFixup & 0xfff) == 0) { 1384 commitPage(ulCurFixup & ~0xfff, TRUE, SINGLE_PAGE); 1385 DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE, PAG_READ|PAG_WRITE); 1386 nrPages++; 1387 } 1161 1388 } 1389 //SvL: And restore original protection flags 1390 ulCurFixup = (ULONG)pID[i].FirstThunk + pOH->ImageBase; 1391 DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE*nrPages, section->pageflags); 1392 1162 1393 fout << "**********************************************************************" << endl; 1163 1394 fout << "************** End Import Module " << pszCurModule << endl; … … 1184 1415 do { 1185 1416 r = WinMessageBox(HWND_DESKTOP, NULLHANDLE, "The application has called a non-existing api\n", 1186 "Internal Error", 0, MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION | MB_MOVEABLE);1417 "Internal Odin Error", 0, MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION | MB_MOVEABLE); 1187 1418 } 1188 1419 while(r == MBID_RETRY); //giggle -
trunk/src/kernel32/wprocess.cpp
r1708 r1811 1 /* $Id: wprocess.cpp,v 1. 49 1999-11-11 19:10:09sandervl Exp $ */1 /* $Id: wprocess.cpp,v 1.50 1999-11-22 20:35:52 sandervl Exp $ */ 2 2 3 3 /* … … 265 265 SetOS2ExceptionChain(-1); 266 266 267 Win32DllExitList(0); 268 269 //Note: Needs to be done after Win32DllExitList (destruction of exe + dll objects) 267 270 //Flush and delete all open memory mapped files 268 271 Win32MemMap::deleteAll(); 269 270 Win32DllExitList(0);271 272 272 273 //Restore original OS/2 TIB selector
Note:
See TracChangeset
for help on using the changeset viewer.