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