/* $Id: LX.CPP,v 1.4 1999-07-07 08:11:10 sandervl Exp $ */ /* * PE2LX LX code * * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl) * Copyright 1998 Knut St. Osmundsen * Copyright 1998 Peter Fitzsimmons * * * Project Odin Software License can be found in LICENSE.TXT * */ #define INCL_DOSFILEMGR /* File Manager values */ #define INCL_DOSERRORS /* DOS Error values */ #define INCL_DOSPROCESS /* DOS Process values */ #define INCL_DOSMISC /* DOS Miscellanous values */ #include #include #include #include #include #include #include #include "lx.h" #include "misc.h" /*PLF Wed 98-03-18 02:00:21*/ #include #define ORD_REGISTERRESOURCEINFO 1203 #define ORD_KERNEL32DLLEXITLIST 1208 #define ORD_REGISTERDLL 1209 #define ZERO(a) (memset(&a, 0, sizeof(a))) #ifndef max /*PLF Sat 97-06-21 22:36:14*/ #define max(a,b) ((a>b) ? (a) : (b)) #endif #ifndef min #define min(a,b) ((aIsEXE = IsEXE; if(IsEXE) { LXHdr.e32_mflags |= E32MODEXE; } else {//Assuming per process initialization/termination... LXHdr.e32_mflags |= E32LIBINIT | E32LIBTERM | E32MODDLL; } } //****************************************************************************** //****************************************************************************** void LXHeader::SetEntryAddress(int address) { LXHdr.e32_eip = address; } //****************************************************************************** //****************************************************************************** void LXHeader::SetStackSize(int size) { if(IsEXE) { //Open32 requires a stack size of at least 64k // if(size < 64*1024) StackSize = 64*1024; if(size < 128*1024) StackSize = 128*1024; else StackSize = size; //KSO - Aug 5 1998 8:13pm: (Borlandfix) stacksize in TIB depend on this. LXHdr.e32_stacksize = StackSize; } } //****************************************************************************** //****************************************************************************** void LXHeader::SetModuleName(char *filename) { char fname[CCHMAXPATH]; strcpy(fname, filename); strcpy(modulename, StripExtension(StripPath(fname))); UpCase(modulename); } //****************************************************************************** //****************************************************************************** void LXHeader::StoreSection(char *rawdata, int rawsize, int virtualsize, int address, int type) { #ifndef RING0 static int idx = 0, i; Section TmpSec[MAX_SECTION]; //Several exes have sections with virtual size 0 if(virtualsize == 0) virtualsize = rawsize; assert(rawdata); if(nrsections == 0) { PESection[0].type = type; PESection[0].rawdata = rawdata; PESection[0].address = address; PESection[0].rawsize = rawsize; //SvL: 5-9-'98 PESection[0].virtualsize = max(virtualsize,rawsize); // PESection[0].virtualsize = virtualsize; PESection[0].nrpages = ((PESection[0].virtualsize + 0xFFF) & ~0xFFF) >> PAGE_SHIFT; PESection[0].endaddress = address + PESection[0].nrpages*PAGE_SIZE - 1; } else { //anders op volgorde toevoegen memset(&TmpSec[0], 0, sizeof(TmpSec)); i = 0; while(i < idx && PESection[i].address < address) { memcpy(&TmpSec[i], &PESection[i], sizeof(PESection[i])); i++; assert( i < MAX_SECTION ); /*PLF Mon 98-02-09 23:44:23*/ } TmpSec[i].type = type; TmpSec[i].rawdata = rawdata; TmpSec[i].address = address; TmpSec[i].rawsize = rawsize; TmpSec[i].virtualsize = max(virtualsize,rawsize); TmpSec[i].nrpages = ((TmpSec[i].virtualsize + 0xFFF) & ~0xFFF) >> PAGE_SHIFT; TmpSec[i].endaddress = address + TmpSec[i].nrpages*PAGE_SIZE - 1; while(i < idx && PESection[i].rawdata) { assert( i+1 < MAX_SECTION ); /*PLF Mon 98-02-09 23:44:23*/ memcpy(&TmpSec[i+1], &PESection[i], sizeof(PESection[i])); i++; } memcpy(&PESection[0], &TmpSec[0], (idx+1)*sizeof(PESection[0])); } idx++; nrsections++; #else int i,j; //Several exes have sections with virtual size 0 if (virtualsize == 0) virtualsize = rawsize; /* sorry this was not optimized! */ /*find place in section table (sort on address)*/ i = 0; while (i < nrsections/*idx?*/ && PESection[i].address < address ) i++; if ( i != nrsections ) { /* move sections from this one entry back */ j = nrsections; while(j > i) { memcpy(&PESection[j], &PESection[j-1], sizeof(PESection[j-1])); j--; } } PESection[i].type = type; #ifndef RING0 PESection[i].rawdata = rawdata; #else PESection[i].rawdata = rawdata ? (rawdata) : ~0; #endif PESection[i].address = address; #if 1 PESection[i].rawsize = min(rawsize,virtualsize); PESection[i].virtualsize = max(virtualsize,rawsize); #else PESection[i].rawsize = rawsize;//min(rawsize,virtualsize); PESection[i].virtualsize = virtualsize;//max(virtualsize,rawsize); #endif PESection[i].nrpages = ((virtualsize + 0xFFF) & ~0xFFF) >> PAGE_SHIFT; PESection[i].endaddress = address + PESection[i].nrpages*PAGE_SIZE - 1; /* Inc number of sections */ nrsections++; /* it wasn't that hard was it? - this code will at least not cause a stack overflow. */ #endif } //****************************************************************************** //SvL: Align code section at 64 kb boundary //SvL: Put adjacent data section in one big section and align it to a 64 kb // boundary //ASSUMPTIONS: - Code section comes first // - (data) sections that aren't adjacent are aligned at 64kb boundary //I could fix the second assumption, but I'm too lazy right now //****************************************************************************** void LXHeader::AlignSections() { int i, j, idx = 0, rawsize; Section CombinedData; //Put TIBFix code before actual win32 code (prevents overlaps)! PESection[0].address -= PAGE_SIZE; PESection[0].nrpages++; if(!(LXHdr.e32_mflags & E32NOINTFIX)) return; //rest not needed if there are internal fixups PESection[0].nrinvalidpages = (PESection[0].address & 0xFFFF) >> PAGE_SHIFT; PESection[0].address &= 0xFFFF0000; //SvL: Concatenate code & data sections into one LX object memcpy(&CombinedData, &PESection[0], sizeof(Section)); //Insert invalid pages to align section at 64 kb boundary CombinedData.type = SECTION_COMBINEDDATA; CombinedData.rawdata = NULL; //not used here (just use the originals) //too much, but just to be sure (in case we need to add extra invalid pages) //TODO: This should be done safer in the future datapage = (DataPage *)malloc((GetNrPages()+256)*sizeof(DataPage)); //process pages of first section (code) rawsize = CombinedData.rawsize; datapage[0].size = EXE_TIB_SIZE; datapage[0].flags = 0; idx = 1; for(j=1;j> PAGE_SHIFT; for(j=0;j (127-3)) name[126] = 0; //OS/2 maximum *curexport = (BYTE)strlen(name); curexport++; strcpy(curexport, name); curexport += strlen(name); *(USHORT *)curexport = (USHORT)(ordinal); curexport += sizeof(USHORT); } //****************************************************************************** //****************************************************************************** void LXHeader::AddOrdExport(int address, int ordinal) { static int lastord = 0; int i; if(ordinal > lastord+1) {//add empty record(s) int diff = ordinal - lastord - 1; while(diff) { curexpb->b32_cnt = min(diff, 255); diff -= curexpb->b32_cnt; curexpb->b32_type = EMPTY; curexpb = (exportbundle *)((int)curexpb + 2*sizeof(char)); } } curexpb->b32_cnt = 1; curexpb->b32_type = ENTRY32; i = GetRealSectionByAddress(address); curexpb->b32_obj = (USHORT)(i + 1); //start at 1 instead of 0 curexpb->e32_flags = E32EXPORT | E32SHARED; curexpb->e32_offset = address - PESection[i].address; lastord = ordinal; curexpb++; } //****************************************************************************** //****************************************************************************** void LXHeader::SetNrExtFixups(int nr) { int len; exports = (char *)malloc(64+nr*(127+1+2)); //length byte, name (max 127) + ordinal (USHORT) memset(exports, 0, 64+nr*(127+1+2)); if(nr > 0) { expbundle = (exportbundle *)malloc(nr*max(sizeof(exportbundle), sizeof(forwardbundle))); memset(expbundle, 0, nr*max(sizeof(exportbundle), sizeof(forwardbundle))); } curexpb = expbundle; curexport = exports; //First entry in resident name table is module name strcpy(&curexport[1], modulename); len = strlen(&curexport[1]); *curexport = (char)len; curexport += len+1; *(USHORT *)curexport = 0; curexport += sizeof(USHORT); #if 0 //first entry in export table is unused curexpb->b32_cnt = 1; curexpb->b32_type = EMPTY; curexpb = (exportbundle *)&curexpb->b32_obj; #endif } //****************************************************************************** //TODO: finish this //forward gives the DLL name and name of the export (i.e. MYDLL.expfunc or MYDLL.#27) //****************************************************************************** #ifdef __WATCOMC__ #pragma off (unreferenced) #endif void LXHeader::AddForwarder(char *name, int ordinal, char *forward) #ifdef __WATCOMC__ #pragma on (unreferenced) #endif { #if 0 *curexport = (BYTE)strlen(name); curexport++; strncpy(curexport, name, 127); curexport += strlen(name); *(USHORT *)curexport = (USHORT)ordinal; curexport += sizeof(USHORT); nrexports++; #endif } //****************************************************************************** //iets te veel, but who cares //****************************************************************************** void LXHeader::SetNrOff32Fixups(int nr) { intfixuprec = (intfixup *)malloc((nr+EXTRA_TLS_FIXUPS)*sizeof(intfixup)); memset(intfixuprec, 0, (nr+EXTRA_TLS_FIXUPS)*sizeof(intfixup)); } //****************************************************************************** //SvL: TLS Section support //Add three interal fixups. One for start of TLS section, one for DWORD that //receives the TLS index and one for the array of TLS callbacks //Also one for the entrypoint address. //****************************************************************************** void LXHeader::AddExtraFixups() { *(ULONG *)&szEXETIBFix[EXE_OFF_TIBOBJ_ADDR] = tlsAddress; *(ULONG *)&szEXETIBFix[EXE_OFF_TIBINIT_SIZE] = tlsInitSize; *(ULONG *)&szEXETIBFix[EXE_OFF_TIBOBJ_SIZE] = tlsTotalSize; *(ULONG *)&szEXETIBFix[EXE_OFF_TIB_INDEX] = tlsIndexAddr; *(ULONG *)&szEXETIBFix[EXE_OFF_TIB_CALLBACK_ADDR] = tlsCallBackAddr; *(ULONG *)&szEXETIBFix[EXE_OFF_ENTRYPOINT] = EntryAddress; if(LXHdr.e32_mflags & E32NOINTFIX) return; //no internal fixups, so we don't have to add them either AddOff32Fixup(PESection[0].address + EXE_OFF_ENTRYPOINT, TRUE); if(tlsAddress == 0) return; //no TLS section in this image AddOff32Fixup(PESection[0].address + EXE_OFF_TIBOBJ_ADDR, TRUE); AddOff32Fixup(PESection[0].address + EXE_OFF_TIB_INDEX, TRUE); AddOff32Fixup(PESection[0].address + EXE_OFF_TIB_CALLBACK_ADDR, TRUE); return; } //****************************************************************************** //SvL: if fLookatStartupCode is set to true, we'll read the szEXETIBFix // fixup addresses instead of those in the section // (section 0 is main code section which doesn't include szEXETIBFix) //****************************************************************************** void LXHeader::AddOff32Fixup(int address, BOOL fLookatStartupCode) { static intfixup crossedpage; static BOOL fCrossed = FALSE; static int crossedpageaddress = 0; intfixup *frec; int type, targetaddr; frec = &intfixuprec[nrintfixups]; //Check if we need to insert a crossed page fixup if(fCrossed == TRUE && address > crossedpageaddress) { memcpy((char *)frec, (char *)&crossedpage, sizeof(crossedpage)); fCrossed = FALSE; crossedpageaddress = 0; nrintfixups++; frec++; } frec->nr_stype = 0x07; //32 bits offset fixup //internal fixup + 32 bits offset + 16 bits object nr frec->nr_flags = 0x00 | 0x10 | 0x40; frec->r32_soff = (SHORT)(address & 0xFFF); type = GetSectionByAddress(address); if(type == -1) { cout << "Oops, fixup error 1.... at " << hex(address) << endl; return; //hmmmmmmmmmm } frec->srcpage = (USHORT)GetAddressPage(address); frec->srcobj = (USHORT)type; //SvL: address could be aligned at 64 kb boundary, so correct address calculation if(type == 0) { // +1 for tibfix page assert(PESection[type].type & SECTION_CODE); if(fLookatStartupCode) { targetaddr = *(int *)(&szEXETIBFix[0] + (address & 0xFF)); } else { targetaddr = *(int *)(PESection[type].rawdata + (address - (PESection[type].address + (PESection[type].nrinvalidpages+1)*PAGE_SIZE))); } } else targetaddr = *(int *)(PESection[type].rawdata + (address - (PESection[type].address + PESection[type].nrinvalidpages*PAGE_SIZE))); //SvL: The target object might be the combined data section, so don't use // GetSectionByAddress type = GetRealSectionByAddress(targetaddr); if(type == -1){ cout << "Oops, fixup error 2.... at " << hex(targetaddr) << endl; return; //hmmmmmmmmmm } //SvL: If it's in the combined data section, the index is incorrect, so // correct it if(PESection[type].type == SECTION_COMBINEDDATA) frec->targetobj = (USHORT)(1+1); //ASSUMPTION else frec->targetobj = (USHORT)(type+1); //vanaf 1 frec->targetaddr = targetaddr - PESection[type].address; //relatief // cout << "src address " << frec->r32_soff << " srcpage " << frec->srcpage << " target " << frec->targetaddr << " frec " << (int)frec << endl; //SvL: Check for fixups that cross page boundaries // If I read the lx doc right, you need to add two fixups in // this case, one for original page and one for original page + 1 //TODO: Doesn't work if the last page contains such a fixup! if(frec->r32_soff + 4 > PAGE_SIZE) { memcpy((char *)&crossedpage, (char *)frec, sizeof(crossedpage)); //crossed page boundary -> negative offset in next page crossedpage.r32_soff = (SHORT)((frec->r32_soff & 0xFFF) - PAGE_SIZE); crossedpage.srcpage = frec->srcpage+1; crossedpageaddress = (address + PAGE_SIZE) & ~0xFFF; fCrossed = TRUE; } nrintfixups++; } //****************************************************************************** //SvL: 30-10-'97, assumption about sorting of fixups is incorrect, so: //ASSUMPTION: namefixup & ordfixup of same size //****************************************************************************** void LXHeader::StoreAndSortImport(namefixup *newfrec) { namefixup *frec; namefixup *tmp; int i; if(nrimpfixups != 0) { frec = &impfixuprec[nrimpfixups - 1]; if(newfrec->srcpage >= frec->srcpage) { memcpy(&impfixuprec[nrimpfixups], newfrec, sizeof(namefixup)); nrimpfixups++; return; } } else { memcpy(&impfixuprec[0], newfrec, sizeof(namefixup)); nrimpfixups++; return; } tmp = (namefixup *)malloc(nrimpfixups*sizeof(namefixup)); frec = &impfixuprec[0]; for(i=0;isrcpage < frec->srcpage) { memcpy(tmp, frec, (nrimpfixups-i)*sizeof(namefixup)); memcpy(frec, newfrec, sizeof(namefixup)); memcpy(frec+1, tmp, (nrimpfixups-i)*sizeof(namefixup)); break; } frec++; } assert(i != nrimpfixups); free(tmp); nrimpfixups++; } //****************************************************************************** //****************************************************************************** void LXHeader::SetNoNameImports() { impnames = (char *)malloc(16); memset(impnames, 0, 16); impnameoff = impnames + 1; //SvL: Bugfix: base 1 impnamesize = 0; //include ending 0 } //****************************************************************************** //****************************************************************************** BOOL LXHeader::StoreImportByName(char *modname, int idxmod, char *name, int offset) { namefixup frec; if(impfixuprec == NULL) { impfixuprec = (namefixup *)malloc(MAX_IMPORT*sizeof(namefixup)); memset(impfixuprec, 0, MAX_IMPORT*sizeof(namefixup)); } if(impnames == NULL) { impnames = (char *)malloc(128*1024); //moet genoeg zijn memset(impnames, 0, 128*1024); impnameoff = impnames + 1; //SvL: Bugfix: base 1 impnamesize = 1; //include ending 0 } if(nrimpfixups >= MAX_IMPORT) { cout << "Oops, too many imported functions...." << endl; return(FALSE); } frec.nr_stype = 0x07; //32 bits offset frec.nr_flags = 0x02 | 0x40; //import by name + mod offset = 16 bits frec.r32_soff = (SHORT)(offset & 0xFFF); //offset within specific page frec.r32_objmod = (USHORT)(idxmod+1); //vanaf 1!!!!! impnameoff[0] = (char)strlen(name); strcpy(&impnameoff[1], name); frec.proc = (USHORT)((int)impnameoff-(int)impnames); //32 bits target flag not set! frec.srcpage = (USHORT)GetAddressPage(offset); impnamesize += impnameoff[0]+1; impnameoff += impnameoff[0]+1; StoreAndSortImport(&frec); return(TRUE); } //****************************************************************************** //****************************************************************************** BOOL LXHeader::StoreImportByOrd(int idxmod, int ordinal, int offset) { ordfixup frec; if(impfixuprec == NULL) { impfixuprec = (namefixup *)malloc(MAX_IMPORT*sizeof(namefixup)); memset(impfixuprec, 0, MAX_IMPORT*sizeof(namefixup)); } if(nrimpfixups >= MAX_IMPORT) { cout << "Oops, too many imported functions...." << endl; return(FALSE); } frec.nr_stype = 0x07; //32 bits offset frec.nr_flags = 0x01 | 0x40; //import by ordinal + mod offset = 16 bits frec.r32_soff = (SHORT)(offset & 0xFFF); //offset within specific page frec.r32_objmod = (USHORT)(idxmod+1); //vanaf 1!!!!! frec.ord = (USHORT)ordinal; frec.srcpage = (USHORT)GetAddressPage(offset); StoreAndSortImport((namefixup *)&frec); return(TRUE); } //****************************************************************************** //****************************************************************************** void LXHeader::StoreImportModules(char *modules, int nrmod) { int size = 0, i; char *src, *dest; ///-4*nrmod = - 4 * .dll impmodules = (char *)malloc(nrmod*9 + 32); /*PLF Sun 97-06-22 00:51:12*/ impmodulesize = 0; src = modules; dest = impmodules; for(i=0;i make 'em zeroed objpage[idx].o32_pageflags = ZEROED; } else { if(PESection[i].type == SECTION_COMBINEDDATA) { if(j == PESection[i].nrinvalidpages) { objpage[idx].o32_pagesize = (USHORT)(EXE_TIB_SIZE); objpage[idx].o32_pageflags = 0; pagedataoffset += EXE_TIB_SIZE; LXHdr.e32_mpages++; LXHdr.e32_eip = PAGE_SIZE*PESection[i].nrinvalidpages; objtable.o32_size = objtable.o32_mapsize*PAGE_SIZE; } else { int didx = j - PESection[i].nrinvalidpages; objpage[idx].o32_pagesize = datapage[didx].size; objpage[idx].o32_pageflags = datapage[didx].flags; pagedataoffset += objpage[idx].o32_pagesize; if(objpage[idx].o32_pageflags == 0) LXHdr.e32_mpages++; } } else if(PESection[i].type == SECTION_UNINITDATA || rawsize == 0) { objpage[idx].o32_pagesize = 0; objpage[idx].o32_pagedataoffset = pagedataoffset; objpage[idx].o32_pageflags = ZEROED; } else //take care of TIBFix code! if(fFirstCode == FALSE && PESection[i].type & SECTION_CODE && j == PESection[i].nrinvalidpages) { objpage[idx].o32_pagesize = (USHORT)EXE_TIB_SIZE; objpage[idx].o32_pageflags = 0; pagedataoffset += EXE_TIB_SIZE; LXHdr.e32_mpages++; LXHdr.e32_eip = PAGE_SIZE*PESection[i].nrinvalidpages; } else { if(rawsize > PAGE_SIZE) objpage[idx].o32_pagesize = PAGE_SIZE; else objpage[idx].o32_pagesize = rawsize; rawsize -= objpage[idx].o32_pagesize; objpage[idx].o32_pageflags = 0; LXHdr.e32_mpages++; pagedataoffset += objpage[idx].o32_pagesize; } } } if(IsEXE && i == nrsections - 1) {//SvL: 25-7-'97 Add stack pages to last data object LXHdr.e32_stackobj = objcnt; LXHdr.e32_autodata = LXHdr.e32_stackobj; objtable.o32_flags |= OBJWRITE; objtable.o32_size += StackSize; LXHdr.e32_esp = objtable.o32_size; //highest address in object } //Write object table entry to file DosWrite(win32handle, &objtable, sizeof(objtable), &ulWrite); if(PESection[i].type & SECTION_CODE) fFirstCode = TRUE; //dealt with first code section pagetblidx += objtable.o32_mapsize; objcnt++; } if(nrresources) { //Correct count in case there are string tables which aren't completely filled nrresources = curresource; //Process Resource Object LXHdr.e32_objcnt++; objtable.o32_pagemap = pagetblidx; objtable.o32_flags = NSSHARED | OBJREAD | OBJRSRC | OBJBIGDEF; objtable.o32_mapsize = ResSection.rawsize >> PAGE_SHIFT; objtable.o32_base = 0; //SvL: Set to 0 in PM exes (plf) objtable.o32_size = ResSection.rawsize; for(j=0;j 1) { rc = DosWrite(win32handle, expbundle, len, &ulWrite); LXHdr.e32_ldrsize += len; } } //#pages * offset naar import fixups + 1 eind offset LXHdr.e32_fpagetab = LXHdr.e32_ldrsize + LXHdr.e32_objtab; LXHdr.e32_frectab = LXHdr.e32_fpagetab + (nrpages+1)*sizeof(int); fixuptable = (int *)malloc((nrpages+1)*sizeof(int)); for(i=0;inr_stype = 0x07; //32 bits offset kerord->nr_flags = 0x01 | 0x40; //import by ordinal + mod offset = 16 bits kerord->r32_soff = EXE_OFF_ENTRYFIX; kerord->r32_objmod = kernel32Object + 1; if(IsEXE) kerord->ord = ORD_REGISTERRESOURCEINFO; else kerord->ord = ORD_REGISTERDLL; currealrec = (realintfixup *)((int)currealrec + sizeof(realnamefixup)); } //SvL: 16-9-'97, for multiple import pages while(k < nrimpfixups && imprec->srcpage == i) { //sizeof(realordfixup) == sizeof(realnamefixup) memcpy(currealrec, imprec, sizeof(realnamefixup)); currealrec = (realintfixup *)((int)currealrec + sizeof(realnamefixup)); imprec++; k++; } while( j < nrintfixups && frec->srcpage == i) { memcpy(currealrec, frec, sizeof(realintfixup)); // cout << "src address " << frec->r32_soff << " srcpage " << frec->srcpage << " target " << frec->targetaddr << " frec " << (int)frec << endl; frec++; currealrec++; j++; } } fixuptable[nrpages] = (int)currealrec - (int)frealrec; //Add extra kernel32 imports nrimpfixups += EXTRA_FIXUPS; //Write fixup page table DosWrite(win32handle, fixuptable, (nrpages+1)*sizeof(int), &ulWrite); //Write fixup record table DosWrite(win32handle, frealrec, nrintfixups*sizeof(realintfixup)+nrimpfixups*sizeof(realnamefixup), &ulWrite); free(frealrec); free(fixuptable); //fixup page + record + import name + module table size LXHdr.e32_fixupsize = (nrpages+1)*sizeof(int) + nrimpfixups*sizeof(realnamefixup) + nrintfixups*sizeof(realintfixup) + impmodulesize + impnamesize; //size tables vanaf object table t/m impproc (eigenlijk pagesum ook..) LXHdr.e32_ldrsize += LXHdr.e32_fixupsize; //offset naar module name array LXHdr.e32_impmod = LXHdr.e32_frectab + nrimpfixups*sizeof(realnamefixup) + nrintfixups*sizeof(realintfixup); //offset naar proc name array LXHdr.e32_impproc = LXHdr.e32_impmod + impmodulesize; //Write Import Module array DosWrite(win32handle, impmodules, impmodulesize, &ulWrite); //Write Import Procedure Name array if(impnamesize) { DosWrite(win32handle, impnames, impnamesize, &ulWrite); } //pointer naar begin code/data LXHdr.e32_datapage = LXHdr.e32_impproc + impnamesize + LXHEADER_OFFSET; //vanaf begin ipv lxheader fFirstCode = FALSE; //TIBfix only for first code object for(i=0;i> PAGE_SHIFT; if(StackSize & 0xFFF) nrpages++; } #endif if(nrresources) { nrpages += ResSection.virtualsize >> PAGE_SHIFT; if(ResSection.rawsize & 0xFFF) nrpages++; } return(nrpages); } //****************************************************************************** //****************************************************************************** void LXHeader::UpCase(char *mixedcase) { int i; for(i=0;i= 'a' && mixedcase[i] <= 'z') { mixedcase[i] += 'A' - 'a'; } } } //****************************************************************************** //****************************************************************************** void LXHeader::SetModuleType(int type) { LXHdr.e32_mflags |= E32PMAPI; if(IsEXE) //don't set it for dlls (in case this flag is accidentally set in the header) fConsole = (type == SYSTEM_CHARACTER); } //****************************************************************************** //****************************************************************************** int LXHeader::GetAddressPage(int address) { int i, page = 0; for(i=0;i PESection[i].endaddress) { page += PESection[i].nrpages + PESection[i].nrinvalidpages; } else { page += ((address - PESection[i].address) >> PAGE_SHIFT); break; } } return(page); } //****************************************************************************** //****************************************************************************** int LXHeader::GetSection(int type) { int i; for(i=0;i address ) { return(i); } } } return(-1); } //****************************************************************************** //SvL: Ignore sections combined into one data section //****************************************************************************** int LXHeader::GetRealSectionByAddress(int address) { int i; for(i=0;i address ) { return(i); } } } return(-1); } //****************************************************************************** //****************************************************************************** int LXHeader::GetSectionLEAddress(int address) { int i; for(i=0;i address) { return(i-1); } } } return(-1); } //****************************************************************************** //****************************************************************************** char *LXHeader::StripPath(char *path) //niets aan de string veranderen!! { while(strchr(path, '\\') != NULL) { path++; } return(path); } /******************************************************************************/ /******************************************************************************/ char *LXHeader::StripExtension(char *fname) { char *tmp = fname; while(strchr(fname, '.') != NULL) { fname++; } fname--; *fname = 0; return(tmp); } /******************************************************************************/ /******************************************************************************/ int LXHeader::GetUniqueId() { int i, j, id; for(j=0;j<65536;j++) { for(i=0;i1) 0xAAAABBBB, AAAA=org id, BBBB=OS/2 id orgrestable = (ULONG *)malloc((nrresources+1)*sizeof(ULONG)); memset(orgrestable, 0, (nrresources+1)*sizeof(ULONG)); } //****************************************************************************** //****************************************************************************** void LXHeader::StoreResourceId(int id) { resids[nrids] = id; nrids++; } /******************************************************************************/ /******************************************************************************/ void LXHeader::StoreWin32Resource(int id, int type, int size, char *resourcedata) { int newid = GetUniqueId(); //First entry used for nr of entries, so + 1 orgrestable[nrorgres+1] = ((id & 0xFFFF) << 16) + (newid & 0xFFFF); nrorgres++; //store them all as rcdata StoreResource(newid, RT_RCDATA, size, resourcedata); } /******************************************************************************/ /******************************************************************************/ void LXHeader::StoreResource(int id, int type, int size, char *resourcedata) { static BOOL fFirstIcon = FALSE; char *tmpbuf; int i, newsize; if(type == RT_POINTER && fFirstIcon == FALSE && curresource > 0) { //put this one in front of all resources so OS/2 recognizes //it as the program object icon tmpbuf = (char *)malloc(curresource*sizeof(rsrc32)+ResSection.curoff); memcpy(tmpbuf, (char *)os2resource, curresource*sizeof(rsrc32)); memcpy((char *)&os2resource[1], tmpbuf, curresource*sizeof(rsrc32)); memcpy(tmpbuf, ResSection.rawdata, ResSection.curoff); memcpy(ResSection.rawdata, resourcedata, size); //SvL: Align all resources on 4 byte boundary newsize = (size + 3) & ~3; for(i=0;iname) == 0) return(resname->id); resname = (NameId *)((int)resname + sizeof(NameId) + strlen(resname->name)); } //Not found, so create one id = GetUniqueId(); curcvtname->id = id; strcpy(curcvtname->name, name); curcvtname = (NameId *)((int)curcvtname + sizeof(NameId) + strlen(name)); nrcvtnames++; return(id); } /******************************************************************************/ /******************************************************************************/ void LXHeader::SaveConvertedNames() { if(nrcvtnames) { //first USHORT = nr of converted names *(USHORT *)cvtname = nrcvtnames; cvtnametableid = GetUniqueId(); //fill in parameter for RegisterResourceInfo *(LONG *)&szEXETIBFix[EXE_OFF_NAMETABLE] = cvtnametableid; StoreResource(cvtnametableid, RT_RCDATA, (int)curcvtname - (int)cvtname, (char *)cvtname); } if(nrorgres) { //first ULONG = nr of original win32 resources stored in OS/2 exe/dll orgrestable[0] = nrorgres; orgrestableid = GetUniqueId(); //fill in parameter for RegisterResourceInfo *(LONG *)&szEXETIBFix[EXE_OFF_ORGRESTABLE] = (fConsole << 24) | orgrestableid; StoreResource(orgrestableid, RT_RCDATA, (nrorgres+1)*sizeof(ULONG), (char *)orgrestable); } else { *(LONG *)&szEXETIBFix[EXE_OFF_ORGRESTABLE] = (fConsole << 24) | 0x888888; } //SvL: 18-7-'98: Store internal pe2lx version and version resource id *(LONG *)&szEXETIBFix[EXE_OFF_PE2LXVER] = PE2LX_VERSION; *(LONG *)&szEXETIBFix[EXE_OFF_VERRESID] = VersionResourceId; } /******************************************************************************/ /******************************************************************************/ int LXHeader::uniqueId = RESID_CONVERTEDNAMES;