source: trunk/src/kernel32/winimage.cpp@ 461

Last change on this file since 461 was 461, checked in by phaller, 26 years ago

Fix: fixes and updates for ODINCRT support

File size: 43.7 KB
Line 
1/* $Id: winimage.cpp,v 1.6 1999-08-09 22:10:09 phaller Exp $ */
2
3/*
4 * Win32 PE Image class
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Knut St. Osmundsen
8 *
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14#define INCL_DOSFILEMGR /* File Manager values */
15#define INCL_DOSMODULEMGR
16#define INCL_DOSERRORS /* DOS Error values */
17#define INCL_DOSPROCESS /* DOS Process values */
18#define INCL_DOSMISC /* DOS Miscellanous values */
19#define INCL_WIN
20#define INCL_BASE
21#include <os2wrap.h> //Odin32 OS/2 api wrappers
22
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26
27#include <odincrt.h>
28
29#include <iostream.h>
30#include <fstream.h>
31#include <assert.h>
32#include "misc.h"
33#include "nameid.h"
34#include "win32type.h"
35#include "winimage.h"
36#include "windll.h"
37#include "winexe.h"
38#include "pefile.h"
39#include "unicode.h"
40#include "winres.h"
41
42char szErrorTitle[] = "Win32 for OS/2";
43char szMemErrorMsg[] = "Memory allocation failure";
44char szFileErrorMsg[] = "File IO error";
45char szPEErrorMsg[] = "Not a valid win32 exe. (perhaps 16 bits windows)";
46char szCPUErrorMsg[] = "Executable doesn't run on x86 machines";
47char szExeErrorMsg[] = "File isn't an executable";
48char szInteralErrorMsg[]= "Internal Error";
49
50#ifndef max
51#define max(a, b) ((a>b) ? a : b)
52#endif
53
54BOOL foutInit = FALSE;
55ofstream fout;
56
57ULONG MissingApi();
58char *hex(ULONG num);
59
60//******************************************************************************
61//******************************************************************************
62Win32Image::Win32Image(char *szFileName) :
63 errorState(NO_ERROR), entryPoint(0), nrsections(0), imageSize(0),
64 imageVirtBase(-1), baseAddress(0), realBaseAddress(0), imageVirtEnd(0),
65 nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
66 szFileName(NULL), NameTable(NULL), Win32Table(NULL), fullpath(NULL),
67 tlsAddress(0), tlsIndexAddr(0), tlsInitSize(0), tlsTotalSize(0), tlsCallBackAddr(0), tlsIndex(-1),
68 pResSection(NULL), pResDir(NULL), winres(NULL), VersionId(-1)
69{
70 //native win32 exe/dll, converted dll or native OS/2 dll
71 //if it's either of the latter two, this flag will be reset when
72 //RegisterDll is called
73 fNativePEImage = TRUE;
74
75 if(foutInit == FALSE) {
76 fout.open("pe.log", ios::out | ios::trunc);
77 foutInit = TRUE;
78 }
79 hinstance = (HINSTANCE)this;
80 this->szFileName = szFileName;
81#ifdef DEBUG
82 magic = MAGIC_WINIMAGE;
83#endif
84}
85//******************************************************************************
86//******************************************************************************
87Win32Image::Win32Image(HINSTANCE hinstance, int NameTableId, int Win32TableId) :
88 errorState(NO_ERROR), entryPoint(0), nrsections(0), imageSize(0),
89 imageVirtBase(-1), baseAddress(0), realBaseAddress(0), imageVirtEnd(0),
90 nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
91 szFileName(NULL), NameTable(NULL), Win32Table(NULL), fullpath(NULL),
92 tlsAddress(0), tlsIndexAddr(0), tlsInitSize(0), tlsTotalSize(0), tlsCallBackAddr(0), tlsIndex(-1),
93 pResSection(NULL), pResDir(NULL), winres(NULL)
94{
95#ifdef DEBUG
96 magic = MAGIC_WINIMAGE;
97#endif
98 OS2ImageInit(hinstance, NameTableId, Win32TableId);
99}
100//******************************************************************************
101//******************************************************************************
102void Win32Image::OS2ImageInit(HINSTANCE hinstance, int NameTableId, int Win32TableId)
103{
104 APIRET rc;
105
106 this->hinstance = hinstance;
107 this->NameTableId = NameTableId;
108 this->Win32TableId = Win32TableId;
109
110 //converted win32 exe/dll or OS/2 system dll
111 fNativePEImage = FALSE;
112
113 if(NameTableId != NO_NAMETABLE) {
114 //Load name table resource
115 rc = DosGetResource(hinstance, RT_RCDATA, NameTableId, (PPVOID)&NameTable);
116 if(rc) {
117 eprintf(("Can't find converted name resource (rc %d)!!\n", rc));
118 return;
119 }
120 }
121 else this->NameTableId = 0;
122
123 //Load win32 id table resource
124 if((Win32TableId & 0xFFFFFF) != NO_LOOKUPTABLE) {
125 rc = DosGetResource(hinstance, RT_RCDATA, Win32TableId, (PPVOID)&Win32Table);
126 if(rc) {
127 eprintf(("Can't find win32 id resource (rc %d)!!\n", rc));
128 return;
129 }
130 }
131 else this->Win32TableId = 0;
132}
133//******************************************************************************
134//******************************************************************************
135Win32Image::~Win32Image()
136{
137 Win32Resource *res;
138
139 if(NameTable)
140 DosFreeResource((PVOID)NameTable);
141
142 if(Win32Table)
143 DosFreeResource((PVOID)Win32Table);
144
145 while(winres)
146 {
147 res = winres->next;
148 ODIN_delete(winres);
149 winres = res;
150 }
151 if(realBaseAddress)
152 DosFreeMem((PVOID)realBaseAddress);
153
154 if(nameexports)
155 free(nameexports);
156
157 if(ordexports)
158 free(ordexports);
159 if(fullpath)
160 free(fullpath);
161}
162//******************************************************************************
163//******************************************************************************
164BOOL Win32Image::init()
165{
166 HFILE win32handle;
167 ULONG ulAction = 0; /* Action taken by DosOpen */
168 ULONG ulLocal = 0; /* File pointer position after DosSetFilePtr */
169 APIRET rc = NO_ERROR; /* Return code */
170 char szErrorMsg[64];
171 LPVOID win32file = NULL;
172 ULONG filesize, ulRead;
173 PIMAGE_SECTION_HEADER psh;
174 int nSections, i;
175
176 rc = DosOpen(szFileName, /* File path name */
177 &win32handle, /* File handle */
178 &ulAction, /* Action taken */
179 0L, /* File primary allocation */
180 0L, /* File attribute */
181 OPEN_ACTION_FAIL_IF_NEW |
182 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */
183 OPEN_FLAGS_NOINHERIT |
184 OPEN_SHARE_DENYNONE |
185 OPEN_ACCESS_READONLY, /* Open mode of the file */
186 0L); /* No extended attribute */
187
188 if (rc != NO_ERROR) {
189 sprintf(szErrorMsg, "Unable to open %32s\n", szFileName);
190 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
191 errorState = ERROR_INTERNAL;
192 return(FALSE);
193 }
194
195 /* Move the file pointer back to the beginning of the file */
196 DosSetFilePtr(win32handle, 0L, FILE_BEGIN, &ulLocal);
197 DosSetFilePtr(win32handle, 0L, FILE_END, &filesize);
198 DosSetFilePtr(win32handle, 0L, FILE_BEGIN, &ulLocal);
199
200 win32file = malloc(filesize);
201 if(win32file == NULL) {
202 fout << "Error allocating memory" << endl;
203 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szMemErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
204 DosClose(win32handle); /* Close the file */
205 errorState = ERROR_INTERNAL;
206 return(FALSE);
207 }
208 rc = DosRead(win32handle, win32file, filesize, &ulRead);
209 if(rc != NO_ERROR) {
210 fout << "DosRead returned " << rc << endl;
211 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szFileErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
212 DosClose(win32handle); /* Close the file */
213 errorState = ERROR_INTERNAL;
214 return(FALSE);
215 }
216
217 if(GetPEFileHeader (win32file, &fh) == FALSE) {
218 fout << "Not a valid PE file (probably a 16 bits windows exe/dll)!" << endl;
219 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
220 DosClose(win32handle); /* Close the file */
221 errorState = ERROR_INTERNAL;
222 return(FALSE);
223 }
224
225 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
226 fout << "Not a valid PE file!" << endl;
227 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
228 DosClose(win32handle); /* Close the file */
229 errorState = ERROR_INTERNAL;
230 return(FALSE);
231 }
232 if(fh.Machine != IMAGE_FILE_MACHINE_I386) {
233 fout << "You need a REAL CPU to run this code" << endl;
234 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szCPUErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
235 DosClose(win32handle); /* Close the file */
236 errorState = ERROR_INTERNAL;
237 return(FALSE);
238 }
239 //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)?
240 if(fh.Characteristics & IMAGE_FILE_SYSTEM) {
241 fout << "Can't convert system files" << endl;
242 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szExeErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
243 DosClose(win32handle); /* Close the file */
244 errorState = ERROR_INTERNAL;
245 return(FALSE);
246 }
247
248 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
249 fout << "No fixups, might not run!" << endl;
250 }
251
252 GetPEOptionalHeader (win32file, &oh);
253 fout << "PE file : " << szFileName << endl;
254 fout << "PE Optional header: " << endl;
255 fout << "Preferred address : " << oh.ImageBase << endl;
256 fout << "Base Of Code : " << oh.BaseOfCode << endl;
257 fout << "CodeSize : " << oh.SizeOfCode << endl;
258 fout << "Base Of Data : " << oh.BaseOfData << endl;
259 fout << "Data Size (uninit): " << oh.SizeOfUninitializedData << endl;
260 fout << "Data Size (init) : " << oh.SizeOfInitializedData << endl;
261 fout << "Entry Point : " << oh.AddressOfEntryPoint << endl;
262 fout << "Section Alignment : " << oh.SectionAlignment << endl;
263 fout << "Stack Reserve size: " << oh.SizeOfStackReserve << endl;
264 fout << "Stack Commit size : " << oh.SizeOfStackCommit << endl;
265 fout << "SizeOfHeapReserve : " << oh.SizeOfHeapReserve << endl;
266 fout << "SizeOfHeapCommit : " << oh.SizeOfHeapCommit << endl;
267 fout << "FileAlignment : " << oh.FileAlignment << endl;
268
269 nSections = NR_SECTIONS(win32file);
270
271 if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL) {
272 fout << endl << "*************************PE SECTIONS START**************************" << endl;
273 for (i=0; i<nSections; i++) {
274 fout << "Raw data size: " << psh[i].SizeOfRawData << endl;
275 fout << "Virtual Address: " << psh[i].VirtualAddress << endl;
276 fout << "Virtual Size: " << psh[i].Misc.VirtualSize << endl;
277 fout << "Pointer to raw data: " << psh[i].PointerToRawData << endl;
278 fout.setf(ios::hex, ios::basefield);
279 fout << "Section flags: " << psh[i].Characteristics << endl << endl;
280 fout.setf(ios::dec, ios::basefield);
281 if(strcmp(psh[i].Name, ".reloc") == 0) {
282 fout << ".reloc" << endl << endl;
283 addSection(SECTION_RELOC, (char *)win32file+psh[i].PointerToRawData,
284 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
285 psh[i].Misc.VirtualSize);
286 continue;
287 }
288 if(strcmp(psh[i].Name, ".edata") == 0) {
289 fout << ".edata" << endl << endl;
290 addSection(SECTION_EXPORT, (char *)win32file+psh[i].PointerToRawData,
291 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
292 psh[i].Misc.VirtualSize);
293 continue;
294 }
295 if(strcmp(psh[i].Name, ".rsrc") == 0) {
296 fout << ".rsrc" << endl << endl;
297 addSection(SECTION_RESOURCE, (char *)win32file+psh[i].PointerToRawData,
298 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
299 psh[i].Misc.VirtualSize);
300 continue;
301 }
302 if(strcmp(psh[i].Name, ".debug") == 0) {
303 fout << ".rdebug" << endl << endl;
304 addSection(SECTION_DEBUG, (char *)win32file+psh[i].PointerToRawData,
305 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
306 psh[i].Misc.VirtualSize);
307 continue;
308 }
309 if(IsImportSection(win32file, &psh[i]))
310 {
311 int type = SECTION_IMPORT;
312 fout << "Import Data Section" << endl << endl;
313 if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE) {
314 fout << "Also Code Section" << endl << endl;
315 type |= SECTION_CODE;
316 }
317 addSection(type, (char *)win32file+psh[i].PointerToRawData,
318 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
319 psh[i].Misc.VirtualSize);
320 continue;
321 }
322
323 //KSO Sun 1998-08-09: Borland does not alway set the CODE flag for its "CODE" section
324 if( psh[i].Characteristics & IMAGE_SCN_CNT_CODE ||
325 (psh[i].Characteristics & IMAGE_SCN_MEM_EXECUTE &&
326 !(psh[i].Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA))) //KSO: make sure its not marked as a datasection
327 )
328 {
329 fout << "Code Section" << endl << endl;
330 addSection(SECTION_CODE, (char *)win32file+psh[i].PointerToRawData,
331 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
332 psh[i].Misc.VirtualSize);
333 continue;
334 }
335 if(!(psh[i].Characteristics & IMAGE_SCN_MEM_WRITE)) { //read only data section
336 fout << "Read Only Data Section" << endl << endl;
337 addSection(SECTION_READONLYDATA, (char *)win32file+psh[i].PointerToRawData,
338 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
339 psh[i].Misc.VirtualSize);
340 continue;
341 }
342 if(psh[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
343 fout << "Uninitialized Data Section" << endl << endl;
344 addSection(SECTION_UNINITDATA, (char *)win32file+psh[i].PointerToRawData,
345 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
346 psh[i].Misc.VirtualSize);
347 continue;
348 }
349 if(psh[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) {
350 fout << "Initialized Data Section" << endl << endl;
351 addSection(SECTION_INITDATA, (char *)win32file+psh[i].PointerToRawData,
352 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
353 psh[i].Misc.VirtualSize);
354 continue;
355 }
356 if(psh[i].Characteristics & (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ)) {
357 fout << "Other Section, stored as read/write uninit data" << endl << endl;
358 addSection(SECTION_UNINITDATA, (char *)win32file+psh[i].PointerToRawData,
359 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
360 psh[i].Misc.VirtualSize);
361 continue;
362 }
363 fout << "Unknown section" << endl;
364 errorState = ERROR_INTERNAL;
365 return(FALSE);
366 }
367 }
368 fout << "*************************PE SECTIONS END **************************" << endl;
369 imageSize += (imageVirtBase - oh.ImageBase);
370 fout << "Total size of Image " << imageSize << endl;
371 fout << "imageVirtBase " << imageVirtBase << endl;
372 fout << "imageVirtEnd " << imageVirtEnd << endl;
373
374 if(imageSize != imageVirtEnd - oh.ImageBase) {
375 fout << "imageSize != imageVirtEnd - oh.ImageBase!" << endl;
376 imageSize = imageVirtEnd - oh.ImageBase;
377 }
378 if(allocSections() == FALSE) {
379 fout << "Failed to allocate image memory, rc " << errorState << endl;
380 return(FALSE);
381 }
382 fout << "OS/2 base address " << baseAddress << endl;
383 if(storeSections() == FALSE) {
384 fout << "Failed to store sections, rc " << errorState << endl;
385 return(FALSE);
386 }
387 entryPoint = baseAddress + oh.AddressOfEntryPoint;
388
389 if(setFixups((PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC)) == FALSE) {
390 fout << "Failed to set fixups" << endl;
391 return(FALSE);
392 }
393 if(processImports((char *)win32file) == FALSE) {
394 fout << "Failed to process imports!" << endl;
395 return(FALSE);
396 }
397
398 if(fh.Characteristics & IMAGE_FILE_DLL) {
399 if(processExports((char *)win32file) == FALSE) {
400 fout << "Failed to process exported apis" << endl;
401 return(FALSE);
402 }
403 }
404 IMAGE_SECTION_HEADER sh;
405 if(GetSectionHdrByName (win32file, &sh, ".rsrc")) {
406 //get offset in resource object of directory entry
407 pResDir = (PIMAGE_RESOURCE_DIRECTORY)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_RESOURCE);
408 }
409 //set final memory protection flags (storeSections sets them to read/write)
410 if(setMemFlags() == FALSE) {
411 fout << "Failed to set memory protection" << endl;
412 return(FALSE);
413 }
414
415 //Now it's safe to free win32file
416 free(win32file);
417 DosClose(win32handle); /* Close the file */
418 return(TRUE);
419}
420//******************************************************************************
421//******************************************************************************
422void Win32Image::addSection(ULONG type, char *rawdata, ULONG rawsize, ULONG virtaddress, ULONG virtsize)
423{
424 virtsize = max(rawsize, virtsize);
425
426 section[nrsections].type = type;
427 section[nrsections].rawdata = rawdata;
428 section[nrsections].rawsize = rawsize;
429 section[nrsections].virtaddr = virtaddress;
430
431 if(type == SECTION_RESOURCE) {
432 pResSection = &section[nrsections];
433 }
434 virtsize = ((virtsize - 1) & ~0xFFF) + PAGE_SIZE;
435 imageSize += virtsize;
436 section[nrsections].virtualsize = virtsize;
437
438 if(virtaddress < imageVirtBase)
439 imageVirtBase = virtaddress;
440 if(virtaddress + virtsize > imageVirtEnd)
441 imageVirtEnd = virtaddress + virtsize;
442
443 nrsections++;
444}
445//******************************************************************************
446//******************************************************************************
447BOOL Win32Image::allocSections()
448{
449 APIRET rc;
450
451 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
452 fout << "No fixups, might not run!" << endl;
453 return allocFixedMem();
454 }
455 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ);
456 if(rc) {
457 errorState = rc;
458 return(FALSE);
459 }
460 realBaseAddress = baseAddress;
461 return(TRUE);
462}
463//******************************************************************************
464#define FALLOC_SIZE (1024*1024)
465//******************************************************************************
466BOOL Win32Image::allocFixedMem()
467{
468 ULONG address = 0;
469 ULONG lastaddress = 0;
470 ULONG firstaddress = 0;
471 ULONG diff, i;
472 APIRET rc;
473
474 baseAddress = realBaseAddress = 0;
475
476 while(TRUE) {
477 rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ);
478 if(rc) break;
479
480 if(firstaddress == 0)
481 firstaddress = address;
482
483 fout << "DosAllocMem returned " << address << endl;
484 if(address + FALLOC_SIZE >= oh.ImageBase) {
485 if(address > oh.ImageBase) {//we've passed it!
486 DosFreeMem((PVOID)address);
487 return(FALSE);
488 }
489 //found the right address
490 DosFreeMem((PVOID)address);
491 //align at 64 kb boundary
492 realBaseAddress = oh.ImageBase & 0xFFFF0000;
493 diff = realBaseAddress - address;
494 if(diff) {
495 rc = DosAllocMem((PPVOID)&address, diff, PAG_READ);
496 if(rc) break;
497 }
498 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ);
499 if(rc) break;
500
501 if(baseAddress != realBaseAddress) {
502 fout << "baseAddress != realBaseAddress!!" << endl;
503 break;
504 }
505 if(diff) DosFreeMem((PVOID)address);
506
507 address = realBaseAddress;
508 realBaseAddress = baseAddress;
509 baseAddress = oh.ImageBase;
510 break;
511 }
512 lastaddress = address;
513 }
514 while(firstaddress <= lastaddress) {
515 DosFreeMem((PVOID)firstaddress);
516 firstaddress += FALLOC_SIZE;
517 }
518 if(baseAddress == 0) //Let me guess.. MS Office app?
519 return(FALSE);
520 return(TRUE);
521}
522//******************************************************************************
523//******************************************************************************
524BOOL Win32Image::storeSections()
525{
526 int i;
527 APIRET rc;
528 ULONG pagFlags = PAG_COMMIT;
529
530 for(i=0;i<nrsections;i++) {
531 section[i].realvirtaddr = baseAddress + (section[i].virtaddr - oh.ImageBase);
532 }
533 for(i=0;i<nrsections;i++) {
534 pagFlags = PAG_COMMIT;
535 switch(section[i].type) {
536 case SECTION_CODE:
537 case (SECTION_CODE | SECTION_IMPORT):
538 case SECTION_INITDATA:
539 case SECTION_UNINITDATA:
540 case SECTION_IMPORT:
541 case SECTION_READONLYDATA:
542 case SECTION_RESOURCE:
543 pagFlags |= PAG_WRITE | PAG_READ;
544 break;
545 case SECTION_EXPORT:
546 case SECTION_DEBUG:
547 case SECTION_RELOC:
548 pagFlags = 0; //don't commit
549 break;
550 }
551 if(pagFlags == 0) continue; //debug or export section
552
553 rc = DosSetMem((PVOID)section[i].realvirtaddr, section[i].virtualsize, pagFlags);
554 if(rc) {
555 errorState = rc;
556 return(FALSE);
557 }
558 if(section[i].type != SECTION_UNINITDATA) {
559 assert(section[i].rawdata);
560 memcpy((char *)section[i].realvirtaddr, section[i].rawdata, section[i].rawsize);
561 }
562 }
563 return(TRUE);
564}
565//******************************************************************************
566//******************************************************************************
567BOOL Win32Image::setMemFlags()
568{
569 int i;
570 APIRET rc;
571 ULONG pagFlags = 0;
572
573 for(i=0;i<nrsections;i++) {
574 pagFlags = 0;
575 switch(section[i].type) {
576 case SECTION_CODE:
577 case (SECTION_CODE | SECTION_IMPORT):
578 pagFlags |= PAG_EXECUTE | PAG_READ;
579 break;
580 case SECTION_INITDATA:
581 case SECTION_UNINITDATA:
582 case SECTION_IMPORT: //TODO: read only?
583 pagFlags |= PAG_WRITE | PAG_READ;
584 break;
585 case SECTION_READONLYDATA:
586 case SECTION_RESOURCE:
587 pagFlags |= PAG_READ;
588 break;
589 default:
590 continue;
591 }
592 rc = DosSetMem((PVOID)section[i].realvirtaddr, section[i].virtualsize, pagFlags);
593 if(rc) {
594 errorState = rc;
595 return(FALSE);
596 }
597 }
598 return(TRUE);
599}
600//******************************************************************************
601//******************************************************************************
602BOOL Win32Image::setFixups(PIMAGE_BASE_RELOCATION prel)
603{
604 int i, j;
605 char *page;
606 ULONG count;
607
608 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
609 return(TRUE);
610 }
611
612 if(prel) {
613 j = 1;
614 while(prel->VirtualAddress) {
615 page = (char *)((char *)prel + (ULONG)prel->VirtualAddress);
616 count = (prel->SizeOfBlock - 8)/2;
617 fout.setf(ios::hex, ios::basefield);
618 fout << "Page " << j << " Address " << (ULONG)prel->VirtualAddress << " Count " << count << endl;
619 fout.setf(ios::dec, ios::basefield);
620 j++;
621 for(i=0;i<count;i++) {
622 int type = prel->TypeOffset[i] >> 12;
623 int offset = prel->TypeOffset[i] & 0xFFF;
624 switch(type) {
625 case IMAGE_REL_BASED_ABSOLUTE:
626//// fout << "absolute fixup; unused" << endl;
627 break; //skip
628 case IMAGE_REL_BASED_HIGHLOW:
629//// fout << "address " << offset << " type " << type << endl;
630 AddOff32Fixup(oh.ImageBase +
631 prel->VirtualAddress + offset);
632 break;
633 case IMAGE_REL_BASED_HIGH:
634 AddOff16Fixup(oh.ImageBase + prel->VirtualAddress + offset, TRUE);
635 break;
636 case IMAGE_REL_BASED_LOW:
637 AddOff16Fixup(oh.ImageBase + prel->VirtualAddress + offset, FALSE);
638 break;
639 case IMAGE_REL_BASED_HIGHADJ:
640 case IMAGE_REL_BASED_MIPS_JMPADDR:
641 default:
642 fout << "Unknown/unsupported fixup type!" << endl;
643 break;
644 }
645 }
646 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
647 }//while
648 }
649 else {
650 fout << "No internal fixups found!\n" << endl;
651 errorState = ERROR_INTERNAL;
652 return(FALSE);
653 }
654 return(TRUE);
655}
656//******************************************************************************
657//******************************************************************************
658void Win32Image::AddOff32Fixup(ULONG fixupaddr)
659{
660 ULONG orgaddr;
661 ULONG *fixup;
662
663 fixup = (ULONG *)(fixupaddr - oh.ImageBase + baseAddress);
664 orgaddr = *fixup;
665 *fixup = baseAddress + (*fixup - oh.ImageBase);
666}
667//******************************************************************************
668//******************************************************************************
669void Win32Image::AddOff16Fixup(ULONG fixupaddr, BOOL fHighFixup)
670{
671 ULONG orgaddr;
672 USHORT *fixup;
673
674 fixup = (USHORT *)(fixupaddr - oh.ImageBase + baseAddress);
675 orgaddr = *fixup;
676 if(fHighFixup) {
677 *fixup += (USHORT)((baseAddress - oh.ImageBase) >> 16);
678 }
679 else {
680 *fixup += (USHORT)((baseAddress - oh.ImageBase) & 0xFFFF);
681 }
682}
683//******************************************************************************
684//******************************************************************************
685void Win32Image::StoreImportByOrd(Win32Dll *WinDll, ULONG ordinal, ULONG impaddr)
686{
687 ULONG *import;
688 ULONG apiaddr;
689
690 import = (ULONG *)(impaddr - oh.ImageBase + baseAddress);
691 apiaddr = WinDll->getApi(ordinal);
692 if(apiaddr == 0) {
693 fout << "--->>> NOT FOUND!";
694 *import = (ULONG)MissingApi;
695 }
696 else *import = apiaddr;
697}
698//******************************************************************************
699//******************************************************************************
700void Win32Image::StoreImportByName(Win32Dll *WinDll, char *impname, ULONG impaddr)
701{
702 ULONG *import;
703 ULONG apiaddr;
704
705 import = (ULONG *)(impaddr - oh.ImageBase + baseAddress);
706 apiaddr = WinDll->getApi(impname);
707 if(apiaddr == 0) {
708 fout << "--->>> NOT FOUND!";
709 *import = (ULONG)MissingApi;
710 }
711 else *import = apiaddr;
712}
713//******************************************************************************
714//******************************************************************************
715BOOL Win32Image::processExports(char *win32file)
716{
717 IMAGE_SECTION_HEADER sh;
718 PIMAGE_EXPORT_DIRECTORY ped;
719 ULONG *ptrNames, *ptrAddress;
720 USHORT *ptrOrd;
721 int i;
722
723 /* get section header and pointer to data directory for .edata section */
724 if((ped = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryOffset
725 (win32file, IMAGE_DIRECTORY_ENTRY_EXPORT)) != NULL &&
726 GetSectionHdrByImageDir(win32file, IMAGE_DIRECTORY_ENTRY_EXPORT, &sh) ) {
727
728 fout << "Exported Functions: " << endl;
729 ptrOrd = (USHORT *)((ULONG)ped->AddressOfNameOrdinals -
730 (ULONG)sh.VirtualAddress +
731 (ULONG)sh.PointerToRawData + (ULONG)win32file);
732 ptrNames = (ULONG *)((ULONG)ped->AddressOfNames -
733 (ULONG)sh.VirtualAddress +
734 (ULONG)sh.PointerToRawData + (ULONG)win32file);
735 ptrAddress = (ULONG *)((ULONG)ped->AddressOfFunctions -
736 (ULONG)sh.VirtualAddress +
737 (ULONG)sh.PointerToRawData + (ULONG)win32file);
738 nrOrdExports = ped->NumberOfFunctions;
739 nrNameExports = ped->NumberOfNames;
740
741 int ord, RVAExport;
742 char *name;
743 for(i=0;i<ped->NumberOfNames;i++) {
744 ord = ptrOrd[i] + ped->Base;
745 name = (char *)((ULONG)ptrNames[i] - (ULONG)sh.VirtualAddress +
746 (ULONG)sh.PointerToRawData + (ULONG)win32file);
747 RVAExport = ptrAddress[ptrOrd[i]];
748#ifdef FORWARDERS
749 if(RVAExport < sh.VirtualAddress || RVAExport > sh.VirtualAddress + sh.SizeOfRawData) {
750#endif
751 //points to code (virtual address relative to oh.ImageBase
752 fout << "address 0x";
753 fout.setf(ios::hex, ios::basefield);
754 fout << RVAExport;
755 fout.setf(ios::dec, ios::basefield);
756 fout << " " << name << "@" << ord << endl;
757 AddNameExport(oh.ImageBase + RVAExport, name, ord);
758#ifdef FORWARDERS
759
760 }
761 else {//forwarder
762 char *forward = (char *)((ULONG)RVAExport -
763 (ULONG)sh.VirtualAddress +
764 (ULONG)sh.PointerToRawData +
765 (ULONG)win32file);
766 fout << RVAExport << " " << name << " @" << ord << " is forwarder to " << (int)forward << endl;
767 }
768#endif
769 }
770 for(i=0;i<max(ped->NumberOfNames,ped->NumberOfFunctions);i++) {
771 ord = ped->Base + i; //Correct??
772 RVAExport = ptrAddress[i];
773#ifdef FORWARDERS
774 if(RVAExport < sh.VirtualAddress || RVAExport > sh.VirtualAddress + sh.SizeOfRawData) {
775#endif
776 if(RVAExport) {
777 //points to code (virtual address relative to oh.ImageBase
778 fout << "ord " << ord << " at 0x";
779 fout.setf(ios::hex, ios::basefield);
780 fout << RVAExport << endl;
781 fout.setf(ios::dec, ios::basefield);
782 AddOrdExport(oh.ImageBase + RVAExport, ord);
783 }
784#ifdef FORWARDERS
785 }
786 else {//forwarder or empty
787 char *forward = (char *)((ULONG)RVAExport -
788 (ULONG)sh.VirtualAddress +
789 (ULONG)sh.PointerToRawData +
790 (ULONG)win32file);
791 fout << "ord " << ord << " at 0x";
792 fout.setf(ios::hex, ios::basefield);
793 fout << RVAExport << " is forwarder to 0x" << (int)forward << endl;
794 fout.setf(ios::dec, ios::basefield);
795 }
796#endif
797 }
798 }
799 return(TRUE);
800}
801//******************************************************************************
802//******************************************************************************
803void Win32Image::AddNameExport(ULONG virtaddr, char *apiname, ULONG ordinal)
804{
805 ULONG nsize;
806
807 if(nameexports == NULL) {
808 nameExportSize= 4096;
809 nameexports = (NameExport *)malloc(nameExportSize);
810 curnameexport = nameexports;
811 }
812 nsize = (ULONG)curnameexport - (ULONG)nameexports;
813 if(nsize + sizeof(NameExport) + strlen(apiname) > nameExportSize) {
814 nameExportSize += 4096;
815 char *tmp = (char *)nameexports;
816 nameexports = (NameExport *)malloc(nameExportSize);
817 memcpy(nameexports, tmp, nsize);
818 curnameexport = (NameExport *)((ULONG)nameexports + nsize);
819 free(tmp);
820 }
821 curnameexport->virtaddr = baseAddress + (virtaddr - oh.ImageBase);
822 curnameexport->ordinal = ordinal;
823 *(ULONG *)curnameexport->name = 0;
824 strcpy(curnameexport->name, apiname);
825
826 curnameexport->nlength = strlen(apiname) + 1;
827 if(curnameexport->nlength < sizeof(curnameexport->name))
828 curnameexport->nlength = sizeof(curnameexport->name);
829 curnameexport = (NameExport *)((ULONG)curnameexport->name + curnameexport->nlength);
830}
831//******************************************************************************
832//******************************************************************************
833void Win32Image::AddOrdExport(ULONG virtaddr, ULONG ordinal)
834{
835 if(ordexports == NULL) {
836 ordexports = (OrdExport *)malloc(nrOrdExports * sizeof(OrdExport));
837 curordexport = ordexports;
838 }
839 curordexport->virtaddr = baseAddress + (virtaddr - oh.ImageBase);
840 curordexport->ordinal = ordinal;
841 curordexport++;
842}
843//******************************************************************************
844/** All initial processing of imports is done here
845 * Should now detect most Borland styled files including the GifCon32.exe and
846 * loader32 from SoftIce. (Stupid Borland!!!)
847 *
848 * knut [Jul 22 1998 2:44am]
849 **/
850//******************************************************************************
851BOOL Win32Image::processImports(char *win32file)
852{
853 PIMAGE_IMPORT_DESCRIPTOR pID;
854 IMAGE_SECTION_HEADER shID;
855 IMAGE_SECTION_HEADER shExtra = {0};
856 PIMAGE_OPTIONAL_HEADER pOH;
857 int i,j;
858 BOOL fBorland = 0;
859 int cModules;
860 char *pszModules;
861 char *pszCurModule;
862 char *pszTmp;
863 ULONG *pulImport;
864 ULONG ulCurFixup;
865 int Size;
866 Win32Dll *WinDll;
867
868/* "algorithm:"
869 * 1) get module names and store them
870 * a) check dwRVAModuleName is within .idata seg - if not find section
871 * 2) iterate thru functions of each module
872 * a) check OriginalFirstThunk is not 0 and that it points to a RVA.
873 * b) if not a) borland-styled PE-file - ARG!!!
874 * check FirstThunk
875 * c) check OriginalFirstThunk/FirstThunk ok RVAs and find right section
876 * d) store ordinal/name import
877 * 3) finished
878 */
879
880 /* 1) get module names */
881 pID = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_IMPORT);
882 if (pID == NULL)
883 return TRUE;
884 if (!GetSectionHdrByImageDir(win32file, IMAGE_DIRECTORY_ENTRY_IMPORT, &shID))
885 return TRUE;
886
887 //calc size of module list
888 i = Size = cModules = 0;
889 while (pID[i].Name != 0)
890 {
891 //test RVA inside ID-Section
892 if (pID[i].Name >= shID.VirtualAddress && pID[i].Name < shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData)) {
893 pszTmp = (char*)(pID[i].Name- shID.VirtualAddress + shID.PointerToRawData + (ULONG)win32file);
894 }
895 else {
896 //is the "Extra"-section already found or do we have to find it?
897 if (pID[i].Name < shExtra.VirtualAddress || pID[i].Name >= shExtra.VirtualAddress + max(shExtra.Misc.VirtualSize, shExtra.SizeOfRawData)) {
898 if (!GetSectionHdrByRVA(win32file, &shExtra, pID[i].Name))
899 return FALSE;
900 }
901 pszTmp = (char*)(pID[i].Name- shExtra.VirtualAddress + shExtra.PointerToRawData + (ULONG)win32file);
902 }
903 Size += strlen(pszTmp) + 1;
904 i++;
905 cModules++;
906 }
907
908 pszModules = (char*)malloc(Size);
909 assert(pszModules != NULL);
910 j = 0;
911 for (i = 0; i < cModules; i++)
912 {
913 //test RVA inside ID-Section
914 if (pID[i].Name >= shID.VirtualAddress && pID[i].Name < shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData)) {
915 pszTmp = (char*)(pID[i].Name- shID.VirtualAddress + shID.PointerToRawData + (ULONG)win32file);
916 }
917 else {
918 fBorland = TRUE;
919 //is the "Extra"-section already found or do we have to find it?
920 if (pID[i].Name < shExtra.VirtualAddress || pID[i].Name >= shExtra.VirtualAddress + max(shExtra.Misc.VirtualSize, shExtra.SizeOfRawData))
921 {
922 if (GetSectionHdrByRVA(win32file, &shExtra, pID[i].Name)) {
923 free(pszModules);
924 return FALSE;
925 }
926 }
927 pszTmp = (char*)(pID[i].Name- shExtra.VirtualAddress + shExtra.PointerToRawData + (ULONG)win32file);
928 }
929
930 strcpy(pszModules+j, pszTmp);
931 j += strlen(pszTmp) + 1;
932 }
933 fout << endl;
934 if (fBorland)
935 fout << "Borland-styled PE-File." << endl;
936 //Store modules
937 fout << cModules << " imported Modules: " << endl;
938
939 /* 2) functions */
940 pszCurModule = pszModules;
941 pOH = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF(win32file);
942 for (i = 0; i < cModules; i++)
943 {
944 fout << "Module " << pszCurModule << endl;
945 // a) check that OriginalFirstThunk not is 0 and look for Borland-styled PE
946 if (i == 0)
947 {
948 //heavy borland-style test - assume array of thunks is within that style does not change
949 if((ULONG)pID[i].u.OriginalFirstThunk == 0 ||
950 (ULONG)pID[i].u.OriginalFirstThunk < shID.VirtualAddress ||
951 (ULONG)pID[i].u.OriginalFirstThunk >= shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData) ||
952 (ULONG)pID[i].u.OriginalFirstThunk >= pOH->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress &&
953 (ULONG)pID[i].u.OriginalFirstThunk < sizeof(*pID)*cModules + pOH->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
954 {
955 fBorland = TRUE;
956 }
957 }
958 //light borland-style test
959 if (pID[i].u.OriginalFirstThunk == 0 || fBorland)
960 pulImport = (ULONG*)pID[i].FirstThunk;
961 else pulImport = (ULONG*)pID[i].u.OriginalFirstThunk;
962
963 // b) check if RVA ok
964 if (!(pulImport > 0 && (ULONG)pulImport < pOH->SizeOfImage)) {
965 fout << "Invalid RVA " << hex((ULONG)pulImport) << endl;
966 break;
967 }
968 // check section
969 if ((ULONG)pulImport < shExtra.VirtualAddress || (ULONG)pulImport >= shExtra.VirtualAddress + max(shExtra.Misc.VirtualSize, shExtra.SizeOfRawData))
970 {
971 if (!GetSectionHdrByRVA(win32file, &shExtra, (ULONG)pulImport))
972 {
973 fout << "warning: could not find section for Thunk RVA " << hex((ULONG)pulImport) << endl;
974 break;
975 }
976 }
977
978 //SvL: Load dll if needed
979 fout << "**********************************************************************" << endl;
980 fout << "************** Import Module " << pszCurModule << endl;
981 fout << "**********************************************************************" << endl;
982 WinDll = Win32Dll::findModule(pszCurModule);
983 if(WinDll == NULL)
984 { //not found, so load it
985 ODIN_FS_BEGIN
986 WinDll = new Win32Dll(pszCurModule);
987 ODIN_FS_END
988
989 if(WinDll == NULL) {
990 fout << "WinDll: Error allocating memory" << endl;
991 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szMemErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
992 errorState = ERROR_INTERNAL;
993 return(FALSE);
994 }
995 fout << "**********************************************************************" << endl;
996 fout << "********************** Loading Module *********************" << endl;
997 fout << "**********************************************************************" << endl;
998 if(WinDll->init() == FALSE) {
999 fout << "Internal WinDll error " << WinDll->getError() << endl;
1000 return(FALSE);
1001 }
1002 if(WinDll->attachProcess() == FALSE) {
1003 fout << "attachProcess failed!" << endl;
1004 errorState = ERROR_INTERNAL;
1005 return(FALSE);
1006 }
1007 fout << "**********************************************************************" << endl;
1008 fout << "********************** Finished Loading Module *********************" << endl;
1009 fout << "**********************************************************************" << endl;
1010 }
1011 else fout << "Already found " << pszCurModule << endl;
1012
1013 WinDll->AddRef();
1014
1015 pulImport = (PULONG)((ULONG)pulImport - shExtra.VirtualAddress + (ULONG)win32file + shExtra.PointerToRawData);
1016 j = 0;
1017 ulCurFixup = (ULONG)pID[i].FirstThunk + pOH->ImageBase;
1018 while (pulImport[j] != 0) {
1019 if (pulImport[j] & IMAGE_ORDINAL_FLAG) { //ordinal
1020 fout.setf(ios::hex, ios::basefield);
1021 fout << "0x" << ulCurFixup << " Imported function " << pszCurModule << "@" << (pulImport[j] & ~IMAGE_ORDINAL_FLAG) << endl;
1022 fout.setf(ios::dec, ios::basefield);
1023 StoreImportByOrd(WinDll, pulImport[j] & ~IMAGE_ORDINAL_FLAG, ulCurFixup);
1024 }
1025 else { //name
1026 //check
1027 if (pulImport[j] < shExtra.VirtualAddress || pulImport[j] >= shExtra.VirtualAddress + max(shExtra.Misc.VirtualSize, shExtra.SizeOfRawData)) {
1028 if (!GetSectionHdrByRVA(win32file, &shExtra, pulImport[j]))
1029 {
1030 fout << "warning: could not find section for Import Name RVA " << hex(pulImport[j]) << endl;
1031 break;
1032 }
1033 }
1034 //KSO - Aug 6 1998 1:15am:this eases comparing...
1035 char *pszFunctionName = (char*)(pulImport[j] + (ULONG)win32file + shExtra.PointerToRawData - shExtra.VirtualAddress + 2);
1036 fout.setf(ios::hex, ios::basefield);
1037 fout << "0x" << ulCurFixup << " Imported function " << pszFunctionName << endl;
1038 fout.setf(ios::dec, ios::basefield);
1039 StoreImportByName(WinDll, pszFunctionName, ulCurFixup);
1040 }
1041 ulCurFixup += sizeof(IMAGE_THUNK_DATA);
1042 j++;
1043 }
1044 fout << "**********************************************************************" << endl;
1045 fout << "************** End Import Module " << pszCurModule << endl;
1046 fout << "**********************************************************************" << endl;
1047
1048 pszCurModule += strlen(pszCurModule) + 1;
1049 fout << endl;
1050 }//for (i = 0; i < cModules; i++)
1051
1052 free(pszModules);
1053 return TRUE;
1054}
1055//******************************************************************************
1056//******************************************************************************
1057BOOL Win32Image::isPEImage(char *szFileName)
1058{
1059 IMAGE_FILE_HEADER fh;
1060 HFILE win32handle;
1061 ULONG ulAction = 0; /* Action taken by DosOpen */
1062 ULONG ulLocal = 0; /* File pointer position after DosSetFilePtr */
1063 APIRET rc = NO_ERROR; /* Return code */
1064 LPVOID win32file = NULL;
1065 ULONG ulRead;
1066 int nSections, i;
1067
1068 rc = DosOpen(szFileName, /* File path name */
1069 &win32handle, /* File handle */
1070 &ulAction, /* Action taken */
1071 0L, /* File primary allocation */
1072 0L, /* File attribute */
1073 OPEN_ACTION_FAIL_IF_NEW |
1074 OPEN_ACTION_OPEN_IF_EXISTS, /* Open function type */
1075 OPEN_FLAGS_NOINHERIT |
1076 OPEN_SHARE_DENYNONE |
1077 OPEN_ACCESS_READONLY, /* Open mode of the file */
1078 0L); /* No extended attribute */
1079
1080 if (rc != NO_ERROR) {
1081 fout << "isPEImage: DosOpen returned " << rc << endl;
1082 return(FALSE);
1083 }
1084
1085 /* Move the file pointer back to the beginning of the file */
1086 DosSetFilePtr(win32handle, 0L, FILE_BEGIN, &ulLocal);
1087
1088 IMAGE_DOS_HEADER *pdoshdr = (IMAGE_DOS_HEADER *)malloc(sizeof(IMAGE_DOS_HEADER));
1089 if(pdoshdr == NULL) {
1090 DosClose(win32handle); /* Close the file */
1091 return(FALSE);
1092 }
1093 rc = DosRead(win32handle, pdoshdr, sizeof(IMAGE_DOS_HEADER), &ulRead);
1094 if(rc != NO_ERROR) {
1095 DosClose(win32handle); /* Close the file */
1096 return(FALSE);
1097 }
1098 ULONG hdrsize = pdoshdr->e_lfanew + SIZE_OF_NT_SIGNATURE + sizeof(IMAGE_FILE_HEADER);
1099 free(pdoshdr);
1100
1101 /* Move the file pointer back to the beginning of the file */
1102 DosSetFilePtr(win32handle, 0L, FILE_BEGIN, &ulLocal);
1103
1104 win32file = malloc(hdrsize);
1105 if(win32file == NULL) {
1106 DosClose(win32handle); /* Close the file */
1107 return(FALSE);
1108 }
1109 rc = DosRead(win32handle, win32file, hdrsize, &ulRead);
1110 if(rc != NO_ERROR) {
1111 goto failure;
1112 }
1113
1114 if(GetPEFileHeader (win32file, &fh) == FALSE) {
1115 goto failure;
1116 }
1117
1118 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
1119 goto failure;
1120 }
1121 if(fh.Machine != IMAGE_FILE_MACHINE_I386) {
1122 goto failure;
1123 }
1124 //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)?
1125 if(fh.Characteristics & IMAGE_FILE_SYSTEM) {
1126 goto failure;
1127 }
1128 DosClose(win32handle);
1129 return(TRUE);
1130
1131failure:
1132 free(win32file);
1133 DosClose(win32handle);
1134 return(FALSE);
1135}
1136//******************************************************************************
1137//******************************************************************************
1138void Win32Image::setFullPath(char *name)
1139{
1140 dassert(name, ("setFullPath, name == NULL"));
1141 fullpath = (char *)malloc(strlen(name)+1);
1142 dassert(fullpath, ("setFullPath, fullpath == NULL"));
1143 strcpy(fullpath, name);
1144}
1145//******************************************************************************
1146//******************************************************************************
1147ULONG MissingApi()
1148{
1149 static BOOL fIgnore = FALSE;
1150 int r;
1151
1152 dprintf(("Missing api called!\n"));
1153 if(fIgnore)
1154 return(0);
1155
1156 do {
1157 r = WinMessageBox(HWND_DESKTOP, NULLHANDLE, "The application has called a non-existing api\n",
1158 "Internal Error", 0, MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION | MB_MOVEABLE);
1159 }
1160 while(r == MBID_RETRY); //giggle
1161
1162 if( r != MBID_IGNORE )
1163 exit(987);
1164
1165 fIgnore = TRUE;
1166 return(0);
1167}
1168//******************************************************************************
1169//******************************************************************************
1170/*heximal(decimal) KSO Sun 24.05.1998*/
1171char szHexBuffer[30];
1172
1173char *hex(ULONG num)
1174{
1175 sprintf(szHexBuffer, "0x%+08x (%lu)",num,num);
1176 return szHexBuffer;
1177}
1178//******************************************************************************
1179//******************************************************************************
Note: See TracBrowser for help on using the repository browser.