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
30 #include "wine/test.h"
33 #define MAPPING_SIZE 0x100000
35 static HINSTANCE hkernel32
;
36 static LPVOID (WINAPI
*pVirtualAllocEx
)(HANDLE
, LPVOID
, SIZE_T
, DWORD
, DWORD
);
37 static BOOL (WINAPI
*pVirtualFreeEx
)(HANDLE
, LPVOID
, SIZE_T
, DWORD
);
38 static UINT (WINAPI
*pGetWriteWatch
)(DWORD
,LPVOID
,SIZE_T
,LPVOID
*,ULONG_PTR
*,ULONG
*);
39 static UINT (WINAPI
*pResetWriteWatch
)(LPVOID
,SIZE_T
);
40 static NTSTATUS (WINAPI
*pNtAreMappedFilesTheSame
)(PVOID
,PVOID
);
41 static NTSTATUS (WINAPI
*pNtMapViewOfSection
)(HANDLE
, HANDLE
, PVOID
*, ULONG
, SIZE_T
, const LARGE_INTEGER
*, SIZE_T
*, ULONG
, ULONG
, ULONG
);
42 static DWORD (WINAPI
*pNtUnmapViewOfSection
)(HANDLE
, PVOID
);
44 /* ############################### */
46 static HANDLE
create_target_process(const char *arg
)
49 char cmdline
[MAX_PATH
];
50 PROCESS_INFORMATION pi
;
52 STARTUPINFO si
= { 0 };
55 winetest_get_mainargs( &argv
);
56 sprintf(cmdline
, "%s %s %s", argv
[0], argv
[1], arg
);
57 ret
= CreateProcess(NULL
, cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
58 ok(ret
, "error: %u\n", GetLastError());
59 ret
= CloseHandle(pi
.hThread
);
60 ok(ret
, "error %u\n", GetLastError());
64 static void test_VirtualAllocEx(void)
66 const unsigned int alloc_size
= 1<<15;
68 SIZE_T bytes_written
= 0, bytes_read
= 0, i
;
72 MEMORY_BASIC_INFORMATION info
;
75 /* not exported in all windows-versions */
76 if ((!pVirtualAllocEx
) || (!pVirtualFreeEx
)) {
77 win_skip("Virtual{Alloc,Free}Ex not available\n");
81 hProcess
= create_target_process("sleep");
82 ok(hProcess
!= NULL
, "Can't start process\n");
84 SetLastError(0xdeadbeef);
85 addr1
= pVirtualAllocEx(hProcess
, NULL
, alloc_size
, MEM_COMMIT
,
86 PAGE_EXECUTE_READWRITE
);
87 if (!addr1
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
89 win_skip("VirtualAllocEx not implemented\n");
90 TerminateProcess(hProcess
, 0);
91 CloseHandle(hProcess
);
95 src
= VirtualAlloc( NULL
, alloc_size
, MEM_COMMIT
, PAGE_READWRITE
);
96 dst
= VirtualAlloc( NULL
, alloc_size
, MEM_COMMIT
, PAGE_READWRITE
);
97 for (i
= 0; i
< alloc_size
; i
++)
100 ok(addr1
!= NULL
, "VirtualAllocEx error %u\n", GetLastError());
101 b
= WriteProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_written
);
102 ok(b
&& (bytes_written
== alloc_size
), "%lu bytes written\n",
104 b
= ReadProcessMemory(hProcess
, addr1
, dst
, alloc_size
, &bytes_read
);
105 ok(b
&& (bytes_read
== alloc_size
), "%lu bytes read\n", bytes_read
);
106 ok(!memcmp(src
, dst
, alloc_size
), "Data from remote process differs\n");
108 /* test invalid source buffers */
110 b
= VirtualProtect( src
+ 0x2000, 0x2000, PAGE_NOACCESS
, &old_prot
);
111 ok( b
, "VirtualProtect failed error %u\n", GetLastError() );
112 b
= WriteProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_written
);
113 ok( !b
, "WriteProcessMemory succeeded\n" );
114 ok( GetLastError() == ERROR_NOACCESS
||
115 GetLastError() == ERROR_PARTIAL_COPY
, /* vista */
116 "wrong error %u\n", GetLastError() );
117 ok( bytes_written
== 0, "%lu bytes written\n", bytes_written
);
118 b
= ReadProcessMemory(hProcess
, addr1
, src
, alloc_size
, &bytes_read
);
119 ok( !b
, "ReadProcessMemory succeeded\n" );
120 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
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
, "wrong error %u\n", GetLastError() );
134 ok( bytes_read
== 0, "%lu bytes written\n", bytes_read
);
136 b
= pVirtualFreeEx(hProcess
, addr1
, 0, MEM_RELEASE
);
137 ok(b
!= 0, "VirtualFreeEx, error %u\n", GetLastError());
139 VirtualFree( src
, 0, MEM_FREE
);
140 VirtualFree( dst
, 0, MEM_FREE
);
143 * The following tests parallel those in test_VirtualAlloc()
146 SetLastError(0xdeadbeef);
147 addr1
= pVirtualAllocEx(hProcess
, 0, 0, MEM_RESERVE
, PAGE_NOACCESS
);
148 ok(addr1
== NULL
, "VirtualAllocEx should fail on zero-sized allocation\n");
149 ok(GetLastError() == ERROR_INVALID_PARAMETER
/* NT */ ||
150 GetLastError() == ERROR_NOT_ENOUGH_MEMORY
, /* Win9x */
151 "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
153 addr1
= pVirtualAllocEx(hProcess
, 0, 0xFFFC, MEM_RESERVE
, PAGE_NOACCESS
);
154 ok(addr1
!= NULL
, "VirtualAllocEx failed\n");
156 /* test a not committed memory */
157 memset(&info
, 'q', sizeof(info
));
158 ok(VirtualQueryEx(hProcess
, addr1
, &info
, sizeof(info
)) == sizeof(info
), "VirtualQueryEx failed\n");
159 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
160 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
161 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
162 ok(info
.RegionSize
== 0x10000, "%lx != 0x10000\n", info
.RegionSize
);
163 ok(info
.State
== MEM_RESERVE
, "%x != MEM_RESERVE\n", info
.State
);
164 /* NT reports Protect == 0 for a not committed memory block */
165 ok(info
.Protect
== 0 /* NT */ ||
166 info
.Protect
== PAGE_NOACCESS
, /* Win9x */
167 "%x != PAGE_NOACCESS\n", info
.Protect
);
168 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
170 SetLastError(0xdeadbeef);
171 ok(!VirtualProtectEx(hProcess
, addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
172 "VirtualProtectEx should fail on a not committed memory\n");
173 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* NT */ ||
174 GetLastError() == ERROR_INVALID_PARAMETER
, /* Win9x */
175 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
177 addr2
= pVirtualAllocEx(hProcess
, addr1
, 0x1000, MEM_COMMIT
, PAGE_NOACCESS
);
178 ok(addr1
== addr2
, "VirtualAllocEx failed\n");
180 /* test a committed memory */
181 ok(VirtualQueryEx(hProcess
, addr1
, &info
, sizeof(info
)) == sizeof(info
),
182 "VirtualQueryEx failed\n");
183 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
184 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
185 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
186 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
187 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
188 /* this time NT reports PAGE_NOACCESS as well */
189 ok(info
.Protect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.Protect
);
190 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
192 /* this should fail, since not the whole range is committed yet */
193 SetLastError(0xdeadbeef);
194 ok(!VirtualProtectEx(hProcess
, addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
195 "VirtualProtectEx should fail on a not committed memory\n");
196 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* NT */ ||
197 GetLastError() == ERROR_INVALID_PARAMETER
, /* Win9x */
198 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
201 ok(VirtualProtectEx(hProcess
, addr1
, 0x1000, PAGE_READONLY
, &old_prot
), "VirtualProtectEx failed\n");
202 ok(old_prot
== PAGE_NOACCESS
, "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot
);
205 ok(VirtualProtectEx(hProcess
, addr1
, 0x1000, PAGE_READWRITE
, &old_prot
), "VirtualProtectEx failed\n");
206 ok(old_prot
== PAGE_READONLY
, "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot
);
208 ok(!pVirtualFreeEx(hProcess
, addr1
, 0x10000, 0),
209 "VirtualFreeEx should fail with type 0\n");
210 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
211 "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
213 ok(pVirtualFreeEx(hProcess
, addr1
, 0x10000, MEM_DECOMMIT
), "VirtualFreeEx failed\n");
215 /* if the type is MEM_RELEASE, size must be 0 */
216 ok(!pVirtualFreeEx(hProcess
, addr1
, 1, MEM_RELEASE
),
217 "VirtualFreeEx should fail\n");
218 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
219 "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
221 ok(pVirtualFreeEx(hProcess
, addr1
, 0, MEM_RELEASE
), "VirtualFreeEx failed\n");
223 TerminateProcess(hProcess
, 0);
224 CloseHandle(hProcess
);
227 static void test_VirtualAlloc(void)
231 MEMORY_BASIC_INFORMATION info
;
233 SetLastError(0xdeadbeef);
234 addr1
= VirtualAlloc(0, 0, MEM_RESERVE
, PAGE_NOACCESS
);
235 ok(addr1
== NULL
, "VirtualAlloc should fail on zero-sized allocation\n");
236 ok(GetLastError() == ERROR_INVALID_PARAMETER
/* NT */ ||
237 GetLastError() == ERROR_NOT_ENOUGH_MEMORY
, /* Win9x */
238 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
240 addr1
= VirtualAlloc(0, 0xFFFC, MEM_RESERVE
, PAGE_NOACCESS
);
241 ok(addr1
!= NULL
, "VirtualAlloc failed\n");
243 /* test a not committed memory */
244 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
245 "VirtualQuery failed\n");
246 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
247 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
248 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
249 ok(info
.RegionSize
== 0x10000, "%lx != 0x10000\n", info
.RegionSize
);
250 ok(info
.State
== MEM_RESERVE
, "%x != MEM_RESERVE\n", info
.State
);
251 /* NT reports Protect == 0 for a not committed memory block */
252 ok(info
.Protect
== 0 /* NT */ ||
253 info
.Protect
== PAGE_NOACCESS
, /* Win9x */
254 "%x != PAGE_NOACCESS\n", info
.Protect
);
255 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
257 SetLastError(0xdeadbeef);
258 ok(!VirtualProtect(addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
259 "VirtualProtect should fail on a not committed memory\n");
260 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* NT */ ||
261 GetLastError() == ERROR_INVALID_PARAMETER
, /* Win9x */
262 "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
264 addr2
= VirtualAlloc(addr1
, 0x1000, MEM_COMMIT
, PAGE_NOACCESS
);
265 ok(addr1
== addr2
, "VirtualAlloc failed\n");
267 /* test a committed memory */
268 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
269 "VirtualQuery failed\n");
270 ok(info
.BaseAddress
== addr1
, "%p != %p\n", info
.BaseAddress
, addr1
);
271 ok(info
.AllocationBase
== addr1
, "%p != %p\n", info
.AllocationBase
, addr1
);
272 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.AllocationProtect
);
273 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
274 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
275 /* this time NT reports PAGE_NOACCESS as well */
276 ok(info
.Protect
== PAGE_NOACCESS
, "%x != PAGE_NOACCESS\n", info
.Protect
);
277 ok(info
.Type
== MEM_PRIVATE
, "%x != MEM_PRIVATE\n", info
.Type
);
279 /* this should fail, since not the whole range is committed yet */
280 SetLastError(0xdeadbeef);
281 ok(!VirtualProtect(addr1
, 0xFFFC, PAGE_READONLY
, &old_prot
),
282 "VirtualProtect should fail on a not committed memory\n");
283 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* NT */ ||
284 GetLastError() == ERROR_INVALID_PARAMETER
, /* Win9x */
285 "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
287 ok(VirtualProtect(addr1
, 0x1000, PAGE_READONLY
, &old_prot
), "VirtualProtect failed\n");
288 ok(old_prot
== PAGE_NOACCESS
,
289 "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot
);
291 ok(VirtualProtect(addr1
, 0x1000, PAGE_READWRITE
, &old_prot
), "VirtualProtect failed\n");
292 ok(old_prot
== PAGE_READONLY
,
293 "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot
);
295 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
296 "VirtualQuery failed\n");
297 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
298 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
299 ok(info
.Protect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.Protect
);
300 memset( addr1
, 0x55, 20 );
301 ok( *(DWORD
*)addr1
== 0x55555555, "wrong data %x\n", *(DWORD
*)addr1
);
303 addr2
= VirtualAlloc( addr1
, 0x1000, MEM_RESET
, PAGE_NOACCESS
);
304 ok( addr2
== addr1
|| broken( !addr2
&& GetLastError() == ERROR_INVALID_PARAMETER
), /* win9x */
305 "VirtualAlloc failed err %u\n", GetLastError() );
306 ok( *(DWORD
*)addr1
== 0x55555555 || *(DWORD
*)addr1
== 0, "wrong data %x\n", *(DWORD
*)addr1
);
309 ok(VirtualQuery(addr1
, &info
, sizeof(info
)) == sizeof(info
),
310 "VirtualQuery failed\n");
311 ok(info
.RegionSize
== 0x1000, "%lx != 0x1000\n", info
.RegionSize
);
312 ok(info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
313 ok(info
.Protect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.Protect
);
315 addr2
= VirtualAlloc( (char *)addr1
+ 0x1000, 0x1000, MEM_RESET
, PAGE_NOACCESS
);
316 ok( (char *)addr2
== (char *)addr1
+ 0x1000, "VirtualAlloc failed\n" );
318 ok(VirtualQuery(addr2
, &info
, sizeof(info
)) == sizeof(info
),
319 "VirtualQuery failed\n");
320 ok(info
.RegionSize
== 0xf000, "%lx != 0xf000\n", info
.RegionSize
);
321 ok(info
.State
== MEM_RESERVE
, "%x != MEM_RESERVE\n", info
.State
);
322 ok(info
.Protect
== 0, "%x != 0\n", info
.Protect
);
324 addr2
= VirtualAlloc( (char *)addr1
+ 0xf000, 0x2000, MEM_RESET
, PAGE_NOACCESS
);
325 ok( !addr2
, "VirtualAlloc failed\n" );
326 ok( GetLastError() == ERROR_INVALID_ADDRESS
, "wrong error %u\n", GetLastError() );
329 /* invalid protection values */
330 SetLastError(0xdeadbeef);
331 addr2
= VirtualAlloc(NULL
, 0x1000, MEM_RESERVE
, 0);
332 ok(!addr2
, "VirtualAlloc succeeded\n");
333 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
335 SetLastError(0xdeadbeef);
336 addr2
= VirtualAlloc(NULL
, 0x1000, MEM_COMMIT
, 0);
337 ok(!addr2
, "VirtualAlloc succeeded\n");
338 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
340 SetLastError(0xdeadbeef);
341 addr2
= VirtualAlloc(addr1
, 0x1000, MEM_COMMIT
, PAGE_READONLY
| PAGE_EXECUTE
);
342 ok(!addr2
, "VirtualAlloc succeeded\n");
343 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
345 SetLastError(0xdeadbeef);
346 ok(!VirtualProtect(addr1
, 0x1000, PAGE_READWRITE
| PAGE_EXECUTE_WRITECOPY
, &old_prot
),
347 "VirtualProtect succeeded\n");
348 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
350 SetLastError(0xdeadbeef);
351 ok(!VirtualProtect(addr1
, 0x1000, 0, &old_prot
), "VirtualProtect succeeded\n");
352 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError());
354 SetLastError(0xdeadbeef);
355 ok(!VirtualFree(addr1
, 0x10000, 0), "VirtualFree should fail with type 0\n");
356 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
357 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
359 ok(VirtualFree(addr1
, 0x10000, MEM_DECOMMIT
), "VirtualFree failed\n");
361 /* if the type is MEM_RELEASE, size must be 0 */
362 ok(!VirtualFree(addr1
, 1, MEM_RELEASE
), "VirtualFree should fail\n");
363 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
364 "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
366 ok(VirtualFree(addr1
, 0, MEM_RELEASE
), "VirtualFree failed\n");
369 static void test_MapViewOfFile(void)
371 static const char testfile
[] = "testfile.xxx";
373 HANDLE file
, mapping
, map2
;
374 void *ptr
, *ptr2
, *addr
;
375 MEMORY_BASIC_INFORMATION info
;
378 SetLastError(0xdeadbeef);
379 file
= CreateFileA( testfile
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
380 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
381 SetFilePointer( file
, 4096, NULL
, FILE_BEGIN
);
382 SetEndOfFile( file
);
384 /* read/write mapping */
386 SetLastError(0xdeadbeef);
387 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
388 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
390 SetLastError(0xdeadbeef);
391 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
392 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAPE_READ error %u\n", GetLastError() );
393 UnmapViewOfFile( ptr
);
395 /* this fails on win9x but succeeds on NT */
396 SetLastError(0xdeadbeef);
397 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
398 if (ptr
) UnmapViewOfFile( ptr
);
399 else ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
401 SetLastError(0xdeadbeef);
402 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
403 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
404 UnmapViewOfFile( ptr
);
406 SetLastError(0xdeadbeef);
407 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
408 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
409 UnmapViewOfFile( ptr
);
411 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
,
412 FILE_MAP_READ
|FILE_MAP_WRITE
, FALSE
, 0 );
413 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
414 ptr
= MapViewOfFile( map2
, FILE_MAP_WRITE
, 0, 0, 4096 );
415 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
416 UnmapViewOfFile( ptr
);
419 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
,
420 FILE_MAP_READ
, FALSE
, 0 );
421 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
422 ptr
= MapViewOfFile( map2
, FILE_MAP_WRITE
, 0, 0, 4096 );
425 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
427 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
, 0, FALSE
, 0 );
428 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
429 ptr
= MapViewOfFile( map2
, 0, 0, 0, 4096 );
430 ok( !ptr
, "MapViewOfFile succeeded\n" );
431 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
433 ret
= DuplicateHandle( GetCurrentProcess(), mapping
, GetCurrentProcess(), &map2
,
434 FILE_MAP_READ
, FALSE
, 0 );
435 ok( ret
, "DuplicateHandle failed error %u\n", GetLastError());
436 ptr
= MapViewOfFile( map2
, 0, 0, 0, 4096 );
437 ok( ptr
!= NULL
, "MapViewOfFile NO_ACCESS error %u\n", GetLastError() );
439 else win_skip( "no access checks on win9x\n" );
441 UnmapViewOfFile( ptr
);
443 CloseHandle( mapping
);
445 /* read-only mapping */
447 SetLastError(0xdeadbeef);
448 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
449 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
451 SetLastError(0xdeadbeef);
452 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
453 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
454 UnmapViewOfFile( ptr
);
456 /* this fails on win9x but succeeds on NT */
457 SetLastError(0xdeadbeef);
458 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
459 if (ptr
) UnmapViewOfFile( ptr
);
460 else ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
462 SetLastError(0xdeadbeef);
463 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
464 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
465 UnmapViewOfFile( ptr
);
467 SetLastError(0xdeadbeef);
468 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
469 ok( !ptr
, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
470 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
471 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
472 CloseHandle( mapping
);
474 /* copy-on-write mapping */
476 SetLastError(0xdeadbeef);
477 mapping
= CreateFileMappingA( file
, NULL
, PAGE_WRITECOPY
, 0, 4096, NULL
);
478 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
480 SetLastError(0xdeadbeef);
481 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
482 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
483 UnmapViewOfFile( ptr
);
485 SetLastError(0xdeadbeef);
486 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
487 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_COPY error %u\n", GetLastError() );
488 UnmapViewOfFile( ptr
);
490 SetLastError(0xdeadbeef);
491 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
492 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
493 UnmapViewOfFile( ptr
);
495 SetLastError(0xdeadbeef);
496 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
497 ok( !ptr
, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
498 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
499 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
500 CloseHandle( mapping
);
502 /* no access mapping */
504 SetLastError(0xdeadbeef);
505 mapping
= CreateFileMappingA( file
, NULL
, PAGE_NOACCESS
, 0, 4096, NULL
);
506 /* fails on NT but succeeds on win9x */
507 if (!mapping
) ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
510 SetLastError(0xdeadbeef);
511 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
512 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
513 UnmapViewOfFile( ptr
);
515 SetLastError(0xdeadbeef);
516 ptr
= MapViewOfFile( mapping
, FILE_MAP_COPY
, 0, 0, 4096 );
517 ok( !ptr
, "MapViewOfFile FILE_MAP_COPY succeeded\n" );
518 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
520 SetLastError(0xdeadbeef);
521 ptr
= MapViewOfFile( mapping
, 0, 0, 0, 4096 );
522 ok( ptr
!= NULL
, "MapViewOfFile 0 error %u\n", GetLastError() );
523 UnmapViewOfFile( ptr
);
525 SetLastError(0xdeadbeef);
526 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 4096 );
527 ok( !ptr
, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
528 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "Wrong error %d\n", GetLastError() );
530 CloseHandle( mapping
);
535 /* now try read-only file */
537 SetLastError(0xdeadbeef);
538 file
= CreateFileA( testfile
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0 );
539 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
541 SetLastError(0xdeadbeef);
542 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
543 ok( !mapping
, "CreateFileMapping PAGE_READWRITE succeeded\n" );
544 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
545 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
547 SetLastError(0xdeadbeef);
548 mapping
= CreateFileMappingA( file
, NULL
, PAGE_WRITECOPY
, 0, 4096, NULL
);
549 ok( mapping
!= 0, "CreateFileMapping PAGE_WRITECOPY error %u\n", GetLastError() );
550 CloseHandle( mapping
);
552 SetLastError(0xdeadbeef);
553 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
554 ok( mapping
!= 0, "CreateFileMapping PAGE_READONLY error %u\n", GetLastError() );
555 CloseHandle( mapping
);
558 /* now try no access file */
560 SetLastError(0xdeadbeef);
561 file
= CreateFileA( testfile
, 0, 0, NULL
, OPEN_EXISTING
, 0, 0 );
562 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
564 SetLastError(0xdeadbeef);
565 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
566 ok( !mapping
, "CreateFileMapping PAGE_READWRITE succeeded\n" );
567 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
568 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
570 SetLastError(0xdeadbeef);
571 mapping
= CreateFileMappingA( file
, NULL
, PAGE_WRITECOPY
, 0, 4096, NULL
);
572 ok( !mapping
, "CreateFileMapping PAGE_WRITECOPY succeeded\n" );
573 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
574 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
576 SetLastError(0xdeadbeef);
577 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
578 ok( !mapping
, "CreateFileMapping PAGE_READONLY succeeded\n" );
579 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
580 GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
583 DeleteFileA( testfile
);
585 SetLastError(0xdeadbeef);
587 file
= CreateFileMapping( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4096, name
);
588 /* nt4 doesn't have Local\\ */
589 if (!file
&& GetLastError() == ERROR_PATH_NOT_FOUND
)
592 file
= CreateFileMapping( INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 4096, name
);
594 ok( file
!= 0, "CreateFileMapping PAGE_READWRITE error %u\n", GetLastError() );
596 SetLastError(0xdeadbeef);
597 mapping
= OpenFileMapping( FILE_MAP_READ
, FALSE
, name
);
598 ok( mapping
!= 0, "OpenFileMapping FILE_MAP_READ error %u\n", GetLastError() );
599 SetLastError(0xdeadbeef);
600 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 0 );
604 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
605 SetLastError(0xdeadbeef);
606 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 0 );
607 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
608 SetLastError(0xdeadbeef);
609 size
= VirtualQuery( ptr
, &info
, sizeof(info
) );
610 ok( size
== sizeof(info
),
611 "VirtualQuery error %u\n", GetLastError() );
612 ok( info
.BaseAddress
== ptr
, "%p != %p\n", info
.BaseAddress
, ptr
);
613 ok( info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
614 ok( info
.AllocationProtect
== PAGE_READONLY
, "%x != PAGE_READONLY\n", info
.AllocationProtect
);
615 ok( info
.RegionSize
== 4096, "%lx != 4096\n", info
.RegionSize
);
616 ok( info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
617 ok( info
.Protect
== PAGE_READONLY
, "%x != PAGE_READONLY\n", info
.Protect
);
619 else win_skip( "no access checks on win9x\n" );
620 UnmapViewOfFile( ptr
);
621 CloseHandle( mapping
);
623 SetLastError(0xdeadbeef);
624 mapping
= OpenFileMapping( FILE_MAP_WRITE
, FALSE
, name
);
625 ok( mapping
!= 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() );
626 SetLastError(0xdeadbeef);
627 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 0 );
631 ok( GetLastError() == ERROR_ACCESS_DENIED
, "Wrong error %d\n", GetLastError() );
632 SetLastError(0xdeadbeef);
633 ptr
= MapViewOfFile( mapping
, FILE_MAP_WRITE
, 0, 0, 0 );
634 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
635 SetLastError(0xdeadbeef);
636 size
= VirtualQuery( ptr
, &info
, sizeof(info
) );
637 ok( size
== sizeof(info
),
638 "VirtualQuery error %u\n", GetLastError() );
639 ok( info
.BaseAddress
== ptr
, "%p != %p\n", info
.BaseAddress
, ptr
);
640 ok( info
.AllocationBase
== ptr
, "%p != %p\n", info
.AllocationBase
, ptr
);
641 ok( info
.AllocationProtect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.AllocationProtect
);
642 ok( info
.RegionSize
== 4096, "%lx != 4096\n", info
.RegionSize
);
643 ok( info
.State
== MEM_COMMIT
, "%x != MEM_COMMIT\n", info
.State
);
644 ok( info
.Protect
== PAGE_READWRITE
, "%x != PAGE_READWRITE\n", info
.Protect
);
646 else win_skip( "no access checks on win9x\n" );
647 UnmapViewOfFile( ptr
);
648 CloseHandle( mapping
);
652 /* read/write mapping with SEC_RESERVE */
653 mapping
= CreateFileMappingA(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
| SEC_RESERVE
, 0, MAPPING_SIZE
, NULL
);
654 ok(mapping
!= INVALID_HANDLE_VALUE
, "CreateFileMappingA failed with error %d\n", GetLastError());
656 ptr
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
657 ok(ptr
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError());
659 ptr2
= MapViewOfFile(mapping
, FILE_MAP_WRITE
, 0, 0, 0);
660 /* on NT ptr != ptr2 but on Win9x ptr == ptr2 */
661 ok(ptr2
!= NULL
, "MapViewOfFile failed with error %d\n", GetLastError());
662 trace("mapping same section resulted in views %p and %p\n", ptr
, ptr2
);
664 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
665 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
666 ok(info
.BaseAddress
== ptr
, "BaseAddress should have been %p but was %p instead\n", ptr
, info
.BaseAddress
);
667 ok(info
.AllocationBase
== ptr
, "AllocationBase should have been %p but was %p instead\n", ptr
, info
.AllocationBase
);
668 ok(info
.RegionSize
== MAPPING_SIZE
, "RegionSize should have been 0x%x but was 0x%x\n", MAPPING_SIZE
, (unsigned int)info
.RegionSize
);
669 ok(info
.State
== MEM_RESERVE
, "State should have been MEM_RESERVE instead of 0x%x\n", info
.State
);
670 if (info
.Type
== MEM_PRIVATE
) /* win9x is different for uncommitted mappings */
672 ok(info
.AllocationProtect
== PAGE_NOACCESS
,
673 "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info
.AllocationProtect
);
674 ok(info
.Protect
== PAGE_NOACCESS
,
675 "Protect should have been PAGE_NOACCESS instead of 0x%x\n", info
.Protect
);
679 ok(info
.AllocationProtect
== PAGE_READWRITE
,
680 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
681 ok(info
.Protect
== 0, "Protect should have been 0 instead of 0x%x\n", info
.Protect
);
682 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
687 ret
= VirtualQuery(ptr2
, &info
, sizeof(info
));
688 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
689 ok(info
.BaseAddress
== ptr2
,
690 "BaseAddress should have been %p but was %p instead\n", ptr2
, info
.BaseAddress
);
691 ok(info
.AllocationBase
== ptr2
,
692 "AllocationBase should have been %p but was %p instead\n", ptr2
, info
.AllocationBase
);
693 ok(info
.AllocationProtect
== PAGE_READWRITE
,
694 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
695 ok(info
.RegionSize
== MAPPING_SIZE
,
696 "RegionSize should have been 0x%x but was 0x%x\n", MAPPING_SIZE
, (unsigned int)info
.RegionSize
);
697 ok(info
.State
== MEM_RESERVE
,
698 "State should have been MEM_RESERVE instead of 0x%x\n", info
.State
);
699 ok(info
.Protect
== 0,
700 "Protect should have been 0 instead of 0x%x\n", info
.Protect
);
701 ok(info
.Type
== MEM_MAPPED
,
702 "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
705 ptr
= VirtualAlloc(ptr
, 0x10000, MEM_COMMIT
, PAGE_READONLY
);
706 ok(ptr
!= NULL
, "VirtualAlloc failed with error %d\n", GetLastError());
708 ret
= VirtualQuery(ptr
, &info
, sizeof(info
));
709 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
710 ok(info
.BaseAddress
== ptr
, "BaseAddress should have been %p but was %p instead\n", ptr
, info
.BaseAddress
);
711 ok(info
.AllocationBase
== ptr
, "AllocationBase should have been %p but was %p instead\n", ptr
, info
.AllocationBase
);
712 ok(info
.RegionSize
== 0x10000, "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info
.RegionSize
);
713 ok(info
.State
== MEM_COMMIT
, "State should have been MEM_RESERVE instead of 0x%x\n", info
.State
);
714 ok(info
.Protect
== PAGE_READONLY
, "Protect should have been 0 instead of 0x%x\n", info
.Protect
);
715 if (info
.Type
== MEM_PRIVATE
) /* win9x is different for uncommitted mappings */
717 ok(info
.AllocationProtect
== PAGE_NOACCESS
,
718 "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info
.AllocationProtect
);
722 ok(info
.AllocationProtect
== PAGE_READWRITE
,
723 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
724 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
727 /* shows that the VirtualAlloc above affects the mapping, not just the
728 * virtual memory in this process - it also affects all other processes
729 * with a view of the mapping, but that isn't tested here */
732 ret
= VirtualQuery(ptr2
, &info
, sizeof(info
));
733 ok(ret
, "VirtualQuery failed with error %d\n", GetLastError());
734 ok(info
.BaseAddress
== ptr2
,
735 "BaseAddress should have been %p but was %p instead\n", ptr2
, info
.BaseAddress
);
736 ok(info
.AllocationBase
== ptr2
,
737 "AllocationBase should have been %p but was %p instead\n", ptr2
, info
.AllocationBase
);
738 ok(info
.AllocationProtect
== PAGE_READWRITE
,
739 "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info
.AllocationProtect
);
740 ok(info
.RegionSize
== 0x10000,
741 "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info
.RegionSize
);
742 ok(info
.State
== MEM_COMMIT
,
743 "State should have been MEM_RESERVE instead of 0x%x\n", info
.State
);
744 ok(info
.Protect
== PAGE_READWRITE
,
745 "Protect should have been 0 instead of 0x%x\n", info
.Protect
);
746 ok(info
.Type
== MEM_MAPPED
, "Type should have been MEM_MAPPED instead of 0x%x\n", info
.Type
);
749 addr
= VirtualAlloc( ptr
, MAPPING_SIZE
, MEM_RESET
, PAGE_READONLY
);
750 ok( addr
== ptr
|| broken(!addr
&& GetLastError() == ERROR_INVALID_PARAMETER
), /* win9x */
751 "VirtualAlloc failed with error %u\n", GetLastError() );
753 ret
= VirtualFree( ptr
, 0x10000, MEM_DECOMMIT
);
754 ok( !ret
|| broken(ret
) /* win9x */, "VirtualFree succeeded\n" );
756 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "VirtualFree failed with %u\n", GetLastError() );
758 ret
= UnmapViewOfFile(ptr2
);
759 ok(ret
, "UnmapViewOfFile failed with error %d\n", GetLastError());
760 ret
= UnmapViewOfFile(ptr
);
761 ok(ret
, "UnmapViewOfFile failed with error %d\n", GetLastError());
762 CloseHandle(mapping
);
764 addr
= VirtualAlloc(NULL
, 0x10000, MEM_COMMIT
, PAGE_READONLY
);
765 ok( addr
!= NULL
, "VirtualAlloc failed with error %u\n", GetLastError() );
767 SetLastError(0xdeadbeef);
768 ok( !UnmapViewOfFile(addr
), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
769 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
770 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
771 SetLastError(0xdeadbeef);
772 ok( !UnmapViewOfFile((char *)addr
+ 0x3000), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
773 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
774 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
775 SetLastError(0xdeadbeef);
776 ok( !UnmapViewOfFile((void *)0xdeadbeef), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
777 ok( GetLastError() == ERROR_INVALID_ADDRESS
,
778 "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
780 ok( VirtualFree(addr
, 0, MEM_RELEASE
), "VirtualFree failed\n" );
783 static void test_NtMapViewOfSection(void)
787 static const char testfile
[] = "testfile.xxx";
788 static const char data
[] = "test data for NtMapViewOfSection";
789 char buffer
[sizeof(data
)];
790 HANDLE file
, mapping
;
793 DWORD status
, written
;
795 LARGE_INTEGER offset
;
797 if (!pNtMapViewOfSection
|| !pNtUnmapViewOfSection
)
799 win_skip( "NtMapViewOfSection not available\n" );
803 file
= CreateFileA( testfile
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
804 ok( file
!= INVALID_HANDLE_VALUE
, "Failed to create test file\n" );
805 WriteFile( file
, data
, sizeof(data
), &written
, NULL
);
806 SetFilePointer( file
, 4096, NULL
, FILE_BEGIN
);
807 SetEndOfFile( file
);
809 /* read/write mapping */
811 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
812 ok( mapping
!= 0, "CreateFileMapping failed\n" );
814 hProcess
= create_target_process("sleep");
815 ok(hProcess
!= NULL
, "Can't start process\n");
820 status
= pNtMapViewOfSection( mapping
, hProcess
, &ptr
, 0, 0, &offset
, &size
, 1, 0, PAGE_READWRITE
);
821 ok( !status
, "NtMapViewOfSection failed status %x\n", status
);
823 ret
= ReadProcessMemory( hProcess
, ptr
, buffer
, sizeof(buffer
), &result
);
824 ok( ret
, "ReadProcessMemory failed\n" );
825 ok( result
== sizeof(buffer
), "ReadProcessMemory didn't read all data (%lx)\n", result
);
826 ok( !memcmp( buffer
, data
, sizeof(buffer
) ), "Wrong data read\n" );
828 status
= pNtUnmapViewOfSection( hProcess
, ptr
);
829 ok( !status
, "NtUnmapViewOfSection failed status %x\n", status
);
831 CloseHandle( mapping
);
833 DeleteFileA( testfile
);
835 TerminateProcess(hProcess
, 0);
836 CloseHandle(hProcess
);
839 static void test_NtAreMappedFilesTheSame(void)
841 static const char testfile
[] = "testfile.xxx";
842 HANDLE file
, file2
, mapping
, map2
;
847 if (!pNtAreMappedFilesTheSame
)
849 win_skip( "NtAreMappedFilesTheSame not available\n" );
853 file
= CreateFileA( testfile
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
854 NULL
, CREATE_ALWAYS
, 0, 0 );
855 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
856 SetFilePointer( file
, 4096, NULL
, FILE_BEGIN
);
857 SetEndOfFile( file
);
859 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READWRITE
, 0, 4096, NULL
);
860 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
862 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
863 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
865 file2
= CreateFileA( testfile
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
866 NULL
, OPEN_EXISTING
, 0, 0 );
867 ok( file2
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
869 map2
= CreateFileMappingA( file2
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
870 ok( map2
!= 0, "CreateFileMapping error %u\n", GetLastError() );
871 ptr2
= MapViewOfFile( map2
, FILE_MAP_READ
, 0, 0, 4096 );
872 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
873 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
874 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
875 UnmapViewOfFile( ptr2
);
877 ptr2
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
878 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
879 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
880 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
881 UnmapViewOfFile( ptr2
);
884 map2
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
885 ok( map2
!= 0, "CreateFileMapping error %u\n", GetLastError() );
886 ptr2
= MapViewOfFile( map2
, FILE_MAP_READ
, 0, 0, 4096 );
887 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
888 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
889 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
890 UnmapViewOfFile( ptr2
);
892 CloseHandle( file2
);
894 status
= pNtAreMappedFilesTheSame( ptr
, ptr
);
895 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
897 status
= pNtAreMappedFilesTheSame( ptr
, (char *)ptr
+ 30 );
898 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
900 status
= pNtAreMappedFilesTheSame( ptr
, GetModuleHandleA("kernel32.dll") );
901 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
903 status
= pNtAreMappedFilesTheSame( ptr
, (void *)0xdeadbeef );
904 ok( status
== STATUS_CONFLICTING_ADDRESSES
|| status
== STATUS_INVALID_ADDRESS
,
905 "NtAreMappedFilesTheSame returned %x\n", status
);
907 status
= pNtAreMappedFilesTheSame( ptr
, NULL
);
908 ok( status
== STATUS_INVALID_ADDRESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
910 status
= pNtAreMappedFilesTheSame( ptr
, (void *)GetProcessHeap() );
911 ok( status
== STATUS_CONFLICTING_ADDRESSES
, "NtAreMappedFilesTheSame returned %x\n", status
);
913 status
= pNtAreMappedFilesTheSame( NULL
, NULL
);
914 ok( status
== STATUS_INVALID_ADDRESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
916 ptr2
= VirtualAlloc( NULL
, 0x10000, MEM_COMMIT
, PAGE_READWRITE
);
917 ok( ptr2
!= NULL
, "VirtualAlloc error %u\n", GetLastError() );
918 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
919 ok( status
== STATUS_CONFLICTING_ADDRESSES
, "NtAreMappedFilesTheSame returned %x\n", status
);
920 VirtualFree( ptr2
, 0, MEM_RELEASE
);
922 UnmapViewOfFile( ptr
);
923 CloseHandle( mapping
);
926 status
= pNtAreMappedFilesTheSame( GetModuleHandleA("ntdll.dll"),
927 GetModuleHandleA("kernel32.dll") );
928 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
929 status
= pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
930 GetModuleHandleA("kernel32.dll") );
931 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
932 status
= pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
933 (char *)GetModuleHandleA("kernel32.dll") + 4096 );
934 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
936 GetSystemDirectoryA( path
, MAX_PATH
);
937 strcat( path
, "\\kernel32.dll" );
938 file
= CreateFileA( path
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
939 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
941 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
, 0, 4096, NULL
);
942 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
943 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
944 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
945 status
= pNtAreMappedFilesTheSame( ptr
, GetModuleHandleA("kernel32.dll") );
946 ok( status
== STATUS_NOT_SAME_DEVICE
, "NtAreMappedFilesTheSame returned %x\n", status
);
947 UnmapViewOfFile( ptr
);
948 CloseHandle( mapping
);
950 mapping
= CreateFileMappingA( file
, NULL
, PAGE_READONLY
| SEC_IMAGE
, 0, 0, NULL
);
951 ok( mapping
!= 0, "CreateFileMapping error %u\n", GetLastError() );
952 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 0 );
953 ok( ptr
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
954 status
= pNtAreMappedFilesTheSame( ptr
, GetModuleHandleA("kernel32.dll") );
956 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
958 file2
= CreateFileA( path
, GENERIC_READ
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
959 ok( file2
!= INVALID_HANDLE_VALUE
, "CreateFile error %u\n", GetLastError() );
960 map2
= CreateFileMappingA( file2
, NULL
, PAGE_READONLY
| SEC_IMAGE
, 0, 0, NULL
);
961 ok( map2
!= 0, "CreateFileMapping error %u\n", GetLastError() );
962 ptr2
= MapViewOfFile( map2
, FILE_MAP_READ
, 0, 0, 0 );
963 ok( ptr2
!= NULL
, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
964 status
= pNtAreMappedFilesTheSame( ptr
, ptr2
);
965 ok( status
== STATUS_SUCCESS
, "NtAreMappedFilesTheSame returned %x\n", status
);
966 UnmapViewOfFile( ptr2
);
968 CloseHandle( file2
);
970 UnmapViewOfFile( ptr
);
971 CloseHandle( mapping
);
974 DeleteFileA( testfile
);
977 static void test_CreateFileMapping(void)
979 HANDLE handle
, handle2
;
981 /* test case sensitivity */
983 SetLastError(0xdeadbeef);
984 handle
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, SEC_COMMIT
| PAGE_READWRITE
, 0, 0x1000,
985 "Wine Test Mapping");
986 ok( handle
!= NULL
, "CreateFileMapping failed with error %u\n", GetLastError());
987 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
989 SetLastError(0xdeadbeef);
990 handle2
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, SEC_COMMIT
| PAGE_READWRITE
, 0, 0x1000,
991 "Wine Test Mapping");
992 ok( handle2
!= NULL
, "CreateFileMapping failed with error %d\n", GetLastError());
993 ok( GetLastError() == ERROR_ALREADY_EXISTS
, "wrong error %u\n", GetLastError());
994 CloseHandle( handle2
);
996 SetLastError(0xdeadbeef);
997 handle2
= CreateFileMappingA( INVALID_HANDLE_VALUE
, NULL
, SEC_COMMIT
| PAGE_READWRITE
, 0, 0x1000,
998 "WINE TEST MAPPING");
999 ok( handle2
!= NULL
, "CreateFileMapping failed with error %d\n", GetLastError());
1000 ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
1001 CloseHandle( handle2
);
1003 SetLastError(0xdeadbeef);
1004 handle2
= OpenFileMappingA( FILE_MAP_ALL_ACCESS
, FALSE
, "Wine Test Mapping");
1005 ok( handle2
!= NULL
, "OpenFileMapping failed with error %d\n", GetLastError());
1006 CloseHandle( handle2
);
1008 SetLastError(0xdeadbeef);
1009 handle2
= OpenFileMappingA( FILE_MAP_ALL_ACCESS
, FALSE
, "WINE TEST MAPPING");
1010 ok( !handle2
, "OpenFileMapping succeeded\n");
1011 ok( GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_INVALID_NAME
/* win9x */,
1012 "wrong error %u\n", GetLastError());
1014 CloseHandle( handle
);
1017 static void test_IsBadReadPtr(void)
1020 void *ptr
= (void *)0xdeadbeef;
1023 ret
= IsBadReadPtr(NULL
, 0);
1024 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1026 ret
= IsBadReadPtr(NULL
, 1);
1027 ok(ret
== TRUE
, "Expected IsBadReadPtr to return TRUE, got %d\n", ret
);
1029 ret
= IsBadReadPtr(ptr
, 0);
1030 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1032 ret
= IsBadReadPtr(ptr
, 1);
1033 ok(ret
== TRUE
, "Expected IsBadReadPtr to return TRUE, got %d\n", ret
);
1035 ret
= IsBadReadPtr(&stackvar
, 0);
1036 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1038 ret
= IsBadReadPtr(&stackvar
, sizeof(char));
1039 ok(ret
== FALSE
, "Expected IsBadReadPtr to return FALSE, got %d\n", ret
);
1042 static void test_IsBadWritePtr(void)
1045 void *ptr
= (void *)0xdeadbeef;
1048 ret
= IsBadWritePtr(NULL
, 0);
1049 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1051 ret
= IsBadWritePtr(NULL
, 1);
1052 ok(ret
== TRUE
, "Expected IsBadWritePtr to return TRUE, got %d\n", ret
);
1054 ret
= IsBadWritePtr(ptr
, 0);
1055 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1057 ret
= IsBadWritePtr(ptr
, 1);
1058 ok(ret
== TRUE
, "Expected IsBadWritePtr to return TRUE, got %d\n", ret
);
1060 ret
= IsBadWritePtr(&stackval
, 0);
1061 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1063 ret
= IsBadWritePtr(&stackval
, sizeof(char));
1064 ok(ret
== FALSE
, "Expected IsBadWritePtr to return FALSE, got %d\n", ret
);
1067 static void test_IsBadCodePtr(void)
1070 void *ptr
= (void *)0xdeadbeef;
1073 ret
= IsBadCodePtr(NULL
);
1074 ok(ret
== TRUE
, "Expected IsBadCodePtr to return TRUE, got %d\n", ret
);
1076 ret
= IsBadCodePtr(ptr
);
1077 ok(ret
== TRUE
, "Expected IsBadCodePtr to return TRUE, got %d\n", ret
);
1079 ret
= IsBadCodePtr((void *)&stackval
);
1080 ok(ret
== FALSE
, "Expected IsBadCodePtr to return FALSE, got %d\n", ret
);
1083 static void test_write_watch(void)
1086 DWORD ret
, size
, old_prot
;
1087 MEMORY_BASIC_INFORMATION info
;
1092 if (!pGetWriteWatch
|| !pResetWriteWatch
)
1094 win_skip( "GetWriteWatch not supported\n" );
1099 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_COMMIT
| MEM_WRITE_WATCH
, PAGE_READWRITE
);
1101 (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_NOT_SUPPORTED
))
1103 win_skip( "MEM_WRITE_WATCH not supported\n" );
1106 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1107 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1108 ok(ret
, "VirtualQuery failed %u\n", GetLastError());
1109 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1110 ok( info
.AllocationProtect
== PAGE_READWRITE
, "wrong AllocationProtect %x\n", info
.AllocationProtect
);
1111 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1112 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1113 ok( info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
1114 ok( info
.Type
== MEM_PRIVATE
, "wrong Type 0x%x\n", info
.Type
);
1117 SetLastError( 0xdeadbeef );
1118 ret
= pGetWriteWatch( 0, NULL
, size
, results
, &count
, &pagesize
);
1119 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1120 ok( GetLastError() == ERROR_INVALID_PARAMETER
||
1121 broken( GetLastError() == 0xdeadbeef ), /* win98 */
1122 "wrong error %u\n", GetLastError() );
1124 SetLastError( 0xdeadbeef );
1125 ret
= pGetWriteWatch( 0, GetModuleHandle(0), size
, results
, &count
, &pagesize
);
1128 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1129 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1133 ok( count
== 0, "wrong count %lu\n", count
);
1136 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1137 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1138 ok( count
== 0, "wrong count %lu\n", count
);
1140 base
[pagesize
+ 1] = 0x44;
1143 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1144 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1145 ok( count
== 1, "wrong count %lu\n", count
);
1146 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1149 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1150 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1151 ok( count
== 1, "wrong count %lu\n", count
);
1152 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1155 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1156 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1157 ok( count
== 0, "wrong count %lu\n", count
);
1159 base
[2*pagesize
+ 3] = 0x11;
1160 base
[4*pagesize
+ 8] = 0x11;
1163 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1164 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1165 ok( count
== 2, "wrong count %lu\n", count
);
1166 ok( results
[0] == base
+ 2*pagesize
, "wrong result %p\n", results
[0] );
1167 ok( results
[1] == base
+ 4*pagesize
, "wrong result %p\n", results
[1] );
1170 ret
= pGetWriteWatch( 0, base
+ 3*pagesize
, 2*pagesize
, results
, &count
, &pagesize
);
1171 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1172 ok( count
== 1, "wrong count %lu\n", count
);
1173 ok( results
[0] == base
+ 4*pagesize
, "wrong result %p\n", results
[0] );
1175 ret
= pResetWriteWatch( base
, 3*pagesize
);
1176 ok( !ret
, "pResetWriteWatch failed %u\n", GetLastError() );
1179 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1180 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1181 ok( count
== 1, "wrong count %lu\n", count
);
1182 ok( results
[0] == base
+ 4*pagesize
, "wrong result %p\n", results
[0] );
1184 *(DWORD
*)(base
+ 2*pagesize
- 2) = 0xdeadbeef;
1187 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1188 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1189 ok( count
== 3, "wrong count %lu\n", count
);
1190 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1191 ok( results
[1] == base
+ 2*pagesize
, "wrong result %p\n", results
[1] );
1192 ok( results
[2] == base
+ 4*pagesize
, "wrong result %p\n", results
[2] );
1195 ret
= pGetWriteWatch( WRITE_WATCH_FLAG_RESET
, base
, size
, results
, &count
, &pagesize
);
1196 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1197 ok( count
== 1, "wrong count %lu\n", count
);
1198 ok( results
[0] == base
+ pagesize
, "wrong result %p\n", results
[0] );
1201 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1202 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1203 ok( count
== 2, "wrong count %lu\n", count
);
1204 ok( results
[0] == base
+ 2*pagesize
, "wrong result %p\n", results
[0] );
1205 ok( results
[1] == base
+ 4*pagesize
, "wrong result %p\n", results
[1] );
1207 /* changing protections doesn't affect watches */
1209 ret
= VirtualProtect( base
, 3*pagesize
, PAGE_READONLY
, &old_prot
);
1210 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1211 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
1213 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1214 ok(ret
, "VirtualQuery failed %u\n", GetLastError());
1215 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1216 ok( info
.RegionSize
== 3*pagesize
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1217 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1218 ok( info
.Protect
== PAGE_READONLY
, "wrong Protect 0x%x\n", info
.Protect
);
1220 ret
= VirtualProtect( base
, 3*pagesize
, PAGE_READWRITE
, &old_prot
);
1221 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1222 ok( old_prot
== PAGE_READONLY
, "wrong old prot %x\n", old_prot
);
1225 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1226 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1227 ok( count
== 2, "wrong count %lu\n", count
);
1228 ok( results
[0] == base
+ 2*pagesize
, "wrong result %p\n", results
[0] );
1229 ok( results
[1] == base
+ 4*pagesize
, "wrong result %p\n", results
[1] );
1231 ret
= VirtualQuery( base
, &info
, sizeof(info
) );
1232 ok(ret
, "VirtualQuery failed %u\n", GetLastError());
1233 ok( info
.BaseAddress
== base
, "BaseAddress %p instead of %p\n", info
.BaseAddress
, base
);
1234 ok( info
.RegionSize
== size
, "wrong RegionSize 0x%lx\n", info
.RegionSize
);
1235 ok( info
.State
== MEM_COMMIT
, "wrong State 0x%x\n", info
.State
);
1236 ok( info
.Protect
== PAGE_READWRITE
, "wrong Protect 0x%x\n", info
.Protect
);
1238 /* some invalid parameter tests */
1240 SetLastError( 0xdeadbeef );
1242 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1245 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1246 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1248 SetLastError( 0xdeadbeef );
1249 ret
= pGetWriteWatch( 0, base
, size
, results
, NULL
, &pagesize
);
1250 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1251 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1253 SetLastError( 0xdeadbeef );
1255 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, NULL
);
1256 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1257 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1259 SetLastError( 0xdeadbeef );
1261 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
1262 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1263 ok( GetLastError() == ERROR_NOACCESS
, "wrong error %u\n", GetLastError() );
1265 SetLastError( 0xdeadbeef );
1267 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
1268 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1269 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1271 SetLastError( 0xdeadbeef );
1273 ret
= pGetWriteWatch( 0xdeadbeef, base
, size
, results
, &count
, &pagesize
);
1274 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1275 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1277 SetLastError( 0xdeadbeef );
1279 ret
= pGetWriteWatch( 0, base
, 0, results
, &count
, &pagesize
);
1280 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1281 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1283 SetLastError( 0xdeadbeef );
1285 ret
= pGetWriteWatch( 0, base
, size
* 2, results
, &count
, &pagesize
);
1286 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1287 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1289 SetLastError( 0xdeadbeef );
1291 ret
= pGetWriteWatch( 0, base
+ size
- pagesize
, pagesize
+ 1, results
, &count
, &pagesize
);
1292 ok( ret
== ~0u, "GetWriteWatch succeeded %u\n", ret
);
1293 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1295 SetLastError( 0xdeadbeef );
1296 ret
= pResetWriteWatch( base
, 0 );
1297 ok( ret
== ~0u, "ResetWriteWatch succeeded %u\n", ret
);
1298 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1300 SetLastError( 0xdeadbeef );
1301 ret
= pResetWriteWatch( GetModuleHandle(0), size
);
1302 ok( ret
== ~0u, "ResetWriteWatch succeeded %u\n", ret
);
1303 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1305 else /* win98 is completely different */
1307 SetLastError( 0xdeadbeef );
1309 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
1310 ok( ret
== ERROR_INVALID_PARAMETER
, "GetWriteWatch succeeded %u\n", ret
);
1311 ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
1314 ret
= pGetWriteWatch( 0, base
, size
, NULL
, &count
, &pagesize
);
1315 ok( !ret
, "GetWriteWatch failed %u\n", ret
);
1318 ret
= pGetWriteWatch( 0xdeadbeef, base
, size
, results
, &count
, &pagesize
);
1319 ok( !ret
, "GetWriteWatch failed %u\n", ret
);
1322 ret
= pGetWriteWatch( 0, base
, 0, results
, &count
, &pagesize
);
1323 ok( !ret
, "GetWriteWatch failed %u\n", ret
);
1325 ret
= pResetWriteWatch( base
, 0 );
1326 ok( !ret
, "ResetWriteWatch failed %u\n", ret
);
1328 ret
= pResetWriteWatch( GetModuleHandle(0), size
);
1329 ok( !ret
, "ResetWriteWatch failed %u\n", ret
);
1332 VirtualFree( base
, 0, MEM_FREE
);
1334 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_WRITE_WATCH
, PAGE_READWRITE
);
1335 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1336 VirtualFree( base
, 0, MEM_FREE
);
1338 base
= VirtualAlloc( 0, size
, MEM_WRITE_WATCH
, PAGE_READWRITE
);
1339 ok( !base
, "VirtualAlloc succeeded\n" );
1340 ok( GetLastError() == ERROR_INVALID_PARAMETER
, "wrong error %u\n", GetLastError() );
1342 /* initial protect doesn't matter */
1344 base
= VirtualAlloc( 0, size
, MEM_RESERVE
| MEM_WRITE_WATCH
, PAGE_NOACCESS
);
1345 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1346 base
= VirtualAlloc( base
, size
, MEM_COMMIT
, PAGE_NOACCESS
);
1347 ok( base
!= NULL
, "VirtualAlloc failed %u\n", GetLastError() );
1350 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1351 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1352 ok( count
== 0, "wrong count %lu\n", count
);
1354 ret
= VirtualProtect( base
, 6*pagesize
, PAGE_READWRITE
, &old_prot
);
1355 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1356 ok( old_prot
== PAGE_NOACCESS
, "wrong old prot %x\n", old_prot
);
1358 base
[5*pagesize
+ 200] = 3;
1360 ret
= VirtualProtect( base
, 6*pagesize
, PAGE_NOACCESS
, &old_prot
);
1361 ok( ret
, "VirtualProtect failed error %u\n", GetLastError() );
1362 ok( old_prot
== PAGE_READWRITE
, "wrong old prot %x\n", old_prot
);
1365 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1366 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1367 ok( count
== 1, "wrong count %lu\n", count
);
1368 ok( results
[0] == base
+ 5*pagesize
, "wrong result %p\n", results
[0] );
1370 ret
= VirtualFree( base
, size
, MEM_DECOMMIT
);
1371 ok( ret
, "VirtualFree failed %u\n", GetLastError() );
1374 ret
= pGetWriteWatch( 0, base
, size
, results
, &count
, &pagesize
);
1375 ok( !ret
, "GetWriteWatch failed %u\n", GetLastError() );
1376 ok( count
== 1 || broken(count
== 0), /* win98 */
1377 "wrong count %lu\n", count
);
1378 if (count
) ok( results
[0] == base
+ 5*pagesize
, "wrong result %p\n", results
[0] );
1380 VirtualFree( base
, 0, MEM_FREE
);
1383 static void test_VirtualProtect(void)
1385 static const struct test_data
1387 DWORD prot_set
, prot_get
;
1390 { 0, 0 }, /* 0x00 */
1391 { PAGE_NOACCESS
, PAGE_NOACCESS
}, /* 0x01 */
1392 { PAGE_READONLY
, PAGE_READONLY
}, /* 0x02 */
1393 { PAGE_READONLY
| PAGE_NOACCESS
, 0 }, /* 0x03 */
1394 { PAGE_READWRITE
, PAGE_READWRITE
}, /* 0x04 */
1395 { PAGE_READWRITE
| PAGE_NOACCESS
, 0 }, /* 0x05 */
1396 { PAGE_READWRITE
| PAGE_READONLY
, 0 }, /* 0x06 */
1397 { PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, 0 }, /* 0x07 */
1398 { PAGE_WRITECOPY
, 0 }, /* 0x08 */
1399 { PAGE_WRITECOPY
| PAGE_NOACCESS
, 0 }, /* 0x09 */
1400 { PAGE_WRITECOPY
| PAGE_READONLY
, 0 }, /* 0x0a */
1401 { PAGE_WRITECOPY
| PAGE_NOACCESS
| PAGE_READONLY
, 0 }, /* 0x0b */
1402 { PAGE_WRITECOPY
| PAGE_READWRITE
, 0 }, /* 0x0c */
1403 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_NOACCESS
, 0 }, /* 0x0d */
1404 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
, 0 }, /* 0x0e */
1405 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, 0 }, /* 0x0f */
1407 { PAGE_EXECUTE
, PAGE_EXECUTE
}, /* 0x10 */
1408 { PAGE_EXECUTE_READ
, PAGE_EXECUTE_READ
}, /* 0x20 */
1409 { PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 }, /* 0x30 */
1410 { PAGE_EXECUTE_READWRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x40 */
1411 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, 0 }, /* 0x50 */
1412 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, 0 }, /* 0x60 */
1413 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 }, /* 0x70 */
1414 { PAGE_EXECUTE_WRITECOPY
, 0 }, /* 0x80 */
1415 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE
, 0 }, /* 0x90 */
1416 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
, 0 }, /* 0xa0 */
1417 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 }, /* 0xb0 */
1418 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
, 0 }, /* 0xc0 */
1419 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, 0 }, /* 0xd0 */
1420 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, 0 }, /* 0xe0 */
1421 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, 0 } /* 0xf0 */
1424 DWORD ret
, old_prot
, rw_prot
, exec_prot
, i
, j
;
1425 MEMORY_BASIC_INFORMATION info
;
1429 trace("system page size %#x\n", si
.dwPageSize
);
1431 SetLastError(0xdeadbeef);
1432 base
= VirtualAlloc(0, si
.dwPageSize
, MEM_RESERVE
| MEM_COMMIT
, PAGE_NOACCESS
);
1433 ok(base
!= NULL
, "VirtualAlloc failed %d\n", GetLastError());
1435 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
1437 SetLastError(0xdeadbeef);
1438 ret
= VirtualQuery(base
, &info
, sizeof(info
));
1439 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
1440 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
1441 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
1442 ok(info
.Protect
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, info
.Protect
);
1443 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
1444 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%d: %#x != PAGE_NOACCESS\n", i
, info
.AllocationProtect
);
1445 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
1446 ok(info
.Type
== MEM_PRIVATE
, "%d: %#x != MEM_PRIVATE\n", i
, info
.Type
);
1448 old_prot
= 0xdeadbeef;
1449 SetLastError(0xdeadbeef);
1450 ret
= VirtualProtect(base
, si
.dwPageSize
, td
[i
].prot_set
, &old_prot
);
1453 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
1454 ok(old_prot
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, old_prot
);
1456 SetLastError(0xdeadbeef);
1457 ret
= VirtualQuery(base
, &info
, sizeof(info
));
1458 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
1459 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
1460 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
1461 ok(info
.Protect
== td
[i
].prot_get
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot_get
);
1462 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
1463 ok(info
.AllocationProtect
== PAGE_NOACCESS
, "%d: %#x != PAGE_NOACCESS\n", i
, info
.AllocationProtect
);
1464 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
1465 ok(info
.Type
== MEM_PRIVATE
, "%d: %#x != MEM_PRIVATE\n", i
, info
.Type
);
1469 ok(!ret
, "%d: VirtualProtect should fail\n", i
);
1470 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
1473 old_prot
= 0xdeadbeef;
1474 SetLastError(0xdeadbeef);
1475 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
1476 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
1478 ok(old_prot
== td
[i
].prot_get
, "%d: got %#x != expected %#x\n", i
, old_prot
, td
[i
].prot_get
);
1480 ok(old_prot
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, old_prot
);
1485 for (i
= 0; i
<= 4; i
++)
1489 for (j
= 0; j
<= 4; j
++)
1491 DWORD prot
= exec_prot
| rw_prot
;
1493 SetLastError(0xdeadbeef);
1494 ret
= VirtualProtect(base
, si
.dwPageSize
, prot
, &old_prot
);
1495 if ((rw_prot
&& exec_prot
) || (!rw_prot
&& !exec_prot
))
1497 ok(!ret
, "VirtualProtect(%02x) should fail\n", prot
);
1498 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1502 if (prot
& (PAGE_WRITECOPY
| PAGE_EXECUTE_WRITECOPY
))
1504 ok(!ret
, "VirtualProtect(%02x) should fail\n", prot
);
1505 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1508 ok(ret
, "VirtualProtect(%02x) error %d\n", prot
, GetLastError());
1514 exec_prot
= 1 << (i
+ 4);
1517 VirtualFree(base
, 0, MEM_FREE
);
1520 static BOOL
is_mem_writable(DWORD prot
)
1522 switch (prot
& 0xff)
1524 case PAGE_READWRITE
:
1525 case PAGE_WRITECOPY
:
1526 case PAGE_EXECUTE_READWRITE
:
1527 case PAGE_EXECUTE_WRITECOPY
:
1535 static void test_VirtualAlloc_protection(void)
1537 static const struct test_data
1543 { 0, FALSE
}, /* 0x00 */
1544 { PAGE_NOACCESS
, TRUE
}, /* 0x01 */
1545 { PAGE_READONLY
, TRUE
}, /* 0x02 */
1546 { PAGE_READONLY
| PAGE_NOACCESS
, FALSE
}, /* 0x03 */
1547 { PAGE_READWRITE
, TRUE
}, /* 0x04 */
1548 { PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
}, /* 0x05 */
1549 { PAGE_READWRITE
| PAGE_READONLY
, FALSE
}, /* 0x06 */
1550 { PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
}, /* 0x07 */
1551 { PAGE_WRITECOPY
, FALSE
}, /* 0x08 */
1552 { PAGE_WRITECOPY
| PAGE_NOACCESS
, FALSE
}, /* 0x09 */
1553 { PAGE_WRITECOPY
| PAGE_READONLY
, FALSE
}, /* 0x0a */
1554 { PAGE_WRITECOPY
| PAGE_NOACCESS
| PAGE_READONLY
, FALSE
}, /* 0x0b */
1555 { PAGE_WRITECOPY
| PAGE_READWRITE
, FALSE
}, /* 0x0c */
1556 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
}, /* 0x0d */
1557 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
, FALSE
}, /* 0x0e */
1558 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
}, /* 0x0f */
1560 { PAGE_EXECUTE
, TRUE
}, /* 0x10 */
1561 { PAGE_EXECUTE_READ
, TRUE
}, /* 0x20 */
1562 { PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
}, /* 0x30 */
1563 { PAGE_EXECUTE_READWRITE
, TRUE
}, /* 0x40 */
1564 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
}, /* 0x50 */
1565 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
}, /* 0x60 */
1566 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
}, /* 0x70 */
1567 { PAGE_EXECUTE_WRITECOPY
, FALSE
}, /* 0x80 */
1568 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE
, FALSE
}, /* 0x90 */
1569 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
, FALSE
}, /* 0xa0 */
1570 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
}, /* 0xb0 */
1571 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
, FALSE
}, /* 0xc0 */
1572 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
}, /* 0xd0 */
1573 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
}, /* 0xe0 */
1574 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
} /* 0xf0 */
1578 MEMORY_BASIC_INFORMATION info
;
1582 trace("system page size %#x\n", si
.dwPageSize
);
1584 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
1586 SetLastError(0xdeadbeef);
1587 base
= VirtualAlloc(0, si
.dwPageSize
, MEM_COMMIT
, td
[i
].prot
);
1591 ok(base
!= NULL
, "%d: VirtualAlloc failed %d\n", i
, GetLastError());
1593 SetLastError(0xdeadbeef);
1594 ret
= VirtualQuery(base
, &info
, sizeof(info
));
1595 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
1596 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
1597 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
1598 ok(info
.Protect
== td
[i
].prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot
);
1599 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
1600 ok(info
.AllocationProtect
== td
[i
].prot
, "%d: %#x != %#x\n", i
, info
.AllocationProtect
, td
[i
].prot
);
1601 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
1602 ok(info
.Type
== MEM_PRIVATE
, "%d: %#x != MEM_PRIVATE\n", i
, info
.Type
);
1604 if (is_mem_writable(info
.Protect
))
1608 SetLastError(0xdeadbeef);
1609 ret
= VirtualQuery(base
, &info
, sizeof(info
));
1610 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
1611 ok(info
.Protect
== td
[i
].prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot
);
1614 VirtualFree(base
, 0, MEM_FREE
);
1618 ok(!base
, "%d: VirtualAlloc should fail\n", i
);
1619 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
1624 static void test_CreateFileMapping_protection(void)
1626 static const struct test_data
1630 DWORD prot_after_write
;
1633 { 0, FALSE
, 0 }, /* 0x00 */
1634 { PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x01 */
1635 { PAGE_READONLY
, TRUE
, PAGE_READONLY
}, /* 0x02 */
1636 { PAGE_READONLY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x03 */
1637 { PAGE_READWRITE
, TRUE
, PAGE_READWRITE
}, /* 0x04 */
1638 { PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x05 */
1639 { PAGE_READWRITE
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x06 */
1640 { PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x07 */
1641 { PAGE_WRITECOPY
, TRUE
, PAGE_READWRITE
}, /* 0x08 */
1642 { PAGE_WRITECOPY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x09 */
1643 { PAGE_WRITECOPY
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x0a */
1644 { PAGE_WRITECOPY
| PAGE_NOACCESS
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x0b */
1645 { PAGE_WRITECOPY
| PAGE_READWRITE
, FALSE
, PAGE_NOACCESS
}, /* 0x0c */
1646 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x0d */
1647 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
, FALSE
, PAGE_NOACCESS
}, /* 0x0e */
1648 { PAGE_WRITECOPY
| PAGE_READWRITE
| PAGE_READONLY
| PAGE_NOACCESS
, FALSE
, PAGE_NOACCESS
}, /* 0x0f */
1650 { PAGE_EXECUTE
, FALSE
, PAGE_EXECUTE
}, /* 0x10 */
1651 { PAGE_EXECUTE_READ
, TRUE
, PAGE_EXECUTE_READ
}, /* 0x20 */
1652 { PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_EXECUTE_READ
}, /* 0x30 */
1653 { PAGE_EXECUTE_READWRITE
, TRUE
, PAGE_EXECUTE_READWRITE
}, /* 0x40 */
1654 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0x50 */
1655 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
, PAGE_NOACCESS
}, /* 0x60 */
1656 { PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0x70 */
1657 { PAGE_EXECUTE_WRITECOPY
, TRUE
, PAGE_EXECUTE_READWRITE
}, /* 0x80 */
1658 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0x90 */
1659 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
, FALSE
, PAGE_NOACCESS
}, /* 0xa0 */
1660 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0xb0 */
1661 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
, FALSE
, PAGE_NOACCESS
}, /* 0xc0 */
1662 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
}, /* 0xd0 */
1663 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
, FALSE
, PAGE_NOACCESS
}, /* 0xe0 */
1664 { PAGE_EXECUTE_WRITECOPY
| PAGE_EXECUTE_READWRITE
| PAGE_EXECUTE_READ
| PAGE_EXECUTE
, FALSE
, PAGE_NOACCESS
} /* 0xf0 */
1667 DWORD ret
, i
, alloc_prot
, prot
, old_prot
;
1668 MEMORY_BASIC_INFORMATION info
;
1670 char temp_path
[MAX_PATH
];
1671 char file_name
[MAX_PATH
];
1673 BOOL page_exec_supported
= TRUE
;
1676 trace("system page size %#x\n", si
.dwPageSize
);
1678 GetTempPath(MAX_PATH
, temp_path
);
1679 GetTempFileName(temp_path
, "map", 0, file_name
);
1681 SetLastError(0xdeadbeef);
1682 hfile
= CreateFile(file_name
, GENERIC_READ
|GENERIC_WRITE
|GENERIC_EXECUTE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
1683 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile(%s) error %d\n", file_name
, GetLastError());
1684 SetFilePointer(hfile
, si
.dwPageSize
, NULL
, FILE_BEGIN
);
1685 SetEndOfFile(hfile
);
1687 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
1689 SetLastError(0xdeadbeef);
1690 hmap
= CreateFileMapping(hfile
, NULL
, td
[i
].prot
| SEC_COMMIT
, 0, si
.dwPageSize
, NULL
);
1696 trace("%d: CreateFileMapping(%04x) failed: %d\n", i
, td
[i
].prot
, GetLastError());
1697 /* NT4 and win2k don't support EXEC on file mappings */
1698 if (td
[i
].prot
== PAGE_EXECUTE_READ
|| td
[i
].prot
== PAGE_EXECUTE_READWRITE
)
1700 page_exec_supported
= FALSE
;
1701 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE\n", i
);
1704 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
1705 if (td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
1707 page_exec_supported
= FALSE
;
1708 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE_WRITECOPY\n", i
);
1712 ok(hmap
!= 0, "%d: CreateFileMapping(%04x) error %d\n", i
, td
[i
].prot
, GetLastError());
1714 base
= MapViewOfFile(hmap
, FILE_MAP_READ
, 0, 0, 0);
1715 ok(base
!= NULL
, "%d: MapViewOfFile failed %d\n", i
, GetLastError());
1717 SetLastError(0xdeadbeef);
1718 ret
= VirtualQuery(base
, &info
, sizeof(info
));
1719 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
1720 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
1721 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
1722 ok(info
.Protect
== PAGE_READONLY
, "%d: got %#x != expected PAGE_READONLY\n", i
, info
.Protect
);
1723 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
1724 ok(info
.AllocationProtect
== PAGE_READONLY
, "%d: %#x != PAGE_READONLY\n", i
, info
.AllocationProtect
);
1725 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
1726 ok(info
.Type
== MEM_MAPPED
, "%d: %#x != MEM_MAPPED\n", i
, info
.Type
);
1728 if (is_mem_writable(info
.Protect
))
1732 SetLastError(0xdeadbeef);
1733 ret
= VirtualQuery(base
, &info
, sizeof(info
));
1734 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
1735 ok(info
.Protect
== td
[i
].prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot
);
1738 UnmapViewOfFile(base
);
1743 ok(!hmap
, "%d: CreateFileMapping should fail\n", i
);
1744 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
1748 if (page_exec_supported
) alloc_prot
= PAGE_EXECUTE_READWRITE
;
1749 else alloc_prot
= PAGE_READWRITE
;
1750 SetLastError(0xdeadbeef);
1751 hmap
= CreateFileMapping(hfile
, NULL
, alloc_prot
, 0, si
.dwPageSize
, NULL
);
1752 ok(hmap
!= 0, "%d: CreateFileMapping error %d\n", i
, GetLastError());
1754 SetLastError(0xdeadbeef);
1755 base
= MapViewOfFile(hmap
, FILE_MAP_READ
| FILE_MAP_WRITE
| (page_exec_supported
? FILE_MAP_EXECUTE
: 0), 0, 0, 0);
1756 ok(base
!= NULL
, "MapViewOfFile failed %d\n", GetLastError());
1758 old_prot
= 0xdeadbeef;
1759 SetLastError(0xdeadbeef);
1760 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
1761 ok(ret
, "VirtualProtect error %d\n", GetLastError());
1762 ok(old_prot
== alloc_prot
, "got %#x != expected %#x\n", old_prot
, alloc_prot
);
1764 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
1766 SetLastError(0xdeadbeef);
1767 ret
= VirtualQuery(base
, &info
, sizeof(info
));
1768 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
1769 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
1770 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
1771 ok(info
.Protect
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, info
.Protect
);
1772 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
1773 ok(info
.AllocationProtect
== alloc_prot
, "%d: %#x != %#x\n", i
, info
.AllocationProtect
, alloc_prot
);
1774 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
1775 ok(info
.Type
== MEM_MAPPED
, "%d: %#x != MEM_MAPPED\n", i
, info
.Type
);
1777 old_prot
= 0xdeadbeef;
1778 SetLastError(0xdeadbeef);
1779 ret
= VirtualProtect(base
, si
.dwPageSize
, td
[i
].prot
, &old_prot
);
1780 if (td
[i
].success
|| td
[i
].prot
== PAGE_NOACCESS
|| td
[i
].prot
== PAGE_EXECUTE
)
1784 /* win2k and XP don't support EXEC on file mappings */
1785 if (td
[i
].prot
== PAGE_EXECUTE
)
1787 ok(broken(!ret
), "%d: VirtualProtect doesn't support PAGE_EXECUTE\n", i
);
1790 /* NT4 and win2k don't support EXEC on file mappings */
1791 if (td
[i
].prot
== PAGE_EXECUTE_READ
|| td
[i
].prot
== PAGE_EXECUTE_READWRITE
)
1793 ok(broken(!ret
), "%d: VirtualProtect doesn't support PAGE_EXECUTE\n", i
);
1796 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
1797 if (td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
1799 ok(broken(!ret
), "%d: VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY\n", i
);
1804 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
1805 ok(old_prot
== PAGE_NOACCESS
, "%d: got %#x != expected PAGE_NOACCESS\n", i
, old_prot
);
1808 /* looks strange but Windows doesn't do this for PAGE_WRITECOPY */
1809 if (prot
== PAGE_EXECUTE_WRITECOPY
) prot
= PAGE_EXECUTE_READWRITE
;
1811 SetLastError(0xdeadbeef);
1812 ret
= VirtualQuery(base
, &info
, sizeof(info
));
1813 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
1814 ok(info
.BaseAddress
== base
, "%d: got %p != expected %p\n", i
, info
.BaseAddress
, base
);
1815 ok(info
.RegionSize
== si
.dwPageSize
, "%d: got %#lx != expected %#x\n", i
, info
.RegionSize
, si
.dwPageSize
);
1816 /* FIXME: remove the condition below once Wine is fixed */
1817 if (td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
1818 todo_wine
ok(info
.Protect
== prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, prot
);
1820 ok(info
.Protect
== prot
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, prot
);
1821 ok(info
.AllocationBase
== base
, "%d: %p != %p\n", i
, info
.AllocationBase
, base
);
1822 ok(info
.AllocationProtect
== alloc_prot
, "%d: %#x != %#x\n", i
, info
.AllocationProtect
, alloc_prot
);
1823 ok(info
.State
== MEM_COMMIT
, "%d: %#x != MEM_COMMIT\n", i
, info
.State
);
1824 ok(info
.Type
== MEM_MAPPED
, "%d: %#x != MEM_MAPPED\n", i
, info
.Type
);
1826 if (is_mem_writable(info
.Protect
))
1830 SetLastError(0xdeadbeef);
1831 ret
= VirtualQuery(base
, &info
, sizeof(info
));
1832 ok(ret
, "VirtualQuery failed %d\n", GetLastError());
1833 /* FIXME: remove the condition below once Wine is fixed */
1834 if (td
[i
].prot
== PAGE_WRITECOPY
|| td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
1835 todo_wine
ok(info
.Protect
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot_after_write
);
1837 ok(info
.Protect
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, info
.Protect
, td
[i
].prot_after_write
);
1842 ok(!ret
, "%d: VirtualProtect should fail\n", i
);
1843 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i
, GetLastError());
1847 old_prot
= 0xdeadbeef;
1848 SetLastError(0xdeadbeef);
1849 ret
= VirtualProtect(base
, si
.dwPageSize
, PAGE_NOACCESS
, &old_prot
);
1850 ok(ret
, "%d: VirtualProtect error %d\n", i
, GetLastError());
1851 /* FIXME: remove the condition below once Wine is fixed */
1852 if (td
[i
].prot
== PAGE_WRITECOPY
|| td
[i
].prot
== PAGE_EXECUTE_WRITECOPY
)
1853 todo_wine
ok(old_prot
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, old_prot
, td
[i
].prot_after_write
);
1855 ok(old_prot
== td
[i
].prot_after_write
, "%d: got %#x != expected %#x\n", i
, old_prot
, td
[i
].prot_after_write
);
1858 UnmapViewOfFile(base
);
1862 DeleteFile(file_name
);
1865 #define ACCESS_READ 0x01
1866 #define ACCESS_WRITE 0x02
1867 #define ACCESS_EXECUTE 0x04
1868 #define ACCESS_WRITECOPY 0x08
1870 static DWORD
page_prot_to_access(DWORD prot
)
1874 case PAGE_READWRITE
:
1875 return ACCESS_READ
| ACCESS_WRITE
;
1878 case PAGE_EXECUTE_READ
:
1879 return ACCESS_READ
| ACCESS_EXECUTE
;
1881 case PAGE_EXECUTE_READWRITE
:
1882 return ACCESS_READ
| ACCESS_WRITE
| ACCESS_WRITECOPY
| ACCESS_EXECUTE
;
1884 case PAGE_EXECUTE_WRITECOPY
:
1885 return ACCESS_READ
| ACCESS_WRITECOPY
| ACCESS_EXECUTE
;
1890 case PAGE_WRITECOPY
:
1898 static BOOL
is_compatible_protection(DWORD map_prot
, DWORD view_prot
, DWORD prot
)
1900 DWORD map_access
, view_access
, prot_access
;
1902 map_access
= page_prot_to_access(map_prot
);
1903 view_access
= page_prot_to_access(view_prot
);
1904 prot_access
= page_prot_to_access(prot
);
1906 if (view_access
== prot_access
) return TRUE
;
1907 if (!view_access
) return FALSE
;
1909 if ((view_access
& prot_access
) != prot_access
) return FALSE
;
1910 if ((map_access
& prot_access
) == prot_access
) return TRUE
;
1915 static DWORD
map_prot_to_access(DWORD prot
)
1919 case PAGE_READWRITE
:
1920 case PAGE_EXECUTE_READWRITE
:
1921 return SECTION_MAP_READ
| SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
| SECTION_MAP_EXECUTE_EXPLICIT
| SECTION_QUERY
;
1923 case PAGE_WRITECOPY
:
1925 case PAGE_EXECUTE_READ
:
1926 case PAGE_EXECUTE_WRITECOPY
:
1927 return SECTION_MAP_READ
| SECTION_MAP_EXECUTE
| SECTION_MAP_EXECUTE_EXPLICIT
| SECTION_QUERY
;
1933 static BOOL
is_compatible_access(DWORD map_prot
, DWORD view_prot
)
1935 DWORD access
= map_prot_to_access(map_prot
);
1936 if (!access
) return FALSE
;
1937 return (view_prot
& access
) == view_prot
;
1940 static void *map_view_of_file(HANDLE handle
, DWORD access
)
1943 LARGE_INTEGER offset
;
1949 if (!pNtMapViewOfSection
) return NULL
;
1952 offset
.u
.LowPart
= 0;
1953 offset
.u
.HighPart
= 0;
1955 exec
= access
& FILE_MAP_EXECUTE
;
1956 access
&= ~FILE_MAP_EXECUTE
;
1958 if (access
== FILE_MAP_COPY
)
1961 protect
= PAGE_EXECUTE_WRITECOPY
;
1963 protect
= PAGE_WRITECOPY
;
1965 else if (access
& FILE_MAP_WRITE
)
1968 protect
= PAGE_EXECUTE_READWRITE
;
1970 protect
= PAGE_READWRITE
;
1972 else if (access
& FILE_MAP_READ
)
1975 protect
= PAGE_EXECUTE_READ
;
1977 protect
= PAGE_READONLY
;
1979 else protect
= PAGE_NOACCESS
;
1982 status
= pNtMapViewOfSection(handle
, GetCurrentProcess(), &addr
, 0, 0, &offset
,
1983 &count
, 1 /* ViewShare */, 0, protect
);
1986 /* for simplicity */
1987 SetLastError(ERROR_ACCESS_DENIED
);
1993 static void test_mapping(void)
1995 static const DWORD page_prot
[] =
1997 PAGE_NOACCESS
, PAGE_READONLY
, PAGE_READWRITE
, PAGE_WRITECOPY
,
1998 PAGE_EXECUTE_READ
, PAGE_EXECUTE_READWRITE
, PAGE_EXECUTE_WRITECOPY
2005 { 0, PAGE_NOACCESS
}, /* 0x00 */
2006 { FILE_MAP_COPY
, PAGE_WRITECOPY
}, /* 0x01 */
2007 { FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x02 */
2008 { FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x03 */
2009 { FILE_MAP_READ
, PAGE_READONLY
}, /* 0x04 */
2010 { FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_READONLY
}, /* 0x05 */
2011 { FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x06 */
2012 { FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x07 */
2013 { SECTION_MAP_EXECUTE
, PAGE_NOACCESS
}, /* 0x08 */
2014 { SECTION_MAP_EXECUTE
| FILE_MAP_COPY
, PAGE_NOACCESS
}, /* 0x09 */
2015 { SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x0a */
2016 { SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x0b */
2017 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
, PAGE_READONLY
}, /* 0x0c */
2018 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_READONLY
}, /* 0x0d */
2019 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_READWRITE
}, /* 0x0e */
2020 { SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_READWRITE
}, /* 0x0f */
2021 { FILE_MAP_EXECUTE
, PAGE_NOACCESS
}, /* 0x20 */
2022 { FILE_MAP_EXECUTE
| FILE_MAP_COPY
, PAGE_EXECUTE_WRITECOPY
}, /* 0x21 */
2023 { FILE_MAP_EXECUTE
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x22 */
2024 { FILE_MAP_EXECUTE
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
}, /* 0x23 */
2025 { FILE_MAP_EXECUTE
| FILE_MAP_READ
, PAGE_EXECUTE_READ
}, /* 0x24 */
2026 { FILE_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_EXECUTE_READ
}, /* 0x25 */
2027 { FILE_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x26 */
2028 { FILE_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
}, /* 0x27 */
2029 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
, PAGE_NOACCESS
}, /* 0x28 */
2030 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_COPY
, PAGE_NOACCESS
}, /* 0x29 */
2031 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x2a */
2032 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
}, /* 0x2b */
2033 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
, PAGE_EXECUTE_READ
}, /* 0x2c */
2034 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_COPY
, PAGE_EXECUTE_READ
}, /* 0x2d */
2035 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
, PAGE_EXECUTE_READWRITE
}, /* 0x2e */
2036 { FILE_MAP_EXECUTE
| SECTION_MAP_EXECUTE
| FILE_MAP_READ
| FILE_MAP_WRITE
| FILE_MAP_COPY
, PAGE_EXECUTE_READWRITE
} /* 0x2f */
2038 void *base
, *nt_base
;
2039 DWORD i
, j
, k
, ret
, old_prot
, prev_prot
;
2041 char temp_path
[MAX_PATH
];
2042 char file_name
[MAX_PATH
];
2044 MEMORY_BASIC_INFORMATION info
, nt_info
;
2047 trace("system page size %#x\n", si
.dwPageSize
);
2049 GetTempPath(MAX_PATH
, temp_path
);
2050 GetTempFileName(temp_path
, "map", 0, file_name
);
2052 SetLastError(0xdeadbeef);
2053 hfile
= CreateFile(file_name
, GENERIC_READ
|GENERIC_WRITE
|GENERIC_EXECUTE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2054 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile(%s) error %d\n", file_name
, GetLastError());
2055 SetFilePointer(hfile
, si
.dwPageSize
, NULL
, FILE_BEGIN
);
2056 SetEndOfFile(hfile
);
2058 for (i
= 0; i
< sizeof(page_prot
)/sizeof(page_prot
[0]); i
++)
2060 SetLastError(0xdeadbeef);
2061 hmap
= CreateFileMapping(hfile
, NULL
, page_prot
[i
] | SEC_COMMIT
, 0, si
.dwPageSize
, NULL
);
2063 if (page_prot
[i
] == PAGE_NOACCESS
)
2067 ok(!hmap
, "CreateFileMapping(PAGE_NOACCESS) should fail\n");
2068 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2070 /* A trick to create a not accessible mapping */
2071 SetLastError(0xdeadbeef);
2072 hmap
= CreateFileMapping(hfile
, NULL
, PAGE_READWRITE
| SEC_COMMIT
, 0, si
.dwPageSize
, NULL
);
2073 ok(hmap
!= 0, "CreateFileMapping(PAGE_READWRITE) error %d\n", GetLastError());
2074 SetLastError(0xdeadbeef);
2075 ret
= DuplicateHandle(GetCurrentProcess(), hmap
, GetCurrentProcess(), &hmap2
, 0, FALSE
, 0);
2076 ok(ret
, "DuplicateHandle error %d\n", GetLastError());
2083 trace("%d: CreateFileMapping(%04x) failed: %d\n", i
, page_prot
[i
], GetLastError());
2085 /* NT4 and win2k don't support EXEC on file mappings */
2086 if (page_prot
[i
] == PAGE_EXECUTE_READ
|| page_prot
[i
] == PAGE_EXECUTE_READWRITE
)
2088 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE\n", i
);
2091 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
2092 if (page_prot
[i
] == PAGE_EXECUTE_WRITECOPY
)
2094 ok(broken(!hmap
), "%d: CreateFileMapping doesn't support PAGE_EXECUTE_WRITECOPY\n", i
);
2099 ok(hmap
!= 0, "%d: CreateFileMapping(%04x) error %d\n", i
, page_prot
[i
], GetLastError());
2101 for (j
= 0; j
< sizeof(view
)/sizeof(view
[0]); j
++)
2103 nt_base
= map_view_of_file(hmap
, view
[j
].access
);
2106 SetLastError(0xdeadbeef);
2107 ret
= VirtualQuery(nt_base
, &nt_info
, sizeof(nt_info
));
2108 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
2109 UnmapViewOfFile(nt_base
);
2112 SetLastError(0xdeadbeef);
2113 base
= MapViewOfFile(hmap
, view
[j
].access
, 0, 0, 0);
2115 /* FIXME: completely remove the condition below once Wine is fixed */
2116 if (!nt_base
!= !base
)
2118 /* Vista+ supports FILE_MAP_EXECUTE properly, earlier versions don't */
2119 ok(!nt_base
== !base
||
2120 broken((view
[j
].access
& FILE_MAP_EXECUTE
) && !nt_base
!= !base
),
2121 "%d: (%04x/%04x) NT %p kernel %p\n", j
, page_prot
[i
], view
[j
].access
, nt_base
, base
);
2123 ok(!nt_base
== !base
||
2124 broken((view
[j
].access
& FILE_MAP_EXECUTE
) && !nt_base
!= !base
),
2125 "%d: (%04x/%04x) NT %p kernel %p\n", j
, page_prot
[i
], view
[j
].access
, nt_base
, base
);
2127 if (!is_compatible_access(page_prot
[i
], view
[j
].access
))
2129 ok(!base
, "%d: MapViewOfFile(%04x/%04x) should fail\n", j
, page_prot
[i
], view
[j
].access
);
2130 ok(GetLastError() == ERROR_ACCESS_DENIED
, "wrong error %d\n", GetLastError());
2134 /* Vista+ properly supports FILE_MAP_EXECUTE, earlier versions don't */
2135 if (!base
&& (view
[j
].access
& FILE_MAP_EXECUTE
))
2137 ok(broken(!base
), "%d: MapViewOfFile(%04x/%04x) failed %d\n", j
, page_prot
[i
], view
[j
].access
, GetLastError());
2141 ok(base
!= NULL
, "%d: MapViewOfFile(%04x/%04x) failed %d\n", j
, page_prot
[i
], view
[j
].access
, GetLastError());
2143 SetLastError(0xdeadbeef);
2144 ret
= VirtualQuery(base
, &info
, sizeof(info
));
2145 ok(ret
, "%d: VirtualQuery failed %d\n", j
, GetLastError());
2146 ok(info
.BaseAddress
== base
, "%d: (%04x) got %p, expected %p\n", j
, view
[j
].access
, info
.BaseAddress
, base
);
2147 ok(info
.RegionSize
== si
.dwPageSize
, "%d: (%04x) got %#lx != expected %#x\n", j
, view
[j
].access
, info
.RegionSize
, si
.dwPageSize
);
2148 /* FIXME: completely remove the condition below once Wine is fixed */
2149 if (info
.Protect
!= view
[j
].prot
)
2151 ok(info
.Protect
== view
[j
].prot
||
2152 broken(view
[j
].prot
== PAGE_EXECUTE_READ
&& info
.Protect
== PAGE_READONLY
) || /* win2k */
2153 broken(view
[j
].prot
== PAGE_EXECUTE_READWRITE
&& info
.Protect
== PAGE_READWRITE
) || /* win2k */
2154 broken(view
[j
].prot
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
2155 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, info
.Protect
, view
[j
].prot
);
2157 ok(info
.Protect
== view
[j
].prot
||
2158 broken(view
[j
].prot
== PAGE_EXECUTE_READ
&& info
.Protect
== PAGE_READONLY
) || /* win2k */
2159 broken(view
[j
].prot
== PAGE_EXECUTE_READWRITE
&& info
.Protect
== PAGE_READWRITE
) || /* win2k */
2160 broken(view
[j
].prot
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
2161 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, info
.Protect
, view
[j
].prot
);
2162 ok(info
.AllocationBase
== base
, "%d: (%04x) got %p, expected %p\n", j
, view
[j
].access
, info
.AllocationBase
, base
);
2163 ok(info
.AllocationProtect
== info
.Protect
, "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, info
.AllocationProtect
, info
.Protect
);
2164 ok(info
.State
== MEM_COMMIT
, "%d: (%04x) got %#x, expected MEM_COMMIT\n", j
, view
[j
].access
, info
.State
);
2165 ok(info
.Type
== MEM_MAPPED
, "%d: (%04x) got %#x, expected MEM_MAPPED\n", j
, view
[j
].access
, info
.Type
);
2167 if (nt_base
&& base
)
2169 ok(nt_info
.RegionSize
== info
.RegionSize
, "%d: (%04x) got %#lx != expected %#lx\n", j
, view
[j
].access
, nt_info
.RegionSize
, info
.RegionSize
);
2170 /* FIXME: completely remove the condition below once Wine is fixed */
2171 if (nt_info
.Protect
!= info
.Protect
)
2173 ok(nt_info
.Protect
== info
.Protect
/* Vista+ */ ||
2174 broken(nt_info
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
2175 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.Protect
, info
.Protect
);
2177 ok(nt_info
.Protect
== info
.Protect
/* Vista+ */ ||
2178 broken(nt_info
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
2179 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.Protect
, info
.Protect
);
2180 /* FIXME: completely remove the condition below once Wine is fixed */
2181 if (nt_info
.AllocationProtect
!= info
.AllocationProtect
)
2183 ok(nt_info
.AllocationProtect
== info
.AllocationProtect
/* Vista+ */ ||
2184 broken(nt_info
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
2185 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.AllocationProtect
, info
.AllocationProtect
);
2187 ok(nt_info
.AllocationProtect
== info
.AllocationProtect
/* Vista+ */ ||
2188 broken(nt_info
.AllocationProtect
== PAGE_EXECUTE_WRITECOPY
&& info
.Protect
== PAGE_NOACCESS
), /* XP */
2189 "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.AllocationProtect
, info
.AllocationProtect
);
2190 ok(nt_info
.State
== info
.State
, "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.State
, info
.State
);
2191 ok(nt_info
.Type
== info
.Type
, "%d: (%04x) got %#x, expected %#x\n", j
, view
[j
].access
, nt_info
.Type
, info
.Type
);
2194 prev_prot
= info
.Protect
;
2196 for (k
= 0; k
< sizeof(page_prot
)/sizeof(page_prot
[0]); k
++)
2198 /*trace("map %#x, view %#x, requested prot %#x\n", page_prot[i], view[j].prot, page_prot[k]);*/
2199 SetLastError(0xdeadbeef);
2200 old_prot
= 0xdeadbeef;
2201 ret
= VirtualProtect(base
, si
.dwPageSize
, page_prot
[k
], &old_prot
);
2202 if (is_compatible_protection(page_prot
[i
], view
[j
].prot
, page_prot
[k
]))
2204 /* win2k and XP don't support EXEC on file mappings */
2205 if (!ret
&& page_prot
[k
] == PAGE_EXECUTE
)
2207 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE\n");
2210 /* NT4 and win2k don't support EXEC on file mappings */
2211 if (!ret
&& (page_prot
[k
] == PAGE_EXECUTE_READ
|| page_prot
[k
] == PAGE_EXECUTE_READWRITE
))
2213 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE\n");
2216 /* Vista+ supports PAGE_EXECUTE_WRITECOPY, earlier versions don't */
2217 if (!ret
&& page_prot
[k
] == PAGE_EXECUTE_WRITECOPY
)
2220 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY\n");
2223 /* win2k and XP don't support PAGE_EXECUTE_WRITECOPY views properly */
2224 if (!ret
&& view
[j
].prot
== PAGE_EXECUTE_WRITECOPY
)
2226 ok(broken(!ret
), "VirtualProtect doesn't support PAGE_EXECUTE_WRITECOPY view properly\n");
2230 ok(ret
, "VirtualProtect error %d, map %#x, view %#x, requested prot %#x\n", GetLastError(), page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
2231 ok(old_prot
== prev_prot
, "got %#x, expected %#x\n", old_prot
, prev_prot
);
2232 prev_prot
= page_prot
[k
];
2236 /* NT4 doesn't fail on incompatible map and view */
2240 ok(broken(ret
), "VirtualProtect should fail, map %#x, view %#x, requested prot %#x\n", page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
2241 skip("Incompatible map and view are not properly handled on this platform\n");
2242 break; /* NT4 won't pass remaining tests */
2245 ok(!ret
, "VirtualProtect should fail, map %#x, view %#x, requested prot %#x\n", page_prot
[i
], view
[j
].prot
, page_prot
[k
]);
2246 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2250 UnmapViewOfFile(base
);
2257 DeleteFile(file_name
);
2264 argc
= winetest_get_mainargs( &argv
);
2268 if (!strcmp(argv
[2], "sleep"))
2270 Sleep(5000); /* spawned process runs for at most 5 seconds */
2277 mem
= VirtualAlloc(NULL
, 1<<20, MEM_COMMIT
|MEM_RESERVE
,
2278 PAGE_EXECUTE_READWRITE
);
2279 ok(mem
!= NULL
, "VirtualAlloc failed %u\n", GetLastError());
2280 if (mem
== NULL
) break;
2281 ret
= VirtualFree(mem
, 0, MEM_RELEASE
);
2282 ok(ret
, "VirtualFree failed %u\n", GetLastError());
2288 hkernel32
= GetModuleHandleA("kernel32.dll");
2289 pVirtualAllocEx
= (void *) GetProcAddress(hkernel32
, "VirtualAllocEx");
2290 pVirtualFreeEx
= (void *) GetProcAddress(hkernel32
, "VirtualFreeEx");
2291 pGetWriteWatch
= (void *) GetProcAddress(hkernel32
, "GetWriteWatch");
2292 pResetWriteWatch
= (void *) GetProcAddress(hkernel32
, "ResetWriteWatch");
2293 pNtAreMappedFilesTheSame
= (void *)GetProcAddress( GetModuleHandle("ntdll.dll"),
2294 "NtAreMappedFilesTheSame" );
2295 pNtMapViewOfSection
= (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtMapViewOfSection");
2296 pNtUnmapViewOfSection
= (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtUnmapViewOfSection");
2299 test_CreateFileMapping_protection();
2300 test_VirtualAlloc_protection();
2301 test_VirtualProtect();
2302 test_VirtualAllocEx();
2303 test_VirtualAlloc();
2304 test_MapViewOfFile();
2305 test_NtMapViewOfSection();
2306 test_NtAreMappedFilesTheSame();
2307 test_CreateFileMapping();
2308 test_IsBadReadPtr();
2309 test_IsBadWritePtr();
2310 test_IsBadCodePtr();