- Implement simple case of RtlInsertUnicodePrefix where a new node entry needs to...
[reactos.git] / reactos / lib / rtl / image.c
1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS system libraries
3 * FILE: lib/rtl/image.c
4 * PURPOSE: Image handling functions
5 * PROGRAMMER: Eric Kohl
6 */
7
8 /* INCLUDES *****************************************************************/
9
10 #include <rtl.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /* FUNCTIONS *****************************************************************/
16
17 /*
18 * @implemented
19 */
20 PIMAGE_NT_HEADERS NTAPI
21 RtlImageNtHeader (IN PVOID BaseAddress)
22 {
23 PIMAGE_NT_HEADERS NtHeader;
24 PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)BaseAddress;
25
26 if (DosHeader && DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
27 {
28 DPRINT1("DosHeader->e_magic %x\n", DosHeader->e_magic);
29 DPRINT1("NtHeader 0x%p\n", ((ULONG_PTR)BaseAddress + DosHeader->e_lfanew));
30 }
31
32 if (DosHeader && DosHeader->e_magic == IMAGE_DOS_SIGNATURE)
33 {
34 NtHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)BaseAddress + DosHeader->e_lfanew);
35 if (NtHeader->Signature == IMAGE_NT_SIGNATURE)
36 return NtHeader;
37 }
38
39 return NULL;
40 }
41
42
43 /*
44 * @implemented
45 */
46 PVOID
47 NTAPI
48 RtlImageDirectoryEntryToData (
49 PVOID BaseAddress,
50 BOOLEAN bMappedAsImage,
51 ULONG Directory,
52 PULONG Size
53 )
54 {
55 PIMAGE_NT_HEADERS NtHeader;
56 ULONG Va;
57
58 /* Magic flag for non-mapped images. */
59 if ((ULONG_PTR)BaseAddress & 1)
60 {
61 BaseAddress = (PVOID)((ULONG_PTR)BaseAddress & ~1);
62 bMappedAsImage = FALSE;
63 }
64
65
66 NtHeader = RtlImageNtHeader (BaseAddress);
67 if (NtHeader == NULL)
68 return NULL;
69
70 if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)
71 return NULL;
72
73 Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
74 if (Va == 0)
75 return NULL;
76
77 *Size = NtHeader->OptionalHeader.DataDirectory[Directory].Size;
78
79 if (bMappedAsImage || Va < NtHeader->OptionalHeader.SizeOfHeaders)
80 return (PVOID)((ULONG_PTR)BaseAddress + Va);
81
82 /* image mapped as ordinary file, we must find raw pointer */
83 return (PVOID)RtlImageRvaToVa (NtHeader, BaseAddress, Va, NULL);
84 }
85
86
87 /*
88 * @implemented
89 */
90 PIMAGE_SECTION_HEADER
91 NTAPI
92 RtlImageRvaToSection (
93 PIMAGE_NT_HEADERS NtHeader,
94 PVOID BaseAddress,
95 ULONG Rva
96 )
97 {
98 PIMAGE_SECTION_HEADER Section;
99 ULONG Va;
100 ULONG Count;
101
102 Count = NtHeader->FileHeader.NumberOfSections;
103 Section = (PIMAGE_SECTION_HEADER)((ULONG)&NtHeader->OptionalHeader +
104 NtHeader->FileHeader.SizeOfOptionalHeader);
105 while (Count)
106 {
107 Va = Section->VirtualAddress;
108 if ((Va <= Rva) &&
109 (Rva < Va + Section->SizeOfRawData))
110 return Section;
111 Section++;
112 }
113 return NULL;
114 }
115
116
117 /*
118 * @implemented
119 */
120 ULONG
121 NTAPI
122 RtlImageRvaToVa (
123 PIMAGE_NT_HEADERS NtHeader,
124 PVOID BaseAddress,
125 ULONG Rva,
126 PIMAGE_SECTION_HEADER *SectionHeader
127 )
128 {
129 PIMAGE_SECTION_HEADER Section = NULL;
130
131 if (SectionHeader)
132 Section = *SectionHeader;
133
134 if (Section == NULL ||
135 Rva < Section->VirtualAddress ||
136 Rva >= Section->VirtualAddress + Section->SizeOfRawData)
137 {
138 Section = RtlImageRvaToSection (NtHeader, BaseAddress, Rva);
139 if (Section == NULL)
140 return 0;
141
142 if (SectionHeader)
143 *SectionHeader = Section;
144 }
145
146 return (ULONG)((ULONG_PTR)BaseAddress +
147 Rva +
148 Section->PointerToRawData -
149 (ULONG_PTR)Section->VirtualAddress);
150 }
151
152 /* EOF */