2 * Unit test suite for Virtual* family of APIs.
4 * Copyright 2004 Dmitry Timoshkov
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.
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.
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
25 #define WIN32_NO_STATUS
33 #include "wine/test.h"
36 #define MAPPING_SIZE 0x100000
38 static HINSTANCE hkernel32
, hntdll
;
39 static LPVOID (WINAPI
*pVirtualAllocEx
)(HANDLE
, LPVOID
, SIZE_T
, DWORD
, DWORD
);
40 static BOOL (WINAPI
*pVirtualFreeEx
)(HANDLE
, LPVOID
, SIZE_T
, DWORD
);
41 static UINT (WINAPI
*pGetWriteWatch
)(DWORD
,LPVOID
,SIZE_T
,LPVOID
*,ULONG_PTR
*,ULONG
*);
42 static UINT (WINAPI
*pResetWriteWatch
)(LPVOID
,SIZE_T
);
43 static NTSTATUS (WINAPI
*pNtAreMappedFilesTheSame
)(PVOID
,PVOID
);
44 static NTSTATUS (WINAPI
*pNtMapViewOfSection
)(HANDLE
, HANDLE
, PVOID
*, ULONG
, SIZE_T
, const LARGE_INTEGER
*, SIZE_T
*, ULONG
, ULONG
, ULONG
);
45 static DWORD (WINAPI
*pNtUnmapViewOfSection
)(HANDLE
, PVOID
);
46 static struct _TEB
* (WINAPI
*pNtCurrentTeb
)(void);
47 static PVOID (WINAPI
*pRtlAddVectoredExceptionHandler
)(ULONG
, PVECTORED_EXCEPTION_HANDLER
);
48 static ULONG (WINAPI
*pRtlRemoveVectoredExceptionHandler
)(PVOID
);
50 /* ############################### */
52 static HANDLE
create_target_process(const char *arg
)
55 char cmdline
[MAX_PATH
];
56 PROCESS_INFORMATION pi
;
58 STARTUPINFOA si
= { 0 };
61 winetest_get_mainargs( &argv
);
62 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], arg
);
63 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
64 ok(ret
, "error: %u\n", GetLastError());
65 ret
= CloseHandle(pi
.hThread
);
66 ok(ret
, "error %u\n", GetLastError());
70 static void test_VirtualAllocEx(void)
72 const unsigned int alloc_size
= 1<<15;
74 SIZE_T bytes_written
= 0, bytes_read
= 0, i
;
78 MEMORY_BASIC_INFORMATION info
;
81 /* not exported in all windows-versions */
82 if ((!pVirtualAllocEx
) || (!pVirtualFreeEx
)) {
83 win_skip("Virtual{Alloc,Free}Ex not available\n");
87 hProcess
= create_target_process("sleep");
88 ok(hProcess
!= NULL
, "Can't start process\n");
90 SetLastError(0xdeadbeef);
91 addr1
= pVirtualAllocEx(hProcess
, NULL
, alloc_size
, MEM_COMMIT
,
92 PAGE_EXECUTE_READWRITE
);
93 if (!addr1
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
95 win_skip("VirtualAllocEx not implemented\n");
96 TerminateProcess(hProcess
, 0);
97 CloseHandle(hProcess
);
101 src
= VirtualAlloc( NULL
, alloc_size
, MEM_COMMIT
, PAGE_READWRITE
);
102 dst
= VirtualAlloc( NULL
, alloc_size
, MEM_COMMIT
, PAGE_READWRITE
);
103 for (i
= 0; i
< alloc_size
; i
++)
106 ok(addr1
!= NULL
, "VirtualAllocEx error %u\n", GetLastError());
107 b
= WriteProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_written
);
108 ok(b
&& (bytes_written
== alloc_size
), "%lu bytes written\n",
110 b
= ReadProcessMemory(hProcess
, addr1
, dst
, alloc_size
, &bytes_read
);
111 ok(b
&& (bytes_read
== alloc_size
), "%lu bytes read\n", bytes_read
);
112 ok(!memcmp(src
, dst
, alloc_size
), "Data from remote process differs\n");
114 /* test invalid source buffers */
116 b
= VirtualProtect( src
+ 0x2000, 0x2000, PAGE_NOACCESS
, &old_prot
);
117 ok( b
, "VirtualProtect failed error %u\n", GetLastError() );
118 b
= WriteProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_written
);
119 ok( !b
, "WriteProcessMemory succeeded\n" );
120 ok( GetLastError() == ERROR_NOACCESS
||
121 GetLastError() == ERROR_PARTIAL_COPY
, /* vista */
122 "wrong error %u\n", GetLastError() );
123 ok( bytes_written
== 0, "%lu bytes written\n", bytes_written
);
124 b
= ReadProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_read
);
125 ok( !b
, "ReadProcessMemory succeeded\n" );
126 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
127 ok( bytes_read
== 0, "%lu bytes written\n", bytes_read
);
129 b
= VirtualProtect( src
, 0x2000, PAGE_NOACCESS
, &old_prot
);
130 ok( b
, "VirtualProtect failed error %u\n", GetLastError() );
131 b
= WriteProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_written
);
132 ok( !b
, "WriteProcessMemory succeeded\n" );
133 ok( GetLastError() == ERROR_NOACCESS
||
134 GetLastError() == ERROR_PARTIAL_COPY
, /* vista */
135 "wrong error %u\n", GetLastError() );
136 ok( bytes_written
== 0, "%lu bytes written\n", bytes_written
);
137 b
= ReadProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_read
);
138 ok( !b
, "ReadProcessMemory succeeded\n" );
139 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
140 ok( bytes_read
== 0, "%lu bytes written\n", bytes_read
);
142 b
= pVirtualFreeEx(hProcess
, addr1
, 0, MEM_RELEASE
);
143 ok(b
!= 0, "VirtualFreeEx, error %u\n", GetLastError());
145 VirtualFree( src
, 0, MEM_FREE
);
146 VirtualFree( dst
, 0, MEM_FREE
);
149 * The following tests parallel those in test_VirtualAlloc()
152 SetLastError(0xdeadbeef);
153 addr1
= pVirtualAllocEx(hProcess
, 0, 0, MEM_RESERVE
, PAGE_NOACCESS
);
154 ok(addr1
== NULL
, "VirtualAllocEx should fail on zero-sized allocation\n");
155 ok(GetLastError() == ERROR_INVALID_PARAMETER
/* NT */ ||
156 GetLastError() == ERROR_NOT_ENOUGH_MEMORY
, /* Win9x */
157 "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
159 addr1
= pVirtualAllocEx(hProcess
, 0, 0xFFFC, MEM_RESERVE
, PAGE_NOACCESS
);
160 ok(addr1
!= NULL
, "VirtualAllocEx failed\n");
162 /* test a not committed memory */
163 memset(&info
, 'q', sizeof(info
));
164 ok(VirtualQueryEx(hProcess
, addr1
, &info
, sizeof(info
)) == sizeof(info
), "VirtualQueryEx failed\n");
165 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
166 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
167 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
168 ok(info
.RegionSize
== 0x10000, "%lx != 0x10000\n", info
.RegionSize
);
169 ok(info
.State
== MEM_RESERVE
, "%x != MEM_RESERVE\n", info
.State
);
170 /* NT reports Protect == 0 for a not committed memory block */
171 ok(info
.Protect
== 0 /* NT */ ||
172 info
.Protect
== PAGE_NOACCESS
, /* Win9x */
173 "%x != PAGE_NOACCESS\n", info
.Protect
);
174 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
176 SetLastError(0xdeadbeef);
177 ok(!VirtualProtectEx(hProcess
, addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
178 "VirtualProtectEx should fail on a not committed memory\n");
179 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* NT */ ||
180 GetLastError() == ERROR_INVALID_PARAMETER
, /* Win9x */
181 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
183 addr2
= pVirtualAllocEx(hProcess
, addr1
, 0x1000, MEM_COMMIT
, PAGE_NOACCESS
);
184 ok(addr1
== addr2
, "VirtualAllocEx failed\n");
186 /* test a committed memory */
187 ok(VirtualQueryEx(hProcess
, addr1
, &info
, sizeof(info
)) == sizeof(info
),
188 "VirtualQueryEx failed\n");
189 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
190 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
191 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
192 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
193 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
194 /* this time NT reports PAGE_NOACCESS as well */
195 ok(info
.Protect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.Protect
);
196 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
198 /* this should fail, since not the whole range is committed yet */
199 SetLastError(0xdeadbeef);
200 ok(!VirtualProtectEx(hProcess
, addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
201 "VirtualProtectEx should fail on a not committed memory\n");
202 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* NT */ ||
203 GetLastError() == ERROR_INVALID_PARAMETER
, /* Win9x */
204 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
207 ok(VirtualProtectEx(hProcess
, addr1
, 0x1000, PAGE_READONLY
, &old_prot
), "VirtualProtectEx failed\n");
208 ok(old_prot
== PAGE_NOACCESS
, "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot
);
211 ok(VirtualProtectEx(hProcess
, addr1
, 0x1000, PAGE_READWRITE
, &old_prot
), "VirtualProtectEx failed\n");
212 ok(old_prot
== PAGE_READONLY
, "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot
);
214 ok(!pVirtualFreeEx(hProcess
, addr1
, 0x10000, 0),
215 "VirtualFreeEx should fail with type 0\n");
216 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
217 "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
219 ok(pVirtualFreeEx(hProcess
, addr1
, 0x10000, MEM_DECOMMIT
), "VirtualFreeEx failed\n");
221 /* if the type is MEM_RELEASE, size must be 0 */
222 ok(!pVirtualFreeEx(hProcess
, addr1
, 1, MEM_RELEASE
),
223 "VirtualFreeEx should fail\n");
224 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
225 "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
227 ok(pVirtualFreeEx(hProcess
, addr1
, 0, MEM_RELEASE
), "VirtualFreeEx failed\n");
229 TerminateProcess(hProcess
, 0);
230 CloseHandle(hProcess
);
233 static void test_VirtualAlloc(void)
237 MEMORY_BASIC_INFORMATION info
;
239 SetLastError(0xdeadbeef);
240 addr1
= VirtualAlloc(0, 0, MEM_RESERVE
, PAGE_NOACCESS
);
241 ok(addr1
== NULL
, "VirtualAlloc should fail on zero-sized allocation\n");
242 ok(GetLastError() == ERROR_INVALID_PARAMETER
/* NT */ ||
243 GetLastError() == ERROR_NOT_ENOUGH_MEMORY
, /* Win9x */
244 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
246 addr1
= VirtualAlloc(0, 0xFFFC, MEM_RESERVE
, PAGE_NOACCESS
);
247 ok(addr1
!= NULL
, "VirtualAlloc failed\n");
249 /* test a not committed memory */
250 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
251 "VirtualQuery failed\n");
252 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
253 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
254 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
255 ok(info
.RegionSize
== 0x10000, "%lx != 0x10000\n", info
.RegionSize
);
256 ok(info
.State
== MEM_RESERVE
, "%x != MEM_RESERVE\n", info
.State
);
257 /* NT reports Protect == 0 for a not committed memory block */
258 ok(info
.Protect
== 0 /* NT */ ||
259 info
.Protect
== PAGE_NOACCESS
, /* Win9x */
260 "%x != PAGE_NOACCESS\n", info
.Protect
);
261 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
263 SetLastError(0xdeadbeef);
264 ok(!VirtualProtect(addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
265 "VirtualProtect should fail on a not committed memory\n");
266 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* NT */ ||
267 GetLastError() == ERROR_INVALID_PARAMETER
, /* Win9x */
268 "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
270 addr2
= VirtualAlloc(addr1
, 0x1000, MEM_COMMIT
, PAGE_NOACCESS
);
271 ok(addr1
== addr2
, "VirtualAlloc failed\n");
273 /* test a committed memory */
274 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
275 "VirtualQuery failed\n");
276 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
277 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
278 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
279 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
280 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
281 /* this time NT reports PAGE_NOACCESS as well */
282 ok(info
.Protect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.Protect
);
283 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
285 /* this should fail, since not the whole range is committed yet */
286 SetLastError(0xdeadbeef);
287 ok(!VirtualProtect(addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
288 "VirtualProtect should fail on a not committed memory\n");
289 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* NT */ ||
290 GetLastError() == ERROR_INVALID_PARAMETER
, /* Win9x */
291 "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
293 ok(VirtualProtect(addr1
, 0x1000, PAGE_READONLY
, &old_prot
), "VirtualProtect failed\n");
294 ok(old_prot
== PAGE_NOACCESS
,
295 "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot
);
297 ok(VirtualProtect(addr1
, 0x1000, PAGE_READWRITE
, &old_prot
), "VirtualProtect failed\n");
298 ok(old_prot
== PAGE_READONLY
,
299 "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot
);
301 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
302 "VirtualQuery failed\n");
303 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
304 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
305 ok(info
.Protect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.Protect
);
306 memset( addr1
, 0x55, 20 );
307 ok( *(DWORD
*)addr1
== 0x55555555, "wrong data %x\n", *(DWORD
*)addr1
);
309 addr2
= VirtualAlloc( addr1
, 0x1000, MEM_RESET
, PAGE_NOACCESS
);
310 ok( addr2
== addr1
|| broken( !addr2
&& GetLastError() == ERROR_INVALID_PARAMETER
), /* win9x */
311 "VirtualAlloc failed err %u\n", GetLastError() );
312 ok( *(DWORD
*)addr1
== 0x55555555 || *(DWORD
*)addr1
== 0, "wrong data %x\n", *(DWORD
*)addr1
);
315 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
316 "VirtualQuery failed\n");
317 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
318 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
319 ok(info
.Protect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.Protect
);
321 addr2
= VirtualAlloc( (char *)addr1
+ 0x1000, 0x1000, MEM_RESET
, PAGE_NOACCESS
);
322 ok( (char *)addr2
== (char *)addr1
+ 0x1000, "VirtualAlloc failed\n" );
324 ok(VirtualQuery(addr2
, &info
, sizeof(info
)) == sizeof(info
),
325 "VirtualQuery failed\n");
326 ok(info
.RegionSize
== 0xf000, "%lx != 0xf000\n", info
.RegionSize
);
327 ok(info
.State
== MEM_RESERVE
, "%x != MEM_RESERVE\n", info
.State
);
328 ok(info
.Protect
== 0, "%x != 0\n", info
.Protect
);
330 addr2
= VirtualAlloc( (char *)addr1
+ 0xf000, 0x2000, MEM_RESET
, PAGE_NOACCESS
);
331 ok( !addr2
, "VirtualAlloc failed\n" );
332 ok( GetLastError() == ERROR_INVALID_ADDRESS
, "wrong error %u\n", GetLastError() );
335 /* invalid protection values */
336 SetLastError(0xdeadbeef);
337 addr2
= VirtualAlloc(NULL
, 0x1000, MEM_RESERVE
, 0);
338 ok(!addr2
, "VirtualAlloc succeeded\n");
339 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
341 SetLastError(0xdeadbeef);
342 addr2
= VirtualAlloc(NULL
, 0x1000, MEM_COMMIT
, 0);
343 ok(!addr2
, "VirtualAlloc succeeded\n");
344 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
346 SetLastError(0xdeadbeef);
347 addr2
= VirtualAlloc(addr1
, 0x1000, MEM_COMMIT
, PAGE_READONLY
| PAGE_EXECUTE
);
348 ok(!addr2
, "VirtualAlloc succeeded\n");
349 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
351 SetLastError(0xdeadbeef);
352 ok(!VirtualProtect(addr1
, 0x1000, PAGE_READWRITE
| PAGE_EXECUTE_WRITECOPY
, &old_prot
),
353 "VirtualProtect succeeded\n");
354 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
356 SetLastError(0xdeadbeef);
357 ok(!VirtualProtect(addr1
, 0x1000, 0, &old_prot
), "VirtualProtect succeeded\n");
358 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
360 SetLastError(0xdeadbeef);
361 ok(!VirtualFree(addr1
, 0x10000, 0), "VirtualFree should fail with type 0\n");
362 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
363 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
365 ok(VirtualFree(addr1
, 0x10000, MEM_DECOMMIT
), "VirtualFree failed\n");
367 /* if the type is MEM_RELEASE, size must be 0 */
368 ok(!VirtualFree(addr1
, 1, MEM_RELEASE
), "VirtualFree should fail\n");
369 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
370 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
372 ok(VirtualFree(addr1
, 0, MEM_RELEASE
), "VirtualFree failed\n");
375 static void test_MapViewOfFile(void)
377 static const char testfile
[] = "testfile.xxx";
379 HANDLE file
, mapping
, map2
;
380 void *ptr
, *ptr2
, *addr
;
381 MEMORY_BASIC_INFORMATION info
;
384 SetLastError(0xdeadbeef);
385 file
= CreateFileA( testfile
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
386 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
387 SetFilePointer( file
, 4096, NULL
, FILE_BEGIN
);
388 SetEndOfFile( file
);
390 /* read/write mapping */
392 SetLastError(0xdeadbeef);
393 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
394 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
396 SetLastError(0xdeadbeef);
397 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
398 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAPE_READ error %u\n", GetLastError() );
399 UnmapViewOfFile( ptr
);
401 /* this fails on win9x but succeeds on NT */
402 SetLastError(0xdeadbeef);
403 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
404 if (ptr
) UnmapViewOfFile( ptr
);
405 else ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
407 SetLastError(0xdeadbeef);
408 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
409 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
410 UnmapViewOfFile( ptr
);
412 SetLastError(0xdeadbeef);
413 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
414 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
415 UnmapViewOfFile( ptr
);
417 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
,
418 FILE_MAP_READ
|FILE_MAP_WRITE
, FALSE
, 0 );
419 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
420 ptr
= MapViewOfFile( map2
, FILE_MAP_WRITE
, 0, 0, 4096 );
421 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
422 UnmapViewOfFile( ptr
);
425 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
,
426 FILE_MAP_READ
, FALSE
, 0 );
427 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
428 SetLastError(0xdeadbeef);
429 ptr
= MapViewOfFile( map2
, FILE_MAP_WRITE
, 0, 0, 4096 );
432 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
434 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
, 0, FALSE
, 0 );
435 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
436 SetLastError(0xdeadbeef);
437 ptr
= MapViewOfFile( map2
, 0, 0, 0, 4096 );
438 ok( !ptr
, "MapViewOfFile succeeded\n" );
439 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
441 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
,
442 FILE_MAP_READ
, FALSE
, 0 );
443 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
444 ptr
= MapViewOfFile( map2
, 0, 0, 0, 4096 );
445 ok( ptr
!= NULL
, "MapViewOfFile NO_ACCESS error %u\n", GetLastError() );
447 else win_skip( "no access checks on win9x\n" );
449 UnmapViewOfFile( ptr
);
451 CloseHandle( mapping
);
453 /* read-only mapping */
455 SetLastError(0xdeadbeef);
456 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
457 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
459 SetLastError(0xdeadbeef);
460 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
461 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
462 UnmapViewOfFile( ptr
);
464 /* this fails on win9x but succeeds on NT */
465 SetLastError(0xdeadbeef);
466 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
467 if (ptr
) UnmapViewOfFile( ptr
);
468 else ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
470 SetLastError(0xdeadbeef);
471 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
472 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
473 UnmapViewOfFile( ptr
);
475 SetLastError(0xdeadbeef);
476 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
477 ok( !ptr
, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
478 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
479 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
480 CloseHandle( mapping
);
482 /* copy-on-write mapping */
484 SetLastError(0xdeadbeef);
485 mapping
= CreateFileMappingA( file
, NULL
, PAGE_WRITECOPY
, 0, 4096, NULL
);
486 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
488 SetLastError(0xdeadbeef);
489 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
490 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
491 UnmapViewOfFile( ptr
);
493 SetLastError(0xdeadbeef);
494 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
495 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_COPY error %u\n", GetLastError() );
496 UnmapViewOfFile( ptr
);
498 SetLastError(0xdeadbeef);
499 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
500 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
501 UnmapViewOfFile( ptr
);
503 SetLastError(0xdeadbeef);
504 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
505 ok( !ptr
, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
506 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
507 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
508 CloseHandle( mapping
);
510 /* no access mapping */
512 SetLastError(0xdeadbeef);
513 mapping
= CreateFileMappingA( file
, NULL
, PAGE_NOACCESS
, 0, 4096, NULL
);
514 /* fails on NT but succeeds on win9x */
515 if (!mapping
) ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
518 SetLastError(0xdeadbeef);
519 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
520 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
521 UnmapViewOfFile( ptr
);
523 SetLastError(0xdeadbeef);
524 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
525 ok( !ptr
, "MapViewOfFile FILE_MAP_COPY succeeded\n" );
526 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
528 SetLastError(0xdeadbeef);
529 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
530 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
531 UnmapViewOfFile( ptr
);
533 SetLastError(0xdeadbeef);
534 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
535 ok( !ptr
, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
536 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
538 CloseHandle( mapping
);
543 /* now try read-only file */
545 SetLastError(0xdeadbeef);
546 file
= CreateFileA( testfile
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0 );
547 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
549 SetLastError(0xdeadbeef);
550 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
551 ok( !mapping
, "CreateFileMapping PAGE_READWRITE succeeded\n" );
552 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
553 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
555 SetLastError(0xdeadbeef);
556 mapping
= CreateFileMappingA( file
, NULL
, PAGE_WRITECOPY
, 0, 4096, NULL
);
557 ok( mapping
!= 0, "CreateFileMapping PAGE_WRITECOPY error %u\n", GetLastError() );
558 CloseHandle( mapping
);
560 SetLastError(0xdeadbeef);
561 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
562 ok( mapping
!= 0, "CreateFileMapping PAGE_READONLY error %u\n", GetLastError() );
563 CloseHandle( mapping
);
566 /* now try no access file */
568 SetLastError(0xdeadbeef);
569 file
= CreateFileA( testfile
, 0, 0, NULL
, OPEN_EXISTING
, 0, 0 );
570 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
572 SetLastError(0xdeadbeef);
573 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
574 ok( !mapping
, "CreateFileMapping PAGE_READWRITE succeeded\n" );
575 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
576 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
578 SetLastError(0xdeadbeef);
579 mapping
= CreateFileMappingA( file
, NULL
, PAGE_WRITECOPY
, 0, 4096, NULL
);
580 ok( !mapping
, "CreateFileMapping PAGE_WRITECOPY succeeded\n" );
581 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
582 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
584 SetLastError(0xdeadbeef);
585 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
586 ok( !mapping
, "CreateFileMapping PAGE_READONLY succeeded\n" );
587 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
588 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
591 DeleteFileA( testfile
);
593 SetLastError(0xdeadbeef);
595 file
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4096, name
);
596 /* nt4 doesn't have Local\\ */
597 if (!file
&& GetLastError() == ERROR_PATH_NOT_FOUND
)
600 file
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4096, name
);
602 ok( file
!= 0, "CreateFileMapping PAGE_READWRITE error %u\n", GetLastError() );
604 SetLastError(0xdeadbeef);
605 mapping
= OpenFileMappingA( FILE_MAP_READ
, FALSE
, name
);
606 ok( mapping
!= 0, "OpenFileMapping FILE_MAP_READ error %u\n", GetLastError() );
607 SetLastError(0xdeadbeef);
608 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 0 );
612 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
613 SetLastError(0xdeadbeef);
614 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 0 );
615 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
616 SetLastError(0xdeadbeef);
617 size
= VirtualQuery( ptr
, &info
, sizeof(info
) );
618 ok( size
== sizeof(info
),
619 "VirtualQuery error %u\n", GetLastError() );
620 ok( info
.BaseAddress
== ptr
, "%p != %p\n", info
.BaseAddress
, ptr
);
621 ok( info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
622 ok( info
.AllocationProtect
== PAGE_READONLY
, "%x != PAGE_READONLY\n", info
.AllocationProtect
);
623 ok( info
.RegionSize
== 4096, "%lx != 4096\n", info
.RegionSize
);
624 ok( info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
625 ok( info
.Protect
== PAGE_READONLY
, "%x != PAGE_READONLY\n", info
.Protect
);
627 else win_skip( "no access checks on win9x\n" );
628 UnmapViewOfFile( ptr
);
629 CloseHandle( mapping
);
631 SetLastError(0xdeadbeef);
632 mapping
= OpenFileMappingA( FILE_MAP_WRITE
, FALSE
, name
);
633 ok( mapping
!= 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() );
634 SetLastError(0xdeadbeef);
635 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 0 );
639 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
640 SetLastError(0xdeadbeef);
641 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 0 );
642 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
643 SetLastError(0xdeadbeef);
644 size
= VirtualQuery( ptr
, &info
, sizeof(info
) );
645 ok( size
== sizeof(info
),
646 "VirtualQuery error %u\n", GetLastError() );
647 ok( info
.BaseAddress
== ptr
, "%p != %p\n", info
.BaseAddress
, ptr
);
648 ok( info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
649 ok( info
.AllocationProtect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.AllocationProtect
);
650 ok( info
.RegionSize
== 4096, "%lx != 4096\n", info
.RegionSize
);
651 ok( info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
652 ok( info
.Protect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.Protect
);
654 else win_skip( "no access checks on win9x\n" );
655 UnmapViewOfFile( ptr
);
656 CloseHandle( mapping
);
660 /* read/write mapping with SEC_RESERVE */
661 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
| SEC_RESERVE
, 0, MAPPING_SIZE
, NULL
);
662 ok(mapping
!= INVALID_HANDLE_VALUE
, "CreateFileMappingA failed with error %d\n", GetLastError());
664 ptr
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
665 ok(ptr
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError());
667 ptr2
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
668 /* on NT ptr != ptr2 but on Win9x ptr == ptr2 */
669 ok(ptr2
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError());
670 trace("mapping same section resulted in views %p and %p\n", ptr
, ptr2
);
672 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
673 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
674 ok(info
.BaseAddress
== ptr
, "BaseAddress should have been %p but was %p instead\n", ptr
, info
.BaseAddress
);
675 ok(info
.AllocationBase
== ptr
, "AllocationBase should have been %p but was %p instead\n", ptr
, info
.AllocationBase
);
676 ok(info
.RegionSize
== MAPPING_SIZE
, "RegionSize should have been 0x%x but was 0x%lx\n", MAPPING_SIZE
, info
.RegionSize
);
677 ok(info
.State
== MEM_RESERVE
, "State should have been MEM_RESERVE instead of 0x%x\n", info
.State
);
678 if (info
.Type
== MEM_PRIVATE
) /* win9x is different for uncommitted mappings */
680 ok(info
.AllocationProtect
== PAGE_NOACCESS
,
681 "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info
.AllocationProtect
);
682 ok(info
.Protect
== PAGE_NOACCESS
,
683 "Protect should have been PAGE_NOACCESS instead of 0x%x\n", info
.Protect
);
687 ok(info
.AllocationProtect
== PAGE_READWRITE
,
688 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
689 ok(info
.Protect
== 0, "Protect should have been 0 instead of 0x%x\n", info
.Protect
);
690 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
695 ret
= VirtualQuery(ptr2
, &info
, sizeof(info
));
696 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
697 ok(info
.BaseAddress
== ptr2
,
698 "BaseAddress should have been %p but was %p instead\n", ptr2
, info
.BaseAddress
);
699 ok(info
.AllocationBase
== ptr2
,
700 "AllocationBase should have been %p but was %p instead\n", ptr2
, info
.AllocationBase
);
701 ok(info
.AllocationProtect
== PAGE_READWRITE
,
702 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
703 ok(info
.RegionSize
== MAPPING_SIZE
,
704 "RegionSize should have been 0x%x but was 0x%lx\n", MAPPING_SIZE
, info
.RegionSize
);
705 ok(info
.State
== MEM_RESERVE
,
706 "State should have been MEM_RESERVE instead of 0x%x\n", info
.State
);
707 ok(info
.Protect
== 0,
708 "Protect should have been 0 instead of 0x%x\n", info
.Protect
);
709 ok(info
.Type
== MEM_MAPPED
,
710 "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
713 ptr
= VirtualAlloc(ptr
, 0x10000, MEM_COMMIT
, PAGE_READONLY
);
714 ok(ptr
!= NULL
, "VirtualAlloc failed with error %d\n", GetLastError());
716 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
717 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
718 ok(info
.BaseAddress
== ptr
, "BaseAddress should have been %p but was %p instead\n", ptr
, info
.BaseAddress
);
719 ok(info
.AllocationBase
== ptr
, "AllocationBase should have been %p but was %p instead\n", ptr
, info
.AllocationBase
);
720 ok(info
.RegionSize
== 0x10000, "RegionSize should have been 0x10000 but was 0x%lx\n", info
.RegionSize
);
721 ok(info
.State
== MEM_COMMIT
, "State should have been MEM_COMMIT instead of 0x%x\n", info
.State
);
722 ok(info
.Protect
== PAGE_READONLY
, "Protect should have been PAGE_READONLY instead of 0x%x\n", info
.Protect
);
723 if (info
.Type
== MEM_PRIVATE
) /* win9x is different for uncommitted mappings */
725 ok(info
.AllocationProtect
== PAGE_NOACCESS
,
726 "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info
.AllocationProtect
);
730 ok(info
.AllocationProtect
== PAGE_READWRITE
,
731 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
732 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
735 /* shows that the VirtualAlloc above affects the mapping, not just the
736 * virtual memory in this process - it also affects all other processes
737 * with a view of the mapping, but that isn't tested here */
740 ret
= VirtualQuery(ptr2
, &info
, sizeof(info
));
741 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
742 ok(info
.BaseAddress
== ptr2
,
743 "BaseAddress should have been %p but was %p instead\n", ptr2
, info
.BaseAddress
);
744 ok(info
.AllocationBase
== ptr2
,
745 "AllocationBase should have been %p but was %p instead\n", ptr2
, info
.AllocationBase
);
746 ok(info
.AllocationProtect
== PAGE_READWRITE
,
747 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
748 ok(info
.RegionSize
== 0x10000,
749 "RegionSize should have been 0x10000 but was 0x%lx\n", info
.RegionSize
);
750 ok(info
.State
== MEM_COMMIT
,
751 "State should have been MEM_COMMIT instead of 0x%x\n", info
.State
);
752 ok(info
.Protect
== PAGE_READWRITE
,
753 "Protect should have been PAGE_READWRITE instead of 0x%x\n", info
.Protect
);
754 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
757 addr
= VirtualAlloc( ptr
, MAPPING_SIZE
, MEM_RESET
, PAGE_READONLY
);
758 ok( addr
== ptr
|| broken(!addr
&& GetLastError() == ERROR_INVALID_PARAMETER
), /* win9x */
759 "VirtualAlloc failed with error %u\n", GetLastError() );
761 ret
= VirtualFree( ptr
, 0x10000, MEM_DECOMMIT
);
762 ok( !ret
|| broken(ret
) /* win9x */, "VirtualFree succeeded\n" );
764 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "VirtualFree failed with %u\n", GetLastError() );
766 ret
= UnmapViewOfFile(ptr2
);
767 ok(ret
, "UnmapViewOfFile failed with error %d\n", GetLastError());
768 ret
= UnmapViewOfFile(ptr
);
769 ok(ret
, "UnmapViewOfFile failed with error %d\n", GetLastError());
770 CloseHandle(mapping
);
772 addr
= VirtualAlloc(NULL
, 0x10000, MEM_COMMIT
, PAGE_READONLY
);
773 ok( addr
!= NULL
, "VirtualAlloc failed with error %u\n", GetLastError() );
775 SetLastError(0xdeadbeef);
776 ok( !UnmapViewOfFile(addr
), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
777 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
778 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
779 SetLastError(0xdeadbeef);
780 ok( !UnmapViewOfFile((char *)addr
+ 0x3000), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
781 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
782 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
783 SetLastError(0xdeadbeef);
784 ok( !UnmapViewOfFile((void *)0xdeadbeef), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
785 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
786 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
788 ok( VirtualFree(addr
, 0, MEM_RELEASE
), "VirtualFree failed\n" );
790 /* close named mapping handle without unmapping */
792 SetLastError(0xdeadbeef);
793 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, MAPPING_SIZE
, name
);
794 ok( mapping
!= 0, "CreateFileMappingA failed with error %d\n", GetLastError() );
795 SetLastError(0xdeadbeef);
796 ptr
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
797 ok( ptr
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError() );
798 SetLastError(0xdeadbeef);
799 map2
= OpenFileMappingA(FILE_MAP_READ
, FALSE
, name
);
800 ok( map2
!= 0, "OpenFileMappingA failed with error %d\n", GetLastError() );
801 SetLastError(0xdeadbeef);
802 ret
= CloseHandle(map2
);
803 ok(ret
, "CloseHandle error %d\n", GetLastError());
804 SetLastError(0xdeadbeef);
805 ret
= CloseHandle(mapping
);
806 ok(ret
, "CloseHandle error %d\n", GetLastError());
808 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
809 ok( !ret
, "memory is not accessible\n" );
811 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
812 ok(ret
, "VirtualQuery error %d\n", GetLastError());
813 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
814 ok(info
.RegionSize
== MAPPING_SIZE
, "got %#lx != expected %#x\n", info
.RegionSize
, MAPPING_SIZE
);
815 ok(info
.Protect
== PAGE_READWRITE
, "got %#x != expected PAGE_READWRITE\n", info
.Protect
);
816 ok(info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
817 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%#x != PAGE_READWRITE\n", info
.AllocationProtect
);
818 ok(info
.State
== MEM_COMMIT
, "%#x != MEM_COMMIT\n", info
.State
);
819 ok(info
.Type
== MEM_MAPPED
, "%#x != MEM_MAPPED\n", info
.Type
);
821 SetLastError(0xdeadbeef);
822 map2
= OpenFileMappingA(FILE_MAP_READ
, FALSE
, name
);
824 ok( map2
== 0, "OpenFileMappingA succeeded\n" );
826 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "OpenFileMappingA set error %d\n", GetLastError() );
827 if (map2
) CloseHandle(map2
); /* FIXME: remove once Wine is fixed */
828 SetLastError(0xdeadbeef);
829 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, MAPPING_SIZE
, name
);
830 ok( mapping
!= 0, "CreateFileMappingA failed\n" );
832 ok( GetLastError() == ERROR_SUCCESS
, "CreateFileMappingA set error %d\n", GetLastError() );
833 SetLastError(0xdeadbeef);
834 ret
= CloseHandle(mapping
);
835 ok(ret
, "CloseHandle error %d\n", GetLastError());
837 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
838 ok( !ret
, "memory is not accessible\n" );
840 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
841 ok(ret
, "VirtualQuery error %d\n", GetLastError());
842 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
843 ok(info
.RegionSize
== MAPPING_SIZE
, "got %#lx != expected %#x\n", info
.RegionSize
, MAPPING_SIZE
);
844 ok(info
.Protect
== PAGE_READWRITE
, "got %#x != expected PAGE_READWRITE\n", info
.Protect
);
845 ok(info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
846 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%#x != PAGE_READWRITE\n", info
.AllocationProtect
);
847 ok(info
.State
== MEM_COMMIT
, "%#x != MEM_COMMIT\n", info
.State
);
848 ok(info
.Type
== MEM_MAPPED
, "%#x != MEM_MAPPED\n", info
.Type
);
850 SetLastError(0xdeadbeef);
851 ret
= UnmapViewOfFile(ptr
);
852 ok( ret
, "UnmapViewOfFile failed with error %d\n", GetLastError() );
854 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
855 ok( ret
, "memory is accessible\n" );
857 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
858 ok(ret
, "VirtualQuery error %d\n", GetLastError());
859 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
860 ok(info
.Protect
== PAGE_NOACCESS
, "got %#x != expected PAGE_NOACCESS\n", info
.Protect
);
861 ok(info
.AllocationBase
== NULL
, "%p != NULL\n", info
.AllocationBase
);
862 ok(info
.AllocationProtect
== 0, "%#x != 0\n", info
.AllocationProtect
);
863 ok(info
.State
== MEM_FREE
, "%#x != MEM_FREE\n", info
.State
);
864 ok(info
.Type
== 0, "%#x != 0\n", info
.Type
);
866 SetLastError(0xdeadbeef);
867 file
= CreateFileA(testfile
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
868 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
869 SetFilePointer(file
, 4096, NULL
, FILE_BEGIN
);
872 SetLastError(0xdeadbeef);
873 mapping
= CreateFileMappingA(file
, NULL
, PAGE_READWRITE
, 0, MAPPING_SIZE
, name
);
874 ok( mapping
!= 0, "CreateFileMappingA failed with error %d\n", GetLastError() );
875 SetLastError(0xdeadbeef);
876 ptr
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
877 ok( ptr
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError() );
878 SetLastError(0xdeadbeef);
879 map2
= OpenFileMappingA(FILE_MAP_READ
, FALSE
, name
);
880 ok( map2
!= 0, "OpenFileMappingA failed with error %d\n", GetLastError() );
881 SetLastError(0xdeadbeef);
882 ret
= CloseHandle(map2
);
883 ok(ret
, "CloseHandle error %d\n", GetLastError());
884 SetLastError(0xdeadbeef);
885 ret
= CloseHandle(mapping
);
886 ok(ret
, "CloseHandle error %d\n", GetLastError());
888 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
889 ok( !ret
, "memory is not accessible\n" );
891 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
892 ok(ret
, "VirtualQuery error %d\n", GetLastError());
893 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
894 ok(info
.RegionSize
== MAPPING_SIZE
, "got %#lx != expected %#x\n", info
.RegionSize
, MAPPING_SIZE
);
895 ok(info
.Protect
== PAGE_READWRITE
, "got %#x != expected PAGE_READWRITE\n", info
.Protect
);
896 ok(info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
897 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%#x != PAGE_READWRITE\n", info
.AllocationProtect
);
898 ok(info
.State
== MEM_COMMIT
, "%#x != MEM_COMMIT\n", info
.State
);
899 ok(info
.Type
== MEM_MAPPED
, "%#x != MEM_MAPPED\n", info
.Type
);
901 SetLastError(0xdeadbeef);
902 map2
= OpenFileMappingA(FILE_MAP_READ
, FALSE
, name
);
904 ok( map2
== 0, "OpenFileMappingA succeeded\n" );
906 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "OpenFileMappingA set error %d\n", GetLastError() );
908 SetLastError(0xdeadbeef);
909 mapping
= CreateFileMappingA(file
, NULL
, PAGE_READWRITE
, 0, MAPPING_SIZE
, name
);
910 ok( mapping
!= 0, "CreateFileMappingA failed\n" );
912 ok( GetLastError() == ERROR_SUCCESS
, "CreateFileMappingA set error %d\n", GetLastError() );
913 SetLastError(0xdeadbeef);
914 ret
= CloseHandle(mapping
);
915 ok(ret
, "CloseHandle error %d\n", GetLastError());
917 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
918 ok( !ret
, "memory is not accessible\n" );
920 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
921 ok(ret
, "VirtualQuery error %d\n", GetLastError());
922 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
923 ok(info
.RegionSize
== MAPPING_SIZE
, "got %#lx != expected %#x\n", info
.RegionSize
, MAPPING_SIZE
);
924 ok(info
.Protect
== PAGE_READWRITE
, "got %#x != expected PAGE_READWRITE\n", info
.Protect
);
925 ok(info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
926 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%#x != PAGE_READWRITE\n", info
.AllocationProtect
);
927 ok(info
.State
== MEM_COMMIT
, "%#x != MEM_COMMIT\n", info
.State
);
928 ok(info
.Type
== MEM_MAPPED
, "%#x != MEM_MAPPED\n", info
.Type
);
930 SetLastError(0xdeadbeef);
931 ret
= UnmapViewOfFile(ptr
);
932 ok( ret
, "UnmapViewOfFile failed with error %d\n", GetLastError() );
934 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
935 ok( ret
, "memory is accessible\n" );
937 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
938 ok(ret
, "VirtualQuery error %d\n", GetLastError());
939 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
940 ok(info
.Protect
== PAGE_NOACCESS
, "got %#x != expected PAGE_NOACCESS\n", info
.Protect
);
941 ok(info
.AllocationBase
== NULL
, "%p != NULL\n", info
.AllocationBase
);
942 ok(info
.AllocationProtect
== 0, "%#x != 0\n", info
.AllocationProtect
);
943 ok(info
.State
== MEM_FREE
, "%#x != MEM_FREE\n", info
.State
);
944 ok(info
.Type
== 0, "%#x != 0\n", info
.Type
);
947 DeleteFileA(testfile
);
950 static void test_NtMapViewOfSection(void)
954 static const char testfile
[] = "testfile.xxx";
955 static const char data
[] = "test data for NtMapViewOfSection";
956 char buffer
[sizeof(data
)];
957 HANDLE file
, mapping
;
960 DWORD status
, written
;
962 LARGE_INTEGER offset
;
964 if (!pNtMapViewOfSection
|| !pNtUnmapViewOfSection
)
966 win_skip( "NtMapViewOfSection not available\n" );
970 file
= CreateFileA( testfile
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
971 ok( file
!= INVALID_HANDLE_VALUE
, "Failed to create test file\n" );
972 WriteFile( file
, data
, sizeof(data
), &written
, NULL
);
973 SetFilePointer( file
, 4096, NULL
, FILE_BEGIN
);
974 SetEndOfFile( file
);
976 /* read/write mapping */
978 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
979 ok( mapping
!= 0, "CreateFileMapping failed\n" );
981 hProcess
= create_target_process("sleep");
982 ok(hProcess
!= NULL
, "Can't start process\n");
987 status
= pNtMapViewOfSection( mapping
, hProcess
, &ptr
, 0, 0, &offset
, &size
, 1, 0, PAGE_READWRITE
);
988 ok( !status
, "NtMapViewOfSection failed status %x\n", status
);
990 ret
= ReadProcessMemory( hProcess
, ptr
, buffer
, sizeof(buffer
), &result
);
991 ok( ret
, "ReadProcessMemory failed\n" );
992 ok( result
== sizeof(buffer
), "ReadProcessMemory didn't read all data (%lx)\n", result
);
993 ok( !memcmp( buffer
, data
, sizeof(buffer
) ), "Wrong data read\n" );
995 status
= pNtUnmapViewOfSection( hProcess
, ptr
);
996 ok( !status
, "NtUnmapViewOfSection failed status %x\n", status
);
998 CloseHandle( mapping
);
1000 DeleteFileA( testfile
);
1002 TerminateProcess(hProcess
, 0);
1003 CloseHandle(hProcess
);
1006 static void test_NtAreMappedFilesTheSame(void)
1008 static const char testfile
[] = "testfile.xxx";
1009 HANDLE file
, file2
, mapping
, map2
;
1012 char path
[MAX_PATH
];
1014 if (!pNtAreMappedFilesTheSame
)
1016 win_skip( "NtAreMappedFilesTheSame not available\n" );
1020 file
= CreateFileA( testfile
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1021 NULL
, CREATE_ALWAYS
, 0, 0 );
1022 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1023 SetFilePointer( file
, 4096, NULL
, FILE_BEGIN
);
1024 SetEndOfFile( file
);
1026 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
1027 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1029 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
1030 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1032 file2
= CreateFileA( testfile
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1033 NULL
, OPEN_EXISTING
, 0, 0 );
1034 ok( file2
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1036 map2
= CreateFileMappingA( file2
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
1037 ok( map2
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1038 ptr2
= MapViewOfFile( map2
, FILE_MAP_READ
, 0, 0, 4096 );
1039 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1040 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1041 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1042 UnmapViewOfFile( ptr2
);
1044 ptr2
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
1045 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1046 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1047 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1048 UnmapViewOfFile( ptr2
);
1049 CloseHandle( map2
);
1051 map2
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
1052 ok( map2
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1053 ptr2
= MapViewOfFile( map2
, FILE_MAP_READ
, 0, 0, 4096 );
1054 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1055 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1056 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1057 UnmapViewOfFile( ptr2
);
1058 CloseHandle( map2
);
1059 CloseHandle( file2
);
1061 status
= pNtAreMappedFilesTheSame( ptr
, ptr
);
1062 ok( status
== STATUS_SUCCESS
|| broken(status
== STATUS_NOT_SAME_DEVICE
),
1063 "NtAreMappedFilesTheSame returned %x\n", status
);
1065 status
= pNtAreMappedFilesTheSame( ptr
, (char *)ptr
+ 30 );
1066 ok( status
== STATUS_SUCCESS
|| broken(status
== STATUS_NOT_SAME_DEVICE
),
1067 "NtAreMappedFilesTheSame returned %x\n", status
);
1069 status
= pNtAreMappedFilesTheSame( ptr
, GetModuleHandleA("kernel32.dll") );
1070 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1072 status
= pNtAreMappedFilesTheSame( ptr
, (void *)0xdeadbeef );
1073 ok( status
== STATUS_CONFLICTING_ADDRESSES
|| status
== STATUS_INVALID_ADDRESS
,
1074 "NtAreMappedFilesTheSame returned %x\n", status
);
1076 status
= pNtAreMappedFilesTheSame( ptr
, NULL
);
1077 ok( status
== STATUS_INVALID_ADDRESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1079 status
= pNtAreMappedFilesTheSame( ptr
, (void *)GetProcessHeap() );
1080 ok( status
== STATUS_CONFLICTING_ADDRESSES
, "NtAreMappedFilesTheSame returned %x\n", status
);
1082 status
= pNtAreMappedFilesTheSame( NULL
, NULL
);
1083 ok( status
== STATUS_INVALID_ADDRESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1085 ptr2
= VirtualAlloc( NULL
, 0x10000, MEM_COMMIT
, PAGE_READWRITE
);
1086 ok( ptr2
!= NULL
, "VirtualAlloc error %u\n", GetLastError() );
1087 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1088 ok( status
== STATUS_CONFLICTING_ADDRESSES
, "NtAreMappedFilesTheSame returned %x\n", status
);
1089 VirtualFree( ptr2
, 0, MEM_RELEASE
);
1091 UnmapViewOfFile( ptr
);
1092 CloseHandle( mapping
);
1093 CloseHandle( file
);
1095 status
= pNtAreMappedFilesTheSame( GetModuleHandleA("ntdll.dll"),
1096 GetModuleHandleA("kernel32.dll") );
1097 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1098 status
= pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
1099 GetModuleHandleA("kernel32.dll") );
1100 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1101 status
= pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
1102 (char *)GetModuleHandleA("kernel32.dll") + 4096 );
1103 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1105 GetSystemDirectoryA( path
, MAX_PATH
);
1106 strcat( path
, "\\kernel32.dll" );
1107 file
= CreateFileA( path
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
1108 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1110 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
1111 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1112 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
1113 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1114 status
= pNtAreMappedFilesTheSame( ptr
, GetModuleHandleA("kernel32.dll") );
1115 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1116 UnmapViewOfFile( ptr
);
1117 CloseHandle( mapping
);
1119 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
| SEC_IMAGE
, 0, 0, NULL
);
1120 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1121 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 0 );
1122 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1123 status
= pNtAreMappedFilesTheSame( ptr
, GetModuleHandleA("kernel32.dll") );
1125 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1127 file2
= CreateFileA( path
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
1128 ok( file2
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1129 map2
= CreateFileMappingA( file2
, NULL
, PAGE_READONLY
| SEC_IMAGE
, 0, 0, NULL
);
1130 ok( map2
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1131 ptr2
= MapViewOfFile( map2
, FILE_MAP_READ
, 0, 0, 0 );
1132 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1133 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1134 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1135 UnmapViewOfFile( ptr2
);
1136 CloseHandle( map2
);
1137 CloseHandle( file2
);
1139 UnmapViewOfFile( ptr
);
1140 CloseHandle( mapping
);
1142 CloseHandle( file
);
1143 DeleteFileA( testfile
);
1146 static void test_CreateFileMapping(void)
1148 HANDLE handle
, handle2
;
1150 /* test case sensitivity */
1152 SetLastError(0xdeadbeef);
1153 handle
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, SEC_COMMIT
| PAGE_READWRITE
, 0, 0x1000,
1154 "Wine Test Mapping");
1155 ok( handle
!= NULL
, "CreateFileMapping failed with error %u\n", GetLastError());
1156 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
1158 SetLastError(0xdeadbeef);
1159 handle2
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, SEC_COMMIT
| PAGE_READWRITE
, 0, 0x1000,
1160 "Wine Test Mapping");
1161 ok( handle2
!= NULL
, "CreateFileMapping failed with error %d\n", GetLastError());
1162 ok( GetLastError() == ERROR_ALREADY_EXISTS
, "wrong error %u\n", GetLastError());
1163 CloseHandle( handle2
);
1165 SetLastError(0xdeadbeef);
1166 handle2
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, SEC_COMMIT
| PAGE_READWRITE
, 0, 0x1000,
1167 "WINE TEST MAPPING");
1168 ok( handle2
!= NULL
, "CreateFileMapping failed with error %d\n", GetLastError());
1169 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
1170 CloseHandle( handle2
);
1172 SetLastError(0xdeadbeef);
1173 handle2
= OpenFileMappingA( FILE_MAP_ALL_ACCESS
, FALSE
, "Wine Test Mapping");
1174 ok( handle2
!= NULL
, "OpenFileMapping failed with error %d\n", GetLastError());
1175 CloseHandle( handle2
);
1177 SetLastError(0xdeadbeef);
1178 handle2
= OpenFileMappingA( FILE_MAP_ALL_ACCESS
, FALSE
, "WINE TEST MAPPING");
1179 ok( !handle2
, "OpenFileMapping succeeded\n");
1180 ok( GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_INVALID_NAME
/* win9x */,
1181 "wrong error %u\n", GetLastError());
1183 CloseHandle( handle
);
1186 static void test_IsBadReadPtr(void)
1189 void *ptr
= (void *)0xdeadbeef;
1192 ret
= IsBadReadPtr(NULL
, 0);
1193 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1195 ret
= IsBadReadPtr(NULL
, 1);
1196 ok(ret
== TRUE
, "Expected IsBadReadPtr to return TRUE, got %d\n", ret
);
1198 ret
= IsBadReadPtr(ptr
, 0);
1199 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1201 ret
= IsBadReadPtr(ptr
, 1);
1202 ok(ret
== TRUE
, "Expected IsBadReadPtr to return TRUE, got %d\n", ret
);
1204 ret
= IsBadReadPtr(&stackvar
, 0);
1205 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1207 ret
= IsBadReadPtr(&stackvar
, sizeof(char));
1208 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1211 static void test_IsBadWritePtr(void)
1214 void *ptr
= (void *)0xdeadbeef;
1217 ret
= IsBadWritePtr(NULL
, 0);
1218 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1220 ret
= IsBadWritePtr(NULL
, 1);
1221 ok(ret
== TRUE
, "Expected IsBadWritePtr to return TRUE, got %d\n", ret
);
1223 ret
= IsBadWritePtr(ptr
, 0);
1224 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1226 ret
= IsBadWritePtr(ptr
, 1);
1227 ok(ret
== TRUE
, "Expected IsBadWritePtr to return TRUE, got %d\n", ret
);
1229 ret
= IsBadWritePtr(&stackval
, 0);
1230 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1232 ret
= IsBadWritePtr(&stackval
, sizeof(char));
1233 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1236 static void test_IsBadCodePtr(void)
1239 void *ptr
= (void *)0xdeadbeef;
1242 ret
= IsBadCodePtr(NULL
);
1243 ok(ret
== TRUE
, "Expected IsBadCodePtr to return TRUE, got %d\n", ret
);
1245 ret
= IsBadCodePtr(ptr
);
1246 ok(ret
== TRUE
, "Expected IsBadCodePtr to return TRUE, got %d\n", ret
);
1248 ret
= IsBadCodePtr((void *)&stackval
);
1249 ok(ret
== FALSE
, "Expected IsBadCodePtr to return FALSE, got %d\n", ret
);
1252 static void test_write_watch(void)
1255 DWORD ret
, size
, old_prot
;
1256 MEMORY_BASIC_INFORMATION info
;
1261 if (!pGetWriteWatch
|| !pResetWriteWatch
)
1263 win_skip( "GetWriteWatch not supported\n" );
1268 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
| MEM_WRITE_WATCH
, PAGE_READWRITE
);
1270 (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_NOT_SUPPORTED
))
1272 win_skip( "MEM_WRITE_WATCH not supported\n" );
1275 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1276 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1277 ok(ret
, "VirtualQuery failed %u\n", GetLastError());
1278 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1279 ok( info
.AllocationProtect
== PAGE_READWRITE
, "wrong AllocationProtect %x\n", info
.AllocationProtect
);
1280 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1281 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1282 ok( info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
1283 ok( info
.Type
== MEM_PRIVATE
, "wrong Type 0x%x\n", info
.Type
);
1286 SetLastError( 0xdeadbeef );
1287 ret
= pGetWriteWatch( 0, NULL
, size
, results
, &count
, &pagesize
);
1288 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1289 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
1290 broken( GetLastError() == 0xdeadbeef ), /* win98 */
1291 "wrong error %u\n", GetLastError() );
1293 SetLastError( 0xdeadbeef );
1294 ret
= pGetWriteWatch( 0, GetModuleHandleW(NULL
), size
, results
, &count
, &pagesize
);
1297 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1298 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1302 ok( count
== 0, "wrong count %lu\n", count
);
1305 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1306 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1307 ok( count
== 0, "wrong count %lu\n", count
);
1309 base
[pagesize
+ 1] = 0x44;
1312 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1313 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1314 ok( count
== 1, "wrong count %lu\n", count
);
1315 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1318 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1319 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1320 ok( count
== 1, "wrong count %lu\n", count
);
1321 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1324 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1325 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1326 ok( count
== 0, "wrong count %lu\n", count
);
1328 base
[2*pagesize
+ 3] = 0x11;
1329 base
[4*pagesize
+ 8] = 0x11;
1332 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1333 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1334 ok( count
== 2, "wrong count %lu\n", count
);
1335 ok( results
[0] == base
+ 2*pagesize
, "wrong result %p\n", results
[0] );
1336 ok( results
[1] == base
+ 4*pagesize
, "wrong result %p\n", results
[1] );
1339 ret
= pGetWriteWatch( 0, base
+ 3*pagesize
, 2*pagesize
, results
, &count
, &pagesize
);
1340 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1341 ok( count
== 1, "wrong count %lu\n", count
);
1342 ok( results
[0] == base
+ 4*pagesize
, "wrong result %p\n", results
[0] );
1344 ret
= pResetWriteWatch( base
, 3*pagesize
);
1345 ok( !ret
, "pResetWriteWatch failed %u\n", GetLastError() );
1348 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1349 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1350 ok( count
== 1, "wrong count %lu\n", count
);
1351 ok( results
[0] == base
+ 4*pagesize
, "wrong result %p\n", results
[0] );
1353 *(DWORD
*)(base
+ 2*pagesize
- 2) = 0xdeadbeef;
1356 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1357 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1358 ok( count
== 3, "wrong count %lu\n", count
);
1359 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1360 ok( results
[1] == base
+ 2*pagesize
, "wrong result %p\n", results
[1] );
1361 ok( results
[2] == base
+ 4*pagesize
, "wrong result %p\n", results
[2] );
1364 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1365 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1366 ok( count
== 1, "wrong count %lu\n", count
);
1367 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1370 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1371 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1372 ok( count
== 2, "wrong count %lu\n", count
);
1373 ok( results
[0] == base
+ 2*pagesize
, "wrong result %p\n", results
[0] );
1374 ok( results
[1] == base
+ 4*pagesize
, "wrong result %p\n", results
[1] );
1376 /* changing protections doesn't affect watches */
1378 ret
= VirtualProtect( base
, 3*pagesize
, PAGE_READONLY
, &old_prot
);
1379 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1380 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
1382 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1383 ok(ret
, "VirtualQuery failed %u\n", GetLastError());
1384 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1385 ok( info
.RegionSize
== 3*pagesize
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1386 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1387 ok( info
.Protect
== PAGE_READONLY
, "wrong Protect 0x%x\n", info
.Protect
);
1389 ret
= VirtualProtect( base
, 3*pagesize
, PAGE_READWRITE
, &old_prot
);
1390 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1391 ok( old_prot
== PAGE_READONLY
, "wrong old prot %x\n", old_prot
);
1394 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1395 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1396 ok( count
== 2, "wrong count %lu\n", count
);
1397 ok( results
[0] == base
+ 2*pagesize
, "wrong result %p\n", results
[0] );
1398 ok( results
[1] == base
+ 4*pagesize
, "wrong result %p\n", results
[1] );
1400 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1401 ok(ret
, "VirtualQuery failed %u\n", GetLastError());
1402 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1403 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1404 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1405 ok( info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
1407 /* some invalid parameter tests */
1409 SetLastError( 0xdeadbeef );
1411 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1414 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1415 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1417 SetLastError( 0xdeadbeef );
1418 ret
= pGetWriteWatch( 0, base
, size
, results
, NULL
, &pagesize
);
1419 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1420 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1422 SetLastError( 0xdeadbeef );
1424 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, NULL
);
1425 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1426 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1428 SetLastError( 0xdeadbeef );
1430 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
1431 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1432 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1434 SetLastError( 0xdeadbeef );
1436 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
1437 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1438 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1440 SetLastError( 0xdeadbeef );
1442 ret
= pGetWriteWatch( 0xdeadbeef, base
, size
, results
, &count
, &pagesize
);
1443 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1444 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1446 SetLastError( 0xdeadbeef );
1448 ret
= pGetWriteWatch( 0, base
, 0, results
, &count
, &pagesize
);
1449 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1450 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1452 SetLastError( 0xdeadbeef );
1454 ret
= pGetWriteWatch( 0, base
, size
* 2, results
, &count
, &pagesize
);
1455 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1456 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1458 SetLastError( 0xdeadbeef );
1460 ret
= pGetWriteWatch( 0, base
+ size
- pagesize
, pagesize
+ 1, results
, &count
, &pagesize
);
1461 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1462 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1464 SetLastError( 0xdeadbeef );
1465 ret
= pResetWriteWatch( base
, 0 );
1466 ok( ret
== ~0u, "ResetWriteWatch succeeded %u\n", ret
);
1467 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1469 SetLastError( 0xdeadbeef );
1470 ret
= pResetWriteWatch( GetModuleHandleW(NULL
), size
);
1471 ok( ret
== ~0u, "ResetWriteWatch succeeded %u\n", ret
);
1472 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1474 else /* win98 is completely different */
1476 SetLastError( 0xdeadbeef );
1478 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
1479 ok( ret
== ERROR_INVALID_PARAMETER
, "GetWriteWatch succeeded %u\n", ret
);
1480 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
1483 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
1484 ok( !ret
, "GetWriteWatch failed %u\n", ret
);
1487 ret
= pGetWriteWatch( 0xdeadbeef, base
, size
, results
, &count
, &pagesize
);
1488 ok( !ret
, "GetWriteWatch failed %u\n", ret
);
1491 ret
= pGetWriteWatch( 0, base
, 0, results
, &count
, &pagesize
);
1492 ok( !ret
, "GetWriteWatch failed %u\n", ret
);
1494 ret
= pResetWriteWatch( base
, 0 );
1495 ok( !ret
, "ResetWriteWatch failed %u\n", ret
);
1497 ret
= pResetWriteWatch( GetModuleHandleW(NULL
), size
);
1498 ok( !ret
, "ResetWriteWatch failed %u\n", ret
);
1501 VirtualFree( base
, 0, MEM_FREE
);
1503 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_WRITE_WATCH
, PAGE_READWRITE
);
1504 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1505 VirtualFree( base
, 0, MEM_FREE
);
1507 base
= VirtualAlloc( 0, size
, MEM_WRITE_WATCH
, PAGE_READWRITE
);
1508 ok( !base
, "VirtualAlloc succeeded\n" );
1509 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1511 /* initial protect doesn't matter */
1513 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_WRITE_WATCH
, PAGE_NOACCESS
);
1514 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1515 base
= VirtualAlloc( base
, size
, MEM_COMMIT
, PAGE_NOACCESS
);
1516 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1519 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1520 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1521 ok( count
== 0, "wrong count %lu\n", count
);
1523 ret
= VirtualProtect( base
, 6*pagesize
, PAGE_READWRITE
, &old_prot
);
1524 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1525 ok( old_prot
== PAGE_NOACCESS
, "wrong old prot %x\n", old_prot
);
1527 base
[5*pagesize
+ 200] = 3;
1529 ret
= VirtualProtect( base
, 6*pagesize
, PAGE_NOACCESS
, &old_prot
);
1530 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1531 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
1534 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1535 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1536 ok( count
== 1, "wrong count %lu\n", count
);
1537 ok( results
[0] == base
+ 5*pagesize
, "wrong result %p\n", results
[0] );
1539 ret
= VirtualFree( base
, size
, MEM_DECOMMIT
);
1540 ok( ret
, "VirtualFree failed %u\n", GetLastError() );
1543 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1544 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1545 ok( count
== 1 || broken(count
== 0), /* win98 */
1546 "wrong count %lu\n", count
);
1547 if (count
) ok( results
[0] == base
+ 5*pagesize
, "wrong result %p\n", results
[0] );
1549 VirtualFree( base
, 0, MEM_FREE
);
1554 static DWORD num_guard_page_calls
;
1556 static DWORD
guard_page_handler( EXCEPTION_RECORD
*rec
, EXCEPTION_REGISTRATION_RECORD
*frame
,
1557 CONTEXT
*context
, EXCEPTION_REGISTRATION_RECORD
**dispatcher
)
1559 trace( "exception: %08x flags:%x addr:%p\n",
1560 rec
->ExceptionCode
, rec
->ExceptionFlags
, rec
->ExceptionAddress
);
1562 ok( rec
->NumberParameters
== 2, "NumberParameters is %d instead of 2\n", rec
->NumberParameters
);
1563 ok( rec
->ExceptionCode
== STATUS_GUARD_PAGE_VIOLATION
, "ExceptionCode is %08x instead of %08x\n",
1564 rec
->ExceptionCode
, STATUS_GUARD_PAGE_VIOLATION
);
1566 num_guard_page_calls
++;
1567 *(int *)rec
->ExceptionInformation
[1] += 0x100;
1569 return ExceptionContinueExecution
;
1572 static void test_guard_page(void)
1574 EXCEPTION_REGISTRATION_RECORD frame
;
1575 MEMORY_BASIC_INFORMATION info
;
1576 DWORD ret
, size
, old_prot
;
1577 int *value
, old_value
;
1586 win_skip( "NtCurrentTeb not supported\n" );
1591 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
, PAGE_READWRITE
| PAGE_GUARD
);
1592 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1593 value
= (int *)base
;
1595 /* verify info structure */
1596 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1597 ok( ret
, "VirtualQuery failed %u\n", GetLastError());
1598 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1599 ok( info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong AllocationProtect %x\n", info
.AllocationProtect
);
1600 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1601 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1602 ok( info
.Protect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong Protect 0x%x\n", info
.Protect
);
1603 ok( info
.Type
== MEM_PRIVATE
, "wrong Type 0x%x\n", info
.Type
);
1605 /* put some initial value into the memory */
1606 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
1607 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1608 ok( old_prot
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong old prot %x\n", old_prot
);
1613 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
1614 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1615 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
1617 /* test behaviour of VirtualLock - first attempt should fail */
1618 SetLastError( 0xdeadbeef );
1619 success
= VirtualLock( base
, size
);
1620 ok( !success
, "VirtualLock unexpectedly succeded\n" );
1622 ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION
, "wrong error %u\n", GetLastError() );
1624 success
= VirtualLock( base
, size
);
1626 ok( success
, "VirtualLock failed %u\n", GetLastError() );
1629 ok( *value
== 1, "memory block contains wrong value, expected 1, got 0x%x\n", *value
);
1630 success
= VirtualUnlock( base
, size
);
1631 ok( success
, "VirtualUnlock failed %u\n", GetLastError() );
1634 /* check info structure again, PAGE_GUARD should be removed now */
1635 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1636 ok( ret
, "VirtualQuery failed %u\n", GetLastError());
1637 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1638 ok( info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong AllocationProtect %x\n", info
.AllocationProtect
);
1639 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1640 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1642 ok( info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
1643 ok( info
.Type
== MEM_PRIVATE
, "wrong Type 0x%x\n", info
.Type
);
1645 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
1646 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1648 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
1650 /* test directly accessing the memory - we need to setup an exception handler first */
1651 frame
.Handler
= guard_page_handler
;
1652 frame
.Prev
= pNtCurrentTeb()->Tib
.ExceptionList
;
1653 pNtCurrentTeb()->Tib
.ExceptionList
= &frame
;
1655 num_guard_page_calls
= 0;
1656 old_value
= *value
; /* exception handler increments value by 0x100 */
1658 ok( old_value
== 0x101, "memory block contains wrong value, expected 0x101, got 0x%x\n", old_value
);
1659 ok( num_guard_page_calls
== 1, "expected one callback of guard page handler, got %d calls\n", num_guard_page_calls
);
1661 pNtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
1663 /* check info structure again, PAGE_GUARD should be removed now */
1664 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1665 ok( ret
, "VirtualQuery failed %u\n", GetLastError());
1666 ok( info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
1668 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
1669 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1670 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
1672 /* test accessing second integer in memory */
1673 frame
.Handler
= guard_page_handler
;
1674 frame
.Prev
= pNtCurrentTeb()->Tib
.ExceptionList
;
1675 pNtCurrentTeb()->Tib
.ExceptionList
= &frame
;
1677 num_guard_page_calls
= 0;
1678 old_value
= *(value
+ 1);
1679 ok( old_value
== 0x102, "memory block contains wrong value, expected 0x102, got 0x%x\n", old_value
);
1680 ok( *value
== 2, "memory block contains wrong value, expected 2, got 0x%x\n", *value
);
1681 ok( num_guard_page_calls
== 1, "expected one callback of guard page handler, got %d calls\n", num_guard_page_calls
);
1683 pNtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
1685 success
= VirtualLock( base
, size
);
1686 ok( success
, "VirtualLock failed %u\n", GetLastError() );
1689 ok( *value
== 2, "memory block contains wrong value, expected 2, got 0x%x\n", *value
);
1690 success
= VirtualUnlock( base
, size
);
1691 ok( success
, "VirtualUnlock failed %u\n", GetLastError() );
1694 VirtualFree( base
, 0, MEM_FREE
);
1696 /* combined guard page / write watch tests */
1697 if (!pGetWriteWatch
|| !pResetWriteWatch
)
1699 win_skip( "GetWriteWatch not supported, skipping combined guard page / write watch tests\n" );
1703 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
| MEM_WRITE_WATCH
, PAGE_READWRITE
| PAGE_GUARD
);
1704 if (!base
&& (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_NOT_SUPPORTED
))
1706 win_skip( "MEM_WRITE_WATCH not supported\n" );
1709 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1710 value
= (int *)base
;
1712 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1713 ok( ret
, "VirtualQuery failed %u\n", GetLastError() );
1714 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1715 ok( info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong AllocationProtect %x\n", info
.AllocationProtect
);
1716 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1717 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1718 ok( info
.Protect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong Protect 0x%x\n", info
.Protect
);
1719 ok( info
.Type
== MEM_PRIVATE
, "wrong Type 0x%x\n", info
.Type
);
1722 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1723 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1724 ok( count
== 0, "wrong count %lu\n", count
);
1726 /* writing to a page should trigger should trigger guard page, even if write watch is set */
1727 frame
.Handler
= guard_page_handler
;
1728 frame
.Prev
= pNtCurrentTeb()->Tib
.ExceptionList
;
1729 pNtCurrentTeb()->Tib
.ExceptionList
= &frame
;
1731 num_guard_page_calls
= 0;
1734 ok( num_guard_page_calls
== 1, "expected one callback of guard page handler, got %d calls\n", num_guard_page_calls
);
1736 pNtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
1739 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1740 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1741 ok( count
== 1, "wrong count %lu\n", count
);
1742 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
1744 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
1745 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1747 /* write watch is triggered from inside of the guard page handler */
1748 frame
.Handler
= guard_page_handler
;
1749 frame
.Prev
= pNtCurrentTeb()->Tib
.ExceptionList
;
1750 pNtCurrentTeb()->Tib
.ExceptionList
= &frame
;
1752 num_guard_page_calls
= 0;
1753 old_value
= *(value
+ 1); /* doesn't trigger write watch */
1754 ok( old_value
== 0x102, "memory block contains wrong value, expected 0x102, got 0x%x\n", old_value
);
1755 ok( *value
== 1, "memory block contains wrong value, expected 1, got 0x%x\n", *value
);
1756 ok( num_guard_page_calls
== 1, "expected one callback of guard page handler, got %d calls\n", num_guard_page_calls
);
1758 pNtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
1761 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1762 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1763 ok( count
== 1, "wrong count %lu\n", count
);
1764 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
1766 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
1767 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1769 /* test behaviour of VirtualLock - first attempt should fail without triggering write watches */
1770 SetLastError( 0xdeadbeef );
1771 success
= VirtualLock( base
, size
);
1772 ok( !success
, "VirtualLock unexpectedly succeded\n" );
1774 ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION
, "wrong error %u\n", GetLastError() );
1777 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1778 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1779 ok( count
== 0, "wrong count %lu\n", count
);
1781 success
= VirtualLock( base
, size
);
1783 ok( success
, "VirtualLock failed %u\n", GetLastError() );
1786 ok( *value
== 1, "memory block contains wrong value, expected 1, got 0x%x\n", *value
);
1787 success
= VirtualUnlock( base
, size
);
1788 ok( success
, "VirtualUnlock failed %u\n", GetLastError() );
1792 results
[0] = (void *)0xdeadbeef;
1793 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1794 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1796 ok( count
== 1 || broken(count
== 0) /* Windows 8 */, "wrong count %lu\n", count
);
1798 ok( results
[0] == base
|| broken(results
[0] == (void *)0xdeadbeef) /* Windows 8 */, "wrong result %p\n", results
[0] );
1800 VirtualFree( base
, 0, MEM_FREE
);
1803 DWORD num_execute_fault_calls
;
1805 static DWORD
execute_fault_seh_handler( EXCEPTION_RECORD
*rec
, EXCEPTION_REGISTRATION_RECORD
*frame
,
1806 CONTEXT
*context
, EXCEPTION_REGISTRATION_RECORD
**dispatcher
)
1808 ULONG flags
= MEM_EXECUTE_OPTION_ENABLE
;
1810 trace( "exception: %08x flags:%x addr:%p info[0]:%ld info[1]:%p\n",
1811 rec
->ExceptionCode
, rec
->ExceptionFlags
, rec
->ExceptionAddress
,
1812 rec
->ExceptionInformation
[0], (void *)rec
->ExceptionInformation
[1] );
1814 ok( rec
->NumberParameters
== 2, "NumberParameters is %d instead of 2\n", rec
->NumberParameters
);
1815 ok( rec
->ExceptionCode
== STATUS_ACCESS_VIOLATION
|| rec
->ExceptionCode
== STATUS_GUARD_PAGE_VIOLATION
,
1816 "ExceptionCode is %08x instead of STATUS_ACCESS_VIOLATION or STATUS_GUARD_PAGE_VIOLATION\n", rec
->ExceptionCode
);
1818 NtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &flags
, sizeof(flags
), NULL
);
1820 if (rec
->ExceptionCode
== STATUS_GUARD_PAGE_VIOLATION
)
1823 ok( rec
->ExceptionInformation
[0] == EXCEPTION_EXECUTE_FAULT
||
1824 broken(!(flags
& MEM_EXECUTE_OPTION_DISABLE
) && rec
->ExceptionInformation
[0] == EXCEPTION_READ_FAULT
), /* Windows 2000 */
1825 "ExceptionInformation[0] is %d instead of %d\n", (DWORD
)rec
->ExceptionInformation
[0], EXCEPTION_EXECUTE_FAULT
);
1827 num_guard_page_calls
++;
1829 else if (rec
->ExceptionCode
== STATUS_ACCESS_VIOLATION
)
1831 DWORD err
, old_prot
;
1834 err
= (flags
& MEM_EXECUTE_OPTION_DISABLE
) ? EXCEPTION_EXECUTE_FAULT
: EXCEPTION_READ_FAULT
;
1835 ok( rec
->ExceptionInformation
[0] == err
, "ExceptionInformation[0] is %d instead of %d\n",
1836 (DWORD
)rec
->ExceptionInformation
[0], err
);
1838 success
= VirtualProtect( (void *)rec
->ExceptionInformation
[1], 16, PAGE_EXECUTE_READWRITE
, &old_prot
);
1839 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1840 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
1842 num_execute_fault_calls
++;
1845 return ExceptionContinueExecution
;
1848 static LONG CALLBACK
execute_fault_vec_handler( EXCEPTION_POINTERS
*ExceptionInfo
)
1850 PEXCEPTION_RECORD rec
= ExceptionInfo
->ExceptionRecord
;
1854 trace( "exception: %08x flags:%x addr:%p info[0]:%ld info[1]:%p\n",
1855 rec
->ExceptionCode
, rec
->ExceptionFlags
, rec
->ExceptionAddress
,
1856 rec
->ExceptionInformation
[0], (void *)rec
->ExceptionInformation
[1] );
1858 ok( rec
->NumberParameters
== 2, "NumberParameters is %d instead of 2\n", rec
->NumberParameters
);
1859 ok( rec
->ExceptionCode
== STATUS_ACCESS_VIOLATION
,
1860 "ExceptionCode is %08x instead of STATUS_ACCESS_VIOLATION\n", rec
->ExceptionCode
);
1862 if (rec
->ExceptionCode
== STATUS_ACCESS_VIOLATION
)
1863 num_execute_fault_calls
++;
1865 if (rec
->ExceptionInformation
[0] == EXCEPTION_READ_FAULT
)
1866 return EXCEPTION_CONTINUE_SEARCH
;
1868 success
= VirtualProtect( (void *)rec
->ExceptionInformation
[1], 16, PAGE_EXECUTE_READWRITE
, &old_prot
);
1869 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1870 ok( old_prot
== PAGE_NOACCESS
, "wrong old prot %x\n", old_prot
);
1872 return EXCEPTION_CONTINUE_EXECUTION
;
1875 static inline DWORD
send_message_excpt( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1877 EXCEPTION_REGISTRATION_RECORD frame
;
1880 frame
.Handler
= execute_fault_seh_handler
;
1881 frame
.Prev
= pNtCurrentTeb()->Tib
.ExceptionList
;
1882 pNtCurrentTeb()->Tib
.ExceptionList
= &frame
;
1884 num_guard_page_calls
= num_execute_fault_calls
= 0;
1885 ret
= SendMessageA( hWnd
, WM_USER
, 0, 0 );
1887 pNtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
1892 static LRESULT CALLBACK
jmp_test_func( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1894 if (uMsg
== WM_USER
)
1897 return DefWindowProcA( hWnd
, uMsg
, wParam
, lParam
);
1900 static LRESULT CALLBACK
atl_test_func( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1902 DWORD arg
= (DWORD
)hWnd
;
1903 ok( arg
== 0x11223344, "arg is 0x%08x instead of 0x11223344\n", arg
);
1907 static void test_atl_thunk_emulation( ULONG dep_flags
)
1909 static const char code_jmp
[] = {0xE9, 0x00, 0x00, 0x00, 0x00};
1910 static const char code_atl
[] = {0xC7, 0x44, 0x24, 0x04, 0x44, 0x33, 0x22, 0x11, 0xE9, 0x00, 0x00, 0x00, 0x00};
1911 static const char cls_name
[] = "atl_thunk_class";
1912 DWORD ret
, size
, old_prot
;
1913 ULONG old_flags
= MEM_EXECUTE_OPTION_ENABLE
;
1924 win_skip( "NtCurrentTeb not supported\n" );
1928 trace( "Running DEP tests with ProcessExecuteFlags = %d\n", dep_flags
);
1930 NtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &old_flags
, sizeof(old_flags
), NULL
);
1931 if (old_flags
!= dep_flags
)
1933 ret
= NtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &dep_flags
, sizeof(dep_flags
) );
1934 if (ret
== STATUS_INVALID_INFO_CLASS
) /* Windows 2000 */
1936 win_skip( "Skipping DEP tests with ProcessExecuteFlags = %d\n", dep_flags
);
1939 ok( !ret
, "NtSetInformationProcess failed with status %08x\n", ret
);
1943 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
, PAGE_READWRITE
);
1944 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1946 memcpy( base
, code_jmp
, sizeof(code_jmp
) );
1947 *(DWORD
*)(base
+ 1) = (DWORD_PTR
)jmp_test_func
- (DWORD_PTR
)(base
+ 5);
1949 /* On Windows, the ATL Thunk emulation is only enabled while running WndProc functions,
1950 * whereas in Wine such a limitation doesn't exist yet. We want to test in a scenario
1951 * where it is active, so that application which depend on that still work properly.
1952 * We have no exception handler enabled yet, so give proper EXECUTE permissions to
1953 * prevent crashes while creating the window. */
1955 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
1956 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1958 memset( &wc
, 0, sizeof(wc
) );
1959 wc
.cbSize
= sizeof(wc
);
1960 wc
.style
= CS_VREDRAW
| CS_HREDRAW
;
1961 wc
.hInstance
= GetModuleHandleA( 0 );
1962 wc
.hCursor
= LoadCursorA( NULL
, (LPCSTR
)IDC_ARROW
);
1963 wc
.hbrBackground
= NULL
;
1964 wc
.lpszClassName
= cls_name
;
1965 wc
.lpfnWndProc
= (WNDPROC
)base
;
1966 success
= RegisterClassExA(&wc
) != 0;
1967 ok( success
, "RegisterClassExA failed %u\n", GetLastError() );
1969 hWnd
= CreateWindowExA(0, cls_name
, "Test", WS_TILEDWINDOW
, 0, 0, 640, 480, 0, 0, 0, 0);
1970 ok( hWnd
!= 0, "CreateWindowExA failed %u\n", GetLastError() );
1972 ret
= SendMessageA(hWnd
, WM_USER
, 0, 0);
1973 ok( ret
== 42, "SendMessage returned unexpected result %d\n", ret
);
1975 /* At first try with an instruction which is not recognized as proper ATL thunk
1976 * by the Windows ATL Thunk Emulator. Removing execute permissions will lead to
1977 * STATUS_ACCESS_VIOLATION exceptions when DEP is enabled. */
1979 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
1980 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1982 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
1983 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
1984 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
1985 if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
1986 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
1988 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
1990 /* Now a bit more complicated, the page containing the code is protected with
1991 * PAGE_GUARD memory protection. */
1993 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
1994 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
1996 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
1997 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
1998 ok( num_guard_page_calls
== 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
1999 if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2000 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2002 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2004 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2005 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2006 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2007 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2009 /* Now test with a proper ATL thunk instruction. */
2011 memcpy( base
, code_atl
, sizeof(code_atl
) );
2012 *(DWORD
*)(base
+ 9) = (DWORD_PTR
)atl_test_func
- (DWORD_PTR
)(base
+ 13);
2014 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2015 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2017 ret
= SendMessageA(hWnd
, WM_USER
, 0, 0);
2018 ok( ret
== 43, "SendMessage returned unexpected result %d\n", ret
);
2020 /* Try executing with PAGE_READWRITE protection. */
2022 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2023 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2025 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2026 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2027 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2028 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2029 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2031 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2033 /* Now a bit more complicated, the page containing the code is protected with
2034 * PAGE_GUARD memory protection. */
2036 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2037 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2039 /* the same, but with PAGE_GUARD set */
2040 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2041 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2042 ok( num_guard_page_calls
== 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2043 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2044 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2046 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2048 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2049 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2050 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2051 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2053 /* The following test shows that on Windows, even a vectored exception handler
2054 * cannot intercept internal exceptions thrown by the ATL thunk emulation layer. */
2056 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && !(dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2058 if (pRtlAddVectoredExceptionHandler
&& pRtlRemoveVectoredExceptionHandler
)
2060 PVOID vectored_handler
;
2062 success
= VirtualProtect( base
, size
, PAGE_NOACCESS
, &old_prot
);
2063 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2065 vectored_handler
= pRtlAddVectoredExceptionHandler( TRUE
, &execute_fault_vec_handler
);
2066 ok( vectored_handler
!= 0, "RtlAddVectoredExceptionHandler failed\n" );
2068 num_execute_fault_calls
= 0;
2069 ret
= SendMessageA( hWnd
, WM_USER
, 0, 0 );
2071 pRtlRemoveVectoredExceptionHandler( vectored_handler
);
2073 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2074 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2077 win_skip( "RtlAddVectoredExceptionHandler or RtlRemoveVectoredExceptionHandler not found\n" );
2080 /* Restore the JMP instruction, set to executable, and then destroy the Window */
2082 memcpy( base
, code_jmp
, sizeof(code_jmp
) );
2083 *(DWORD
*)(base
+ 1) = (DWORD_PTR
)jmp_test_func
- (DWORD_PTR
)(base
+ 5);
2085 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2086 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2088 DestroyWindow( hWnd
);
2090 success
= UnregisterClassA( cls_name
, GetModuleHandleA(0) );
2091 ok( success
, "UnregisterClass failed %u\n", GetLastError() );
2093 VirtualFree( base
, 0, MEM_FREE
);
2095 /* Repeat the tests from above with MEM_WRITE_WATCH protected memory. */
2097 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
| MEM_WRITE_WATCH
, PAGE_READWRITE
);
2098 if (!base
&& (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_NOT_SUPPORTED
))
2100 win_skip( "MEM_WRITE_WATCH not supported\n" );
2103 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2106 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2107 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2108 ok( count
== 0, "wrong count %lu\n", count
);
2110 memcpy( base
, code_jmp
, sizeof(code_jmp
) );
2111 *(DWORD
*)(base
+ 1) = (DWORD_PTR
)jmp_test_func
- (DWORD_PTR
)(base
+ 5);
2114 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2115 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2116 ok( count
== 1, "wrong count %lu\n", count
);
2117 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
2119 /* Create a new window class and associcated Window (see above) */
2121 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2122 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2124 memset( &wc
, 0, sizeof(wc
) );
2125 wc
.cbSize
= sizeof(wc
);
2126 wc
.style
= CS_VREDRAW
| CS_HREDRAW
;
2127 wc
.hInstance
= GetModuleHandleA( 0 );
2128 wc
.hCursor
= LoadCursorA( NULL
, (LPCSTR
)IDC_ARROW
);
2129 wc
.hbrBackground
= NULL
;
2130 wc
.lpszClassName
= cls_name
;
2131 wc
.lpfnWndProc
= (WNDPROC
)base
;
2132 success
= RegisterClassExA(&wc
) != 0;
2133 ok( success
, "RegisterClassExA failed %u\n", GetLastError() );
2135 hWnd
= CreateWindowExA(0, cls_name
, "Test", WS_TILEDWINDOW
, 0, 0, 640, 480, 0, 0, 0, 0);
2136 ok( hWnd
!= 0, "CreateWindowExA failed %u\n", GetLastError() );
2138 ret
= SendMessageA(hWnd
, WM_USER
, 0, 0);
2139 ok( ret
== 42, "SendMessage returned unexpected result %d\n", ret
);
2142 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2143 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2144 ok( count
== 0, "wrong count %lu\n", count
);
2146 /* At first try with an instruction which is not recognized as proper ATL thunk
2147 * by the Windows ATL Thunk Emulator. Removing execute permissions will lead to
2148 * STATUS_ACCESS_VIOLATION exceptions when DEP is enabled. */
2150 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2151 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2153 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2154 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2155 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2156 if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2157 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2159 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2162 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2163 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2164 ok( count
== 0, "wrong count %lu\n", count
);
2166 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2167 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2168 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2169 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2171 /* Now a bit more complicated, the page containing the code is protected with
2172 * PAGE_GUARD memory protection. */
2174 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2175 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2177 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2178 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2179 ok( num_guard_page_calls
== 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2180 if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2181 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2183 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2185 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2186 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2187 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2188 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2191 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2192 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2193 ok( count
== 0 || broken(count
== 1) /* Windows 8 */, "wrong count %lu\n", count
);
2195 /* Now test with a proper ATL thunk instruction. */
2197 memcpy( base
, code_atl
, sizeof(code_atl
) );
2198 *(DWORD
*)(base
+ 9) = (DWORD_PTR
)atl_test_func
- (DWORD_PTR
)(base
+ 13);
2201 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2202 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2203 ok( count
== 1, "wrong count %lu\n", count
);
2204 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
2206 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2207 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2209 ret
= SendMessageA(hWnd
, WM_USER
, 0, 0);
2210 ok( ret
== 43, "SendMessage returned unexpected result %d\n", ret
);
2212 /* Try executing with PAGE_READWRITE protection. */
2214 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2215 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2217 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2218 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2219 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2220 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2221 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2223 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2226 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2227 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2228 ok( count
== 0, "wrong count %lu\n", count
);
2230 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2231 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2232 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2233 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2234 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2236 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2238 /* Now a bit more complicated, the page containing the code is protected with
2239 * PAGE_GUARD memory protection. */
2241 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2242 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2244 /* the same, but with PAGE_GUARD set */
2245 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2246 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2247 ok( num_guard_page_calls
== 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2248 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2249 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2251 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2253 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2254 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2255 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2256 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2259 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2260 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2261 ok( count
== 0 || broken(count
== 1) /* Windows 8 */, "wrong count %lu\n", count
);
2263 /* Restore the JMP instruction, set to executable, and then destroy the Window */
2265 memcpy( base
, code_jmp
, sizeof(code_jmp
) );
2266 *(DWORD
*)(base
+ 1) = (DWORD_PTR
)jmp_test_func
- (DWORD_PTR
)(base
+ 5);
2269 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2270 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2271 ok( count
== 1, "wrong count %lu\n", count
);
2272 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
2274 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2275 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2277 DestroyWindow( hWnd
);
2279 success
= UnregisterClassA( cls_name
, GetModuleHandleA(0) );
2280 ok( success
, "UnregisterClass failed %u\n", GetLastError() );
2282 VirtualFree( base
, 0, MEM_FREE
);
2285 if (old_flags
!= dep_flags
)
2287 ret
= NtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &old_flags
, sizeof(old_flags
) );
2288 ok( !ret
, "NtSetInformationProcess failed with status %08x\n", ret
);
2292 #endif /* __i386__ */
2294 static void test_VirtualProtect(void)
2296 static const struct test_data
2298 DWORD prot_set
, prot_get
;
2301 { 0, 0 }, /* 0x00 */
2302 { PAGE_NOACCESS
, PAGE_NOACCESS
}, /* 0x01 */
2303 { PAGE_READONLY
, PAGE_READONLY
}, /* 0x02 */
2304 { PAGE_READONLY
| PAGE_NOACCESS
, 0 }, /* 0x03 */
2305 { PAGE_READWRITE
, PAGE_READWRITE
}, /* 0x04 */
2306 { PAGE_READWRITE
| PAGE_NOACCESS
, 0 }, /* 0x05 */
2307 { PAGE_READWRITE
| PAGE_READONLY
, 0 }, /* 0x06 */
2308 { PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, 0 }, /* 0x07 */
2309 { PAGE_WRITECOPY
, 0 }, /* 0x08 */
2310 { PAGE_WRITECOPY
| PAGE_NOACCESS
, 0 }, /* 0x09 */
2311 { PAGE_WRITECOPY
| PAGE_READONLY
, 0 }, /* 0x0a */
2312 { PAGE_WRITECOPY
| PAGE_NOACCESS
| PAGE_READONLY
, 0 }, /* 0x0b */
2313 { PAGE_WRITECOPY
| PAGE_READWRITE
, 0 }, /* 0x0c */
2314 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_NOACCESS
, 0 }, /* 0x0d */
2315 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
, 0 }, /* 0x0e */
2316 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, 0 }, /* 0x0f */
2318 { PAGE_EXECUTE
, PAGE_EXECUTE
}, /* 0x10 */
2319 { PAGE_EXECUTE_READ
, PAGE_EXECUTE_READ
}, /* 0x20 */
2320 { PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 }, /* 0x30 */
2321 { PAGE_EXECUTE_READWRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x40 */
2322 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, 0 }, /* 0x50 */
2323 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, 0 }, /* 0x60 */
2324 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 }, /* 0x70 */
2325 { PAGE_EXECUTE_WRITECOPY
, 0 }, /* 0x80 */
2326 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE
, 0 }, /* 0x90 */
2327 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
, 0 }, /* 0xa0 */
2328 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 }, /* 0xb0 */
2329 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
, 0 }, /* 0xc0 */
2330 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, 0 }, /* 0xd0 */
2331 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, 0 }, /* 0xe0 */
2332 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 } /* 0xf0 */
2335 DWORD ret
, old_prot
, rw_prot
, exec_prot
, i
, j
;
2336 MEMORY_BASIC_INFORMATION info
;
2340 trace("system page size %#x\n", si
.dwPageSize
);
2342 SetLastError(0xdeadbeef);
2343 base
= VirtualAlloc(0, si
.dwPageSize
, MEM_RESERVE
| MEM_COMMIT
, PAGE_NOACCESS
);
2344 ok(base
!= NULL
, "VirtualAlloc failed %d\n", GetLastError());
2346 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
2348 SetLastError(0xdeadbeef);
2349 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2350 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
2351 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
2352 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
2353 ok(info
.Protect
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, info
.Protect
);
2354 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
2355 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%d: %#x != PAGE_NOACCESS\n", i
, info
.AllocationProtect
);
2356 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
2357 ok(info
.Type
== MEM_PRIVATE
, "%d: %#x != MEM_PRIVATE\n", i
, info
.Type
);
2359 old_prot
= 0xdeadbeef;
2360 SetLastError(0xdeadbeef);
2361 ret
= VirtualProtect(base
, si
.dwPageSize
, td
[i
].prot_set
, &old_prot
);
2364 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
2365 ok(old_prot
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, old_prot
);
2367 SetLastError(0xdeadbeef);
2368 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2369 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
2370 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
2371 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
2372 ok(info
.Protect
== td
[i
].prot_get
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot_get
);
2373 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
2374 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%d: %#x != PAGE_NOACCESS\n", i
, info
.AllocationProtect
);
2375 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
2376 ok(info
.Type
== MEM_PRIVATE
, "%d: %#x != MEM_PRIVATE\n", i
, info
.Type
);
2380 ok(!ret
, "%d: VirtualProtect should fail\n", i
);
2381 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
2384 old_prot
= 0xdeadbeef;
2385 SetLastError(0xdeadbeef);
2386 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
2387 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
2389 ok(old_prot
== td
[i
].prot_get
, "%d: got %#x != expected %#x\n", i
, old_prot
, td
[i
].prot_get
);
2391 ok(old_prot
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, old_prot
);
2396 for (i
= 0; i
<= 4; i
++)
2400 for (j
= 0; j
<= 4; j
++)
2402 DWORD prot
= exec_prot
| rw_prot
;
2404 SetLastError(0xdeadbeef);
2405 ptr
= VirtualAlloc(base
, si
.dwPageSize
, MEM_COMMIT
, prot
);
2406 if ((rw_prot
&& exec_prot
) || (!rw_prot
&& !exec_prot
))
2408 ok(!ptr
, "VirtualAlloc(%02x) should fail\n", prot
);
2409 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2413 if (prot
& (PAGE_WRITECOPY
| PAGE_EXECUTE_WRITECOPY
))
2415 ok(!ptr
, "VirtualAlloc(%02x) should fail\n", prot
);
2416 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2420 ok(ptr
!= NULL
, "VirtualAlloc(%02x) error %d\n", prot
, GetLastError());
2421 ok(ptr
== base
, "expected %p, got %p\n", base
, ptr
);
2425 SetLastError(0xdeadbeef);
2426 ret
= VirtualProtect(base
, si
.dwPageSize
, prot
, &old_prot
);
2427 if ((rw_prot
&& exec_prot
) || (!rw_prot
&& !exec_prot
))
2429 ok(!ret
, "VirtualProtect(%02x) should fail\n", prot
);
2430 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2434 if (prot
& (PAGE_WRITECOPY
| PAGE_EXECUTE_WRITECOPY
))
2436 ok(!ret
, "VirtualProtect(%02x) should fail\n", prot
);
2437 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2440 ok(ret
, "VirtualProtect(%02x) error %d\n", prot
, GetLastError());
2446 exec_prot
= 1 << (i
+ 4);
2449 VirtualFree(base
, 0, MEM_FREE
);
2452 static BOOL
is_mem_writable(DWORD prot
)
2454 switch (prot
& 0xff)
2456 case PAGE_READWRITE
:
2457 case PAGE_WRITECOPY
:
2458 case PAGE_EXECUTE_READWRITE
:
2459 case PAGE_EXECUTE_WRITECOPY
:
2467 static void test_VirtualAlloc_protection(void)
2469 static const struct test_data
2475 { 0, FALSE
}, /* 0x00 */
2476 { PAGE_NOACCESS
, TRUE
}, /* 0x01 */
2477 { PAGE_READONLY
, TRUE
}, /* 0x02 */
2478 { PAGE_READONLY
| PAGE_NOACCESS
, FALSE
}, /* 0x03 */
2479 { PAGE_READWRITE
, TRUE
}, /* 0x04 */
2480 { PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
}, /* 0x05 */
2481 { PAGE_READWRITE
| PAGE_READONLY
, FALSE
}, /* 0x06 */
2482 { PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
}, /* 0x07 */
2483 { PAGE_WRITECOPY
, FALSE
}, /* 0x08 */
2484 { PAGE_WRITECOPY
| PAGE_NOACCESS
, FALSE
}, /* 0x09 */
2485 { PAGE_WRITECOPY
| PAGE_READONLY
, FALSE
}, /* 0x0a */
2486 { PAGE_WRITECOPY
| PAGE_NOACCESS
| PAGE_READONLY
, FALSE
}, /* 0x0b */
2487 { PAGE_WRITECOPY
| PAGE_READWRITE
, FALSE
}, /* 0x0c */
2488 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
}, /* 0x0d */
2489 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
, FALSE
}, /* 0x0e */
2490 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
}, /* 0x0f */
2492 { PAGE_EXECUTE
, TRUE
}, /* 0x10 */
2493 { PAGE_EXECUTE_READ
, TRUE
}, /* 0x20 */
2494 { PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
}, /* 0x30 */
2495 { PAGE_EXECUTE_READWRITE
, TRUE
}, /* 0x40 */
2496 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
}, /* 0x50 */
2497 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
}, /* 0x60 */
2498 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
}, /* 0x70 */
2499 { PAGE_EXECUTE_WRITECOPY
, FALSE
}, /* 0x80 */
2500 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE
, FALSE
}, /* 0x90 */
2501 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
, FALSE
}, /* 0xa0 */
2502 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
}, /* 0xb0 */
2503 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
, FALSE
}, /* 0xc0 */
2504 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
}, /* 0xd0 */
2505 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
}, /* 0xe0 */
2506 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
} /* 0xf0 */
2510 MEMORY_BASIC_INFORMATION info
;
2514 trace("system page size %#x\n", si
.dwPageSize
);
2516 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
2518 SetLastError(0xdeadbeef);
2519 base
= VirtualAlloc(0, si
.dwPageSize
, MEM_COMMIT
, td
[i
].prot
);
2523 ok(base
!= NULL
, "%d: VirtualAlloc failed %d\n", i
, GetLastError());
2525 SetLastError(0xdeadbeef);
2526 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2527 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
2528 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
2529 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
2530 ok(info
.Protect
== td
[i
].prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot
);
2531 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
2532 ok(info
.AllocationProtect
== td
[i
].prot
, "%d: %#x != %#x\n", i
, info
.AllocationProtect
, td
[i
].prot
);
2533 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
2534 ok(info
.Type
== MEM_PRIVATE
, "%d: %#x != MEM_PRIVATE\n", i
, info
.Type
);
2536 if (is_mem_writable(info
.Protect
))
2540 SetLastError(0xdeadbeef);
2541 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2542 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
2543 ok(info
.Protect
== td
[i
].prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot
);
2546 SetLastError(0xdeadbeef);
2547 ptr
= VirtualAlloc(base
, si
.dwPageSize
, MEM_COMMIT
, td
[i
].prot
);
2548 ok(ptr
== base
, "%d: VirtualAlloc failed %d\n", i
, GetLastError());
2550 VirtualFree(base
, 0, MEM_FREE
);
2554 ok(!base
, "%d: VirtualAlloc should fail\n", i
);
2555 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
2560 static void test_CreateFileMapping_protection(void)
2562 static const struct test_data
2566 DWORD prot_after_write
;
2569 { 0, FALSE
, 0 }, /* 0x00 */
2570 { PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x01 */
2571 { PAGE_READONLY
, TRUE
, PAGE_READONLY
}, /* 0x02 */
2572 { PAGE_READONLY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x03 */
2573 { PAGE_READWRITE
, TRUE
, PAGE_READWRITE
}, /* 0x04 */
2574 { PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x05 */
2575 { PAGE_READWRITE
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x06 */
2576 { PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x07 */
2577 { PAGE_WRITECOPY
, TRUE
, PAGE_READWRITE
}, /* 0x08 */
2578 { PAGE_WRITECOPY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x09 */
2579 { PAGE_WRITECOPY
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x0a */
2580 { PAGE_WRITECOPY
| PAGE_NOACCESS
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x0b */
2581 { PAGE_WRITECOPY
| PAGE_READWRITE
, FALSE
, PAGE_NOACCESS
}, /* 0x0c */
2582 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x0d */
2583 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x0e */
2584 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x0f */
2586 { PAGE_EXECUTE
, FALSE
, PAGE_EXECUTE
}, /* 0x10 */
2587 { PAGE_EXECUTE_READ
, TRUE
, PAGE_EXECUTE_READ
}, /* 0x20 */
2588 { PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_EXECUTE_READ
}, /* 0x30 */
2589 { PAGE_EXECUTE_READWRITE
, TRUE
, PAGE_EXECUTE_READWRITE
}, /* 0x40 */
2590 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0x50 */
2591 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
, PAGE_NOACCESS
}, /* 0x60 */
2592 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0x70 */
2593 { PAGE_EXECUTE_WRITECOPY
, TRUE
, PAGE_EXECUTE_READWRITE
}, /* 0x80 */
2594 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0x90 */
2595 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
, FALSE
, PAGE_NOACCESS
}, /* 0xa0 */
2596 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0xb0 */
2597 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
, FALSE
, PAGE_NOACCESS
}, /* 0xc0 */
2598 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0xd0 */
2599 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
, PAGE_NOACCESS
}, /* 0xe0 */
2600 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
} /* 0xf0 */
2603 DWORD ret
, i
, alloc_prot
, prot
, old_prot
;
2604 MEMORY_BASIC_INFORMATION info
;
2606 char temp_path
[MAX_PATH
];
2607 char file_name
[MAX_PATH
];
2609 BOOL page_exec_supported
= TRUE
;
2612 trace("system page size %#x\n", si
.dwPageSize
);
2614 GetTempPathA(MAX_PATH
, temp_path
);
2615 GetTempFileNameA(temp_path
, "map", 0, file_name
);
2617 SetLastError(0xdeadbeef);
2618 hfile
= CreateFileA(file_name
, GENERIC_READ
|GENERIC_WRITE
|GENERIC_EXECUTE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2619 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile(%s) error %d\n", file_name
, GetLastError());
2620 SetFilePointer(hfile
, si
.dwPageSize
, NULL
, FILE_BEGIN
);
2621 SetEndOfFile(hfile
);
2623 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
2625 SetLastError(0xdeadbeef);
2626 hmap
= CreateFileMappingW(hfile
, NULL
, td
[i
].prot
| SEC_COMMIT
, 0, si
.dwPageSize
, NULL
);
2632 trace("%d: CreateFileMapping(%04x) failed: %d\n", i
, td
[i
].prot
, GetLastError());
2633 /* NT4 and win2k don't support EXEC on file mappings */
2634 if (td
[i
].prot
== PAGE_EXECUTE_READ
|| td
[i
].prot
== PAGE_EXECUTE_READWRITE
)
2636 page_exec_supported
= FALSE
;
2637 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE\n", i
);
2640 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
2641 if (td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
2643 page_exec_supported
= FALSE
;
2644 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE_WRITECOPY\n", i
);
2648 ok(hmap
!= 0, "%d: CreateFileMapping(%04x) error %d\n", i
, td
[i
].prot
, GetLastError());
2650 base
= MapViewOfFile(hmap
, FILE_MAP_READ
, 0, 0, 0);
2651 ok(base
!= NULL
, "%d: MapViewOfFile failed %d\n", i
, GetLastError());
2653 SetLastError(0xdeadbeef);
2654 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2655 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
2656 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
2657 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
2658 ok(info
.Protect
== PAGE_READONLY
, "%d: got %#x != expected PAGE_READONLY\n", i
, info
.Protect
);
2659 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
2660 ok(info
.AllocationProtect
== PAGE_READONLY
, "%d: %#x != PAGE_READONLY\n", i
, info
.AllocationProtect
);
2661 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
2662 ok(info
.Type
== MEM_MAPPED
, "%d: %#x != MEM_MAPPED\n", i
, info
.Type
);
2664 if (is_mem_writable(info
.Protect
))
2668 SetLastError(0xdeadbeef);
2669 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2670 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
2671 ok(info
.Protect
== td
[i
].prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot
);
2674 SetLastError(0xdeadbeef);
2675 ptr
= VirtualAlloc(base
, si
.dwPageSize
, MEM_COMMIT
, td
[i
].prot
);
2676 ok(!ptr
, "%d: VirtualAlloc(%02x) should fail\n", i
, td
[i
].prot
);
2677 /* FIXME: remove once Wine is fixed */
2678 if (td
[i
].prot
== PAGE_WRITECOPY
|| td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
2680 ok(GetLastError() == ERROR_ACCESS_DENIED
, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i
, GetLastError());
2682 ok(GetLastError() == ERROR_ACCESS_DENIED
, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i
, GetLastError());
2684 SetLastError(0xdeadbeef);
2685 ret
= VirtualProtect(base
, si
.dwPageSize
, td
[i
].prot
, &old_prot
);
2686 if (td
[i
].prot
== PAGE_READONLY
|| td
[i
].prot
== PAGE_WRITECOPY
)
2687 ok(ret
, "%d: VirtualProtect(%02x) error %d\n", i
, td
[i
].prot
, GetLastError());
2690 ok(!ret
, "%d: VirtualProtect(%02x) should fail\n", i
, td
[i
].prot
);
2691 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
2694 UnmapViewOfFile(base
);
2699 ok(!hmap
, "%d: CreateFileMapping should fail\n", i
);
2700 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
2704 if (page_exec_supported
) alloc_prot
= PAGE_EXECUTE_READWRITE
;
2705 else alloc_prot
= PAGE_READWRITE
;
2706 SetLastError(0xdeadbeef);
2707 hmap
= CreateFileMappingW(hfile
, NULL
, alloc_prot
, 0, si
.dwPageSize
, NULL
);
2708 ok(hmap
!= 0, "%d: CreateFileMapping error %d\n", i
, GetLastError());
2710 SetLastError(0xdeadbeef);
2711 base
= MapViewOfFile(hmap
, FILE_MAP_READ
| FILE_MAP_WRITE
| (page_exec_supported
? FILE_MAP_EXECUTE
: 0), 0, 0, 0);
2712 ok(base
!= NULL
, "MapViewOfFile failed %d\n", GetLastError());
2714 old_prot
= 0xdeadbeef;
2715 SetLastError(0xdeadbeef);
2716 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
2717 ok(ret
, "VirtualProtect error %d\n", GetLastError());
2718 ok(old_prot
== alloc_prot
, "got %#x != expected %#x\n", old_prot
, alloc_prot
);
2720 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
2722 SetLastError(0xdeadbeef);
2723 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2724 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
2725 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
2726 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
2727 ok(info
.Protect
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, info
.Protect
);
2728 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
2729 ok(info
.AllocationProtect
== alloc_prot
, "%d: %#x != %#x\n", i
, info
.AllocationProtect
, alloc_prot
);
2730 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
2731 ok(info
.Type
== MEM_MAPPED
, "%d: %#x != MEM_MAPPED\n", i
, info
.Type
);
2733 old_prot
= 0xdeadbeef;
2734 SetLastError(0xdeadbeef);
2735 ret
= VirtualProtect(base
, si
.dwPageSize
, td
[i
].prot
, &old_prot
);
2736 if (td
[i
].success
|| td
[i
].prot
== PAGE_NOACCESS
|| td
[i
].prot
== PAGE_EXECUTE
)
2740 /* win2k and XP don't support EXEC on file mappings */
2741 if (td
[i
].prot
== PAGE_EXECUTE
)
2743 ok(broken(!ret
), "%d: VirtualProtect doesn't support PAGE_EXECUTE\n", i
);
2746 /* NT4 and win2k don't support EXEC on file mappings */
2747 if (td
[i
].prot
== PAGE_EXECUTE_READ
|| td
[i
].prot
== PAGE_EXECUTE_READWRITE
)
2749 ok(broken(!ret
), "%d: VirtualProtect doesn't support PAGE_EXECUTE\n", i
);
2752 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
2753 if (td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
2755 ok(broken(!ret
), "%d: VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY\n", i
);
2760 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
2761 ok(old_prot
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, old_prot
);
2764 /* looks strange but Windows doesn't do this for PAGE_WRITECOPY */
2765 if (prot
== PAGE_EXECUTE_WRITECOPY
) prot
= PAGE_EXECUTE_READWRITE
;
2767 SetLastError(0xdeadbeef);
2768 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2769 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
2770 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
2771 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
2772 /* FIXME: remove the condition below once Wine is fixed */
2773 if (td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
2774 todo_wine
ok(info
.Protect
== prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, prot
);
2776 ok(info
.Protect
== prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, prot
);
2777 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
2778 ok(info
.AllocationProtect
== alloc_prot
, "%d: %#x != %#x\n", i
, info
.AllocationProtect
, alloc_prot
);
2779 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
2780 ok(info
.Type
== MEM_MAPPED
, "%d: %#x != MEM_MAPPED\n", i
, info
.Type
);
2782 if (is_mem_writable(info
.Protect
))
2786 SetLastError(0xdeadbeef);
2787 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2788 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
2789 /* FIXME: remove the condition below once Wine is fixed */
2790 if (td
[i
].prot
== PAGE_WRITECOPY
|| td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
2791 todo_wine
ok(info
.Protect
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot_after_write
);
2793 ok(info
.Protect
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot_after_write
);
2798 ok(!ret
, "%d: VirtualProtect should fail\n", i
);
2799 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
2803 old_prot
= 0xdeadbeef;
2804 SetLastError(0xdeadbeef);
2805 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
2806 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
2807 /* FIXME: remove the condition below once Wine is fixed */
2808 if (td
[i
].prot
== PAGE_WRITECOPY
|| td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
2809 todo_wine
ok(old_prot
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, old_prot
, td
[i
].prot_after_write
);
2811 ok(old_prot
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, old_prot
, td
[i
].prot_after_write
);
2814 UnmapViewOfFile(base
);
2818 DeleteFileA(file_name
);
2821 #define ACCESS_READ 0x01
2822 #define ACCESS_WRITE 0x02
2823 #define ACCESS_EXECUTE 0x04
2824 #define ACCESS_WRITECOPY 0x08
2826 static DWORD
page_prot_to_access(DWORD prot
)
2830 case PAGE_READWRITE
:
2831 return ACCESS_READ
| ACCESS_WRITE
;
2834 case PAGE_EXECUTE_READ
:
2835 return ACCESS_READ
| ACCESS_EXECUTE
;
2837 case PAGE_EXECUTE_READWRITE
:
2838 return ACCESS_READ
| ACCESS_WRITE
| ACCESS_WRITECOPY
| ACCESS_EXECUTE
;
2840 case PAGE_EXECUTE_WRITECOPY
:
2841 return ACCESS_READ
| ACCESS_WRITECOPY
| ACCESS_EXECUTE
;
2846 case PAGE_WRITECOPY
:
2854 static BOOL
is_compatible_protection(DWORD map_prot
, DWORD view_prot
, DWORD prot
)
2856 DWORD map_access
, view_access
, prot_access
;
2858 map_access
= page_prot_to_access(map_prot
);
2859 view_access
= page_prot_to_access(view_prot
);
2860 prot_access
= page_prot_to_access(prot
);
2862 if (view_access
== prot_access
) return TRUE
;
2863 if (!view_access
) return FALSE
;
2865 if ((view_access
& prot_access
) != prot_access
) return FALSE
;
2866 if ((map_access
& prot_access
) == prot_access
) return TRUE
;
2871 static DWORD
map_prot_to_access(DWORD prot
)
2875 case PAGE_READWRITE
:
2876 case PAGE_EXECUTE_READWRITE
:
2877 return SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
| SECTION_MAP_EXECUTE_EXPLICIT
| SECTION_QUERY
;
2879 case PAGE_WRITECOPY
:
2881 case PAGE_EXECUTE_READ
:
2882 case PAGE_EXECUTE_WRITECOPY
:
2883 return SECTION_MAP_READ
| SECTION_MAP_EXECUTE
| SECTION_MAP_EXECUTE_EXPLICIT
| SECTION_QUERY
;
2889 static BOOL
is_compatible_access(DWORD map_prot
, DWORD view_prot
)
2891 DWORD access
= map_prot_to_access(map_prot
);
2892 if (!view_prot
) view_prot
= SECTION_MAP_READ
;
2893 return (view_prot
& access
) == view_prot
;
2896 static void *map_view_of_file(HANDLE handle
, DWORD access
)
2899 LARGE_INTEGER offset
;
2905 if (!pNtMapViewOfSection
) return NULL
;
2908 offset
.u
.LowPart
= 0;
2909 offset
.u
.HighPart
= 0;
2911 exec
= access
& FILE_MAP_EXECUTE
;
2912 access
&= ~FILE_MAP_EXECUTE
;
2914 if (access
== FILE_MAP_COPY
)
2917 protect
= PAGE_EXECUTE_WRITECOPY
;
2919 protect
= PAGE_WRITECOPY
;
2921 else if (access
& FILE_MAP_WRITE
)
2924 protect
= PAGE_EXECUTE_READWRITE
;
2926 protect
= PAGE_READWRITE
;
2928 else if (access
& FILE_MAP_READ
)
2931 protect
= PAGE_EXECUTE_READ
;
2933 protect
= PAGE_READONLY
;
2935 else protect
= PAGE_NOACCESS
;
2938 status
= pNtMapViewOfSection(handle
, GetCurrentProcess(), &addr
, 0, 0, &offset
,
2939 &count
, 1 /* ViewShare */, 0, protect
);
2942 /* for simplicity */
2943 SetLastError(ERROR_ACCESS_DENIED
);
2949 static void test_mapping(void)
2951 static const DWORD page_prot
[] =
2953 PAGE_NOACCESS
, PAGE_READONLY
, PAGE_READWRITE
, PAGE_WRITECOPY
,
2954 PAGE_EXECUTE_READ
, PAGE_EXECUTE_READWRITE
, PAGE_EXECUTE_WRITECOPY
2961 { 0, PAGE_NOACCESS
}, /* 0x00 */
2962 { FILE_MAP_COPY
, PAGE_WRITECOPY
}, /* 0x01 */
2963 { FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x02 */
2964 { FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x03 */
2965 { FILE_MAP_READ
, PAGE_READONLY
}, /* 0x04 */
2966 { FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_READONLY
}, /* 0x05 */
2967 { FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x06 */
2968 { FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x07 */
2969 { SECTION_MAP_EXECUTE
, PAGE_NOACCESS
}, /* 0x08 */
2970 { SECTION_MAP_EXECUTE
| FILE_MAP_COPY
, PAGE_NOACCESS
}, /* 0x09 */
2971 { SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x0a */
2972 { SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x0b */
2973 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
, PAGE_READONLY
}, /* 0x0c */
2974 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_READONLY
}, /* 0x0d */
2975 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x0e */
2976 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x0f */
2977 { FILE_MAP_EXECUTE
, PAGE_NOACCESS
}, /* 0x20 */
2978 { FILE_MAP_EXECUTE
| FILE_MAP_COPY
, PAGE_EXECUTE_WRITECOPY
}, /* 0x21 */
2979 { FILE_MAP_EXECUTE
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x22 */
2980 { FILE_MAP_EXECUTE
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
}, /* 0x23 */
2981 { FILE_MAP_EXECUTE
| FILE_MAP_READ
, PAGE_EXECUTE_READ
}, /* 0x24 */
2982 { FILE_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_EXECUTE_READ
}, /* 0x25 */
2983 { FILE_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x26 */
2984 { FILE_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
}, /* 0x27 */
2985 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
, PAGE_NOACCESS
}, /* 0x28 */
2986 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_COPY
, PAGE_NOACCESS
}, /* 0x29 */
2987 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x2a */
2988 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
}, /* 0x2b */
2989 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
, PAGE_EXECUTE_READ
}, /* 0x2c */
2990 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_EXECUTE_READ
}, /* 0x2d */
2991 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x2e */
2992 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
} /* 0x2f */
2994 void *base
, *nt_base
, *ptr
;
2995 DWORD i
, j
, k
, ret
, old_prot
, prev_prot
;
2997 char temp_path
[MAX_PATH
];
2998 char file_name
[MAX_PATH
];
3000 MEMORY_BASIC_INFORMATION info
, nt_info
;
3003 trace("system page size %#x\n", si
.dwPageSize
);
3005 GetTempPathA(MAX_PATH
, temp_path
);
3006 GetTempFileNameA(temp_path
, "map", 0, file_name
);
3008 SetLastError(0xdeadbeef);
3009 hfile
= CreateFileA(file_name
, GENERIC_READ
|GENERIC_WRITE
|GENERIC_EXECUTE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3010 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile(%s) error %d\n", file_name
, GetLastError());
3011 SetFilePointer(hfile
, si
.dwPageSize
, NULL
, FILE_BEGIN
);
3012 SetEndOfFile(hfile
);
3014 for (i
= 0; i
< sizeof(page_prot
)/sizeof(page_prot
[0]); i
++)
3016 SetLastError(0xdeadbeef);
3017 hmap
= CreateFileMappingW(hfile
, NULL
, page_prot
[i
] | SEC_COMMIT
, 0, si
.dwPageSize
, NULL
);
3019 if (page_prot
[i
] == PAGE_NOACCESS
)
3023 ok(!hmap
, "CreateFileMapping(PAGE_NOACCESS) should fail\n");
3024 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3026 /* A trick to create a not accessible mapping */
3027 SetLastError(0xdeadbeef);
3028 hmap
= CreateFileMappingW(hfile
, NULL
, PAGE_READWRITE
| SEC_COMMIT
, 0, si
.dwPageSize
, NULL
);
3029 ok(hmap
!= 0, "CreateFileMapping(PAGE_READWRITE) error %d\n", GetLastError());
3030 SetLastError(0xdeadbeef);
3031 ret
= DuplicateHandle(GetCurrentProcess(), hmap
, GetCurrentProcess(), &hmap2
, 0, FALSE
, 0);
3032 ok(ret
, "DuplicateHandle error %d\n", GetLastError());
3039 trace("%d: CreateFileMapping(%04x) failed: %d\n", i
, page_prot
[i
], GetLastError());
3041 /* NT4 and win2k don't support EXEC on file mappings */
3042 if (page_prot
[i
] == PAGE_EXECUTE_READ
|| page_prot
[i
] == PAGE_EXECUTE_READWRITE
)
3044 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE\n", i
);
3047 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
3048 if (page_prot
[i
] == PAGE_EXECUTE_WRITECOPY
)
3050 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE_WRITECOPY\n", i
);
3055 ok(hmap
!= 0, "%d: CreateFileMapping(%04x) error %d\n", i
, page_prot
[i
], GetLastError());
3057 for (j
= 0; j
< sizeof(view
)/sizeof(view
[0]); j
++)
3059 nt_base
= map_view_of_file(hmap
, view
[j
].access
);
3062 SetLastError(0xdeadbeef);
3063 ret
= VirtualQuery(nt_base
, &nt_info
, sizeof(nt_info
));
3064 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
3065 UnmapViewOfFile(nt_base
);
3068 SetLastError(0xdeadbeef);
3069 base
= MapViewOfFile(hmap
, view
[j
].access
, 0, 0, 0);
3071 /* Vista+ supports FILE_MAP_EXECUTE properly, earlier versions don't */
3072 ok(!nt_base
== !base
||
3073 broken((view
[j
].access
& FILE_MAP_EXECUTE
) && !nt_base
!= !base
),
3074 "%d: (%04x/%04x) NT %p kernel %p\n", j
, page_prot
[i
], view
[j
].access
, nt_base
, base
);
3076 if (!is_compatible_access(page_prot
[i
], view
[j
].access
))
3078 ok(!base
, "%d: MapViewOfFile(%04x/%04x) should fail\n", j
, page_prot
[i
], view
[j
].access
);
3079 ok(GetLastError() == ERROR_ACCESS_DENIED
, "wrong error %d\n", GetLastError());
3083 /* Vista+ properly supports FILE_MAP_EXECUTE, earlier versions don't */
3084 if (!base
&& (view
[j
].access
& FILE_MAP_EXECUTE
))
3086 ok(broken(!base
), "%d: MapViewOfFile(%04x/%04x) failed %d\n", j
, page_prot
[i
], view
[j
].access
, GetLastError());
3090 ok(base
!= NULL
, "%d: MapViewOfFile(%04x/%04x) failed %d\n", j
, page_prot
[i
], view
[j
].access
, GetLastError());
3092 SetLastError(0xdeadbeef);
3093 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3094 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
3095 ok(info
.BaseAddress
== base
, "%d: (%04x) got %p, expected %p\n", j
, view
[j
].access
, info
.BaseAddress
, base
);
3096 ok(info
.RegionSize
== si
.dwPageSize
, "%d: (%04x) got %#lx != expected %#x\n", j
, view
[j
].access
, info
.RegionSize
, si
.dwPageSize
);
3097 ok(info
.Protect
== view
[j
].prot
||
3098 broken(view
[j
].prot
== PAGE_EXECUTE_READ
&& info
.Protect
== PAGE_READONLY
) || /* win2k */
3099 broken(view
[j
].prot
== PAGE_EXECUTE_READWRITE
&& info
.Protect
== PAGE_READWRITE
) || /* win2k */
3100 broken(view
[j
].prot
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
3101 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, info
.Protect
, view
[j
].prot
);
3102 ok(info
.AllocationBase
== base
, "%d: (%04x) got %p, expected %p\n", j
, view
[j
].access
, info
.AllocationBase
, base
);
3103 ok(info
.AllocationProtect
== info
.Protect
, "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, info
.AllocationProtect
, info
.Protect
);
3104 ok(info
.State
== MEM_COMMIT
, "%d: (%04x) got %#x, expected MEM_COMMIT\n", j
, view
[j
].access
, info
.State
);
3105 ok(info
.Type
== MEM_MAPPED
, "%d: (%04x) got %#x, expected MEM_MAPPED\n", j
, view
[j
].access
, info
.Type
);
3107 if (nt_base
&& base
)
3109 ok(nt_info
.RegionSize
== info
.RegionSize
, "%d: (%04x) got %#lx != expected %#lx\n", j
, view
[j
].access
, nt_info
.RegionSize
, info
.RegionSize
);
3110 ok(nt_info
.Protect
== info
.Protect
/* Vista+ */ ||
3111 broken(nt_info
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
3112 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.Protect
, info
.Protect
);
3113 ok(nt_info
.AllocationProtect
== info
.AllocationProtect
/* Vista+ */ ||
3114 broken(nt_info
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
3115 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.AllocationProtect
, info
.AllocationProtect
);
3116 ok(nt_info
.State
== info
.State
, "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.State
, info
.State
);
3117 ok(nt_info
.Type
== info
.Type
, "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.Type
, info
.Type
);
3120 prev_prot
= info
.Protect
;
3122 for (k
= 0; k
< sizeof(page_prot
)/sizeof(page_prot
[0]); k
++)
3124 /*trace("map %#x, view %#x, requested prot %#x\n", page_prot[i], view[j].prot, page_prot[k]);*/
3125 SetLastError(0xdeadbeef);
3126 old_prot
= 0xdeadbeef;
3127 ret
= VirtualProtect(base
, si
.dwPageSize
, page_prot
[k
], &old_prot
);
3128 if (is_compatible_protection(page_prot
[i
], view
[j
].prot
, page_prot
[k
]))
3130 /* win2k and XP don't support EXEC on file mappings */
3131 if (!ret
&& page_prot
[k
] == PAGE_EXECUTE
)
3133 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE\n");
3136 /* NT4 and win2k don't support EXEC on file mappings */
3137 if (!ret
&& (page_prot
[k
] == PAGE_EXECUTE_READ
|| page_prot
[k
] == PAGE_EXECUTE_READWRITE
))
3139 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE\n");
3142 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
3143 if (!ret
&& page_prot
[k
] == PAGE_EXECUTE_WRITECOPY
)
3145 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY\n");
3148 /* win2k and XP don't support PAGE_EXECUTE_WRITECOPY views properly */
3149 if (!ret
&& view
[j
].prot
== PAGE_EXECUTE_WRITECOPY
)
3151 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY view properly\n");
3155 ok(ret
, "VirtualProtect error %d, map %#x, view %#x, requested prot %#x\n", GetLastError(), page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
3156 ok(old_prot
== prev_prot
, "got %#x, expected %#x\n", old_prot
, prev_prot
);
3157 prev_prot
= page_prot
[k
];
3161 /* NT4 doesn't fail on incompatible map and view */
3164 ok(broken(ret
), "VirtualProtect should fail, map %#x, view %#x, requested prot %#x\n", page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
3165 skip("Incompatible map and view are not properly handled on this platform\n");
3166 break; /* NT4 won't pass remaining tests */
3169 ok(!ret
, "VirtualProtect should fail, map %#x, view %#x, requested prot %#x\n", page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
3170 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3174 for (k
= 0; k
< sizeof(page_prot
)/sizeof(page_prot
[0]); k
++)
3176 /*trace("map %#x, view %#x, requested prot %#x\n", page_prot[i], view[j].prot, page_prot[k]);*/
3177 SetLastError(0xdeadbeef);
3178 ptr
= VirtualAlloc(base
, si
.dwPageSize
, MEM_COMMIT
, page_prot
[k
]);
3179 ok(!ptr
, "VirtualAlloc(%02x) should fail\n", page_prot
[k
]);
3180 /* FIXME: remove once Wine is fixed */
3181 if (page_prot
[k
] == PAGE_WRITECOPY
|| page_prot
[k
] == PAGE_EXECUTE_WRITECOPY
)
3183 ok(GetLastError() == ERROR_ACCESS_DENIED
, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3185 ok(GetLastError() == ERROR_ACCESS_DENIED
, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3188 UnmapViewOfFile(base
);
3195 DeleteFileA(file_name
);
3198 static void test_shared_memory(BOOL is_child
)
3203 SetLastError(0xdeadbef);
3204 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4096, "winetest_virtual.c");
3205 ok(mapping
!= 0, "CreateFileMapping error %d\n", GetLastError());
3207 ok(GetLastError() == ERROR_ALREADY_EXISTS
, "expected ERROR_ALREADY_EXISTS, got %d\n", GetLastError());
3209 SetLastError(0xdeadbef);
3210 p
= MapViewOfFile(mapping
, FILE_MAP_READ
|FILE_MAP_WRITE
, 0, 0, 4096);
3211 ok(p
!= NULL
, "MapViewOfFile error %d\n", GetLastError());
3215 ok(*p
== 0x1a2b3c4d, "expected 0x1a2b3c4d in child, got %#x\n", *p
);
3220 char cmdline
[MAX_PATH
];
3221 PROCESS_INFORMATION pi
;
3222 STARTUPINFOA si
= { sizeof(si
) };
3227 winetest_get_mainargs(&argv
);
3228 sprintf(cmdline
, "\"%s\" virtual sharedmem", argv
[0]);
3229 ret
= CreateProcessA(argv
[0], cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
3230 ok(ret
, "CreateProcess(%s) error %d\n", cmdline
, GetLastError());
3231 winetest_wait_child_process(pi
.hProcess
);
3232 CloseHandle(pi
.hThread
);
3233 CloseHandle(pi
.hProcess
);
3237 CloseHandle(mapping
);
3240 static void test_shared_memory_ro(BOOL is_child
, DWORD child_access
)
3245 SetLastError(0xdeadbef);
3246 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4096, "winetest_virtual.c_ro");
3247 ok(mapping
!= 0, "CreateFileMapping error %d\n", GetLastError());
3249 ok(GetLastError() == ERROR_ALREADY_EXISTS
, "expected ERROR_ALREADY_EXISTS, got %d\n", GetLastError());
3251 SetLastError(0xdeadbef);
3252 p
= MapViewOfFile(mapping
, is_child
? child_access
: FILE_MAP_READ
, 0, 0, 4096);
3253 ok(p
!= NULL
, "MapViewOfFile error %d\n", GetLastError());
3262 char cmdline
[MAX_PATH
];
3263 PROCESS_INFORMATION pi
;
3264 STARTUPINFOA si
= { sizeof(si
) };
3267 winetest_get_mainargs(&argv
);
3268 sprintf(cmdline
, "\"%s\" virtual sharedmemro %x", argv
[0], child_access
);
3269 ret
= CreateProcessA(argv
[0], cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
3270 ok(ret
, "CreateProcess(%s) error %d\n", cmdline
, GetLastError());
3271 winetest_wait_child_process(pi
.hProcess
);
3272 CloseHandle(pi
.hThread
);
3273 CloseHandle(pi
.hProcess
);
3275 if(child_access
& FILE_MAP_WRITE
)
3276 ok(*p
== 0xdeadbeef, "*p = %x, expected 0xdeadbeef\n", *p
);
3278 ok(!*p
, "*p = %x, expected 0\n", *p
);
3282 CloseHandle(mapping
);
3289 argc
= winetest_get_mainargs( &argv
);
3293 if (!strcmp(argv
[2], "sleep"))
3295 Sleep(5000); /* spawned process runs for at most 5 seconds */
3298 if (!strcmp(argv
[2], "sharedmem"))
3300 test_shared_memory(TRUE
);
3303 if (!strcmp(argv
[2], "sharedmemro"))
3305 test_shared_memory_ro(TRUE
, strtol(argv
[3], NULL
, 16));
3312 mem
= VirtualAlloc(NULL
, 1<<20, MEM_COMMIT
|MEM_RESERVE
,
3313 PAGE_EXECUTE_READWRITE
);
3314 ok(mem
!= NULL
, "VirtualAlloc failed %u\n", GetLastError());
3315 if (mem
== NULL
) break;
3316 ret
= VirtualFree(mem
, 0, MEM_RELEASE
);
3317 ok(ret
, "VirtualFree failed %u\n", GetLastError());
3323 hkernel32
= GetModuleHandleA("kernel32.dll");
3324 hntdll
= GetModuleHandleA("ntdll.dll");
3326 pVirtualAllocEx
= (void *) GetProcAddress(hkernel32
, "VirtualAllocEx");
3327 pVirtualFreeEx
= (void *) GetProcAddress(hkernel32
, "VirtualFreeEx");
3328 pGetWriteWatch
= (void *) GetProcAddress(hkernel32
, "GetWriteWatch");
3329 pResetWriteWatch
= (void *) GetProcAddress(hkernel32
, "ResetWriteWatch");
3330 pNtAreMappedFilesTheSame
= (void *)GetProcAddress( hntdll
, "NtAreMappedFilesTheSame" );
3331 pNtMapViewOfSection
= (void *)GetProcAddress( hntdll
, "NtMapViewOfSection" );
3332 pNtUnmapViewOfSection
= (void *)GetProcAddress( hntdll
, "NtUnmapViewOfSection" );
3333 pNtCurrentTeb
= (void *)GetProcAddress( hntdll
, "NtCurrentTeb" );
3334 pRtlAddVectoredExceptionHandler
= (void *)GetProcAddress( hntdll
, "RtlAddVectoredExceptionHandler" );
3335 pRtlRemoveVectoredExceptionHandler
= (void *)GetProcAddress( hntdll
, "RtlRemoveVectoredExceptionHandler" );
3337 test_shared_memory(FALSE
);
3338 test_shared_memory_ro(FALSE
, FILE_MAP_READ
|FILE_MAP_WRITE
);
3339 test_shared_memory_ro(FALSE
, FILE_MAP_COPY
);
3340 test_shared_memory_ro(FALSE
, FILE_MAP_COPY
|FILE_MAP_WRITE
);
3342 test_CreateFileMapping_protection();
3343 test_VirtualAlloc_protection();
3344 test_VirtualProtect();
3345 test_VirtualAllocEx();
3346 test_VirtualAlloc();
3347 test_MapViewOfFile();
3348 test_NtMapViewOfSection();
3349 test_NtAreMappedFilesTheSame();
3350 test_CreateFileMapping();
3351 test_IsBadReadPtr();
3352 test_IsBadWritePtr();
3353 test_IsBadCodePtr();
3357 /* The following tests should be executed as a last step, and in exactly this
3358 * order, since ATL thunk emulation cannot be enabled anymore on Windows. */
3359 test_atl_thunk_emulation( MEM_EXECUTE_OPTION_ENABLE
);
3360 test_atl_thunk_emulation( MEM_EXECUTE_OPTION_DISABLE
);
3361 test_atl_thunk_emulation( MEM_EXECUTE_OPTION_DISABLE
| MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
);