1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: lib/rossym/fromfile.c 5 * PURPOSE: Creating rossym info from a file 6 * 7 * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com) 8 */ 9 10 #include <ntdef.h> 11 #include <reactos/rossym.h> 12 #include "rossympriv.h" 13 #include <ntimage.h> 14 15 #define NDEBUG 16 #include <debug.h> 17 18 BOOLEAN 19 RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo) 20 { 21 IMAGE_DOS_HEADER DosHeader; 22 IMAGE_NT_HEADERS NtHeaders; 23 PIMAGE_SECTION_HEADER SectionHeaders, SectionHeader; 24 unsigned SectionIndex; 25 char SectionName[IMAGE_SIZEOF_SHORT_NAME]; 26 ROSSYM_HEADER RosSymHeader; 27 28 /* Load DOS header */ 29 if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER))) 30 { 31 DPRINT1("Failed to read DOS header\n"); 32 return FALSE; 33 } 34 if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader)) 35 { 36 DPRINT1("Image doesn't have a valid DOS header\n"); 37 return FALSE; 38 } 39 40 /* Load NT headers */ 41 if (! RosSymSeekFile(FileContext, DosHeader.e_lfanew)) 42 { 43 DPRINT1("Failed seeking to NT headers\n"); 44 return FALSE; 45 } 46 if (! RosSymReadFile(FileContext, &NtHeaders, sizeof(IMAGE_NT_HEADERS))) 47 { 48 DPRINT1("Failed to read NT headers\n"); 49 return FALSE; 50 } 51 if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders)) 52 { 53 DPRINT1("Image doesn't have a valid PE header\n"); 54 return FALSE; 55 } 56 57 /* Load section headers */ 58 if (! RosSymSeekFile(FileContext, (char *) IMAGE_FIRST_SECTION(&NtHeaders) - 59 (char *) &NtHeaders + DosHeader.e_lfanew)) 60 { 61 DPRINT1("Failed seeking to section headers\n"); 62 return FALSE; 63 } 64 SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections 65 * sizeof(IMAGE_SECTION_HEADER)); 66 if (NULL == SectionHeaders) 67 { 68 DPRINT1("Failed to allocate memory for %u section headers\n", 69 NtHeaders.FileHeader.NumberOfSections); 70 return FALSE; 71 } 72 if (! RosSymReadFile(FileContext, SectionHeaders, 73 NtHeaders.FileHeader.NumberOfSections 74 * sizeof(IMAGE_SECTION_HEADER))) 75 { 76 RosSymFreeMem(SectionHeaders); 77 DPRINT1("Failed to read section headers\n"); 78 return FALSE; 79 } 80 81 /* Search for the section header */ 82 strncpy(SectionName, ROSSYM_SECTION_NAME, IMAGE_SIZEOF_SHORT_NAME); 83 SectionHeader = SectionHeaders; 84 for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections; SectionIndex++) 85 { 86 if (0 == memcmp(SectionName, SectionHeader->Name, IMAGE_SIZEOF_SHORT_NAME)) 87 { 88 break; 89 } 90 SectionHeader++; 91 } 92 if (NtHeaders.FileHeader.NumberOfSections <= SectionIndex) 93 { 94 RosSymFreeMem(SectionHeaders); 95 DPRINT("No %s section found\n", ROSSYM_SECTION_NAME); 96 return FALSE; 97 } 98 99 /* Load rossym header */ 100 if (! RosSymSeekFile(FileContext, SectionHeader->PointerToRawData)) 101 { 102 RosSymFreeMem(SectionHeaders); 103 DPRINT1("Failed seeking to section data\n"); 104 return FALSE; 105 } 106 RosSymFreeMem(SectionHeaders); 107 if (! RosSymReadFile(FileContext, &RosSymHeader, sizeof(ROSSYM_HEADER))) 108 { 109 DPRINT1("Failed to read rossym header\n"); 110 return FALSE; 111 } 112 if (RosSymHeader.SymbolsOffset < sizeof(ROSSYM_HEADER) 113 || RosSymHeader.StringsOffset < RosSymHeader.SymbolsOffset + RosSymHeader.SymbolsLength 114 || 0 != (RosSymHeader.SymbolsLength % sizeof(ROSSYM_ENTRY))) 115 { 116 DPRINT1("Invalid ROSSYM_HEADER\n"); 117 return FALSE; 118 } 119 120 *RosSymInfo = RosSymAllocMem(sizeof(ROSSYM_INFO) - sizeof(ROSSYM_HEADER) 121 + RosSymHeader.StringsOffset + RosSymHeader.StringsLength + 1); 122 if (NULL == *RosSymInfo) 123 { 124 DPRINT1("Failed to allocate memory for rossym\n"); 125 return FALSE; 126 } 127 (*RosSymInfo)->Symbols = (PROSSYM_ENTRY)((char *) *RosSymInfo + sizeof(ROSSYM_INFO) 128 - sizeof(ROSSYM_HEADER) + RosSymHeader.SymbolsOffset); 129 (*RosSymInfo)->SymbolsCount = RosSymHeader.SymbolsLength / sizeof(ROSSYM_ENTRY); 130 (*RosSymInfo)->Strings = (PCHAR) *RosSymInfo + sizeof(ROSSYM_INFO) - sizeof(ROSSYM_HEADER) 131 + RosSymHeader.StringsOffset; 132 (*RosSymInfo)->StringsLength = RosSymHeader.StringsLength; 133 if (! RosSymReadFile(FileContext, *RosSymInfo + 1, 134 RosSymHeader.StringsOffset + RosSymHeader.StringsLength 135 - sizeof(ROSSYM_HEADER))) 136 { 137 DPRINT1("Failed to read rossym headers\n"); 138 return FALSE; 139 } 140 /* Make sure the last string is null terminated, we allocated an extra byte for that */ 141 (*RosSymInfo)->Strings[(*RosSymInfo)->StringsLength] = '\0'; 142 143 return TRUE; 144 } 145 146 /* EOF */ 147