ReactOS 0.4.16-dev-2207-geb15453
virtual.c
Go to the documentation of this file.
1/*
2 * Unit test suite for Virtual* family of APIs.
3 *
4 * Copyright 2004 Dmitry Timoshkov
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdarg.h>
22#include <stdio.h>
23
24#include "ntstatus.h"
25#define WIN32_NO_STATUS
26#include "windef.h"
27#include "winbase.h"
28#include "winnt.h"
29#include "winternl.h"
30#include "winerror.h"
31#include "winuser.h"
32#include "excpt.h"
33#include "wine/test.h"
34
35#define NUM_THREADS 4
36#define MAPPING_SIZE 0x100000
37
41static UINT (WINAPI *pGetWriteWatch)(DWORD,LPVOID,SIZE_T,LPVOID*,ULONG_PTR*,ULONG*);
42static UINT (WINAPI *pResetWriteWatch)(LPVOID,SIZE_T);
43static NTSTATUS (WINAPI *pNtAreMappedFilesTheSame)(PVOID,PVOID);
44static NTSTATUS (WINAPI *pNtCreateSection)(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *,
46static NTSTATUS (WINAPI *pNtMapViewOfSection)(HANDLE, HANDLE, PVOID *, ULONG_PTR, SIZE_T, const LARGE_INTEGER *, SIZE_T *, ULONG, ULONG, ULONG);
47static DWORD (WINAPI *pNtUnmapViewOfSection)(HANDLE, PVOID);
48static NTSTATUS (WINAPI *pNtQuerySection)(HANDLE, SECTION_INFORMATION_CLASS, void *, SIZE_T, SIZE_T *);
49static PVOID (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG, PVECTORED_EXCEPTION_HANDLER);
50static ULONG (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID);
51static BOOL (WINAPI *pGetProcessDEPPolicy)(HANDLE, LPDWORD, PBOOL);
52static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
53static NTSTATUS (WINAPI *pNtProtectVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG *);
54static NTSTATUS (WINAPI *pNtReadVirtualMemory)(HANDLE,const void *,void *,SIZE_T, SIZE_T *);
55static NTSTATUS (WINAPI *pNtWriteVirtualMemory)(HANDLE, void *, const void *, SIZE_T, SIZE_T *);
56#ifndef __REACTOS__ // TODO: Enable when kernelbase is fixed. ROSTESTS-414
57static BOOL (WINAPI *pPrefetchVirtualMemory)(HANDLE, ULONG_PTR, PWIN32_MEMORY_RANGE_ENTRY, ULONG);
58#endif
59
60/* ############################### */
61
62static HANDLE create_target_process(const char *arg)
63{
64 char **argv;
65 char cmdline[MAX_PATH];
67 BOOL ret;
68 STARTUPINFOA si = { 0 };
69 si.cb = sizeof(si);
70
72 sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
74 ok(ret, "error: %lu\n", GetLastError());
76 ok(ret, "error %lu\n", GetLastError());
77 return pi.hProcess;
78}
79
80static void test_VirtualAllocEx(void)
81{
82 const unsigned int alloc_size = 1<<15;
83 char *src, *dst;
84 SIZE_T bytes_written = 0, bytes_read = 0, i;
85 void *addr1, *addr2;
86 BOOL b, ret;
87 DWORD old_prot;
91
92 /* Same process */
94 ok(!!addr1, "Failed to allocated, error %lu.\n", GetLastError());
95 ret = VirtualFreeEx(NULL, addr1, 0, MEM_RELEASE);
96 ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Unexpected value %d, error %lu.\n", ret, GetLastError());
98 ok(!addr2 && GetLastError() == ERROR_INVALID_HANDLE, "Unexpected value %p, error %lu.\n", addr2, GetLastError());
100 ok(ret, "Unexpected value %d, error %lu.\n", ret, GetLastError());
101
103 ok(hProcess != NULL, "Can't start process\n");
104
105 SetLastError(0xdeadbeef);
106 addr1 = VirtualAllocEx(hProcess, NULL, alloc_size, MEM_COMMIT,
108 ok(addr1 != NULL, "VirtualAllocEx error %lu\n", GetLastError());
109
110 src = VirtualAlloc( NULL, alloc_size, MEM_COMMIT, PAGE_READWRITE );
111 dst = VirtualAlloc( NULL, alloc_size, MEM_COMMIT, PAGE_READWRITE );
112 for (i = 0; i < alloc_size; i++)
113 src[i] = i & 0xff;
114
115 b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
116 ok(b && (bytes_written == alloc_size), "%Iu bytes written\n",
117 bytes_written);
118 b = ReadProcessMemory(hProcess, addr1, dst, alloc_size, &bytes_read);
119 ok(b && (bytes_read == alloc_size), "%Iu bytes read\n", bytes_read);
120 ok(!memcmp(src, dst, alloc_size), "Data from remote process differs\n");
121 bytes_written = 0xdeadbeef;
122 status = pNtWriteVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_written );
123 ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
124 ok( bytes_written == alloc_size, "%Iu bytes written\n", bytes_written );
125 bytes_read = 0xdeadbeef;
126 memset( dst, 0, alloc_size );
127 status = pNtReadVirtualMemory( hProcess, addr1, dst, alloc_size, &bytes_read );
128 ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
129 ok( bytes_read == alloc_size, "%Iu bytes read\n", bytes_read );
130 ok(!memcmp(src, dst, alloc_size), "Data from remote process differs\n");
131
132 /* test 0 length */
133 bytes_written = 0xdeadbeef;
134 b = WriteProcessMemory(hProcess, addr1, src, 0, &bytes_written);
135 ok((b && !bytes_written) || broken(!b && GetLastError() == ERROR_INVALID_PARAMETER), "write failed: %lu\n", GetLastError());
136 bytes_read = 0xdeadbeef;
137 b = ReadProcessMemory(hProcess, addr1, src, 0, &bytes_read);
138 ok(b && !bytes_read, "read failed: %lu\n", GetLastError());
139 bytes_written = 0xdeadbeef;
140 status = pNtWriteVirtualMemory( hProcess, addr1, src, 0, &bytes_written );
141 ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
142 ok( bytes_written == 0, "%Iu bytes written\n", bytes_written );
143 bytes_read = 0xdeadbeef;
144 status = pNtReadVirtualMemory( hProcess, addr1, src, 0, &bytes_read );
145 ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
146 ok( !bytes_read, "%Iu bytes read\n", bytes_read );
147
148 /* test invalid source buffers */
149
150 b = VirtualProtect( src + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot );
151 ok( b, "VirtualProtect failed error %lu\n", GetLastError() );
152 bytes_written = 0xdeadbeef;
153 b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
154 ok( !b, "WriteProcessMemory succeeded\n" );
156 GetLastError() == ERROR_PARTIAL_COPY, /* vista */
157 "wrong error %lu\n", GetLastError() );
158 ok( bytes_written == 0, "%Iu bytes written\n", bytes_written );
159 bytes_read = 0xdeadbeef;
160 b = ReadProcessMemory(hProcess, addr1, src, alloc_size, &bytes_read);
161 ok( !b, "ReadProcessMemory succeeded\n" );
163 GetLastError() == ERROR_PARTIAL_COPY, /* win10 v1607+ */
164 "wrong error %lu\n", GetLastError() );
166 ok( bytes_read == 0, "%Iu bytes read\n", bytes_read );
167 else
168 ok( bytes_read == 0x2000, "%Iu bytes read\n", bytes_read );
169 bytes_written = 0xdeadbeef;
170 status = pNtWriteVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_written );
171 ok( status == STATUS_PARTIAL_COPY, "wrong status %lx\n", status );
172 ok( bytes_written == 0, "%Iu bytes written\n", bytes_written );
173 bytes_read = 0xdeadbeef;
174 status = pNtReadVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_read );
175 ok( status == STATUS_PARTIAL_COPY || status == STATUS_ACCESS_VIOLATION, "wrong status %lx\n", status );
176 ok( bytes_read == (status == STATUS_PARTIAL_COPY ? 0x2000 : 0), "%Iu bytes read\n", bytes_read );
177
178 b = VirtualProtect( src, 0x2000, PAGE_NOACCESS, &old_prot );
179 ok( b, "VirtualProtect failed error %lu\n", GetLastError() );
180 bytes_written = 0xdeadbeef;
181 b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
182 ok( !b, "WriteProcessMemory succeeded\n" );
184 GetLastError() == ERROR_PARTIAL_COPY, /* vista */
185 "wrong error %lu\n", GetLastError() );
186 ok( bytes_written == 0, "%Iu bytes written\n", bytes_written );
187 bytes_read = 0xdeadbeef;
188 b = ReadProcessMemory(hProcess, addr1, src, alloc_size, &bytes_read);
189 ok( !b, "ReadProcessMemory succeeded\n" );
191 GetLastError() == ERROR_PARTIAL_COPY, /* win10 v1607+ */
192 "wrong error %lu\n", GetLastError() );
193 ok( bytes_read == 0, "%Iu bytes read\n", bytes_read );
194 bytes_written = 0xdeadbeef;
195 status = pNtWriteVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_written );
196 ok( status == STATUS_PARTIAL_COPY, "wrong status %lx\n", status );
197 ok( bytes_written == 0, "%Iu bytes written\n", bytes_written );
198 bytes_read = 0xdeadbeef;
199 status = pNtReadVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_read );
200 ok( status == STATUS_PARTIAL_COPY || status == STATUS_ACCESS_VIOLATION, "wrong status %lx\n", status );
201 ok( bytes_read == 0, "%Iu bytes read\n", bytes_read );
202 b = VirtualProtect( src, alloc_size, PAGE_READWRITE, &old_prot );
203 ok( b, "VirtualProtect failed error %lu\n", GetLastError() );
204
205 /* test readonly buffers */
206
207 b = VirtualProtectEx( hProcess, addr1, alloc_size, PAGE_READONLY, &old_prot );
208 ok( b, "VirtualProtectEx, error %lu\n", GetLastError() );
209 bytes_written = 0xdeadbeef;
210 b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
211 ok( !b, "WriteProcessMemory succeeded\n" );
212 if (!b) ok( GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError() );
213 ok( bytes_written == 0xdeadbeef, "%Iu bytes written\n", bytes_written );
214 status = pNtWriteVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_written );
217 "wrong status %lx\n", status );
219 ok( bytes_written == 0, "%Iu bytes written\n", bytes_written );
220
221 b = VirtualProtectEx( hProcess, addr1, alloc_size, PAGE_EXECUTE_READ, &old_prot );
222 ok( b, "VirtualProtectEx, error %lu\n", GetLastError() );
223 bytes_written = 0xdeadbeef;
224 b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
225 ok( b, "WriteProcessMemory failed\n" );
226 ok( bytes_written == alloc_size, "%Iu bytes written\n", bytes_written );
227 bytes_written = 0xdeadbeef;
228 status = pNtWriteVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_written );
231 "wrong status %lx\n", status );
233 ok( bytes_written == 0, "%Iu bytes written\n", bytes_written );
234
235 b = VirtualProtectEx( hProcess, addr1, 0x2000, PAGE_EXECUTE_READWRITE, &old_prot );
236 ok( b, "VirtualProtectEx, error %lu\n", GetLastError() );
237 bytes_written = 0xdeadbeef;
238 b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
240 ok( !b || broken(b), /* <= win10 1507 */ "WriteProcessMemory succeeded\n" );
241 bytes_written = 0xdeadbeef;
242 status = pNtWriteVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_written );
244 ok( status == STATUS_PARTIAL_COPY || broken(status == STATUS_SUCCESS), /* <= win10 1507 */
245 "wrong status %lx\n", status );
246 ok( bytes_written == (status ? 0x2000 : alloc_size), "%Iu bytes written\n", bytes_written );
247
248 b = VirtualProtectEx( hProcess, (char *)addr1 + 0x2000, alloc_size - 0x2000, PAGE_READONLY, &old_prot );
249 ok( b, "VirtualProtectEx, error %lu\n", GetLastError() );
250 bytes_written = 0xdeadbeef;
251 b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
253 ok( !b || broken(b), /* <= win10 1507 */ "WriteProcessMemory succeeded\n" );
254 status = pNtWriteVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_written );
256 ok( status == STATUS_PARTIAL_COPY || broken(status == STATUS_SUCCESS), /* <= win10 1507 */
257 "wrong status %lx\n", status );
258 ok( bytes_written == (status ? 0x2000 : alloc_size), "%Iu bytes written\n", bytes_written );
259
262
263 /*
264 * The following tests parallel those in test_VirtualAlloc()
265 */
266
267 SetLastError(0xdeadbeef);
269 ok(addr1 == NULL, "VirtualAllocEx should fail on zero-sized allocation\n");
271 "got %lu, expected ERROR_INVALID_PARAMETER\n", GetLastError());
272
273 addr1 = VirtualAllocEx(hProcess, 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS);
274 ok(addr1 != NULL, "VirtualAllocEx failed\n");
275
276 /* test a not committed memory */
277 memset(&info, 'q', sizeof(info));
278 ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info)) == sizeof(info), "VirtualQueryEx failed\n");
279 ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
280 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
281 ok(info.AllocationProtect == PAGE_NOACCESS, "%lx != PAGE_NOACCESS\n", info.AllocationProtect);
282 ok(info.RegionSize == 0x10000, "%Ix != 0x10000\n", info.RegionSize);
283 ok(info.State == MEM_RESERVE, "%lx != MEM_RESERVE\n", info.State);
284 ok(info.Protect == 0, "%lx != PAGE_NOACCESS\n", info.Protect);
285 ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type);
286
287 SetLastError(0xdeadbeef);
288 ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
289 "VirtualProtectEx should fail on a not committed memory\n");
291 "got %lu, expected ERROR_INVALID_ADDRESS\n", GetLastError());
292
293 addr2 = VirtualAllocEx(hProcess, addr1, 0x1000, MEM_COMMIT, PAGE_NOACCESS);
294 ok(addr1 == addr2, "VirtualAllocEx failed\n");
295
296 /* test a committed memory */
297 ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info)) == sizeof(info),
298 "VirtualQueryEx failed\n");
299 ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
300 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
301 ok(info.AllocationProtect == PAGE_NOACCESS, "%lx != PAGE_NOACCESS\n", info.AllocationProtect);
302 ok(info.RegionSize == 0x1000, "%Ix != 0x1000\n", info.RegionSize);
303 ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
304 /* this time NT reports PAGE_NOACCESS as well */
305 ok(info.Protect == PAGE_NOACCESS, "%lx != PAGE_NOACCESS\n", info.Protect);
306 ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type);
307
308 /* this should fail, since not the whole range is committed yet */
309 SetLastError(0xdeadbeef);
310 ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
311 "VirtualProtectEx should fail on a not committed memory\n");
313 "got %lu, expected ERROR_INVALID_ADDRESS\n", GetLastError());
314
315 old_prot = 0;
316 ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtectEx failed\n");
317 ok(old_prot == PAGE_NOACCESS, "wrong old protection: got %04lx instead of PAGE_NOACCESS\n", old_prot);
318
319 old_prot = 0;
320 ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtectEx failed\n");
321 ok(old_prot == PAGE_READONLY, "wrong old protection: got %04lx instead of PAGE_READONLY\n", old_prot);
322
323 ok(!VirtualFreeEx(hProcess, addr1, 0x10000, 0),
324 "VirtualFreeEx should fail with type 0\n");
326 "got %lu, expected ERROR_INVALID_PARAMETER\n", GetLastError());
327
328 ok(VirtualFreeEx(hProcess, addr1, 0x10000, MEM_DECOMMIT), "VirtualFreeEx failed\n");
329
330 /* if the type is MEM_RELEASE, size must be 0 */
332 "VirtualFreeEx should fail\n");
334 "got %lu, expected ERROR_INVALID_PARAMETER\n", GetLastError());
335
336 ok(VirtualFreeEx(hProcess, addr1, 0, MEM_RELEASE), "VirtualFreeEx failed\n");
337
340}
341
342static void test_VirtualAlloc(void)
343{
344 void *addr1, *addr2;
345 DWORD old_prot;
347
348 SetLastError(0xdeadbeef);
349 addr1 = VirtualAlloc(0, 0, MEM_RESERVE, PAGE_NOACCESS);
350 ok(addr1 == NULL, "VirtualAlloc should fail on zero-sized allocation\n");
352 "got %ld, expected ERROR_INVALID_PARAMETER\n", GetLastError());
353
354 addr1 = VirtualAlloc(0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS);
355 ok(addr1 != NULL, "VirtualAlloc failed\n");
356
357 /* test a not committed memory */
358 ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
359 "VirtualQuery failed\n");
360 ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
361 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
362 ok(info.AllocationProtect == PAGE_NOACCESS, "%lx != PAGE_NOACCESS\n", info.AllocationProtect);
363 ok(info.RegionSize == 0x10000, "%Ix != 0x10000\n", info.RegionSize);
364 ok(info.State == MEM_RESERVE, "%lx != MEM_RESERVE\n", info.State);
365 ok(info.Protect == 0, "%lx != PAGE_NOACCESS\n", info.Protect);
366 ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type);
367
368 SetLastError(0xdeadbeef);
369 ok(!VirtualProtect(addr1, 0xFFFC, PAGE_READONLY, &old_prot),
370 "VirtualProtect should fail on a not committed memory\n");
372 "got %ld, expected ERROR_INVALID_ADDRESS\n", GetLastError());
373
374 addr2 = VirtualAlloc(addr1, 0x1000, MEM_COMMIT, PAGE_NOACCESS);
375 ok(addr1 == addr2, "VirtualAlloc failed\n");
376
377 /* test a committed memory */
378 ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
379 "VirtualQuery failed\n");
380 ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
381 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
382 ok(info.AllocationProtect == PAGE_NOACCESS, "%lx != PAGE_NOACCESS\n", info.AllocationProtect);
383 ok(info.RegionSize == 0x1000, "%Ix != 0x1000\n", info.RegionSize);
384 ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
385 /* this time NT reports PAGE_NOACCESS as well */
386 ok(info.Protect == PAGE_NOACCESS, "%lx != PAGE_NOACCESS\n", info.Protect);
387 ok(info.Type == MEM_PRIVATE, "%lx != MEM_PRIVATE\n", info.Type);
388
389 /* this should fail, since not the whole range is committed yet */
390 SetLastError(0xdeadbeef);
391 ok(!VirtualProtect(addr1, 0xFFFC, PAGE_READONLY, &old_prot),
392 "VirtualProtect should fail on a not committed memory\n");
394 "got %ld, expected ERROR_INVALID_ADDRESS\n", GetLastError());
395
396 ok(VirtualProtect(addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtect failed\n");
397 ok(old_prot == PAGE_NOACCESS,
398 "wrong old protection: got %04lx instead of PAGE_NOACCESS\n", old_prot);
399
400 ok(VirtualProtect(addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtect failed\n");
401 ok(old_prot == PAGE_READONLY,
402 "wrong old protection: got %04lx instead of PAGE_READONLY\n", old_prot);
403
404 ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
405 "VirtualQuery failed\n");
406 ok(info.RegionSize == 0x1000, "%Ix != 0x1000\n", info.RegionSize);
407 ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
408 ok(info.Protect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.Protect);
409 memset( addr1, 0x55, 20 );
410 ok( *(DWORD *)addr1 == 0x55555555, "wrong data %lx\n", *(DWORD *)addr1 );
411
412 addr2 = VirtualAlloc( addr1, 0x1000, MEM_RESET, PAGE_NOACCESS );
413 ok( addr2 == addr1, "VirtualAlloc failed err %lu\n", GetLastError() );
414 ok( *(DWORD *)addr1 == 0x55555555 || *(DWORD *)addr1 == 0, "wrong data %lx\n", *(DWORD *)addr1 );
415 ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
416 "VirtualQuery failed\n");
417 ok(info.RegionSize == 0x1000, "%Ix != 0x1000\n", info.RegionSize);
418 ok(info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State);
419 ok(info.Protect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.Protect);
420
421 addr2 = VirtualAlloc( (char *)addr1 + 0x1000, 0x1000, MEM_RESET, PAGE_NOACCESS );
422 ok( (char *)addr2 == (char *)addr1 + 0x1000, "VirtualAlloc failed\n" );
423
424 ok(VirtualQuery(addr2, &info, sizeof(info)) == sizeof(info),
425 "VirtualQuery failed\n");
426 ok(info.RegionSize == 0xf000, "%Ix != 0xf000\n", info.RegionSize);
427 ok(info.State == MEM_RESERVE, "%lx != MEM_RESERVE\n", info.State);
428 ok(info.Protect == 0, "%lx != 0\n", info.Protect);
429
430 addr2 = VirtualAlloc( (char *)addr1 + 0xf000, 0x2000, MEM_RESET, PAGE_NOACCESS );
431 ok( !addr2, "VirtualAlloc failed\n" );
432 ok( GetLastError() == ERROR_INVALID_ADDRESS, "wrong error %lu\n", GetLastError() );
433
434 /* invalid protection values */
435 SetLastError(0xdeadbeef);
436 addr2 = VirtualAlloc(NULL, 0x1000, MEM_RESERVE, 0);
437 ok(!addr2, "VirtualAlloc succeeded\n");
438 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError());
439
440 SetLastError(0xdeadbeef);
441 addr2 = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, 0);
442 ok(!addr2, "VirtualAlloc succeeded\n");
443 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError());
444
445 SetLastError(0xdeadbeef);
446 addr2 = VirtualAlloc(addr1, 0x1000, MEM_COMMIT, PAGE_READONLY | PAGE_EXECUTE);
447 ok(!addr2, "VirtualAlloc succeeded\n");
448 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError());
449
450 SetLastError(0xdeadbeef);
451 ok(!VirtualProtect(addr1, 0x1000, PAGE_READWRITE | PAGE_EXECUTE_WRITECOPY, &old_prot),
452 "VirtualProtect succeeded\n");
453 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError());
454
455 SetLastError(0xdeadbeef);
456 ok(!VirtualProtect(addr1, 0x1000, 0, &old_prot), "VirtualProtect succeeded\n");
457 ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError());
458
459 SetLastError(0xdeadbeef);
460 ok(!VirtualFree(addr1, 0x10000, 0), "VirtualFree should fail with type 0\n");
462 "got %ld, expected ERROR_INVALID_PARAMETER\n", GetLastError());
463
464 SetLastError(0xdeadbeef);
465 ok(!VirtualFree(addr1, 0, MEM_FREE), "VirtualFree should fail with type MEM_FREE\n");
467 "got %ld, expected ERROR_INVALID_PARAMETER\n", GetLastError());
468
469 ok(VirtualFree(addr1, 0x10000, MEM_DECOMMIT), "VirtualFree failed\n");
470
471 /* if the type is MEM_RELEASE, size must be 0 */
472 ok(!VirtualFree(addr1, 1, MEM_RELEASE), "VirtualFree should fail\n");
474 "got %ld, expected ERROR_INVALID_PARAMETER\n", GetLastError());
475
476 ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
477
478 /* PAGE_NOCACHE cannot be set per page in recent Windows */
480 ok( addr1 != NULL, "VirtualAlloc failed\n");
481 ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
482 ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
483 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
484 ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE),
485 "wrong protect %lx\n", info.AllocationProtect);
486 ok(info.RegionSize == 0x2000, "wrong size %Ix\n", info.RegionSize);
487 ok(info.State == MEM_COMMIT, "wrong state %lx\n", info.State);
488 ok(info.Protect == (PAGE_READWRITE | PAGE_NOCACHE), "wrong protect %lx\n", info.Protect);
489 ok(info.Type == MEM_PRIVATE, "wrong type %lx\n", info.Type);
490
491 ok(VirtualProtect(addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtect failed\n");
492 ok( old_prot == (PAGE_READWRITE | PAGE_NOCACHE), "wrong protect %lx\n", old_prot );
493 ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
494 ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
495 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
496 ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE),
497 "wrong protect %lx\n", info.AllocationProtect);
498 ok(info.RegionSize == 0x2000 || broken(info.RegionSize == 0x1000),
499 "wrong size %Ix\n", info.RegionSize);
500 ok(info.State == MEM_COMMIT, "wrong state %lx\n", info.State);
501 ok(info.Protect == (PAGE_READWRITE | PAGE_NOCACHE) || broken(info.Protect == PAGE_READWRITE),
502 "wrong protect %lx\n", info.Protect);
503 ok(info.Type == MEM_PRIVATE, "wrong type %lx\n", info.Type);
504
505 ok(VirtualProtect(addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtect failed\n");
506 ok( old_prot == (PAGE_READWRITE | PAGE_NOCACHE) || broken(old_prot == PAGE_READWRITE),
507 "wrong protect %lx\n", old_prot );
508 ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
509 ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
510 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
511 ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE),
512 "wrong protect %lx\n", info.AllocationProtect);
513 ok(info.RegionSize == 0x1000, "wrong size %Ix\n", info.RegionSize);
514 ok(info.State == MEM_COMMIT, "wrong state %lx\n", info.State);
515 ok(info.Protect == (PAGE_READONLY | PAGE_NOCACHE) || broken(info.Protect == PAGE_READONLY),
516 "wrong protect %lx\n", info.Protect);
517 ok(info.Type == MEM_PRIVATE, "wrong type %lx\n", info.Type);
518
519 ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
520
521 addr1 = VirtualAlloc( NULL, 0x2000, MEM_COMMIT, PAGE_READWRITE );
522 ok( addr1 != NULL, "VirtualAlloc failed\n");
523 ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
524 ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
525 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
526 ok(info.AllocationProtect == PAGE_READWRITE,
527 "wrong protect %lx\n", info.AllocationProtect);
528 ok(info.RegionSize == 0x2000, "wrong size %Ix\n", info.RegionSize);
529 ok(info.State == MEM_COMMIT, "wrong state %lx\n", info.State);
530 ok(info.Protect == PAGE_READWRITE, "wrong protect %lx\n", info.Protect);
531 ok(info.Type == MEM_PRIVATE, "wrong type %lx\n", info.Type);
532
533 ok(VirtualProtect(addr1, 0x1000, PAGE_READONLY | PAGE_NOCACHE, &old_prot), "VirtualProtect failed\n");
534 ok( old_prot == PAGE_READWRITE, "wrong protect %lx\n", old_prot );
535 ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info), "VirtualQuery failed\n");
536 ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
537 ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
538 ok(info.AllocationProtect == PAGE_READWRITE, "wrong protect %lx\n", info.AllocationProtect);
539 ok(info.RegionSize == 0x1000, "wrong size %Ix\n", info.RegionSize);
540 ok(info.State == MEM_COMMIT, "wrong state %lx\n", info.State);
541 ok(info.Protect == PAGE_READONLY || broken(info.Protect == (PAGE_READONLY | PAGE_NOCACHE)),
542 "wrong protect %lx\n", info.Protect);
543 ok(info.Type == MEM_PRIVATE, "wrong type %lx\n", info.Type);
544
545 ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
546
547 /* memory returned by VirtualAlloc should be aligned to 64k */
549 ok(addr1 != NULL, "VirtualAlloc failed\n");
550 ok(!((ULONG_PTR)addr1 & 0xffff), "returned memory %p is not aligned to 64k\n", addr1);
551 ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
553 ok(addr2 == addr1, "VirtualAlloc returned %p, expected %p\n", addr2, addr1);
554
555 /* AT_ROUND_TO_PAGE flag is not supported for VirtualAlloc */
556 SetLastError(0xdeadbeef);
558 ok(!addr2, "VirtualAlloc unexpectedly succeeded\n");
559 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %ld, expected ERROR_INVALID_PARAMETER\n", GetLastError());
560
561 ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
562}
563
564static void test_MapViewOfFile(void)
565{
566 static const char testfile[] = "testfile.xxx";
567 const char *name;
568 HANDLE file, mapping, map2;
569 void *ptr, *ptr2, *addr;
571 SECTION_IMAGE_INFORMATION image_info;
573 BOOL ret;
574 SIZE_T size;
576 SIZE_T info_size;
577 LARGE_INTEGER map_size;
578
579 SetLastError(0xdeadbeef);
581 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
584
585 /* read/write mapping */
586
587 SetLastError(0xdeadbeef);
589 ok( mapping != 0, "CreateFileMapping error %lu\n", GetLastError() );
590
591 SetLastError(0xdeadbeef);
592 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
593 ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
595
596 SetLastError(0xdeadbeef);
597 ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
598 ok( ptr != NULL, "MapViewOfFile FILE_MAP_COPY error %lu\n", GetLastError() );
600
601 SetLastError(0xdeadbeef);
602 ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
603 ok( ptr != NULL, "MapViewOfFile 0 error %lu\n", GetLastError() );
605
606 SetLastError(0xdeadbeef);
607 ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
608 ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %lu\n", GetLastError() );
610
613 ok( ret, "DuplicateHandle failed error %lu\n", GetLastError());
614 ptr = MapViewOfFile( map2, FILE_MAP_WRITE, 0, 0, 4096 );
615 ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %lu\n", GetLastError() );
617 CloseHandle( map2 );
618
620 FILE_MAP_READ, FALSE, 0 );
621 ok( ret, "DuplicateHandle failed error %lu\n", GetLastError());
622 SetLastError(0xdeadbeef);
623 ptr = MapViewOfFile( map2, FILE_MAP_WRITE, 0, 0, 4096 );
624 ok( !ptr, "MapViewOfFile succeeded\n" );
625 ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
626 CloseHandle( map2 );
628 ok( ret, "DuplicateHandle failed error %lu\n", GetLastError());
629 SetLastError(0xdeadbeef);
630 ptr = MapViewOfFile( map2, 0, 0, 0, 4096 );
631 ok( !ptr, "MapViewOfFile succeeded\n" );
632 ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
633 CloseHandle( map2 );
635 FILE_MAP_READ, FALSE, 0 );
636 ok( ret, "DuplicateHandle failed error %lu\n", GetLastError());
637 ptr = MapViewOfFile( map2, 0, 0, 0, 4096 );
638 ok( ptr != NULL, "MapViewOfFile NO_ACCESS error %lu\n", GetLastError() );
639
641 CloseHandle( map2 );
643
644 /* read-only mapping */
645
646 SetLastError(0xdeadbeef);
648 ok( mapping != 0, "CreateFileMapping error %lu\n", GetLastError() );
649
650 SetLastError(0xdeadbeef);
651 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
652 ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
654
655 SetLastError(0xdeadbeef);
656 ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
657 ok( ptr != NULL, "MapViewOfFile FILE_MAP_COPY error %lu\n", GetLastError() );
659
660 SetLastError(0xdeadbeef);
661 ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
662 ok( ptr != NULL, "MapViewOfFile 0 error %lu\n", GetLastError() );
664
665 SetLastError(0xdeadbeef);
666 ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
667 ok( !ptr, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
669 GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
671
672 /* copy-on-write mapping */
673
674 SetLastError(0xdeadbeef);
676 ok( mapping != 0, "CreateFileMapping error %lu\n", GetLastError() );
677
678 SetLastError(0xdeadbeef);
679 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
680 ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
682
683 SetLastError(0xdeadbeef);
684 ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
685 ok( ptr != NULL, "MapViewOfFile FILE_MAP_COPY error %lu\n", GetLastError() );
687
688 SetLastError(0xdeadbeef);
689 ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
690 ok( ptr != NULL, "MapViewOfFile 0 error %lu\n", GetLastError() );
692
693 SetLastError(0xdeadbeef);
694 ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
695 ok( !ptr, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
697 GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
699
700 /* no access mapping */
701
702 SetLastError(0xdeadbeef);
704 ok( !mapping, "CreateFileMappingA succeeded\n" );
705 ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %ld\n", GetLastError() );
706 CloseHandle( file );
707
708 /* now try read-only file */
709
710 SetLastError(0xdeadbeef);
711 file = CreateFileA( testfile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
712 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
713
714 SetLastError(0xdeadbeef);
716 ok( !mapping, "CreateFileMapping PAGE_READWRITE succeeded\n" );
718 GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
719
720 SetLastError(0xdeadbeef);
722 ok( mapping != 0, "CreateFileMapping PAGE_WRITECOPY error %lu\n", GetLastError() );
724
725 SetLastError(0xdeadbeef);
727 ok( mapping != 0, "CreateFileMapping PAGE_READONLY error %lu\n", GetLastError() );
729 CloseHandle( file );
730
731 /* now try no access file */
732
733 SetLastError(0xdeadbeef);
734 file = CreateFileA( testfile, 0, 0, NULL, OPEN_EXISTING, 0, 0 );
735 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
736
737 SetLastError(0xdeadbeef);
739 ok( !mapping, "CreateFileMapping PAGE_READWRITE succeeded\n" );
741 GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
742
743 SetLastError(0xdeadbeef);
745 ok( !mapping, "CreateFileMapping PAGE_WRITECOPY succeeded\n" );
747 GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
748
749 SetLastError(0xdeadbeef);
751 ok( !mapping, "CreateFileMapping PAGE_READONLY succeeded\n" );
753 GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
754
755 CloseHandle( file );
756 DeleteFileA( testfile );
757
758 SetLastError(0xdeadbeef);
759 name = "Local\\Foo";
761 /* nt4 doesn't have Local\\ */
763 {
764 name = "Foo";
766 }
767 ok( file != 0, "CreateFileMapping PAGE_READWRITE error %lu\n", GetLastError() );
768
769 SetLastError(0xdeadbeef);
771 ok( mapping != 0, "OpenFileMapping FILE_MAP_READ error %lu\n", GetLastError() );
772 SetLastError(0xdeadbeef);
774 ok( !ptr, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
775 ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
776 SetLastError(0xdeadbeef);
777 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
778 ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
779 SetLastError(0xdeadbeef);
780 size = VirtualQuery( ptr, &info, sizeof(info) );
781 ok( size == sizeof(info),
782 "VirtualQuery error %lu\n", GetLastError() );
783 ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
784 ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
785 ok( info.AllocationProtect == PAGE_READONLY, "%lx != PAGE_READONLY\n", info.AllocationProtect );
786 ok( info.RegionSize == 4096, "%Ix != 4096\n", info.RegionSize );
787 ok( info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State );
788 ok( info.Protect == PAGE_READONLY, "%lx != PAGE_READONLY\n", info.Protect );
791 sizeof(section_info), &info_size );
792 ok( status == STATUS_ACCESS_DENIED, "NtQuerySection failed err %lx\n", status );
795 ok( mapping != 0, "OpenFileMapping FILE_MAP_READ error %lu\n", GetLastError() );
796 info_size = (SIZE_T)0xdeadbeef << 16;
798 sizeof(section_info), &info_size );
799 ok( !status, "NtQuerySection failed err %lx\n", status );
800 ok( info_size == sizeof(section_info), "NtQuerySection wrong size %Iu\n", info_size );
801 ok( section_info.Attributes == SEC_COMMIT, "NtQuerySection wrong attr %08lx\n",
802 section_info.Attributes );
803 ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
804 ok( section_info.Size.QuadPart == info.RegionSize, "NtQuerySection wrong size %lx%08lx / %08Ix\n",
805 section_info.Size.u.HighPart, section_info.Size.u.LowPart, info.RegionSize );
807
808 SetLastError(0xdeadbeef);
810 ok( mapping != 0, "OpenFileMapping FILE_MAP_WRITE error %lu\n", GetLastError() );
811 SetLastError(0xdeadbeef);
812 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
813 ok( !ptr, "MapViewOfFile succeeded\n" );
814 ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %ld\n", GetLastError() );
815 SetLastError(0xdeadbeef);
817 ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %lu\n", GetLastError() );
818 SetLastError(0xdeadbeef);
819 size = VirtualQuery( ptr, &info, sizeof(info) );
820 ok( size == sizeof(info),
821 "VirtualQuery error %lu\n", GetLastError() );
822 ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
823 ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
824 ok( info.AllocationProtect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.AllocationProtect );
825 ok( info.RegionSize == 4096, "%Ix != 4096\n", info.RegionSize );
826 ok( info.State == MEM_COMMIT, "%lx != MEM_COMMIT\n", info.State );
827 ok( info.Protect == PAGE_READWRITE, "%lx != PAGE_READWRITE\n", info.Protect );
830 sizeof(section_info), &info_size );
831 ok( status == STATUS_ACCESS_DENIED, "NtQuerySection failed err %lx\n", status );
833
835 ok( mapping != 0, "OpenFileMapping FILE_MAP_WRITE error %lu\n", GetLastError() );
837 sizeof(section_info), &info_size );
838 ok( !status, "NtQuerySection failed err %lx\n", status );
839 ok( info_size == sizeof(section_info), "NtQuerySection wrong size %Iu\n", info_size );
840 ok( section_info.Attributes == SEC_COMMIT, "NtQuerySection wrong attr %08lx\n",
841 section_info.Attributes );
842 ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
843 ok( section_info.Size.QuadPart == info.RegionSize, "NtQuerySection wrong size %lx%08lx / %08Ix\n",
844 section_info.Size.u.HighPart, section_info.Size.u.LowPart, info.RegionSize );
846
847 CloseHandle( file );
848
849 /* read/write mapping with SEC_RESERVE */
851 ok(mapping != 0, "CreateFileMappingA failed with error %ld\n", GetLastError());
853 sizeof(section_info), NULL );
854 ok( !status, "NtQuerySection failed err %lx\n", status );
855 ok( section_info.Attributes == SEC_RESERVE, "NtQuerySection wrong attr %08lx\n",
856 section_info.Attributes );
857 ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
858 ok( section_info.Size.QuadPart == MAPPING_SIZE, "NtQuerySection wrong size %lx%08lx / %08x\n",
859 section_info.Size.u.HighPart, section_info.Size.u.LowPart, MAPPING_SIZE );
860
862 ok(ptr != NULL, "MapViewOfFile failed with error %ld\n", GetLastError());
863
864 ptr2 = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
865 ok( ptr2 != NULL, "MapViewOfFile failed with error %ld\n", GetLastError());
866 ok( ptr != ptr2, "MapViewOfFile returned same pointer\n" );
867
868 ret = VirtualQuery(ptr, &info, sizeof(info));
869 ok(ret, "VirtualQuery failed with error %ld\n", GetLastError());
870 ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
871 ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
872 ok(info.RegionSize == MAPPING_SIZE, "RegionSize should have been 0x%x but was 0x%Ix\n", MAPPING_SIZE, info.RegionSize);
873 ok(info.State == MEM_RESERVE, "State should have been MEM_RESERVE instead of 0x%lx\n", info.State);
874 ok(info.AllocationProtect == PAGE_READWRITE,
875 "AllocationProtect should have been PAGE_READWRITE but was 0x%lx\n", info.AllocationProtect);
876 ok(info.Protect == 0, "Protect should have been 0 instead of 0x%lx\n", info.Protect);
877 ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%lx\n", info.Type);
878
879 ret = VirtualQuery(ptr2, &info, sizeof(info));
880 ok(ret, "VirtualQuery failed with error %ld\n", GetLastError());
881 ok(info.BaseAddress == ptr2,
882 "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
883 ok(info.AllocationBase == ptr2,
884 "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
885 ok(info.AllocationProtect == PAGE_READWRITE,
886 "AllocationProtect should have been PAGE_READWRITE but was 0x%lx\n", info.AllocationProtect);
887 ok(info.RegionSize == MAPPING_SIZE,
888 "RegionSize should have been 0x%x but was 0x%Ix\n", MAPPING_SIZE, info.RegionSize);
889 ok(info.State == MEM_RESERVE, "State should have been MEM_RESERVE instead of 0x%lx\n", info.State);
890 ok(info.Protect == 0, "Protect should have been 0 instead of 0x%lx\n", info.Protect);
891 ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%lx\n", info.Type);
892
894 ok(ptr != NULL, "VirtualAlloc failed with error %ld\n", GetLastError());
895
896 ret = VirtualQuery(ptr, &info, sizeof(info));
897 ok(ret, "VirtualQuery failed with error %ld\n", GetLastError());
898 ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
899 ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
900 ok(info.RegionSize == 0x10000, "RegionSize should have been 0x10000 but was 0x%Ix\n", info.RegionSize);
901 ok(info.State == MEM_COMMIT, "State should have been MEM_COMMIT instead of 0x%lx\n", info.State);
902 ok(info.Protect == PAGE_READONLY, "Protect should have been PAGE_READONLY instead of 0x%lx\n", info.Protect);
903 ok(info.AllocationProtect == PAGE_READWRITE,
904 "AllocationProtect should have been PAGE_READWRITE but was 0x%lx\n", info.AllocationProtect);
905 ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%lx\n", info.Type);
906
907 /* shows that the VirtualAlloc above affects the mapping, not just the
908 * virtual memory in this process - it also affects all other processes
909 * with a view of the mapping, but that isn't tested here */
910 ret = VirtualQuery(ptr2, &info, sizeof(info));
911 ok(ret, "VirtualQuery failed with error %ld\n", GetLastError());
912 ok(info.BaseAddress == ptr2,
913 "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
914 ok(info.AllocationBase == ptr2,
915 "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
916 ok(info.AllocationProtect == PAGE_READWRITE,
917 "AllocationProtect should have been PAGE_READWRITE but was 0x%lx\n", info.AllocationProtect);
918 ok(info.RegionSize == 0x10000,
919 "RegionSize should have been 0x10000 but was 0x%Ix\n", info.RegionSize);
920 ok(info.State == MEM_COMMIT,
921 "State should have been MEM_COMMIT instead of 0x%lx\n", info.State);
922 ok(info.Protect == PAGE_READWRITE,
923 "Protect should have been PAGE_READWRITE instead of 0x%lx\n", info.Protect);
924 ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%lx\n", info.Type);
925
927 ok( addr == ptr, "VirtualAlloc failed with error %lu\n", GetLastError() );
928
929 ret = VirtualFree( ptr, 0x10000, MEM_DECOMMIT );
930 ok( !ret, "VirtualFree succeeded\n" );
931 ok( GetLastError() == ERROR_INVALID_PARAMETER, "VirtualFree failed with %lu\n", GetLastError() );
932
933 ret = UnmapViewOfFile(ptr2);
934 ok(ret, "UnmapViewOfFile failed with error %ld\n", GetLastError());
936 ok(ret, "UnmapViewOfFile failed with error %ld\n", GetLastError());
938
939 /* same thing with SEC_COMMIT */
941 ok(mapping != 0, "CreateFileMappingA failed with error %ld\n", GetLastError());
943 sizeof(section_info), NULL );
944 ok( !status, "NtQuerySection failed err %lx\n", status );
945 ok( section_info.Attributes == SEC_COMMIT, "NtQuerySection wrong attr %08lx\n",
946 section_info.Attributes );
947 ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
948 ok( section_info.Size.QuadPart == MAPPING_SIZE, "NtQuerySection wrong size %lx%08lx / %08x\n",
949 section_info.Size.u.HighPart, section_info.Size.u.LowPart, MAPPING_SIZE );
950
952 ok(ptr != NULL, "MapViewOfFile failed with error %ld\n", GetLastError());
953
954 ret = VirtualQuery(ptr, &info, sizeof(info));
955 ok(ret, "VirtualQuery failed with error %ld\n", GetLastError());
956 ok(info.BaseAddress == ptr, "wrong BaseAddress %p/%p\n", ptr, info.BaseAddress);
957 ok(info.AllocationBase == ptr, "wrong AllocationBase %p/%p\n", ptr, info.AllocationBase);
958 ok(info.RegionSize == MAPPING_SIZE, "wrong RegionSize 0x%Ix\n", info.RegionSize);
959 ok(info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State);
960 ok(info.AllocationProtect == PAGE_READWRITE, "wrong AllocationProtect 0x%lx\n", info.AllocationProtect);
961 ok(info.Protect == PAGE_READWRITE, "wrong Protect 0x%lx\n", info.Protect);
962 ok(info.Type == MEM_MAPPED, "wrong Type 0x%lx\n", info.Type);
963
965 ok(ptr != NULL, "VirtualAlloc failed with error %ld\n", GetLastError());
966
967 ret = VirtualQuery(ptr, &info, sizeof(info));
968 ok(ret, "VirtualQuery failed with error %ld\n", GetLastError());
969 ok(info.BaseAddress == ptr, "wrong BaseAddress %p/%p\n", ptr, info.BaseAddress);
970 ok(info.AllocationBase == ptr, "wrong AllocationBase %p/%p\n", ptr, info.AllocationBase);
971 ok(info.RegionSize == 0x10000, "wrong RegionSize 0x%Ix\n", info.RegionSize);
972 ok(info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State);
973 ok(info.AllocationProtect == PAGE_READWRITE, "wrong AllocationProtect 0x%lx\n", info.AllocationProtect);
974 ok(info.Protect == PAGE_READONLY, "wrong Protect 0x%lx\n", info.Protect);
975 ok(info.Type == MEM_MAPPED, "wrong Type 0x%lx\n", info.Type);
976
978 ok( addr == ptr, "VirtualAlloc failed with error %lu\n", GetLastError() );
979
980 ret = VirtualFree( ptr, 0x10000, MEM_DECOMMIT );
981 ok( !ret, "VirtualFree succeeded\n" );
982 ok( GetLastError() == ERROR_INVALID_PARAMETER, "VirtualFree failed with %lu\n", GetLastError() );
983
985 ok(ret, "UnmapViewOfFile failed with error %ld\n", GetLastError());
987
988 /* same thing with SEC_NOCACHE (only supported on recent Windows versions) */
990 0, MAPPING_SIZE, NULL);
991 ok(mapping != 0, "CreateFileMappingA failed with error %ld\n", GetLastError());
993 sizeof(section_info), NULL );
994 ok( !status, "NtQuerySection failed err %lx\n", status );
995 ok( section_info.Attributes == (SEC_COMMIT | SEC_NOCACHE) ||
996 broken(section_info.Attributes == SEC_COMMIT),
997 "NtQuerySection wrong attr %08lx\n", section_info.Attributes );
998 if (section_info.Attributes & SEC_NOCACHE)
999 {
1001 ok(ptr != NULL, "MapViewOfFile failed with error %ld\n", GetLastError());
1002
1003 ret = VirtualQuery(ptr, &info, sizeof(info));
1004 ok(ret, "VirtualQuery failed with error %ld\n", GetLastError());
1005 ok(info.BaseAddress == ptr, "wrong BaseAddress %p/%p\n", ptr, info.BaseAddress);
1006 ok(info.AllocationBase == ptr, "wrong AllocationBase %p/%p\n", ptr, info.AllocationBase);
1007 ok(info.RegionSize == MAPPING_SIZE, "wrong RegionSize 0x%Ix\n", info.RegionSize);
1008 ok(info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State);
1009 ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE),
1010 "wrong AllocationProtect 0x%lx\n", info.AllocationProtect);
1011 ok(info.Protect == (PAGE_READWRITE | PAGE_NOCACHE), "wrong Protect 0x%lx\n", info.Protect);
1012 ok(info.Type == MEM_MAPPED, "wrong Type 0x%lx\n", info.Type);
1013
1015 ok(ptr != NULL, "VirtualAlloc failed with error %ld\n", GetLastError());
1016
1017 ret = VirtualQuery(ptr, &info, sizeof(info));
1018 ok(ret, "VirtualQuery failed with error %ld\n", GetLastError());
1019 ok(info.BaseAddress == ptr, "wrong BaseAddress %p/%p\n", ptr, info.BaseAddress);
1020 ok(info.AllocationBase == ptr, "wrong AllocationBase %p/%p\n", ptr, info.AllocationBase);
1021 ok(info.RegionSize == 0x10000, "wrong RegionSize 0x%Ix\n", info.RegionSize);
1022 ok(info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State);
1023 ok(info.AllocationProtect == (PAGE_READWRITE | PAGE_NOCACHE),
1024 "wrong AllocationProtect 0x%lx\n", info.AllocationProtect);
1025 ok(info.Protect == (PAGE_READONLY | PAGE_NOCACHE), "wrong Protect 0x%lx\n", info.Protect);
1026 ok(info.Type == MEM_MAPPED, "wrong Type 0x%lx\n", info.Type);
1027
1029 ok(ret, "UnmapViewOfFile failed with error %ld\n", GetLastError());
1030 }
1032
1034 ok( addr != NULL, "VirtualAlloc failed with error %lu\n", GetLastError() );
1035
1036 SetLastError(0xdeadbeef);
1037 ok( !UnmapViewOfFile(addr), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
1039 "got %lu, expected ERROR_INVALID_ADDRESS\n", GetLastError());
1040 SetLastError(0xdeadbeef);
1041 ok( !UnmapViewOfFile((char *)addr + 0x3000), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
1043 "got %lu, expected ERROR_INVALID_ADDRESS\n", GetLastError());
1044 SetLastError(0xdeadbeef);
1045 ok( !UnmapViewOfFile((void *)0xdeadbeef), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
1047 "got %lu, expected ERROR_INVALID_ADDRESS\n", GetLastError());
1048
1049 ok( VirtualFree(addr, 0, MEM_RELEASE), "VirtualFree failed\n" );
1050
1051 /* close named mapping handle without unmapping */
1052 name = "Foo";
1053 SetLastError(0xdeadbeef);
1055 ok( mapping != 0, "CreateFileMappingA failed with error %ld\n", GetLastError() );
1056 SetLastError(0xdeadbeef);
1058 ok( ptr != NULL, "MapViewOfFile failed with error %ld\n", GetLastError() );
1059 SetLastError(0xdeadbeef);
1061 ok( map2 != 0, "OpenFileMappingA failed with error %ld\n", GetLastError() );
1062 SetLastError(0xdeadbeef);
1063 ret = CloseHandle(map2);
1064 ok(ret, "CloseHandle error %ld\n", GetLastError());
1065 SetLastError(0xdeadbeef);
1067 ok(ret, "CloseHandle error %ld\n", GetLastError());
1068
1070 ok( !ret, "memory is not accessible\n" );
1071
1072 ret = VirtualQuery(ptr, &info, sizeof(info));
1073 ok(ret, "VirtualQuery error %ld\n", GetLastError());
1074 ok(info.BaseAddress == ptr, "got %p != expected %p\n", info.BaseAddress, ptr);
1075 ok(info.RegionSize == MAPPING_SIZE, "got %#Ix != expected %#x\n", info.RegionSize, MAPPING_SIZE);
1076 ok(info.Protect == PAGE_READWRITE, "got %#lx != expected PAGE_READWRITE\n", info.Protect);
1077 ok(info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr);
1078 ok(info.AllocationProtect == PAGE_READWRITE, "%#lx != PAGE_READWRITE\n", info.AllocationProtect);
1079 ok(info.State == MEM_COMMIT, "%#lx != MEM_COMMIT\n", info.State);
1080 ok(info.Type == MEM_MAPPED, "%#lx != MEM_MAPPED\n", info.Type);
1081
1082 SetLastError(0xdeadbeef);
1084 ok( map2 == 0, "OpenFileMappingA succeeded\n" );
1085 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "OpenFileMappingA set error %ld\n", GetLastError() );
1086 if (map2) CloseHandle(map2); /* FIXME: remove once Wine is fixed */
1087 SetLastError(0xdeadbeef);
1089 ok( mapping != 0, "CreateFileMappingA failed\n" );
1090 ok( GetLastError() == ERROR_SUCCESS, "CreateFileMappingA set error %ld\n", GetLastError() );
1091 SetLastError(0xdeadbeef);
1093 ok(ret, "CloseHandle error %ld\n", GetLastError());
1094
1096 ok( !ret, "memory is not accessible\n" );
1097
1098 ret = VirtualQuery(ptr, &info, sizeof(info));
1099 ok(ret, "VirtualQuery error %ld\n", GetLastError());
1100 ok(info.BaseAddress == ptr, "got %p != expected %p\n", info.BaseAddress, ptr);
1101 ok(info.RegionSize == MAPPING_SIZE, "got %#Ix != expected %#x\n", info.RegionSize, MAPPING_SIZE);
1102 ok(info.Protect == PAGE_READWRITE, "got %#lx != expected PAGE_READWRITE\n", info.Protect);
1103 ok(info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr);
1104 ok(info.AllocationProtect == PAGE_READWRITE, "%#lx != PAGE_READWRITE\n", info.AllocationProtect);
1105 ok(info.State == MEM_COMMIT, "%#lx != MEM_COMMIT\n", info.State);
1106 ok(info.Type == MEM_MAPPED, "%#lx != MEM_MAPPED\n", info.Type);
1107
1108 SetLastError(0xdeadbeef);
1110 ok( ret, "UnmapViewOfFile failed with error %ld\n", GetLastError() );
1111
1113 ok( ret, "memory is accessible\n" );
1114
1115 ret = VirtualQuery(ptr, &info, sizeof(info));
1116 ok(ret, "VirtualQuery error %ld\n", GetLastError());
1117 ok(info.BaseAddress == ptr, "got %p != expected %p\n", info.BaseAddress, ptr);
1118 ok(info.Protect == PAGE_NOACCESS, "got %#lx != expected PAGE_NOACCESS\n", info.Protect);
1119 ok(info.AllocationBase == NULL, "%p != NULL\n", info.AllocationBase);
1120 ok(info.AllocationProtect == 0, "%#lx != 0\n", info.AllocationProtect);
1121 ok(info.State == MEM_FREE, "%#lx != MEM_FREE\n", info.State);
1122 ok(info.Type == 0, "%#lx != 0\n", info.Type);
1123
1124 SetLastError(0xdeadbeef);
1126 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
1129
1130 SetLastError(0xdeadbeef);
1132 ok( mapping != 0, "CreateFileMappingA failed with error %ld\n", GetLastError() );
1133 SetLastError(0xdeadbeef);
1135 ok( ptr != NULL, "MapViewOfFile failed with error %ld\n", GetLastError() );
1136 SetLastError(0xdeadbeef);
1138 ok( map2 != 0, "OpenFileMappingA failed with error %ld\n", GetLastError() );
1139 SetLastError(0xdeadbeef);
1140 ret = CloseHandle(map2);
1141 ok(ret, "CloseHandle error %ld\n", GetLastError());
1142 status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
1143 sizeof(section_info), &info_size );
1144 ok( !status, "NtQuerySection failed err %lx\n", status );
1145 ok( info_size == sizeof(section_info), "NtQuerySection wrong size %Iu\n", info_size );
1146 ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08lx\n",
1147 section_info.Attributes );
1148 ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
1149 ok( section_info.Size.QuadPart == MAPPING_SIZE, "NtQuerySection wrong size %lx%08lx\n",
1150 section_info.Size.u.HighPart, section_info.Size.u.LowPart );
1151 SetLastError(0xdeadbeef);
1153 ok(ret, "CloseHandle error %ld\n", GetLastError());
1154
1156 ok( !ret, "memory is not accessible\n" );
1157
1158 ret = VirtualQuery(ptr, &info, sizeof(info));
1159 ok(ret, "VirtualQuery error %ld\n", GetLastError());
1160 ok(info.BaseAddress == ptr, "got %p != expected %p\n", info.BaseAddress, ptr);
1161 ok(info.RegionSize == MAPPING_SIZE, "got %#Ix != expected %#x\n", info.RegionSize, MAPPING_SIZE);
1162 ok(info.Protect == PAGE_READWRITE, "got %#lx != expected PAGE_READWRITE\n", info.Protect);
1163 ok(info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr);
1164 ok(info.AllocationProtect == PAGE_READWRITE, "%#lx != PAGE_READWRITE\n", info.AllocationProtect);
1165 ok(info.State == MEM_COMMIT, "%#lx != MEM_COMMIT\n", info.State);
1166 ok(info.Type == MEM_MAPPED, "%#lx != MEM_MAPPED\n", info.Type);
1167
1168 SetLastError(0xdeadbeef);
1170 ok( map2 == 0, "OpenFileMappingA succeeded\n" );
1171 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "OpenFileMappingA set error %ld\n", GetLastError() );
1172 CloseHandle(map2);
1173 SetLastError(0xdeadbeef);
1175 ok( mapping != 0, "CreateFileMappingA failed\n" );
1176 ok( GetLastError() == ERROR_SUCCESS, "CreateFileMappingA set error %ld\n", GetLastError() );
1177 SetLastError(0xdeadbeef);
1179 ok(ret, "CloseHandle error %ld\n", GetLastError());
1180
1182 ok( !ret, "memory is not accessible\n" );
1183
1184 ret = VirtualQuery(ptr, &info, sizeof(info));
1185 ok(ret, "VirtualQuery error %ld\n", GetLastError());
1186 ok(info.BaseAddress == ptr, "got %p != expected %p\n", info.BaseAddress, ptr);
1187 ok(info.RegionSize == MAPPING_SIZE, "got %#Ix != expected %#x\n", info.RegionSize, MAPPING_SIZE);
1188 ok(info.Protect == PAGE_READWRITE, "got %#lx != expected PAGE_READWRITE\n", info.Protect);
1189 ok(info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr);
1190 ok(info.AllocationProtect == PAGE_READWRITE, "%#lx != PAGE_READWRITE\n", info.AllocationProtect);
1191 ok(info.State == MEM_COMMIT, "%#lx != MEM_COMMIT\n", info.State);
1192 ok(info.Type == MEM_MAPPED, "%#lx != MEM_MAPPED\n", info.Type);
1193
1194 SetLastError(0xdeadbeef);
1196 ok( ret, "UnmapViewOfFile failed with error %ld\n", GetLastError() );
1197
1199 ok( ret, "memory is accessible\n" );
1200
1201 ret = VirtualQuery(ptr, &info, sizeof(info));
1202 ok(ret, "VirtualQuery error %ld\n", GetLastError());
1203 ok(info.BaseAddress == ptr, "got %p != expected %p\n", info.BaseAddress, ptr);
1204 ok(info.Protect == PAGE_NOACCESS, "got %#lx != expected PAGE_NOACCESS\n", info.Protect);
1205 ok(info.AllocationBase == NULL, "%p != NULL\n", info.AllocationBase);
1206 ok(info.AllocationProtect == 0, "%#lx != 0\n", info.AllocationProtect);
1207 ok(info.State == MEM_FREE, "%#lx != MEM_FREE\n", info.State);
1208 ok(info.Type == 0, "%#lx != 0\n", info.Type);
1209
1211 ok( mapping != NULL, "CreateFileMappingA failed with error %lu\n", GetLastError() );
1212
1213 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 12288 );
1214 ok( ptr != NULL, "MapViewOfFile failed with error %lu\n", GetLastError() );
1215
1216 ret = UnmapViewOfFile( (char *)ptr + 100 );
1217 ok( ret, "UnmapViewOfFile failed with error %lu\n", GetLastError() );
1218
1219 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 12288 );
1220 ok( ptr != NULL, "MapViewOfFile failed with error %lu\n", GetLastError() );
1221
1222 ret = UnmapViewOfFile( (char *)ptr + 4096 );
1223 ok( ret, "UnmapViewOfFile failed with error %lu\n", GetLastError() );
1224
1225 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 12288 );
1226 ok( ptr != NULL, "MapViewOfFile failed with error %lu\n", GetLastError() );
1227
1228 ret = UnmapViewOfFile( (char *)ptr + 4096 + 100 );
1229 ok( ret, "UnmapViewOfFile failed with error %lu\n", GetLastError() );
1230
1232
1234 ok( mapping != NULL, "CreateFileMappingA failed with error %lu\n", GetLastError() );
1235 status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
1236 sizeof(section_info), &info_size );
1237 ok( !status, "NtQuerySection failed err %lx\n", status );
1238 ok( info_size == sizeof(section_info), "NtQuerySection wrong size %Iu\n", info_size );
1239 ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08lx\n",
1240 section_info.Attributes );
1241 ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
1242 ok( section_info.Size.QuadPart == 36, "NtQuerySection wrong size %lx%08lx\n",
1243 section_info.Size.u.HighPart, section_info.Size.u.LowPart );
1245
1249 ok( mapping != NULL, "CreateFileMappingA failed with error %lu\n", GetLastError() );
1250 status = pNtQuerySection( mapping, SectionBasicInformation, &section_info,
1251 sizeof(section_info), &info_size );
1252 ok( !status, "NtQuerySection failed err %lx\n", status );
1253 ok( info_size == sizeof(section_info), "NtQuerySection wrong size %Iu\n", info_size );
1254 ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08lx\n",
1255 section_info.Attributes );
1256 ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
1257 ok( section_info.Size.QuadPart == 0x3456, "NtQuerySection wrong size %lx%08lx\n",
1258 section_info.Size.u.HighPart, section_info.Size.u.LowPart );
1260
1261 map_size.QuadPart = 0x3457;
1262 status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
1263 &map_size, PAGE_READONLY, SEC_COMMIT, file );
1264 ok( status == STATUS_SECTION_TOO_BIG, "NtCreateSection failed %lx\n", status );
1265 status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
1266 &map_size, PAGE_READONLY, SEC_IMAGE, file );
1267 ok( status == STATUS_INVALID_IMAGE_NOT_MZ, "NtCreateSection failed %lx\n", status );
1268 if (!status) CloseHandle( mapping );
1269 map_size.QuadPart = 0x3452;
1270 status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
1271 &map_size, PAGE_READONLY, SEC_COMMIT, file );
1272 ok( !status, "NtCreateSection failed %lx\n", status );
1273 status = pNtQuerySection( mapping, SectionBasicInformation, &section_info, sizeof(section_info), NULL );
1274 ok( !status, "NtQuerySection failed err %lx\n", status );
1275 ok( section_info.Attributes == SEC_FILE, "NtQuerySection wrong attr %08lx\n",
1276 section_info.Attributes );
1277 ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
1278 ok( section_info.Size.QuadPart == 0x3452, "NtQuerySection wrong size %lx%08lx\n",
1279 section_info.Size.u.HighPart, section_info.Size.u.LowPart );
1280 size = map_size.QuadPart;
1281 status = pNtMapViewOfSection( mapping, GetCurrentProcess(), &ptr, 0, 0, NULL,
1283 ok( !status, "NtMapViewOfSection failed err %lx\n", status );
1284 pNtUnmapViewOfSection( GetCurrentProcess(), ptr );
1285 size = map_size.QuadPart + 1;
1286 status = pNtMapViewOfSection( mapping, GetCurrentProcess(), &ptr, 0, 0, NULL,
1288 ok( status == STATUS_INVALID_VIEW_SIZE, "NtMapViewOfSection failed err %lx\n", status );
1290
1291 status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
1292 &map_size, PAGE_READONLY, SEC_COMMIT, 0 );
1293 ok( !status, "NtCreateSection failed %lx\n", status );
1294 status = pNtQuerySection( mapping, SectionBasicInformation, &section_info, sizeof(section_info), NULL );
1295 ok( !status, "NtQuerySection failed err %lx\n", status );
1296 ok( section_info.Attributes == SEC_COMMIT, "NtQuerySection wrong attr %08lx\n",
1297 section_info.Attributes );
1298 ok( section_info.BaseAddress == NULL, "NtQuerySection wrong base %p\n", section_info.BaseAddress );
1299 ok( section_info.Size.QuadPart == 0x4000, "NtQuerySection wrong size %lx%08lx\n",
1300 section_info.Size.u.HighPart, section_info.Size.u.LowPart );
1301 status = pNtQuerySection( mapping, SectionBasicInformation, &section_info, sizeof(section_info)-1, NULL );
1302 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySection failed err %lx\n", status );
1303 status = pNtQuerySection( mapping, SectionBasicInformation, &section_info, sizeof(section_info)+1, NULL );
1304 ok( !status, "NtQuerySection failed err %lx\n", status );
1305 status = pNtQuerySection( mapping, SectionImageInformation, &image_info, sizeof(image_info)-1, NULL );
1306 ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySection failed err %lx\n", status );
1307 status = pNtQuerySection( mapping, SectionImageInformation, &image_info, sizeof(image_info), NULL );
1308 ok( status == STATUS_SECTION_NOT_IMAGE, "NtQuerySection failed err %lx\n", status );
1309 status = pNtQuerySection( mapping, SectionImageInformation, &image_info, sizeof(image_info)+1, NULL );
1310 ok( status == STATUS_SECTION_NOT_IMAGE, "NtQuerySection failed err %lx\n", status );
1311 if (sizeof(SIZE_T) > sizeof(int))
1312 {
1313 status = pNtQuerySection( mapping, SectionImageInformation, &image_info,
1314 sizeof(image_info) + ((SIZE_T)0x10000000 << 8), NULL );
1315 todo_wine
1316 ok( status == STATUS_ACCESS_VIOLATION, "NtQuerySection wrong err %lx\n", status );
1317 }
1319
1322 status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
1324 ok( status == STATUS_MAPPED_FILE_SIZE_ZERO, "NtCreateSection failed %lx\n", status );
1325 status = pNtCreateSection( &mapping, SECTION_QUERY | SECTION_MAP_READ, NULL,
1327 ok( status == STATUS_INVALID_FILE_FOR_SECTION, "NtCreateSection failed %lx\n", status );
1328
1330 DeleteFileA(testfile);
1331}
1332
1333
1335{
1336 static const char testfile[] = "testfile.xxx";
1337 HANDLE file, file2, mapping, map2;
1338 void *ptr, *ptr2;
1340 char path[MAX_PATH];
1341
1342 if (!pNtAreMappedFilesTheSame)
1343 {
1344 win_skip( "NtAreMappedFilesTheSame not available\n" );
1345 return;
1346 }
1347
1349 NULL, CREATE_ALWAYS, 0, 0 );
1350 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
1352 SetEndOfFile( file );
1353
1355 ok( mapping != 0, "CreateFileMapping error %lu\n", GetLastError() );
1356
1357 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
1358 ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
1359
1361 NULL, OPEN_EXISTING, 0, 0 );
1362 ok( file2 != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
1363
1364 map2 = CreateFileMappingA( file2, NULL, PAGE_READONLY, 0, 4096, NULL );
1365 ok( map2 != 0, "CreateFileMapping error %lu\n", GetLastError() );
1366 ptr2 = MapViewOfFile( map2, FILE_MAP_READ, 0, 0, 4096 );
1367 ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
1368 status = pNtAreMappedFilesTheSame( ptr, ptr2 );
1369 ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %lx\n", status );
1370 UnmapViewOfFile( ptr2 );
1371
1372 ptr2 = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
1373 ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
1374 status = pNtAreMappedFilesTheSame( ptr, ptr2 );
1375 ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %lx\n", status );
1376 UnmapViewOfFile( ptr2 );
1377 CloseHandle( map2 );
1378
1379 map2 = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
1380 ok( map2 != 0, "CreateFileMapping error %lu\n", GetLastError() );
1381 ptr2 = MapViewOfFile( map2, FILE_MAP_READ, 0, 0, 4096 );
1382 ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
1383 status = pNtAreMappedFilesTheSame( ptr, ptr2 );
1384 ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %lx\n", status );
1385 UnmapViewOfFile( ptr2 );
1386 CloseHandle( map2 );
1387 CloseHandle( file2 );
1388
1389 status = pNtAreMappedFilesTheSame( ptr, ptr );
1391 "NtAreMappedFilesTheSame returned %lx\n", status );
1392
1393 status = pNtAreMappedFilesTheSame( ptr, (char *)ptr + 30 );
1395 "NtAreMappedFilesTheSame returned %lx\n", status );
1396
1397 status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
1398 ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %lx\n", status );
1399
1400 status = pNtAreMappedFilesTheSame( ptr, (void *)0xdeadbeef );
1402 "NtAreMappedFilesTheSame returned %lx\n", status );
1403
1404 status = pNtAreMappedFilesTheSame( ptr, NULL );
1405 ok( status == STATUS_INVALID_ADDRESS, "NtAreMappedFilesTheSame returned %lx\n", status );
1406
1407 status = pNtAreMappedFilesTheSame( ptr, (void *)GetProcessHeap() );
1408 ok( status == STATUS_CONFLICTING_ADDRESSES, "NtAreMappedFilesTheSame returned %lx\n", status );
1409
1410 status = pNtAreMappedFilesTheSame( NULL, NULL );
1411 ok( status == STATUS_INVALID_ADDRESS, "NtAreMappedFilesTheSame returned %lx\n", status );
1412
1413 ptr2 = VirtualAlloc( NULL, 0x10000, MEM_COMMIT, PAGE_READWRITE );
1414 ok( ptr2 != NULL, "VirtualAlloc error %lu\n", GetLastError() );
1415 status = pNtAreMappedFilesTheSame( ptr, ptr2 );
1416 ok( status == STATUS_CONFLICTING_ADDRESSES, "NtAreMappedFilesTheSame returned %lx\n", status );
1417 VirtualFree( ptr2, 0, MEM_RELEASE );
1418
1421 CloseHandle( file );
1422
1423 status = pNtAreMappedFilesTheSame( GetModuleHandleA("ntdll.dll"),
1424 GetModuleHandleA("kernel32.dll") );
1425 ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %lx\n", status );
1426 status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
1427 GetModuleHandleA("kernel32.dll") );
1428 ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %lx\n", status );
1429 status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
1430 (char *)GetModuleHandleA("kernel32.dll") + 4096 );
1431 ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %lx\n", status );
1432
1434 strcat( path, "\\kernel32.dll" );
1436 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
1437
1439 ok( mapping != 0, "CreateFileMapping error %lu\n", GetLastError() );
1440 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
1441 ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
1442 status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
1443 ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %lx\n", status );
1444 status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"), ptr );
1445 todo_wine
1446 ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %lx\n", status );
1449
1451 ok( mapping != 0, "CreateFileMapping error %lu\n", GetLastError() );
1452 ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
1453 ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
1454 status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
1455 ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %lx\n", status );
1456 status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"), ptr );
1457 ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %lx\n", status );
1458
1460 ok( file2 != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
1461 map2 = CreateFileMappingA( file2, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL );
1462 ok( map2 != 0, "CreateFileMapping error %lu\n", GetLastError() );
1463 ptr2 = MapViewOfFile( map2, FILE_MAP_READ, 0, 0, 0 );
1464 ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %lu\n", GetLastError() );
1465 status = pNtAreMappedFilesTheSame( ptr, ptr2 );
1466 ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %lx\n", status );
1467 status = pNtAreMappedFilesTheSame( ptr2, ptr );
1468 ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %lx\n", status );
1469 UnmapViewOfFile( ptr2 );
1470 CloseHandle( map2 );
1471 CloseHandle( file2 );
1472
1475
1476 CloseHandle( file );
1477 DeleteFileA( testfile );
1478}
1479
1480static void test_CreateFileMapping(void)
1481{
1482 HANDLE handle, handle2, file[3];
1484 unsigned int i;
1486
1487 static const struct { DWORD file, flags, error, attrs; } sec_flag_tests[] =
1488 {
1489 /* anonymous mapping */
1490 { 0, SEC_RESERVE, 0 }, /* 0 */
1491 { 0, SEC_RESERVE | SEC_NOCACHE, 0 },
1493 { 0, SEC_RESERVE | SEC_WRITECOMBINE, 0 },
1494 { 0, SEC_COMMIT, 0 },
1495 { 0, SEC_COMMIT | SEC_NOCACHE, 0 }, /* 5 */
1496 { 0, SEC_COMMIT | SEC_WRITECOMBINE, 0 },
1500 { 0, SEC_IMAGE | SEC_COMMIT, ERROR_INVALID_PARAMETER }, /* 10 */
1505 { 0, SEC_FILE | SEC_RESERVE, ERROR_INVALID_PARAMETER }, /* 15 */
1507 { 0, 0, 0, SEC_COMMIT },
1508 /* normal file */
1509 { 1, SEC_RESERVE, 0, SEC_FILE },
1513 { 1, SEC_COMMIT, 0, SEC_FILE },
1516 { 1, SEC_COMMIT | SEC_WRITECOMBINE, 0, SEC_FILE | SEC_WRITECOMBINE }, /* 25 */
1521 { 1, SEC_NOCACHE, ERROR_INVALID_PARAMETER }, /* 30 */
1526 { 1, SEC_FILE | SEC_COMMIT, ERROR_INVALID_PARAMETER }, /* 35 */
1527 { 1, 0, 0, SEC_FILE },
1528 /* PE image file */
1529 { 2, SEC_IMAGE, 0, SEC_FILE | SEC_IMAGE },
1531 { 2, SEC_IMAGE | SEC_NOCACHE, 0, SEC_FILE | SEC_IMAGE },
1536 };
1537
1538 /* test case sensitivity */
1539
1540 SetLastError(0xdeadbeef);
1542 "Wine Test Mapping");
1543 ok( handle != NULL, "CreateFileMapping failed with error %lu\n", GetLastError());
1544 ok( GetLastError() == 0, "wrong error %lu\n", GetLastError());
1545
1546 SetLastError(0xdeadbeef);
1548 "Wine Test Mapping");
1549 ok( handle2 != NULL, "CreateFileMapping failed with error %ld\n", GetLastError());
1550 ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %lu\n", GetLastError());
1551 CloseHandle( handle2 );
1552
1553 SetLastError(0xdeadbeef);
1555 "WINE TEST MAPPING");
1556 ok( handle2 != NULL, "CreateFileMapping failed with error %ld\n", GetLastError());
1557 ok( GetLastError() == 0, "wrong error %lu\n", GetLastError());
1558 CloseHandle( handle2 );
1559
1560 SetLastError(0xdeadbeef);
1561 handle2 = OpenFileMappingA( FILE_MAP_ALL_ACCESS, FALSE, "Wine Test Mapping");
1562 ok( handle2 != NULL, "OpenFileMapping failed with error %ld\n", GetLastError());
1563 CloseHandle( handle2 );
1564
1565 SetLastError(0xdeadbeef);
1566 handle2 = OpenFileMappingA( FILE_MAP_ALL_ACCESS, FALSE, "WINE TEST MAPPING");
1567 ok( !handle2, "OpenFileMapping succeeded\n");
1568 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError());
1569
1571
1572 /* test SEC_* flags */
1573
1576 GetTempFileNameA( path, "map", 0, filename );
1577
1579 ok( file[1] != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
1580 SetFilePointer( file[1], 0x2000, NULL, FILE_BEGIN );
1581 SetEndOfFile( file[1] );
1582
1584 strcat( path, "\\kernel32.dll" );
1586 ok( file[2] != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
1587
1588 for (i = 0; i < ARRAY_SIZE(sec_flag_tests); i++)
1589 {
1590 DWORD flags = sec_flag_tests[i].flags;
1591 DWORD perm = sec_flag_tests[i].file == 2 ? PAGE_READONLY : PAGE_READWRITE;
1592 SetLastError( 0xdeadbeef );
1593 handle = CreateFileMappingA( file[sec_flag_tests[i].file], NULL,
1594 flags | perm, 0, 0x1000, "Wine Test Mapping" );
1595 if (sec_flag_tests[i].error)
1596 {
1597 ok( !handle, "%u: CreateFileMapping succeeded\n", i );
1598 ok( GetLastError() == sec_flag_tests[i].error, "%u: wrong error %lu\n", i, GetLastError());
1599 }
1600 else
1601 {
1602 /* SEC_WRITECOMBINE and SEC_IMAGE_NO_EXECUTE not supported on older Windows */
1603 BOOL new_flags = ((flags & SEC_WRITECOMBINE) ||
1605 ok( handle != NULL || broken(new_flags),
1606 "%u: CreateFileMapping failed with error %lu\n", i, GetLastError());
1607 ok( GetLastError() == 0 || broken(new_flags && GetLastError() == ERROR_INVALID_PARAMETER),
1608 "%u: wrong error %lu\n", i, GetLastError());
1609 }
1610
1611 if (handle)
1612 {
1614 DWORD expect = sec_flag_tests[i].attrs ? sec_flag_tests[i].attrs : sec_flag_tests[i].flags;
1615
1616 status = pNtQuerySection( handle, SectionBasicInformation, &info, sizeof(info), NULL );
1617 ok( !status, "%u: NtQuerySection failed err %lx\n", i, status );
1618 /* SEC_NOCACHE not supported on older Windows */
1619 ok( info.Attributes == expect || broken( info.Attributes == (expect & ~SEC_NOCACHE) ),
1620 "%u: NtQuerySection wrong attr %08lx\n", i, info.Attributes );
1622 }
1623 }
1624 CloseHandle( file[1] );
1625 CloseHandle( file[2] );
1627}
1628
1629static void test_IsBadReadPtr(void)
1630{
1631 BOOL ret;
1632 void *ptr = (void *)0xdeadbeef;
1633 char stackvar;
1634
1635 ret = IsBadReadPtr(NULL, 0);
1636 ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1637
1638 ret = IsBadReadPtr(NULL, 1);
1639 ok(ret == TRUE, "Expected IsBadReadPtr to return TRUE, got %d\n", ret);
1640
1641 ret = IsBadReadPtr(ptr, 0);
1642 ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1643
1644 ret = IsBadReadPtr(ptr, 1);
1645 ok(ret == TRUE, "Expected IsBadReadPtr to return TRUE, got %d\n", ret);
1646
1647 ret = IsBadReadPtr(&stackvar, 0);
1648 ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1649
1650 ret = IsBadReadPtr(&stackvar, sizeof(char));
1651 ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1652
1653 ret = IsBadReadPtr((char *)NtCurrentTeb()->DeallocationStack + 4096, sizeof(DWORD));
1654 ok(ret == TRUE, "Expected IsBadReadPtr to return TRUE, got %d\n", ret);
1655
1656 ret = IsBadReadPtr((char *)NtCurrentTeb()->DeallocationStack + 4096, sizeof(DWORD));
1657 ok(ret == TRUE, "Expected IsBadReadPtr to return TRUE, got %d\n", ret);
1658}
1659
1660static void test_IsBadWritePtr(void)
1661{
1662 BOOL ret;
1663 void *ptr = (void *)0xdeadbeef;
1664 char stackval;
1665
1666 ret = IsBadWritePtr(NULL, 0);
1667 ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1668
1669 ret = IsBadWritePtr(NULL, 1);
1670 ok(ret == TRUE, "Expected IsBadWritePtr to return TRUE, got %d\n", ret);
1671
1672 ret = IsBadWritePtr(ptr, 0);
1673 ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1674
1675 ret = IsBadWritePtr(ptr, 1);
1676 ok(ret == TRUE, "Expected IsBadWritePtr to return TRUE, got %d\n", ret);
1677
1678 ret = IsBadWritePtr(&stackval, 0);
1679 ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1680
1681 ret = IsBadWritePtr(&stackval, sizeof(char));
1682 ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1683
1684 ret = IsBadWritePtr((char *)NtCurrentTeb()->DeallocationStack + 4096, sizeof(DWORD));
1685 ok(ret == TRUE, "Expected IsBadWritePtr to return TRUE, got %d\n", ret);
1686
1687 ret = IsBadWritePtr((char *)NtCurrentTeb()->DeallocationStack + 4096, sizeof(DWORD));
1688 ok(ret == TRUE, "Expected IsBadWritePtr to return TRUE, got %d\n", ret);
1689}
1690
1691static void test_IsBadCodePtr(void)
1692{
1693 BOOL ret;
1694 void *ptr = (void *)0xdeadbeef;
1695 char stackval;
1696
1698 ok(ret == TRUE, "Expected IsBadCodePtr to return TRUE, got %d\n", ret);
1699
1700 ret = IsBadCodePtr(ptr);
1701 ok(ret == TRUE, "Expected IsBadCodePtr to return TRUE, got %d\n", ret);
1702
1703 ret = IsBadCodePtr((void *)&stackval);
1704 ok(ret == FALSE, "Expected IsBadCodePtr to return FALSE, got %d\n", ret);
1705}
1706
1708{
1711 void *base;
1713};
1714
1715static const char testdata[] = "Hello World";
1716
1718{
1719 struct read_pipe_args *args = arg;
1720 DWORD num_bytes;
1723 "%u: ConnectNamedPipe failed %lu\n", args->index, GetLastError() );
1724
1725 success = ReadFile( args->pipe, args->base, args->size, &num_bytes, NULL );
1726 ok( success, "%u: ReadFile failed %lu\n", args->index, GetLastError() );
1727 ok( num_bytes == sizeof(testdata), "%u: wrong number of bytes read %lu\n", args->index, num_bytes );
1728 ok( !memcmp( args->base, testdata, sizeof(testdata)),
1729 "%u: didn't receive expected data\n", args->index );
1730 return 0;
1731}
1732
1733static void test_write_watch(void)
1734{
1735 static const char pipename[] = "\\\\.\\pipe\\test_write_watch_pipe";
1736 DWORD ret, size, old_prot, num_bytes;
1738 HANDLE readpipe, writepipe, file;
1739 OVERLAPPED overlapped, *overlapped2;
1740 void *results[64];
1742 ULONG i, pagesize;
1743 BOOL success;
1745
1746 if (!pGetWriteWatch || !pResetWriteWatch)
1747 {
1748 win_skip( "GetWriteWatch not supported\n" );
1749 return;
1750 }
1751
1752 size = 0x10000;
1754 if (!base &&
1756 {
1757 win_skip( "MEM_WRITE_WATCH not supported\n" );
1758 return;
1759 }
1760 ok( base != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
1761 ret = VirtualQuery( base, &info, sizeof(info) );
1762 ok(ret, "VirtualQuery failed %lu\n", GetLastError());
1763 ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
1764 ok( info.AllocationProtect == PAGE_READWRITE, "wrong AllocationProtect %lx\n", info.AllocationProtect );
1765 ok( info.RegionSize == size, "wrong RegionSize 0x%Ix\n", info.RegionSize );
1766 ok( info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State );
1767 ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%lx\n", info.Protect );
1768 ok( info.Type == MEM_PRIVATE, "wrong Type 0x%lx\n", info.Type );
1769
1770 count = 64;
1771 SetLastError( 0xdeadbeef );
1772 ret = pGetWriteWatch( 0, NULL, size, results, &count, &pagesize );
1773 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
1775 broken( GetLastError() == 0xdeadbeef ), /* win98 */
1776 "wrong error %lu\n", GetLastError() );
1777
1778 SetLastError( 0xdeadbeef );
1779 ret = pGetWriteWatch( 0, GetModuleHandleW(NULL), size, results, &count, &pagesize );
1780 if (ret)
1781 {
1782 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
1783 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
1784 }
1785 else /* win98 */
1786 {
1787 ok( count == 0, "wrong count %Iu\n", count );
1788 }
1789
1790 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1791 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1792 ok( count == 0, "wrong count %Iu\n", count );
1793
1794 base[pagesize + 1] = 0x44;
1795
1796 count = 64;
1797 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1798 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1799 ok( count == 1, "wrong count %Iu\n", count );
1800 ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1801
1802 count = 64;
1803 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1804 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1805 ok( count == 1, "wrong count %Iu\n", count );
1806 ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1807
1808 count = 64;
1809 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1810 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1811 ok( count == 0, "wrong count %Iu\n", count );
1812
1813 base[2*pagesize + 3] = 0x11;
1814 base[4*pagesize + 8] = 0x11;
1815
1816 count = 64;
1817 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1818 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1819 ok( count == 2, "wrong count %Iu\n", count );
1820 ok( results[0] == base + 2*pagesize, "wrong result %p\n", results[0] );
1821 ok( results[1] == base + 4*pagesize, "wrong result %p\n", results[1] );
1822
1823 count = 64;
1824 ret = pGetWriteWatch( 0, base + 3*pagesize, 2*pagesize, results, &count, &pagesize );
1825 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1826 ok( count == 1, "wrong count %Iu\n", count );
1827 ok( results[0] == base + 4*pagesize, "wrong result %p\n", results[0] );
1828
1829 ret = pResetWriteWatch( base, 3*pagesize );
1830 ok( !ret, "pResetWriteWatch failed %lu\n", GetLastError() );
1831
1832 count = 64;
1833 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1834 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1835 ok( count == 1, "wrong count %Iu\n", count );
1836 ok( results[0] == base + 4*pagesize, "wrong result %p\n", results[0] );
1837
1838 *(DWORD *)(base + 2*pagesize - 2) = 0xdeadbeef;
1839
1840 count = 64;
1841 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1842 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1843 ok( count == 3, "wrong count %Iu\n", count );
1844 ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1845 ok( results[1] == base + 2*pagesize, "wrong result %p\n", results[1] );
1846 ok( results[2] == base + 4*pagesize, "wrong result %p\n", results[2] );
1847
1848 count = 1;
1849 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1850 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1851 ok( count == 1, "wrong count %Iu\n", count );
1852 ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1853
1854 count = 64;
1855 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1856 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1857 ok( count == 2, "wrong count %Iu\n", count );
1858 ok( results[0] == base + 2*pagesize, "wrong result %p\n", results[0] );
1859 ok( results[1] == base + 4*pagesize, "wrong result %p\n", results[1] );
1860
1861 /* changing protections doesn't affect watches */
1862
1863 ret = VirtualProtect( base, 3*pagesize, PAGE_READONLY, &old_prot );
1864 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() );
1865 ok( old_prot == PAGE_READWRITE, "wrong old prot %lx\n", old_prot );
1866
1867 ret = VirtualQuery( base, &info, sizeof(info) );
1868 ok(ret, "VirtualQuery failed %lu\n", GetLastError());
1869 ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
1870 ok( info.RegionSize == 3*pagesize, "wrong RegionSize 0x%Ix\n", info.RegionSize );
1871 ok( info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State );
1872 ok( info.Protect == PAGE_READONLY, "wrong Protect 0x%lx\n", info.Protect );
1873
1874 ret = VirtualProtect( base, 3*pagesize, PAGE_READWRITE, &old_prot );
1875 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() );
1876 ok( old_prot == PAGE_READONLY, "wrong old prot %lx\n", old_prot );
1877
1878 count = 64;
1879 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1880 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
1881 ok( count == 2, "wrong count %Iu\n", count );
1882 ok( results[0] == base + 2*pagesize, "wrong result %p\n", results[0] );
1883 ok( results[1] == base + 4*pagesize, "wrong result %p\n", results[1] );
1884
1885 ret = VirtualQuery( base, &info, sizeof(info) );
1886 ok(ret, "VirtualQuery failed %lu\n", GetLastError());
1887 ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
1888 ok( info.RegionSize == size, "wrong RegionSize 0x%Ix\n", info.RegionSize );
1889 ok( info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State );
1890 ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%lx\n", info.Protect );
1891
1892 /* ReadFile should trigger write watches */
1893
1894 for (i = 0; i < 2; i++)
1895 {
1896 memset( &overlapped, 0, sizeof(overlapped) );
1897 overlapped.hEvent = CreateEventA( NULL, TRUE, FALSE, NULL );
1898
1900 (i ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE) | PIPE_WAIT, 1, 1024, 1024,
1902 ok( readpipe != INVALID_HANDLE_VALUE, "CreateNamedPipeA failed %lu\n", GetLastError() );
1903
1904 success = ConnectNamedPipe( readpipe, &overlapped );
1905 ok( !success, "%lu: ConnectNamedPipe unexpectedly succeeded\n", i );
1906 ok( GetLastError() == ERROR_IO_PENDING, "%lu: expected ERROR_IO_PENDING, got %lu\n",
1907 i, GetLastError() );
1908
1909 writepipe = CreateFileA( pipename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
1910 ok( writepipe != INVALID_HANDLE_VALUE, "%lu: CreateFileA failed %lu\n", i, GetLastError() );
1911
1912 ret = WaitForSingleObject( overlapped.hEvent, 1000 );
1913 ok( ret == WAIT_OBJECT_0, "%lu: expected WAIT_OBJECT_0, got %lu\n", i, ret );
1914
1915 memset( base, 0, size );
1916
1917 count = 64;
1918 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1919 ok( !ret, "%lu: GetWriteWatch failed %lu\n", i, GetLastError() );
1920 ok( count == 16, "%lu: wrong count %Iu\n", i, count );
1921
1922 success = ReadFile( readpipe, base, size, NULL, &overlapped );
1923 ok( !success, "%lu: ReadFile unexpectedly succeeded\n", i );
1924 ok( GetLastError() == ERROR_IO_PENDING, "%lu: expected ERROR_IO_PENDING, got %lu\n",
1925 i, GetLastError() );
1926
1927 count = 64;
1928 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1929 ok( !ret, "%lu: GetWriteWatch failed %lu\n", i, GetLastError() );
1930 ok( count == 16, "%lu: wrong count %Iu\n", i, count );
1931
1932 num_bytes = 0;
1933 success = WriteFile( writepipe, testdata, sizeof(testdata), &num_bytes, NULL );
1934 ok( success, "%lu: WriteFile failed %lu\n", i, GetLastError() );
1935 ok( num_bytes == sizeof(testdata), "%lu: wrong number of bytes written %lu\n", i, num_bytes );
1936
1937 num_bytes = 0;
1938 success = GetOverlappedResult( readpipe, &overlapped, &num_bytes, TRUE );
1939 ok( success, "%lu: GetOverlappedResult failed %lu\n", i, GetLastError() );
1940 ok( num_bytes == sizeof(testdata), "%lu: wrong number of bytes read %lu\n", i, num_bytes );
1941 ok( !memcmp( base, testdata, sizeof(testdata)), "%lu: didn't receive expected data\n", i );
1942
1943 count = 64;
1944 memset( results, 0, sizeof(results) );
1945 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1946 ok( !ret, "%lu: GetWriteWatch failed %lu\n", i, GetLastError() );
1947 ok( count == 1, "%lu: wrong count %Iu\n", i, count );
1948 ok( results[0] == base, "%lu: wrong result %p\n", i, results[0] );
1949
1950 CloseHandle( readpipe );
1951 CloseHandle( writepipe );
1952 CloseHandle( overlapped.hEvent );
1953 }
1954
1955 for (i = 0; i < 2; i++)
1956 {
1957 struct read_pipe_args args;
1958 HANDLE thread;
1959
1960 readpipe = CreateNamedPipeA( pipename, PIPE_ACCESS_INBOUND,
1961 (i ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE) | PIPE_WAIT, 1, 1024, 1024,
1963 ok( readpipe != INVALID_HANDLE_VALUE, "CreateNamedPipeA failed %lu\n", GetLastError() );
1964
1965 memset( base, 0, size );
1966
1967 count = 64;
1968 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1969 ok( !ret, "%lu: GetWriteWatch failed %lu\n", i, GetLastError() );
1970 ok( count == 16, "%lu: wrong count %Iu\n", i, count );
1971
1972 args.pipe = readpipe;
1973 args.index = i;
1974 args.base = base;
1975 args.size = size;
1976 thread = CreateThread( NULL, 0, read_pipe, &args, 0, NULL );
1977
1978 writepipe = CreateFileA( pipename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
1979 ok( writepipe != INVALID_HANDLE_VALUE, "%lu: CreateFileA failed %lu\n", i, GetLastError() );
1980 Sleep( 200 );
1981
1982 count = 64;
1983 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1984 ok( !ret, "%lu: GetWriteWatch failed %lu\n", i, GetLastError() );
1985 ok( count == 16, "%lu: wrong count %Iu\n", i, count );
1986
1987 num_bytes = 0;
1988 success = WriteFile( writepipe, testdata, sizeof(testdata), &num_bytes, NULL );
1989 ok( success, "%lu: WriteFile failed %lu\n", i, GetLastError() );
1990 ok( num_bytes == sizeof(testdata), "%lu: wrong number of bytes written %lu\n", i, num_bytes );
1991 WaitForSingleObject( thread, 10000 );
1992
1993 count = 64;
1994 memset( results, 0, sizeof(results) );
1995 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1996 ok( !ret, "%lu: GetWriteWatch failed %lu\n", i, GetLastError() );
1997 ok( count == 1, "%lu: wrong count %Iu\n", i, count );
1998 ok( results[0] == base, "%lu: wrong result %p\n", i, results[0] );
1999
2000 CloseHandle( readpipe );
2001 CloseHandle( writepipe );
2003 }
2004
2006 GetTempFileNameA( path, "map", 0, filename );
2008 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
2009 SetFilePointer( file, 2 * pagesize + 3, NULL, FILE_BEGIN );
2010 SetEndOfFile( file );
2012
2013 success = ReadFile( file, base, size, &num_bytes, NULL );
2014 ok( success, "ReadFile failed %lu\n", GetLastError() );
2015 ok( num_bytes == 2 * pagesize + 3, "wrong bytes %lu\n", num_bytes );
2016
2017 count = 64;
2018 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
2019 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2020 ok( count == 16, "wrong count %Iu\n", count );
2021
2022 success = ReadFile( file, base, size, &num_bytes, NULL );
2023 ok( success, "ReadFile failed %lu\n", GetLastError() );
2024 ok( num_bytes == 0, "wrong bytes %lu\n", num_bytes );
2025
2026 count = 64;
2027 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
2028 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2029 ok( count == 16, "wrong count %Iu\n", count );
2030
2031 CloseHandle( file );
2033
2034 success = ReadFile( (HANDLE)0xdead, base, size, &num_bytes, NULL );
2035 ok( !success, "ReadFile succeeded\n" );
2036 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError() );
2037
2038 count = 64;
2039 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
2040 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2041 ok( count == 0, "wrong count %Iu\n", count );
2042
2043 /* OVERLAPPED structure write watch */
2044 memset( &overlapped, 0, sizeof(overlapped) );
2045 overlapped.hEvent = CreateEventA( NULL, TRUE, FALSE, NULL );
2046
2048 PIPE_TYPE_MESSAGE | PIPE_WAIT, 1, 1024, 1024,
2050 ok( readpipe != INVALID_HANDLE_VALUE, "CreateNamedPipeA failed %lu\n", GetLastError() );
2051
2052 success = ConnectNamedPipe( readpipe, &overlapped );
2053 ok( !success, "ConnectNamedPipe unexpectedly succeeded\n" );
2054 ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %lu\n", GetLastError() );
2055
2056 writepipe = CreateFileA( pipename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
2057 ok( writepipe != INVALID_HANDLE_VALUE, "CreateFileA failed %lu\n", GetLastError() );
2058
2059 ret = WaitForSingleObject( overlapped.hEvent, 1000 );
2060 ok( ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %lu\n", ret );
2061
2062 memset( base, 0, size );
2063 overlapped2 = (OVERLAPPED*)(base + size - sizeof(*overlapped2));
2064 overlapped2->hEvent = CreateEventA( NULL, TRUE, FALSE, NULL );
2065
2066 count = 64;
2067 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
2068 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2069 ok( count == 16, "wrong count %Iu\n", count );
2070
2071 success = ReadFile( readpipe, base, sizeof(testdata), NULL, overlapped2 );
2072 ok( !success, "ReadFile unexpectedly succeeded\n" );
2073 ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %lu\n", GetLastError() );
2074 overlapped2->Internal = 0xdeadbeef;
2075
2076 count = 64;
2077 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
2078 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2079 ok( count == 2, "wrong count %Iu\n", count );
2080
2081 num_bytes = 0;
2082 success = WriteFile( writepipe, testdata, sizeof(testdata), &num_bytes, NULL );
2083 ok( success, "WriteFile failed %lu\n", GetLastError() );
2084 ok( num_bytes == sizeof(testdata), "wrong number of bytes written %lu\n", num_bytes );
2085
2086 num_bytes = 0;
2087 success = GetOverlappedResult( readpipe, overlapped2, &num_bytes, TRUE );
2088 ok( success, "GetOverlappedResult failed %lu\n", GetLastError() );
2089 ok( num_bytes == sizeof(testdata), "wrong number of bytes read %lu\n", num_bytes );
2090 ok( !memcmp( base, testdata, sizeof(testdata)), "didn't receive expected data\n" );
2091
2092 count = 64;
2093 memset( results, 0, sizeof(results) );
2094 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
2095 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2096 ok( count == 2, "wrong count %Iu\n", count );
2097 ok( results[0] == base, "wrong result %p\n", results[0] );
2098
2099 CloseHandle( readpipe );
2100 CloseHandle( writepipe );
2101 CloseHandle( overlapped.hEvent );
2102 CloseHandle( overlapped2->hEvent );
2103
2104 /* some invalid parameter tests */
2105
2106 SetLastError( 0xdeadbeef );
2107 count = 0;
2108 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
2109 if (ret)
2110 {
2111 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
2112 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2113
2114 SetLastError( 0xdeadbeef );
2115 ret = pGetWriteWatch( 0, base, size, results, NULL, &pagesize );
2116 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
2117 ok( GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError() );
2118
2119 SetLastError( 0xdeadbeef );
2120 count = 64;
2121 ret = pGetWriteWatch( 0, base, size, results, &count, NULL );
2122 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
2123 ok( GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError() );
2124
2125 SetLastError( 0xdeadbeef );
2126 count = 64;
2127 ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
2128 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
2129 ok( GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError() );
2130
2131 SetLastError( 0xdeadbeef );
2132 count = 0;
2133 ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
2134 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
2135 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2136
2137 SetLastError( 0xdeadbeef );
2138 count = 64;
2139 ret = pGetWriteWatch( 0xdeadbeef, base, size, results, &count, &pagesize );
2140 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
2141 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2142
2143 SetLastError( 0xdeadbeef );
2144 count = 64;
2145 ret = pGetWriteWatch( 0, base, 0, results, &count, &pagesize );
2146 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
2147 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2148
2149 SetLastError( 0xdeadbeef );
2150 count = 64;
2151 ret = pGetWriteWatch( 0, base, size * 2, results, &count, &pagesize );
2152 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
2153 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2154
2155 SetLastError( 0xdeadbeef );
2156 count = 64;
2157 ret = pGetWriteWatch( 0, base + size - pagesize, pagesize + 1, results, &count, &pagesize );
2158 ok( ret == ~0u, "GetWriteWatch succeeded %lu\n", ret );
2159 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2160
2161 SetLastError( 0xdeadbeef );
2162 ret = pResetWriteWatch( base, 0 );
2163 ok( ret == ~0u, "ResetWriteWatch succeeded %lu\n", ret );
2164 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2165
2166 SetLastError( 0xdeadbeef );
2167 ret = pResetWriteWatch( GetModuleHandleW(NULL), size );
2168 ok( ret == ~0u, "ResetWriteWatch succeeded %lu\n", ret );
2169 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2170 }
2171 else /* win98 is completely different */
2172 {
2173 SetLastError( 0xdeadbeef );
2174 count = 64;
2175 ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
2176 ok( ret == ERROR_INVALID_PARAMETER, "GetWriteWatch succeeded %lu\n", ret );
2177 ok( GetLastError() == 0xdeadbeef, "wrong error %lu\n", GetLastError() );
2178
2179 count = 0;
2180 ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
2181 ok( !ret, "GetWriteWatch failed %lu\n", ret );
2182
2183 count = 64;
2184 ret = pGetWriteWatch( 0xdeadbeef, base, size, results, &count, &pagesize );
2185 ok( !ret, "GetWriteWatch failed %lu\n", ret );
2186
2187 count = 64;
2188 ret = pGetWriteWatch( 0, base, 0, results, &count, &pagesize );
2189 ok( !ret, "GetWriteWatch failed %lu\n", ret );
2190
2191 ret = pResetWriteWatch( base, 0 );
2192 ok( !ret, "ResetWriteWatch failed %lu\n", ret );
2193
2194 ret = pResetWriteWatch( GetModuleHandleW(NULL), size );
2195 ok( !ret, "ResetWriteWatch failed %lu\n", ret );
2196 }
2197
2199
2201 ok( base != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
2203
2205 ok( !base, "VirtualAlloc succeeded\n" );
2206 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
2207
2208 /* initial protect doesn't matter */
2209
2211 ok( base != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
2213 ok( base != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
2214
2215 count = 64;
2216 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
2217 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2218 ok( count == 0, "wrong count %Iu\n", count );
2219
2220 ret = VirtualProtect( base, 6*pagesize, PAGE_READWRITE, &old_prot );
2221 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() );
2222 ok( old_prot == PAGE_NOACCESS, "wrong old prot %lx\n", old_prot );
2223
2224 base[5*pagesize + 200] = 3;
2225
2226 ret = VirtualProtect( base, 6*pagesize, PAGE_NOACCESS, &old_prot );
2227 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() );
2228 ok( old_prot == PAGE_READWRITE, "wrong old prot %lx\n", old_prot );
2229
2230 count = 64;
2231 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
2232 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2233 ok( count == 1, "wrong count %Iu\n", count );
2234 ok( results[0] == base + 5*pagesize, "wrong result %p\n", results[0] );
2235
2237 ok( ret, "VirtualFree failed %lu\n", GetLastError() );
2238
2239 count = 64;
2240 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
2241 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2242 ok( count == 1 || broken(count == 0), /* win98 */
2243 "wrong count %Iu\n", count );
2244 if (count) ok( results[0] == base + 5*pagesize, "wrong result %p\n", results[0] );
2245
2247}
2248
2249#if defined(__i386__) || defined(__x86_64__)
2250
2251static DWORD WINAPI stack_commit_func( void *arg )
2252{
2253 volatile char *p = (char *)&p;
2254
2255 /* trigger all guard pages, to ensure that the pages are committed */
2256 while (p >= (char *)NtCurrentTeb()->DeallocationStack + 4 * 0x1000)
2257 {
2258 p[0] |= 0;
2259 p -= 0x1000;
2260 }
2261
2262 ok( arg == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", arg );
2263 return 42;
2264}
2265
2266static void test_stack_commit(void)
2267{
2268#ifdef __i386__
2269 static const char code_call_on_stack[] = {
2270 0x55, /* pushl %ebp */
2271 0x56, /* pushl %esi */
2272 0x89, 0xe6, /* movl %esp,%esi */
2273 0x8b, 0x4c, 0x24, 0x0c, /* movl 12(%esp),%ecx - func */
2274 0x8b, 0x54, 0x24, 0x10, /* movl 16(%esp),%edx - arg */
2275 0x8b, 0x44, 0x24, 0x14, /* movl 20(%esp),%eax - stack */
2276 0x83, 0xe0, 0xf0, /* andl $~15,%eax */
2277 0x83, 0xe8, 0x0c, /* subl $12,%eax */
2278 0x89, 0xc4, /* movl %eax,%esp */
2279 0x52, /* pushl %edx */
2280 0x31, 0xed, /* xorl %ebp,%ebp */
2281 0xff, 0xd1, /* call *%ecx */
2282 0x89, 0xf4, /* movl %esi,%esp */
2283 0x5e, /* popl %esi */
2284 0x5d, /* popl %ebp */
2285 0xc2, 0x0c, 0x00 }; /* ret $12 */
2286#else
2287 static const char code_call_on_stack[] = {
2288 0x55, /* pushq %rbp */
2289 0x48, 0x89, 0xe5, /* movq %rsp,%rbp */
2290 /* %rcx - func, %rdx - arg, %r8 - stack */
2291 0x48, 0x87, 0xca, /* xchgq %rcx,%rdx */
2292 0x49, 0x83, 0xe0, 0xf0, /* andq $~15,%r8 */
2293 0x49, 0x83, 0xe8, 0x20, /* subq $0x20,%r8 */
2294 0x4c, 0x89, 0xc4, /* movq %r8,%rsp */
2295 0xff, 0xd2, /* callq *%rdx */
2296 0x48, 0x89, 0xec, /* movq %rbp,%rsp */
2297 0x5d, /* popq %rbp */
2298 0xc3 }; /* ret */
2299#endif
2300 DWORD (WINAPI *call_on_stack)( DWORD (WINAPI *func)(void *), void *arg, void *stack );
2301 void *old_stack, *old_stack_base, *old_stack_limit;
2302 void *new_stack, *new_stack_base;
2303 DWORD result;
2304
2305 call_on_stack = VirtualAlloc( 0, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
2306 ok( call_on_stack != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
2307 memcpy( call_on_stack, code_call_on_stack, sizeof(code_call_on_stack) );
2308
2309 /* allocate a new stack, only the first guard page is committed */
2310 new_stack = VirtualAlloc( 0, 0x400000, MEM_RESERVE, PAGE_READWRITE );
2311 ok( new_stack != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
2312 new_stack_base = (char *)new_stack + 0x400000;
2313 VirtualAlloc( (char *)new_stack_base - 0x1000, 0x1000, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD );
2314
2315 old_stack = NtCurrentTeb()->DeallocationStack;
2316 old_stack_base = NtCurrentTeb()->Tib.StackBase;
2317 old_stack_limit = NtCurrentTeb()->Tib.StackLimit;
2318
2319 NtCurrentTeb()->DeallocationStack = new_stack;
2320 NtCurrentTeb()->Tib.StackBase = new_stack_base;
2321 NtCurrentTeb()->Tib.StackLimit = new_stack_base;
2322
2323 result = call_on_stack( stack_commit_func, (void *)0xdeadbeef, new_stack_base );
2324
2325 NtCurrentTeb()->DeallocationStack = old_stack;
2326 NtCurrentTeb()->Tib.StackBase = old_stack_base;
2327 NtCurrentTeb()->Tib.StackLimit = old_stack_limit;
2328
2329 ok( result == 42, "expected 42, got %lu\n", result );
2330
2331 VirtualFree( new_stack, 0, MEM_RELEASE );
2332 VirtualFree( call_on_stack, 0, MEM_RELEASE );
2333}
2334
2335#endif /* defined(__i386__) || defined(__x86_64__) */
2336#ifdef __i386__
2337
2338static LONG num_guard_page_calls;
2339
2340static DWORD guard_page_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
2342{
2343 trace( "exception: %08lx flags:%lx addr:%p\n",
2345
2346 ok( rec->NumberParameters == 2, "NumberParameters is %ld instead of 2\n", rec->NumberParameters );
2347 ok( rec->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION, "ExceptionCode is %08lx instead of %08lx\n",
2349
2350 InterlockedIncrement( &num_guard_page_calls );
2351 *(int *)rec->ExceptionInformation[1] += 0x100;
2352
2354}
2355
2356static void test_guard_page(void)
2357{
2360 DWORD ret, size, old_prot;
2362 void *results[64];
2364 ULONG pagesize;
2365 BOOL success;
2366 char *base;
2367
2368 size = 0x1000;
2370 ok( base != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
2371 value = (LONG *)base;
2372
2373 /* verify info structure */
2374 ret = VirtualQuery( base, &info, sizeof(info) );
2375 ok( ret, "VirtualQuery failed %lu\n", GetLastError());
2376 ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
2377 ok( info.AllocationProtect == (PAGE_READWRITE | PAGE_GUARD), "wrong AllocationProtect %lx\n", info.AllocationProtect );
2378 ok( info.RegionSize == size, "wrong RegionSize 0x%Ix\n", info.RegionSize );
2379 ok( info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State );
2380 ok( info.Protect == (PAGE_READWRITE | PAGE_GUARD), "wrong Protect 0x%lx\n", info.Protect );
2381 ok( info.Type == MEM_PRIVATE, "wrong Type 0x%lx\n", info.Type );
2382
2383 /* put some initial value into the memory */
2384 success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
2385 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2386 ok( old_prot == (PAGE_READWRITE | PAGE_GUARD), "wrong old prot %lx\n", old_prot );
2387
2388 *value = 1;
2389 *(value + 1) = 2;
2390
2392 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2393 ok( old_prot == PAGE_READWRITE, "wrong old prot %lx\n", old_prot );
2394
2395 /* test behaviour of VirtualLock - first attempt should fail */
2396 SetLastError( 0xdeadbeef );
2398 ok( !success, "VirtualLock unexpectedly succeeded\n" );
2399 todo_wine
2400 ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION, "wrong error %lu\n", GetLastError() );
2401
2403 todo_wine
2404 ok( success, "VirtualLock failed %lu\n", GetLastError() );
2405 if (success)
2406 {
2407 ok( *value == 1, "memory block contains wrong value, expected 1, got 0x%lx\n", *value );
2409 ok( success, "VirtualUnlock failed %lu\n", GetLastError() );
2410 }
2411
2412 /* check info structure again, PAGE_GUARD should be removed now */
2413 ret = VirtualQuery( base, &info, sizeof(info) );
2414 ok( ret, "VirtualQuery failed %lu\n", GetLastError());
2415 ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
2416 ok( info.AllocationProtect == (PAGE_READWRITE | PAGE_GUARD), "wrong AllocationProtect %lx\n", info.AllocationProtect );
2417 ok( info.RegionSize == size, "wrong RegionSize 0x%Ix\n", info.RegionSize );
2418 ok( info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State );
2419 todo_wine
2420 ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%lx\n", info.Protect );
2421 ok( info.Type == MEM_PRIVATE, "wrong Type 0x%lx\n", info.Type );
2422
2424 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2425 todo_wine
2426 ok( old_prot == PAGE_READWRITE, "wrong old prot %lx\n", old_prot );
2427
2428 /* test directly accessing the memory - we need to setup an exception handler first */
2429 frame.Handler = guard_page_handler;
2430 frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
2431 NtCurrentTeb()->Tib.ExceptionList = &frame;
2432
2433 InterlockedExchange( &num_guard_page_calls, 0 );
2434 InterlockedExchange( &old_value, *value ); /* exception handler increments value by 0x100 */
2435 *value = 2;
2436 ok( old_value == 0x101, "memory block contains wrong value, expected 0x101, got 0x%lx\n", old_value );
2437 ok( num_guard_page_calls == 1, "expected one callback of guard page handler, got %ld calls\n", num_guard_page_calls );
2438
2439 NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
2440
2441 /* check info structure again, PAGE_GUARD should be removed now */
2442 ret = VirtualQuery( base, &info, sizeof(info) );
2443 ok( ret, "VirtualQuery failed %lu\n", GetLastError());
2444 ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%lx\n", info.Protect );
2445
2447 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2448 ok( old_prot == PAGE_READWRITE, "wrong old prot %lx\n", old_prot );
2449
2450 /* test accessing second integer in memory */
2451 frame.Handler = guard_page_handler;
2452 frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
2453 NtCurrentTeb()->Tib.ExceptionList = &frame;
2454
2455 InterlockedExchange( &num_guard_page_calls, 0 );
2456 old_value = *(value + 1);
2457 ok( old_value == 0x102, "memory block contains wrong value, expected 0x102, got 0x%lx\n", old_value );
2458 ok( *value == 2, "memory block contains wrong value, expected 2, got 0x%lx\n", *value );
2459 ok( num_guard_page_calls == 1, "expected one callback of guard page handler, got %ld calls\n", num_guard_page_calls );
2460
2461 NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
2462
2464 ok( success, "VirtualLock failed %lu\n", GetLastError() );
2465 if (success)
2466 {
2467 ok( *value == 2, "memory block contains wrong value, expected 2, got 0x%lx\n", *value );
2469 ok( success, "VirtualUnlock failed %lu\n", GetLastError() );
2470 }
2471
2473
2474 /* combined guard page / write watch tests */
2475 if (!pGetWriteWatch || !pResetWriteWatch)
2476 {
2477 win_skip( "GetWriteWatch not supported, skipping combined guard page / write watch tests\n" );
2478 return;
2479 }
2480
2483 {
2484 win_skip( "MEM_WRITE_WATCH not supported\n" );
2485 return;
2486 }
2487 ok( base != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
2488 value = (LONG *)base;
2489
2490 ret = VirtualQuery( base, &info, sizeof(info) );
2491 ok( ret, "VirtualQuery failed %lu\n", GetLastError() );
2492 ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
2493 ok( info.AllocationProtect == (PAGE_READWRITE | PAGE_GUARD), "wrong AllocationProtect %lx\n", info.AllocationProtect );
2494 ok( info.RegionSize == size, "wrong RegionSize 0x%Ix\n", info.RegionSize );
2495 ok( info.State == MEM_COMMIT, "wrong State 0x%lx\n", info.State );
2496 ok( info.Protect == (PAGE_READWRITE | PAGE_GUARD), "wrong Protect 0x%lx\n", info.Protect );
2497 ok( info.Type == MEM_PRIVATE, "wrong Type 0x%lx\n", info.Type );
2498
2499 count = 64;
2500 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
2501 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2502 ok( count == 0, "wrong count %Iu\n", count );
2503
2504 /* writing to a page should trigger should trigger guard page, even if write watch is set */
2505 frame.Handler = guard_page_handler;
2506 frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
2507 NtCurrentTeb()->Tib.ExceptionList = &frame;
2508
2509 InterlockedExchange( &num_guard_page_calls, 0 );
2510 *value = 1;
2511 *(value + 1) = 2;
2512 ok( num_guard_page_calls == 1, "expected one callback of guard page handler, got %ld calls\n", num_guard_page_calls );
2513
2514 NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
2515
2516 count = 64;
2517 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
2518 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2519 ok( count == 1, "wrong count %Iu\n", count );
2520 ok( results[0] == base, "wrong result %p\n", results[0] );
2521
2523 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2524
2525 /* write watch is triggered from inside of the guard page handler */
2526 frame.Handler = guard_page_handler;
2527 frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
2528 NtCurrentTeb()->Tib.ExceptionList = &frame;
2529
2530 InterlockedExchange( &num_guard_page_calls, 0 );
2531 old_value = *(value + 1); /* doesn't trigger write watch */
2532 ok( old_value == 0x102, "memory block contains wrong value, expected 0x102, got 0x%lx\n", old_value );
2533 ok( *value == 1, "memory block contains wrong value, expected 1, got 0x%lx\n", *value );
2534 ok( num_guard_page_calls == 1, "expected one callback of guard page handler, got %ld calls\n", num_guard_page_calls );
2535
2536 NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
2537
2538 count = 64;
2539 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
2540 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2541 ok( count == 1, "wrong count %Iu\n", count );
2542 ok( results[0] == base, "wrong result %p\n", results[0] );
2543
2545 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2546
2547 /* test behaviour of VirtualLock - first attempt should fail without triggering write watches */
2548 SetLastError( 0xdeadbeef );
2550 ok( !success, "VirtualLock unexpectedly succeeded\n" );
2551 todo_wine
2552 ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION, "wrong error %lu\n", GetLastError() );
2553
2554 count = 64;
2555 ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
2556 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2557 ok( count == 0, "wrong count %Iu\n", count );
2558
2560 todo_wine
2561 ok( success, "VirtualLock failed %lu\n", GetLastError() );
2562 if (success)
2563 {
2564 ok( *value == 1, "memory block contains wrong value, expected 1, got 0x%lx\n", *value );
2566 ok( success, "VirtualUnlock failed %lu\n", GetLastError() );
2567 }
2568
2569 count = 64;
2570 results[0] = (void *)0xdeadbeef;
2571 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
2572 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
2573 todo_wine
2574 ok( count == 1 || broken(count == 0) /* Windows 8 */, "wrong count %Iu\n", count );
2575 todo_wine
2576 ok( results[0] == base || broken(results[0] == (void *)0xdeadbeef) /* Windows 8 */, "wrong result %p\n", results[0] );
2577
2579}
2580
2581static LONG num_execute_fault_calls;
2582
2583static DWORD execute_fault_seh_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
2585{
2587 DWORD err;
2588
2589 trace( "exception: %08lx flags:%lx addr:%p info[0]:%Id info[1]:%p\n",
2591 rec->ExceptionInformation[0], (void *)rec->ExceptionInformation[1] );
2592
2593 ok( rec->NumberParameters == 2, "NumberParameters is %ld instead of 2\n", rec->NumberParameters );
2595 "ExceptionCode is %08lx instead of STATUS_ACCESS_VIOLATION or STATUS_GUARD_PAGE_VIOLATION\n", rec->ExceptionCode );
2596
2598
2600 {
2601
2603 ok( rec->ExceptionInformation[0] == err, "ExceptionInformation[0] is %ld instead of %ld\n",
2604 (DWORD)rec->ExceptionInformation[0], err );
2605
2606 InterlockedIncrement( &num_guard_page_calls );
2607 }
2608 else if (rec->ExceptionCode == STATUS_ACCESS_VIOLATION)
2609 {
2610 DWORD old_prot;
2611 BOOL success;
2612
2614#ifdef __REACTOS__
2616#endif
2617 ok( rec->ExceptionInformation[0] == err, "ExceptionInformation[0] is %ld instead of %ld\n",
2618 (DWORD)rec->ExceptionInformation[0], err );
2619#ifdef __REACTOS__
2620 }
2621#endif
2622
2623 success = VirtualProtect( (void *)rec->ExceptionInformation[1], 16, PAGE_EXECUTE_READWRITE, &old_prot );
2624 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2625#ifdef __REACTOS__
2626 ok( old_prot == PAGE_READWRITE || broken(old_prot == PAGE_NOACCESS) /* WS03 */, "wrong old prot %lx\n", old_prot );
2627#else
2628 ok( old_prot == PAGE_READWRITE, "wrong old prot %lx\n", old_prot );
2629#endif
2630
2631 InterlockedIncrement( &num_execute_fault_calls );
2632 }
2633
2635}
2636
2637static LONG CALLBACK execute_fault_vec_handler( EXCEPTION_POINTERS *ExceptionInfo )
2638{
2639 PEXCEPTION_RECORD rec = ExceptionInfo->ExceptionRecord;
2640 DWORD old_prot;
2641 BOOL success;
2642
2643 trace( "exception: %08lx flags:%lx addr:%p info[0]:%Id info[1]:%p\n",
2645 rec->ExceptionInformation[0], (void *)rec->ExceptionInformation[1] );
2646
2647 ok( rec->NumberParameters == 2, "NumberParameters is %ld instead of 2\n", rec->NumberParameters );
2649 "ExceptionCode is %08lx instead of STATUS_ACCESS_VIOLATION\n", rec->ExceptionCode );
2650
2652 InterlockedIncrement( &num_execute_fault_calls );
2653
2656
2657 success = VirtualProtect( (void *)rec->ExceptionInformation[1], 16, PAGE_EXECUTE_READWRITE, &old_prot );
2658 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2659 ok( old_prot == PAGE_NOACCESS, "wrong old prot %lx\n", old_prot );
2660
2662}
2663
2664static inline DWORD send_message_excpt( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
2665{
2667 DWORD ret;
2668
2669 frame.Handler = execute_fault_seh_handler;
2670 frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
2671 NtCurrentTeb()->Tib.ExceptionList = &frame;
2672
2673 InterlockedExchange( &num_guard_page_calls, 0 );
2674 InterlockedExchange( &num_execute_fault_calls, 0 );
2675 ret = SendMessageA( hWnd, uMsg, wParam, lParam );
2676
2677 NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
2678
2679 return ret;
2680}
2681
2682static inline DWORD call_proc_excpt( DWORD (CALLBACK *code)(void *), void *arg )
2683{
2685 DWORD ret;
2686
2687 frame.Handler = execute_fault_seh_handler;
2688 frame.Prev = NtCurrentTeb()->Tib.ExceptionList;
2689 NtCurrentTeb()->Tib.ExceptionList = &frame;
2690
2691 InterlockedExchange( &num_guard_page_calls, 0 );
2692 InterlockedExchange( &num_execute_fault_calls, 0 );
2693 ret = code( arg );
2694
2695 NtCurrentTeb()->Tib.ExceptionList = frame.Prev;
2696
2697 return ret;
2698}
2699
2700static LRESULT CALLBACK jmp_test_func( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
2701{
2702 if (uMsg == WM_USER)
2703 return 42;
2704
2705 return DefWindowProcA( hWnd, uMsg, wParam, lParam );
2706}
2707
2708static LRESULT CALLBACK atl_test_func( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
2709{
2710 DWORD arg = (DWORD)hWnd;
2711 if (uMsg == WM_USER)
2712 ok( arg == 0x11223344, "arg is 0x%08lx instead of 0x11223344\n", arg );
2713 else
2714 ok( arg != 0x11223344, "arg is unexpectedly 0x11223344\n" );
2715 return 43;
2716}
2717
2718static DWORD CALLBACK atl5_test_func( void )
2719{
2720 return 44;
2721}
2722
2723static void test_atl_thunk_emulation( ULONG dep_flags )
2724{
2725 static const char code_jmp[] = {0xE9, 0x00, 0x00, 0x00, 0x00};
2726 static const char code_atl1[] = {0xC7, 0x44, 0x24, 0x04, 0x44, 0x33, 0x22, 0x11, 0xE9, 0x00, 0x00, 0x00, 0x00};
2727 static const char code_atl2[] = {0xB9, 0x44, 0x33, 0x22, 0x11, 0xE9, 0x00, 0x00, 0x00, 0x00};
2728 static const char code_atl3[] = {0xBA, 0x44, 0x33, 0x22, 0x11, 0xB9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE1};
2729 static const char code_atl4[] = {0xB9, 0x44, 0x33, 0x22, 0x11, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0};
2730 static const char code_atl5[] = {0x59, 0x58, 0x51, 0xFF, 0x60, 0x04};
2731 static const char cls_name[] = "atl_thunk_class";
2732 DWORD ret, size, old_prot;
2733 ULONG old_flags = MEM_EXECUTE_OPTION_ENABLE;
2734 BOOL success, restore_flags = FALSE;
2735 void *results[64];
2737 ULONG pagesize;
2738 WNDCLASSEXA wc;
2739 char *base;
2740 HWND hWnd;
2741
2742 trace( "Running DEP tests with ProcessExecuteFlags = %ld\n", dep_flags );
2743
2744 NtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &old_flags, sizeof(old_flags), NULL );
2745 if (old_flags != dep_flags)
2746 {
2747 ret = NtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &dep_flags, sizeof(dep_flags) );
2748 if (ret == STATUS_INVALID_INFO_CLASS /* Windows 2000 */ ||
2750 {
2751 win_skip( "Skipping DEP tests with ProcessExecuteFlags = %ld\n", dep_flags );
2752 return;
2753 }
2754 ok( !ret, "NtSetInformationProcess failed with status %08lx\n", ret );
2755 restore_flags = TRUE;
2756 }
2757
2758 size = 0x1000;
2760 ok( base != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
2761
2762 /* Check result of GetProcessDEPPolicy */
2763 if (!pGetProcessDEPPolicy)
2764 win_skip( "GetProcessDEPPolicy not supported\n" );
2765 else
2766 {
2767 BOOL (WINAPI *get_dep_policy)(HANDLE, LPDWORD, PBOOL) = (void *)base;
2768 BOOL policy_permanent = 0xdeadbeef;
2769 DWORD policy_flags = 0xdeadbeef;
2770
2771 /* GetProcessDEPPolicy crashes on Windows when a NULL pointer is passed.
2772 * Moreover this function has a bug on Windows 8, which has the effect that
2773 * policy_permanent is set to the content of the CL register instead of 0,
2774 * when the policy is not permanent. To detect that we use an assembler
2775 * wrapper to call the function. */
2776
2777 memcpy( base, code_atl2, sizeof(code_atl2) );
2778 *(DWORD *)(base + 6) = (DWORD_PTR)pGetProcessDEPPolicy - (DWORD_PTR)(base + 10);
2779
2781 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2782
2783 success = get_dep_policy( GetCurrentProcess(), &policy_flags, &policy_permanent );
2784 ok( success, "GetProcessDEPPolicy failed %lu\n", GetLastError() );
2785
2786 ret = 0;
2787 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
2788 ret |= PROCESS_DEP_ENABLE;
2790 ret |= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION;
2791
2792 ok( policy_flags == ret, "expected policy flags %ld, got %ld\n", ret, policy_flags );
2793 ok( !policy_permanent || broken(policy_permanent == 0x44),
2794 "expected policy permanent FALSE, got %d\n", policy_permanent );
2795 }
2796
2797 memcpy( base, code_jmp, sizeof(code_jmp) );
2798 *(DWORD *)(base + 1) = (DWORD_PTR)jmp_test_func - (DWORD_PTR)(base + 5);
2799
2800 /* On Windows, the ATL Thunk emulation is only enabled while running WndProc functions,
2801 * whereas in Wine such a limitation doesn't exist yet. We want to test in a scenario
2802 * where it is active, so that application which depend on that still work properly.
2803 * We have no exception handler enabled yet, so give proper EXECUTE permissions to
2804 * prevent crashes while creating the window. */
2805
2807 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2808
2809 memset( &wc, 0, sizeof(wc) );
2810 wc.cbSize = sizeof(wc);
2812 wc.hInstance = GetModuleHandleA( 0 );
2814 wc.hbrBackground = NULL;
2816 wc.lpfnWndProc = (WNDPROC)base;
2817 success = RegisterClassExA(&wc) != 0;
2818 ok( success, "RegisterClassExA failed %lu\n", GetLastError() );
2819
2820 hWnd = CreateWindowExA(0, cls_name, "Test", WS_TILEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
2821 ok( hWnd != 0, "CreateWindowExA failed %lu\n", GetLastError() );
2822
2823 ret = SendMessageA(hWnd, WM_USER, 0, 0);
2824 ok( ret == 42, "SendMessage returned unexpected result %ld\n", ret );
2825
2826 /* At first try with an instruction which is not recognized as proper ATL thunk
2827 * by the Windows ATL Thunk Emulator. Removing execute permissions will lead to
2828 * STATUS_ACCESS_VIOLATION exceptions when DEP is enabled. */
2829
2830 success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
2831 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2832
2833 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
2834 ok( ret == 42, "call returned wrong result, expected 42, got %ld\n", ret );
2835 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
2837 {
2838 trace( "DEP hardware support is not available\n" );
2839 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2840 dep_flags = MEM_EXECUTE_OPTION_ENABLE;
2841 }
2842 else if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
2843 {
2844 trace( "DEP hardware support is available\n" );
2845#ifdef __REACTOS__
2846 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2847#else
2848 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2849#endif
2850 }
2851 else
2852 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2853
2854 /* Now a bit more complicated, the page containing the code is protected with
2855 * PAGE_GUARD memory protection. */
2856
2858 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2859
2860 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
2861 ok( ret == 42, "call returned wrong result, expected 42, got %ld\n", ret );
2862 ok( num_guard_page_calls == 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
2863 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
2864#ifdef __REACTOS__
2865 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2866#else
2867 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2868#endif
2869 else
2870 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2871
2872 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
2873 ok( ret == 42, "call returned wrong result, expected 42, got %ld\n", ret );
2874 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
2875 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2876
2877 /* Now test with a proper ATL thunk instruction. */
2878
2879 memcpy( base, code_atl1, sizeof(code_atl1) );
2880 *(DWORD *)(base + 9) = (DWORD_PTR)atl_test_func - (DWORD_PTR)(base + 13);
2881
2883 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2884
2885 ret = SendMessageA(hWnd, WM_USER, 0, 0);
2886 ok( ret == 43, "SendMessage returned unexpected result %ld\n", ret );
2887
2888 /* Try executing with PAGE_READWRITE protection. */
2889
2890 success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
2891 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2892
2893 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
2894 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
2895 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
2897#ifdef __REACTOS__
2898 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2899#else
2900 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2901#endif
2902 else
2903 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2904
2905 /* Now a bit more complicated, the page containing the code is protected with
2906 * PAGE_GUARD memory protection. */
2907
2909 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2910
2911 /* the same, but with PAGE_GUARD set */
2912 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
2913 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
2914 ok( num_guard_page_calls == 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
2916#ifdef __REACTOS__
2917 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2918#else
2919 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2920#endif
2921 else
2922 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2923
2924 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
2925 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
2926 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
2927 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2928
2929 /* The following test shows that on Windows, even a vectored exception handler
2930 * cannot intercept internal exceptions thrown by the ATL thunk emulation layer. */
2931
2933 {
2934 if (pRtlAddVectoredExceptionHandler && pRtlRemoveVectoredExceptionHandler)
2935 {
2936 PVOID vectored_handler;
2937
2938 success = VirtualProtect( base, size, PAGE_NOACCESS, &old_prot );
2939 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2940
2941 vectored_handler = pRtlAddVectoredExceptionHandler( TRUE, &execute_fault_vec_handler );
2942 ok( vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n" );
2943
2944 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
2945
2946 pRtlRemoveVectoredExceptionHandler( vectored_handler );
2947
2948 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
2949#ifdef __REACTOS__
2950 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 2) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2951#else
2952 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2953#endif
2954 }
2955 else
2956 win_skip( "RtlAddVectoredExceptionHandler or RtlRemoveVectoredExceptionHandler not found\n" );
2957 }
2958
2959 /* Test alternative ATL thunk instructions. */
2960
2961 memcpy( base, code_atl2, sizeof(code_atl2) );
2962 *(DWORD *)(base + 6) = (DWORD_PTR)atl_test_func - (DWORD_PTR)(base + 10);
2963
2964 success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
2965 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2966
2967 ret = send_message_excpt( hWnd, WM_USER + 1, 0, 0 );
2968 /* FIXME: we don't check the content of the register ECX yet */
2969 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
2970 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
2972#ifdef __REACTOS__
2973 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2974#else
2975 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2976#endif
2977 else
2978 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2979
2980 memcpy( base, code_atl3, sizeof(code_atl3) );
2981 *(DWORD *)(base + 6) = (DWORD_PTR)atl_test_func;
2982
2983 success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
2984 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
2985
2986 ret = send_message_excpt( hWnd, WM_USER + 1, 0, 0 );
2987 /* FIXME: we don't check the content of the registers ECX/EDX yet */
2988 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
2989 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
2991#ifdef __REACTOS__
2992 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2993#else
2994 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2995#endif
2996 else
2997 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
2998
2999 memcpy( base, code_atl4, sizeof(code_atl4) );
3000 *(DWORD *)(base + 6) = (DWORD_PTR)atl_test_func;
3001
3002 success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
3003 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3004
3005 ret = send_message_excpt( hWnd, WM_USER + 1, 0, 0 );
3006 /* FIXME: We don't check the content of the registers EAX/ECX yet */
3007 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
3008 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3010#ifdef __REACTOS__
3011 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3012#else
3013 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3014#endif
3015 else if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
3016 ok( num_execute_fault_calls == 0 || broken(num_execute_fault_calls == 1) /* Windows XP */,
3017 "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3018 else
3019 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3020
3021 memcpy( base, code_atl5, sizeof(code_atl5) );
3022
3023 success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
3024 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3025
3026 results[1] = atl5_test_func;
3027 ret = call_proc_excpt( (void *)base, results );
3028 /* FIXME: We don't check the content of the registers EAX/ECX yet */
3029 ok( ret == 44, "call returned wrong result, expected 44, got %ld\n", ret );
3030 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3032#ifdef __REACTOS__
3033 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3034#else
3035 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3036#endif
3037 else if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
3038 ok( num_execute_fault_calls == 0 || broken(num_execute_fault_calls == 1) /* Windows XP */,
3039 "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3040 else
3041 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3042
3043 /* Restore the JMP instruction, set to executable, and then destroy the Window */
3044
3045 memcpy( base, code_jmp, sizeof(code_jmp) );
3046 *(DWORD *)(base + 1) = (DWORD_PTR)jmp_test_func - (DWORD_PTR)(base + 5);
3047
3049 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3050
3052
3054 ok( success, "UnregisterClass failed %lu\n", GetLastError() );
3055
3057
3058 /* Repeat the tests from above with MEM_WRITE_WATCH protected memory. */
3059
3062 {
3063 win_skip( "MEM_WRITE_WATCH not supported\n" );
3064 goto out;
3065 }
3066 ok( base != NULL, "VirtualAlloc failed %lu\n", GetLastError() );
3067
3068 count = 64;
3069 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
3070 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
3071 ok( count == 0, "wrong count %Iu\n", count );
3072
3073 memcpy( base, code_jmp, sizeof(code_jmp) );
3074 *(DWORD *)(base + 1) = (DWORD_PTR)jmp_test_func - (DWORD_PTR)(base + 5);
3075
3076 count = 64;
3077 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
3078 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
3079 ok( count == 1, "wrong count %Iu\n", count );
3080 ok( results[0] == base, "wrong result %p\n", results[0] );
3081
3082 /* Create a new window class and associated Window (see above) */
3083
3085 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3086
3087 memset( &wc, 0, sizeof(wc) );
3088 wc.cbSize = sizeof(wc);
3090 wc.hInstance = GetModuleHandleA( 0 );
3092 wc.hbrBackground = NULL;
3094 wc.lpfnWndProc = (WNDPROC)base;
3095 success = RegisterClassExA(&wc) != 0;
3096 ok( success, "RegisterClassExA failed %lu\n", GetLastError() );
3097
3098 hWnd = CreateWindowExA(0, cls_name, "Test", WS_TILEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
3099 ok( hWnd != 0, "CreateWindowExA failed %lu\n", GetLastError() );
3100
3101 ret = SendMessageA(hWnd, WM_USER, 0, 0);
3102 ok( ret == 42, "SendMessage returned unexpected result %ld\n", ret );
3103
3104 count = 64;
3105 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
3106 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
3107 ok( count == 0, "wrong count %Iu\n", count );
3108
3109 /* At first try with an instruction which is not recognized as proper ATL thunk
3110 * by the Windows ATL Thunk Emulator. Removing execute permissions will lead to
3111 * STATUS_ACCESS_VIOLATION exceptions when DEP is enabled. */
3112
3113 success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
3114 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3115
3116 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
3117 ok( ret == 42, "call returned wrong result, expected 42, got %ld\n", ret );
3118 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3119 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
3120#ifdef __REACTOS__
3121 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3122#else
3123 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3124#endif
3125 else
3126 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3127
3128 count = 64;
3129 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
3130 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
3131 ok( count == 0, "wrong count %Iu\n", count );
3132
3133 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
3134 ok( ret == 42, "call returned wrong result, expected 42, got %ld\n", ret );
3135 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3136 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3137
3138 /* Now a bit more complicated, the page containing the code is protected with
3139 * PAGE_GUARD memory protection. */
3140
3142 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3143
3144 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
3145 ok( ret == 42, "call returned wrong result, expected 42, got %ld\n", ret );
3146 ok( num_guard_page_calls == 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3147 if (dep_flags & MEM_EXECUTE_OPTION_DISABLE)
3148#ifdef __REACTOS__
3149 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3150#else
3151 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3152#endif
3153 else
3154 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3155
3156 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
3157 ok( ret == 42, "call returned wrong result, expected 42, got %ld\n", ret );
3158 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3159 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3160
3161 count = 64;
3162 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
3163 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
3164 ok( count == 0 || broken(count == 1) /* Windows 8 */, "wrong count %Iu\n", count );
3165
3166 /* Now test with a proper ATL thunk instruction. */
3167
3168 memcpy( base, code_atl1, sizeof(code_atl1) );
3169 *(DWORD *)(base + 9) = (DWORD_PTR)atl_test_func - (DWORD_PTR)(base + 13);
3170
3171 count = 64;
3172 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
3173 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
3174 ok( count == 1, "wrong count %Iu\n", count );
3175 ok( results[0] == base, "wrong result %p\n", results[0] );
3176
3178 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3179
3180 ret = SendMessageA(hWnd, WM_USER, 0, 0);
3181 ok( ret == 43, "SendMessage returned unexpected result %ld\n", ret );
3182
3183 /* Try executing with PAGE_READWRITE protection. */
3184
3185 success = VirtualProtect( base, size, PAGE_READWRITE, &old_prot );
3186 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3187
3188 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
3189 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
3190 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3192#ifdef __REACTOS__
3193 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0), "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3194#else
3195 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3196#endif
3197 else
3198 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3199
3200 count = 64;
3201 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
3202 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
3203 ok( count == 0, "wrong count %Iu\n", count );
3204
3205 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
3206 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
3207 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3208 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3209
3210 /* Now a bit more complicated, the page containing the code is protected with
3211 * PAGE_GUARD memory protection. */
3212
3214 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3215
3216 /* the same, but with PAGE_GUARD set */
3217 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
3218 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
3219 ok( num_guard_page_calls == 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3221#ifdef __REACTOS__
3222 ok( num_execute_fault_calls == 1 || broken(num_execute_fault_calls == 0) /* WS03 */, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3223#else
3224 ok( num_execute_fault_calls == 1, "expected one STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3225#endif
3226 else
3227 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3228
3229 ret = send_message_excpt( hWnd, WM_USER, 0, 0 );
3230 ok( ret == 43, "call returned wrong result, expected 43, got %ld\n", ret );
3231 ok( num_guard_page_calls == 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %ld exceptions\n", num_guard_page_calls );
3232 ok( num_execute_fault_calls == 0, "expected no STATUS_ACCESS_VIOLATION exception, got %ld exceptions\n", num_execute_fault_calls );
3233
3234 count = 64;
3235 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
3236 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
3237 ok( count == 0 || broken(count == 1) /* Windows 8 */, "wrong count %Iu\n", count );
3238
3239 /* Restore the JMP instruction, set to executable, and then destroy the Window */
3240
3241 memcpy( base, code_jmp, sizeof(code_jmp) );
3242 *(DWORD *)(base + 1) = (DWORD_PTR)jmp_test_func - (DWORD_PTR)(base + 5);
3243
3244 count = 64;
3245 ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
3246 ok( !ret, "GetWriteWatch failed %lu\n", GetLastError() );
3247 ok( count == 1, "wrong count %Iu\n", count );
3248 ok( results[0] == base, "wrong result %p\n", results[0] );
3249
3251 ok( success, "VirtualProtect failed %lu\n", GetLastError() );
3252
3254
3256 ok( success, "UnregisterClass failed %lu\n", GetLastError() );
3257
3259
3260out:
3261 if (restore_flags)
3262 {
3263 ret = NtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &old_flags, sizeof(old_flags) );
3264 ok( !ret, "NtSetInformationProcess failed with status %08lx\n", ret );
3265 }
3266}
3267#endif /* __i386__ */
3268
3269static void test_VirtualProtect(void)
3270{
3271 static const struct test_data
3272 {
3273 DWORD prot_set, prot_get;
3274 } td[] =
3275 {
3276 { 0, 0 }, /* 0x00 */
3277 { PAGE_NOACCESS, PAGE_NOACCESS }, /* 0x01 */
3278 { PAGE_READONLY, PAGE_READONLY }, /* 0x02 */
3279 { PAGE_READONLY | PAGE_NOACCESS, 0 }, /* 0x03 */
3280 { PAGE_READWRITE, PAGE_READWRITE }, /* 0x04 */
3281 { PAGE_READWRITE | PAGE_NOACCESS, 0 }, /* 0x05 */
3282 { PAGE_READWRITE | PAGE_READONLY, 0 }, /* 0x06 */
3283 { PAGE_READWRITE | PAGE_READONLY | PAGE_NOACCESS, 0 }, /* 0x07 */
3284 { PAGE_WRITECOPY, 0 }, /* 0x08 */
3285 { PAGE_WRITECOPY | PAGE_NOACCESS, 0 }, /* 0x09 */
3286 { PAGE_WRITECOPY | PAGE_READONLY, 0 }, /* 0x0a */
3287 { PAGE_WRITECOPY | PAGE_NOACCESS | PAGE_READONLY, 0 }, /* 0x0b */
3288 { PAGE_WRITECOPY | PAGE_READWRITE, 0 }, /* 0x0c */
3289 { PAGE_WRITECOPY | PAGE_READWRITE | PAGE_NOACCESS, 0 }, /* 0x0d */
3290 { PAGE_WRITECOPY | PAGE_READWRITE | PAGE_READONLY, 0 }, /* 0x0e */
3292
3293 { PAGE_EXECUTE, PAGE_EXECUTE }, /* 0x10 */
3294 { PAGE_EXECUTE_READ, PAGE_EXECUTE_READ }, /* 0x20 */
3295 { PAGE_EXECUTE_READ | PAGE_EXECUTE, 0 }, /* 0x30 */
3297 { PAGE_EXECUTE_READWRITE | PAGE_EXECUTE, 0 }, /* 0x50 */
3298 { PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ, 0 }, /* 0x60 */
3300 { PAGE_EXECUTE_WRITECOPY, 0 }, /* 0x80 */
3301 { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE, 0 }, /* 0x90 */
3302 { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READ, 0 }, /* 0xa0 */
3308 };
3309 char *base, *ptr;
3310 DWORD ret, old_prot, rw_prot, exec_prot, i, j;
3312 void *addr;
3313 SIZE_T size;
3315
3316 SetLastError(0xdeadbeef);
3318 ok(base != NULL, "VirtualAlloc failed %ld\n", GetLastError());
3319
3320 SetLastError(0xdeadbeef);
3322 ok(!ret, "VirtualProtect should fail\n");
3323 ok(GetLastError() == ERROR_NOACCESS, "expected ERROR_NOACCESS, got %ld\n", GetLastError());
3324 old_prot = 0xdeadbeef;
3326 ok(ret, "VirtualProtect failed %ld\n", GetLastError());
3327 ok(old_prot == PAGE_NOACCESS, "got %#lx != expected PAGE_NOACCESS\n", old_prot);
3328
3329 addr = base;
3330 size = si.dwPageSize;
3331 status = pNtProtectVirtualMemory(GetCurrentProcess(), &addr, &size, PAGE_READONLY, NULL);
3332 ok(status == STATUS_ACCESS_VIOLATION, "NtProtectVirtualMemory should fail, got %08lx\n", status);
3333 addr = base;
3334 size = si.dwPageSize;
3335 old_prot = 0xdeadbeef;
3336 status = pNtProtectVirtualMemory(GetCurrentProcess(), &addr, &size, PAGE_NOACCESS, &old_prot);
3337 ok(status == STATUS_SUCCESS, "NtProtectVirtualMemory should succeed, got %08lx\n", status);
3338 ok(old_prot == PAGE_NOACCESS, "got %#lx != expected PAGE_NOACCESS\n", old_prot);
3339
3340 for (i = 0; i < ARRAY_SIZE(td); i++)
3341 {
3342 SetLastError(0xdeadbeef);
3343 ret = VirtualQuery(base, &info, sizeof(info));
3344 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
3345 ok(info.BaseAddress == base, "%ld: got %p != expected %p\n", i, info.BaseAddress, base);
3346 ok(info.RegionSize == si.dwPageSize, "%ld: got %#Ix != expected %#lx\n", i, info.RegionSize, si.dwPageSize);
3347 ok(info.Protect == PAGE_NOACCESS, "%ld: got %#lx != expected PAGE_NOACCESS\n", i, info.Protect);
3348 ok(info.AllocationBase == base, "%ld: %p != %p\n", i, info.AllocationBase, base);
3349 ok(info.AllocationProtect == PAGE_NOACCESS, "%ld: %#lx != PAGE_NOACCESS\n", i, info.AllocationProtect);
3350 ok(info.State == MEM_COMMIT, "%ld: %#lx != MEM_COMMIT\n", i, info.State);
3351 ok(info.Type == MEM_PRIVATE, "%ld: %#lx != MEM_PRIVATE\n", i, info.Type);
3352
3353 old_prot = 0xdeadbeef;
3354 SetLastError(0xdeadbeef);
3355 ret = VirtualProtect(base, si.dwPageSize, td[i].prot_set, &old_prot);
3356 if (td[i].prot_get)
3357 {
3358 ok(ret, "%ld: VirtualProtect error %ld\n", i, GetLastError());
3359 ok(old_prot == PAGE_NOACCESS, "%ld: got %#lx != expected PAGE_NOACCESS\n", i, old_prot);
3360
3361 SetLastError(0xdeadbeef);
3362 ret = VirtualQuery(base, &info, sizeof(info));
3363 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
3364 ok(info.BaseAddress == base, "%ld: got %p != expected %p\n", i, info.BaseAddress, base);
3365 ok(info.RegionSize == si.dwPageSize, "%ld: got %#Ix != expected %#lx\n", i, info.RegionSize, si.dwPageSize);
3366 ok(info.Protect == td[i].prot_get, "%ld: got %#lx != expected %#lx\n", i, info.Protect, td[i].prot_get);
3367 ok(info.AllocationBase == base, "%ld: %p != %p\n", i, info.AllocationBase, base);
3368 ok(info.AllocationProtect == PAGE_NOACCESS, "%ld: %#lx != PAGE_NOACCESS\n", i, info.AllocationProtect);
3369 ok(info.State == MEM_COMMIT, "%ld: %#lx != MEM_COMMIT\n", i, info.State);
3370 ok(info.Type == MEM_PRIVATE, "%ld: %#lx != MEM_PRIVATE\n", i, info.Type);
3371 }
3372 else
3373 {
3374 ok(!ret, "%ld: VirtualProtect should fail\n", i);
3375 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError());
3376 }
3377
3378 old_prot = 0xdeadbeef;
3379 SetLastError(0xdeadbeef);
3381 ok(ret, "%ld: VirtualProtect error %ld\n", i, GetLastError());
3382 if (td[i].prot_get)
3383 ok(old_prot == td[i].prot_get, "%ld: got %#lx != expected %#lx\n", i, old_prot, td[i].prot_get);
3384 else
3385 ok(old_prot == PAGE_NOACCESS, "%ld: got %#lx != expected PAGE_NOACCESS\n", i, old_prot);
3386 }
3387
3388 exec_prot = 0;
3389
3390 for (i = 0; i <= 4; i++)
3391 {
3392 rw_prot = 0;
3393
3394 for (j = 0; j <= 4; j++)
3395 {
3396 DWORD prot = exec_prot | rw_prot;
3397
3398 SetLastError(0xdeadbeef);
3400 if ((rw_prot && exec_prot) || (!rw_prot && !exec_prot))
3401 {
3402 ok(!ptr, "VirtualAlloc(%02lx) should fail\n", prot);
3403 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
3404 }
3405 else
3406 {
3408 {
3409 ok(!ptr, "VirtualAlloc(%02lx) should fail\n", prot);
3410 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
3411 }
3412 else
3413 {
3414 ok(ptr != NULL, "VirtualAlloc(%02lx) error %ld\n", prot, GetLastError());
3415 ok(ptr == base, "expected %p, got %p\n", base, ptr);
3416 }
3417 }
3418
3419 SetLastError(0xdeadbeef);
3420 ret = VirtualProtect(base, si.dwPageSize, prot, &old_prot);
3421 if ((rw_prot && exec_prot) || (!rw_prot && !exec_prot))
3422 {
3423 ok(!ret, "VirtualProtect(%02lx) should fail\n", prot);
3424 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
3425 }
3426 else
3427 {
3429 {
3430 ok(!ret, "VirtualProtect(%02lx) should fail\n", prot);
3431 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
3432 }
3433 else
3434 ok(ret, "VirtualProtect(%02lx) error %ld\n", prot, GetLastError());
3435 }
3436
3437 rw_prot = 1 << j;
3438 }
3439
3440 exec_prot = 1 << (i + 4);
3441 }
3442
3444}
3445
3447{
3448 switch (prot & 0xff)
3449 {
3450 case PAGE_READWRITE:
3451 case PAGE_WRITECOPY:
3454 return TRUE;
3455
3456 default:
3457 return FALSE;
3458 }
3459}
3460
3462{
3463 static const struct test_data
3464 {
3465 DWORD prot;
3466 BOOL success;
3467 } td[] =
3468 {
3469 { 0, FALSE }, /* 0x00 */
3470 { PAGE_NOACCESS, TRUE }, /* 0x01 */
3471 { PAGE_READONLY, TRUE }, /* 0x02 */
3472 { PAGE_READONLY | PAGE_NOACCESS, FALSE }, /* 0x03 */
3473 { PAGE_READWRITE, TRUE }, /* 0x04 */
3474 { PAGE_READWRITE | PAGE_NOACCESS, FALSE }, /* 0x05 */
3475 { PAGE_READWRITE | PAGE_READONLY, FALSE }, /* 0x06 */
3476 { PAGE_READWRITE | PAGE_READONLY | PAGE_NOACCESS, FALSE }, /* 0x07 */
3477 { PAGE_WRITECOPY, FALSE }, /* 0x08 */
3478 { PAGE_WRITECOPY | PAGE_NOACCESS, FALSE }, /* 0x09 */
3479 { PAGE_WRITECOPY | PAGE_READONLY, FALSE }, /* 0x0a */
3480 { PAGE_WRITECOPY | PAGE_NOACCESS | PAGE_READONLY, FALSE }, /* 0x0b */
3481 { PAGE_WRITECOPY | PAGE_READWRITE, FALSE }, /* 0x0c */
3485
3486 { PAGE_EXECUTE, TRUE }, /* 0x10 */
3487 { PAGE_EXECUTE_READ, TRUE }, /* 0x20 */
3488 { PAGE_EXECUTE_READ | PAGE_EXECUTE, FALSE }, /* 0x30 */
3489 { PAGE_EXECUTE_READWRITE, TRUE }, /* 0x40 */
3490 { PAGE_EXECUTE_READWRITE | PAGE_EXECUTE, FALSE }, /* 0x50 */
3493 { PAGE_EXECUTE_WRITECOPY, FALSE }, /* 0x80 */
3494 { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE, FALSE }, /* 0x90 */
3501 };
3502 char *base, *ptr;
3503 DWORD ret, i;
3505
3506 for (i = 0; i < ARRAY_SIZE(td); i++)
3507 {
3508 SetLastError(0xdeadbeef);
3509 base = VirtualAlloc(0, si.dwPageSize, MEM_COMMIT, td[i].prot);
3510
3511 if (td[i].success)
3512 {
3513 ok(base != NULL, "%ld: VirtualAlloc failed %ld\n", i, GetLastError());
3514
3515 SetLastError(0xdeadbeef);
3516 ret = VirtualQuery(base, &info, sizeof(info));
3517 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
3518 ok(info.BaseAddress == base, "%ld: got %p != expected %p\n", i, info.BaseAddress, base);
3519 ok(info.RegionSize == si.dwPageSize, "%ld: got %#Ix != expected %#lx\n", i, info.RegionSize, si.dwPageSize);
3520 ok(info.Protect == td[i].prot, "%ld: got %#lx != expected %#lx\n", i, info.Protect, td[i].prot);
3521 ok(info.AllocationBase == base, "%ld: %p != %p\n", i, info.AllocationBase, base);
3522 ok(info.AllocationProtect == td[i].prot, "%ld: %#lx != %#lx\n", i, info.AllocationProtect, td[i].prot);
3523 ok(info.State == MEM_COMMIT, "%ld: %#lx != MEM_COMMIT\n", i, info.State);
3524 ok(info.Type == MEM_PRIVATE, "%ld: %#lx != MEM_PRIVATE\n", i, info.Type);
3525
3526 if (is_mem_writable(info.Protect))
3527 {
3528 base[0] = 0xfe;
3529
3530 SetLastError(0xdeadbeef);
3531 ret = VirtualQuery(base, &info, sizeof(info));
3532 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
3533 ok(info.Protect == td[i].prot, "%ld: got %#lx != expected %#lx\n", i, info.Protect, td[i].prot);
3534 }
3535
3536 SetLastError(0xdeadbeef);
3537 ptr = VirtualAlloc(base, si.dwPageSize, MEM_COMMIT, td[i].prot);
3538 ok(ptr == base, "%ld: VirtualAlloc failed %ld\n", i, GetLastError());
3539
3541 }
3542 else
3543 {
3544 ok(!base, "%ld: VirtualAlloc should fail\n", i);
3545 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError());
3546 }
3547 }
3548}
3549
3551{
3552 static const struct test_data
3553 {
3554 DWORD prot;
3555 BOOL success;
3556 DWORD prot_after_write;
3557 } td[] =
3558 {
3559 { 0, FALSE, 0 }, /* 0x00 */
3560 { PAGE_NOACCESS, FALSE, PAGE_NOACCESS }, /* 0x01 */
3561 { PAGE_READONLY, TRUE, PAGE_READONLY }, /* 0x02 */
3563 { PAGE_READWRITE, TRUE, PAGE_READWRITE }, /* 0x04 */
3567 { PAGE_WRITECOPY, TRUE, PAGE_READWRITE }, /* 0x08 */
3575
3576 { PAGE_EXECUTE, FALSE, PAGE_EXECUTE }, /* 0x10 */
3577 { PAGE_EXECUTE_READ, TRUE, PAGE_EXECUTE_READ }, /* 0x20 */
3591 };
3592 char *base, *ptr;
3593 DWORD ret, i, alloc_prot, old_prot;
3595 char temp_path[MAX_PATH];
3596 char file_name[MAX_PATH];
3597 HANDLE hfile, hmap;
3598 BOOL page_exec_supported = TRUE;
3599
3602
3603 SetLastError(0xdeadbeef);
3605 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile(%s) error %ld\n", file_name, GetLastError());
3607 SetEndOfFile(hfile);
3608
3609 for (i = 0; i < ARRAY_SIZE(td); i++)
3610 {
3611 SetLastError(0xdeadbeef);
3612 hmap = CreateFileMappingW(hfile, NULL, td[i].prot | SEC_COMMIT, 0, si.dwPageSize, NULL);
3613
3614 if (td[i].success)
3615 {
3616 if (!hmap)
3617 {
3618 trace("%ld: CreateFileMapping(%04lx) failed: %ld\n", i, td[i].prot, GetLastError());
3619 /* NT4 and win2k don't support EXEC on file mappings */
3620 if (td[i].prot == PAGE_EXECUTE_READ || td[i].prot == PAGE_EXECUTE_READWRITE)
3621 {
3622 page_exec_supported = FALSE;
3623 ok(broken(!hmap), "%ld: CreateFileMapping doesn't support PAGE_EXECUTE\n", i);
3624 continue;
3625 }
3626 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
3627 if (td[i].prot == PAGE_EXECUTE_WRITECOPY)
3628 {
3629 page_exec_supported = FALSE;
3630 ok(broken(!hmap), "%ld: CreateFileMapping doesn't support PAGE_EXECUTE_WRITECOPY\n", i);
3631 continue;
3632 }
3633 }
3634 ok(hmap != 0, "%ld: CreateFileMapping(%04lx) error %ld\n", i, td[i].prot, GetLastError());
3635
3636 base = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0);
3637 ok(base != NULL, "%ld: MapViewOfFile failed %ld\n", i, GetLastError());
3638
3639 SetLastError(0xdeadbeef);
3640 ret = VirtualQuery(base, &info, sizeof(info));
3641 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
3642 ok(info.BaseAddress == base, "%ld: got %p != expected %p\n", i, info.BaseAddress, base);
3643 ok(info.RegionSize == si.dwPageSize, "%ld: got %#Ix != expected %#lx\n", i, info.RegionSize, si.dwPageSize);
3644 ok(info.Protect == PAGE_READONLY, "%ld: got %#lx != expected PAGE_READONLY\n", i, info.Protect);
3645 ok(info.AllocationBase == base, "%ld: %p != %p\n", i, info.AllocationBase, base);
3646 ok(info.AllocationProtect == PAGE_READONLY, "%ld: %#lx != PAGE_READONLY\n", i, info.AllocationProtect);
3647 ok(info.State == MEM_COMMIT, "%ld: %#lx != MEM_COMMIT\n", i, info.State);
3648 ok(info.Type == MEM_MAPPED, "%ld: %#lx != MEM_MAPPED\n", i, info.Type);
3649
3650 SetLastError(0xdeadbeef);
3651 ptr = VirtualAlloc(base, si.dwPageSize, MEM_COMMIT, td[i].prot);
3652 ok(!ptr, "%ld: VirtualAlloc(%02lx) should fail\n", i, td[i].prot);
3653 ok(GetLastError() == ERROR_ACCESS_DENIED, "%ld: expected ERROR_ACCESS_DENIED, got %ld\n", i, GetLastError());
3654
3655 SetLastError(0xdeadbeef);
3656 ret = VirtualProtect(base, si.dwPageSize, td[i].prot, &old_prot);
3657 if (td[i].prot == PAGE_READONLY || td[i].prot == PAGE_WRITECOPY)
3658 ok(ret, "%ld: VirtualProtect(%02lx) error %ld\n", i, td[i].prot, GetLastError());
3659 else
3660 {
3661 ok(!ret, "%ld: VirtualProtect(%02lx) should fail\n", i, td[i].prot);
3662 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError());
3663 }
3664
3666 CloseHandle(hmap);
3667 }
3668 else
3669 {
3670 ok(!hmap, "%ld: CreateFileMapping should fail\n", i);
3671 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError());
3672 }
3673 }
3674
3675 if (page_exec_supported) alloc_prot = PAGE_EXECUTE_READWRITE;
3676 else alloc_prot = PAGE_READWRITE;
3677 SetLastError(0xdeadbeef);
3678 hmap = CreateFileMappingW(hfile, NULL, alloc_prot, 0, si.dwPageSize, NULL);
3679 ok(hmap != 0, "%ld: CreateFileMapping error %ld\n", i, GetLastError());
3680
3681 for (i = 0; i < ARRAY_SIZE(td); i++)
3682 {
3683 SetLastError(0xdeadbeef);
3684 base = MapViewOfFile(hmap, FILE_MAP_READ | FILE_MAP_WRITE | (page_exec_supported ? FILE_MAP_EXECUTE : 0), 0, 0, 0);
3685 ok(base != NULL, "MapViewOfFile failed %ld\n", GetLastError());
3686
3687 old_prot = 0xdeadbeef;
3688 SetLastError(0xdeadbeef);
3690 ok(ret, "VirtualProtect error %ld\n", GetLastError());
3691 ok(old_prot == alloc_prot, "got %#lx != expected %#lx\n", old_prot, alloc_prot);
3692
3693 SetLastError(0xdeadbeef);
3694 ret = VirtualQuery(base, &info, sizeof(info));
3695 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
3696 ok(info.BaseAddress == base, "%ld: got %p != expected %p\n", i, info.BaseAddress, base);
3697 ok(info.RegionSize == si.dwPageSize, "%ld: got %#Ix != expected %#lx\n", i, info.RegionSize, si.dwPageSize);
3698 ok(info.Protect == PAGE_NOACCESS, "%ld: got %#lx != expected PAGE_NOACCESS\n", i, info.Protect);
3699 ok(info.AllocationBase == base, "%ld: %p != %p\n", i, info.AllocationBase, base);
3700 ok(info.AllocationProtect == alloc_prot, "%ld: %#lx != %#lx\n", i, info.AllocationProtect, alloc_prot);
3701 ok(info.State == MEM_COMMIT, "%ld: %#lx != MEM_COMMIT\n", i, info.State);
3702 ok(info.Type == MEM_MAPPED, "%ld: %#lx != MEM_MAPPED\n", i, info.Type);
3703
3704 old_prot = 0xdeadbeef;
3705 SetLastError(0xdeadbeef);
3706 ret = VirtualProtect(base, si.dwPageSize, td[i].prot, &old_prot);
3707 if (td[i].success || td[i].prot == PAGE_NOACCESS || td[i].prot == PAGE_EXECUTE)
3708 {
3709 if (!ret)
3710 {
3711 /* win2k and XP don't support EXEC on file mappings */
3712 if (td[i].prot == PAGE_EXECUTE)
3713 {
3714 ok(broken(!ret), "%ld: VirtualProtect doesn't support PAGE_EXECUTE\n", i);
3715 continue;
3716 }
3717 /* NT4 and win2k don't support EXEC on file mappings */
3718 if (td[i].prot == PAGE_EXECUTE_READ || td[i].prot == PAGE_EXECUTE_READWRITE)
3719 {
3720 ok(broken(!ret), "%ld: VirtualProtect doesn't support PAGE_EXECUTE\n", i);
3721 continue;
3722 }
3723 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
3724 if (td[i].prot == PAGE_EXECUTE_WRITECOPY)
3725 {
3726 ok(broken(!ret), "%ld: VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY\n", i);
3727 continue;
3728 }
3729 }
3730
3731 ok(ret, "%ld: VirtualProtect error %ld\n", i, GetLastError());
3732 ok(old_prot == PAGE_NOACCESS, "%ld: got %#lx != expected PAGE_NOACCESS\n", i, old_prot);
3733
3734 SetLastError(0xdeadbeef);
3735 ret = VirtualQuery(base, &info, sizeof(info));
3736 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
3737 ok(info.BaseAddress == base, "%ld: got %p != expected %p\n", i, info.BaseAddress, base);
3738 ok(info.RegionSize == si.dwPageSize, "%ld: got %#Ix != expected %#lx\n", i, info.RegionSize, si.dwPageSize);
3739 ok(info.Protect == td[i].prot, "%ld: got %#lx != expected %#lx\n", i, info.Protect, td[i].prot);
3740 ok(info.AllocationBase == base, "%ld: %p != %p\n", i, info.AllocationBase, base);
3741 ok(info.AllocationProtect == alloc_prot, "%ld: %#lx != %#lx\n", i, info.AllocationProtect, alloc_prot);
3742 ok(info.State == MEM_COMMIT, "%ld: %#lx != MEM_COMMIT\n", i, info.State);
3743 ok(info.Type == MEM_MAPPED, "%ld: %#lx != MEM_MAPPED\n", i, info.Type);
3744
3745 if (is_mem_writable(info.Protect))
3746 {
3747 base[0] = 0xfe;
3748
3749 SetLastError(0xdeadbeef);
3750 ret = VirtualQuery(base, &info, sizeof(info));
3751 ok(ret, "VirtualQuery failed %ld\n", GetLastError());
3752 /* FIXME: remove the condition below once Wine is fixed */
3753 todo_wine_if (td[i].prot == PAGE_WRITECOPY || td[i].prot == PAGE_EXECUTE_WRITECOPY)
3754 ok(info.Protect == td[i].prot_after_write, "%ld: got %#lx != expected %#lx\n", i, info.Protect, td[i].prot_after_write);
3755 }
3756 }
3757 else
3758 {
3759 ok(!ret, "%ld: VirtualProtect should fail\n", i);
3760 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError());
3761 continue;
3762 }
3763
3764 old_prot = 0xdeadbeef;
3765 SetLastError(0xdeadbeef);
3767 ok(ret, "%ld: VirtualProtect error %ld\n", i, GetLastError());
3768 /* FIXME: remove the condition below once Wine is fixed */
3769 todo_wine_if (td[i].prot == PAGE_WRITECOPY || td[i].prot == PAGE_EXECUTE_WRITECOPY)
3770 ok(old_prot == td[i].prot_after_write, "%ld: got %#lx != expected %#lx\n", i, old_prot, td[i].prot_after_write);
3771
3773 }
3774
3775 CloseHandle(hmap);
3776
3777 CloseHandle(hfile);
3779}
3780
3781#define ACCESS_READ 0x01
3782#define ACCESS_WRITE 0x02
3783#define ACCESS_EXECUTE 0x04
3784
3786{
3787 switch (prot)
3788 {
3789 case PAGE_READONLY:
3790 case PAGE_WRITECOPY:
3791 return ACCESS_READ;
3792 case PAGE_READWRITE:
3793 return ACCESS_READ | ACCESS_WRITE;
3794 case PAGE_EXECUTE:
3795 case PAGE_EXECUTE_READ:
3797 return ACCESS_READ | ACCESS_EXECUTE;
3800 default:
3801 return 0;
3802 }
3803}
3804
3806{
3807 DWORD view_access, prot_access;
3808
3809 view_access = page_prot_to_access(view_prot);
3810 prot_access = page_prot_to_access(prot);
3811
3812 return ((view_access & prot_access) == prot_access);
3813}
3814
3816{
3817 switch (prot)
3818 {
3819 case PAGE_READWRITE:
3823 case PAGE_READONLY:
3824 case PAGE_WRITECOPY:
3826 case PAGE_EXECUTE:
3827 case PAGE_EXECUTE_READ:
3830 default:
3831 return 0;
3832 }
3833}
3834
3836{
3837 switch (prot)
3838 {
3839 case PAGE_READWRITE: return PAGE_WRITECOPY;
3841 default: return prot;
3842 }
3843}
3844
3846{
3847 switch (prot)
3848 {
3849 case PAGE_WRITECOPY: return PAGE_READWRITE;
3851 default: return prot;
3852 }
3853}
3854
3856{
3857 BOOL exec = access & FILE_MAP_EXECUTE;
3858 access &= ~FILE_MAP_EXECUTE;
3859
3862 if (access & FILE_MAP_READ) return exec ? PAGE_EXECUTE_READ : PAGE_READONLY;
3863 return PAGE_NOACCESS;
3864}
3865
3866static BOOL is_compatible_access(DWORD map_prot, DWORD view_prot)
3867{
3868 DWORD access = map_prot_to_access(map_prot);
3869 DWORD view_access = map_prot_to_access( file_access_to_prot( view_prot ));
3870 if (!view_access) view_access = SECTION_MAP_READ;
3871 return (view_access & access) == view_access;
3872}
3873
3875{
3878 SIZE_T count;
3879 ULONG protect;
3880 void *addr;
3881
3882 if (!pNtMapViewOfSection) return NULL;
3883
3884 count = 0;
3885 offset.u.LowPart = 0;
3886 offset.u.HighPart = 0;
3887
3888 protect = file_access_to_prot( access );
3889 addr = NULL;
3890 status = pNtMapViewOfSection(handle, GetCurrentProcess(), &addr, 0, 0, &offset,
3891 &count, 1 /* ViewShare */, 0, protect);
3892 if ((int)status < 0) addr = NULL;
3893 return addr;
3894}
3895
3896static void test_mapping( HANDLE hfile, DWORD sec_flags, BOOL readonly )
3897{
3898 static const DWORD page_prot[] =
3899 {
3902 };
3903 static const struct
3904 {
3905 DWORD access, prot;
3906 } view[] =
3907 {
3908 { 0, PAGE_NOACCESS }, /* 0x00 */
3909 { FILE_MAP_COPY, PAGE_WRITECOPY }, /* 0x01 */
3910 { FILE_MAP_WRITE, PAGE_READWRITE }, /* 0x02 */
3912 { FILE_MAP_READ, PAGE_READONLY }, /* 0x04 */
3913 { FILE_MAP_READ | FILE_MAP_COPY, PAGE_READONLY }, /* 0x05 */
3916 { SECTION_MAP_EXECUTE, PAGE_NOACCESS }, /* 0x08 */
3924 { FILE_MAP_EXECUTE, PAGE_NOACCESS }, /* 0x20 */
3940 };
3941 void *base, *nt_base, *ptr;
3942 DWORD i, j, k, ret, old_prot, prev_prot, alloc_prot;
3943 HANDLE hmap;
3945 BOOL anon_mapping = (hfile == INVALID_HANDLE_VALUE);
3946
3947 trace( "testing %s mapping flags %08lx %s\n", anon_mapping ? "anonymous" : "file",
3948 sec_flags, readonly ? "readonly file" : "" );
3949 for (i = 0; i < ARRAY_SIZE(page_prot); i++)
3950 {
3951 SetLastError(0xdeadbeef);
3952 hmap = CreateFileMappingW(hfile, NULL, page_prot[i] | sec_flags, 0, 2*si.dwPageSize, NULL);
3953
3954 if (readonly && (page_prot[i] == PAGE_READWRITE || page_prot[i] == PAGE_EXECUTE_READ
3955 || page_prot[i] == PAGE_EXECUTE_READWRITE || page_prot[i] == PAGE_EXECUTE_WRITECOPY))
3956 {
3957 todo_wine_if(page_prot[i] == PAGE_EXECUTE_READ || page_prot[i] == PAGE_EXECUTE_WRITECOPY)
3958 {
3959 ok(!hmap, "%ld: CreateFileMapping(%04lx) should fail\n", i, page_prot[i]);
3961 "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
3962 }
3963 if (hmap) CloseHandle(hmap);
3964 continue;
3965 }
3966
3967 if (page_prot[i] == PAGE_NOACCESS)
3968 {
3969 HANDLE hmap2;
3970
3971 ok(!hmap, "CreateFileMapping(PAGE_NOACCESS) should fail\n");
3972 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
3973
3974 /* A trick to create a not accessible mapping */
3975 SetLastError(0xdeadbeef);
3976 if (sec_flags & SEC_IMAGE)
3977 hmap = CreateFileMappingW(hfile, NULL, PAGE_WRITECOPY | sec_flags, 0, si.dwPageSize, NULL);
3978 else
3979 hmap = CreateFileMappingW(hfile, NULL, PAGE_READONLY | sec_flags, 0, si.dwPageSize, NULL);
3980 ok(hmap != 0, "CreateFileMapping(PAGE_READWRITE) error %ld\n", GetLastError());
3981 SetLastError(0xdeadbeef);
3982 ret = DuplicateHandle(GetCurrentProcess(), hmap, GetCurrentProcess(), &hmap2, 0, FALSE, 0);
3983 ok(ret, "DuplicateHandle error %ld\n", GetLastError());
3984 CloseHandle(hmap);
3985 hmap = hmap2;
3986 }
3987 if (page_prot[i] == PAGE_EXECUTE)
3988 {
3989 ok(!hmap, "CreateFileMapping(PAGE_EXECUTE) should fail\n");
3991 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
3992 continue;
3993 }
3994
3995 if (!hmap)
3996 {
3997 trace("%ld: CreateFileMapping(%04lx) failed: %ld\n", i, page_prot[i], GetLastError());
3998
3999 if ((sec_flags & SEC_IMAGE) &&
4000 (page_prot[i] == PAGE_READWRITE || page_prot[i] == PAGE_EXECUTE_READWRITE))
4001 continue; /* SEC_IMAGE doesn't support write access */
4002
4003 /* NT4 and win2k don't support EXEC on file mappings */
4004 if (page_prot[i] == PAGE_EXECUTE_READ || page_prot[i] == PAGE_EXECUTE_READWRITE)
4005 {
4006 ok(broken(!hmap), "%ld: CreateFileMapping doesn't support PAGE_EXECUTE\n", i);
4007 continue;
4008 }
4009 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
4010 if (page_prot[i] == PAGE_EXECUTE_WRITECOPY)
4011 {
4012 ok(broken(!hmap), "%ld: CreateFileMapping doesn't support PAGE_EXECUTE_WRITECOPY\n", i);
4013 continue;
4014 }
4015 }
4016
4017 ok(hmap != 0, "%ld: CreateFileMapping(%04lx) error %ld\n", i, page_prot[i], GetLastError());
4018
4019 for (j = 0; j < ARRAY_SIZE(view); j++)
4020 {
4021 nt_base = map_view_of_file(hmap, view[j].access);
4022 if (nt_base)
4023 {
4024 SetLastError(0xdeadbeef);
4025 ret = VirtualQuery(nt_base, &nt_info, sizeof(nt_info));
4026 ok(ret, "%ld: VirtualQuery failed %ld\n", j, GetLastError());
4027 UnmapViewOfFile(nt_base);
4028 }
4029
4030 SetLastError(0xdeadbeef);
4031 base = MapViewOfFile(hmap, view[j].access, 0, 0, 0);
4032
4033 /* Vista+ supports FILE_MAP_EXECUTE properly, earlier versions don't */
4034 ok(!nt_base == !base ||
4035 broken((view[j].access & FILE_MAP_EXECUTE) && !nt_base != !base),
4036 "%ld: (%04lx/%04lx) NT %p kernel %p\n", j, page_prot[i], view[j].access, nt_base, base);
4037
4038 if (!is_compatible_access(page_prot[i], view[j].access))
4039 {
4040 /* FILE_MAP_EXECUTE | FILE_MAP_COPY broken on XP */
4042 {
4043 ok( broken(base != NULL), "%ld: MapViewOfFile(%04lx/%04lx) should fail\n",
4044 j, page_prot[i], view[j].access);
4046 }
4047 else
4048 {
4049 ok(!base, "%ld: MapViewOfFile(%04lx/%04lx) should fail\n",
4050 j, page_prot[i], view[j].access);
4051 ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %ld\n", GetLastError());
4052 }
4053 continue;
4054 }
4055
4056 /* Vista+ properly supports FILE_MAP_EXECUTE, earlier versions don't */
4057 if (!base && (view[j].access & FILE_MAP_EXECUTE))
4058 {
4059 ok(broken(!base), "%ld: MapViewOfFile(%04lx/%04lx) failed %ld\n", j, page_prot[i], view[j].access, GetLastError());
4060 continue;
4061 }
4062
4063 ok(base != NULL, "%ld: MapViewOfFile(%04lx/%04lx) failed %ld\n", j, page_prot[i], view[j].access, GetLastError());
4064
4065 SetLastError(0xdeadbeef);
4066 ret = VirtualQuery(base, &info, sizeof(info));
4067 ok(ret, "%ld: VirtualQuery failed %ld\n", j, GetLastError());
4068 ok(info.BaseAddress == base, "%ld: (%04lx) got %p, expected %p\n", j, view[j].access, info.BaseAddress, base);
4069 ok(info.RegionSize == 2*si.dwPageSize || (info.RegionSize == si.dwPageSize && (sec_flags & SEC_IMAGE)),
4070 "%ld: (%04lx) got %#Ix != expected %#lx\n", j, view[j].access, info.RegionSize, 2*si.dwPageSize);
4071 if (sec_flags & SEC_IMAGE)
4072 ok(info.Protect == PAGE_READONLY,
4073 "%ld: (%04lx) got %#lx, expected %#lx\n", j, view[j].access, info.Protect, view[j].prot);
4074 else
4075 ok(info.Protect == view[j].prot ||
4076 broken(view[j].prot == PAGE_EXECUTE_READ && info.Protect == PAGE_READONLY) || /* win2k */
4077 broken(view[j].prot == PAGE_EXECUTE_READWRITE && info.Protect == PAGE_READWRITE) || /* win2k */
4078 broken(view[j].prot == PAGE_EXECUTE_WRITECOPY && info.Protect == PAGE_NOACCESS), /* XP */
4079 "%ld: (%04lx) got %#lx, expected %#lx\n", j, view[j].access, info.Protect, view[j].prot);
4080 ok(info.AllocationBase == base, "%ld: (%04lx) got %p, expected %p\n", j, view[j].access, info.AllocationBase, base);
4081 if (sec_flags & SEC_IMAGE)
4082 ok(info.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "%ld: (%04lx) got %#lx, expected %#lx\n",
4083 j, view[j].access, info.AllocationProtect, info.Protect);
4084 else
4085 ok(info.AllocationProtect == info.Protect, "%ld: (%04lx) got %#lx, expected %#lx\n",
4086 j, view[j].access, info.AllocationProtect, info.Protect);
4087 ok(info.State == MEM_COMMIT, "%ld: (%04lx) got %#lx, expected MEM_COMMIT\n", j, view[j].access, info.State);
4088 ok(info.Type == (sec_flags & SEC_IMAGE) ? SEC_IMAGE : MEM_MAPPED,
4089 "%ld: (%04lx) got %#lx, expected MEM_MAPPED\n", j, view[j].access, info.Type);
4090
4091 if (nt_base && base)
4092 {
4093 ok(nt_info.RegionSize == info.RegionSize, "%ld: (%04lx) got %#Ix != expected %#Ix\n", j, view[j].access, nt_info.RegionSize, info.RegionSize);
4094 ok(nt_info.Protect == info.Protect /* Vista+ */ ||
4095 broken(nt_info.AllocationProtect == PAGE_EXECUTE_WRITECOPY && info.Protect == PAGE_NOACCESS), /* XP */
4096 "%ld: (%04lx) got %#lx, expected %#lx\n", j, view[j].access, nt_info.Protect, info.Protect);
4097 ok(nt_info.AllocationProtect == info.AllocationProtect /* Vista+ */ ||
4098 broken(nt_info.AllocationProtect == PAGE_EXECUTE_WRITECOPY && info.Protect == PAGE_NOACCESS), /* XP */
4099 "%ld: (%04lx) got %#lx, expected %#lx\n", j, view[j].access, nt_info.AllocationProtect, info.AllocationProtect);
4100 ok(nt_info.State == info.State, "%ld: (%04lx) got %#lx, expected %#lx\n", j, view[j].access, nt_info.State, info.State);
4101 ok(nt_info.Type == info.Type, "%ld: (%04lx) got %#lx, expected %#lx\n", j, view[j].access, nt_info.Type, info.Type);
4102 }
4103
4104 prev_prot = info.Protect;
4105 alloc_prot = info.AllocationProtect;
4106
4107 for (k = 0; k < ARRAY_SIZE(page_prot); k++)
4108 {
4109 /*trace("map %#x, view %#x, requested prot %#x\n", page_prot[i], view[j].prot, page_prot[k]);*/
4110 DWORD actual_prot = (sec_flags & SEC_IMAGE) ? map_prot_no_write(page_prot[k]) : page_prot[k];
4111 SetLastError(0xdeadbeef);
4112 old_prot = 0xdeadbeef;
4113 ret = VirtualProtect(base, si.dwPageSize, page_prot[k], &old_prot);
4114 if (is_compatible_protection(alloc_prot, actual_prot))
4115 {
4116 /* win2k and XP don't support EXEC on file mappings */
4117 if (!ret && (page_prot[k] == PAGE_EXECUTE || page_prot[k] == PAGE_EXECUTE_WRITECOPY || view[j].prot == PAGE_EXECUTE_WRITECOPY))
4118 {
4119 ok(broken(!ret), "VirtualProtect doesn't support PAGE_EXECUTE\n");
4120 continue;
4121 }
4122
4123 todo_wine_if(readonly && page_prot[k] == PAGE_WRITECOPY && view[j].prot != PAGE_WRITECOPY)
4124 ok(ret, "VirtualProtect error %ld, map %#lx, view %#lx, requested prot %#lx\n", GetLastError(), page_prot[i], view[j].prot, page_prot[k]);
4125 todo_wine_if(readonly && page_prot[k] == PAGE_WRITECOPY && view[j].prot != PAGE_WRITECOPY)
4126 ok(old_prot == prev_prot, "got %#lx, expected %#lx\n", old_prot, prev_prot);
4127 prev_prot = actual_prot;
4128
4129 ret = VirtualQuery(base, &info, sizeof(info));
4130 ok(ret, "%ld: VirtualQuery failed %ld\n", j, GetLastError());
4131 todo_wine_if(readonly && page_prot[k] == PAGE_WRITECOPY && view[j].prot != PAGE_WRITECOPY)
4132 ok(info.Protect == actual_prot,
4133 "VirtualProtect wrong prot, map %#lx, view %#lx, requested prot %#lx got %#lx\n",
4134 page_prot[i], view[j].prot, page_prot[k], info.Protect );
4135 }
4136 else
4137 {
4138 ok(!ret, "VirtualProtect should fail, map %#lx, view %#lx, requested prot %#lx\n", page_prot[i], view[j].prot, page_prot[k]);
4139 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
4140 }
4141 }
4142
4143 for (k = 0; k < ARRAY_SIZE(page_prot); k++)
4144 {
4145 /*trace("map %#x, view %#x, requested prot %#x\n", page_prot[i], view[j].prot, page_prot[k]);*/
4146 SetLastError(0xdeadbeef);
4147 ptr = VirtualAlloc(base, si.dwPageSize, MEM_COMMIT, page_prot[k]);
4148 if (anon_mapping)
4149 {
4150 if (is_compatible_protection(view[j].prot, page_prot[k]))
4151 {
4152 ok(ptr != NULL, "VirtualAlloc error %lu, map %#lx, view %#lx, requested prot %#lx\n",
4153 GetLastError(), page_prot[i], view[j].prot, page_prot[k]);
4154 }
4155 else
4156 {
4157 /* versions <= Vista accept all protections without checking */
4158 ok(!ptr || broken(ptr != NULL),
4159 "VirtualAlloc should fail, map %#lx, view %#lx, requested prot %#lx\n",
4160 page_prot[i], view[j].prot, page_prot[k]);
4162 "wrong error %lu\n", GetLastError());
4163 }
4164 if (ptr)
4165 {
4166 ret = VirtualQuery(base, &info, sizeof(info));
4167 ok(ret, "%ld: VirtualQuery failed %ld\n", j, GetLastError());
4168 ok(info.Protect == page_prot[k] ||
4169 /* if the mapping doesn't have write access,
4170 * broken versions silently switch to WRITECOPY */
4171 broken( info.Protect == map_prot_no_write(page_prot[k]) ),
4172 "VirtualAlloc wrong prot, map %#lx, view %#lx, requested prot %#lx got %#lx\n",
4173 page_prot[i], view[j].prot, page_prot[k], info.Protect );
4174 }
4175 }
4176 else
4177 {
4178 ok(!ptr, "VirtualAlloc(%02lx) should fail\n", page_prot[k]);
4179 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
4180 }
4181 }
4182
4183 if (!anon_mapping && is_compatible_protection(alloc_prot, PAGE_WRITECOPY))
4184 {
4185 ret = VirtualProtect(base, sec_flags & SEC_IMAGE ? si.dwPageSize : 2*si.dwPageSize, PAGE_WRITECOPY, &old_prot);
4186 todo_wine_if(readonly && view[j].prot != PAGE_WRITECOPY)
4187 ok(ret, "VirtualProtect error %ld, map %#lx, view %#lx\n", GetLastError(), page_prot[i], view[j].prot);
4188 if (ret) *(DWORD*)base = 0xdeadbeef;
4189 ret = VirtualQuery(base, &info, sizeof(info));
4190 ok(ret, "%ld: VirtualQuery failed %ld\n", j, GetLastError());
4191 todo_wine
4192 ok(info.Protect == PAGE_READWRITE, "VirtualProtect wrong prot, map %#lx, view %#lx got %#lx\n",
4193 page_prot[i], view[j].prot, info.Protect );
4194 todo_wine_if (!(sec_flags & SEC_IMAGE))
4195 ok(info.RegionSize == si.dwPageSize, "wrong region size %#Ix after write, map %#lx, view %#lx got %#lx\n",
4196 info.RegionSize, page_prot[i], view[j].prot, info.Protect );
4197
4198 prev_prot = info.Protect;
4199 alloc_prot = info.AllocationProtect;
4200
4201 if (!(sec_flags & SEC_IMAGE))
4202 {
4203 ret = VirtualQuery((char*)base + si.dwPageSize, &info, sizeof(info));
4204 ok(ret, "%ld: VirtualQuery failed %ld\n", j, GetLastError());
4205 todo_wine_if(readonly && view[j].prot != PAGE_WRITECOPY)
4206 ok(info.Protect == PAGE_WRITECOPY, "wrong prot, map %#lx, view %#lx got %#lx\n",
4207 page_prot[i], view[j].prot, info.Protect);
4208 }
4209
4210 for (k = 0; k < ARRAY_SIZE(page_prot); k++)
4211 {
4212 DWORD actual_prot = (sec_flags & SEC_IMAGE) ? map_prot_no_write(page_prot[k]) : page_prot[k];
4213 SetLastError(0xdeadbeef);
4214 old_prot = 0xdeadbeef;
4215 ret = VirtualProtect(base, si.dwPageSize, page_prot[k], &old_prot);
4216 if (is_compatible_protection(alloc_prot, actual_prot))
4217 {
4218 /* win2k and XP don't support EXEC on file mappings */
4219 if (!ret && (page_prot[k] == PAGE_EXECUTE || page_prot[k] == PAGE_EXECUTE_WRITECOPY || view[j].prot == PAGE_EXECUTE_WRITECOPY))
4220 {
4221 ok(broken(!ret), "VirtualProtect doesn't support PAGE_EXECUTE\n");
4222 continue;
4223 }
4224
4225 todo_wine_if(readonly && page_prot[k] == PAGE_WRITECOPY && view[j].prot != PAGE_WRITECOPY)
4226 ok(ret, "VirtualProtect error %ld, map %#lx, view %#lx, requested prot %#lx\n", GetLastError(), page_prot[i], view[j].prot, page_prot[k]);
4227 todo_wine_if(readonly && page_prot[k] == PAGE_WRITECOPY && view[j].prot != PAGE_WRITECOPY)
4228 ok(old_prot == prev_prot, "got %#lx, expected %#lx\n", old_prot, prev_prot);
4229
4230 ret = VirtualQuery(base, &info, sizeof(info));
4231 ok(ret, "%ld: VirtualQuery failed %ld\n", j, GetLastError());
4232 todo_wine_if( map_prot_written( page_prot[k] ) != actual_prot )
4233 ok(info.Protect == map_prot_written( page_prot[k] ),
4234 "VirtualProtect wrong prot, map %#lx, view %#lx, requested prot %#lx got %#lx\n",
4235 page_prot[i], view[j].prot, page_prot[k], info.Protect );
4236 prev_prot = info.Protect;
4237 }
4238 else
4239 {
4240 ok(!ret, "VirtualProtect should fail, map %#lx, view %#lx, requested prot %#lx\n", page_prot[i], view[j].prot, page_prot[k]);
4241 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
4242 }
4243 }
4244 }
4246 }
4247
4248 CloseHandle(hmap);
4249 }
4250}
4251
4252static void test_mappings(void)
4253{
4254 char temp_path[MAX_PATH];
4255 char file_name[MAX_PATH];
4256 DWORD data, num_bytes;
4257 HANDLE hfile;
4258
4261
4263 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile(%s) error %ld\n", file_name, GetLastError());
4265 SetEndOfFile(hfile);
4266
4267 test_mapping( hfile, SEC_COMMIT, FALSE );
4268
4269 /* test that file was not modified */
4270 SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
4271 ok(ReadFile(hfile, &data, sizeof(data), &num_bytes, NULL), "ReadFile failed\n");
4272 ok(num_bytes == sizeof(data), "num_bytes = %ld\n", num_bytes);
4273 todo_wine
4274 ok(!data, "data = %lx\n", data);
4275
4276 CloseHandle( hfile );
4277
4279 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile(%s) error %ld\n", file_name, GetLastError());
4280
4281 test_mapping( hfile, SEC_COMMIT, TRUE );
4282
4283 CloseHandle( hfile );
4285
4286 /* SEC_IMAGE mapping */
4288 strcat( file_name, "\\kernel32.dll" );
4289
4291 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile(%s) error %ld\n", file_name, GetLastError());
4292
4293 test_mapping( hfile, SEC_IMAGE, FALSE );
4294
4295 CloseHandle( hfile );
4296
4297 /* now anonymous mappings */
4299}
4300
4301static void test_shared_memory(BOOL is_child)
4302{
4304 LONG *p;
4305
4306 SetLastError(0xdeadbef);
4307 mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "winetest_virtual.c");
4308 ok(mapping != 0, "CreateFileMapping error %ld\n", GetLastError());
4309 if (is_child)
4310 ok(GetLastError() == ERROR_ALREADY_EXISTS, "expected ERROR_ALREADY_EXISTS, got %ld\n", GetLastError());
4311
4312 SetLastError(0xdeadbef);
4314 ok(p != NULL, "MapViewOfFile error %ld\n", GetLastError());
4315
4316 if (is_child)
4317 {
4318 ok(*p == 0x1a2b3c4d, "expected 0x1a2b3c4d in child, got %#lx\n", *p);
4319 }
4320 else
4321 {
4322 char **argv;
4323 char cmdline[MAX_PATH];
4325 STARTUPINFOA si = { sizeof(si) };
4326 DWORD ret;
4327
4328 *p = 0x1a2b3c4d;
4329
4331 sprintf(cmdline, "\"%s\" virtual sharedmem", argv[0]);
4332 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
4333 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
4337 }
4338
4341}
4342
4343static void test_shared_memory_ro(BOOL is_child, DWORD child_access)
4344{
4346 LONG *p;
4347
4348 SetLastError(0xdeadbef);
4349 mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, "winetest_virtual.c_ro");
4350 ok(mapping != 0, "CreateFileMapping error %ld\n", GetLastError());
4351 if (is_child)
4352 ok(GetLastError() == ERROR_ALREADY_EXISTS, "expected ERROR_ALREADY_EXISTS, got %ld\n", GetLastError());
4353
4354 SetLastError(0xdeadbef);
4355 p = MapViewOfFile(mapping, is_child ? child_access : FILE_MAP_READ, 0, 0, 4096);
4356 ok(p != NULL, "MapViewOfFile error %ld\n", GetLastError());
4357
4358 if (is_child)
4359 {
4360 *p = 0xdeadbeef;
4361 }
4362 else
4363 {
4364 char **argv;
4365 char cmdline[MAX_PATH];
4367 STARTUPINFOA si = { sizeof(si) };
4368 DWORD ret;
4369
4371 sprintf(cmdline, "\"%s\" virtual sharedmemro %lx", argv[0], child_access);
4372 ret = CreateProcessA(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
4373 ok(ret, "CreateProcess(%s) error %ld\n", cmdline, GetLastError());
4377
4378 if(child_access & FILE_MAP_WRITE)
4379 ok(*p == 0xdeadbeef, "*p = %lx, expected 0xdeadbeef\n", *p);
4380 else
4381 ok(!*p, "*p = %lx, expected 0\n", *p);
4382 }
4383
4386}
4387
4389{
4390#ifdef __REACTOS__
4391 skip("Cannot build test_PrefetchVirtualMemory() until kernelbase is synced.\n");
4392#else
4393 WIN32_MEMORY_RANGE_ENTRY entries[2];
4394 char stackmem[] = "Test stack mem";
4395 static char testmem[] = "Test memory range data";
4396 unsigned int page_size = si.dwPageSize;
4397 BOOL ret;
4398
4399 if (!pPrefetchVirtualMemory)
4400 {
4401 skip("no PrefetchVirtualMemory in kernelbase\n");
4402 return;
4403 }
4404
4405 ok( !pPrefetchVirtualMemory( GetCurrentProcess(), 0, NULL, 0 ),
4406 "PrefetchVirtualMemory unexpected success on 0 entries\n" );
4407
4408 entries[0].VirtualAddress = ULongToPtr(PtrToUlong(testmem) & -(ULONG_PTR)page_size);
4409 entries[0].NumberOfBytes = page_size;
4410 ret = pPrefetchVirtualMemory( GetCurrentProcess(), 1, entries, 0 );
4411 ok( ret || broken( is_wow64 && GetLastError() == ERROR_INVALID_PARAMETER ) /* win10 1507 */,
4412 "PrefetchVirtualMemory unexpected status on 1 page-aligned entry: %ld\n", GetLastError() );
4413
4414 entries[0].VirtualAddress = testmem;
4415 entries[0].NumberOfBytes = sizeof(testmem);
4416 ret = pPrefetchVirtualMemory( GetCurrentProcess(), 1, entries, 0 );
4417 ok( ret || broken( is_wow64 && GetLastError() == ERROR_INVALID_PARAMETER ) /* win10 1507 */,
4418 "PrefetchVirtualMemory unexpected status on 1 entry: %ld\n", GetLastError() );
4419
4420 entries[0].VirtualAddress = NULL;
4421 entries[0].NumberOfBytes = page_size;
4422 ret = pPrefetchVirtualMemory( GetCurrentProcess(), 1, entries, 0 );
4423 ok( ret ||broken( is_wow64 && GetLastError() == ERROR_INVALID_PARAMETER ) /* win10 1507 */,
4424 "PrefetchVirtualMemory unexpected status on 1 unmapped entry: %ld\n", GetLastError() );
4425
4426 entries[0].VirtualAddress = ULongToPtr(PtrToUlong(testmem) & -(ULONG_PTR)page_size);
4427 entries[0].NumberOfBytes = page_size;
4428 entries[1].VirtualAddress = ULongToPtr(PtrToUlong(stackmem) & -(ULONG_PTR)page_size);
4429 entries[1].NumberOfBytes = page_size;
4430 ret = pPrefetchVirtualMemory( GetCurrentProcess(), 2, entries, 0 );
4431 ok( ret ||broken( is_wow64 && GetLastError() == ERROR_INVALID_PARAMETER ) /* win10 1507 */,
4432 "PrefetchVirtualMemory unexpected status on 2 page-aligned entries: %ld\n", GetLastError() );
4433#endif
4434}
4435
4436static void test_ReadProcessMemory(void)
4437{
4438 BYTE *buf;
4439 DWORD old_prot;
4440 SIZE_T copied;
4441 HANDLE hproc;
4442 void *ptr;
4443 BOOL ret;
4444
4445 buf = malloc(2 * si.dwPageSize);
4446 ok(buf != NULL, "OOM\n");
4448 &hproc, 0, FALSE, DUPLICATE_SAME_ACCESS);
4449 ok(ret, "DuplicateHandle failed %lu\n", GetLastError());
4451 ok(ptr != NULL, "Virtual failed %lu\n", GetLastError());
4453 ok(ret, "VirtualProtect failed %lu\n", GetLastError());
4454
4455 copied = 1;
4457 ok(!ret, "ReadProcessMemory succeeded\n");
4458 ok(!copied, "copied = %Id\n", copied);
4459 ok(GetLastError() == ERROR_PARTIAL_COPY, "GetLastError() = %lu\n", GetLastError());
4460
4462 ok(ret, "ReadProcessMemory failed %lu\n", GetLastError());
4463 ok(copied == si.dwPageSize, "copied = %Id\n", copied);
4464
4465 ret = ReadProcessMemory(hproc, ptr, buf, 2 * si.dwPageSize, &copied);
4466 todo_wine ok(!ret, "ReadProcessMemory succeeded\n");
4467
4468 ret = ReadProcessMemory(hproc, ptr, buf, si.dwPageSize, &copied);
4469 ok(ret, "ReadProcessMemory failed %lu\n", GetLastError());
4470 ok(copied == si.dwPageSize, "copied = %Id\n", copied);
4471
4473 ok(ret, "VirtualFree failed %lu\n", GetLastError());
4474 CloseHandle(hproc);
4475 free(buf);
4476}
4477
4479{
4480 int argc;
4481 char **argv;
4483
4484#if defined(__REACTOS__) && defined(SKIPBADHEAP_K32_WINETEST)
4485 if (is_reactos()) {
4486 ok(FALSE, "FIXME: These tests are too rough on ReactOS heap manager on x64. It will eventually finish but it takes over an hour to complete the test suite with it which isn't acceptable.\n");
4487 return;
4488 }
4489#endif
4490 if (argc >= 3)
4491 {
4492 if (!strcmp(argv[2], "sleep"))
4493 {
4494 Sleep(5000); /* spawned process runs for at most 5 seconds */
4495 return;
4496 }
4497 if (!strcmp(argv[2], "sharedmem"))
4498 {
4500 return;
4501 }
4502 if (!strcmp(argv[2], "sharedmemro"))
4503 {
4505 return;
4506 }
4507 while (1)
4508 {
4509 void *mem;
4510 BOOL ret;
4513 ok(mem != NULL, "VirtualAlloc failed %lu\n", GetLastError());
4514 if (mem == NULL) break;
4516 ok(ret, "VirtualFree failed %lu\n", GetLastError());
4517 if (!ret) break;
4518 }
4519 return;
4520 }
4521
4522 hkernel32 = GetModuleHandleA("kernel32.dll");
4523 hkernelbase = GetModuleHandleA("kernelbase.dll");
4524 hntdll = GetModuleHandleA("ntdll.dll");
4525
4526 pGetWriteWatch = (void *) GetProcAddress(hkernel32, "GetWriteWatch");
4527 pResetWriteWatch = (void *) GetProcAddress(hkernel32, "ResetWriteWatch");
4528 pGetProcessDEPPolicy = (void *)GetProcAddress( hkernel32, "GetProcessDEPPolicy" );
4529 pIsWow64Process = (void *)GetProcAddress( hkernel32, "IsWow64Process" );
4530 pNtAreMappedFilesTheSame = (void *)GetProcAddress( hntdll, "NtAreMappedFilesTheSame" );
4531 pNtCreateSection = (void *)GetProcAddress( hntdll, "NtCreateSection" );
4532 pNtMapViewOfSection = (void *)GetProcAddress( hntdll, "NtMapViewOfSection" );
4533 pNtUnmapViewOfSection = (void *)GetProcAddress( hntdll, "NtUnmapViewOfSection" );
4534 pNtQuerySection = (void *)GetProcAddress( hntdll, "NtQuerySection" );
4535 pRtlAddVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlAddVectoredExceptionHandler" );
4536 pRtlRemoveVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlRemoveVectoredExceptionHandler" );
4537 pNtProtectVirtualMemory = (void *)GetProcAddress( hntdll, "NtProtectVirtualMemory" );
4538 pNtReadVirtualMemory = (void *)GetProcAddress( hntdll, "NtReadVirtualMemory" );
4539 pNtWriteVirtualMemory = (void *)GetProcAddress( hntdll, "NtWriteVirtualMemory" );
4540#ifndef __REACTOS__ // TODO: Enable when kernelbase is fixed. ROSTESTS-414
4541 pPrefetchVirtualMemory = (void *)GetProcAddress( hkernelbase, "PrefetchVirtualMemory" );
4542#endif
4543
4544 GetSystemInfo(&si);
4545 trace("system page size %#lx\n", si.dwPageSize);
4546
4547 if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
4548
4553 test_mappings();
4568#if defined(__i386__) || defined(__x86_64__)
4569 test_stack_commit();
4570#endif
4571#ifdef __i386__
4572 test_guard_page();
4573 /* The following tests should be executed as a last step, and in exactly this
4574 * order, since ATL thunk emulation cannot be enabled anymore on Windows. */
4575 test_atl_thunk_emulation( MEM_EXECUTE_OPTION_ENABLE );
4576 test_atl_thunk_emulation( MEM_EXECUTE_OPTION_DISABLE );
4578#endif
4579}
static int argc
Definition: ServiceArgs.c:12
static struct _test_info results[8]
Definition: SetCursorPos.c:31
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
#define GetNTVersion()
Definition: apitest.h:17
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
HWND hWnd
Definition: settings.c:17
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:20
static HANDLE thread
Definition: service.c:33
#define ULongToPtr(ul)
Definition: basetsd.h:86
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NTSTATUS
Definition: precomp.h:19
#define CloseHandle
Definition: compat.h:739
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:758
@ ExceptionContinueExecution
Definition: compat.h:90
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define FILE_BEGIN
Definition: compat.h:761
#define SECTION_MAP_READ
Definition: compat.h:139
#define UnmapViewOfFile
Definition: compat.h:746
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define FILE_MAP_READ
Definition: compat.h:776
#define CALLBACK
Definition: compat.h:35
#define MapViewOfFile
Definition: compat.h:745
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI IsBadReadPtr(IN LPCVOID lp, IN UINT_PTR ucb)
Definition: except.c:805
BOOL NTAPI IsBadWritePtr(IN LPVOID lp, IN UINT_PTR ucb)
Definition: except.c:883
BOOL NTAPI IsBadCodePtr(FARPROC lpfn)
Definition: except.c:872
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2283
BOOL NTAPI WriteProcessMemory(IN HANDLE hProcess, IN LPVOID lpBaseAddress, IN LPCVOID lpBuffer, IN SIZE_T nSize, OUT SIZE_T *lpNumberOfBytesWritten)
Definition: proc.c:2064
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4749
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1534
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
BOOL WINAPI IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
Definition: sysinfo.c:169
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP __msvcrt_long __cdecl strtol(const char *, char **, int)
Definition: string.c:1833
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
return ret
Definition: mutex.c:146
#define PtrToUlong(u)
Definition: config.h:107
HANDLE NTAPI CreateFileMappingA(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, IN DWORD flProtect, IN DWORD dwMaximumSizeHigh, IN DWORD dwMaximumSizeLow, IN LPCSTR lpName)
Definition: filemap.c:23
HANDLE NTAPI OpenFileMappingA(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCSTR lpName)
Definition: filemap.c:284
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_ACCESS_VIOLATION
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum func
Definition: glext.h:6028
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLenum const GLvoid * addr
Definition: glext.h:9621
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
GLfloat GLfloat p
Definition: glext.h:8902
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
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 * u
Definition: glfuncs.h:240
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 GLint GLint j
Definition: glfuncs.h:250
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:92
@ ProcessExecuteFlags
Definition: winternl.h:1916
const char * filename
Definition: ioapi.h:137
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:221
#define NtCurrentTeb
#define b
Definition: ke_i.h:79
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define win_skip
Definition: minitest.h:67
#define todo_wine_if(is_todo)
Definition: minitest.h:81
#define todo_wine
Definition: minitest.h:80
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define CREATE_ALWAYS
Definition: disk.h:72
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
#define sprintf
Definition: sprintf.c:45
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static DWORD page_size
Definition: loader.c:54
static ACCESS_MASK
Definition: virtual.c:44
static void test_shared_memory(BOOL is_child)
Definition: virtual.c:4301
static void test_PrefetchVirtualMemory(void)
Definition: virtual.c:4388
static void SIZE_T *static PVECTORED_EXCEPTION_HANDLER
Definition: virtual.c:49
static void test_mappings(void)
Definition: virtual.c:4252
static void test_shared_memory_ro(BOOL is_child, DWORD child_access)
Definition: virtual.c:4343
static void test_CreateFileMapping(void)
Definition: virtual.c:1480
static HINSTANCE hkernel32
Definition: virtual.c:38
static void test_IsBadCodePtr(void)
Definition: virtual.c:1691
static void test_write_watch(void)
Definition: virtual.c:1733
static BOOL is_compatible_access(DWORD map_prot, DWORD view_prot)
Definition: virtual.c:3866
static void test_CreateFileMapping_protection(void)
Definition: virtual.c:3550
static const OBJECT_ATTRIBUTES const LARGE_INTEGER ULONG
Definition: virtual.c:44
static void * map_view_of_file(HANDLE handle, DWORD access)
Definition: virtual.c:3874
static void test_NtAreMappedFilesTheSame(void)
Definition: virtual.c:1334
static const OBJECT_ATTRIBUTES const LARGE_INTEGER HANDLE
Definition: virtual.c:45
static DWORD map_prot_to_access(DWORD prot)
Definition: virtual.c:3815
#define ACCESS_WRITE
Definition: virtual.c:3782
static BOOL is_wow64
Definition: virtual.c:40
static DWORD file_access_to_prot(DWORD access)
Definition: virtual.c:3855
static HANDLE create_target_process(const char *arg)
Definition: virtual.c:62
static PVOID ULONG_PTR
Definition: virtual.c:46
static void test_VirtualAlloc(void)
Definition: virtual.c:342
static SYSTEM_INFO si
Definition: virtual.c:39
static void test_VirtualAlloc_protection(void)
Definition: virtual.c:3461
static DWORD page_prot_to_access(DWORD prot)
Definition: virtual.c:3785
static DWORD map_prot_no_write(DWORD prot)
Definition: virtual.c:3835
static PBOOL
Definition: virtual.c:51
static DWORD map_prot_written(DWORD prot)
Definition: virtual.c:3845
static SIZE_T
Definition: virtual.c:41
static SECTION_INFORMATION_CLASS
Definition: virtual.c:48
static void test_MapViewOfFile(void)
Definition: virtual.c:564
static PVOID
Definition: virtual.c:43
static HINSTANCE hntdll
Definition: virtual.c:38
static void test_IsBadReadPtr(void)
Definition: virtual.c:1629
static HINSTANCE hkernelbase
Definition: virtual.c:38
static PVOID SIZE_T ULONG *static const void void SIZE_T *static void const void SIZE_T *static PWIN32_MEMORY_RANGE_ENTRY
Definition: virtual.c:57
static LPVOID
Definition: virtual.c:41
#define ACCESS_READ
Definition: virtual.c:3781
static LPDWORD
Definition: virtual.c:51
static void test_VirtualAllocEx(void)
Definition: virtual.c:80
#define MAPPING_SIZE
Definition: virtual.c:36
static DWORD CALLBACK read_pipe(void *arg)
Definition: virtual.c:1717
static void test_VirtualProtect(void)
Definition: virtual.c:3269
static void test_ReadProcessMemory(void)
Definition: virtual.c:4436
#define ACCESS_EXECUTE
Definition: virtual.c:3783
static BOOL is_compatible_protection(DWORD view_prot, DWORD prot)
Definition: virtual.c:3805
static BOOL is_mem_writable(DWORD prot)
Definition: virtual.c:3446
static void test_IsBadWritePtr(void)
Definition: virtual.c:1660
static void test_mapping(HANDLE hfile, DWORD sec_flags, BOOL readonly)
Definition: virtual.c:3896
static ULONG * old_value
Definition: directory.c:54
static const char cls_name[]
Definition: compobj.c:2476
static LPCWSTR file_name
Definition: protocol.c:147
int k
Definition: mpi.c:3369
#define argv
Definition: mplay32.c:18
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
unsigned int UINT
Definition: ndis.h:50
#define MEM_EXECUTE_OPTION_DISABLE
Definition: mmtypes.h:73
#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
Definition: mmtypes.h:75
#define SEC_NOCACHE
Definition: mmtypes.h:101
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SEC_IMAGE
Definition: mmtypes.h:97
#define MEM_EXECUTE_OPTION_ENABLE
Definition: mmtypes.h:74
#define SEC_FILE
Definition: mmtypes.h:96
#define SEC_LARGE_PAGES
Definition: mmtypes.h:103
#define SEC_WRITECOMBINE
Definition: mmtypes.h:102
#define MEM_WRITE_WATCH
Definition: mmtypes.h:86
@ SectionBasicInformation
Definition: mmtypes.h:195
@ SectionImageInformation
Definition: mmtypes.h:196
BOOL WINAPI ConnectNamedPipe(IN HANDLE hNamedPipe, IN LPOVERLAPPED lpOverlapped)
Definition: npipe.c:701
HANDLE WINAPI CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: npipe.c:220
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1293
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define PAGE_WRITECOPY
Definition: nt_native.h:1308
#define MEM_FREE
Definition: nt_native.h:1320
#define SECTION_MAP_WRITE
Definition: nt_native.h:1291
#define PAGE_NOCACHE
Definition: nt_native.h:1314
#define MEM_DECOMMIT
Definition: nt_native.h:1318
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1310
#define MEM_RESET
Definition: nt_native.h:1323
#define SECTION_QUERY
Definition: nt_native.h:1290
#define MEM_PRIVATE
Definition: nt_native.h:1321
#define PAGE_EXECUTE
Definition: nt_native.h:1309
#define SEC_RESERVE
Definition: nt_native.h:1326
#define MEM_MAPPED
Definition: nt_native.h:1322
@ ViewShare
Definition: nt_native.h:1281
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1312
#define BOOL
Definition: nt_native.h:43
#define MEM_RESERVE
Definition: nt_native.h:1317
#define MEM_RELEASE
Definition: nt_native.h:1319
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
#define MEM_COMMIT
Definition: nt_native.h:1316
#define GENERIC_EXECUTE
Definition: nt_native.h:91
#define PAGE_NOACCESS
Definition: nt_native.h:1305
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1311
#define PAGE_GUARD
Definition: nt_native.h:1313
NTSTATUS NTAPI NtSetInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)
Definition: query.c:1389
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:211
#define STATUS_INVALID_VIEW_SIZE
Definition: ntstatus.h:361
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:651
#define STATUS_SECTION_NOT_IMAGE
Definition: ntstatus.h:403
#define STATUS_INVALID_IMAGE_NOT_MZ
Definition: ntstatus.h:633
#define STATUS_INVALID_FILE_FOR_SECTION
Definition: ntstatus.h:362
#define STATUS_MAPPED_FILE_SIZE_ZERO
Definition: ntstatus.h:616
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:354
#define STATUS_SECTION_TOO_BIG
Definition: ntstatus.h:394
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
#define STATUS_GUARD_PAGE_VIOLATION
Definition: ntstatus.h:262
#define STATUS_PARTIAL_COPY
Definition: ntstatus.h:273
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:542
#define WS_TILEDWINDOW
Definition: pedump.c:643
long LONG
Definition: pedump.c:60
#define err(...)
strcat
Definition: string.h:92
#define is_reactos()
Definition: test.h:1041
int winetest_get_mainargs(char ***pargv)
#define wait_child_process
Definition: test.h:177
#define EXCEPTION_EXECUTE_FAULT
#define EXCEPTION_READ_FAULT
#define memset(x, y, z)
Definition: compat.h:39
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define STATUS_SUCCESS
Definition: shellext.h:65
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED * overlapped
Definition: sock.c:81
TCHAR * cmdline
Definition: stretchblt.cpp:32
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
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
PEXCEPTION_ROUTINE Handler
Definition: compat.h:727
struct _EXCEPTION_REGISTRATION_RECORD * Prev
Definition: exception.h:45
HANDLE hEvent
Definition: minwinbase.h:230
ULONG_PTR Internal
Definition: minwinbase.h:219
DWORD dwPageSize
Definition: winbase.h:898
HINSTANCE hInstance
Definition: winuser.h:3308
HCURSOR hCursor
Definition: winuser.h:3310
UINT style
Definition: winuser.h:3304
UINT cbSize
Definition: winuser.h:3303
WNDPROC lpfnWndProc
Definition: winuser.h:3305
LPCSTR lpszClassName
Definition: winuser.h:3313
HBRUSH hbrBackground
Definition: winuser.h:3311
Definition: match.c:390
Definition: inflate.c:139
Definition: http.c:7252
Definition: fci.c:127
Definition: mem.c:349
Definition: name.c:39
void * base
Definition: virtual.c:1711
HANDLE pipe
Definition: virtual.c:1709
Definition: format.c:80
Definition: ps.c:97
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: pdh_main.c:96
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:65
BOOL NTAPI VirtualProtect(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:135
LPVOID NTAPI VirtualAllocEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:23
BOOL NTAPI VirtualProtectEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:153
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:119
SIZE_T NTAPI VirtualQueryEx(IN HANDLE hProcess, IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:227
BOOL NTAPI VirtualUnlock(IN LPVOID lpAddress, IN SIZE_T dwSize)
Definition: virtmem.c:258
SIZE_T NTAPI VirtualQuery(IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:211
BOOL NTAPI VirtualFreeEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:83
BOOL NTAPI VirtualLock(IN LPVOID lpAddress, IN SIZE_T dwSize)
Definition: virtmem.c:183
#define success(from, fromstr, to, tostr)
#define PIPE_ACCESS_INBOUND
Definition: winbase.h:167
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FILE_MAP_WRITE
Definition: winbase.h:156
#define NMPWAIT_USE_DEFAULT_WAIT
Definition: winbase.h:136
#define FILE_MAP_ALL_ACCESS
Definition: winbase.h:158
#define FILE_MAP_COPY
Definition: winbase.h:155
#define FILE_MAP_EXECUTE
Definition: winbase.h:159
#define PIPE_WAIT
Definition: winbase.h:173
#define PIPE_TYPE_BYTE
Definition: winbase.h:169
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define PIPE_TYPE_MESSAGE
Definition: winbase.h:170
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define ERROR_PARTIAL_COPY
Definition: winerror.h:424
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define ERROR_BAD_EXE_FORMAT
Definition: winerror.h:373
#define ERROR_NOACCESS
Definition: winerror.h:902
#define ERROR_PIPE_CONNECTED
Definition: winerror.h:624
#define WRITE_WATCH_FLAG_RESET
Definition: winnt_old.h:612
#define AT_ROUND_TO_PAGE
Definition: winnt_old.h:617
#define SEC_IMAGE_NO_EXECUTE
Definition: winnt_old.h:604
#define CS_VREDRAW
Definition: winuser.h:666
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CS_HREDRAW
Definition: winuser.h:661
#define IDC_ARROW
Definition: winuser.h:695
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
ATOM WINAPI RegisterClassExA(_In_ CONST WNDCLASSEXA *)
#define WM_USER
Definition: winuser.h:1923
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:3008
BOOL WINAPI DestroyWindow(_In_ HWND)
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2442
#define PF_NX_ENABLED
Definition: ketypes.h:188
#define DUPLICATE_SAME_ACCESS
const char * LPCSTR
Definition: xmlstorage.h:183
unsigned char BYTE
Definition: xxhash.c:193