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 START_TEST(RtlImageRvaToVa)
11 {
12     PIMAGE_NT_HEADERS NtHeader;
13     PIMAGE_SECTION_HEADER Section;
14     ULONG NumberOfSections;
15     ULONG ImageSize;
16     PUCHAR BaseAddress;
17     PVOID Va;
18     PIMAGE_SECTION_HEADER OutSection;
19     IMAGE_SECTION_HEADER DummySection;
20     struct
21     {
22         ULONG Rva;
23         ULONG VaOffset;
24         ULONG SectionIndex;
25     } Tests[] =
26     {
27         {      0,      0, 0 },
28         {  0xfff,      0, 0 },
29         { 0x1000, 0x3000, 0 },
30         { 0x1001, 0x3001, 0 },
31         { 0x1fff, 0x3fff, 0 },
32         { 0x2000,      0, 0 },
33         { 0x2fff,      0, 0 },
34         { 0x3000, 0x4000, 3 },
35         { 0x3fff, 0x4fff, 3 },
36         { 0x4000, 0x5000, 3 },
37         { 0x4fff, 0x5fff, 3 },
38         { 0x5000,      0, 0 },
39         { 0x5fff,      0, 0 },
40         { 0x6000,      0, 0 },
41         { 0x6fff,      0, 0 },
42         { 0x7000, 0x7000, 5 },
43         { 0x7fff, 0x7fff, 5 },
44         { 0x8000, 0x9000, 7 },
45         { 0x8fff, 0x9fff, 7 },
46         { 0x9000, 0x8000, 6 },
47         { 0x9fff, 0x8fff, 6 },
48     };
49     ULONG i;
50 
51     NumberOfSections = 8;
52     ImageSize = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader.DataDirectory) +
53                 NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
54     NtHeader = AllocateGuarded(ImageSize);
55     if (!NtHeader)
56     {
57         skip("Could not allocate %lu bytes\n", ImageSize);
58         return;
59     }
60 
61     RtlFillMemory(NtHeader, ImageSize, 0xDD);
62     NtHeader->FileHeader.NumberOfSections = NumberOfSections;
63     NtHeader->FileHeader.SizeOfOptionalHeader = FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, DataDirectory);
64     Section = (PIMAGE_SECTION_HEADER)((PUCHAR)&NtHeader->OptionalHeader +
65                                       NtHeader->FileHeader.SizeOfOptionalHeader);
66     Section[0].VirtualAddress = 0x1000;
67     Section[0].Misc.VirtualSize = 0x1000;
68     Section[0].SizeOfRawData = 0x1000;
69     Section[0].PointerToRawData = 0x3000;
70     Section[1].VirtualAddress = 0x2000;
71     Section[1].Misc.VirtualSize = 0;
72     Section[1].SizeOfRawData = 0;
73     Section[1].PointerToRawData = 0x4000;
74     Section[2].VirtualAddress = 0x2000;
75     Section[2].Misc.VirtualSize = 0x1000;
76     Section[2].SizeOfRawData = 0;
77     Section[2].PointerToRawData = 0x4000;
78     Section[3].VirtualAddress = 0x3000;
79     Section[3].Misc.VirtualSize = 0x1000;
80     Section[3].SizeOfRawData = 0x2000;
81     Section[3].PointerToRawData = 0x4000;
82     Section[4].VirtualAddress = 0x4000;
83     Section[4].Misc.VirtualSize = 0x2000;
84     Section[4].SizeOfRawData = 0x1000;
85     Section[4].PointerToRawData = 0x6000;
86     Section[5].VirtualAddress = 0x7000;
87     Section[5].Misc.VirtualSize = 0x1000;
88     Section[5].SizeOfRawData = 0x1000;
89     Section[5].PointerToRawData = 0x7000;
90     Section[6].VirtualAddress = 0x9000;
91     Section[6].Misc.VirtualSize = 0x1000;
92     Section[6].SizeOfRawData = 0x1000;
93     Section[6].PointerToRawData = 0x8000;
94     Section[7].VirtualAddress = 0x8000;
95     Section[7].Misc.VirtualSize = 0x1000;
96     Section[7].SizeOfRawData = 0x1000;
97     Section[7].PointerToRawData = 0x9000;
98     DummySection.VirtualAddress = 0xf000;
99     DummySection.Misc.VirtualSize = 0xf000;
100     DummySection.SizeOfRawData = 0xf000;
101     DummySection.PointerToRawData = 0xf000;
102 
103     BaseAddress = (PUCHAR)0x2000000;
104 
105     StartSeh()
106         RtlImageRvaToVa(NULL, NULL, 0, NULL);
107     EndSeh(STATUS_ACCESS_VIOLATION);
108 
109     Va = RtlImageRvaToVa(NtHeader, NULL, 0, NULL);
110     ok(Va == NULL, "Va = %p\n", Va);
111 
112     Va = RtlImageRvaToVa(NtHeader, BaseAddress, 0, NULL);
113     ok(Va == NULL, "Va = %p\n", Va);
114 
115     OutSection = NULL;
116     Va = RtlImageRvaToVa(NtHeader, BaseAddress, 0, &OutSection);
117     ok(Va == NULL, "Va = %p\n", Va);
118     ok(OutSection == NULL, "OutSection = %p\n", OutSection);
119 
120     OutSection = (PVOID)1;
121     StartSeh()
122         RtlImageRvaToVa(NtHeader, BaseAddress, 0, &OutSection);
123     EndSeh(STATUS_ACCESS_VIOLATION);
124 
125     for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
126     {
127         /* Section = not specified */
128         StartSeh()
129             Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, NULL);
130         EndSeh(STATUS_SUCCESS);
131         if (Tests[i].VaOffset == 0)
132             ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
133         else
134             ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
135 
136         /* Section = NULL */
137         OutSection = NULL;
138         StartSeh()
139             Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, &OutSection);
140         EndSeh(STATUS_SUCCESS);
141         if (Tests[i].VaOffset == 0)
142         {
143             ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
144             ok(OutSection == NULL, "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
145         }
146         else
147         {
148             ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
149             ok(OutSection == &Section[Tests[i].SectionIndex], "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
150         }
151 
152         /* Section = first section */
153         OutSection = Section;
154         StartSeh()
155             Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, &OutSection);
156         EndSeh(STATUS_SUCCESS);
157         if (Tests[i].VaOffset == 0)
158         {
159             ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
160             ok(OutSection == Section, "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
161         }
162         else
163         {
164             ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
165             ok(OutSection == &Section[Tests[i].SectionIndex], "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
166         }
167 
168         /* Section = dummy section */
169         OutSection = &DummySection;
170         StartSeh()
171             Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, &OutSection);
172         EndSeh(STATUS_SUCCESS);
173         if (Tests[i].VaOffset == 0)
174         {
175             ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
176             ok(OutSection == &DummySection, "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
177         }
178         else
179         {
180             ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va);
181             ok(OutSection == &Section[Tests[i].SectionIndex], "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section);
182         }
183     }
184 
185     FreeGuarded(NtHeader);
186 }
187