Leaked source code of windows server 2003
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.

260 lines
7.2 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. {
  55. BYTE *pb = REALLOC(pArray->rgByte,pArray->byteMax);
  56. if (!pb)
  57. Fatal(ER_memovf);
  58. pArray->rgByte = pb;
  59. }
  60. ASSERT (pArray->byteMax > pArray->byteMac + size);
  61. }
  62. idx = pArray->byteMac;
  63. pTmp = &(pArray->rgByte[idx]);
  64. FMEMCPY(pTmp, pBuf, size);
  65. pArray->byteMac += size;
  66. return(idx);
  67. }
  68. void WriteByteArray(DYNBYTEARRAY *pArray)
  69. {
  70. WriteExe(pArray->rgByte, pArray->byteMac);
  71. }
  72. //
  73. // Functions operating on dynamic word arrays
  74. //
  75. void InitWordArray(DYNWORDARRAY *pArray)
  76. {
  77. pArray->wordMac = 0;
  78. pArray->wordMax = DEF_WORD_ARR_SIZE;
  79. pArray->rgWord = (WORD FAR *) GetMem(DEF_WORD_ARR_SIZE * sizeof(WORD));
  80. }
  81. void FreeWordArray(DYNWORDARRAY *pArray)
  82. {
  83. FFREE(pArray->rgWord);
  84. pArray->wordMac = 0;
  85. pArray->wordMax = 0;
  86. }
  87. WORD WordArrayPut(DYNWORDARRAY *pArray, WORD val)
  88. {
  89. WORD FAR *pTmp;
  90. WORD idx;
  91. if ((WORD) (pArray->wordMac + 1) >= pArray->wordMax)
  92. {
  93. // Realloc array
  94. pTmp = (WORD FAR *) GetMem((pArray->wordMax << 1) * sizeof(WORD));
  95. FMEMCPY(pTmp, pArray->rgWord, pArray->wordMac * sizeof(WORD));
  96. FFREE(pArray->rgWord);
  97. pArray->rgWord = pTmp;
  98. pArray->wordMax <<= 1;
  99. }
  100. idx = pArray->wordMac;
  101. pArray->rgWord[idx] = val;
  102. pArray->wordMac++;
  103. return(idx);
  104. }
  105. void WriteWordArray(DYNWORDARRAY *pArray)
  106. {
  107. WriteExe(pArray->rgWord, pArray->wordMac*sizeof(WORD));
  108. }
  109. //
  110. // IMPORT/EXPORT tables
  111. //
  112. DYNBYTEARRAY ResidentName;
  113. DYNBYTEARRAY NonResidentName;
  114. DYNBYTEARRAY ImportedName;
  115. DYNWORDARRAY ModuleRefTable;
  116. DYNBYTEARRAY EntryTable;
  117. //
  118. // Functions adding names to tables
  119. //
  120. void AddName(DYNBYTEARRAY *pTable, BYTE *sbName, WORD ord)
  121. {
  122. WORD cb;
  123. cb = sbName[0] + 1 + sizeof(WORD);
  124. if ((WORD)(0xFFFE - pTable->byteMac) < cb)
  125. {
  126. if (pTable == &ResidentName)
  127. Fatal(ER_resovf);
  128. else
  129. Fatal(ER_nresovf);
  130. }
  131. ByteArrayPut(pTable, (WORD) (sbName[0] + 1), sbName);
  132. ByteArrayPut(pTable, sizeof(WORD), (BYTE *) &ord);
  133. }
  134. WORD AddImportedName(BYTE *sbName)
  135. {
  136. if ((WORD) (0xfffe - ImportedName.byteMac) < (WORD) (sbName[0] + 1))
  137. Fatal(ER_inamovf);
  138. return(ByteArrayPut(&ImportedName, (WORD) (sbName[0] + 1), sbName));
  139. }
  140. //
  141. // Function adding entries to the Entry Table
  142. //
  143. WORD AddEntry(BYTE *entry, WORD size)
  144. {
  145. if ((WORD)(EntryTable.byteMax + size) < EntryTable.byteMax)
  146. Fatal(ER_etovf);
  147. return (ByteArrayPut(&EntryTable, size, entry));
  148. }
  149. /*
  150. * This function writes either the resident or nonresident names table
  151. * to a file f. If targeting Windows it also converts the names
  152. * to upper case.
  153. */
  154. void WriteNTable(DYNBYTEARRAY *pArray, FILE *f)
  155. {
  156. BYTE *p;
  157. WORD *pOrd; // points to the ordinal
  158. WORD Ord; // ordinal value
  159. int i;
  160. p = pArray->rgByte;
  161. #if DEBUG_EXP
  162. for( i = 0; i<pArray->byteMac; i++)
  163. {
  164. fprintf(stdout, "\r\n%d : %d(%c) ", i, *(p+i), *(p+i));
  165. fflush(stdout);
  166. }
  167. #endif
  168. while(p[0]) // Until names left
  169. {
  170. if(f) // If writing to a file
  171. {
  172. pOrd = (WORD*)(p+p[0]+1);
  173. Ord = *pOrd;
  174. #if DEBUG_EXP
  175. fprintf(stdout, "\r\np[0]=%d, p[1]=%d Ord = %d", p[0], p[1], Ord);
  176. #endif
  177. if(Ord) // Don't output module name/description
  178. {
  179. *pOrd = 0;
  180. fprintf(f, "\r\n %s @%d", p+1, Ord);
  181. *pOrd = Ord;
  182. }
  183. }
  184. // Windows loader requires both res-and nonresident name tables in uppercase
  185. // If fIgnoreCase is TRUE, the names are already converted by SavExp2
  186. if(!fIgnoreCase && TargetOs == NE_WINDOWS)
  187. SbUcase(p); // Make upper case
  188. p += p[0] + sizeof(WORD) + 1; // Advance to the next name
  189. }
  190. }
  191. /*
  192. * This function converts the res- and nonresident name symbols
  193. * to uppercase (when targeting Windows). On user request it also
  194. * writes all the names to a text file, that can later be included
  195. * in the user's .def file. This frees the user from the need of
  196. * manually copying the decorated names from the .map file.
  197. */
  198. void ProcesNTables( char *pName)
  199. {
  200. FILE *f = NULL;
  201. int i;
  202. #if DEBUG_EXP
  203. fprintf(stdout, "\r\nOutput file name : %s ", psbRun);
  204. #endif
  205. if(pName[0]) // user requested export file
  206. {
  207. if(pName[0] == '.') // use the default name
  208. {
  209. for(i=0; i< _MAX_PATH; i++)
  210. {
  211. if((pName[i] = psbRun[i]) == '.')
  212. {
  213. pName[i+1] = '\0';
  214. break;
  215. }
  216. }
  217. strcat(pName, "EXP"); // the default name is 'DLLNAME'.EXP
  218. }
  219. #if DEBUG_EXP
  220. fprintf(stdout, "\r\nEXPORT FILE : %s ", pName+1);
  221. #endif
  222. if((f = fopen(pName+1, WRBIN)) == NULL)
  223. OutError(ER_openw, pName);
  224. }
  225. WriteNTable(&ResidentName, f);
  226. WriteNTable(&NonResidentName, f);
  227. fclose(f);
  228. }