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