75 // |
75 // |
76 // Converts unicode string to narrow string |
76 // Converts unicode string to narrow string |
77 // |
77 // |
78 { |
78 { |
79 return WideCharToMultiByte(Data.iCodePage,0,aUnicode,-1,aNarrow,aLength,"@",NULL); |
79 return WideCharToMultiByte(Data.iCodePage,0,aUnicode,-1,aNarrow,aLength,"@",NULL); |
|
80 } |
|
81 |
|
82 LOCAL_C TInt GetSectionsSize(const IMAGE_NT_HEADERS32* aBase) |
|
83 // |
|
84 // Iterates through the section headers at the start of an image and determines the minimum amount of the |
|
85 // PE file that must be read in in order to examine the sections themselves |
|
86 // |
|
87 { |
|
88 // List of sections are are interested in examining |
|
89 const BYTE* sectionNames[] = |
|
90 { |
|
91 KWin32SectionName_Symbian, KWin32SectionName_Import, KWin32SectionName_EpocData, KWin32SectionName_EpocBss, |
|
92 KWin32SectionName_Text, KWin32SectionName_RData, KWin32SectionName_NmdExpData |
|
93 }; |
|
94 |
|
95 // Get a ptr to the first section header in preparation for examining all the section headers |
|
96 DWORD maxOffset = 0; |
|
97 const IMAGE_NT_HEADERS32* ntHead = aBase; |
|
98 const IMAGE_SECTION_HEADER* imgHead = (const IMAGE_SECTION_HEADER*) ((TUint8*) &ntHead->OptionalHeader + ntHead->FileHeader.SizeOfOptionalHeader); |
|
99 const IMAGE_SECTION_HEADER* end = imgHead + ntHead->FileHeader.NumberOfSections; |
|
100 |
|
101 for (; imgHead < end; ++imgHead) |
|
102 { |
|
103 TBool SectionUsed = EFalse; |
|
104 |
|
105 // Go through each of the sections that we need to examine and see if the current section is in the list |
|
106 for (TInt index = 0; index < (sizeof(sectionNames) / sizeof(BYTE*)); ++index) |
|
107 { |
|
108 if (memcmp(imgHead->Name, sectionNames[index], IMAGE_SIZEOF_SHORT_NAME)==0) |
|
109 SectionUsed = ETrue; |
|
110 } |
|
111 |
|
112 // If the current section is one we are interested in, calculate its offset in the raw file and add its size; |
|
113 // this gives us the minimum amount of the file to be mapped in order to examine this section and all those |
|
114 // preceding it |
|
115 if (SectionUsed) |
|
116 { |
|
117 if ((imgHead->PointerToRawData + imgHead->SizeOfRawData) > maxOffset) |
|
118 { |
|
119 maxOffset = (imgHead->PointerToRawData + imgHead->SizeOfRawData); |
|
120 } |
|
121 } |
|
122 } |
|
123 |
|
124 return(maxOffset); |
80 } |
125 } |
81 |
126 |
82 template <TUint S> |
127 template <TUint S> |
83 struct Buf8 |
128 struct Buf8 |
84 { |
129 { |
808 if (!iModule) |
853 if (!iModule) |
809 { |
854 { |
810 if (!iMapping) |
855 if (!iMapping) |
811 return LastError(); |
856 return LastError(); |
812 |
857 |
813 iBase = MapViewOfFile(iMapping, FILE_MAP_READ, 0, 0, 0); |
858 // First we need to read in the PE file's image headers, which consist of a 4 byte signature, the file header |
|
859 // containing general information and up to 96 section headers. Map this amount of the file into memory so |
|
860 // that we can examine it and calculate the minimum size of the sections themselves that need to be mapped into |
|
861 // memory in order to examine the actual sections |
|
862 SIZE_T headersSize = (sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + (96 * sizeof(IMAGE_OPTIONAL_HEADER))); |
|
863 iBase = MapViewOfFile(iMapping, FILE_MAP_READ, 0, 0, headersSize); |
|
864 |
|
865 if (iBase) |
|
866 { |
|
867 // Scan through the section headers and determine the minimum amount of the file to be mapped into memory |
|
868 // in order for us to safely examine the sections, and map the file into memory. We do this rather than |
|
869 // map the entire PE file into memory because with full debug information, DLLs can be anything up to 100 MB!!! |
|
870 TInt sectionsSize = GetSectionsSize(NtHeader()); |
|
871 |
|
872 // Before remapping the file with its new size, unmap it. While one would think that it is safe to |
|
873 // increase the size of the file's mapping it is not, and doing so triggers behaviour in Windows that |
|
874 // results in quickly using up all available virtual memory address space! |
|
875 if (UnmapViewOfFile(iBase)) |
|
876 { |
|
877 iBase = MapViewOfFile(iMapping, FILE_MAP_READ, 0, 0, sectionsSize); |
|
878 } |
|
879 else |
|
880 { |
|
881 iBase = NULL; |
|
882 } |
|
883 } |
814 |
884 |
815 if (!iBase) |
885 if (!iBase) |
816 { |
886 { |
817 CloseHandle(iMapping); |
887 CloseHandle(iMapping); |
818 iMapping = 0; |
888 iMapping = 0; |