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

Last change on this file since 532 was 532, checked in by sandervl, 26 years ago

Compilation fixes

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