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