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 SYSTEM_INFO si
;
40 static UINT (WINAPI
*pGetWriteWatch
)(DWORD
,LPVOID
,SIZE_T
,LPVOID
*,ULONG_PTR
*,ULONG
*);
41 static UINT (WINAPI
*pResetWriteWatch
)(LPVOID
,SIZE_T
);
42 static NTSTATUS (WINAPI
*pNtAreMappedFilesTheSame
)(PVOID
,PVOID
);
43 static NTSTATUS (WINAPI
*pNtCreateSection
)(HANDLE
*, ACCESS_MASK
, const OBJECT_ATTRIBUTES
*,
44 const LARGE_INTEGER
*, ULONG
, ULONG
, HANDLE
);
45 static NTSTATUS (WINAPI
*pNtMapViewOfSection
)(HANDLE
, HANDLE
, PVOID
*, ULONG_PTR
, SIZE_T
, const LARGE_INTEGER
*, SIZE_T
*, ULONG
, ULONG
, ULONG
);
46 static DWORD (WINAPI
*pNtUnmapViewOfSection
)(HANDLE
, PVOID
);
47 static NTSTATUS (WINAPI
*pNtQuerySection
)(HANDLE
, SECTION_INFORMATION_CLASS
, void *, SIZE_T
, SIZE_T
*);
48 static PVOID (WINAPI
*pRtlAddVectoredExceptionHandler
)(ULONG
, PVECTORED_EXCEPTION_HANDLER
);
49 static ULONG (WINAPI
*pRtlRemoveVectoredExceptionHandler
)(PVOID
);
50 static BOOL (WINAPI
*pGetProcessDEPPolicy
)(HANDLE
, LPDWORD
, PBOOL
);
51 static BOOL (WINAPI
*pIsWow64Process
)(HANDLE
, PBOOL
);
52 static NTSTATUS (WINAPI
*pNtProtectVirtualMemory
)(HANDLE
, PVOID
*, SIZE_T
*, ULONG
, ULONG
*);
54 /* ############################### */
56 static HANDLE
create_target_process(const char *arg
)
59 char cmdline
[MAX_PATH
];
60 PROCESS_INFORMATION pi
;
62 STARTUPINFOA si
= { 0 };
65 winetest_get_mainargs( &argv
);
66 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], arg
);
67 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
68 ok(ret
, "error: %u\n", GetLastError());
69 ret
= CloseHandle(pi
.hThread
);
70 ok(ret
, "error %u\n", GetLastError());
74 static void test_VirtualAllocEx(void)
76 const unsigned int alloc_size
= 1<<15;
78 SIZE_T bytes_written
= 0, bytes_read
= 0, i
;
82 MEMORY_BASIC_INFORMATION info
;
85 hProcess
= create_target_process("sleep");
86 ok(hProcess
!= NULL
, "Can't start process\n");
88 SetLastError(0xdeadbeef);
89 addr1
= VirtualAllocEx(hProcess
, NULL
, alloc_size
, MEM_COMMIT
,
90 PAGE_EXECUTE_READWRITE
);
91 ok(addr1
!= NULL
, "VirtualAllocEx error %u\n", GetLastError());
93 src
= VirtualAlloc( NULL
, alloc_size
, MEM_COMMIT
, PAGE_READWRITE
);
94 dst
= VirtualAlloc( NULL
, alloc_size
, MEM_COMMIT
, PAGE_READWRITE
);
95 for (i
= 0; i
< alloc_size
; i
++)
98 b
= WriteProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_written
);
99 ok(b
&& (bytes_written
== alloc_size
), "%lu bytes written\n",
101 b
= ReadProcessMemory(hProcess
, addr1
, dst
, alloc_size
, &bytes_read
);
102 ok(b
&& (bytes_read
== alloc_size
), "%lu bytes read\n", bytes_read
);
103 ok(!memcmp(src
, dst
, alloc_size
), "Data from remote process differs\n");
105 /* test invalid source buffers */
107 b
= VirtualProtect( src
+ 0x2000, 0x2000, PAGE_NOACCESS
, &old_prot
);
108 ok( b
, "VirtualProtect failed error %u\n", GetLastError() );
109 b
= WriteProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_written
);
110 ok( !b
, "WriteProcessMemory succeeded\n" );
111 ok( GetLastError() == ERROR_NOACCESS
||
112 GetLastError() == ERROR_PARTIAL_COPY
, /* vista */
113 "wrong error %u\n", GetLastError() );
114 ok( bytes_written
== 0, "%lu bytes written\n", bytes_written
);
115 b
= ReadProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_read
);
116 ok( !b
, "ReadProcessMemory succeeded\n" );
117 ok( GetLastError() == ERROR_NOACCESS
||
118 GetLastError() == ERROR_PARTIAL_COPY
, /* win10 v1607+ */
119 "wrong error %u\n", GetLastError() );
120 if (GetLastError() == ERROR_NOACCESS
)
121 ok( bytes_read
== 0, "%lu bytes written\n", bytes_read
);
123 b
= VirtualProtect( src
, 0x2000, PAGE_NOACCESS
, &old_prot
);
124 ok( b
, "VirtualProtect failed error %u\n", GetLastError() );
125 b
= WriteProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_written
);
126 ok( !b
, "WriteProcessMemory succeeded\n" );
127 ok( GetLastError() == ERROR_NOACCESS
||
128 GetLastError() == ERROR_PARTIAL_COPY
, /* vista */
129 "wrong error %u\n", GetLastError() );
130 ok( bytes_written
== 0, "%lu bytes written\n", bytes_written
);
131 b
= ReadProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_read
);
132 ok( !b
, "ReadProcessMemory succeeded\n" );
133 ok( GetLastError() == ERROR_NOACCESS
||
134 GetLastError() == ERROR_PARTIAL_COPY
, /* win10 v1607+ */
135 "wrong error %u\n", GetLastError() );
136 if (GetLastError() == ERROR_NOACCESS
)
137 ok( bytes_read
== 0, "%lu bytes written\n", bytes_read
);
139 b
= VirtualFreeEx(hProcess
, addr1
, 0, MEM_RELEASE
);
140 ok(b
!= 0, "VirtualFreeEx, error %u\n", GetLastError());
142 VirtualFree( src
, 0, MEM_RELEASE
);
143 VirtualFree( dst
, 0, MEM_RELEASE
);
146 * The following tests parallel those in test_VirtualAlloc()
149 SetLastError(0xdeadbeef);
150 addr1
= VirtualAllocEx(hProcess
, 0, 0, MEM_RESERVE
, PAGE_NOACCESS
);
151 ok(addr1
== NULL
, "VirtualAllocEx should fail on zero-sized allocation\n");
152 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
153 "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
155 addr1
= VirtualAllocEx(hProcess
, 0, 0xFFFC, MEM_RESERVE
, PAGE_NOACCESS
);
156 ok(addr1
!= NULL
, "VirtualAllocEx failed\n");
158 /* test a not committed memory */
159 memset(&info
, 'q', sizeof(info
));
160 ok(VirtualQueryEx(hProcess
, addr1
, &info
, sizeof(info
)) == sizeof(info
), "VirtualQueryEx failed\n");
161 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
162 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
163 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
164 ok(info
.RegionSize
== 0x10000, "%lx != 0x10000\n", info
.RegionSize
);
165 ok(info
.State
== MEM_RESERVE
, "%x != MEM_RESERVE\n", info
.State
);
166 ok(info
.Protect
== 0, "%x != PAGE_NOACCESS\n", info
.Protect
);
167 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
169 SetLastError(0xdeadbeef);
170 ok(!VirtualProtectEx(hProcess
, addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
171 "VirtualProtectEx should fail on a not committed memory\n");
172 ok(GetLastError() == ERROR_INVALID_ADDRESS
,
173 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
175 addr2
= VirtualAllocEx(hProcess
, addr1
, 0x1000, MEM_COMMIT
, PAGE_NOACCESS
);
176 ok(addr1
== addr2
, "VirtualAllocEx failed\n");
178 /* test a committed memory */
179 ok(VirtualQueryEx(hProcess
, addr1
, &info
, sizeof(info
)) == sizeof(info
),
180 "VirtualQueryEx failed\n");
181 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
182 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
183 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
184 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
185 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
186 /* this time NT reports PAGE_NOACCESS as well */
187 ok(info
.Protect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.Protect
);
188 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
190 /* this should fail, since not the whole range is committed yet */
191 SetLastError(0xdeadbeef);
192 ok(!VirtualProtectEx(hProcess
, addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
193 "VirtualProtectEx should fail on a not committed memory\n");
194 ok(GetLastError() == ERROR_INVALID_ADDRESS
,
195 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
198 ok(VirtualProtectEx(hProcess
, addr1
, 0x1000, PAGE_READONLY
, &old_prot
), "VirtualProtectEx failed\n");
199 ok(old_prot
== PAGE_NOACCESS
, "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot
);
202 ok(VirtualProtectEx(hProcess
, addr1
, 0x1000, PAGE_READWRITE
, &old_prot
), "VirtualProtectEx failed\n");
203 ok(old_prot
== PAGE_READONLY
, "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot
);
205 ok(!VirtualFreeEx(hProcess
, addr1
, 0x10000, 0),
206 "VirtualFreeEx should fail with type 0\n");
207 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
208 "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
210 ok(VirtualFreeEx(hProcess
, addr1
, 0x10000, MEM_DECOMMIT
), "VirtualFreeEx failed\n");
212 /* if the type is MEM_RELEASE, size must be 0 */
213 ok(!VirtualFreeEx(hProcess
, addr1
, 1, MEM_RELEASE
),
214 "VirtualFreeEx should fail\n");
215 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
216 "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
218 ok(VirtualFreeEx(hProcess
, addr1
, 0, MEM_RELEASE
), "VirtualFreeEx failed\n");
220 TerminateProcess(hProcess
, 0);
221 CloseHandle(hProcess
);
224 static void test_VirtualAlloc(void)
228 MEMORY_BASIC_INFORMATION info
;
230 SetLastError(0xdeadbeef);
231 addr1
= VirtualAlloc(0, 0, MEM_RESERVE
, PAGE_NOACCESS
);
232 ok(addr1
== NULL
, "VirtualAlloc should fail on zero-sized allocation\n");
233 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
234 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
236 addr1
= VirtualAlloc(0, 0xFFFC, MEM_RESERVE
, PAGE_NOACCESS
);
237 ok(addr1
!= NULL
, "VirtualAlloc failed\n");
239 /* test a not committed memory */
240 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
241 "VirtualQuery failed\n");
242 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
243 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
244 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
245 ok(info
.RegionSize
== 0x10000, "%lx != 0x10000\n", info
.RegionSize
);
246 ok(info
.State
== MEM_RESERVE
, "%x != MEM_RESERVE\n", info
.State
);
247 ok(info
.Protect
== 0, "%x != PAGE_NOACCESS\n", info
.Protect
);
248 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
250 SetLastError(0xdeadbeef);
251 ok(!VirtualProtect(addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
252 "VirtualProtect should fail on a not committed memory\n");
253 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
254 "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
256 addr2
= VirtualAlloc(addr1
, 0x1000, MEM_COMMIT
, PAGE_NOACCESS
);
257 ok(addr1
== addr2
, "VirtualAlloc failed\n");
259 /* test a committed memory */
260 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
261 "VirtualQuery failed\n");
262 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
263 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
264 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
265 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
266 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
267 /* this time NT reports PAGE_NOACCESS as well */
268 ok(info
.Protect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.Protect
);
269 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
271 /* this should fail, since not the whole range is committed yet */
272 SetLastError(0xdeadbeef);
273 ok(!VirtualProtect(addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
274 "VirtualProtect should fail on a not committed memory\n");
275 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
276 "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
278 ok(VirtualProtect(addr1
, 0x1000, PAGE_READONLY
, &old_prot
), "VirtualProtect failed\n");
279 ok(old_prot
== PAGE_NOACCESS
,
280 "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot
);
282 ok(VirtualProtect(addr1
, 0x1000, PAGE_READWRITE
, &old_prot
), "VirtualProtect failed\n");
283 ok(old_prot
== PAGE_READONLY
,
284 "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot
);
286 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
287 "VirtualQuery failed\n");
288 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
289 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
290 ok(info
.Protect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.Protect
);
291 memset( addr1
, 0x55, 20 );
292 ok( *(DWORD
*)addr1
== 0x55555555, "wrong data %x\n", *(DWORD
*)addr1
);
294 addr2
= VirtualAlloc( addr1
, 0x1000, MEM_RESET
, PAGE_NOACCESS
);
295 ok( addr2
== addr1
, "VirtualAlloc failed err %u\n", GetLastError() );
296 ok( *(DWORD
*)addr1
== 0x55555555 || *(DWORD
*)addr1
== 0, "wrong data %x\n", *(DWORD
*)addr1
);
297 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
298 "VirtualQuery failed\n");
299 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
300 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
301 ok(info
.Protect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.Protect
);
303 addr2
= VirtualAlloc( (char *)addr1
+ 0x1000, 0x1000, MEM_RESET
, PAGE_NOACCESS
);
304 ok( (char *)addr2
== (char *)addr1
+ 0x1000, "VirtualAlloc failed\n" );
306 ok(VirtualQuery(addr2
, &info
, sizeof(info
)) == sizeof(info
),
307 "VirtualQuery failed\n");
308 ok(info
.RegionSize
== 0xf000, "%lx != 0xf000\n", info
.RegionSize
);
309 ok(info
.State
== MEM_RESERVE
, "%x != MEM_RESERVE\n", info
.State
);
310 ok(info
.Protect
== 0, "%x != 0\n", info
.Protect
);
312 addr2
= VirtualAlloc( (char *)addr1
+ 0xf000, 0x2000, MEM_RESET
, PAGE_NOACCESS
);
313 ok( !addr2
, "VirtualAlloc failed\n" );
314 ok( GetLastError() == ERROR_INVALID_ADDRESS
, "wrong error %u\n", GetLastError() );
316 /* invalid protection values */
317 SetLastError(0xdeadbeef);
318 addr2
= VirtualAlloc(NULL
, 0x1000, MEM_RESERVE
, 0);
319 ok(!addr2
, "VirtualAlloc succeeded\n");
320 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
322 SetLastError(0xdeadbeef);
323 addr2
= VirtualAlloc(NULL
, 0x1000, MEM_COMMIT
, 0);
324 ok(!addr2
, "VirtualAlloc succeeded\n");
325 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
327 SetLastError(0xdeadbeef);
328 addr2
= VirtualAlloc(addr1
, 0x1000, MEM_COMMIT
, PAGE_READONLY
| PAGE_EXECUTE
);
329 ok(!addr2
, "VirtualAlloc succeeded\n");
330 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
332 SetLastError(0xdeadbeef);
333 ok(!VirtualProtect(addr1
, 0x1000, PAGE_READWRITE
| PAGE_EXECUTE_WRITECOPY
, &old_prot
),
334 "VirtualProtect succeeded\n");
335 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
337 SetLastError(0xdeadbeef);
338 ok(!VirtualProtect(addr1
, 0x1000, 0, &old_prot
), "VirtualProtect succeeded\n");
339 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
341 SetLastError(0xdeadbeef);
342 ok(!VirtualFree(addr1
, 0x10000, 0), "VirtualFree should fail with type 0\n");
343 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
344 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
346 SetLastError(0xdeadbeef);
347 ok(!VirtualFree(addr1
, 0, MEM_FREE
), "VirtualFree should fail with type MEM_FREE\n");
348 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
349 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
351 ok(VirtualFree(addr1
, 0x10000, MEM_DECOMMIT
), "VirtualFree failed\n");
353 /* if the type is MEM_RELEASE, size must be 0 */
354 ok(!VirtualFree(addr1
, 1, MEM_RELEASE
), "VirtualFree should fail\n");
355 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
356 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
358 ok(VirtualFree(addr1
, 0, MEM_RELEASE
), "VirtualFree failed\n");
360 /* PAGE_NOCACHE cannot be set per page in recent Windows */
361 addr1
= VirtualAlloc( NULL
, 0x2000, MEM_COMMIT
, PAGE_READWRITE
| PAGE_NOCACHE
);
362 ok( addr1
!= NULL
, "VirtualAlloc failed\n");
363 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
), "VirtualQuery failed\n");
364 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
365 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
366 ok(info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_NOCACHE
),
367 "wrong protect %x\n", info
.AllocationProtect
);
368 ok(info
.RegionSize
== 0x2000, "wrong size %lx\n", info
.RegionSize
);
369 ok(info
.State
== MEM_COMMIT
, "wrong state %x\n", info
.State
);
370 ok(info
.Protect
== (PAGE_READWRITE
| PAGE_NOCACHE
), "wrong protect %x\n", info
.Protect
);
371 ok(info
.Type
== MEM_PRIVATE
, "wrong type %x\n", info
.Type
);
373 ok(VirtualProtect(addr1
, 0x1000, PAGE_READWRITE
, &old_prot
), "VirtualProtect failed\n");
374 ok( old_prot
== (PAGE_READWRITE
| PAGE_NOCACHE
), "wrong protect %x\n", old_prot
);
375 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
), "VirtualQuery failed\n");
376 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
377 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
378 ok(info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_NOCACHE
),
379 "wrong protect %x\n", info
.AllocationProtect
);
380 ok(info
.RegionSize
== 0x2000 || broken(info
.RegionSize
== 0x1000),
381 "wrong size %lx\n", info
.RegionSize
);
382 ok(info
.State
== MEM_COMMIT
, "wrong state %x\n", info
.State
);
383 ok(info
.Protect
== (PAGE_READWRITE
| PAGE_NOCACHE
) || broken(info
.Protect
== PAGE_READWRITE
),
384 "wrong protect %x\n", info
.Protect
);
385 ok(info
.Type
== MEM_PRIVATE
, "wrong type %x\n", info
.Type
);
387 ok(VirtualProtect(addr1
, 0x1000, PAGE_READONLY
, &old_prot
), "VirtualProtect failed\n");
388 ok( old_prot
== (PAGE_READWRITE
| PAGE_NOCACHE
) || broken(old_prot
== PAGE_READWRITE
),
389 "wrong protect %x\n", old_prot
);
390 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
), "VirtualQuery failed\n");
391 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
392 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
393 ok(info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_NOCACHE
),
394 "wrong protect %x\n", info
.AllocationProtect
);
395 ok(info
.RegionSize
== 0x1000, "wrong size %lx\n", info
.RegionSize
);
396 ok(info
.State
== MEM_COMMIT
, "wrong state %x\n", info
.State
);
397 ok(info
.Protect
== (PAGE_READONLY
| PAGE_NOCACHE
) || broken(info
.Protect
== PAGE_READONLY
),
398 "wrong protect %x\n", info
.Protect
);
399 ok(info
.Type
== MEM_PRIVATE
, "wrong type %x\n", info
.Type
);
401 ok(VirtualFree(addr1
, 0, MEM_RELEASE
), "VirtualFree failed\n");
403 addr1
= VirtualAlloc( NULL
, 0x2000, MEM_COMMIT
, PAGE_READWRITE
);
404 ok( addr1
!= NULL
, "VirtualAlloc failed\n");
405 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
), "VirtualQuery failed\n");
406 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
407 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
408 ok(info
.AllocationProtect
== PAGE_READWRITE
,
409 "wrong protect %x\n", info
.AllocationProtect
);
410 ok(info
.RegionSize
== 0x2000, "wrong size %lx\n", info
.RegionSize
);
411 ok(info
.State
== MEM_COMMIT
, "wrong state %x\n", info
.State
);
412 ok(info
.Protect
== PAGE_READWRITE
, "wrong protect %x\n", info
.Protect
);
413 ok(info
.Type
== MEM_PRIVATE
, "wrong type %x\n", info
.Type
);
415 ok(VirtualProtect(addr1
, 0x1000, PAGE_READONLY
| PAGE_NOCACHE
, &old_prot
), "VirtualProtect failed\n");
416 ok( old_prot
== PAGE_READWRITE
, "wrong protect %x\n", old_prot
);
417 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
), "VirtualQuery failed\n");
418 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
419 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
420 ok(info
.AllocationProtect
== PAGE_READWRITE
, "wrong protect %x\n", info
.AllocationProtect
);
421 ok(info
.RegionSize
== 0x1000, "wrong size %lx\n", info
.RegionSize
);
422 ok(info
.State
== MEM_COMMIT
, "wrong state %x\n", info
.State
);
423 ok(info
.Protect
== PAGE_READONLY
|| broken(info
.Protect
== (PAGE_READONLY
| PAGE_NOCACHE
)),
424 "wrong protect %x\n", info
.Protect
);
425 ok(info
.Type
== MEM_PRIVATE
, "wrong type %x\n", info
.Type
);
427 ok(VirtualFree(addr1
, 0, MEM_RELEASE
), "VirtualFree failed\n");
429 /* memory returned by VirtualAlloc should be aligned to 64k */
430 addr1
= VirtualAlloc(0, 0x2000, MEM_RESERVE
| MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
431 ok(addr1
!= NULL
, "VirtualAlloc failed\n");
432 ok(!((ULONG_PTR
)addr1
& 0xffff), "returned memory %p is not aligned to 64k\n", addr1
);
433 ok(VirtualFree(addr1
, 0, MEM_RELEASE
), "VirtualFree failed\n");
434 addr2
= VirtualAlloc(addr1
, 0x1000, MEM_RESERVE
| MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
435 ok(addr2
== addr1
, "VirtualAlloc returned %p, expected %p\n", addr2
, addr1
);
437 /* AT_ROUND_TO_PAGE flag is not supported for VirtualAlloc */
438 SetLastError(0xdeadbeef);
439 addr2
= VirtualAlloc(addr1
, 0x1000, MEM_RESERVE
| MEM_COMMIT
| AT_ROUND_TO_PAGE
, PAGE_EXECUTE_READWRITE
);
440 ok(!addr2
, "VirtualAlloc unexpectedly succeeded\n");
441 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
443 ok(VirtualFree(addr1
, 0, MEM_RELEASE
), "VirtualFree failed\n");
446 static void test_MapViewOfFile(void)
448 static const char testfile
[] = "testfile.xxx";
450 HANDLE file
, mapping
, map2
;
451 void *ptr
, *ptr2
, *addr
;
452 SECTION_BASIC_INFORMATION section_info
;
453 SECTION_IMAGE_INFORMATION image_info
;
454 MEMORY_BASIC_INFORMATION info
;
459 LARGE_INTEGER map_size
;
461 SetLastError(0xdeadbeef);
462 file
= CreateFileA( testfile
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
463 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
464 SetFilePointer( file
, 12288, NULL
, FILE_BEGIN
);
465 SetEndOfFile( file
);
467 /* read/write mapping */
469 SetLastError(0xdeadbeef);
470 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
471 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
473 SetLastError(0xdeadbeef);
474 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
475 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
476 UnmapViewOfFile( ptr
);
478 SetLastError(0xdeadbeef);
479 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
480 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_COPY error %u\n", GetLastError() );
481 UnmapViewOfFile( ptr
);
483 SetLastError(0xdeadbeef);
484 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
485 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
486 UnmapViewOfFile( ptr
);
488 SetLastError(0xdeadbeef);
489 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
490 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
491 UnmapViewOfFile( ptr
);
493 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
,
494 FILE_MAP_READ
|FILE_MAP_WRITE
, FALSE
, 0 );
495 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
496 ptr
= MapViewOfFile( map2
, FILE_MAP_WRITE
, 0, 0, 4096 );
497 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
498 UnmapViewOfFile( ptr
);
501 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
,
502 FILE_MAP_READ
, FALSE
, 0 );
503 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
504 SetLastError(0xdeadbeef);
505 ptr
= MapViewOfFile( map2
, FILE_MAP_WRITE
, 0, 0, 4096 );
506 ok( !ptr
, "MapViewOfFile succeeded\n" );
507 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
509 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
, 0, FALSE
, 0 );
510 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
511 SetLastError(0xdeadbeef);
512 ptr
= MapViewOfFile( map2
, 0, 0, 0, 4096 );
513 ok( !ptr
, "MapViewOfFile succeeded\n" );
514 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
516 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
,
517 FILE_MAP_READ
, FALSE
, 0 );
518 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
519 ptr
= MapViewOfFile( map2
, 0, 0, 0, 4096 );
520 ok( ptr
!= NULL
, "MapViewOfFile NO_ACCESS error %u\n", GetLastError() );
522 UnmapViewOfFile( ptr
);
524 CloseHandle( mapping
);
526 /* read-only mapping */
528 SetLastError(0xdeadbeef);
529 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
530 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
532 SetLastError(0xdeadbeef);
533 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
534 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
535 UnmapViewOfFile( ptr
);
537 SetLastError(0xdeadbeef);
538 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
539 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_COPY error %u\n", GetLastError() );
540 UnmapViewOfFile( ptr
);
542 SetLastError(0xdeadbeef);
543 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
544 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
545 UnmapViewOfFile( ptr
);
547 SetLastError(0xdeadbeef);
548 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
549 ok( !ptr
, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
550 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
551 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
552 CloseHandle( mapping
);
554 /* copy-on-write mapping */
556 SetLastError(0xdeadbeef);
557 mapping
= CreateFileMappingA( file
, NULL
, PAGE_WRITECOPY
, 0, 4096, NULL
);
558 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
560 SetLastError(0xdeadbeef);
561 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
562 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
563 UnmapViewOfFile( ptr
);
565 SetLastError(0xdeadbeef);
566 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
567 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_COPY error %u\n", GetLastError() );
568 UnmapViewOfFile( ptr
);
570 SetLastError(0xdeadbeef);
571 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
572 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
573 UnmapViewOfFile( ptr
);
575 SetLastError(0xdeadbeef);
576 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
577 ok( !ptr
, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
578 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
579 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
580 CloseHandle( mapping
);
582 /* no access mapping */
584 SetLastError(0xdeadbeef);
585 mapping
= CreateFileMappingA( file
, NULL
, PAGE_NOACCESS
, 0, 4096, NULL
);
586 ok( !mapping
, "CreateFileMappingA succeeded\n" );
587 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
590 /* now try read-only file */
592 SetLastError(0xdeadbeef);
593 file
= CreateFileA( testfile
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0 );
594 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
596 SetLastError(0xdeadbeef);
597 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
598 ok( !mapping
, "CreateFileMapping PAGE_READWRITE succeeded\n" );
599 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
600 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
602 SetLastError(0xdeadbeef);
603 mapping
= CreateFileMappingA( file
, NULL
, PAGE_WRITECOPY
, 0, 4096, NULL
);
604 ok( mapping
!= 0, "CreateFileMapping PAGE_WRITECOPY error %u\n", GetLastError() );
605 CloseHandle( mapping
);
607 SetLastError(0xdeadbeef);
608 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
609 ok( mapping
!= 0, "CreateFileMapping PAGE_READONLY error %u\n", GetLastError() );
610 CloseHandle( mapping
);
613 /* now try no access file */
615 SetLastError(0xdeadbeef);
616 file
= CreateFileA( testfile
, 0, 0, NULL
, OPEN_EXISTING
, 0, 0 );
617 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
619 SetLastError(0xdeadbeef);
620 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
621 ok( !mapping
, "CreateFileMapping PAGE_READWRITE succeeded\n" );
622 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
623 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
625 SetLastError(0xdeadbeef);
626 mapping
= CreateFileMappingA( file
, NULL
, PAGE_WRITECOPY
, 0, 4096, NULL
);
627 ok( !mapping
, "CreateFileMapping PAGE_WRITECOPY succeeded\n" );
628 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
629 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
631 SetLastError(0xdeadbeef);
632 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
633 ok( !mapping
, "CreateFileMapping PAGE_READONLY succeeded\n" );
634 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
635 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
638 DeleteFileA( testfile
);
640 SetLastError(0xdeadbeef);
642 file
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4090, name
);
643 /* nt4 doesn't have Local\\ */
644 if (!file
&& GetLastError() == ERROR_PATH_NOT_FOUND
)
647 file
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4090, name
);
649 ok( file
!= 0, "CreateFileMapping PAGE_READWRITE error %u\n", GetLastError() );
651 SetLastError(0xdeadbeef);
652 mapping
= OpenFileMappingA( FILE_MAP_READ
, FALSE
, name
);
653 ok( mapping
!= 0, "OpenFileMapping FILE_MAP_READ error %u\n", GetLastError() );
654 SetLastError(0xdeadbeef);
655 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 0 );
656 ok( !ptr
, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
657 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
658 SetLastError(0xdeadbeef);
659 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 0 );
660 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
661 SetLastError(0xdeadbeef);
662 size
= VirtualQuery( ptr
, &info
, sizeof(info
) );
663 ok( size
== sizeof(info
),
664 "VirtualQuery error %u\n", GetLastError() );
665 ok( info
.BaseAddress
== ptr
, "%p != %p\n", info
.BaseAddress
, ptr
);
666 ok( info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
667 ok( info
.AllocationProtect
== PAGE_READONLY
, "%x != PAGE_READONLY\n", info
.AllocationProtect
);
668 ok( info
.RegionSize
== 4096, "%lx != 4096\n", info
.RegionSize
);
669 ok( info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
670 ok( info
.Protect
== PAGE_READONLY
, "%x != PAGE_READONLY\n", info
.Protect
);
671 UnmapViewOfFile( ptr
);
672 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
673 sizeof(section_info
), &info_size
);
674 ok( status
== STATUS_ACCESS_DENIED
, "NtQuerySection failed err %x\n", status
);
675 CloseHandle( mapping
);
676 mapping
= OpenFileMappingA( FILE_MAP_READ
| SECTION_QUERY
, FALSE
, name
);
677 ok( mapping
!= 0, "OpenFileMapping FILE_MAP_READ error %u\n", GetLastError() );
678 info_size
= (SIZE_T
)0xdeadbeef << 16;
679 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
680 sizeof(section_info
), &info_size
);
681 ok( !status
, "NtQuerySection failed err %x\n", status
);
682 ok( info_size
== sizeof(section_info
), "NtQuerySection wrong size %lu\n", info_size
);
683 ok( section_info
.Attributes
== SEC_COMMIT
, "NtQuerySection wrong attr %08x\n",
684 section_info
.Attributes
);
685 ok( section_info
.BaseAddress
== NULL
, "NtQuerySection wrong base %p\n", section_info
.BaseAddress
);
686 ok( section_info
.Size
.QuadPart
== info
.RegionSize
, "NtQuerySection wrong size %x%08x / %08lx\n",
687 section_info
.Size
.u
.HighPart
, section_info
.Size
.u
.LowPart
, info
.RegionSize
);
688 CloseHandle( mapping
);
690 SetLastError(0xdeadbeef);
691 mapping
= OpenFileMappingA( FILE_MAP_WRITE
, FALSE
, name
);
692 ok( mapping
!= 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() );
693 SetLastError(0xdeadbeef);
694 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 0 );
695 ok( !ptr
, "MapViewOfFile succeeded\n" );
696 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
697 SetLastError(0xdeadbeef);
698 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 0 );
699 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
700 SetLastError(0xdeadbeef);
701 size
= VirtualQuery( ptr
, &info
, sizeof(info
) );
702 ok( size
== sizeof(info
),
703 "VirtualQuery error %u\n", GetLastError() );
704 ok( info
.BaseAddress
== ptr
, "%p != %p\n", info
.BaseAddress
, ptr
);
705 ok( info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
706 ok( info
.AllocationProtect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.AllocationProtect
);
707 ok( info
.RegionSize
== 4096, "%lx != 4096\n", info
.RegionSize
);
708 ok( info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
709 ok( info
.Protect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.Protect
);
710 UnmapViewOfFile( ptr
);
711 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
712 sizeof(section_info
), &info_size
);
713 ok( status
== STATUS_ACCESS_DENIED
, "NtQuerySection failed err %x\n", status
);
714 CloseHandle( mapping
);
716 mapping
= OpenFileMappingA( FILE_MAP_WRITE
| SECTION_QUERY
, FALSE
, name
);
717 ok( mapping
!= 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() );
718 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
719 sizeof(section_info
), &info_size
);
720 ok( !status
, "NtQuerySection failed err %x\n", status
);
721 ok( info_size
== sizeof(section_info
), "NtQuerySection wrong size %lu\n", info_size
);
722 ok( section_info
.Attributes
== SEC_COMMIT
, "NtQuerySection wrong attr %08x\n",
723 section_info
.Attributes
);
724 ok( section_info
.BaseAddress
== NULL
, "NtQuerySection wrong base %p\n", section_info
.BaseAddress
);
725 ok( section_info
.Size
.QuadPart
== info
.RegionSize
, "NtQuerySection wrong size %x%08x / %08lx\n",
726 section_info
.Size
.u
.HighPart
, section_info
.Size
.u
.LowPart
, info
.RegionSize
);
727 CloseHandle( mapping
);
731 /* read/write mapping with SEC_RESERVE */
732 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
| SEC_RESERVE
, 0, MAPPING_SIZE
, NULL
);
733 ok(mapping
!= 0, "CreateFileMappingA failed with error %d\n", GetLastError());
734 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
735 sizeof(section_info
), NULL
);
736 ok( !status
, "NtQuerySection failed err %x\n", status
);
737 ok( section_info
.Attributes
== SEC_RESERVE
, "NtQuerySection wrong attr %08x\n",
738 section_info
.Attributes
);
739 ok( section_info
.BaseAddress
== NULL
, "NtQuerySection wrong base %p\n", section_info
.BaseAddress
);
740 ok( section_info
.Size
.QuadPart
== MAPPING_SIZE
, "NtQuerySection wrong size %x%08x / %08x\n",
741 section_info
.Size
.u
.HighPart
, section_info
.Size
.u
.LowPart
, MAPPING_SIZE
);
743 ptr
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
744 ok(ptr
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError());
746 ptr2
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
747 ok( ptr2
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError());
748 ok( ptr
!= ptr2
, "MapViewOfFile returned same pointer\n" );
750 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
751 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
752 ok(info
.BaseAddress
== ptr
, "BaseAddress should have been %p but was %p instead\n", ptr
, info
.BaseAddress
);
753 ok(info
.AllocationBase
== ptr
, "AllocationBase should have been %p but was %p instead\n", ptr
, info
.AllocationBase
);
754 ok(info
.RegionSize
== MAPPING_SIZE
, "RegionSize should have been 0x%x but was 0x%lx\n", MAPPING_SIZE
, info
.RegionSize
);
755 ok(info
.State
== MEM_RESERVE
, "State should have been MEM_RESERVE instead of 0x%x\n", info
.State
);
756 ok(info
.AllocationProtect
== PAGE_READWRITE
,
757 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
758 ok(info
.Protect
== 0, "Protect should have been 0 instead of 0x%x\n", info
.Protect
);
759 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
761 ret
= VirtualQuery(ptr2
, &info
, sizeof(info
));
762 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
763 ok(info
.BaseAddress
== ptr2
,
764 "BaseAddress should have been %p but was %p instead\n", ptr2
, info
.BaseAddress
);
765 ok(info
.AllocationBase
== ptr2
,
766 "AllocationBase should have been %p but was %p instead\n", ptr2
, info
.AllocationBase
);
767 ok(info
.AllocationProtect
== PAGE_READWRITE
,
768 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
769 ok(info
.RegionSize
== MAPPING_SIZE
,
770 "RegionSize should have been 0x%x but was 0x%lx\n", MAPPING_SIZE
, info
.RegionSize
);
771 ok(info
.State
== MEM_RESERVE
, "State should have been MEM_RESERVE instead of 0x%x\n", info
.State
);
772 ok(info
.Protect
== 0, "Protect should have been 0 instead of 0x%x\n", info
.Protect
);
773 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
775 ptr
= VirtualAlloc(ptr
, 0x10000, MEM_COMMIT
, PAGE_READONLY
);
776 ok(ptr
!= NULL
, "VirtualAlloc failed with error %d\n", GetLastError());
778 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
779 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
780 ok(info
.BaseAddress
== ptr
, "BaseAddress should have been %p but was %p instead\n", ptr
, info
.BaseAddress
);
781 ok(info
.AllocationBase
== ptr
, "AllocationBase should have been %p but was %p instead\n", ptr
, info
.AllocationBase
);
782 ok(info
.RegionSize
== 0x10000, "RegionSize should have been 0x10000 but was 0x%lx\n", info
.RegionSize
);
783 ok(info
.State
== MEM_COMMIT
, "State should have been MEM_COMMIT instead of 0x%x\n", info
.State
);
784 ok(info
.Protect
== PAGE_READONLY
, "Protect should have been PAGE_READONLY instead of 0x%x\n", info
.Protect
);
785 ok(info
.AllocationProtect
== PAGE_READWRITE
,
786 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
787 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
789 /* shows that the VirtualAlloc above affects the mapping, not just the
790 * virtual memory in this process - it also affects all other processes
791 * with a view of the mapping, but that isn't tested here */
792 ret
= VirtualQuery(ptr2
, &info
, sizeof(info
));
793 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
794 ok(info
.BaseAddress
== ptr2
,
795 "BaseAddress should have been %p but was %p instead\n", ptr2
, info
.BaseAddress
);
796 ok(info
.AllocationBase
== ptr2
,
797 "AllocationBase should have been %p but was %p instead\n", ptr2
, info
.AllocationBase
);
798 ok(info
.AllocationProtect
== PAGE_READWRITE
,
799 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
800 ok(info
.RegionSize
== 0x10000,
801 "RegionSize should have been 0x10000 but was 0x%lx\n", info
.RegionSize
);
802 ok(info
.State
== MEM_COMMIT
,
803 "State should have been MEM_COMMIT instead of 0x%x\n", info
.State
);
804 ok(info
.Protect
== PAGE_READWRITE
,
805 "Protect should have been PAGE_READWRITE instead of 0x%x\n", info
.Protect
);
806 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
808 addr
= VirtualAlloc( ptr
, MAPPING_SIZE
, MEM_RESET
, PAGE_READONLY
);
809 ok( addr
== ptr
, "VirtualAlloc failed with error %u\n", GetLastError() );
811 ret
= VirtualFree( ptr
, 0x10000, MEM_DECOMMIT
);
812 ok( !ret
, "VirtualFree succeeded\n" );
813 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "VirtualFree failed with %u\n", GetLastError() );
815 ret
= UnmapViewOfFile(ptr2
);
816 ok(ret
, "UnmapViewOfFile failed with error %d\n", GetLastError());
817 ret
= UnmapViewOfFile(ptr
);
818 ok(ret
, "UnmapViewOfFile failed with error %d\n", GetLastError());
819 CloseHandle(mapping
);
821 /* same thing with SEC_COMMIT */
822 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
| SEC_COMMIT
, 0, MAPPING_SIZE
, NULL
);
823 ok(mapping
!= 0, "CreateFileMappingA failed with error %d\n", GetLastError());
824 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
825 sizeof(section_info
), NULL
);
826 ok( !status
, "NtQuerySection failed err %x\n", status
);
827 ok( section_info
.Attributes
== SEC_COMMIT
, "NtQuerySection wrong attr %08x\n",
828 section_info
.Attributes
);
829 ok( section_info
.BaseAddress
== NULL
, "NtQuerySection wrong base %p\n", section_info
.BaseAddress
);
830 ok( section_info
.Size
.QuadPart
== MAPPING_SIZE
, "NtQuerySection wrong size %x%08x / %08x\n",
831 section_info
.Size
.u
.HighPart
, section_info
.Size
.u
.LowPart
, MAPPING_SIZE
);
833 ptr
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
834 ok(ptr
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError());
836 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
837 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
838 ok(info
.BaseAddress
== ptr
, "wrong BaseAddress %p/%p\n", ptr
, info
.BaseAddress
);
839 ok(info
.AllocationBase
== ptr
, "wrong AllocationBase %p/%p\n", ptr
, info
.AllocationBase
);
840 ok(info
.RegionSize
== MAPPING_SIZE
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
841 ok(info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
842 ok(info
.AllocationProtect
== PAGE_READWRITE
, "wrong AllocationProtect 0x%x\n", info
.AllocationProtect
);
843 ok(info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
844 ok(info
.Type
== MEM_MAPPED
, "wrong Type 0x%x\n", info
.Type
);
846 ptr
= VirtualAlloc(ptr
, 0x10000, MEM_COMMIT
, PAGE_READONLY
);
847 ok(ptr
!= NULL
, "VirtualAlloc failed with error %d\n", GetLastError());
849 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
850 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
851 ok(info
.BaseAddress
== ptr
, "wrong BaseAddress %p/%p\n", ptr
, info
.BaseAddress
);
852 ok(info
.AllocationBase
== ptr
, "wrong AllocationBase %p/%p\n", ptr
, info
.AllocationBase
);
853 ok(info
.RegionSize
== 0x10000, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
854 ok(info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
855 ok(info
.AllocationProtect
== PAGE_READWRITE
, "wrong AllocationProtect 0x%x\n", info
.AllocationProtect
);
856 ok(info
.Protect
== PAGE_READONLY
, "wrong Protect 0x%x\n", info
.Protect
);
857 ok(info
.Type
== MEM_MAPPED
, "wrong Type 0x%x\n", info
.Type
);
859 addr
= VirtualAlloc( ptr
, MAPPING_SIZE
, MEM_RESET
, PAGE_READONLY
);
860 ok( addr
== ptr
, "VirtualAlloc failed with error %u\n", GetLastError() );
862 ret
= VirtualFree( ptr
, 0x10000, MEM_DECOMMIT
);
863 ok( !ret
, "VirtualFree succeeded\n" );
864 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "VirtualFree failed with %u\n", GetLastError() );
866 ret
= UnmapViewOfFile(ptr
);
867 ok(ret
, "UnmapViewOfFile failed with error %d\n", GetLastError());
868 CloseHandle(mapping
);
870 /* same thing with SEC_NOCACHE (only supported on recent Windows versions) */
871 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
| SEC_COMMIT
| SEC_NOCACHE
,
872 0, MAPPING_SIZE
, NULL
);
873 ok(mapping
!= 0, "CreateFileMappingA failed with error %d\n", GetLastError());
874 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
875 sizeof(section_info
), NULL
);
876 ok( !status
, "NtQuerySection failed err %x\n", status
);
877 ok( section_info
.Attributes
== (SEC_COMMIT
| SEC_NOCACHE
) ||
878 broken(section_info
.Attributes
== SEC_COMMIT
),
879 "NtQuerySection wrong attr %08x\n", section_info
.Attributes
);
880 if (section_info
.Attributes
& SEC_NOCACHE
)
882 ptr
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
883 ok(ptr
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError());
885 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
886 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
887 ok(info
.BaseAddress
== ptr
, "wrong BaseAddress %p/%p\n", ptr
, info
.BaseAddress
);
888 ok(info
.AllocationBase
== ptr
, "wrong AllocationBase %p/%p\n", ptr
, info
.AllocationBase
);
889 ok(info
.RegionSize
== MAPPING_SIZE
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
890 ok(info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
891 ok(info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_NOCACHE
),
892 "wrong AllocationProtect 0x%x\n", info
.AllocationProtect
);
893 ok(info
.Protect
== (PAGE_READWRITE
| PAGE_NOCACHE
), "wrong Protect 0x%x\n", info
.Protect
);
894 ok(info
.Type
== MEM_MAPPED
, "wrong Type 0x%x\n", info
.Type
);
896 ptr
= VirtualAlloc(ptr
, 0x10000, MEM_COMMIT
, PAGE_READONLY
);
897 ok(ptr
!= NULL
, "VirtualAlloc failed with error %d\n", GetLastError());
899 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
900 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
901 ok(info
.BaseAddress
== ptr
, "wrong BaseAddress %p/%p\n", ptr
, info
.BaseAddress
);
902 ok(info
.AllocationBase
== ptr
, "wrong AllocationBase %p/%p\n", ptr
, info
.AllocationBase
);
903 ok(info
.RegionSize
== 0x10000, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
904 ok(info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
905 ok(info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_NOCACHE
),
906 "wrong AllocationProtect 0x%x\n", info
.AllocationProtect
);
907 ok(info
.Protect
== (PAGE_READONLY
| PAGE_NOCACHE
), "wrong Protect 0x%x\n", info
.Protect
);
908 ok(info
.Type
== MEM_MAPPED
, "wrong Type 0x%x\n", info
.Type
);
910 ret
= UnmapViewOfFile(ptr
);
911 ok(ret
, "UnmapViewOfFile failed with error %d\n", GetLastError());
913 CloseHandle(mapping
);
915 addr
= VirtualAlloc(NULL
, 0x10000, MEM_COMMIT
, PAGE_READONLY
);
916 ok( addr
!= NULL
, "VirtualAlloc failed with error %u\n", GetLastError() );
918 SetLastError(0xdeadbeef);
919 ok( !UnmapViewOfFile(addr
), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
920 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
921 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
922 SetLastError(0xdeadbeef);
923 ok( !UnmapViewOfFile((char *)addr
+ 0x3000), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
924 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
925 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
926 SetLastError(0xdeadbeef);
927 ok( !UnmapViewOfFile((void *)0xdeadbeef), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
928 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
929 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
931 ok( VirtualFree(addr
, 0, MEM_RELEASE
), "VirtualFree failed\n" );
933 /* close named mapping handle without unmapping */
935 SetLastError(0xdeadbeef);
936 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, MAPPING_SIZE
, name
);
937 ok( mapping
!= 0, "CreateFileMappingA failed with error %d\n", GetLastError() );
938 SetLastError(0xdeadbeef);
939 ptr
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
940 ok( ptr
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError() );
941 SetLastError(0xdeadbeef);
942 map2
= OpenFileMappingA(FILE_MAP_READ
, FALSE
, name
);
943 ok( map2
!= 0, "OpenFileMappingA failed with error %d\n", GetLastError() );
944 SetLastError(0xdeadbeef);
945 ret
= CloseHandle(map2
);
946 ok(ret
, "CloseHandle error %d\n", GetLastError());
947 SetLastError(0xdeadbeef);
948 ret
= CloseHandle(mapping
);
949 ok(ret
, "CloseHandle error %d\n", GetLastError());
951 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
952 ok( !ret
, "memory is not accessible\n" );
954 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
955 ok(ret
, "VirtualQuery error %d\n", GetLastError());
956 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
957 ok(info
.RegionSize
== MAPPING_SIZE
, "got %#lx != expected %#x\n", info
.RegionSize
, MAPPING_SIZE
);
958 ok(info
.Protect
== PAGE_READWRITE
, "got %#x != expected PAGE_READWRITE\n", info
.Protect
);
959 ok(info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
960 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%#x != PAGE_READWRITE\n", info
.AllocationProtect
);
961 ok(info
.State
== MEM_COMMIT
, "%#x != MEM_COMMIT\n", info
.State
);
962 ok(info
.Type
== MEM_MAPPED
, "%#x != MEM_MAPPED\n", info
.Type
);
964 SetLastError(0xdeadbeef);
965 map2
= OpenFileMappingA(FILE_MAP_READ
, FALSE
, name
);
966 ok( map2
== 0, "OpenFileMappingA succeeded\n" );
967 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "OpenFileMappingA set error %d\n", GetLastError() );
968 if (map2
) CloseHandle(map2
); /* FIXME: remove once Wine is fixed */
969 SetLastError(0xdeadbeef);
970 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, MAPPING_SIZE
, name
);
971 ok( mapping
!= 0, "CreateFileMappingA failed\n" );
972 ok( GetLastError() == ERROR_SUCCESS
, "CreateFileMappingA set error %d\n", GetLastError() );
973 SetLastError(0xdeadbeef);
974 ret
= CloseHandle(mapping
);
975 ok(ret
, "CloseHandle error %d\n", GetLastError());
977 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
978 ok( !ret
, "memory is not accessible\n" );
980 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
981 ok(ret
, "VirtualQuery error %d\n", GetLastError());
982 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
983 ok(info
.RegionSize
== MAPPING_SIZE
, "got %#lx != expected %#x\n", info
.RegionSize
, MAPPING_SIZE
);
984 ok(info
.Protect
== PAGE_READWRITE
, "got %#x != expected PAGE_READWRITE\n", info
.Protect
);
985 ok(info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
986 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%#x != PAGE_READWRITE\n", info
.AllocationProtect
);
987 ok(info
.State
== MEM_COMMIT
, "%#x != MEM_COMMIT\n", info
.State
);
988 ok(info
.Type
== MEM_MAPPED
, "%#x != MEM_MAPPED\n", info
.Type
);
990 SetLastError(0xdeadbeef);
991 ret
= UnmapViewOfFile(ptr
);
992 ok( ret
, "UnmapViewOfFile failed with error %d\n", GetLastError() );
994 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
995 ok( ret
, "memory is accessible\n" );
997 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
998 ok(ret
, "VirtualQuery error %d\n", GetLastError());
999 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
1000 ok(info
.Protect
== PAGE_NOACCESS
, "got %#x != expected PAGE_NOACCESS\n", info
.Protect
);
1001 ok(info
.AllocationBase
== NULL
, "%p != NULL\n", info
.AllocationBase
);
1002 ok(info
.AllocationProtect
== 0, "%#x != 0\n", info
.AllocationProtect
);
1003 ok(info
.State
== MEM_FREE
, "%#x != MEM_FREE\n", info
.State
);
1004 ok(info
.Type
== 0, "%#x != 0\n", info
.Type
);
1006 SetLastError(0xdeadbeef);
1007 file
= CreateFileA(testfile
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
1008 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1009 SetFilePointer(file
, 4096, NULL
, FILE_BEGIN
);
1012 SetLastError(0xdeadbeef);
1013 mapping
= CreateFileMappingA(file
, NULL
, PAGE_READWRITE
, 0, MAPPING_SIZE
, name
);
1014 ok( mapping
!= 0, "CreateFileMappingA failed with error %d\n", GetLastError() );
1015 SetLastError(0xdeadbeef);
1016 ptr
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
1017 ok( ptr
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError() );
1018 SetLastError(0xdeadbeef);
1019 map2
= OpenFileMappingA(FILE_MAP_READ
, FALSE
, name
);
1020 ok( map2
!= 0, "OpenFileMappingA failed with error %d\n", GetLastError() );
1021 SetLastError(0xdeadbeef);
1022 ret
= CloseHandle(map2
);
1023 ok(ret
, "CloseHandle error %d\n", GetLastError());
1024 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
1025 sizeof(section_info
), &info_size
);
1026 ok( !status
, "NtQuerySection failed err %x\n", status
);
1027 ok( info_size
== sizeof(section_info
), "NtQuerySection wrong size %lu\n", info_size
);
1028 ok( section_info
.Attributes
== SEC_FILE
, "NtQuerySection wrong attr %08x\n",
1029 section_info
.Attributes
);
1030 ok( section_info
.BaseAddress
== NULL
, "NtQuerySection wrong base %p\n", section_info
.BaseAddress
);
1031 ok( section_info
.Size
.QuadPart
== MAPPING_SIZE
, "NtQuerySection wrong size %x%08x\n",
1032 section_info
.Size
.u
.HighPart
, section_info
.Size
.u
.LowPart
);
1033 SetLastError(0xdeadbeef);
1034 ret
= CloseHandle(mapping
);
1035 ok(ret
, "CloseHandle error %d\n", GetLastError());
1037 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
1038 ok( !ret
, "memory is not accessible\n" );
1040 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
1041 ok(ret
, "VirtualQuery error %d\n", GetLastError());
1042 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
1043 ok(info
.RegionSize
== MAPPING_SIZE
, "got %#lx != expected %#x\n", info
.RegionSize
, MAPPING_SIZE
);
1044 ok(info
.Protect
== PAGE_READWRITE
, "got %#x != expected PAGE_READWRITE\n", info
.Protect
);
1045 ok(info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
1046 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%#x != PAGE_READWRITE\n", info
.AllocationProtect
);
1047 ok(info
.State
== MEM_COMMIT
, "%#x != MEM_COMMIT\n", info
.State
);
1048 ok(info
.Type
== MEM_MAPPED
, "%#x != MEM_MAPPED\n", info
.Type
);
1050 SetLastError(0xdeadbeef);
1051 map2
= OpenFileMappingA(FILE_MAP_READ
, FALSE
, name
);
1052 ok( map2
== 0, "OpenFileMappingA succeeded\n" );
1053 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "OpenFileMappingA set error %d\n", GetLastError() );
1055 SetLastError(0xdeadbeef);
1056 mapping
= CreateFileMappingA(file
, NULL
, PAGE_READWRITE
, 0, MAPPING_SIZE
, name
);
1057 ok( mapping
!= 0, "CreateFileMappingA failed\n" );
1058 ok( GetLastError() == ERROR_SUCCESS
, "CreateFileMappingA set error %d\n", GetLastError() );
1059 SetLastError(0xdeadbeef);
1060 ret
= CloseHandle(mapping
);
1061 ok(ret
, "CloseHandle error %d\n", GetLastError());
1063 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
1064 ok( !ret
, "memory is not accessible\n" );
1066 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
1067 ok(ret
, "VirtualQuery error %d\n", GetLastError());
1068 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
1069 ok(info
.RegionSize
== MAPPING_SIZE
, "got %#lx != expected %#x\n", info
.RegionSize
, MAPPING_SIZE
);
1070 ok(info
.Protect
== PAGE_READWRITE
, "got %#x != expected PAGE_READWRITE\n", info
.Protect
);
1071 ok(info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
1072 ok(info
.AllocationProtect
== PAGE_READWRITE
, "%#x != PAGE_READWRITE\n", info
.AllocationProtect
);
1073 ok(info
.State
== MEM_COMMIT
, "%#x != MEM_COMMIT\n", info
.State
);
1074 ok(info
.Type
== MEM_MAPPED
, "%#x != MEM_MAPPED\n", info
.Type
);
1076 SetLastError(0xdeadbeef);
1077 ret
= UnmapViewOfFile(ptr
);
1078 ok( ret
, "UnmapViewOfFile failed with error %d\n", GetLastError() );
1080 ret
= IsBadReadPtr(ptr
, MAPPING_SIZE
);
1081 ok( ret
, "memory is accessible\n" );
1083 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
1084 ok(ret
, "VirtualQuery error %d\n", GetLastError());
1085 ok(info
.BaseAddress
== ptr
, "got %p != expected %p\n", info
.BaseAddress
, ptr
);
1086 ok(info
.Protect
== PAGE_NOACCESS
, "got %#x != expected PAGE_NOACCESS\n", info
.Protect
);
1087 ok(info
.AllocationBase
== NULL
, "%p != NULL\n", info
.AllocationBase
);
1088 ok(info
.AllocationProtect
== 0, "%#x != 0\n", info
.AllocationProtect
);
1089 ok(info
.State
== MEM_FREE
, "%#x != MEM_FREE\n", info
.State
);
1090 ok(info
.Type
== 0, "%#x != 0\n", info
.Type
);
1092 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 12288, NULL
);
1093 ok( mapping
!= NULL
, "CreateFileMappingA failed with error %u\n", GetLastError() );
1095 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 12288 );
1096 ok( ptr
!= NULL
, "MapViewOfFile failed with error %u\n", GetLastError() );
1098 ret
= UnmapViewOfFile( (char *)ptr
+ 100 );
1099 ok( ret
, "UnmapViewOfFile failed with error %u\n", GetLastError() );
1101 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 12288 );
1102 ok( ptr
!= NULL
, "MapViewOfFile failed with error %u\n", GetLastError() );
1104 ret
= UnmapViewOfFile( (char *)ptr
+ 4096 );
1105 ok( ret
, "UnmapViewOfFile failed with error %u\n", GetLastError() );
1107 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 12288 );
1108 ok( ptr
!= NULL
, "MapViewOfFile failed with error %u\n", GetLastError() );
1110 ret
= UnmapViewOfFile( (char *)ptr
+ 4096 + 100 );
1111 ok( ret
, "UnmapViewOfFile failed with error %u\n", GetLastError() );
1113 CloseHandle(mapping
);
1115 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 36, NULL
);
1116 ok( mapping
!= NULL
, "CreateFileMappingA failed with error %u\n", GetLastError() );
1117 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
1118 sizeof(section_info
), &info_size
);
1119 ok( !status
, "NtQuerySection failed err %x\n", status
);
1120 ok( info_size
== sizeof(section_info
), "NtQuerySection wrong size %lu\n", info_size
);
1121 ok( section_info
.Attributes
== SEC_FILE
, "NtQuerySection wrong attr %08x\n",
1122 section_info
.Attributes
);
1123 ok( section_info
.BaseAddress
== NULL
, "NtQuerySection wrong base %p\n", section_info
.BaseAddress
);
1124 ok( section_info
.Size
.QuadPart
== 36, "NtQuerySection wrong size %x%08x\n",
1125 section_info
.Size
.u
.HighPart
, section_info
.Size
.u
.LowPart
);
1126 CloseHandle(mapping
);
1128 SetFilePointer(file
, 0x3456, NULL
, FILE_BEGIN
);
1130 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
1131 ok( mapping
!= NULL
, "CreateFileMappingA failed with error %u\n", GetLastError() );
1132 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
,
1133 sizeof(section_info
), &info_size
);
1134 ok( !status
, "NtQuerySection failed err %x\n", status
);
1135 ok( info_size
== sizeof(section_info
), "NtQuerySection wrong size %lu\n", info_size
);
1136 ok( section_info
.Attributes
== SEC_FILE
, "NtQuerySection wrong attr %08x\n",
1137 section_info
.Attributes
);
1138 ok( section_info
.BaseAddress
== NULL
, "NtQuerySection wrong base %p\n", section_info
.BaseAddress
);
1139 ok( section_info
.Size
.QuadPart
== 0x3456, "NtQuerySection wrong size %x%08x\n",
1140 section_info
.Size
.u
.HighPart
, section_info
.Size
.u
.LowPart
);
1141 CloseHandle(mapping
);
1143 map_size
.QuadPart
= 0x3457;
1144 status
= pNtCreateSection( &mapping
, SECTION_QUERY
| SECTION_MAP_READ
, NULL
,
1145 &map_size
, PAGE_READONLY
, SEC_COMMIT
, file
);
1146 ok( status
== STATUS_SECTION_TOO_BIG
, "NtCreateSection failed %x\n", status
);
1147 status
= pNtCreateSection( &mapping
, SECTION_QUERY
| SECTION_MAP_READ
, NULL
,
1148 &map_size
, PAGE_READONLY
, SEC_IMAGE
, file
);
1149 ok( status
== STATUS_INVALID_IMAGE_NOT_MZ
, "NtCreateSection failed %x\n", status
);
1150 if (!status
) CloseHandle( mapping
);
1151 map_size
.QuadPart
= 0x3452;
1152 status
= pNtCreateSection( &mapping
, SECTION_QUERY
| SECTION_MAP_READ
, NULL
,
1153 &map_size
, PAGE_READONLY
, SEC_COMMIT
, file
);
1154 ok( !status
, "NtCreateSection failed %x\n", status
);
1155 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
, sizeof(section_info
), NULL
);
1156 ok( !status
, "NtQuerySection failed err %x\n", status
);
1157 ok( section_info
.Attributes
== SEC_FILE
, "NtQuerySection wrong attr %08x\n",
1158 section_info
.Attributes
);
1159 ok( section_info
.BaseAddress
== NULL
, "NtQuerySection wrong base %p\n", section_info
.BaseAddress
);
1160 ok( section_info
.Size
.QuadPart
== 0x3452, "NtQuerySection wrong size %x%08x\n",
1161 section_info
.Size
.u
.HighPart
, section_info
.Size
.u
.LowPart
);
1162 size
= map_size
.QuadPart
;
1163 status
= pNtMapViewOfSection( mapping
, GetCurrentProcess(), &ptr
, 0, 0, NULL
,
1164 &size
, ViewShare
, 0, PAGE_READONLY
);
1165 ok( !status
, "NtMapViewOfSection failed err %x\n", status
);
1166 pNtUnmapViewOfSection( GetCurrentProcess(), ptr
);
1167 size
= map_size
.QuadPart
+ 1;
1168 status
= pNtMapViewOfSection( mapping
, GetCurrentProcess(), &ptr
, 0, 0, NULL
,
1169 &size
, ViewShare
, 0, PAGE_READONLY
);
1170 ok( status
== STATUS_INVALID_VIEW_SIZE
, "NtMapViewOfSection failed err %x\n", status
);
1171 CloseHandle(mapping
);
1173 status
= pNtCreateSection( &mapping
, SECTION_QUERY
| SECTION_MAP_READ
, NULL
,
1174 &map_size
, PAGE_READONLY
, SEC_COMMIT
, 0 );
1175 ok( !status
, "NtCreateSection failed %x\n", status
);
1176 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
, sizeof(section_info
), NULL
);
1177 ok( !status
, "NtQuerySection failed err %x\n", status
);
1178 ok( section_info
.Attributes
== SEC_COMMIT
, "NtQuerySection wrong attr %08x\n",
1179 section_info
.Attributes
);
1180 ok( section_info
.BaseAddress
== NULL
, "NtQuerySection wrong base %p\n", section_info
.BaseAddress
);
1181 ok( section_info
.Size
.QuadPart
== 0x4000, "NtQuerySection wrong size %x%08x\n",
1182 section_info
.Size
.u
.HighPart
, section_info
.Size
.u
.LowPart
);
1183 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
, sizeof(section_info
)-1, NULL
);
1184 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQuerySection failed err %x\n", status
);
1185 status
= pNtQuerySection( mapping
, SectionBasicInformation
, §ion_info
, sizeof(section_info
)+1, NULL
);
1186 ok( !status
, "NtQuerySection failed err %x\n", status
);
1187 status
= pNtQuerySection( mapping
, SectionImageInformation
, &image_info
, sizeof(image_info
)-1, NULL
);
1188 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "NtQuerySection failed err %x\n", status
);
1189 status
= pNtQuerySection( mapping
, SectionImageInformation
, &image_info
, sizeof(image_info
), NULL
);
1190 ok( status
== STATUS_SECTION_NOT_IMAGE
, "NtQuerySection failed err %x\n", status
);
1191 status
= pNtQuerySection( mapping
, SectionImageInformation
, &image_info
, sizeof(image_info
)+1, NULL
);
1192 ok( status
== STATUS_SECTION_NOT_IMAGE
, "NtQuerySection failed err %x\n", status
);
1193 if (sizeof(SIZE_T
) > sizeof(int))
1195 status
= pNtQuerySection( mapping
, SectionImageInformation
, &image_info
,
1196 sizeof(image_info
) + ((SIZE_T
)0x10000000 << 8), NULL
);
1198 ok( status
== STATUS_ACCESS_VIOLATION
, "NtQuerySection wrong err %x\n", status
);
1200 CloseHandle(mapping
);
1202 SetFilePointer(file
, 0, NULL
, FILE_BEGIN
);
1204 status
= pNtCreateSection( &mapping
, SECTION_QUERY
| SECTION_MAP_READ
, NULL
,
1205 NULL
, PAGE_READONLY
, SEC_COMMIT
, file
);
1206 ok( status
== STATUS_MAPPED_FILE_SIZE_ZERO
, "NtCreateSection failed %x\n", status
);
1207 status
= pNtCreateSection( &mapping
, SECTION_QUERY
| SECTION_MAP_READ
, NULL
,
1208 NULL
, PAGE_READONLY
, SEC_IMAGE
, file
);
1209 ok( status
== STATUS_INVALID_FILE_FOR_SECTION
, "NtCreateSection failed %x\n", status
);
1212 DeleteFileA(testfile
);
1216 static void test_NtAreMappedFilesTheSame(void)
1218 static const char testfile
[] = "testfile.xxx";
1219 HANDLE file
, file2
, mapping
, map2
;
1222 char path
[MAX_PATH
];
1224 if (!pNtAreMappedFilesTheSame
)
1226 win_skip( "NtAreMappedFilesTheSame not available\n" );
1230 file
= CreateFileA( testfile
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1231 NULL
, CREATE_ALWAYS
, 0, 0 );
1232 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1233 SetFilePointer( file
, 4096, NULL
, FILE_BEGIN
);
1234 SetEndOfFile( file
);
1236 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
1237 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1239 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
1240 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1242 file2
= CreateFileA( testfile
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
1243 NULL
, OPEN_EXISTING
, 0, 0 );
1244 ok( file2
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1246 map2
= CreateFileMappingA( file2
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
1247 ok( map2
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1248 ptr2
= MapViewOfFile( map2
, FILE_MAP_READ
, 0, 0, 4096 );
1249 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1250 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1251 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1252 UnmapViewOfFile( ptr2
);
1254 ptr2
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
1255 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1256 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1257 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1258 UnmapViewOfFile( ptr2
);
1259 CloseHandle( map2
);
1261 map2
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
1262 ok( map2
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1263 ptr2
= MapViewOfFile( map2
, FILE_MAP_READ
, 0, 0, 4096 );
1264 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1265 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1266 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1267 UnmapViewOfFile( ptr2
);
1268 CloseHandle( map2
);
1269 CloseHandle( file2
);
1271 status
= pNtAreMappedFilesTheSame( ptr
, ptr
);
1272 ok( status
== STATUS_SUCCESS
|| broken(status
== STATUS_NOT_SAME_DEVICE
),
1273 "NtAreMappedFilesTheSame returned %x\n", status
);
1275 status
= pNtAreMappedFilesTheSame( ptr
, (char *)ptr
+ 30 );
1276 ok( status
== STATUS_SUCCESS
|| broken(status
== STATUS_NOT_SAME_DEVICE
),
1277 "NtAreMappedFilesTheSame returned %x\n", status
);
1279 status
= pNtAreMappedFilesTheSame( ptr
, GetModuleHandleA("kernel32.dll") );
1280 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1282 status
= pNtAreMappedFilesTheSame( ptr
, (void *)0xdeadbeef );
1283 ok( status
== STATUS_CONFLICTING_ADDRESSES
|| status
== STATUS_INVALID_ADDRESS
,
1284 "NtAreMappedFilesTheSame returned %x\n", status
);
1286 status
= pNtAreMappedFilesTheSame( ptr
, NULL
);
1287 ok( status
== STATUS_INVALID_ADDRESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1289 status
= pNtAreMappedFilesTheSame( ptr
, (void *)GetProcessHeap() );
1290 ok( status
== STATUS_CONFLICTING_ADDRESSES
, "NtAreMappedFilesTheSame returned %x\n", status
);
1292 status
= pNtAreMappedFilesTheSame( NULL
, NULL
);
1293 ok( status
== STATUS_INVALID_ADDRESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1295 ptr2
= VirtualAlloc( NULL
, 0x10000, MEM_COMMIT
, PAGE_READWRITE
);
1296 ok( ptr2
!= NULL
, "VirtualAlloc error %u\n", GetLastError() );
1297 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1298 ok( status
== STATUS_CONFLICTING_ADDRESSES
, "NtAreMappedFilesTheSame returned %x\n", status
);
1299 VirtualFree( ptr2
, 0, MEM_RELEASE
);
1301 UnmapViewOfFile( ptr
);
1302 CloseHandle( mapping
);
1303 CloseHandle( file
);
1305 status
= pNtAreMappedFilesTheSame( GetModuleHandleA("ntdll.dll"),
1306 GetModuleHandleA("kernel32.dll") );
1307 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1308 status
= pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
1309 GetModuleHandleA("kernel32.dll") );
1310 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1311 status
= pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
1312 (char *)GetModuleHandleA("kernel32.dll") + 4096 );
1313 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1315 GetSystemDirectoryA( path
, MAX_PATH
);
1316 strcat( path
, "\\kernel32.dll" );
1317 file
= CreateFileA( path
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
1318 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1320 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
1321 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1322 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
1323 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1324 status
= pNtAreMappedFilesTheSame( ptr
, GetModuleHandleA("kernel32.dll") );
1325 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
1326 UnmapViewOfFile( ptr
);
1327 CloseHandle( mapping
);
1329 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
| SEC_IMAGE
, 0, 0, NULL
);
1330 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1331 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 0 );
1332 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1333 status
= pNtAreMappedFilesTheSame( ptr
, GetModuleHandleA("kernel32.dll") );
1334 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1336 file2
= CreateFileA( path
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
1337 ok( file2
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1338 map2
= CreateFileMappingA( file2
, NULL
, PAGE_READONLY
| SEC_IMAGE
, 0, 0, NULL
);
1339 ok( map2
!= 0, "CreateFileMapping error %u\n", GetLastError() );
1340 ptr2
= MapViewOfFile( map2
, FILE_MAP_READ
, 0, 0, 0 );
1341 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
1342 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
1343 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
1344 UnmapViewOfFile( ptr2
);
1345 CloseHandle( map2
);
1346 CloseHandle( file2
);
1348 UnmapViewOfFile( ptr
);
1349 CloseHandle( mapping
);
1351 CloseHandle( file
);
1352 DeleteFileA( testfile
);
1355 static void test_CreateFileMapping(void)
1357 HANDLE handle
, handle2
, file
[3];
1358 char path
[MAX_PATH
], filename
[MAX_PATH
];
1362 static const struct { DWORD file
, flags
, error
, attrs
; } sec_flag_tests
[] =
1364 /* anonymous mapping */
1365 { 0, SEC_RESERVE
, 0 }, /* 0 */
1366 { 0, SEC_RESERVE
| SEC_NOCACHE
, 0 },
1367 { 0, SEC_RESERVE
| SEC_LARGE_PAGES
, ERROR_INVALID_PARAMETER
},
1368 { 0, SEC_RESERVE
| SEC_WRITECOMBINE
, 0 },
1369 { 0, SEC_COMMIT
, 0 },
1370 { 0, SEC_COMMIT
| SEC_NOCACHE
, 0 }, /* 5 */
1371 { 0, SEC_COMMIT
| SEC_WRITECOMBINE
, 0 },
1372 { 0, SEC_RESERVE
| SEC_COMMIT
, ERROR_INVALID_PARAMETER
},
1373 { 0, SEC_IMAGE
, ERROR_BAD_EXE_FORMAT
},
1374 { 0, SEC_IMAGE
| SEC_RESERVE
, ERROR_INVALID_PARAMETER
},
1375 { 0, SEC_IMAGE
| SEC_COMMIT
, ERROR_INVALID_PARAMETER
}, /* 10 */
1376 { 0, SEC_NOCACHE
, ERROR_INVALID_PARAMETER
},
1377 { 0, SEC_LARGE_PAGES
, ERROR_INVALID_PARAMETER
},
1378 { 0, SEC_WRITECOMBINE
, ERROR_INVALID_PARAMETER
},
1379 { 0, SEC_FILE
, ERROR_INVALID_PARAMETER
},
1380 { 0, SEC_FILE
| SEC_RESERVE
, ERROR_INVALID_PARAMETER
}, /* 15 */
1381 { 0, SEC_FILE
| SEC_COMMIT
, ERROR_INVALID_PARAMETER
},
1382 { 0, 0, 0, SEC_COMMIT
},
1384 { 1, SEC_RESERVE
, 0, SEC_FILE
},
1385 { 1, SEC_RESERVE
| SEC_NOCACHE
, 0, SEC_FILE
| SEC_NOCACHE
},
1386 { 1, SEC_RESERVE
| SEC_LARGE_PAGES
, ERROR_INVALID_PARAMETER
}, /* 20 */
1387 { 1, SEC_RESERVE
| SEC_WRITECOMBINE
, 0, SEC_FILE
| SEC_WRITECOMBINE
},
1388 { 1, SEC_COMMIT
, 0, SEC_FILE
},
1389 { 1, SEC_COMMIT
| SEC_NOCACHE
, 0, SEC_FILE
| SEC_NOCACHE
},
1390 { 1, SEC_COMMIT
| SEC_LARGE_PAGES
, ERROR_INVALID_PARAMETER
},
1391 { 1, SEC_COMMIT
| SEC_WRITECOMBINE
, 0, SEC_FILE
| SEC_WRITECOMBINE
}, /* 25 */
1392 { 1, SEC_RESERVE
| SEC_COMMIT
, ERROR_INVALID_PARAMETER
},
1393 { 1, SEC_IMAGE
, ERROR_BAD_EXE_FORMAT
},
1394 { 1, SEC_IMAGE
| SEC_RESERVE
, ERROR_INVALID_PARAMETER
},
1395 { 1, SEC_IMAGE
| SEC_COMMIT
, ERROR_INVALID_PARAMETER
},
1396 { 1, SEC_NOCACHE
, ERROR_INVALID_PARAMETER
}, /* 30 */
1397 { 1, SEC_LARGE_PAGES
, ERROR_INVALID_PARAMETER
},
1398 { 1, SEC_WRITECOMBINE
, ERROR_INVALID_PARAMETER
},
1399 { 1, SEC_FILE
, ERROR_INVALID_PARAMETER
},
1400 { 1, SEC_FILE
| SEC_RESERVE
, ERROR_INVALID_PARAMETER
},
1401 { 1, SEC_FILE
| SEC_COMMIT
, ERROR_INVALID_PARAMETER
}, /* 35 */
1402 { 1, 0, 0, SEC_FILE
},
1404 { 2, SEC_IMAGE
, 0, SEC_FILE
| SEC_IMAGE
},
1405 { 2, SEC_IMAGE
| SEC_FILE
, ERROR_INVALID_PARAMETER
},
1406 { 2, SEC_IMAGE
| SEC_NOCACHE
, 0, SEC_FILE
| SEC_IMAGE
},
1407 { 2, SEC_IMAGE
| SEC_LARGE_PAGES
, ERROR_INVALID_PARAMETER
}, /* 40 */
1408 { 2, SEC_IMAGE
| SEC_WRITECOMBINE
, ERROR_INVALID_PARAMETER
},
1409 { 2, SEC_IMAGE
| SEC_RESERVE
, ERROR_INVALID_PARAMETER
},
1410 { 2, SEC_IMAGE
| SEC_COMMIT
, ERROR_INVALID_PARAMETER
},
1413 /* test case sensitivity */
1415 SetLastError(0xdeadbeef);
1416 handle
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, SEC_COMMIT
| PAGE_READWRITE
, 0, 0x1000,
1417 "Wine Test Mapping");
1418 ok( handle
!= NULL
, "CreateFileMapping failed with error %u\n", GetLastError());
1419 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
1421 SetLastError(0xdeadbeef);
1422 handle2
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, SEC_COMMIT
| PAGE_READWRITE
, 0, 0x1000,
1423 "Wine Test Mapping");
1424 ok( handle2
!= NULL
, "CreateFileMapping failed with error %d\n", GetLastError());
1425 ok( GetLastError() == ERROR_ALREADY_EXISTS
, "wrong error %u\n", GetLastError());
1426 CloseHandle( handle2
);
1428 SetLastError(0xdeadbeef);
1429 handle2
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, SEC_COMMIT
| PAGE_READWRITE
, 0, 0x1000,
1430 "WINE TEST MAPPING");
1431 ok( handle2
!= NULL
, "CreateFileMapping failed with error %d\n", GetLastError());
1432 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
1433 CloseHandle( handle2
);
1435 SetLastError(0xdeadbeef);
1436 handle2
= OpenFileMappingA( FILE_MAP_ALL_ACCESS
, FALSE
, "Wine Test Mapping");
1437 ok( handle2
!= NULL
, "OpenFileMapping failed with error %d\n", GetLastError());
1438 CloseHandle( handle2
);
1440 SetLastError(0xdeadbeef);
1441 handle2
= OpenFileMappingA( FILE_MAP_ALL_ACCESS
, FALSE
, "WINE TEST MAPPING");
1442 ok( !handle2
, "OpenFileMapping succeeded\n");
1443 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "wrong error %u\n", GetLastError());
1445 CloseHandle( handle
);
1447 /* test SEC_* flags */
1449 file
[0] = INVALID_HANDLE_VALUE
;
1450 GetTempPathA( MAX_PATH
, path
);
1451 GetTempFileNameA( path
, "map", 0, filename
);
1453 file
[1] = CreateFileA( filename
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1454 ok( file
[1] != INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1455 SetFilePointer( file
[1], 0x2000, NULL
, FILE_BEGIN
);
1456 SetEndOfFile( file
[1] );
1458 GetSystemDirectoryA( path
, MAX_PATH
);
1459 strcat( path
, "\\kernel32.dll" );
1460 file
[2] = CreateFileA( path
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
1461 ok( file
[2] != INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1463 for (i
= 0; i
< ARRAY_SIZE(sec_flag_tests
); i
++)
1465 DWORD flags
= sec_flag_tests
[i
].flags
;
1466 DWORD perm
= sec_flag_tests
[i
].file
== 2 ? PAGE_READONLY
: PAGE_READWRITE
;
1467 SetLastError( 0xdeadbeef );
1468 handle
= CreateFileMappingA( file
[sec_flag_tests
[i
].file
], NULL
,
1469 flags
| perm
, 0, 0x1000, "Wine Test Mapping" );
1470 if (sec_flag_tests
[i
].error
)
1472 ok( !handle
, "%u: CreateFileMapping succeeded\n", i
);
1473 ok( GetLastError() == sec_flag_tests
[i
].error
, "%u: wrong error %u\n", i
, GetLastError());
1477 /* SEC_WRITECOMBINE and SEC_IMAGE_NO_EXECUTE not supported on older Windows */
1478 BOOL new_flags
= ((flags
& SEC_WRITECOMBINE
) ||
1479 ((flags
& SEC_IMAGE_NO_EXECUTE
) == SEC_IMAGE_NO_EXECUTE
));
1480 ok( handle
!= NULL
|| broken(new_flags
),
1481 "%u: CreateFileMapping failed with error %u\n", i
, GetLastError());
1482 ok( GetLastError() == 0 || broken(new_flags
&& GetLastError() == ERROR_INVALID_PARAMETER
),
1483 "%u: wrong error %u\n", i
, GetLastError());
1488 SECTION_BASIC_INFORMATION info
;
1489 DWORD expect
= sec_flag_tests
[i
].attrs
? sec_flag_tests
[i
].attrs
: sec_flag_tests
[i
].flags
;
1491 status
= pNtQuerySection( handle
, SectionBasicInformation
, &info
, sizeof(info
), NULL
);
1492 ok( !status
, "%u: NtQuerySection failed err %x\n", i
, status
);
1493 /* SEC_NOCACHE not supported on older Windows */
1494 ok( info
.Attributes
== expect
|| broken( info
.Attributes
== (expect
& ~SEC_NOCACHE
) ),
1495 "%u: NtQuerySection wrong attr %08x\n", i
, info
.Attributes
);
1496 CloseHandle( handle
);
1499 CloseHandle( file
[1] );
1500 CloseHandle( file
[2] );
1501 DeleteFileA( filename
);
1504 static void test_IsBadReadPtr(void)
1507 void *ptr
= (void *)0xdeadbeef;
1510 ret
= IsBadReadPtr(NULL
, 0);
1511 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1513 ret
= IsBadReadPtr(NULL
, 1);
1514 ok(ret
== TRUE
, "Expected IsBadReadPtr to return TRUE, got %d\n", ret
);
1516 ret
= IsBadReadPtr(ptr
, 0);
1517 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1519 ret
= IsBadReadPtr(ptr
, 1);
1520 ok(ret
== TRUE
, "Expected IsBadReadPtr to return TRUE, got %d\n", ret
);
1522 ret
= IsBadReadPtr(&stackvar
, 0);
1523 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1525 ret
= IsBadReadPtr(&stackvar
, sizeof(char));
1526 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1528 ret
= IsBadReadPtr((char *)NtCurrentTeb()->DeallocationStack
+ 4096, sizeof(DWORD
));
1529 ok(ret
== TRUE
, "Expected IsBadReadPtr to return TRUE, got %d\n", ret
);
1531 ret
= IsBadReadPtr((char *)NtCurrentTeb()->DeallocationStack
+ 4096, sizeof(DWORD
));
1532 ok(ret
== TRUE
, "Expected IsBadReadPtr to return TRUE, got %d\n", ret
);
1535 static void test_IsBadWritePtr(void)
1538 void *ptr
= (void *)0xdeadbeef;
1541 ret
= IsBadWritePtr(NULL
, 0);
1542 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1544 ret
= IsBadWritePtr(NULL
, 1);
1545 ok(ret
== TRUE
, "Expected IsBadWritePtr to return TRUE, got %d\n", ret
);
1547 ret
= IsBadWritePtr(ptr
, 0);
1548 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1550 ret
= IsBadWritePtr(ptr
, 1);
1551 ok(ret
== TRUE
, "Expected IsBadWritePtr to return TRUE, got %d\n", ret
);
1553 ret
= IsBadWritePtr(&stackval
, 0);
1554 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1556 ret
= IsBadWritePtr(&stackval
, sizeof(char));
1557 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1559 ret
= IsBadWritePtr((char *)NtCurrentTeb()->DeallocationStack
+ 4096, sizeof(DWORD
));
1560 ok(ret
== TRUE
, "Expected IsBadWritePtr to return TRUE, got %d\n", ret
);
1562 ret
= IsBadWritePtr((char *)NtCurrentTeb()->DeallocationStack
+ 4096, sizeof(DWORD
));
1563 ok(ret
== TRUE
, "Expected IsBadWritePtr to return TRUE, got %d\n", ret
);
1566 static void test_IsBadCodePtr(void)
1569 void *ptr
= (void *)0xdeadbeef;
1572 ret
= IsBadCodePtr(NULL
);
1573 ok(ret
== TRUE
, "Expected IsBadCodePtr to return TRUE, got %d\n", ret
);
1575 ret
= IsBadCodePtr(ptr
);
1576 ok(ret
== TRUE
, "Expected IsBadCodePtr to return TRUE, got %d\n", ret
);
1578 ret
= IsBadCodePtr((void *)&stackval
);
1579 ok(ret
== FALSE
, "Expected IsBadCodePtr to return FALSE, got %d\n", ret
);
1582 struct read_pipe_args
1590 static const char testdata
[] = "Hello World";
1592 static DWORD CALLBACK
read_pipe( void *arg
)
1594 struct read_pipe_args
*args
= arg
;
1596 BOOL success
= ConnectNamedPipe( args
->pipe
, NULL
);
1597 ok( success
|| GetLastError() == ERROR_PIPE_CONNECTED
,
1598 "%u: ConnectNamedPipe failed %u\n", args
->index
, GetLastError() );
1600 success
= ReadFile( args
->pipe
, args
->base
, args
->size
, &num_bytes
, NULL
);
1601 ok( success
, "%u: ReadFile failed %u\n", args
->index
, GetLastError() );
1602 ok( num_bytes
== sizeof(testdata
), "%u: wrong number of bytes read %u\n", args
->index
, num_bytes
);
1603 ok( !memcmp( args
->base
, testdata
, sizeof(testdata
)),
1604 "%u: didn't receive expected data\n", args
->index
);
1608 static void test_write_watch(void)
1610 static const char pipename
[] = "\\\\.\\pipe\\test_write_watch_pipe";
1611 DWORD ret
, size
, old_prot
, num_bytes
;
1612 MEMORY_BASIC_INFORMATION info
;
1613 HANDLE readpipe
, writepipe
, file
;
1614 OVERLAPPED overlapped
, *overlapped2
;
1619 char path
[MAX_PATH
], filename
[MAX_PATH
], *base
;
1621 if (!pGetWriteWatch
|| !pResetWriteWatch
)
1623 win_skip( "GetWriteWatch not supported\n" );
1628 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
| MEM_WRITE_WATCH
, PAGE_READWRITE
);
1630 (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_NOT_SUPPORTED
))
1632 win_skip( "MEM_WRITE_WATCH not supported\n" );
1635 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1636 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1637 ok(ret
, "VirtualQuery failed %u\n", GetLastError());
1638 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1639 ok( info
.AllocationProtect
== PAGE_READWRITE
, "wrong AllocationProtect %x\n", info
.AllocationProtect
);
1640 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1641 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
);
1646 SetLastError( 0xdeadbeef );
1647 ret
= pGetWriteWatch( 0, NULL
, size
, results
, &count
, &pagesize
);
1648 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1649 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
1650 broken( GetLastError() == 0xdeadbeef ), /* win98 */
1651 "wrong error %u\n", GetLastError() );
1653 SetLastError( 0xdeadbeef );
1654 ret
= pGetWriteWatch( 0, GetModuleHandleW(NULL
), size
, results
, &count
, &pagesize
);
1657 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1658 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1662 ok( count
== 0, "wrong count %lu\n", count
);
1665 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1666 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1667 ok( count
== 0, "wrong count %lu\n", count
);
1669 base
[pagesize
+ 1] = 0x44;
1672 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1673 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1674 ok( count
== 1, "wrong count %lu\n", count
);
1675 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1678 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1679 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1680 ok( count
== 1, "wrong count %lu\n", count
);
1681 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1684 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1685 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1686 ok( count
== 0, "wrong count %lu\n", count
);
1688 base
[2*pagesize
+ 3] = 0x11;
1689 base
[4*pagesize
+ 8] = 0x11;
1692 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1693 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1694 ok( count
== 2, "wrong count %lu\n", count
);
1695 ok( results
[0] == base
+ 2*pagesize
, "wrong result %p\n", results
[0] );
1696 ok( results
[1] == base
+ 4*pagesize
, "wrong result %p\n", results
[1] );
1699 ret
= pGetWriteWatch( 0, base
+ 3*pagesize
, 2*pagesize
, results
, &count
, &pagesize
);
1700 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1701 ok( count
== 1, "wrong count %lu\n", count
);
1702 ok( results
[0] == base
+ 4*pagesize
, "wrong result %p\n", results
[0] );
1704 ret
= pResetWriteWatch( base
, 3*pagesize
);
1705 ok( !ret
, "pResetWriteWatch failed %u\n", GetLastError() );
1708 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1709 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1710 ok( count
== 1, "wrong count %lu\n", count
);
1711 ok( results
[0] == base
+ 4*pagesize
, "wrong result %p\n", results
[0] );
1713 *(DWORD
*)(base
+ 2*pagesize
- 2) = 0xdeadbeef;
1716 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1717 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1718 ok( count
== 3, "wrong count %lu\n", count
);
1719 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1720 ok( results
[1] == base
+ 2*pagesize
, "wrong result %p\n", results
[1] );
1721 ok( results
[2] == base
+ 4*pagesize
, "wrong result %p\n", results
[2] );
1724 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1725 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1726 ok( count
== 1, "wrong count %lu\n", count
);
1727 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1730 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1731 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1732 ok( count
== 2, "wrong count %lu\n", count
);
1733 ok( results
[0] == base
+ 2*pagesize
, "wrong result %p\n", results
[0] );
1734 ok( results
[1] == base
+ 4*pagesize
, "wrong result %p\n", results
[1] );
1736 /* changing protections doesn't affect watches */
1738 ret
= VirtualProtect( base
, 3*pagesize
, PAGE_READONLY
, &old_prot
);
1739 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1740 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
1742 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1743 ok(ret
, "VirtualQuery failed %u\n", GetLastError());
1744 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1745 ok( info
.RegionSize
== 3*pagesize
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1746 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1747 ok( info
.Protect
== PAGE_READONLY
, "wrong Protect 0x%x\n", info
.Protect
);
1749 ret
= VirtualProtect( base
, 3*pagesize
, PAGE_READWRITE
, &old_prot
);
1750 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1751 ok( old_prot
== PAGE_READONLY
, "wrong old prot %x\n", old_prot
);
1754 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1755 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1756 ok( count
== 2, "wrong count %lu\n", count
);
1757 ok( results
[0] == base
+ 2*pagesize
, "wrong result %p\n", results
[0] );
1758 ok( results
[1] == base
+ 4*pagesize
, "wrong result %p\n", results
[1] );
1760 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1761 ok(ret
, "VirtualQuery failed %u\n", GetLastError());
1762 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1763 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1764 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1765 ok( info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
1767 /* ReadFile should trigger write watches */
1769 for (i
= 0; i
< 2; i
++)
1771 memset( &overlapped
, 0, sizeof(overlapped
) );
1772 overlapped
.hEvent
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
1774 readpipe
= CreateNamedPipeA( pipename
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_INBOUND
,
1775 (i
? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
) | PIPE_WAIT
, 1, 1024, 1024,
1776 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1777 ok( readpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipeA failed %u\n", GetLastError() );
1779 success
= ConnectNamedPipe( readpipe
, &overlapped
);
1780 ok( !success
, "%u: ConnectNamedPipe unexpectedly succeeded\n", i
);
1781 ok( GetLastError() == ERROR_IO_PENDING
, "%u: expected ERROR_IO_PENDING, got %u\n",
1782 i
, GetLastError() );
1784 writepipe
= CreateFileA( pipename
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1785 ok( writepipe
!= INVALID_HANDLE_VALUE
, "%u: CreateFileA failed %u\n", i
, GetLastError() );
1787 ret
= WaitForSingleObject( overlapped
.hEvent
, 1000 );
1788 ok( ret
== WAIT_OBJECT_0
, "%u: expected WAIT_OBJECT_0, got %u\n", i
, ret
);
1790 memset( base
, 0, size
);
1793 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1794 ok( !ret
, "%u: GetWriteWatch failed %u\n", i
, GetLastError() );
1795 ok( count
== 16, "%u: wrong count %lu\n", i
, count
);
1797 success
= ReadFile( readpipe
, base
, size
, NULL
, &overlapped
);
1798 ok( !success
, "%u: ReadFile unexpectedly succeeded\n", i
);
1799 ok( GetLastError() == ERROR_IO_PENDING
, "%u: expected ERROR_IO_PENDING, got %u\n",
1800 i
, GetLastError() );
1803 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1804 ok( !ret
, "%u: GetWriteWatch failed %u\n", i
, GetLastError() );
1805 ok( count
== 16, "%u: wrong count %lu\n", i
, count
);
1808 success
= WriteFile( writepipe
, testdata
, sizeof(testdata
), &num_bytes
, NULL
);
1809 ok( success
, "%u: WriteFile failed %u\n", i
, GetLastError() );
1810 ok( num_bytes
== sizeof(testdata
), "%u: wrong number of bytes written %u\n", i
, num_bytes
);
1813 success
= GetOverlappedResult( readpipe
, &overlapped
, &num_bytes
, TRUE
);
1814 ok( success
, "%u: GetOverlappedResult failed %u\n", i
, GetLastError() );
1815 ok( num_bytes
== sizeof(testdata
), "%u: wrong number of bytes read %u\n", i
, num_bytes
);
1816 ok( !memcmp( base
, testdata
, sizeof(testdata
)), "%u: didn't receive expected data\n", i
);
1819 memset( results
, 0, sizeof(results
) );
1820 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1821 ok( !ret
, "%u: GetWriteWatch failed %u\n", i
, GetLastError() );
1822 ok( count
== 1, "%u: wrong count %lu\n", i
, count
);
1823 ok( results
[0] == base
, "%u: wrong result %p\n", i
, results
[0] );
1825 CloseHandle( readpipe
);
1826 CloseHandle( writepipe
);
1827 CloseHandle( overlapped
.hEvent
);
1830 for (i
= 0; i
< 2; i
++)
1832 struct read_pipe_args args
;
1835 readpipe
= CreateNamedPipeA( pipename
, PIPE_ACCESS_INBOUND
,
1836 (i
? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
) | PIPE_WAIT
, 1, 1024, 1024,
1837 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1838 ok( readpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipeA failed %u\n", GetLastError() );
1840 memset( base
, 0, size
);
1843 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1844 ok( !ret
, "%u: GetWriteWatch failed %u\n", i
, GetLastError() );
1845 ok( count
== 16, "%u: wrong count %lu\n", i
, count
);
1847 args
.pipe
= readpipe
;
1851 thread
= CreateThread( NULL
, 0, read_pipe
, &args
, 0, NULL
);
1853 writepipe
= CreateFileA( pipename
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1854 ok( writepipe
!= INVALID_HANDLE_VALUE
, "%u: CreateFileA failed %u\n", i
, GetLastError() );
1858 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1859 ok( !ret
, "%u: GetWriteWatch failed %u\n", i
, GetLastError() );
1860 ok( count
== 16, "%u: wrong count %lu\n", i
, count
);
1863 success
= WriteFile( writepipe
, testdata
, sizeof(testdata
), &num_bytes
, NULL
);
1864 ok( success
, "%u: WriteFile failed %u\n", i
, GetLastError() );
1865 ok( num_bytes
== sizeof(testdata
), "%u: wrong number of bytes written %u\n", i
, num_bytes
);
1866 WaitForSingleObject( thread
, 10000 );
1869 memset( results
, 0, sizeof(results
) );
1870 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1871 ok( !ret
, "%u: GetWriteWatch failed %u\n", i
, GetLastError() );
1872 ok( count
== 1, "%u: wrong count %lu\n", i
, count
);
1873 ok( results
[0] == base
, "%u: wrong result %p\n", i
, results
[0] );
1875 CloseHandle( readpipe
);
1876 CloseHandle( writepipe
);
1877 CloseHandle( thread
);
1880 GetTempPathA( MAX_PATH
, path
);
1881 GetTempFileNameA( path
, "map", 0, filename
);
1882 file
= CreateFileA( filename
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1883 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
1884 SetFilePointer( file
, 2 * pagesize
+ 3, NULL
, FILE_BEGIN
);
1885 SetEndOfFile( file
);
1886 SetFilePointer( file
, 0, NULL
, FILE_BEGIN
);
1888 success
= ReadFile( file
, base
, size
, &num_bytes
, NULL
);
1889 ok( success
, "ReadFile failed %u\n", GetLastError() );
1890 ok( num_bytes
== 2 * pagesize
+ 3, "wrong bytes %u\n", num_bytes
);
1893 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1894 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1895 ok( count
== 16, "wrong count %lu\n", count
);
1897 success
= ReadFile( file
, base
, size
, &num_bytes
, NULL
);
1898 ok( success
, "ReadFile failed %u\n", GetLastError() );
1899 ok( num_bytes
== 0, "wrong bytes %u\n", num_bytes
);
1902 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1903 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1904 ok( count
== 16, "wrong count %lu\n", count
);
1906 CloseHandle( file
);
1907 DeleteFileA( filename
);
1909 success
= ReadFile( (HANDLE
)0xdead, base
, size
, &num_bytes
, NULL
);
1910 ok( !success
, "ReadFile succeeded\n" );
1911 ok( GetLastError() == ERROR_INVALID_HANDLE
, "wrong error %u\n", GetLastError() );
1914 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1915 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1916 ok( count
== 0, "wrong count %lu\n", count
);
1918 /* OVERLAPPED structure write watch */
1919 memset( &overlapped
, 0, sizeof(overlapped
) );
1920 overlapped
.hEvent
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
1922 readpipe
= CreateNamedPipeA( pipename
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_INBOUND
,
1923 PIPE_TYPE_MESSAGE
| PIPE_WAIT
, 1, 1024, 1024,
1924 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1925 ok( readpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipeA failed %u\n", GetLastError() );
1927 success
= ConnectNamedPipe( readpipe
, &overlapped
);
1928 ok( !success
, "ConnectNamedPipe unexpectedly succeeded\n" );
1929 ok( GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
1931 writepipe
= CreateFileA( pipename
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
1932 ok( writepipe
!= INVALID_HANDLE_VALUE
, "CreateFileA failed %u\n", GetLastError() );
1934 ret
= WaitForSingleObject( overlapped
.hEvent
, 1000 );
1935 ok( ret
== WAIT_OBJECT_0
, "expected WAIT_OBJECT_0, got %u\n", ret
);
1937 memset( base
, 0, size
);
1938 overlapped2
= (OVERLAPPED
*)(base
+ size
- sizeof(*overlapped2
));
1939 overlapped2
->hEvent
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
1942 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1943 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1944 ok( count
== 16, "wrong count %lu\n", count
);
1946 success
= ReadFile( readpipe
, base
, sizeof(testdata
), NULL
, overlapped2
);
1947 ok( !success
, "ReadFile unexpectedly succeeded\n" );
1948 ok( GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
1949 overlapped2
->Internal
= 0xdeadbeef;
1952 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1953 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1954 ok( count
== 2, "wrong count %lu\n", count
);
1957 success
= WriteFile( writepipe
, testdata
, sizeof(testdata
), &num_bytes
, NULL
);
1958 ok( success
, "WriteFile failed %u\n", GetLastError() );
1959 ok( num_bytes
== sizeof(testdata
), "wrong number of bytes written %u\n", num_bytes
);
1962 success
= GetOverlappedResult( readpipe
, overlapped2
, &num_bytes
, TRUE
);
1963 ok( success
, "GetOverlappedResult failed %u\n", GetLastError() );
1964 ok( num_bytes
== sizeof(testdata
), "wrong number of bytes read %u\n", num_bytes
);
1965 ok( !memcmp( base
, testdata
, sizeof(testdata
)), "didn't receive expected data\n" );
1968 memset( results
, 0, sizeof(results
) );
1969 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1970 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1971 ok( count
== 2, "wrong count %lu\n", count
);
1972 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
1974 CloseHandle( readpipe
);
1975 CloseHandle( writepipe
);
1976 CloseHandle( overlapped
.hEvent
);
1977 CloseHandle( overlapped2
->hEvent
);
1979 /* some invalid parameter tests */
1981 SetLastError( 0xdeadbeef );
1983 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1986 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1987 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1989 SetLastError( 0xdeadbeef );
1990 ret
= pGetWriteWatch( 0, base
, size
, results
, NULL
, &pagesize
);
1991 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1992 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1994 SetLastError( 0xdeadbeef );
1996 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, NULL
);
1997 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1998 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2000 SetLastError( 0xdeadbeef );
2002 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
2003 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
2004 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
2006 SetLastError( 0xdeadbeef );
2008 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
2009 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
2010 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
2012 SetLastError( 0xdeadbeef );
2014 ret
= pGetWriteWatch( 0xdeadbeef, base
, size
, results
, &count
, &pagesize
);
2015 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
2016 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
2018 SetLastError( 0xdeadbeef );
2020 ret
= pGetWriteWatch( 0, base
, 0, results
, &count
, &pagesize
);
2021 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
2022 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
2024 SetLastError( 0xdeadbeef );
2026 ret
= pGetWriteWatch( 0, base
, size
* 2, results
, &count
, &pagesize
);
2027 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
2028 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
2030 SetLastError( 0xdeadbeef );
2032 ret
= pGetWriteWatch( 0, base
+ size
- pagesize
, pagesize
+ 1, results
, &count
, &pagesize
);
2033 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
2034 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
2036 SetLastError( 0xdeadbeef );
2037 ret
= pResetWriteWatch( base
, 0 );
2038 ok( ret
== ~0u, "ResetWriteWatch succeeded %u\n", ret
);
2039 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
2041 SetLastError( 0xdeadbeef );
2042 ret
= pResetWriteWatch( GetModuleHandleW(NULL
), size
);
2043 ok( ret
== ~0u, "ResetWriteWatch succeeded %u\n", ret
);
2044 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
2046 else /* win98 is completely different */
2048 SetLastError( 0xdeadbeef );
2050 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
2051 ok( ret
== ERROR_INVALID_PARAMETER
, "GetWriteWatch succeeded %u\n", ret
);
2052 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
2055 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
2056 ok( !ret
, "GetWriteWatch failed %u\n", ret
);
2059 ret
= pGetWriteWatch( 0xdeadbeef, base
, size
, results
, &count
, &pagesize
);
2060 ok( !ret
, "GetWriteWatch failed %u\n", ret
);
2063 ret
= pGetWriteWatch( 0, base
, 0, results
, &count
, &pagesize
);
2064 ok( !ret
, "GetWriteWatch failed %u\n", ret
);
2066 ret
= pResetWriteWatch( base
, 0 );
2067 ok( !ret
, "ResetWriteWatch failed %u\n", ret
);
2069 ret
= pResetWriteWatch( GetModuleHandleW(NULL
), size
);
2070 ok( !ret
, "ResetWriteWatch failed %u\n", ret
);
2073 VirtualFree( base
, 0, MEM_RELEASE
);
2075 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_WRITE_WATCH
, PAGE_READWRITE
);
2076 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2077 VirtualFree( base
, 0, MEM_RELEASE
);
2079 base
= VirtualAlloc( 0, size
, MEM_WRITE_WATCH
, PAGE_READWRITE
);
2080 ok( !base
, "VirtualAlloc succeeded\n" );
2081 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
2083 /* initial protect doesn't matter */
2085 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_WRITE_WATCH
, PAGE_NOACCESS
);
2086 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2087 base
= VirtualAlloc( base
, size
, MEM_COMMIT
, PAGE_NOACCESS
);
2088 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2091 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
2092 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2093 ok( count
== 0, "wrong count %lu\n", count
);
2095 ret
= VirtualProtect( base
, 6*pagesize
, PAGE_READWRITE
, &old_prot
);
2096 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
2097 ok( old_prot
== PAGE_NOACCESS
, "wrong old prot %x\n", old_prot
);
2099 base
[5*pagesize
+ 200] = 3;
2101 ret
= VirtualProtect( base
, 6*pagesize
, PAGE_NOACCESS
, &old_prot
);
2102 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
2103 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
2106 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
2107 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2108 ok( count
== 1, "wrong count %lu\n", count
);
2109 ok( results
[0] == base
+ 5*pagesize
, "wrong result %p\n", results
[0] );
2111 ret
= VirtualFree( base
, size
, MEM_DECOMMIT
);
2112 ok( ret
, "VirtualFree failed %u\n", GetLastError() );
2115 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
2116 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2117 ok( count
== 1 || broken(count
== 0), /* win98 */
2118 "wrong count %lu\n", count
);
2119 if (count
) ok( results
[0] == base
+ 5*pagesize
, "wrong result %p\n", results
[0] );
2121 VirtualFree( base
, 0, MEM_RELEASE
);
2124 #if defined(__i386__) || defined(__x86_64__)
2126 static DWORD WINAPI
stack_commit_func( void *arg
)
2128 volatile char *p
= (char *)&p
;
2130 /* trigger all guard pages, to ensure that the pages are committed */
2131 while (p
>= (char *)NtCurrentTeb()->DeallocationStack
+ 4 * 0x1000)
2137 ok( arg
== (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", arg
);
2141 static void test_stack_commit(void)
2144 static const char code_call_on_stack
[] = {
2145 0x55, /* pushl %ebp */
2146 0x56, /* pushl %esi */
2147 0x89, 0xe6, /* movl %esp,%esi */
2148 0x8b, 0x4c, 0x24, 0x0c, /* movl 12(%esp),%ecx - func */
2149 0x8b, 0x54, 0x24, 0x10, /* movl 16(%esp),%edx - arg */
2150 0x8b, 0x44, 0x24, 0x14, /* movl 20(%esp),%eax - stack */
2151 0x83, 0xe0, 0xf0, /* andl $~15,%eax */
2152 0x83, 0xe8, 0x0c, /* subl $12,%eax */
2153 0x89, 0xc4, /* movl %eax,%esp */
2154 0x52, /* pushl %edx */
2155 0x31, 0xed, /* xorl %ebp,%ebp */
2156 0xff, 0xd1, /* call *%ecx */
2157 0x89, 0xf4, /* movl %esi,%esp */
2158 0x5e, /* popl %esi */
2159 0x5d, /* popl %ebp */
2160 0xc2, 0x0c, 0x00 }; /* ret $12 */
2162 static const char code_call_on_stack
[] = {
2163 0x55, /* pushq %rbp */
2164 0x48, 0x89, 0xe5, /* movq %rsp,%rbp */
2165 /* %rcx - func, %rdx - arg, %r8 - stack */
2166 0x48, 0x87, 0xca, /* xchgq %rcx,%rdx */
2167 0x49, 0x83, 0xe0, 0xf0, /* andq $~15,%r8 */
2168 0x49, 0x83, 0xe8, 0x20, /* subq $0x20,%r8 */
2169 0x4c, 0x89, 0xc4, /* movq %r8,%rsp */
2170 0xff, 0xd2, /* callq *%rdx */
2171 0x48, 0x89, 0xec, /* movq %rbp,%rsp */
2172 0x5d, /* popq %rbp */
2175 DWORD (WINAPI
*call_on_stack
)( DWORD (WINAPI
*func
)(void *), void *arg
, void *stack
);
2176 void *old_stack
, *old_stack_base
, *old_stack_limit
;
2177 void *new_stack
, *new_stack_base
;
2180 call_on_stack
= VirtualAlloc( 0, 0x1000, MEM_RESERVE
| MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
2181 ok( call_on_stack
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2182 memcpy( call_on_stack
, code_call_on_stack
, sizeof(code_call_on_stack
) );
2184 /* allocate a new stack, only the first guard page is committed */
2185 new_stack
= VirtualAlloc( 0, 0x400000, MEM_RESERVE
, PAGE_READWRITE
);
2186 ok( new_stack
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2187 new_stack_base
= (char *)new_stack
+ 0x400000;
2188 VirtualAlloc( (char *)new_stack_base
- 0x1000, 0x1000, MEM_COMMIT
, PAGE_READWRITE
| PAGE_GUARD
);
2190 old_stack
= NtCurrentTeb()->DeallocationStack
;
2191 old_stack_base
= NtCurrentTeb()->Tib
.StackBase
;
2192 old_stack_limit
= NtCurrentTeb()->Tib
.StackLimit
;
2194 NtCurrentTeb()->DeallocationStack
= new_stack
;
2195 NtCurrentTeb()->Tib
.StackBase
= new_stack_base
;
2196 NtCurrentTeb()->Tib
.StackLimit
= new_stack_base
;
2198 result
= call_on_stack( stack_commit_func
, (void *)0xdeadbeef, new_stack_base
);
2200 NtCurrentTeb()->DeallocationStack
= old_stack
;
2201 NtCurrentTeb()->Tib
.StackBase
= old_stack_base
;
2202 NtCurrentTeb()->Tib
.StackLimit
= old_stack_limit
;
2204 ok( result
== 42, "expected 42, got %u\n", result
);
2206 VirtualFree( new_stack
, 0, MEM_RELEASE
);
2207 VirtualFree( call_on_stack
, 0, MEM_RELEASE
);
2210 #endif /* defined(__i386__) || defined(__x86_64__) */
2213 static LONG num_guard_page_calls
;
2215 static DWORD
guard_page_handler( EXCEPTION_RECORD
*rec
, EXCEPTION_REGISTRATION_RECORD
*frame
,
2216 CONTEXT
*context
, EXCEPTION_REGISTRATION_RECORD
**dispatcher
)
2218 trace( "exception: %08x flags:%x addr:%p\n",
2219 rec
->ExceptionCode
, rec
->ExceptionFlags
, rec
->ExceptionAddress
);
2221 ok( rec
->NumberParameters
== 2, "NumberParameters is %d instead of 2\n", rec
->NumberParameters
);
2222 ok( rec
->ExceptionCode
== STATUS_GUARD_PAGE_VIOLATION
, "ExceptionCode is %08x instead of %08x\n",
2223 rec
->ExceptionCode
, STATUS_GUARD_PAGE_VIOLATION
);
2225 InterlockedIncrement( &num_guard_page_calls
);
2226 *(int *)rec
->ExceptionInformation
[1] += 0x100;
2228 return ExceptionContinueExecution
;
2231 static void test_guard_page(void)
2233 EXCEPTION_REGISTRATION_RECORD frame
;
2234 MEMORY_BASIC_INFORMATION info
;
2235 DWORD ret
, size
, old_prot
;
2236 int *value
, old_value
;
2244 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
, PAGE_READWRITE
| PAGE_GUARD
);
2245 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2246 value
= (int *)base
;
2248 /* verify info structure */
2249 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
2250 ok( ret
, "VirtualQuery failed %u\n", GetLastError());
2251 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
2252 ok( info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong AllocationProtect %x\n", info
.AllocationProtect
);
2253 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
2254 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
2255 ok( info
.Protect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong Protect 0x%x\n", info
.Protect
);
2256 ok( info
.Type
== MEM_PRIVATE
, "wrong Type 0x%x\n", info
.Type
);
2258 /* put some initial value into the memory */
2259 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2260 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2261 ok( old_prot
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong old prot %x\n", old_prot
);
2266 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2267 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2268 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
2270 /* test behaviour of VirtualLock - first attempt should fail */
2271 SetLastError( 0xdeadbeef );
2272 success
= VirtualLock( base
, size
);
2273 ok( !success
, "VirtualLock unexpectedly succeeded\n" );
2275 ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION
, "wrong error %u\n", GetLastError() );
2277 success
= VirtualLock( base
, size
);
2279 ok( success
, "VirtualLock failed %u\n", GetLastError() );
2282 ok( *value
== 1, "memory block contains wrong value, expected 1, got 0x%x\n", *value
);
2283 success
= VirtualUnlock( base
, size
);
2284 ok( success
, "VirtualUnlock failed %u\n", GetLastError() );
2287 /* check info structure again, PAGE_GUARD should be removed now */
2288 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
2289 ok( ret
, "VirtualQuery failed %u\n", GetLastError());
2290 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
2291 ok( info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong AllocationProtect %x\n", info
.AllocationProtect
);
2292 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
2293 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
2295 ok( info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
2296 ok( info
.Type
== MEM_PRIVATE
, "wrong Type 0x%x\n", info
.Type
);
2298 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2299 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2301 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
2303 /* test directly accessing the memory - we need to setup an exception handler first */
2304 frame
.Handler
= guard_page_handler
;
2305 frame
.Prev
= NtCurrentTeb()->Tib
.ExceptionList
;
2306 NtCurrentTeb()->Tib
.ExceptionList
= &frame
;
2308 InterlockedExchange( &num_guard_page_calls
, 0 );
2309 InterlockedExchange( &old_value
, *value
); /* exception handler increments value by 0x100 */
2311 ok( old_value
== 0x101, "memory block contains wrong value, expected 0x101, got 0x%x\n", old_value
);
2312 ok( num_guard_page_calls
== 1, "expected one callback of guard page handler, got %d calls\n", num_guard_page_calls
);
2314 NtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
2316 /* check info structure again, PAGE_GUARD should be removed now */
2317 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
2318 ok( ret
, "VirtualQuery failed %u\n", GetLastError());
2319 ok( info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
2321 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2322 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2323 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
2325 /* test accessing second integer in memory */
2326 frame
.Handler
= guard_page_handler
;
2327 frame
.Prev
= NtCurrentTeb()->Tib
.ExceptionList
;
2328 NtCurrentTeb()->Tib
.ExceptionList
= &frame
;
2330 InterlockedExchange( &num_guard_page_calls
, 0 );
2331 old_value
= *(value
+ 1);
2332 ok( old_value
== 0x102, "memory block contains wrong value, expected 0x102, got 0x%x\n", old_value
);
2333 ok( *value
== 2, "memory block contains wrong value, expected 2, got 0x%x\n", *value
);
2334 ok( num_guard_page_calls
== 1, "expected one callback of guard page handler, got %d calls\n", num_guard_page_calls
);
2336 NtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
2338 success
= VirtualLock( base
, size
);
2339 ok( success
, "VirtualLock failed %u\n", GetLastError() );
2342 ok( *value
== 2, "memory block contains wrong value, expected 2, got 0x%x\n", *value
);
2343 success
= VirtualUnlock( base
, size
);
2344 ok( success
, "VirtualUnlock failed %u\n", GetLastError() );
2347 VirtualFree( base
, 0, MEM_RELEASE
);
2349 /* combined guard page / write watch tests */
2350 if (!pGetWriteWatch
|| !pResetWriteWatch
)
2352 win_skip( "GetWriteWatch not supported, skipping combined guard page / write watch tests\n" );
2356 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
| MEM_WRITE_WATCH
, PAGE_READWRITE
| PAGE_GUARD
);
2357 if (!base
&& (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_NOT_SUPPORTED
))
2359 win_skip( "MEM_WRITE_WATCH not supported\n" );
2362 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2363 value
= (int *)base
;
2365 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
2366 ok( ret
, "VirtualQuery failed %u\n", GetLastError() );
2367 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
2368 ok( info
.AllocationProtect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong AllocationProtect %x\n", info
.AllocationProtect
);
2369 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
2370 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
2371 ok( info
.Protect
== (PAGE_READWRITE
| PAGE_GUARD
), "wrong Protect 0x%x\n", info
.Protect
);
2372 ok( info
.Type
== MEM_PRIVATE
, "wrong Type 0x%x\n", info
.Type
);
2375 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
2376 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2377 ok( count
== 0, "wrong count %lu\n", count
);
2379 /* writing to a page should trigger should trigger guard page, even if write watch is set */
2380 frame
.Handler
= guard_page_handler
;
2381 frame
.Prev
= NtCurrentTeb()->Tib
.ExceptionList
;
2382 NtCurrentTeb()->Tib
.ExceptionList
= &frame
;
2384 InterlockedExchange( &num_guard_page_calls
, 0 );
2387 ok( num_guard_page_calls
== 1, "expected one callback of guard page handler, got %d calls\n", num_guard_page_calls
);
2389 NtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
2392 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2393 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2394 ok( count
== 1, "wrong count %lu\n", count
);
2395 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
2397 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2398 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2400 /* write watch is triggered from inside of the guard page handler */
2401 frame
.Handler
= guard_page_handler
;
2402 frame
.Prev
= NtCurrentTeb()->Tib
.ExceptionList
;
2403 NtCurrentTeb()->Tib
.ExceptionList
= &frame
;
2405 InterlockedExchange( &num_guard_page_calls
, 0 );
2406 old_value
= *(value
+ 1); /* doesn't trigger write watch */
2407 ok( old_value
== 0x102, "memory block contains wrong value, expected 0x102, got 0x%x\n", old_value
);
2408 ok( *value
== 1, "memory block contains wrong value, expected 1, got 0x%x\n", *value
);
2409 ok( num_guard_page_calls
== 1, "expected one callback of guard page handler, got %d calls\n", num_guard_page_calls
);
2411 NtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
2414 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2415 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2416 ok( count
== 1, "wrong count %lu\n", count
);
2417 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
2419 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2420 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2422 /* test behaviour of VirtualLock - first attempt should fail without triggering write watches */
2423 SetLastError( 0xdeadbeef );
2424 success
= VirtualLock( base
, size
);
2425 ok( !success
, "VirtualLock unexpectedly succeeded\n" );
2427 ok( GetLastError() == STATUS_GUARD_PAGE_VIOLATION
, "wrong error %u\n", GetLastError() );
2430 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
2431 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2432 ok( count
== 0, "wrong count %lu\n", count
);
2434 success
= VirtualLock( base
, size
);
2436 ok( success
, "VirtualLock failed %u\n", GetLastError() );
2439 ok( *value
== 1, "memory block contains wrong value, expected 1, got 0x%x\n", *value
);
2440 success
= VirtualUnlock( base
, size
);
2441 ok( success
, "VirtualUnlock failed %u\n", GetLastError() );
2445 results
[0] = (void *)0xdeadbeef;
2446 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2447 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2449 ok( count
== 1 || broken(count
== 0) /* Windows 8 */, "wrong count %lu\n", count
);
2451 ok( results
[0] == base
|| broken(results
[0] == (void *)0xdeadbeef) /* Windows 8 */, "wrong result %p\n", results
[0] );
2453 VirtualFree( base
, 0, MEM_RELEASE
);
2456 static LONG num_execute_fault_calls
;
2458 static DWORD
execute_fault_seh_handler( EXCEPTION_RECORD
*rec
, EXCEPTION_REGISTRATION_RECORD
*frame
,
2459 CONTEXT
*context
, EXCEPTION_REGISTRATION_RECORD
**dispatcher
)
2461 ULONG flags
= MEM_EXECUTE_OPTION_ENABLE
;
2464 trace( "exception: %08x flags:%x addr:%p info[0]:%ld info[1]:%p\n",
2465 rec
->ExceptionCode
, rec
->ExceptionFlags
, rec
->ExceptionAddress
,
2466 rec
->ExceptionInformation
[0], (void *)rec
->ExceptionInformation
[1] );
2468 ok( rec
->NumberParameters
== 2, "NumberParameters is %d instead of 2\n", rec
->NumberParameters
);
2469 ok( rec
->ExceptionCode
== STATUS_ACCESS_VIOLATION
|| rec
->ExceptionCode
== STATUS_GUARD_PAGE_VIOLATION
,
2470 "ExceptionCode is %08x instead of STATUS_ACCESS_VIOLATION or STATUS_GUARD_PAGE_VIOLATION\n", rec
->ExceptionCode
);
2472 NtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &flags
, sizeof(flags
), NULL
);
2474 if (rec
->ExceptionCode
== STATUS_GUARD_PAGE_VIOLATION
)
2477 err
= IsProcessorFeaturePresent( PF_NX_ENABLED
) ? EXCEPTION_EXECUTE_FAULT
: EXCEPTION_READ_FAULT
;
2478 ok( rec
->ExceptionInformation
[0] == err
, "ExceptionInformation[0] is %d instead of %d\n",
2479 (DWORD
)rec
->ExceptionInformation
[0], err
);
2481 InterlockedIncrement( &num_guard_page_calls
);
2483 else if (rec
->ExceptionCode
== STATUS_ACCESS_VIOLATION
)
2488 err
= (flags
& MEM_EXECUTE_OPTION_DISABLE
) ? EXCEPTION_EXECUTE_FAULT
: EXCEPTION_READ_FAULT
;
2489 ok( rec
->ExceptionInformation
[0] == err
, "ExceptionInformation[0] is %d instead of %d\n",
2490 (DWORD
)rec
->ExceptionInformation
[0], err
);
2492 success
= VirtualProtect( (void *)rec
->ExceptionInformation
[1], 16, PAGE_EXECUTE_READWRITE
, &old_prot
);
2493 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2494 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
2496 InterlockedIncrement( &num_execute_fault_calls
);
2499 return ExceptionContinueExecution
;
2502 static LONG CALLBACK
execute_fault_vec_handler( EXCEPTION_POINTERS
*ExceptionInfo
)
2504 PEXCEPTION_RECORD rec
= ExceptionInfo
->ExceptionRecord
;
2508 trace( "exception: %08x flags:%x addr:%p info[0]:%ld info[1]:%p\n",
2509 rec
->ExceptionCode
, rec
->ExceptionFlags
, rec
->ExceptionAddress
,
2510 rec
->ExceptionInformation
[0], (void *)rec
->ExceptionInformation
[1] );
2512 ok( rec
->NumberParameters
== 2, "NumberParameters is %d instead of 2\n", rec
->NumberParameters
);
2513 ok( rec
->ExceptionCode
== STATUS_ACCESS_VIOLATION
,
2514 "ExceptionCode is %08x instead of STATUS_ACCESS_VIOLATION\n", rec
->ExceptionCode
);
2516 if (rec
->ExceptionCode
== STATUS_ACCESS_VIOLATION
)
2517 InterlockedIncrement( &num_execute_fault_calls
);
2519 if (rec
->ExceptionInformation
[0] == EXCEPTION_READ_FAULT
)
2520 return EXCEPTION_CONTINUE_SEARCH
;
2522 success
= VirtualProtect( (void *)rec
->ExceptionInformation
[1], 16, PAGE_EXECUTE_READWRITE
, &old_prot
);
2523 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2524 ok( old_prot
== PAGE_NOACCESS
, "wrong old prot %x\n", old_prot
);
2526 return EXCEPTION_CONTINUE_EXECUTION
;
2529 static inline DWORD
send_message_excpt( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2531 EXCEPTION_REGISTRATION_RECORD frame
;
2534 frame
.Handler
= execute_fault_seh_handler
;
2535 frame
.Prev
= NtCurrentTeb()->Tib
.ExceptionList
;
2536 NtCurrentTeb()->Tib
.ExceptionList
= &frame
;
2538 InterlockedExchange( &num_guard_page_calls
, 0 );
2539 InterlockedExchange( &num_execute_fault_calls
, 0 );
2540 ret
= SendMessageA( hWnd
, uMsg
, wParam
, lParam
);
2542 NtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
2547 static inline DWORD
call_proc_excpt( DWORD (CALLBACK
*code
)(void *), void *arg
)
2549 EXCEPTION_REGISTRATION_RECORD frame
;
2552 frame
.Handler
= execute_fault_seh_handler
;
2553 frame
.Prev
= NtCurrentTeb()->Tib
.ExceptionList
;
2554 NtCurrentTeb()->Tib
.ExceptionList
= &frame
;
2556 InterlockedExchange( &num_guard_page_calls
, 0 );
2557 InterlockedExchange( &num_execute_fault_calls
, 0 );
2560 NtCurrentTeb()->Tib
.ExceptionList
= frame
.Prev
;
2565 static LRESULT CALLBACK
jmp_test_func( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2567 if (uMsg
== WM_USER
)
2570 return DefWindowProcA( hWnd
, uMsg
, wParam
, lParam
);
2573 static LRESULT CALLBACK
atl_test_func( HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2575 DWORD arg
= (DWORD
)hWnd
;
2576 if (uMsg
== WM_USER
)
2577 ok( arg
== 0x11223344, "arg is 0x%08x instead of 0x11223344\n", arg
);
2579 ok( arg
!= 0x11223344, "arg is unexpectedly 0x11223344\n" );
2583 static DWORD CALLBACK
atl5_test_func( void )
2588 static void test_atl_thunk_emulation( ULONG dep_flags
)
2590 static const char code_jmp
[] = {0xE9, 0x00, 0x00, 0x00, 0x00};
2591 static const char code_atl1
[] = {0xC7, 0x44, 0x24, 0x04, 0x44, 0x33, 0x22, 0x11, 0xE9, 0x00, 0x00, 0x00, 0x00};
2592 static const char code_atl2
[] = {0xB9, 0x44, 0x33, 0x22, 0x11, 0xE9, 0x00, 0x00, 0x00, 0x00};
2593 static const char code_atl3
[] = {0xBA, 0x44, 0x33, 0x22, 0x11, 0xB9, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE1};
2594 static const char code_atl4
[] = {0xB9, 0x44, 0x33, 0x22, 0x11, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0};
2595 static const char code_atl5
[] = {0x59, 0x58, 0x51, 0xFF, 0x60, 0x04};
2596 static const char cls_name
[] = "atl_thunk_class";
2597 DWORD ret
, size
, old_prot
;
2598 ULONG old_flags
= MEM_EXECUTE_OPTION_ENABLE
;
2599 BOOL success
, restore_flags
= FALSE
;
2607 trace( "Running DEP tests with ProcessExecuteFlags = %d\n", dep_flags
);
2609 NtQueryInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &old_flags
, sizeof(old_flags
), NULL
);
2610 if (old_flags
!= dep_flags
)
2612 ret
= NtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &dep_flags
, sizeof(dep_flags
) );
2613 if (ret
== STATUS_INVALID_INFO_CLASS
/* Windows 2000 */ ||
2614 ret
== STATUS_ACCESS_DENIED
)
2616 win_skip( "Skipping DEP tests with ProcessExecuteFlags = %d\n", dep_flags
);
2619 ok( !ret
, "NtSetInformationProcess failed with status %08x\n", ret
);
2620 restore_flags
= TRUE
;
2624 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
, PAGE_READWRITE
);
2625 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2627 /* Check result of GetProcessDEPPolicy */
2628 if (!pGetProcessDEPPolicy
)
2629 win_skip( "GetProcessDEPPolicy not supported\n" );
2632 BOOL (WINAPI
*get_dep_policy
)(HANDLE
, LPDWORD
, PBOOL
) = (void *)base
;
2633 BOOL policy_permanent
= 0xdeadbeef;
2634 DWORD policy_flags
= 0xdeadbeef;
2636 /* GetProcessDEPPolicy crashes on Windows when a NULL pointer is passed.
2637 * Moreover this function has a bug on Windows 8, which has the effect that
2638 * policy_permanent is set to the content of the CL register instead of 0,
2639 * when the policy is not permanent. To detect that we use an assembler
2640 * wrapper to call the function. */
2642 memcpy( base
, code_atl2
, sizeof(code_atl2
) );
2643 *(DWORD
*)(base
+ 6) = (DWORD_PTR
)pGetProcessDEPPolicy
- (DWORD_PTR
)(base
+ 10);
2645 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2646 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2648 success
= get_dep_policy( GetCurrentProcess(), &policy_flags
, &policy_permanent
);
2649 ok( success
, "GetProcessDEPPolicy failed %u\n", GetLastError() );
2652 if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2653 ret
|= PROCESS_DEP_ENABLE
;
2654 if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
)
2655 ret
|= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION
;
2657 ok( policy_flags
== ret
, "expected policy flags %d, got %d\n", ret
, policy_flags
);
2658 ok( !policy_permanent
|| broken(policy_permanent
== 0x44),
2659 "expected policy permanent FALSE, got %d\n", policy_permanent
);
2662 memcpy( base
, code_jmp
, sizeof(code_jmp
) );
2663 *(DWORD
*)(base
+ 1) = (DWORD_PTR
)jmp_test_func
- (DWORD_PTR
)(base
+ 5);
2665 /* On Windows, the ATL Thunk emulation is only enabled while running WndProc functions,
2666 * whereas in Wine such a limitation doesn't exist yet. We want to test in a scenario
2667 * where it is active, so that application which depend on that still work properly.
2668 * We have no exception handler enabled yet, so give proper EXECUTE permissions to
2669 * prevent crashes while creating the window. */
2671 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2672 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2674 memset( &wc
, 0, sizeof(wc
) );
2675 wc
.cbSize
= sizeof(wc
);
2676 wc
.style
= CS_VREDRAW
| CS_HREDRAW
;
2677 wc
.hInstance
= GetModuleHandleA( 0 );
2678 wc
.hCursor
= LoadCursorA( NULL
, (LPCSTR
)IDC_ARROW
);
2679 wc
.hbrBackground
= NULL
;
2680 wc
.lpszClassName
= cls_name
;
2681 wc
.lpfnWndProc
= (WNDPROC
)base
;
2682 success
= RegisterClassExA(&wc
) != 0;
2683 ok( success
, "RegisterClassExA failed %u\n", GetLastError() );
2685 hWnd
= CreateWindowExA(0, cls_name
, "Test", WS_TILEDWINDOW
, 0, 0, 640, 480, 0, 0, 0, 0);
2686 ok( hWnd
!= 0, "CreateWindowExA failed %u\n", GetLastError() );
2688 ret
= SendMessageA(hWnd
, WM_USER
, 0, 0);
2689 ok( ret
== 42, "SendMessage returned unexpected result %d\n", ret
);
2691 /* At first try with an instruction which is not recognized as proper ATL thunk
2692 * by the Windows ATL Thunk Emulator. Removing execute permissions will lead to
2693 * STATUS_ACCESS_VIOLATION exceptions when DEP is enabled. */
2695 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2696 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2698 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2699 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2700 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2701 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && !IsProcessorFeaturePresent( PF_NX_ENABLED
))
2703 trace( "DEP hardware support is not available\n" );
2704 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2705 dep_flags
= MEM_EXECUTE_OPTION_ENABLE
;
2707 else if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2709 trace( "DEP hardware support is available\n" );
2710 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2713 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2715 /* Now a bit more complicated, the page containing the code is protected with
2716 * PAGE_GUARD memory protection. */
2718 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2719 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2721 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2722 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2723 ok( num_guard_page_calls
== 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2724 if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2725 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2727 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2729 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2730 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2731 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2732 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2734 /* Now test with a proper ATL thunk instruction. */
2736 memcpy( base
, code_atl1
, sizeof(code_atl1
) );
2737 *(DWORD
*)(base
+ 9) = (DWORD_PTR
)atl_test_func
- (DWORD_PTR
)(base
+ 13);
2739 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2740 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2742 ret
= SendMessageA(hWnd
, WM_USER
, 0, 0);
2743 ok( ret
== 43, "SendMessage returned unexpected result %d\n", ret
);
2745 /* Try executing with PAGE_READWRITE protection. */
2747 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2748 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2750 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2751 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2752 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2753 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2754 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2756 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2758 /* Now a bit more complicated, the page containing the code is protected with
2759 * PAGE_GUARD memory protection. */
2761 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2762 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2764 /* the same, but with PAGE_GUARD set */
2765 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2766 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2767 ok( num_guard_page_calls
== 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2768 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2769 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2771 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2773 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2774 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2775 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2776 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2778 /* The following test shows that on Windows, even a vectored exception handler
2779 * cannot intercept internal exceptions thrown by the ATL thunk emulation layer. */
2781 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && !(dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2783 if (pRtlAddVectoredExceptionHandler
&& pRtlRemoveVectoredExceptionHandler
)
2785 PVOID vectored_handler
;
2787 success
= VirtualProtect( base
, size
, PAGE_NOACCESS
, &old_prot
);
2788 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2790 vectored_handler
= pRtlAddVectoredExceptionHandler( TRUE
, &execute_fault_vec_handler
);
2791 ok( vectored_handler
!= 0, "RtlAddVectoredExceptionHandler failed\n" );
2793 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2795 pRtlRemoveVectoredExceptionHandler( vectored_handler
);
2797 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2798 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2801 win_skip( "RtlAddVectoredExceptionHandler or RtlRemoveVectoredExceptionHandler not found\n" );
2804 /* Test alternative ATL thunk instructions. */
2806 memcpy( base
, code_atl2
, sizeof(code_atl2
) );
2807 *(DWORD
*)(base
+ 6) = (DWORD_PTR
)atl_test_func
- (DWORD_PTR
)(base
+ 10);
2809 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2810 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2812 ret
= send_message_excpt( hWnd
, WM_USER
+ 1, 0, 0 );
2813 /* FIXME: we don't check the content of the register ECX yet */
2814 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2815 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2816 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2817 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2819 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2821 memcpy( base
, code_atl3
, sizeof(code_atl3
) );
2822 *(DWORD
*)(base
+ 6) = (DWORD_PTR
)atl_test_func
;
2824 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2825 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2827 ret
= send_message_excpt( hWnd
, WM_USER
+ 1, 0, 0 );
2828 /* FIXME: we don't check the content of the registers ECX/EDX yet */
2829 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2830 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2831 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2832 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2834 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2836 memcpy( base
, code_atl4
, sizeof(code_atl4
) );
2837 *(DWORD
*)(base
+ 6) = (DWORD_PTR
)atl_test_func
;
2839 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2840 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2842 ret
= send_message_excpt( hWnd
, WM_USER
+ 1, 0, 0 );
2843 /* FIXME: We don't check the content of the registers EAX/ECX yet */
2844 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
2845 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2846 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2847 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2848 else if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2849 ok( num_execute_fault_calls
== 0 || broken(num_execute_fault_calls
== 1) /* Windows XP */,
2850 "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2852 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2854 memcpy( base
, code_atl5
, sizeof(code_atl5
) );
2856 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2857 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2859 results
[1] = atl5_test_func
;
2860 ret
= call_proc_excpt( (void *)base
, results
);
2861 /* FIXME: We don't check the content of the registers EAX/ECX yet */
2862 ok( ret
== 44, "call returned wrong result, expected 44, got %d\n", ret
);
2863 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2864 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
2865 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2866 else if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2867 ok( num_execute_fault_calls
== 0 || broken(num_execute_fault_calls
== 1) /* Windows XP */,
2868 "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2870 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2872 /* Restore the JMP instruction, set to executable, and then destroy the Window */
2874 memcpy( base
, code_jmp
, sizeof(code_jmp
) );
2875 *(DWORD
*)(base
+ 1) = (DWORD_PTR
)jmp_test_func
- (DWORD_PTR
)(base
+ 5);
2877 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2878 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2880 DestroyWindow( hWnd
);
2882 success
= UnregisterClassA( cls_name
, GetModuleHandleA(0) );
2883 ok( success
, "UnregisterClass failed %u\n", GetLastError() );
2885 VirtualFree( base
, 0, MEM_RELEASE
);
2887 /* Repeat the tests from above with MEM_WRITE_WATCH protected memory. */
2889 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
| MEM_WRITE_WATCH
, PAGE_READWRITE
);
2890 if (!base
&& (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_NOT_SUPPORTED
))
2892 win_skip( "MEM_WRITE_WATCH not supported\n" );
2895 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
2898 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2899 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2900 ok( count
== 0, "wrong count %lu\n", count
);
2902 memcpy( base
, code_jmp
, sizeof(code_jmp
) );
2903 *(DWORD
*)(base
+ 1) = (DWORD_PTR
)jmp_test_func
- (DWORD_PTR
)(base
+ 5);
2906 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2907 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2908 ok( count
== 1, "wrong count %lu\n", count
);
2909 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
2911 /* Create a new window class and associated Window (see above) */
2913 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2914 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2916 memset( &wc
, 0, sizeof(wc
) );
2917 wc
.cbSize
= sizeof(wc
);
2918 wc
.style
= CS_VREDRAW
| CS_HREDRAW
;
2919 wc
.hInstance
= GetModuleHandleA( 0 );
2920 wc
.hCursor
= LoadCursorA( NULL
, (LPCSTR
)IDC_ARROW
);
2921 wc
.hbrBackground
= NULL
;
2922 wc
.lpszClassName
= cls_name
;
2923 wc
.lpfnWndProc
= (WNDPROC
)base
;
2924 success
= RegisterClassExA(&wc
) != 0;
2925 ok( success
, "RegisterClassExA failed %u\n", GetLastError() );
2927 hWnd
= CreateWindowExA(0, cls_name
, "Test", WS_TILEDWINDOW
, 0, 0, 640, 480, 0, 0, 0, 0);
2928 ok( hWnd
!= 0, "CreateWindowExA failed %u\n", GetLastError() );
2930 ret
= SendMessageA(hWnd
, WM_USER
, 0, 0);
2931 ok( ret
== 42, "SendMessage returned unexpected result %d\n", ret
);
2934 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2935 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2936 ok( count
== 0, "wrong count %lu\n", count
);
2938 /* At first try with an instruction which is not recognized as proper ATL thunk
2939 * by the Windows ATL Thunk Emulator. Removing execute permissions will lead to
2940 * STATUS_ACCESS_VIOLATION exceptions when DEP is enabled. */
2942 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
2943 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2945 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2946 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2947 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2948 if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2949 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2951 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2954 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2955 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2956 ok( count
== 0, "wrong count %lu\n", count
);
2958 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2959 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2960 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2961 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2963 /* Now a bit more complicated, the page containing the code is protected with
2964 * PAGE_GUARD memory protection. */
2966 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
2967 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
2969 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2970 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2971 ok( num_guard_page_calls
== 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2972 if (dep_flags
& MEM_EXECUTE_OPTION_DISABLE
)
2973 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2975 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2977 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
2978 ok( ret
== 42, "call returned wrong result, expected 42, got %d\n", ret
);
2979 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
2980 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
2983 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2984 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2985 ok( count
== 0 || broken(count
== 1) /* Windows 8 */, "wrong count %lu\n", count
);
2987 /* Now test with a proper ATL thunk instruction. */
2989 memcpy( base
, code_atl1
, sizeof(code_atl1
) );
2990 *(DWORD
*)(base
+ 9) = (DWORD_PTR
)atl_test_func
- (DWORD_PTR
)(base
+ 13);
2993 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
2994 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
2995 ok( count
== 1, "wrong count %lu\n", count
);
2996 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
2998 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
2999 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
3001 ret
= SendMessageA(hWnd
, WM_USER
, 0, 0);
3002 ok( ret
== 43, "SendMessage returned unexpected result %d\n", ret
);
3004 /* Try executing with PAGE_READWRITE protection. */
3006 success
= VirtualProtect( base
, size
, PAGE_READWRITE
, &old_prot
);
3007 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
3009 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
3010 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
3011 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
3012 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
3013 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
3015 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
3018 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
3019 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
3020 ok( count
== 0, "wrong count %lu\n", count
);
3022 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
3023 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
3024 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
3025 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
3027 /* Now a bit more complicated, the page containing the code is protected with
3028 * PAGE_GUARD memory protection. */
3030 success
= VirtualProtect( base
, size
, PAGE_READWRITE
| PAGE_GUARD
, &old_prot
);
3031 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
3033 /* the same, but with PAGE_GUARD set */
3034 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
3035 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
3036 ok( num_guard_page_calls
== 1, "expected one STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
3037 if ((dep_flags
& MEM_EXECUTE_OPTION_DISABLE
) && (dep_flags
& MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
))
3038 ok( num_execute_fault_calls
== 1, "expected one STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
3040 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
3042 ret
= send_message_excpt( hWnd
, WM_USER
, 0, 0 );
3043 ok( ret
== 43, "call returned wrong result, expected 43, got %d\n", ret
);
3044 ok( num_guard_page_calls
== 0, "expected no STATUS_GUARD_PAGE_VIOLATION exception, got %d exceptions\n", num_guard_page_calls
);
3045 ok( num_execute_fault_calls
== 0, "expected no STATUS_ACCESS_VIOLATION exception, got %d exceptions\n", num_execute_fault_calls
);
3048 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
3049 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
3050 ok( count
== 0 || broken(count
== 1) /* Windows 8 */, "wrong count %lu\n", count
);
3052 /* Restore the JMP instruction, set to executable, and then destroy the Window */
3054 memcpy( base
, code_jmp
, sizeof(code_jmp
) );
3055 *(DWORD
*)(base
+ 1) = (DWORD_PTR
)jmp_test_func
- (DWORD_PTR
)(base
+ 5);
3058 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
3059 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
3060 ok( count
== 1, "wrong count %lu\n", count
);
3061 ok( results
[0] == base
, "wrong result %p\n", results
[0] );
3063 success
= VirtualProtect( base
, size
, PAGE_EXECUTE_READWRITE
, &old_prot
);
3064 ok( success
, "VirtualProtect failed %u\n", GetLastError() );
3066 DestroyWindow( hWnd
);
3068 success
= UnregisterClassA( cls_name
, GetModuleHandleA(0) );
3069 ok( success
, "UnregisterClass failed %u\n", GetLastError() );
3071 VirtualFree( base
, 0, MEM_RELEASE
);
3076 ret
= NtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags
, &old_flags
, sizeof(old_flags
) );
3077 ok( !ret
, "NtSetInformationProcess failed with status %08x\n", ret
);
3081 #endif /* __i386__ */
3083 static void test_VirtualProtect(void)
3085 static const struct test_data
3087 DWORD prot_set
, prot_get
;
3090 { 0, 0 }, /* 0x00 */
3091 { PAGE_NOACCESS
, PAGE_NOACCESS
}, /* 0x01 */
3092 { PAGE_READONLY
, PAGE_READONLY
}, /* 0x02 */
3093 { PAGE_READONLY
| PAGE_NOACCESS
, 0 }, /* 0x03 */
3094 { PAGE_READWRITE
, PAGE_READWRITE
}, /* 0x04 */
3095 { PAGE_READWRITE
| PAGE_NOACCESS
, 0 }, /* 0x05 */
3096 { PAGE_READWRITE
| PAGE_READONLY
, 0 }, /* 0x06 */
3097 { PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, 0 }, /* 0x07 */
3098 { PAGE_WRITECOPY
, 0 }, /* 0x08 */
3099 { PAGE_WRITECOPY
| PAGE_NOACCESS
, 0 }, /* 0x09 */
3100 { PAGE_WRITECOPY
| PAGE_READONLY
, 0 }, /* 0x0a */
3101 { PAGE_WRITECOPY
| PAGE_NOACCESS
| PAGE_READONLY
, 0 }, /* 0x0b */
3102 { PAGE_WRITECOPY
| PAGE_READWRITE
, 0 }, /* 0x0c */
3103 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_NOACCESS
, 0 }, /* 0x0d */
3104 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
, 0 }, /* 0x0e */
3105 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, 0 }, /* 0x0f */
3107 { PAGE_EXECUTE
, PAGE_EXECUTE
}, /* 0x10 */
3108 { PAGE_EXECUTE_READ
, PAGE_EXECUTE_READ
}, /* 0x20 */
3109 { PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 }, /* 0x30 */
3110 { PAGE_EXECUTE_READWRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x40 */
3111 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, 0 }, /* 0x50 */
3112 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, 0 }, /* 0x60 */
3113 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 }, /* 0x70 */
3114 { PAGE_EXECUTE_WRITECOPY
, 0 }, /* 0x80 */
3115 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE
, 0 }, /* 0x90 */
3116 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
, 0 }, /* 0xa0 */
3117 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 }, /* 0xb0 */
3118 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
, 0 }, /* 0xc0 */
3119 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, 0 }, /* 0xd0 */
3120 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, 0 }, /* 0xe0 */
3121 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 } /* 0xf0 */
3124 DWORD ret
, old_prot
, rw_prot
, exec_prot
, i
, j
;
3125 MEMORY_BASIC_INFORMATION info
;
3130 SetLastError(0xdeadbeef);
3131 base
= VirtualAlloc(0, si
.dwPageSize
, MEM_RESERVE
| MEM_COMMIT
, PAGE_NOACCESS
);
3132 ok(base
!= NULL
, "VirtualAlloc failed %d\n", GetLastError());
3134 SetLastError(0xdeadbeef);
3135 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_READONLY
, NULL
);
3136 ok(!ret
, "VirtualProtect should fail\n");
3137 ok(GetLastError() == ERROR_NOACCESS
, "expected ERROR_NOACCESS, got %d\n", GetLastError());
3138 old_prot
= 0xdeadbeef;
3139 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
3140 ok(ret
, "VirtualProtect failed %d\n", GetLastError());
3141 ok(old_prot
== PAGE_NOACCESS
, "got %#x != expected PAGE_NOACCESS\n", old_prot
);
3144 size
= si
.dwPageSize
;
3145 status
= pNtProtectVirtualMemory(GetCurrentProcess(), &addr
, &size
, PAGE_READONLY
, NULL
);
3146 ok(status
== STATUS_ACCESS_VIOLATION
, "NtProtectVirtualMemory should fail, got %08x\n", status
);
3148 size
= si
.dwPageSize
;
3149 old_prot
= 0xdeadbeef;
3150 status
= pNtProtectVirtualMemory(GetCurrentProcess(), &addr
, &size
, PAGE_NOACCESS
, &old_prot
);
3151 ok(status
== STATUS_SUCCESS
, "NtProtectVirtualMemory should succeed, got %08x\n", status
);
3152 ok(old_prot
== PAGE_NOACCESS
, "got %#x != expected PAGE_NOACCESS\n", old_prot
);
3154 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
3156 SetLastError(0xdeadbeef);
3157 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3158 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
3159 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
3160 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
3161 ok(info
.Protect
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, info
.Protect
);
3162 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
3163 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%d: %#x != PAGE_NOACCESS\n", i
, info
.AllocationProtect
);
3164 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
3165 ok(info
.Type
== MEM_PRIVATE
, "%d: %#x != MEM_PRIVATE\n", i
, info
.Type
);
3167 old_prot
= 0xdeadbeef;
3168 SetLastError(0xdeadbeef);
3169 ret
= VirtualProtect(base
, si
.dwPageSize
, td
[i
].prot_set
, &old_prot
);
3172 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
3173 ok(old_prot
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, old_prot
);
3175 SetLastError(0xdeadbeef);
3176 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3177 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
3178 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
3179 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
3180 ok(info
.Protect
== td
[i
].prot_get
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot_get
);
3181 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
3182 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%d: %#x != PAGE_NOACCESS\n", i
, info
.AllocationProtect
);
3183 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
3184 ok(info
.Type
== MEM_PRIVATE
, "%d: %#x != MEM_PRIVATE\n", i
, info
.Type
);
3188 ok(!ret
, "%d: VirtualProtect should fail\n", i
);
3189 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
3192 old_prot
= 0xdeadbeef;
3193 SetLastError(0xdeadbeef);
3194 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
3195 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
3197 ok(old_prot
== td
[i
].prot_get
, "%d: got %#x != expected %#x\n", i
, old_prot
, td
[i
].prot_get
);
3199 ok(old_prot
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, old_prot
);
3204 for (i
= 0; i
<= 4; i
++)
3208 for (j
= 0; j
<= 4; j
++)
3210 DWORD prot
= exec_prot
| rw_prot
;
3212 SetLastError(0xdeadbeef);
3213 ptr
= VirtualAlloc(base
, si
.dwPageSize
, MEM_COMMIT
, prot
);
3214 if ((rw_prot
&& exec_prot
) || (!rw_prot
&& !exec_prot
))
3216 ok(!ptr
, "VirtualAlloc(%02x) should fail\n", prot
);
3217 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3221 if (prot
& (PAGE_WRITECOPY
| PAGE_EXECUTE_WRITECOPY
))
3223 ok(!ptr
, "VirtualAlloc(%02x) should fail\n", prot
);
3224 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3228 ok(ptr
!= NULL
, "VirtualAlloc(%02x) error %d\n", prot
, GetLastError());
3229 ok(ptr
== base
, "expected %p, got %p\n", base
, ptr
);
3233 SetLastError(0xdeadbeef);
3234 ret
= VirtualProtect(base
, si
.dwPageSize
, prot
, &old_prot
);
3235 if ((rw_prot
&& exec_prot
) || (!rw_prot
&& !exec_prot
))
3237 ok(!ret
, "VirtualProtect(%02x) should fail\n", prot
);
3238 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3242 if (prot
& (PAGE_WRITECOPY
| PAGE_EXECUTE_WRITECOPY
))
3244 ok(!ret
, "VirtualProtect(%02x) should fail\n", prot
);
3245 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3248 ok(ret
, "VirtualProtect(%02x) error %d\n", prot
, GetLastError());
3254 exec_prot
= 1 << (i
+ 4);
3257 VirtualFree(base
, 0, MEM_RELEASE
);
3260 static BOOL
is_mem_writable(DWORD prot
)
3262 switch (prot
& 0xff)
3264 case PAGE_READWRITE
:
3265 case PAGE_WRITECOPY
:
3266 case PAGE_EXECUTE_READWRITE
:
3267 case PAGE_EXECUTE_WRITECOPY
:
3275 static void test_VirtualAlloc_protection(void)
3277 static const struct test_data
3283 { 0, FALSE
}, /* 0x00 */
3284 { PAGE_NOACCESS
, TRUE
}, /* 0x01 */
3285 { PAGE_READONLY
, TRUE
}, /* 0x02 */
3286 { PAGE_READONLY
| PAGE_NOACCESS
, FALSE
}, /* 0x03 */
3287 { PAGE_READWRITE
, TRUE
}, /* 0x04 */
3288 { PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
}, /* 0x05 */
3289 { PAGE_READWRITE
| PAGE_READONLY
, FALSE
}, /* 0x06 */
3290 { PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
}, /* 0x07 */
3291 { PAGE_WRITECOPY
, FALSE
}, /* 0x08 */
3292 { PAGE_WRITECOPY
| PAGE_NOACCESS
, FALSE
}, /* 0x09 */
3293 { PAGE_WRITECOPY
| PAGE_READONLY
, FALSE
}, /* 0x0a */
3294 { PAGE_WRITECOPY
| PAGE_NOACCESS
| PAGE_READONLY
, FALSE
}, /* 0x0b */
3295 { PAGE_WRITECOPY
| PAGE_READWRITE
, FALSE
}, /* 0x0c */
3296 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
}, /* 0x0d */
3297 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
, FALSE
}, /* 0x0e */
3298 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
}, /* 0x0f */
3300 { PAGE_EXECUTE
, TRUE
}, /* 0x10 */
3301 { PAGE_EXECUTE_READ
, TRUE
}, /* 0x20 */
3302 { PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
}, /* 0x30 */
3303 { PAGE_EXECUTE_READWRITE
, TRUE
}, /* 0x40 */
3304 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
}, /* 0x50 */
3305 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
}, /* 0x60 */
3306 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
}, /* 0x70 */
3307 { PAGE_EXECUTE_WRITECOPY
, FALSE
}, /* 0x80 */
3308 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE
, FALSE
}, /* 0x90 */
3309 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
, FALSE
}, /* 0xa0 */
3310 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
}, /* 0xb0 */
3311 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
, FALSE
}, /* 0xc0 */
3312 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
}, /* 0xd0 */
3313 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
}, /* 0xe0 */
3314 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
} /* 0xf0 */
3318 MEMORY_BASIC_INFORMATION info
;
3320 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
3322 SetLastError(0xdeadbeef);
3323 base
= VirtualAlloc(0, si
.dwPageSize
, MEM_COMMIT
, td
[i
].prot
);
3327 ok(base
!= NULL
, "%d: VirtualAlloc failed %d\n", i
, GetLastError());
3329 SetLastError(0xdeadbeef);
3330 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3331 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
3332 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
3333 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
3334 ok(info
.Protect
== td
[i
].prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot
);
3335 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
3336 ok(info
.AllocationProtect
== td
[i
].prot
, "%d: %#x != %#x\n", i
, info
.AllocationProtect
, td
[i
].prot
);
3337 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
3338 ok(info
.Type
== MEM_PRIVATE
, "%d: %#x != MEM_PRIVATE\n", i
, info
.Type
);
3340 if (is_mem_writable(info
.Protect
))
3344 SetLastError(0xdeadbeef);
3345 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3346 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
3347 ok(info
.Protect
== td
[i
].prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot
);
3350 SetLastError(0xdeadbeef);
3351 ptr
= VirtualAlloc(base
, si
.dwPageSize
, MEM_COMMIT
, td
[i
].prot
);
3352 ok(ptr
== base
, "%d: VirtualAlloc failed %d\n", i
, GetLastError());
3354 VirtualFree(base
, 0, MEM_RELEASE
);
3358 ok(!base
, "%d: VirtualAlloc should fail\n", i
);
3359 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
3364 static void test_CreateFileMapping_protection(void)
3366 static const struct test_data
3370 DWORD prot_after_write
;
3373 { 0, FALSE
, 0 }, /* 0x00 */
3374 { PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x01 */
3375 { PAGE_READONLY
, TRUE
, PAGE_READONLY
}, /* 0x02 */
3376 { PAGE_READONLY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x03 */
3377 { PAGE_READWRITE
, TRUE
, PAGE_READWRITE
}, /* 0x04 */
3378 { PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x05 */
3379 { PAGE_READWRITE
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x06 */
3380 { PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x07 */
3381 { PAGE_WRITECOPY
, TRUE
, PAGE_READWRITE
}, /* 0x08 */
3382 { PAGE_WRITECOPY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x09 */
3383 { PAGE_WRITECOPY
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x0a */
3384 { PAGE_WRITECOPY
| PAGE_NOACCESS
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x0b */
3385 { PAGE_WRITECOPY
| PAGE_READWRITE
, FALSE
, PAGE_NOACCESS
}, /* 0x0c */
3386 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x0d */
3387 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x0e */
3388 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x0f */
3390 { PAGE_EXECUTE
, FALSE
, PAGE_EXECUTE
}, /* 0x10 */
3391 { PAGE_EXECUTE_READ
, TRUE
, PAGE_EXECUTE_READ
}, /* 0x20 */
3392 { PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_EXECUTE_READ
}, /* 0x30 */
3393 { PAGE_EXECUTE_READWRITE
, TRUE
, PAGE_EXECUTE_READWRITE
}, /* 0x40 */
3394 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0x50 */
3395 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
, PAGE_NOACCESS
}, /* 0x60 */
3396 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0x70 */
3397 { PAGE_EXECUTE_WRITECOPY
, TRUE
, PAGE_EXECUTE_READWRITE
}, /* 0x80 */
3398 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0x90 */
3399 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
, FALSE
, PAGE_NOACCESS
}, /* 0xa0 */
3400 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0xb0 */
3401 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
, FALSE
, PAGE_NOACCESS
}, /* 0xc0 */
3402 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0xd0 */
3403 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
, PAGE_NOACCESS
}, /* 0xe0 */
3404 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
} /* 0xf0 */
3407 DWORD ret
, i
, alloc_prot
, old_prot
;
3408 MEMORY_BASIC_INFORMATION info
;
3409 char temp_path
[MAX_PATH
];
3410 char file_name
[MAX_PATH
];
3412 BOOL page_exec_supported
= TRUE
;
3414 GetTempPathA(MAX_PATH
, temp_path
);
3415 GetTempFileNameA(temp_path
, "map", 0, file_name
);
3417 SetLastError(0xdeadbeef);
3418 hfile
= CreateFileA(file_name
, GENERIC_READ
|GENERIC_WRITE
|GENERIC_EXECUTE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3419 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile(%s) error %d\n", file_name
, GetLastError());
3420 SetFilePointer(hfile
, si
.dwPageSize
, NULL
, FILE_BEGIN
);
3421 SetEndOfFile(hfile
);
3423 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
3425 SetLastError(0xdeadbeef);
3426 hmap
= CreateFileMappingW(hfile
, NULL
, td
[i
].prot
| SEC_COMMIT
, 0, si
.dwPageSize
, NULL
);
3432 trace("%d: CreateFileMapping(%04x) failed: %d\n", i
, td
[i
].prot
, GetLastError());
3433 /* NT4 and win2k don't support EXEC on file mappings */
3434 if (td
[i
].prot
== PAGE_EXECUTE_READ
|| td
[i
].prot
== PAGE_EXECUTE_READWRITE
)
3436 page_exec_supported
= FALSE
;
3437 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE\n", i
);
3440 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
3441 if (td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
3443 page_exec_supported
= FALSE
;
3444 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE_WRITECOPY\n", i
);
3448 ok(hmap
!= 0, "%d: CreateFileMapping(%04x) error %d\n", i
, td
[i
].prot
, GetLastError());
3450 base
= MapViewOfFile(hmap
, FILE_MAP_READ
, 0, 0, 0);
3451 ok(base
!= NULL
, "%d: MapViewOfFile failed %d\n", i
, GetLastError());
3453 SetLastError(0xdeadbeef);
3454 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3455 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
3456 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
3457 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
3458 ok(info
.Protect
== PAGE_READONLY
, "%d: got %#x != expected PAGE_READONLY\n", i
, info
.Protect
);
3459 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
3460 ok(info
.AllocationProtect
== PAGE_READONLY
, "%d: %#x != PAGE_READONLY\n", i
, info
.AllocationProtect
);
3461 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
3462 ok(info
.Type
== MEM_MAPPED
, "%d: %#x != MEM_MAPPED\n", i
, info
.Type
);
3464 SetLastError(0xdeadbeef);
3465 ptr
= VirtualAlloc(base
, si
.dwPageSize
, MEM_COMMIT
, td
[i
].prot
);
3466 ok(!ptr
, "%d: VirtualAlloc(%02x) should fail\n", i
, td
[i
].prot
);
3467 ok(GetLastError() == ERROR_ACCESS_DENIED
, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i
, GetLastError());
3469 SetLastError(0xdeadbeef);
3470 ret
= VirtualProtect(base
, si
.dwPageSize
, td
[i
].prot
, &old_prot
);
3471 if (td
[i
].prot
== PAGE_READONLY
|| td
[i
].prot
== PAGE_WRITECOPY
)
3472 ok(ret
, "%d: VirtualProtect(%02x) error %d\n", i
, td
[i
].prot
, GetLastError());
3475 ok(!ret
, "%d: VirtualProtect(%02x) should fail\n", i
, td
[i
].prot
);
3476 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
3479 UnmapViewOfFile(base
);
3484 ok(!hmap
, "%d: CreateFileMapping should fail\n", i
);
3485 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
3489 if (page_exec_supported
) alloc_prot
= PAGE_EXECUTE_READWRITE
;
3490 else alloc_prot
= PAGE_READWRITE
;
3491 SetLastError(0xdeadbeef);
3492 hmap
= CreateFileMappingW(hfile
, NULL
, alloc_prot
, 0, si
.dwPageSize
, NULL
);
3493 ok(hmap
!= 0, "%d: CreateFileMapping error %d\n", i
, GetLastError());
3495 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
3497 SetLastError(0xdeadbeef);
3498 base
= MapViewOfFile(hmap
, FILE_MAP_READ
| FILE_MAP_WRITE
| (page_exec_supported
? FILE_MAP_EXECUTE
: 0), 0, 0, 0);
3499 ok(base
!= NULL
, "MapViewOfFile failed %d\n", GetLastError());
3501 old_prot
= 0xdeadbeef;
3502 SetLastError(0xdeadbeef);
3503 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
3504 ok(ret
, "VirtualProtect error %d\n", GetLastError());
3505 ok(old_prot
== alloc_prot
, "got %#x != expected %#x\n", old_prot
, alloc_prot
);
3507 SetLastError(0xdeadbeef);
3508 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3509 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
3510 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
3511 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
3512 ok(info
.Protect
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, info
.Protect
);
3513 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
3514 ok(info
.AllocationProtect
== alloc_prot
, "%d: %#x != %#x\n", i
, info
.AllocationProtect
, alloc_prot
);
3515 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
3516 ok(info
.Type
== MEM_MAPPED
, "%d: %#x != MEM_MAPPED\n", i
, info
.Type
);
3518 old_prot
= 0xdeadbeef;
3519 SetLastError(0xdeadbeef);
3520 ret
= VirtualProtect(base
, si
.dwPageSize
, td
[i
].prot
, &old_prot
);
3521 if (td
[i
].success
|| td
[i
].prot
== PAGE_NOACCESS
|| td
[i
].prot
== PAGE_EXECUTE
)
3525 /* win2k and XP don't support EXEC on file mappings */
3526 if (td
[i
].prot
== PAGE_EXECUTE
)
3528 ok(broken(!ret
), "%d: VirtualProtect doesn't support PAGE_EXECUTE\n", i
);
3531 /* NT4 and win2k don't support EXEC on file mappings */
3532 if (td
[i
].prot
== PAGE_EXECUTE_READ
|| td
[i
].prot
== PAGE_EXECUTE_READWRITE
)
3534 ok(broken(!ret
), "%d: VirtualProtect doesn't support PAGE_EXECUTE\n", i
);
3537 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
3538 if (td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
3540 ok(broken(!ret
), "%d: VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY\n", i
);
3545 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
3546 ok(old_prot
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, old_prot
);
3548 SetLastError(0xdeadbeef);
3549 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3550 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
3551 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
3552 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
3553 ok(info
.Protect
== td
[i
].prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot
);
3554 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
3555 ok(info
.AllocationProtect
== alloc_prot
, "%d: %#x != %#x\n", i
, info
.AllocationProtect
, alloc_prot
);
3556 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
3557 ok(info
.Type
== MEM_MAPPED
, "%d: %#x != MEM_MAPPED\n", i
, info
.Type
);
3559 if (is_mem_writable(info
.Protect
))
3563 SetLastError(0xdeadbeef);
3564 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3565 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
3566 /* FIXME: remove the condition below once Wine is fixed */
3567 todo_wine_if (td
[i
].prot
== PAGE_WRITECOPY
|| td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
3568 ok(info
.Protect
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot_after_write
);
3573 ok(!ret
, "%d: VirtualProtect should fail\n", i
);
3574 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
3578 old_prot
= 0xdeadbeef;
3579 SetLastError(0xdeadbeef);
3580 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
3581 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
3582 /* FIXME: remove the condition below once Wine is fixed */
3583 todo_wine_if (td
[i
].prot
== PAGE_WRITECOPY
|| td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
3584 ok(old_prot
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, old_prot
, td
[i
].prot_after_write
);
3586 UnmapViewOfFile(base
);
3592 DeleteFileA(file_name
);
3595 #define ACCESS_READ 0x01
3596 #define ACCESS_WRITE 0x02
3597 #define ACCESS_EXECUTE 0x04
3599 static DWORD
page_prot_to_access(DWORD prot
)
3604 case PAGE_WRITECOPY
:
3606 case PAGE_READWRITE
:
3607 return ACCESS_READ
| ACCESS_WRITE
;
3609 case PAGE_EXECUTE_READ
:
3610 case PAGE_EXECUTE_WRITECOPY
:
3611 return ACCESS_READ
| ACCESS_EXECUTE
;
3612 case PAGE_EXECUTE_READWRITE
:
3613 return ACCESS_READ
| ACCESS_WRITE
| ACCESS_EXECUTE
;
3619 static BOOL
is_compatible_protection(DWORD view_prot
, DWORD prot
)
3621 DWORD view_access
, prot_access
;
3623 view_access
= page_prot_to_access(view_prot
);
3624 prot_access
= page_prot_to_access(prot
);
3626 return ((view_access
& prot_access
) == prot_access
);
3629 static DWORD
map_prot_to_access(DWORD prot
)
3633 case PAGE_READWRITE
:
3634 return SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_QUERY
;
3635 case PAGE_EXECUTE_READWRITE
:
3636 return SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
| SECTION_QUERY
;
3638 case PAGE_WRITECOPY
:
3639 return SECTION_MAP_READ
| SECTION_QUERY
;
3641 case PAGE_EXECUTE_READ
:
3642 case PAGE_EXECUTE_WRITECOPY
:
3643 return SECTION_MAP_READ
| SECTION_MAP_EXECUTE
| SECTION_QUERY
;
3649 static DWORD
map_prot_no_write(DWORD prot
)
3653 case PAGE_READWRITE
: return PAGE_WRITECOPY
;
3654 case PAGE_EXECUTE_READWRITE
: return PAGE_EXECUTE_WRITECOPY
;
3655 default: return prot
;
3659 static DWORD
map_prot_written(DWORD prot
)
3663 case PAGE_WRITECOPY
: return PAGE_READWRITE
;
3664 case PAGE_EXECUTE_WRITECOPY
: return PAGE_EXECUTE_READWRITE
;
3665 default: return prot
;
3669 static DWORD
file_access_to_prot( DWORD access
)
3671 BOOL exec
= access
& FILE_MAP_EXECUTE
;
3672 access
&= ~FILE_MAP_EXECUTE
;
3674 if (access
== FILE_MAP_COPY
) return exec
? PAGE_EXECUTE_WRITECOPY
: PAGE_WRITECOPY
;
3675 if (access
& FILE_MAP_WRITE
) return exec
? PAGE_EXECUTE_READWRITE
: PAGE_READWRITE
;
3676 if (access
& FILE_MAP_READ
) return exec
? PAGE_EXECUTE_READ
: PAGE_READONLY
;
3677 return PAGE_NOACCESS
;
3680 static BOOL
is_compatible_access(DWORD map_prot
, DWORD view_prot
)
3682 DWORD access
= map_prot_to_access(map_prot
);
3683 DWORD view_access
= map_prot_to_access( file_access_to_prot( view_prot
));
3684 if (!view_access
) view_access
= SECTION_MAP_READ
;
3685 return (view_access
& access
) == view_access
;
3688 static void *map_view_of_file(HANDLE handle
, DWORD access
)
3691 LARGE_INTEGER offset
;
3696 if (!pNtMapViewOfSection
) return NULL
;
3699 offset
.u
.LowPart
= 0;
3700 offset
.u
.HighPart
= 0;
3702 protect
= file_access_to_prot( access
);
3704 status
= pNtMapViewOfSection(handle
, GetCurrentProcess(), &addr
, 0, 0, &offset
,
3705 &count
, 1 /* ViewShare */, 0, protect
);
3706 if ((int)status
< 0) addr
= NULL
;
3710 static void test_mapping( HANDLE hfile
, DWORD sec_flags
, BOOL readonly
)
3712 static const DWORD page_prot
[] =
3714 PAGE_NOACCESS
, PAGE_READONLY
, PAGE_READWRITE
, PAGE_WRITECOPY
,
3715 PAGE_EXECUTE
, PAGE_EXECUTE_READ
, PAGE_EXECUTE_READWRITE
, PAGE_EXECUTE_WRITECOPY
3722 { 0, PAGE_NOACCESS
}, /* 0x00 */
3723 { FILE_MAP_COPY
, PAGE_WRITECOPY
}, /* 0x01 */
3724 { FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x02 */
3725 { FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x03 */
3726 { FILE_MAP_READ
, PAGE_READONLY
}, /* 0x04 */
3727 { FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_READONLY
}, /* 0x05 */
3728 { FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x06 */
3729 { FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x07 */
3730 { SECTION_MAP_EXECUTE
, PAGE_NOACCESS
}, /* 0x08 */
3731 { SECTION_MAP_EXECUTE
| FILE_MAP_COPY
, PAGE_NOACCESS
}, /* 0x09 */
3732 { SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x0a */
3733 { SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x0b */
3734 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
, PAGE_READONLY
}, /* 0x0c */
3735 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_READONLY
}, /* 0x0d */
3736 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x0e */
3737 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x0f */
3738 { FILE_MAP_EXECUTE
, PAGE_NOACCESS
}, /* 0x20 */
3739 { FILE_MAP_EXECUTE
| FILE_MAP_COPY
, PAGE_EXECUTE_WRITECOPY
}, /* 0x21 */
3740 { FILE_MAP_EXECUTE
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x22 */
3741 { FILE_MAP_EXECUTE
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
}, /* 0x23 */
3742 { FILE_MAP_EXECUTE
| FILE_MAP_READ
, PAGE_EXECUTE_READ
}, /* 0x24 */
3743 { FILE_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_EXECUTE_READ
}, /* 0x25 */
3744 { FILE_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x26 */
3745 { FILE_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
}, /* 0x27 */
3746 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
, PAGE_NOACCESS
}, /* 0x28 */
3747 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_COPY
, PAGE_NOACCESS
}, /* 0x29 */
3748 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x2a */
3749 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
}, /* 0x2b */
3750 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
, PAGE_EXECUTE_READ
}, /* 0x2c */
3751 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_EXECUTE_READ
}, /* 0x2d */
3752 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x2e */
3753 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
} /* 0x2f */
3755 void *base
, *nt_base
, *ptr
;
3756 DWORD i
, j
, k
, ret
, old_prot
, prev_prot
, alloc_prot
;
3758 MEMORY_BASIC_INFORMATION info
, nt_info
;
3759 BOOL anon_mapping
= (hfile
== INVALID_HANDLE_VALUE
);
3761 trace( "testing %s mapping flags %08x %s\n", anon_mapping
? "anonymous" : "file",
3762 sec_flags
, readonly
? "readonly file" : "" );
3763 for (i
= 0; i
< ARRAY_SIZE(page_prot
); i
++)
3765 SetLastError(0xdeadbeef);
3766 hmap
= CreateFileMappingW(hfile
, NULL
, page_prot
[i
] | sec_flags
, 0, 2*si
.dwPageSize
, NULL
);
3768 if (readonly
&& (page_prot
[i
] == PAGE_READWRITE
|| page_prot
[i
] == PAGE_EXECUTE_READ
3769 || page_prot
[i
] == PAGE_EXECUTE_READWRITE
|| page_prot
[i
] == PAGE_EXECUTE_WRITECOPY
))
3771 todo_wine_if(page_prot
[i
] == PAGE_EXECUTE_READ
|| page_prot
[i
] == PAGE_EXECUTE_WRITECOPY
)
3773 ok(!hmap
, "%d: CreateFileMapping(%04x) should fail\n", i
, page_prot
[i
]);
3774 ok(GetLastError() == ERROR_ACCESS_DENIED
|| broken(GetLastError() == ERROR_INVALID_PARAMETER
),
3775 "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3777 if (hmap
) CloseHandle(hmap
);
3781 if (page_prot
[i
] == PAGE_NOACCESS
)
3785 ok(!hmap
, "CreateFileMapping(PAGE_NOACCESS) should fail\n");
3786 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3788 /* A trick to create a not accessible mapping */
3789 SetLastError(0xdeadbeef);
3790 if (sec_flags
& SEC_IMAGE
)
3791 hmap
= CreateFileMappingW(hfile
, NULL
, PAGE_WRITECOPY
| sec_flags
, 0, si
.dwPageSize
, NULL
);
3793 hmap
= CreateFileMappingW(hfile
, NULL
, PAGE_READONLY
| sec_flags
, 0, si
.dwPageSize
, NULL
);
3794 ok(hmap
!= 0, "CreateFileMapping(PAGE_READWRITE) error %d\n", GetLastError());
3795 SetLastError(0xdeadbeef);
3796 ret
= DuplicateHandle(GetCurrentProcess(), hmap
, GetCurrentProcess(), &hmap2
, 0, FALSE
, 0);
3797 ok(ret
, "DuplicateHandle error %d\n", GetLastError());
3801 if (page_prot
[i
] == PAGE_EXECUTE
)
3803 ok(!hmap
, "CreateFileMapping(PAGE_EXECUTE) should fail\n");
3804 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
3805 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3811 trace("%d: CreateFileMapping(%04x) failed: %d\n", i
, page_prot
[i
], GetLastError());
3813 if ((sec_flags
& SEC_IMAGE
) &&
3814 (page_prot
[i
] == PAGE_READWRITE
|| page_prot
[i
] == PAGE_EXECUTE_READWRITE
))
3815 continue; /* SEC_IMAGE doesn't support write access */
3817 /* NT4 and win2k don't support EXEC on file mappings */
3818 if (page_prot
[i
] == PAGE_EXECUTE_READ
|| page_prot
[i
] == PAGE_EXECUTE_READWRITE
)
3820 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE\n", i
);
3823 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
3824 if (page_prot
[i
] == PAGE_EXECUTE_WRITECOPY
)
3826 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE_WRITECOPY\n", i
);
3831 ok(hmap
!= 0, "%d: CreateFileMapping(%04x) error %d\n", i
, page_prot
[i
], GetLastError());
3833 for (j
= 0; j
< ARRAY_SIZE(view
); j
++)
3835 nt_base
= map_view_of_file(hmap
, view
[j
].access
);
3838 SetLastError(0xdeadbeef);
3839 ret
= VirtualQuery(nt_base
, &nt_info
, sizeof(nt_info
));
3840 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
3841 UnmapViewOfFile(nt_base
);
3844 SetLastError(0xdeadbeef);
3845 base
= MapViewOfFile(hmap
, view
[j
].access
, 0, 0, 0);
3847 /* Vista+ supports FILE_MAP_EXECUTE properly, earlier versions don't */
3848 ok(!nt_base
== !base
||
3849 broken((view
[j
].access
& FILE_MAP_EXECUTE
) && !nt_base
!= !base
),
3850 "%d: (%04x/%04x) NT %p kernel %p\n", j
, page_prot
[i
], view
[j
].access
, nt_base
, base
);
3852 if (!is_compatible_access(page_prot
[i
], view
[j
].access
))
3854 /* FILE_MAP_EXECUTE | FILE_MAP_COPY broken on XP */
3855 if (base
!= NULL
&& view
[j
].access
== (FILE_MAP_EXECUTE
| FILE_MAP_COPY
))
3857 ok( broken(base
!= NULL
), "%d: MapViewOfFile(%04x/%04x) should fail\n",
3858 j
, page_prot
[i
], view
[j
].access
);
3859 UnmapViewOfFile( base
);
3863 ok(!base
, "%d: MapViewOfFile(%04x/%04x) should fail\n",
3864 j
, page_prot
[i
], view
[j
].access
);
3865 ok(GetLastError() == ERROR_ACCESS_DENIED
, "wrong error %d\n", GetLastError());
3870 /* Vista+ properly supports FILE_MAP_EXECUTE, earlier versions don't */
3871 if (!base
&& (view
[j
].access
& FILE_MAP_EXECUTE
))
3873 ok(broken(!base
), "%d: MapViewOfFile(%04x/%04x) failed %d\n", j
, page_prot
[i
], view
[j
].access
, GetLastError());
3877 ok(base
!= NULL
, "%d: MapViewOfFile(%04x/%04x) failed %d\n", j
, page_prot
[i
], view
[j
].access
, GetLastError());
3879 SetLastError(0xdeadbeef);
3880 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3881 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
3882 ok(info
.BaseAddress
== base
, "%d: (%04x) got %p, expected %p\n", j
, view
[j
].access
, info
.BaseAddress
, base
);
3883 ok(info
.RegionSize
== 2*si
.dwPageSize
|| (info
.RegionSize
== si
.dwPageSize
&& (sec_flags
& SEC_IMAGE
)),
3884 "%d: (%04x) got %#lx != expected %#x\n", j
, view
[j
].access
, info
.RegionSize
, 2*si
.dwPageSize
);
3885 if (sec_flags
& SEC_IMAGE
)
3886 ok(info
.Protect
== PAGE_READONLY
,
3887 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, info
.Protect
, view
[j
].prot
);
3889 ok(info
.Protect
== view
[j
].prot
||
3890 broken(view
[j
].prot
== PAGE_EXECUTE_READ
&& info
.Protect
== PAGE_READONLY
) || /* win2k */
3891 broken(view
[j
].prot
== PAGE_EXECUTE_READWRITE
&& info
.Protect
== PAGE_READWRITE
) || /* win2k */
3892 broken(view
[j
].prot
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
3893 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, info
.Protect
, view
[j
].prot
);
3894 ok(info
.AllocationBase
== base
, "%d: (%04x) got %p, expected %p\n", j
, view
[j
].access
, info
.AllocationBase
, base
);
3895 if (sec_flags
& SEC_IMAGE
)
3896 ok(info
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
, "%d: (%04x) got %#x, expected %#x\n",
3897 j
, view
[j
].access
, info
.AllocationProtect
, info
.Protect
);
3899 ok(info
.AllocationProtect
== info
.Protect
, "%d: (%04x) got %#x, expected %#x\n",
3900 j
, view
[j
].access
, info
.AllocationProtect
, info
.Protect
);
3901 ok(info
.State
== MEM_COMMIT
, "%d: (%04x) got %#x, expected MEM_COMMIT\n", j
, view
[j
].access
, info
.State
);
3902 ok(info
.Type
== (sec_flags
& SEC_IMAGE
) ? SEC_IMAGE
: MEM_MAPPED
,
3903 "%d: (%04x) got %#x, expected MEM_MAPPED\n", j
, view
[j
].access
, info
.Type
);
3905 if (nt_base
&& base
)
3907 ok(nt_info
.RegionSize
== info
.RegionSize
, "%d: (%04x) got %#lx != expected %#lx\n", j
, view
[j
].access
, nt_info
.RegionSize
, info
.RegionSize
);
3908 ok(nt_info
.Protect
== info
.Protect
/* Vista+ */ ||
3909 broken(nt_info
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
3910 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.Protect
, info
.Protect
);
3911 ok(nt_info
.AllocationProtect
== info
.AllocationProtect
/* Vista+ */ ||
3912 broken(nt_info
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
3913 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.AllocationProtect
, info
.AllocationProtect
);
3914 ok(nt_info
.State
== info
.State
, "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.State
, info
.State
);
3915 ok(nt_info
.Type
== info
.Type
, "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.Type
, info
.Type
);
3918 prev_prot
= info
.Protect
;
3919 alloc_prot
= info
.AllocationProtect
;
3921 for (k
= 0; k
< ARRAY_SIZE(page_prot
); k
++)
3923 /*trace("map %#x, view %#x, requested prot %#x\n", page_prot[i], view[j].prot, page_prot[k]);*/
3924 DWORD actual_prot
= (sec_flags
& SEC_IMAGE
) ? map_prot_no_write(page_prot
[k
]) : page_prot
[k
];
3925 SetLastError(0xdeadbeef);
3926 old_prot
= 0xdeadbeef;
3927 ret
= VirtualProtect(base
, si
.dwPageSize
, page_prot
[k
], &old_prot
);
3928 if (is_compatible_protection(alloc_prot
, actual_prot
))
3930 /* win2k and XP don't support EXEC on file mappings */
3931 if (!ret
&& (page_prot
[k
] == PAGE_EXECUTE
|| page_prot
[k
] == PAGE_EXECUTE_WRITECOPY
|| view
[j
].prot
== PAGE_EXECUTE_WRITECOPY
))
3933 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE\n");
3937 todo_wine_if(readonly
&& page_prot
[k
] == PAGE_WRITECOPY
&& view
[j
].prot
!= PAGE_WRITECOPY
)
3938 ok(ret
, "VirtualProtect error %d, map %#x, view %#x, requested prot %#x\n", GetLastError(), page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
3939 todo_wine_if(readonly
&& page_prot
[k
] == PAGE_WRITECOPY
&& view
[j
].prot
!= PAGE_WRITECOPY
)
3940 ok(old_prot
== prev_prot
, "got %#x, expected %#x\n", old_prot
, prev_prot
);
3941 prev_prot
= actual_prot
;
3943 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3944 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
3945 todo_wine_if(readonly
&& page_prot
[k
] == PAGE_WRITECOPY
&& view
[j
].prot
!= PAGE_WRITECOPY
)
3946 ok(info
.Protect
== actual_prot
,
3947 "VirtualProtect wrong prot, map %#x, view %#x, requested prot %#x got %#x\n",
3948 page_prot
[i
], view
[j
].prot
, page_prot
[k
], info
.Protect
);
3952 ok(!ret
, "VirtualProtect should fail, map %#x, view %#x, requested prot %#x\n", page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
3953 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3957 for (k
= 0; k
< ARRAY_SIZE(page_prot
); k
++)
3959 /*trace("map %#x, view %#x, requested prot %#x\n", page_prot[i], view[j].prot, page_prot[k]);*/
3960 SetLastError(0xdeadbeef);
3961 ptr
= VirtualAlloc(base
, si
.dwPageSize
, MEM_COMMIT
, page_prot
[k
]);
3964 if (is_compatible_protection(view
[j
].prot
, page_prot
[k
]))
3966 ok(ptr
!= NULL
, "VirtualAlloc error %u, map %#x, view %#x, requested prot %#x\n",
3967 GetLastError(), page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
3971 /* versions <= Vista accept all protections without checking */
3972 ok(!ptr
|| broken(ptr
!= NULL
),
3973 "VirtualAlloc should fail, map %#x, view %#x, requested prot %#x\n",
3974 page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
3975 if (!ptr
) ok( GetLastError() == ERROR_INVALID_PARAMETER
,
3976 "wrong error %u\n", GetLastError());
3980 ret
= VirtualQuery(base
, &info
, sizeof(info
));
3981 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
3982 ok(info
.Protect
== page_prot
[k
] ||
3983 /* if the mapping doesn't have write access,
3984 * broken versions silently switch to WRITECOPY */
3985 broken( info
.Protect
== map_prot_no_write(page_prot
[k
]) ),
3986 "VirtualAlloc wrong prot, map %#x, view %#x, requested prot %#x got %#x\n",
3987 page_prot
[i
], view
[j
].prot
, page_prot
[k
], info
.Protect
);
3992 ok(!ptr
, "VirtualAlloc(%02x) should fail\n", page_prot
[k
]);
3993 ok(GetLastError() == ERROR_ACCESS_DENIED
, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
3997 if (!anon_mapping
&& is_compatible_protection(alloc_prot
, PAGE_WRITECOPY
))
3999 ret
= VirtualProtect(base
, sec_flags
& SEC_IMAGE
? si
.dwPageSize
: 2*si
.dwPageSize
, PAGE_WRITECOPY
, &old_prot
);
4000 todo_wine_if(readonly
&& view
[j
].prot
!= PAGE_WRITECOPY
)
4001 ok(ret
, "VirtualProtect error %d, map %#x, view %#x\n", GetLastError(), page_prot
[i
], view
[j
].prot
);
4002 if (ret
) *(DWORD
*)base
= 0xdeadbeef;
4003 ret
= VirtualQuery(base
, &info
, sizeof(info
));
4004 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
4006 ok(info
.Protect
== PAGE_READWRITE
, "VirtualProtect wrong prot, map %#x, view %#x got %#x\n",
4007 page_prot
[i
], view
[j
].prot
, info
.Protect
);
4008 todo_wine_if (!(sec_flags
& SEC_IMAGE
))
4009 ok(info
.RegionSize
== si
.dwPageSize
, "wrong region size %#lx after write, map %#x, view %#x got %#x\n",
4010 info
.RegionSize
, page_prot
[i
], view
[j
].prot
, info
.Protect
);
4012 prev_prot
= info
.Protect
;
4013 alloc_prot
= info
.AllocationProtect
;
4015 if (!(sec_flags
& SEC_IMAGE
))
4017 ret
= VirtualQuery((char*)base
+ si
.dwPageSize
, &info
, sizeof(info
));
4018 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
4019 todo_wine_if(readonly
&& view
[j
].prot
!= PAGE_WRITECOPY
)
4020 ok(info
.Protect
== PAGE_WRITECOPY
, "wrong prot, map %#x, view %#x got %#x\n",
4021 page_prot
[i
], view
[j
].prot
, info
.Protect
);
4024 for (k
= 0; k
< ARRAY_SIZE(page_prot
); k
++)
4026 DWORD actual_prot
= (sec_flags
& SEC_IMAGE
) ? map_prot_no_write(page_prot
[k
]) : page_prot
[k
];
4027 SetLastError(0xdeadbeef);
4028 old_prot
= 0xdeadbeef;
4029 ret
= VirtualProtect(base
, si
.dwPageSize
, page_prot
[k
], &old_prot
);
4030 if (is_compatible_protection(alloc_prot
, actual_prot
))
4032 /* win2k and XP don't support EXEC on file mappings */
4033 if (!ret
&& (page_prot
[k
] == PAGE_EXECUTE
|| page_prot
[k
] == PAGE_EXECUTE_WRITECOPY
|| view
[j
].prot
== PAGE_EXECUTE_WRITECOPY
))
4035 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE\n");
4039 todo_wine_if(readonly
&& page_prot
[k
] == PAGE_WRITECOPY
&& view
[j
].prot
!= PAGE_WRITECOPY
)
4040 ok(ret
, "VirtualProtect error %d, map %#x, view %#x, requested prot %#x\n", GetLastError(), page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
4041 todo_wine_if(readonly
&& page_prot
[k
] == PAGE_WRITECOPY
&& view
[j
].prot
!= PAGE_WRITECOPY
)
4042 ok(old_prot
== prev_prot
, "got %#x, expected %#x\n", old_prot
, prev_prot
);
4044 ret
= VirtualQuery(base
, &info
, sizeof(info
));
4045 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
4046 todo_wine_if( map_prot_written( page_prot
[k
] ) != actual_prot
)
4047 ok(info
.Protect
== map_prot_written( page_prot
[k
] ),
4048 "VirtualProtect wrong prot, map %#x, view %#x, requested prot %#x got %#x\n",
4049 page_prot
[i
], view
[j
].prot
, page_prot
[k
], info
.Protect
);
4050 prev_prot
= info
.Protect
;
4054 ok(!ret
, "VirtualProtect should fail, map %#x, view %#x, requested prot %#x\n", page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
4055 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4059 UnmapViewOfFile(base
);
4066 static void test_mappings(void)
4068 char temp_path
[MAX_PATH
];
4069 char file_name
[MAX_PATH
];
4070 DWORD data
, num_bytes
;
4073 GetTempPathA(MAX_PATH
, temp_path
);
4074 GetTempFileNameA(temp_path
, "map", 0, file_name
);
4076 hfile
= CreateFileA(file_name
, GENERIC_READ
|GENERIC_WRITE
|GENERIC_EXECUTE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
4077 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile(%s) error %d\n", file_name
, GetLastError());
4078 SetFilePointer(hfile
, 2*si
.dwPageSize
, NULL
, FILE_BEGIN
);
4079 SetEndOfFile(hfile
);
4081 test_mapping( hfile
, SEC_COMMIT
, FALSE
);
4083 /* test that file was not modified */
4084 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4085 ok(ReadFile(hfile
, &data
, sizeof(data
), &num_bytes
, NULL
), "ReadFile failed\n");
4086 ok(num_bytes
== sizeof(data
), "num_bytes = %d\n", num_bytes
);
4088 ok(!data
, "data = %x\n", data
);
4090 CloseHandle( hfile
);
4092 hfile
= CreateFileA(file_name
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4093 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile(%s) error %d\n", file_name
, GetLastError());
4095 test_mapping( hfile
, SEC_COMMIT
, TRUE
);
4097 CloseHandle( hfile
);
4098 DeleteFileA( file_name
);
4100 /* SEC_IMAGE mapping */
4101 GetSystemDirectoryA( file_name
, MAX_PATH
);
4102 strcat( file_name
, "\\kernel32.dll" );
4104 hfile
= CreateFileA( file_name
, GENERIC_READ
|GENERIC_EXECUTE
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, 0 );
4105 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile(%s) error %d\n", file_name
, GetLastError());
4107 test_mapping( hfile
, SEC_IMAGE
, FALSE
);
4109 CloseHandle( hfile
);
4111 /* now anonymous mappings */
4112 test_mapping( INVALID_HANDLE_VALUE
, SEC_COMMIT
, FALSE
);
4115 static void test_shared_memory(BOOL is_child
)
4120 SetLastError(0xdeadbef);
4121 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4096, "winetest_virtual.c");
4122 ok(mapping
!= 0, "CreateFileMapping error %d\n", GetLastError());
4124 ok(GetLastError() == ERROR_ALREADY_EXISTS
, "expected ERROR_ALREADY_EXISTS, got %d\n", GetLastError());
4126 SetLastError(0xdeadbef);
4127 p
= MapViewOfFile(mapping
, FILE_MAP_READ
|FILE_MAP_WRITE
, 0, 0, 4096);
4128 ok(p
!= NULL
, "MapViewOfFile error %d\n", GetLastError());
4132 ok(*p
== 0x1a2b3c4d, "expected 0x1a2b3c4d in child, got %#x\n", *p
);
4137 char cmdline
[MAX_PATH
];
4138 PROCESS_INFORMATION pi
;
4139 STARTUPINFOA si
= { sizeof(si
) };
4144 winetest_get_mainargs(&argv
);
4145 sprintf(cmdline
, "\"%s\" virtual sharedmem", argv
[0]);
4146 ret
= CreateProcessA(argv
[0], cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
4147 ok(ret
, "CreateProcess(%s) error %d\n", cmdline
, GetLastError());
4148 wait_child_process(pi
.hProcess
);
4149 CloseHandle(pi
.hThread
);
4150 CloseHandle(pi
.hProcess
);
4154 CloseHandle(mapping
);
4157 static void test_shared_memory_ro(BOOL is_child
, DWORD child_access
)
4162 SetLastError(0xdeadbef);
4163 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4096, "winetest_virtual.c_ro");
4164 ok(mapping
!= 0, "CreateFileMapping error %d\n", GetLastError());
4166 ok(GetLastError() == ERROR_ALREADY_EXISTS
, "expected ERROR_ALREADY_EXISTS, got %d\n", GetLastError());
4168 SetLastError(0xdeadbef);
4169 p
= MapViewOfFile(mapping
, is_child
? child_access
: FILE_MAP_READ
, 0, 0, 4096);
4170 ok(p
!= NULL
, "MapViewOfFile error %d\n", GetLastError());
4179 char cmdline
[MAX_PATH
];
4180 PROCESS_INFORMATION pi
;
4181 STARTUPINFOA si
= { sizeof(si
) };
4184 winetest_get_mainargs(&argv
);
4185 sprintf(cmdline
, "\"%s\" virtual sharedmemro %x", argv
[0], child_access
);
4186 ret
= CreateProcessA(argv
[0], cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
4187 ok(ret
, "CreateProcess(%s) error %d\n", cmdline
, GetLastError());
4188 wait_child_process(pi
.hProcess
);
4189 CloseHandle(pi
.hThread
);
4190 CloseHandle(pi
.hProcess
);
4192 if(child_access
& FILE_MAP_WRITE
)
4193 ok(*p
== 0xdeadbeef, "*p = %x, expected 0xdeadbeef\n", *p
);
4195 ok(!*p
, "*p = %x, expected 0\n", *p
);
4199 CloseHandle(mapping
);
4206 argc
= winetest_get_mainargs( &argv
);
4210 if (!strcmp(argv
[2], "sleep"))
4212 Sleep(5000); /* spawned process runs for at most 5 seconds */
4215 if (!strcmp(argv
[2], "sharedmem"))
4217 test_shared_memory(TRUE
);
4220 if (!strcmp(argv
[2], "sharedmemro"))
4222 test_shared_memory_ro(TRUE
, strtol(argv
[3], NULL
, 16));
4229 mem
= VirtualAlloc(NULL
, 1<<20, MEM_COMMIT
|MEM_RESERVE
,
4230 PAGE_EXECUTE_READWRITE
);
4231 ok(mem
!= NULL
, "VirtualAlloc failed %u\n", GetLastError());
4232 if (mem
== NULL
) break;
4233 ret
= VirtualFree(mem
, 0, MEM_RELEASE
);
4234 ok(ret
, "VirtualFree failed %u\n", GetLastError());
4240 hkernel32
= GetModuleHandleA("kernel32.dll");
4241 hntdll
= GetModuleHandleA("ntdll.dll");
4243 pGetWriteWatch
= (void *) GetProcAddress(hkernel32
, "GetWriteWatch");
4244 pResetWriteWatch
= (void *) GetProcAddress(hkernel32
, "ResetWriteWatch");
4245 pGetProcessDEPPolicy
= (void *)GetProcAddress( hkernel32
, "GetProcessDEPPolicy" );
4246 pIsWow64Process
= (void *)GetProcAddress( hkernel32
, "IsWow64Process" );
4247 pNtAreMappedFilesTheSame
= (void *)GetProcAddress( hntdll
, "NtAreMappedFilesTheSame" );
4248 pNtCreateSection
= (void *)GetProcAddress( hntdll
, "NtCreateSection" );
4249 pNtMapViewOfSection
= (void *)GetProcAddress( hntdll
, "NtMapViewOfSection" );
4250 pNtUnmapViewOfSection
= (void *)GetProcAddress( hntdll
, "NtUnmapViewOfSection" );
4251 pNtQuerySection
= (void *)GetProcAddress( hntdll
, "NtQuerySection" );
4252 pRtlAddVectoredExceptionHandler
= (void *)GetProcAddress( hntdll
, "RtlAddVectoredExceptionHandler" );
4253 pRtlRemoveVectoredExceptionHandler
= (void *)GetProcAddress( hntdll
, "RtlRemoveVectoredExceptionHandler" );
4254 pNtProtectVirtualMemory
= (void *)GetProcAddress( hntdll
, "NtProtectVirtualMemory" );
4257 trace("system page size %#x\n", si
.dwPageSize
);
4259 test_shared_memory(FALSE
);
4260 test_shared_memory_ro(FALSE
, FILE_MAP_READ
|FILE_MAP_WRITE
);
4261 test_shared_memory_ro(FALSE
, FILE_MAP_COPY
);
4262 test_shared_memory_ro(FALSE
, FILE_MAP_COPY
|FILE_MAP_WRITE
);
4264 test_CreateFileMapping_protection();
4265 test_VirtualAlloc_protection();
4266 test_VirtualProtect();
4267 test_VirtualAllocEx();
4268 test_VirtualAlloc();
4269 test_MapViewOfFile();
4270 test_NtAreMappedFilesTheSame();
4271 test_CreateFileMapping();
4272 test_IsBadReadPtr();
4273 test_IsBadWritePtr();
4274 test_IsBadCodePtr();
4276 #if defined(__i386__) || defined(__x86_64__)
4277 test_stack_commit();
4281 /* The following tests should be executed as a last step, and in exactly this
4282 * order, since ATL thunk emulation cannot be enabled anymore on Windows. */
4283 test_atl_thunk_emulation( MEM_EXECUTE_OPTION_ENABLE
);
4284 test_atl_thunk_emulation( MEM_EXECUTE_OPTION_DISABLE
);
4285 test_atl_thunk_emulation( MEM_EXECUTE_OPTION_DISABLE
| MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION
);