Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
6.9 KiB

  1. /*** impexp.c - Import/Export module - implementation
  2. *
  3. * Copyright <C> 1992, Microsoft Corporation
  4. *
  5. * This module contains proprietary information of Microsoft
  6. * Corporation and should be treated as confidential.
  7. *
  8. * Purpose:
  9. * Build and write segmented-executable import/export tables
  10. *
  11. * Revision History:
  12. *
  13. * 29-May-1992 Wieslaw Kalkus Created
  14. *
  15. *************************************************************************/
  16. #include <minlit.h>
  17. #include <bndtrn.h>
  18. #include <bndrel.h>
  19. #include <lnkio.h>
  20. #include <newexe.h>
  21. #include <lnkmsg.h>
  22. #include <extern.h>
  23. #include <string.h>
  24. #include <impexp.h>
  25. //
  26. // Functions operating on dynamic byte arrays
  27. //
  28. void InitByteArray(DYNBYTEARRAY *pArray)
  29. {
  30. pArray->byteMac = 0;
  31. pArray->byteMax = DEF_BYTE_ARR_SIZE;
  32. pArray->rgByte = GetMem(DEF_BYTE_ARR_SIZE);
  33. }
  34. void FreeByteArray(DYNBYTEARRAY *pArray)
  35. {
  36. FFREE(pArray->rgByte);
  37. pArray->byteMac = 0;
  38. pArray->byteMax = 0;
  39. }
  40. WORD ByteArrayPut(DYNBYTEARRAY *pArray, WORD size, BYTE *pBuf)
  41. {
  42. BYTE FAR *pTmp;
  43. WORD idx;
  44. if ((DWORD)(pArray->byteMac) + size > 0xFFFE)
  45. Fatal(ER_memovf);
  46. if ((WORD) (pArray->byteMac + size) >= pArray->byteMax)
  47. {
  48. // Realloc array
  49. if(pArray->byteMax < 0xffff/2)
  50. pArray->byteMax <<= 1;
  51. else
  52. while (pArray->byteMac + size >= pArray->byteMax)
  53. pArray->byteMax += (0x10000 - pArray->byteMax) / 2;
  54. pArray->rgByte = REALLOC(pArray->rgByte,pArray->byteMax);
  55. if(!pArray->rgByte)
  56. Fatal(ER_memovf);
  57. ASSERT (pArray->byteMax > pArray->byteMac + size);
  58. }
  59. idx = pArray->byteMac;
  60. pTmp = &(pArray->rgByte[idx]);
  61. FMEMCPY(pTmp, pBuf, size);
  62. pArray->byteMac += size;
  63. return(idx);
  64. }
  65. void WriteByteArray(DYNBYTEARRAY *pArray)
  66. {
  67. WriteExe(pArray->rgByte, pArray->byteMac);
  68. }
  69. //
  70. // Functions operating on dynamic word arrays
  71. //
  72. void InitWordArray(DYNWORDARRAY *pArray)
  73. {
  74. pArray->wordMac = 0;
  75. pArray->wordMax = DEF_WORD_ARR_SIZE;
  76. pArray->rgWord = (WORD FAR *) GetMem(DEF_WORD_ARR_SIZE * sizeof(WORD));
  77. }
  78. void FreeWordArray(DYNWORDARRAY *pArray)
  79. {
  80. FFREE(pArray->rgWord);
  81. pArray->wordMac = 0;
  82. pArray->wordMax = 0;
  83. }
  84. WORD WordArrayPut(DYNWORDARRAY *pArray, WORD val)
  85. {
  86. WORD FAR *pTmp;
  87. WORD idx;
  88. if ((WORD) (pArray->wordMac + 1) >= pArray->wordMax)
  89. {
  90. // Realloc array
  91. pTmp = (WORD FAR *) GetMem((pArray->wordMax << 1) * sizeof(WORD));
  92. FMEMCPY(pTmp, pArray->rgWord, pArray->wordMac * sizeof(WORD));
  93. FFREE(pArray->rgWord);
  94. pArray->rgWord = pTmp;
  95. pArray->wordMax <<= 1;
  96. }
  97. idx = pArray->wordMac;
  98. pArray->rgWord[idx] = val;
  99. pArray->wordMac++;
  100. return(idx);
  101. }
  102. void WriteWordArray(DYNWORDARRAY *pArray)
  103. {
  104. WriteExe(pArray->rgWord, pArray->wordMac*sizeof(WORD));
  105. }
  106. //
  107. // IMPORT/EXPORT tables
  108. //
  109. DYNBYTEARRAY ResidentName;
  110. DYNBYTEARRAY NonResidentName;
  111. DYNBYTEARRAY ImportedName;
  112. DYNWORDARRAY ModuleRefTable;
  113. DYNBYTEARRAY EntryTable;
  114. //
  115. // Functions adding names to tables
  116. //
  117. void AddName(DYNBYTEARRAY *pTable, BYTE *sbName, WORD ord)
  118. {
  119. WORD cb;
  120. cb = sbName[0] + 1 + sizeof(WORD);
  121. if ((WORD)(0xFFFE - pTable->byteMac) < cb)
  122. {
  123. if (pTable == &ResidentName)
  124. Fatal(ER_resovf);
  125. else
  126. Fatal(ER_nresovf);
  127. }
  128. ByteArrayPut(pTable, (WORD) (sbName[0] + 1), sbName);
  129. ByteArrayPut(pTable, sizeof(WORD), (BYTE *) &ord);
  130. }
  131. WORD AddImportedName(BYTE *sbName)
  132. {
  133. if ((WORD) (0xfffe - ImportedName.byteMac) < (WORD) (sbName[0] + 1))
  134. Fatal(ER_inamovf);
  135. return(ByteArrayPut(&ImportedName, (WORD) (sbName[0] + 1), sbName));
  136. }
  137. //
  138. // Function adding entries to the Entry Table
  139. //
  140. WORD AddEntry(BYTE *entry, WORD size)
  141. {
  142. if ((WORD)(EntryTable.byteMax + size) < EntryTable.byteMax)
  143. Fatal(ER_etovf);
  144. return (ByteArrayPut(&EntryTable, size, entry));
  145. }
  146. /*
  147. * This function writes either the resident or nonresident names table
  148. * to a file f. If targeting Windows it also converts the names
  149. * to upper case.
  150. */
  151. void WriteNTable(DYNBYTEARRAY *pArray, FILE *f)
  152. {
  153. BYTE *p;
  154. WORD *pOrd; // points to the ordinal
  155. WORD Ord; // ordinal value
  156. int i;
  157. p = pArray->rgByte;
  158. #if DEBUG_EXP
  159. for( i = 0; i<pArray->byteMac; i++)
  160. {
  161. fprintf(stdout, "\r\n%d : %d(%c) ", i, *(p+i), *(p+i));
  162. fflush(stdout);
  163. }
  164. #endif
  165. while(p[0]) // Until names left
  166. {
  167. if(f) // If writing to a file
  168. {
  169. pOrd = (WORD*)(p+p[0]+1);
  170. Ord = *pOrd;
  171. #if DEBUG_EXP
  172. fprintf(stdout, "\r\np[0]=%d, p[1]=%d Ord = %d", p[0], p[1], Ord);
  173. #endif
  174. if(Ord) // Don't output module name/description
  175. {
  176. *pOrd = 0;
  177. fprintf(f, "\r\n %s @%d", p+1, Ord);
  178. *pOrd = Ord;
  179. }
  180. }
  181. // Windows loader requires both res-and nonresident name tables in uppercase
  182. // If fIgnoreCase is TRUE, the names are already converted by SavExp2
  183. if(!fIgnoreCase && TargetOs == NE_WINDOWS)
  184. SbUcase(p); // Make upper case
  185. p += p[0] + sizeof(WORD) + 1; // Advance to the next name
  186. }
  187. }
  188. /*
  189. * This function converts the res- and nonresident name symbols
  190. * to uppercase (when targeting Windows). On user request it also
  191. * writes all the names to a text file, that can later be included
  192. * in the user's .def file. This frees the user from the need of
  193. * manually copying the decorated names from the .map file.
  194. */
  195. void ProcesNTables( char *pName)
  196. {
  197. FILE *f = NULL;
  198. int i;
  199. #if DEBUG_EXP
  200. fprintf(stdout, "\r\nOutput file name : %s ", psbRun);
  201. #endif
  202. if(pName[0]) // user requested export file
  203. {
  204. if(pName[0] == '.') // use the default name
  205. {
  206. for(i=0; i< _MAX_PATH; i++)
  207. {
  208. if((pName[i] = psbRun[i]) == '.')
  209. {
  210. pName[i+1] = '\0';
  211. break;
  212. }
  213. }
  214. strcat(pName, "EXP"); // the default name is 'DLLNAME'.EXP
  215. }
  216. #if DEBUG_EXP
  217. fprintf(stdout, "\r\nEXPORT FILE : %s ", pName+1);
  218. #endif
  219. if((f = fopen(pName+1, WRBIN)) == NULL)
  220. OutError(ER_openw, pName);
  221. }
  222. WriteNTable(&ResidentName, f);
  223. WriteNTable(&NonResidentName, f);
  224. fclose(f);
  225. }