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.

466 lines
14 KiB

  1. /*++
  2. Copyright 1996 - 1997 Microsoft Corporation
  3. Module Name:
  4. file.c
  5. Abstract:
  6. This module handles all file i/o for SYMCVT. This includes the
  7. mapping of all files and establishing all file pointers for the
  8. mapped file(s).
  9. Author:
  10. Wesley A. Witt (wesw) 19-April-1993
  11. Environment:
  12. Win32, User Mode
  13. --*/
  14. #include <windows.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <stdio.h>
  18. #define _SYMCVT_SOURCE_
  19. #include "symcvt.h"
  20. static BOOL CalculateOutputFilePointers( PIMAGEPOINTERS pi, PIMAGEPOINTERS po );
  21. static BOOL CalculateInputFilePointers( PIMAGEPOINTERS p );
  22. MapInputFile (
  23. PPOINTERS p,
  24. HANDLE hFile,
  25. char * fname
  26. )
  27. /*++
  28. Routine Description:
  29. Maps the input file specified by the fname argument and saves the
  30. file handle & file pointer in the POINTERS structure.
  31. Arguments:
  32. p - Supplies pointer to a POINTERS structure
  33. hFile - OPTIONAL Supplies handle for file if already open
  34. fname - Supplies ascii string for the file name
  35. Return Value:
  36. TRUE - file mapped ok
  37. FALSE - file could not be mapped
  38. --*/
  39. {
  40. BOOL rVal = TRUE;
  41. memset( p, 0, sizeof(POINTERS) );
  42. strcpy( p->iptrs.szName, fname );
  43. if (hFile != NULL) {
  44. p->iptrs.hFile = hFile;
  45. } else {
  46. p->iptrs.hFile = CreateFileA(p->iptrs.szName,
  47. GENERIC_READ,
  48. FILE_SHARE_READ | FILE_SHARE_WRITE,
  49. NULL,
  50. OPEN_EXISTING,
  51. 0,
  52. NULL );
  53. }
  54. if (p->iptrs.hFile == INVALID_HANDLE_VALUE) {
  55. rVal = FALSE;
  56. } else {
  57. p->iptrs.fsize = GetFileSize( p->iptrs.hFile, NULL );
  58. p->iptrs.hMap = CreateFileMapping( p->iptrs.hFile,
  59. NULL,
  60. PAGE_READONLY,
  61. 0,
  62. 0,
  63. NULL
  64. );
  65. if (p->iptrs.hMap == INVALID_HANDLE_VALUE) {
  66. p->iptrs.hMap = NULL;
  67. rVal = FALSE;
  68. } else {
  69. p->iptrs.fptr = MapViewOfFile( p->iptrs.hMap,
  70. FILE_MAP_READ,
  71. 0, 0, 0 );
  72. if (p->iptrs.fptr == NULL) {
  73. CloseHandle( p->iptrs.hMap );
  74. p->iptrs.hMap = NULL;
  75. rVal = FALSE;
  76. }
  77. }
  78. }
  79. if (!hFile && p->iptrs.hFile != INVALID_HANDLE_VALUE) {
  80. CloseHandle(p->iptrs.hFile);
  81. p->iptrs.hFile = NULL;
  82. }
  83. return rVal;
  84. } /* MapInputFile() */
  85. BOOL
  86. UnMapInputFile (
  87. PPOINTERS p
  88. )
  89. /*++
  90. Routine Description:
  91. Unmaps the input file specified by the fname argument and then
  92. closes the file.
  93. Arguments:
  94. p - pointer to a POINTERS structure
  95. Return Value:
  96. TRUE - file mapped ok
  97. FALSE - file could not be mapped
  98. --*/
  99. {
  100. if ( p->iptrs.fptr ) {
  101. UnmapViewOfFile( p->iptrs.fptr );
  102. p->iptrs.fptr = NULL;
  103. }
  104. if ( p->iptrs.hMap ) {
  105. CloseHandle( p->iptrs.hMap );
  106. p->iptrs.hMap = NULL;
  107. }
  108. if (p->iptrs.hFile != NULL) {
  109. CloseHandle( p->iptrs.hFile );
  110. p->iptrs.hFile = NULL;
  111. }
  112. return TRUE;
  113. } /* UnMapInputFile() */
  114. BOOL
  115. FillInSeparateImagePointers(
  116. PIMAGEPOINTERS p
  117. )
  118. /*++
  119. Routine Description:
  120. This routine will go through the exe file and fill in the
  121. pointers needed relative to the separate debug information files
  122. Arguments:
  123. p - Supplies the structure to fill in
  124. Return Value:
  125. TRUE if successful and FALSE otherwise.
  126. --*/
  127. {
  128. int li;
  129. int numDebugDirs;
  130. PIMAGE_DEBUG_DIRECTORY pDebugDir;
  131. PIMAGE_COFF_SYMBOLS_HEADER pCoffHdr;
  132. p->sectionHdrs = (PIMAGE_SECTION_HEADER)
  133. (p->fptr + sizeof(IMAGE_SEPARATE_DEBUG_HEADER));
  134. numDebugDirs = p->sepHdr->DebugDirectorySize/sizeof(IMAGE_DEBUG_DIRECTORY);
  135. if (numDebugDirs == 0) {
  136. return FALSE;
  137. }
  138. /*
  139. * For each debug directory, determine the debug directory type
  140. * and cache any information about them.
  141. */
  142. pDebugDir = (PIMAGE_DEBUG_DIRECTORY)
  143. (p->fptr + sizeof(IMAGE_SEPARATE_DEBUG_HEADER) +
  144. p->sepHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
  145. p->sepHdr->ExportedNamesSize);
  146. for (li=0; li<numDebugDirs; li++, pDebugDir++) {
  147. if (((int) pDebugDir->Type) > p->cDebugDir) {
  148. p->cDebugDir += 10;
  149. p->rgDebugDir = realloc((char *) p->rgDebugDir,
  150. p->cDebugDir * sizeof(p->rgDebugDir[0]));
  151. memset(&p->rgDebugDir[p->cDebugDir-10], 0,
  152. 10*sizeof(p->rgDebugDir[0]));
  153. }
  154. p->rgDebugDir[pDebugDir->Type] = pDebugDir;
  155. }
  156. if (p->rgDebugDir[IMAGE_DEBUG_TYPE_COFF] != NULL) {
  157. pCoffHdr = (PIMAGE_COFF_SYMBOLS_HEADER) (p->fptr +
  158. p->rgDebugDir[IMAGE_DEBUG_TYPE_COFF]->PointerToRawData);
  159. p->AllSymbols = (PIMAGE_SYMBOL)
  160. ((char *) pCoffHdr + pCoffHdr->LvaToFirstSymbol);
  161. p->stringTable = pCoffHdr->NumberOfSymbols * IMAGE_SIZEOF_SYMBOL +
  162. (char *) p->AllSymbols;
  163. p->numberOfSymbols = pCoffHdr->NumberOfSymbols;
  164. }
  165. p->numberOfSections = p->sepHdr->NumberOfSections;
  166. return TRUE;
  167. } /* FillInSeparateImagePointers() */
  168. BOOL
  169. CalculateNtImagePointers(
  170. PIMAGEPOINTERS p
  171. )
  172. /*++
  173. Routine Description:
  174. This function reads an NT image and its associated COFF headers
  175. and file pointers and build a set of pointers into the mapped image.
  176. The pointers are all relative to the image's mapped file pointer
  177. and allow direct access to the necessary data.
  178. Arguments:
  179. p - pointer to a IMAGEPOINTERS structure
  180. Return Value:
  181. TRUE - pointers were created
  182. FALSE - pointers could not be created
  183. --*/
  184. {
  185. PIMAGE_DEBUG_DIRECTORY debugDir;
  186. PIMAGE_SECTION_HEADER sh;
  187. DWORD i, li, rva, numDebugDirs;
  188. PIMAGE_FILE_HEADER pFileHdr;
  189. PIMAGE_OPTIONAL_HEADER pOptHdr;
  190. DWORD offDebugInfo;
  191. try {
  192. /*
  193. * Based on wheither or not we find the dos (MZ) header
  194. * at the beginning of the file, attempt to get a pointer
  195. * to where the PE header is suppose to be.
  196. */
  197. p->dosHdr = (PIMAGE_DOS_HEADER) p->fptr;
  198. if (p->dosHdr->e_magic == IMAGE_DOS_SIGNATURE) {
  199. p->ntHdr = (PIMAGE_NT_HEADERS)
  200. ((DWORD)p->dosHdr->e_lfanew + p->fptr);
  201. p->fRomImage = FALSE;
  202. } else if (p->dosHdr->e_magic == IMAGE_SEPARATE_DEBUG_SIGNATURE) {
  203. p->sepHdr = (PIMAGE_SEPARATE_DEBUG_HEADER) p->fptr;
  204. p->dosHdr = NULL;
  205. p->fRomImage = FALSE;
  206. return FillInSeparateImagePointers(p);
  207. } else {
  208. p->romHdr = (PIMAGE_ROM_HEADERS) p->fptr;
  209. if (p->romHdr->FileHeader.SizeOfOptionalHeader ==
  210. IMAGE_SIZEOF_ROM_OPTIONAL_HEADER &&
  211. p->romHdr->OptionalHeader.Magic ==
  212. IMAGE_ROM_OPTIONAL_HDR_MAGIC) {
  213. //
  214. // its a rom image
  215. //
  216. p->fRomImage = TRUE;
  217. p->ntHdr = NULL;
  218. p->dosHdr = NULL;
  219. } else {
  220. p->fRomImage = FALSE;
  221. p->ntHdr = (PIMAGE_NT_HEADERS) p->fptr;
  222. p->dosHdr = NULL;
  223. p->romHdr = NULL;
  224. }
  225. }
  226. /*
  227. * What comes next must be a PE header. If not then pop out
  228. */
  229. if ( p->ntHdr ) {
  230. if ( p->dosHdr && (DWORD)p->dosHdr->e_lfanew > (DWORD)p->fsize ) {
  231. return FALSE;
  232. }
  233. if ( p->ntHdr->Signature != IMAGE_NT_SIGNATURE ) {
  234. return FALSE;
  235. }
  236. /*
  237. * We did find a PE header so start setting pointers to various
  238. * structures in the exe file.
  239. */
  240. pFileHdr = p->fileHdr = &p->ntHdr->FileHeader;
  241. pOptHdr = p->optHdr = &p->ntHdr->OptionalHeader;
  242. } else if (p->romHdr) {
  243. pFileHdr = p->fileHdr = &p->romHdr->FileHeader;
  244. pOptHdr = (PIMAGE_OPTIONAL_HEADER) &p->romHdr->OptionalHeader;
  245. p->optHdr = (PIMAGE_OPTIONAL_HEADER) &p->romHdr->OptionalHeader;
  246. } else {
  247. return FALSE;
  248. }
  249. if (!(pFileHdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {
  250. return FALSE;
  251. }
  252. if (pFileHdr->Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
  253. return(FALSE);
  254. }
  255. /*
  256. * If they exists then get a pointer to the symbol table and
  257. * the string table
  258. */
  259. if (pFileHdr->PointerToSymbolTable) {
  260. p->AllSymbols = (PIMAGE_SYMBOL)
  261. (pFileHdr->PointerToSymbolTable + p->fptr);
  262. p->stringTable = (LPSTR)((ULONG)p->AllSymbols +
  263. (IMAGE_SIZEOF_SYMBOL * pFileHdr->NumberOfSymbols));
  264. p->numberOfSymbols = pFileHdr->NumberOfSymbols;
  265. }
  266. p->numberOfSections = pFileHdr->NumberOfSections;
  267. if (p->romHdr) {
  268. sh = p->sectionHdrs = (PIMAGE_SECTION_HEADER) (p->romHdr+1);
  269. p->cDebugDir = 10;
  270. p->rgDebugDir = calloc(sizeof(IMAGE_DEBUG_DIRECTORY) * 10, 1);
  271. debugDir = 0;
  272. for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) {
  273. if (!strcmp(sh->Name, ".rdata")) {
  274. debugDir = (PIMAGE_DEBUG_DIRECTORY)(sh->PointerToRawData + p->fptr);
  275. }
  276. if (strncmp(sh->Name,".debug",8)==0) {
  277. p->debugSection = sh;
  278. }
  279. }
  280. if (debugDir) {
  281. do {
  282. if ((int)debugDir->Type > p->cDebugDir) {
  283. p->cDebugDir += 10;
  284. p->rgDebugDir = realloc((char *) p->rgDebugDir,
  285. p->cDebugDir * sizeof(p->rgDebugDir[0]));
  286. memset(&p->rgDebugDir[p->cDebugDir-10],
  287. 0,
  288. 10*sizeof(IMAGE_DEBUG_DIRECTORY));
  289. }
  290. p->rgDebugDir[debugDir->Type] = debugDir;
  291. debugDir++;
  292. } while (debugDir->Type != 0);
  293. }
  294. } else {
  295. /*
  296. * Locate the debug directory
  297. */
  298. rva =
  299. pOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
  300. numDebugDirs =
  301. pOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size /
  302. sizeof(IMAGE_DEBUG_DIRECTORY);
  303. if (numDebugDirs == 0) {
  304. return FALSE;
  305. }
  306. sh = p->sectionHdrs = IMAGE_FIRST_SECTION( p->ntHdr );
  307. /*
  308. * Find the section the debug directory is in.
  309. */
  310. for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) {
  311. if (rva >= sh->VirtualAddress &&
  312. rva < sh->VirtualAddress+sh->SizeOfRawData) {
  313. break;
  314. }
  315. }
  316. /*
  317. * For each debug directory, determine the debug directory
  318. * type and cache any information about them.
  319. */
  320. debugDir = (PIMAGE_DEBUG_DIRECTORY) ( rva - sh->VirtualAddress +
  321. sh->PointerToRawData +
  322. p->fptr );
  323. for (li=0; li<numDebugDirs; li++, debugDir++) {
  324. if (((int) debugDir->Type) > p->cDebugDir) {
  325. p->cDebugDir += 10;
  326. p->rgDebugDir = realloc((char *) p->rgDebugDir,
  327. p->cDebugDir * sizeof(p->rgDebugDir[0]));
  328. memset(&p->rgDebugDir[p->cDebugDir-10], 0,
  329. 10*sizeof(p->rgDebugDir[0]));
  330. }
  331. p->rgDebugDir[debugDir->Type] = debugDir;
  332. offDebugInfo = debugDir->AddressOfRawData;
  333. }
  334. /*
  335. * Check to see if the debug information is mapped and if
  336. * there is a section called .debug
  337. */
  338. sh = p->sectionHdrs = IMAGE_FIRST_SECTION( p->ntHdr );
  339. for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) {
  340. if ((offDebugInfo >= sh->VirtualAddress) &&
  341. (offDebugInfo < sh->VirtualAddress+sh->SizeOfRawData)) {
  342. p->debugSection = sh;
  343. break;
  344. }
  345. }
  346. }
  347. return TRUE;
  348. } except (EXCEPTION_EXECUTE_HANDLER) {
  349. return FALSE;
  350. }
  351. } /* CalcuateNtImagePointers() */