9d15c58e717efc3ac3116d0206f1ee9275a972ed
[reactos.git] / modules / rostests / apitests / ntdll / RtlImageRvaToVa.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for RtlImageRvaToVa
5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 static
11 PVOID
12 AllocateGuarded(
13 _In_ SIZE_T SizeRequested)
14 {
15 NTSTATUS Status;
16 SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE);
17 PVOID VirtualMemory = NULL;
18 PCHAR StartOfBuffer;
19
20 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS);
21
22 if (!NT_SUCCESS(Status))
23 return NULL;
24
25 Size -= PAGE_SIZE;
26 if (Size)
27 {
28 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE);
29 if (!NT_SUCCESS(Status))
30 {
31 Size = 0;
32 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
33 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
34 return NULL;
35 }
36 }
37
38 StartOfBuffer = VirtualMemory;
39 StartOfBuffer += Size - SizeRequested;
40
41 return StartOfBuffer;
42 }
43
44 static
45 VOID
46 FreeGuarded(
47 _In_ PVOID Pointer)
48 {
49 NTSTATUS Status;
50 PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer);
51 SIZE_T Size = 0;
52
53 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
54 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
55 }
56
57 START_TEST(RtlImageRvaToVa)
58 {
59 PIMAGE_NT_HEADERS NtHeader;
60 PIMAGE_SECTION_HEADER Section;
61 ULONG NumberOfSections;
62 ULONG ImageSize;
63 PUCHAR BaseAddress;
64 PVOID Va;
65 PIMAGE_SECTION_HEADER OutSection;
66 IMAGE_SECTION_HEADER DummySection;
67 struct
68 {
69 ULONG Rva;
70 ULONG VaOffset;
71 ULONG SectionIndex;
72 } Tests[] =
73 {
74 { 0, 0, 0 },
75 { 0xfff, 0, 0 },
76 { 0x1000, 0x3000, 0 },
77 { 0x1001, 0x3001, 0 },
78 { 0x1fff, 0x3fff, 0 },
79 { 0x2000, 0, 0 },
80 { 0x2fff, 0, 0 },
81 { 0x3000, 0x4000, 3 },
82 { 0x3fff, 0x4fff, 3 },
83 { 0x4000, 0x5000, 3 },
84 { 0x4fff, 0x5fff, 3 },
85 { 0x5000, 0, 0 },
86 { 0x5fff, 0, 0 },
87 { 0x6000, 0, 0 },
88 { 0x6fff, 0, 0 },
89 { 0x7000, 0x7000, 5 },
90 { 0x7fff, 0x7fff, 5 },
91 { 0x8000, 0x9000, 7 },
92 { 0x8fff, 0x9fff, 7 },
93 { 0x9000, 0x8000, 6 },
94 { 0x9fff, 0x8fff, 6 },
95 };
96 ULONG i;
97
98 NumberOfSections = 8;
99 ImageSize = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader.DataDirectory) +
100 NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
101 NtHeader = AllocateGuarded(ImageSize);
102 if (!NtHeader)
103 {
104 skip("Could not allocate %lu bytes\n", ImageSize);
105 return;
106 }
107
108 RtlFillMemory(NtHeader, ImageSize, 0xDD);
109 NtHeader->FileHeader.NumberOfSections = NumberOfSections;
110 NtHeader->FileHeader.SizeOfOptionalHeader = FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, DataDirectory);
111 Section = (PIMAGE_SECTION_HEADER)((PUCHAR)&NtHeader->OptionalHeader +
112 NtHeader->FileHeader.SizeOfOptionalHeader);
113 Section[0].VirtualAddress = 0x1000;
114 Section[0].Misc.VirtualSize = 0x1000;
115 Section[0].SizeOfRawData = 0x1000;
116 Section[0].PointerToRawData = 0x3000;
117 Section[1].VirtualAddress = 0x2000;
118 Section[1].Misc.VirtualSize = 0;
119 Section[1].SizeOfRawData = 0;
120 Section[1].PointerToRawData = 0x4000;
121 Section[2].VirtualAddress = 0x2000;
122 Section[2].Misc.VirtualSize = 0x1000;
123 Section[2].SizeOfRawData = 0;
124 Section[2].PointerToRawData = 0x4000;
125 Section[3].VirtualAddress = 0x3000;
126 Section[3].Misc.VirtualSize = 0x1000;
127 Section[3].SizeOfRawData = 0x2000;
128 Section[3].PointerToRawData = 0x4000;
129 Section[4].VirtualAddress = 0x4000;
130 Section[4].Misc.VirtualSize = 0x2000;
131 Section[4].SizeOfRawData = 0x1000;
132 Section[4].PointerToRawData = 0x6000;
133 Section[5].VirtualAddress = 0x7000;
134 Section[5].Misc.VirtualSize = 0x1000;
135 Section[5].SizeOfRawData = 0x1000;
136 Section[5].PointerToRawData = 0x7000;
137 Section[6].VirtualAddress = 0x9000;
138 Section[6].Misc.VirtualSize = 0x1000;
139 Section[6].SizeOfRawData = 0x1000;
140 Section[6].PointerToRawData = 0x8000;
141 Section[7].VirtualAddress = 0x8000;
142 Section[7].Misc.VirtualSize = 0x1000;
143 Section[7].SizeOfRawData = 0x1000;
144 Section[7].PointerToRawData = 0x9000;
145 DummySection.VirtualAddress = 0xf000;
146 DummySection.Misc.VirtualSize = 0xf000;
147 DummySection.SizeOfRawData = 0xf000;
148 DummySection.PointerToRawData = 0xf000;
149
150 BaseAddress = (PUCHAR)0x2000000;
151
152 StartSeh()
153 RtlImageRvaToVa(NULL, NULL, 0, NULL);
154 EndSeh(STATUS_ACCESS_VIOLATION);
155
156 Va = RtlImageRvaToVa(NtHeader, NULL, 0, NULL);
157 ok(Va == NULL, "Va = %p\n", Va);
158
159 Va = RtlImageRvaToVa(NtHeader, BaseAddress, 0, NULL);
160 ok(Va == NULL, "Va = %p\n", Va);
161
162 OutSection = NULL;
163 Va = RtlImageRvaToVa(NtHeader, BaseAddress, 0, &OutSection);
164 ok(Va == NULL, "Va = %p\n", Va);
165 ok(OutSection == NULL, "OutSection = %p\n", OutSection);
166
167 OutSection = (PVOID)1;
168 StartSeh()
169 RtlImageRvaToVa(NtHeader, BaseAddress, 0, &OutSection);
170 EndSeh(STATUS_ACCESS_VIOLATION);
171
172 for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
173 {
174 /* Section = not specified */
175 StartSeh()
176 Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, NULL);
177 EndSeh(STATUS_SUCCESS);
178 if (Tests[i].VaOffset == 0)
179 ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
180 else
181 ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
182
183 /* Section = NULL */
184 OutSection = NULL;
185 StartSeh()
186 Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, &OutSection);
187 EndSeh(STATUS_SUCCESS);
188 if (Tests[i].VaOffset == 0)
189 {
190 ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
191 ok(OutSection == NULL, "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
192 }
193 else
194 {
195 ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
196 ok(OutSection == &Section[Tests[i].SectionIndex], "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
197 }
198
199 /* Section = first section */
200 OutSection = Section;
201 StartSeh()
202 Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, &OutSection);
203 EndSeh(STATUS_SUCCESS);
204 if (Tests[i].VaOffset == 0)
205 {
206 ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
207 ok(OutSection == Section, "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
208 }
209 else
210 {
211 ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
212 ok(OutSection == &Section[Tests[i].SectionIndex], "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
213 }
214
215 /* Section = dummy section */
216 OutSection = &DummySection;
217 StartSeh()
218 Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, &OutSection);
219 EndSeh(STATUS_SUCCESS);
220 if (Tests[i].VaOffset == 0)
221 {
222 ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
223 ok(OutSection == &DummySection, "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
224 }
225 else
226 {
227 ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
228 ok(OutSection == &Section[Tests[i].SectionIndex], "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
229 }
230 }
231
232 FreeGuarded(NtHeader);
233 }