[PEFILE_APITEST] Introduce tests that load ntoskrnl.exe and validate various section...
[reactos.git] / rostests / apitests / pefile / ntoskrnl.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test to validate section flags in ntoskrnl
5 * PROGRAMMER: Mark Jansen
6 */
7
8 #include <apitest.h>
9 #include <strsafe.h>
10
11 typedef struct KnownSections
12 {
13 const char* Name;
14 DWORD Required;
15 DWORD Disallowed;
16 } KnownSections;
17
18 static struct KnownSections g_Sections[] = {
19 {
20 ".text",
21 IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ,
22 IMAGE_SCN_MEM_DISCARDABLE
23 // optional: IMAGE_SCN_MEM_NOT_PAGED
24 },
25 {
26 ".data",
27 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE,
28 IMAGE_SCN_MEM_DISCARDABLE
29 // optional: IMAGE_SCN_MEM_NOT_PAGED
30 },
31 {
32 ".rsrc",
33 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ,
34 IMAGE_SCN_MEM_DISCARDABLE
35 },
36 {
37 ".reloc",
38 IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_READ,
39 0
40 },
41 {
42 "INIT",
43 IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ,
44 0
45 // optional?? : IMAGE_SCN_MEM_WRITE
46 },
47 { NULL, 0 },
48 };
49
50 static char* Chr2Str(DWORD value)
51 {
52 static char buf[512];
53 buf[0] = '\0';
54 #define IFX(x) if( value & IMAGE_SCN_##x )\
55 {\
56 if(buf[0]) { StringCchCatA(buf, _countof(buf), "|" ); }\
57 StringCchCatA(buf, _countof(buf), #x );\
58 value &= ~(IMAGE_SCN_##x);\
59 }
60 IFX(TYPE_NO_PAD);
61 IFX(CNT_CODE);
62 IFX(CNT_INITIALIZED_DATA);
63 IFX(CNT_UNINITIALIZED_DATA);
64 IFX(LNK_OTHER);
65 IFX(LNK_INFO);
66 IFX(LNK_REMOVE);
67 IFX(LNK_COMDAT);
68 //IFX(NO_DEFER_SPEC_EXC);
69 //IFX(GPREL);
70 IFX(MEM_FARDATA);
71 IFX(MEM_PURGEABLE);
72 IFX(MEM_16BIT);
73 IFX(MEM_LOCKED);
74 IFX(MEM_PRELOAD);
75 IFX(ALIGN_1BYTES);
76 IFX(ALIGN_2BYTES);
77 IFX(ALIGN_4BYTES);
78 IFX(ALIGN_8BYTES);
79 IFX(ALIGN_16BYTES);
80 IFX(ALIGN_32BYTES);
81 IFX(ALIGN_64BYTES);
82 //IFX(ALIGN_128BYTES);
83 //IFX(ALIGN_256BYTES);
84 //IFX(ALIGN_512BYTES);
85 //IFX(ALIGN_1024BYTES);
86 //IFX(ALIGN_2048BYTES);
87 //IFX(ALIGN_4096BYTES);
88 //IFX(ALIGN_8192BYTES);
89 IFX(LNK_NRELOC_OVFL);
90 IFX(MEM_DISCARDABLE);
91 IFX(MEM_NOT_CACHED);
92 IFX(MEM_NOT_PAGED);
93 IFX(MEM_SHARED);
94 IFX(MEM_EXECUTE);
95 IFX(MEM_READ);
96 IFX(MEM_WRITE);
97 if( value )
98 {
99 StringCchPrintfA(buf + strlen(buf), _countof(buf) - strlen(buf), "|0x%x", value);
100 }
101 return buf;
102 }
103
104
105 START_TEST(ntoskrnl_SectionFlags)
106 {
107 char buf[MAX_PATH];
108 HMODULE mod;
109 GetSystemDirectoryA(buf, _countof(buf));
110 StringCchCatA(buf, _countof(buf), "\\ntoskrnl.exe");
111
112 mod = LoadLibraryExA( buf, NULL, LOAD_LIBRARY_AS_DATAFILE );
113 if( mod != NULL )
114 {
115 // we have to take into account that a datafile is not returned at the exact address it's loaded at.
116 PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)(((size_t)mod) & (~0xf));
117 PIMAGE_NT_HEADERS nt;
118 PIMAGE_SECTION_HEADER firstSection;
119 WORD numSections, n;
120
121 if( dos->e_magic != IMAGE_DOS_SIGNATURE )
122 {
123 skip("Couldn't find ntoskrnl.exe dos header\n");
124 FreeLibrary(mod);
125 return;
126 }
127 nt = (PIMAGE_NT_HEADERS)( ((PBYTE)dos) + dos->e_lfanew );
128 if( nt->Signature != IMAGE_NT_SIGNATURE )
129 {
130 skip("Couldn't find ntoskrnl.exe nt header\n");
131 FreeLibrary(mod);
132 return;
133 }
134 firstSection = IMAGE_FIRST_SECTION(nt);
135 numSections = nt->FileHeader.NumberOfSections;
136 for( n = 0; n < numSections; ++n )
137 {
138 PIMAGE_SECTION_HEADER section = firstSection + n;
139 char name[9] = {0};
140 size_t i;
141 StringCchCopyNA(name, _countof(name), (PCSTR)section->Name, 8);
142
143 for( i = 0; g_Sections[i].Name; ++i )
144 {
145 if( !_strnicmp(name, g_Sections[i].Name, 8) )
146 {
147 if( g_Sections[i].Required )
148 {
149 DWORD Flags = g_Sections[i].Required & section->Characteristics;
150 ok(Flags == g_Sections[i].Required,
151 "Missing required Characteristics on %s: %s\n",
152 name, Chr2Str(Flags ^ g_Sections[i].Required));
153 }
154 if( g_Sections[i].Disallowed )
155 {
156 DWORD Flags = g_Sections[i].Disallowed & section->Characteristics;
157 ok(!Flags, "Disallowed section Characteristics on %s: %s\n",
158 name, Chr2Str(section->Characteristics));
159 }
160 break;
161 }
162 }
163 }
164 FreeLibrary(mod);
165 }
166 else
167 {
168 skip("Couldn't load ntoskrnl.exe as datafile\n");
169 }
170 }
171