|
|
/*** impexp.c - Import/Export module - implementation
* * Copyright <C> 1992, Microsoft Corporation * * This module contains proprietary information of Microsoft * Corporation and should be treated as confidential. * * Purpose: * Build and write segmented-executable import/export tables * * Revision History: * * 29-May-1992 Wieslaw Kalkus Created * *************************************************************************/
#include <minlit.h>
#include <bndtrn.h>
#include <bndrel.h>
#include <lnkio.h>
#include <newexe.h>
#include <lnkmsg.h>
#include <extern.h>
#include <string.h>
#include <impexp.h>
//
// Functions operating on dynamic byte arrays
//
void InitByteArray(DYNBYTEARRAY *pArray) { pArray->byteMac = 0; pArray->byteMax = DEF_BYTE_ARR_SIZE; pArray->rgByte = GetMem(DEF_BYTE_ARR_SIZE); }
void FreeByteArray(DYNBYTEARRAY *pArray) { FFREE(pArray->rgByte); pArray->byteMac = 0; pArray->byteMax = 0; }
WORD ByteArrayPut(DYNBYTEARRAY *pArray, WORD size, BYTE *pBuf) { BYTE FAR *pTmp; WORD idx;
if ((DWORD)(pArray->byteMac) + size > 0xFFFE) Fatal(ER_memovf);
if ((WORD) (pArray->byteMac + size) >= pArray->byteMax) { // Realloc array
if(pArray->byteMax < 0xffff/2) pArray->byteMax <<= 1; else while (pArray->byteMac + size >= pArray->byteMax) pArray->byteMax += (0x10000 - pArray->byteMax) / 2; pArray->rgByte = REALLOC(pArray->rgByte,pArray->byteMax); if(!pArray->rgByte) Fatal(ER_memovf); ASSERT (pArray->byteMax > pArray->byteMac + size); } idx = pArray->byteMac; pTmp = &(pArray->rgByte[idx]); FMEMCPY(pTmp, pBuf, size); pArray->byteMac += size; return(idx); }
void WriteByteArray(DYNBYTEARRAY *pArray) { WriteExe(pArray->rgByte, pArray->byteMac); }
//
// Functions operating on dynamic word arrays
//
void InitWordArray(DYNWORDARRAY *pArray) { pArray->wordMac = 0; pArray->wordMax = DEF_WORD_ARR_SIZE; pArray->rgWord = (WORD FAR *) GetMem(DEF_WORD_ARR_SIZE * sizeof(WORD)); }
void FreeWordArray(DYNWORDARRAY *pArray) { FFREE(pArray->rgWord); pArray->wordMac = 0; pArray->wordMax = 0; }
WORD WordArrayPut(DYNWORDARRAY *pArray, WORD val) { WORD FAR *pTmp; WORD idx;
if ((WORD) (pArray->wordMac + 1) >= pArray->wordMax) { // Realloc array
pTmp = (WORD FAR *) GetMem((pArray->wordMax << 1) * sizeof(WORD)); FMEMCPY(pTmp, pArray->rgWord, pArray->wordMac * sizeof(WORD)); FFREE(pArray->rgWord); pArray->rgWord = pTmp; pArray->wordMax <<= 1; } idx = pArray->wordMac; pArray->rgWord[idx] = val; pArray->wordMac++; return(idx); }
void WriteWordArray(DYNWORDARRAY *pArray) { WriteExe(pArray->rgWord, pArray->wordMac*sizeof(WORD)); }
//
// IMPORT/EXPORT tables
//
DYNBYTEARRAY ResidentName; DYNBYTEARRAY NonResidentName; DYNBYTEARRAY ImportedName; DYNWORDARRAY ModuleRefTable; DYNBYTEARRAY EntryTable;
//
// Functions adding names to tables
//
void AddName(DYNBYTEARRAY *pTable, BYTE *sbName, WORD ord) { WORD cb;
cb = sbName[0] + 1 + sizeof(WORD); if ((WORD)(0xFFFE - pTable->byteMac) < cb) { if (pTable == &ResidentName) Fatal(ER_resovf); else Fatal(ER_nresovf); } ByteArrayPut(pTable, (WORD) (sbName[0] + 1), sbName); ByteArrayPut(pTable, sizeof(WORD), (BYTE *) &ord); }
WORD AddImportedName(BYTE *sbName) { if ((WORD) (0xfffe - ImportedName.byteMac) < (WORD) (sbName[0] + 1)) Fatal(ER_inamovf); return(ByteArrayPut(&ImportedName, (WORD) (sbName[0] + 1), sbName)); }
//
// Function adding entries to the Entry Table
//
WORD AddEntry(BYTE *entry, WORD size) { if ((WORD)(EntryTable.byteMax + size) < EntryTable.byteMax) Fatal(ER_etovf); return (ByteArrayPut(&EntryTable, size, entry)); }
/*
* This function writes either the resident or nonresident names table * to a file f. If targeting Windows it also converts the names * to upper case. */
void WriteNTable(DYNBYTEARRAY *pArray, FILE *f) { BYTE *p; WORD *pOrd; // points to the ordinal
WORD Ord; // ordinal value
int i; p = pArray->rgByte; #if DEBUG_EXP
for( i = 0; i<pArray->byteMac; i++) { fprintf(stdout, "\r\n%d : %d(%c) ", i, *(p+i), *(p+i)); fflush(stdout); } #endif
while(p[0]) // Until names left
{ if(f) // If writing to a file
{ pOrd = (WORD*)(p+p[0]+1); Ord = *pOrd; #if DEBUG_EXP
fprintf(stdout, "\r\np[0]=%d, p[1]=%d Ord = %d", p[0], p[1], Ord); #endif
if(Ord) // Don't output module name/description
{ *pOrd = 0; fprintf(f, "\r\n %s @%d", p+1, Ord); *pOrd = Ord; } }
// Windows loader requires both res-and nonresident name tables in uppercase
// If fIgnoreCase is TRUE, the names are already converted by SavExp2
if(!fIgnoreCase && TargetOs == NE_WINDOWS) SbUcase(p); // Make upper case
p += p[0] + sizeof(WORD) + 1; // Advance to the next name
} } /*
* This function converts the res- and nonresident name symbols * to uppercase (when targeting Windows). On user request it also * writes all the names to a text file, that can later be included * in the user's .def file. This frees the user from the need of * manually copying the decorated names from the .map file. */
void ProcesNTables( char *pName) { FILE *f = NULL; int i; #if DEBUG_EXP
fprintf(stdout, "\r\nOutput file name : %s ", psbRun); #endif
if(pName[0]) // user requested export file
{ if(pName[0] == '.') // use the default name
{ for(i=0; i< _MAX_PATH; i++) { if((pName[i] = psbRun[i]) == '.') { pName[i+1] = '\0'; break; } } strcat(pName, "EXP"); // the default name is 'DLLNAME'.EXP
} #if DEBUG_EXP
fprintf(stdout, "\r\nEXPORT FILE : %s ", pName+1); #endif
if((f = fopen(pName+1, WRBIN)) == NULL) OutError(ER_openw, pName); }
WriteNTable(&ResidentName, f); WriteNTable(&NonResidentName, f);
fclose(f); }
|