ReactOS 0.4.15-dev-7907-g95bf896
UserModeException.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for user mode exceptions
5 * COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
6 */
7
8#include "precomp.h"
9#include <pseh/pseh2.h>
10
11typedef enum _CPU_VENDOR
12{
20
23
24#define CPU_FEATURE_VMX 0x01
25#define CPU_FEATURE_HV 0x02
26
27typedef void (*PFUNC)(void);
28
29#define FL_INVALID 0
30#define FL_AMD 0x01
31#define FL_INTEL 0x02
32#define FL_CYRIX 0x04
33#define FL_VIA 0x08
34#define FL_TM 0x10
35#define FL_ANY (FL_AMD | FL_INTEL | FL_CYRIX | FL_VIA | FL_TM)
36
37#define FL_VMX 0x20
38#define FL_HV 0x40
39
40#define FL_PRIV 0x100
41#define FL_ACC 0x200
42#define FL_INVLS 0x400
43
44typedef struct _TEST_ENTRY
45{
51
52static
55{
56 INT CpuInfo[4];
57 union
58 {
59 INT ShuffledInts[3];
60 CHAR VendorString[13];
61 } Vendor;
62
63 __cpuid(CpuInfo, 0);
64 Vendor.ShuffledInts[0] = CpuInfo[1];
65 Vendor.ShuffledInts[1] = CpuInfo[3];
66 Vendor.ShuffledInts[2] = CpuInfo[2];
67 Vendor.VendorString[12] = 0;
68 trace("Vendor: %s\n", Vendor.VendorString);
69
70 if (strcmp(Vendor.VendorString, "GenuineIntel") == 0)
71 {
72 return CPU_VENDOR_INTEL;
73 }
74 else if (strcmp(Vendor.VendorString, "AuthenticAMD") == 0)
75 {
76 return CPU_VENDOR_AMD;
77 }
78 else if (strcmp(Vendor.VendorString, "CyrixInstead") == 0)
79 {
80 return CPU_VENDOR_CYRIX;
81 }
82 else if (strcmp(Vendor.VendorString, "CentaurHauls") == 0)
83 {
84 return CPU_VENDOR_VIA;
85 }
86 else if (strcmp(Vendor.VendorString, "GenuineTMx86") == 0)
87 {
89 }
90 else
91 {
92 return CPU_VENDOR_UNKNOWN;
93 }
94}
95
96static
97void
99{
100 INT CpuInfo[4];
101 ULONG Features = 0;
102
104
105 __cpuid(CpuInfo, 1);
106 if (CpuInfo[2] & (1 << 5)) Features |= CPU_FEATURE_VMX;
107 if (CpuInfo[2] & (1 << 31)) Features |= CPU_FEATURE_HV;
108 trace("CPUID 1: 0x%x, 0x%x, 0x%x, 0x%x\n", CpuInfo[0], CpuInfo[1], CpuInfo[2], CpuInfo[3]);
109
110 g_CpuFeatures = Features;
111}
112
114{
115 /* Some invalid instruction encodings */
116 { __LINE__, { 0x0F, 0x0B, 0xC3 }, 0, FL_INVALID },
117 { __LINE__, { 0x0F, 0x38, 0x0C, 0xC3 }, 0, FL_INVALID },
118#ifdef _M_AMD64
119 { __LINE__, { 0x06, 0xC3 }, 0, FL_INVALID },
120#endif
121
122 /* Privileged instructions */
123 { __LINE__, { 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // HLT
124 { __LINE__, { 0xFA, 0xC3 }, 0, FL_ANY | FL_PRIV }, // CLI
125 { __LINE__, { 0xFB, 0xC3 }, 0, FL_ANY | FL_PRIV }, // STI
126 { __LINE__, { 0x0F, 0x06, 0xC3 }, 0, FL_ANY | FL_PRIV }, // CLTS
127#ifdef _M_AMD64
128 { __LINE__, { 0x0F, 0x07, 0xC3 }, 0, FL_ANY | FL_PRIV }, // SYSRET
129#endif
130 { __LINE__, { 0x0F, 0x08, 0xC3 }, 0, FL_ANY | FL_PRIV }, // INVD
131 { __LINE__, { 0x0F, 0x09, 0xC3 }, 0, FL_ANY | FL_PRIV }, // WBINVD
132 { __LINE__, { 0x0F, 0x20, 0xC3 }, 0, FL_ANY | FL_PRIV }, // MOV CR, XXX
133 { __LINE__, { 0x0F, 0x21, 0xC3 }, 0, FL_ANY | FL_PRIV }, // MOV DR, XXX
134 { __LINE__, { 0x0F, 0x22, 0xC3 }, 0, FL_ANY | FL_PRIV }, // MOV XXX, CR
135 { __LINE__, { 0x0F, 0x23, 0xC3 }, 0, FL_ANY | FL_PRIV }, // MOV YYY, DR
136 { __LINE__, { 0x0F, 0x30, 0xC3 }, 0, FL_ANY | FL_PRIV }, // WRMSR
137 { __LINE__, { 0x0F, 0x32, 0xC3 }, 0, FL_ANY | FL_PRIV }, // RDMSR
138 { __LINE__, { 0x0F, 0x33, 0xC3 }, 0, FL_ANY | FL_PRIV }, // RDPMC
139 { __LINE__, { 0x0F, 0x35, 0xC3 }, 0, FL_ANY | FL_PRIV }, // SYSEXIT
140 { __LINE__, { 0x0F, 0x78, 0xC8, 0xC3 }, 0, FL_INTEL | FL_HV | FL_ACC }, // VMREAD EAX, ECX
141 { __LINE__, { 0x0F, 0x79, 0xC1, 0xC3 }, 0, FL_INTEL | FL_HV | FL_ACC }, // VMWRITE EAX, ECX
142 { __LINE__, { 0x0F, 0x00, 0x10, 0xC3 }, 0, FL_ANY | FL_PRIV }, // LLDT WORD PTR [EAX]
143 { __LINE__, { 0x0F, 0x00, 0x50, 0x00, 0xC3 }, 0, FL_ANY | FL_PRIV }, // LLDT WORD PTR [EAX + 0x00]
144 { __LINE__, { 0x0F, 0x00, 0x18, 0xC3 }, 0, FL_ANY | FL_PRIV }, // LTR WORD PTR [EAX]
145 { __LINE__, { 0x0F, 0x00, 0x58, 0x00, 0xC3 }, 0, FL_ANY | FL_PRIV }, // LTR WORD PTR [EAX + 0x00]
146 { __LINE__, { 0x0F, 0x01, 0xC1, 0xC3 }, 0, FL_INTEL | FL_HV }, // VMCALL
147 { __LINE__, { 0x0F, 0x01, 0xC2, 0xC3 }, 0, FL_INTEL | FL_HV | FL_ACC }, // VMLAUNCH
148 { __LINE__, { 0x0F, 0x01, 0xC3, 0xC3 }, 0, FL_INTEL | FL_HV | FL_ACC }, // VMRESUME
149 { __LINE__, { 0x0F, 0x01, 0xC4, 0xC3 }, 0, FL_INTEL | FL_HV | FL_ACC }, // VMXOFF
150 { __LINE__, { 0x0F, 0x01, 0xC8, 0xC3 }, 0, FL_INVALID }, // MONITOR
151 { __LINE__, { 0x0F, 0x01, 0xC9, 0xC3 }, 0, FL_INVALID }, // MWAIT
152 // { __LINE__, { 0x0F, 0x01, 0xD1, 0xC3 }, 0, FL_ANY | FL_PRIV }, // XSETBV FIXME: privileged or access violation?
153#ifdef _M_AMD64
154 { __LINE__, { 0x0F, 0x01, 0xF8, 0xC3 }, 0, FL_ANY | FL_PRIV }, // SWAPGS
155#endif
156 { __LINE__, { 0x0F, 0x01, 0x10, 0xC3 }, 0, FL_ANY | FL_PRIV }, // LGDT [EAX]
157 { __LINE__, { 0x0F, 0x01, 0x18, 0xC3 }, 0, FL_ANY | FL_PRIV }, // LIDT [EAX]
158 { __LINE__, { 0x0F, 0x01, 0x30, 0xC3 }, 0, FL_ANY | FL_PRIV }, // LMSW [EAX]
159#ifdef _M_AMD64 // Gives access violation on Test WHS for some reason
160 { __LINE__, { 0x0F, 0x01, 0x38, 0xC3 }, 0, FL_ANY | FL_PRIV }, // INVLPG [EAX]
161#endif
162 { __LINE__, { 0x66, 0x0F, 0x38, 0x80, 0x01, 0xC3 }, 0, FL_INTEL | FL_HV | FL_ACC }, // INVEPT EAX,OWORD PTR [ECX]
163 { __LINE__, { 0x66, 0x0F, 0x38, 0x81, 0x01, 0xC3 }, 0, FL_INTEL | FL_HV | FL_ACC }, // INVVPID EAX,OWORD PTR [ECX]
164 { __LINE__, { 0x0F, 0xC7, 0x31, 0xC3 }, 0, FL_INTEL | FL_HV | FL_ACC }, // VMPTRLD QWORD PTR [ECX]
165 { __LINE__, { 0x66, 0x0F, 0xC7, 0x31, 0xC3 }, 0, FL_INTEL | FL_HV | FL_ACC }, // VMCLEAR QWORD PTR [ECX]
166 { __LINE__, { 0xF3, 0x0F, 0xC7, 0x31, 0xC3 }, 0, FL_INVALID }, // VMXON QWORD PTR [ECX]
167 { __LINE__, { 0x0F, 0xC7, 0xE0, 0xC3 }, 0, FL_INVALID }, // VMPTRST
168
169 /* Test prefixes */
170 { __LINE__, { 0x26, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // ES HLT
171 { __LINE__, { 0x2E, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // CS: HLT
172 { __LINE__, { 0x36, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // SS: HLT
173 { __LINE__, { 0x3E, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // DS: HLT
174 { __LINE__, { 0x64, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // FS: HLT
175 { __LINE__, { 0x65, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // GS: HLT
176 { __LINE__, { 0x66, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // DATA HLT
177 { __LINE__, { 0x67, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // ADDR HLT
178 { __LINE__, { 0xF0, 0xF4, 0xC3 }, 0, FL_ANY | FL_INVLS | FL_PRIV }, // LOCK HLT
179 { __LINE__, { 0xF2, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // REP HLT
180 { __LINE__, { 0xF3, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // REPZ HLT
181 { __LINE__, { 0x9B, 0xF4, 0xC3 }, 1, FL_ANY | FL_PRIV }, // WAIT // not a prefix
182#ifdef _M_AMD64
183 { __LINE__, { 0x40, 0xF4, 0xC3 }, 0, FL_ANY | FL_PRIV }, // REX HLT
184#endif
185 { __LINE__, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0xC3 }, 0, FL_ANY }, // This one is OK
186#ifdef _M_AMD64
187 { __LINE__, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0xC3 }, 0, FL_ANY | FL_ACC }, // Too many prefixes
188#else
189 { __LINE__, { 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0xC3 }, 0, FL_INVALID }, // Too many prefixes
190#endif
191 { __LINE__, { 0xF0, 0x90, 0xC3 }, 0, FL_INVLS }, // LOCK NOP
192 { __LINE__, { 0xF0, 0x83, 0x0C, 0x24, 0x00, 0xC3 }, 0, FL_ANY }, // LOCK OR DWORD PTR [ESP], 0x0
193 { __LINE__, { 0x3E, 0x66, 0x67, 0xF0, 0xF3, 0xF4, 0xC3 }, 0, FL_ANY | FL_INVLS | FL_PRIV }, // DS: DATA ADDR LOCK REPZ HLT
194#ifdef _M_AMD64
195 /* Check non-canonical address access (causes a #GP) */
196 { __LINE__, { 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xC3 }, 0, FL_ANY | FL_ACC }, // MOV AL, [0x1000000000000000]
197#endif
198
199};
200
202 PVOID RwxMemory,
204{
205 PEXCEPTION_POINTERS ExcPtrs;
206 EXCEPTION_RECORD ExceptionRecord;
207 NTSTATUS ExpectedStatus, Status = STATUS_SUCCESS;
208 PFUNC Func = (PFUNC)RwxMemory;
209 ULONG Flags;
210
211 RtlZeroMemory(&ExceptionRecord, sizeof(ExceptionRecord));
212
213 RtlCopyMemory(RwxMemory,
214 TestEntry->InstructionBytes,
215 sizeof(TestEntry->InstructionBytes));
216
218 {
219 Func();
220 }
222 ExceptionRecord = *ExcPtrs->ExceptionRecord,
224 {
226 }
227 _SEH2_END;
228
229 Flags = TestEntry->Flags;
230#ifdef _M_IX86
231 if (Flags & FL_INVLS)
232 {
233 ExpectedStatus = STATUS_INVALID_LOCK_SEQUENCE;
234 }
235 else
236#endif
237 if (((g_CpuVendor == CPU_VENDOR_INTEL) && !(Flags & FL_INTEL)) ||
238 ((g_CpuVendor == CPU_VENDOR_AMD) && !(Flags & FL_AMD)) ||
240 ((g_CpuVendor == CPU_VENDOR_VIA) && !(Flags & FL_VIA)))
241 {
242 ExpectedStatus = STATUS_ILLEGAL_INSTRUCTION;
243 }
244 else if (((Flags & FL_VMX) && !(g_CpuFeatures & CPU_FEATURE_VMX)) ||
246 {
247 ExpectedStatus = STATUS_ILLEGAL_INSTRUCTION;
248 }
249 else if (Flags & FL_PRIV)
250 {
251 ExpectedStatus = STATUS_PRIVILEGED_INSTRUCTION;
252 }
253 else if (Flags & FL_ACC)
254 {
255 ExpectedStatus = STATUS_ACCESS_VIOLATION;
256 }
257 else
258 {
259 ExpectedStatus = STATUS_SUCCESS;
260 }
261
262 ok_hex_(__FILE__, TestEntry->Line, Status, ExpectedStatus);
263 ok_hex_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionCode, Status);
264 ok_hex_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionFlags, 0);
265 ok_ptr_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionRecord, NULL);
266
267 if (Status == STATUS_SUCCESS)
268 {
269 ok_ptr_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionAddress, NULL);
270 }
271 else
272 {
273 ok_ptr_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionAddress, (PUCHAR)Func + TestEntry->ExpectedAddressOffset);
274 }
275
277 {
278 ok_dec_(__FILE__, TestEntry->Line, ExceptionRecord.NumberParameters, 2);
279 ok_size_t_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionInformation[0], 0);
280 ok_size_t_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionInformation[1], (LONG_PTR)-1);
281 }
282 else
283 {
284 ok_dec_(__FILE__, TestEntry->Line, ExceptionRecord.NumberParameters, 0);
285#if 0 // FIXME: These are inconsistent between Windows versions (simply uninitialized?)
286 ok_size_t_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionInformation[0], 0);
287 ok_size_t_(__FILE__, TestEntry->Line, ExceptionRecord.ExceptionInformation[1], 0);
288#endif
289 }
290}
291
292static
293void
295{
296 PVOID RwxMemory;
297 ULONG i;
298
299 /* Allocate a page of RWX memory */
300 RwxMemory = VirtualAlloc(NULL,
301 PAGE_SIZE,
304 ok(RwxMemory != NULL, "Failed to allocate RWX memory!\n");
305 if (RwxMemory == NULL)
306 {
307 return;
308 }
309
310 for (i = 0; i < ARRAYSIZE(TestEntries); i++)
311 {
313 }
314
315 /* Clean up */
316 VirtualFree(RwxMemory, 0, MEM_RELEASE);
317}
318
319START_TEST(UserModeException)
320{
322
324}
#define ok_hex_(expression, result)
static void TestEntry(const ENTRY *pEntry)
TEST_ENTRY TestEntries[]
#define FL_VIA
static void DetermineCpuFeatures(void)
#define CPU_FEATURE_VMX
#define FL_AMD
#define FL_ACC
_CPU_VENDOR
@ CPU_VENDOR_CYRIX
@ CPU_VENDOR_TRANSMETA
@ CPU_VENDOR_INTEL
@ CPU_VENDOR_UNKNOWN
@ CPU_VENDOR_AMD
@ CPU_VENDOR_VIA
struct _TEST_ENTRY TEST_ENTRY
CPU_VENDOR g_CpuVendor
void(* PFUNC)(void)
#define FL_INTEL
#define FL_ANY
#define CPU_FEATURE_HV
#define FL_INVLS
enum _CPU_VENDOR CPU_VENDOR
static void Test_InstructionFaults(void)
#define FL_CYRIX
#define FL_VMX
#define FL_HV
#define FL_PRIV
#define FL_INVALID
static CPU_VENDOR DetermineCpuVendor(void)
struct _TEST_ENTRY * PTEST_ENTRY
void Test_SingleInstruction(PVOID RwxMemory, PTEST_ENTRY TestEntry)
ULONG g_CpuFeatures
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
Definition: intrin_ppc.h:682
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define MEM_RESERVE
Definition: nt_native.h:1314
#define MEM_RELEASE
Definition: nt_native.h:1316
#define MEM_COMMIT
Definition: nt_native.h:1313
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define STATUS_ILLEGAL_INSTRUCTION
Definition: ntstatus.h:266
#define STATUS_PRIVILEGED_INSTRUCTION
Definition: ntstatus.h:386
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_INVALID_LOCK_SEQUENCE
Definition: ntstatus.h:267
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
void(* Func)(int)
#define ok_size_t_(file, line, expression, result)
Definition: test.h:967
#define ok_ptr_(file, line, expression, result)
Definition: test.h:958
#define ok_dec_(file, line, expression, result)
Definition: test.h:949
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: cmd.c:13
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
PVOID ExceptionAddress
Definition: compat.h:211
ULONG Line
UCHAR InstructionBytes[64]
ULONG ExpectedAddressOffset
ULONG Flags
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:65
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:119
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175