kernel32: Add a bunch of VirtualProtect tests.
[wine] / dlls / kernel32 / tests / virtual.c
1 /*
2  * Unit test suite for Virtual* family of APIs.
3  *
4  * Copyright 2004 Dmitry Timoshkov
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winternl.h"
29 #include "winerror.h"
30 #include "wine/test.h"
31
32 #define NUM_THREADS 4
33 #define MAPPING_SIZE 0x100000
34
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
42 /* ############################### */
43
44 static HANDLE create_target_process(const char *arg)
45 {
46     char **argv;
47     char cmdline[MAX_PATH];
48     PROCESS_INFORMATION pi;
49     BOOL ret;
50     STARTUPINFO si = { 0 };
51     si.cb = sizeof(si);
52
53     winetest_get_mainargs( &argv );
54     sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
55     ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
56     ok(ret, "error: %u\n", GetLastError());
57     ret = CloseHandle(pi.hThread);
58     ok(ret, "error %u\n", GetLastError());
59     return pi.hProcess;
60 }
61
62 static void test_VirtualAllocEx(void)
63 {
64     const unsigned int alloc_size = 1<<15;
65     char *src, *dst;
66     SIZE_T bytes_written = 0, bytes_read = 0, i;
67     void *addr1, *addr2;
68     BOOL b;
69     DWORD old_prot;
70     MEMORY_BASIC_INFORMATION info;
71     HANDLE hProcess;
72
73     /* not exported in all windows-versions  */
74     if ((!pVirtualAllocEx) || (!pVirtualFreeEx)) {
75         win_skip("Virtual{Alloc,Free}Ex not available\n");
76         return;
77     }
78
79     hProcess = create_target_process("sleep");
80     ok(hProcess != NULL, "Can't start process\n");
81
82     SetLastError(0xdeadbeef);
83     addr1 = pVirtualAllocEx(hProcess, NULL, alloc_size, MEM_COMMIT,
84                            PAGE_EXECUTE_READWRITE);
85     if (!addr1 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
86     {   /* Win9x */
87         win_skip("VirtualAllocEx not implemented\n");
88         TerminateProcess(hProcess, 0);
89         CloseHandle(hProcess);
90         return;
91     }
92
93     src = VirtualAlloc( NULL, alloc_size, MEM_COMMIT, PAGE_READWRITE );
94     dst = VirtualAlloc( NULL, alloc_size, MEM_COMMIT, PAGE_READWRITE );
95     for (i = 0; i < alloc_size; i++)
96         src[i] = i & 0xff;
97
98     ok(addr1 != NULL, "VirtualAllocEx error %u\n", GetLastError());
99     b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
100     ok(b && (bytes_written == alloc_size), "%lu bytes written\n",
101        bytes_written);
102     b = ReadProcessMemory(hProcess, addr1, dst, alloc_size, &bytes_read);
103     ok(b && (bytes_read == alloc_size), "%lu bytes read\n", bytes_read);
104     ok(!memcmp(src, dst, alloc_size), "Data from remote process differs\n");
105
106     /* test invalid source buffers */
107
108     b = VirtualProtect( src + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot );
109     ok( b, "VirtualProtect failed error %u\n", GetLastError() );
110     b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
111     ok( !b, "WriteProcessMemory succeeded\n" );
112     ok( GetLastError() == ERROR_NOACCESS ||
113         GetLastError() == ERROR_PARTIAL_COPY, /* vista */
114         "wrong error %u\n", GetLastError() );
115     ok( bytes_written == 0, "%lu bytes written\n", bytes_written );
116     b = ReadProcessMemory(hProcess, addr1, src, alloc_size, &bytes_read);
117     ok( !b, "ReadProcessMemory succeeded\n" );
118     ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
119     ok( bytes_read == 0, "%lu bytes written\n", bytes_read );
120
121     b = VirtualProtect( src, 0x2000, PAGE_NOACCESS, &old_prot );
122     ok( b, "VirtualProtect failed error %u\n", GetLastError() );
123     b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
124     ok( !b, "WriteProcessMemory succeeded\n" );
125     ok( GetLastError() == ERROR_NOACCESS ||
126         GetLastError() == ERROR_PARTIAL_COPY, /* vista */
127         "wrong error %u\n", GetLastError() );
128     ok( bytes_written == 0, "%lu bytes written\n", bytes_written );
129     b = ReadProcessMemory(hProcess, addr1, src, alloc_size, &bytes_read);
130     ok( !b, "ReadProcessMemory succeeded\n" );
131     ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
132     ok( bytes_read == 0, "%lu bytes written\n", bytes_read );
133
134     b = pVirtualFreeEx(hProcess, addr1, 0, MEM_RELEASE);
135     ok(b != 0, "VirtualFreeEx, error %u\n", GetLastError());
136
137     VirtualFree( src, 0, MEM_FREE );
138     VirtualFree( dst, 0, MEM_FREE );
139
140     /*
141      * The following tests parallel those in test_VirtualAlloc()
142      */
143
144     SetLastError(0xdeadbeef);
145     addr1 = pVirtualAllocEx(hProcess, 0, 0, MEM_RESERVE, PAGE_NOACCESS);
146     ok(addr1 == NULL, "VirtualAllocEx should fail on zero-sized allocation\n");
147     ok(GetLastError() == ERROR_INVALID_PARAMETER /* NT */ ||
148        GetLastError() == ERROR_NOT_ENOUGH_MEMORY, /* Win9x */
149         "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
150
151     addr1 = pVirtualAllocEx(hProcess, 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS);
152     ok(addr1 != NULL, "VirtualAllocEx failed\n");
153
154     /* test a not committed memory */
155     memset(&info, 'q', sizeof(info));
156     ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info)) == sizeof(info), "VirtualQueryEx failed\n");
157     ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
158     ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
159     ok(info.AllocationProtect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.AllocationProtect);
160     ok(info.RegionSize == 0x10000, "%lx != 0x10000\n", info.RegionSize);
161     ok(info.State == MEM_RESERVE, "%x != MEM_RESERVE\n", info.State);
162     /* NT reports Protect == 0 for a not committed memory block */
163     ok(info.Protect == 0 /* NT */ ||
164        info.Protect == PAGE_NOACCESS, /* Win9x */
165         "%x != PAGE_NOACCESS\n", info.Protect);
166     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
167
168     SetLastError(0xdeadbeef);
169     ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
170        "VirtualProtectEx should fail on a not committed memory\n");
171     ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
172        GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
173         "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
174
175     addr2 = pVirtualAllocEx(hProcess, addr1, 0x1000, MEM_COMMIT, PAGE_NOACCESS);
176     ok(addr1 == addr2, "VirtualAllocEx failed\n");
177
178     /* test a committed memory */
179     ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info)) == sizeof(info),
180         "VirtualQueryEx failed\n");
181     ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
182     ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
183     ok(info.AllocationProtect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.AllocationProtect);
184     ok(info.RegionSize == 0x1000, "%lx != 0x1000\n", info.RegionSize);
185     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
186     /* this time NT reports PAGE_NOACCESS as well */
187     ok(info.Protect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.Protect);
188     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
189
190     /* this should fail, since not the whole range is committed yet */
191     SetLastError(0xdeadbeef);
192     ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
193         "VirtualProtectEx should fail on a not committed memory\n");
194     ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
195        GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
196         "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
197
198     old_prot = 0;
199     ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtectEx failed\n");
200     ok(old_prot == PAGE_NOACCESS, "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot);
201
202     old_prot = 0;
203     ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtectEx failed\n");
204     ok(old_prot == PAGE_READONLY, "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot);
205
206     ok(!pVirtualFreeEx(hProcess, addr1, 0x10000, 0),
207        "VirtualFreeEx should fail with type 0\n");
208     ok(GetLastError() == ERROR_INVALID_PARAMETER,
209         "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
210
211     ok(pVirtualFreeEx(hProcess, addr1, 0x10000, MEM_DECOMMIT), "VirtualFreeEx failed\n");
212
213     /* if the type is MEM_RELEASE, size must be 0 */
214     ok(!pVirtualFreeEx(hProcess, addr1, 1, MEM_RELEASE),
215        "VirtualFreeEx should fail\n");
216     ok(GetLastError() == ERROR_INVALID_PARAMETER,
217         "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
218
219     ok(pVirtualFreeEx(hProcess, addr1, 0, MEM_RELEASE), "VirtualFreeEx failed\n");
220
221     TerminateProcess(hProcess, 0);
222     CloseHandle(hProcess);
223 }
224
225 static void test_VirtualAlloc(void)
226 {
227     void *addr1, *addr2;
228     DWORD old_prot;
229     MEMORY_BASIC_INFORMATION info;
230
231     SetLastError(0xdeadbeef);
232     addr1 = VirtualAlloc(0, 0, MEM_RESERVE, PAGE_NOACCESS);
233     ok(addr1 == NULL, "VirtualAlloc should fail on zero-sized allocation\n");
234     ok(GetLastError() == ERROR_INVALID_PARAMETER /* NT */ ||
235        GetLastError() == ERROR_NOT_ENOUGH_MEMORY, /* Win9x */
236         "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
237
238     addr1 = VirtualAlloc(0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS);
239     ok(addr1 != NULL, "VirtualAlloc failed\n");
240
241     /* test a not committed memory */
242     ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
243         "VirtualQuery failed\n");
244     ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
245     ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
246     ok(info.AllocationProtect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.AllocationProtect);
247     ok(info.RegionSize == 0x10000, "%lx != 0x10000\n", info.RegionSize);
248     ok(info.State == MEM_RESERVE, "%x != MEM_RESERVE\n", info.State);
249     /* NT reports Protect == 0 for a not committed memory block */
250     ok(info.Protect == 0 /* NT */ ||
251        info.Protect == PAGE_NOACCESS, /* Win9x */
252         "%x != PAGE_NOACCESS\n", info.Protect);
253     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
254
255     SetLastError(0xdeadbeef);
256     ok(!VirtualProtect(addr1, 0xFFFC, PAGE_READONLY, &old_prot),
257        "VirtualProtect should fail on a not committed memory\n");
258     ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
259        GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
260         "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
261
262     addr2 = VirtualAlloc(addr1, 0x1000, MEM_COMMIT, PAGE_NOACCESS);
263     ok(addr1 == addr2, "VirtualAlloc failed\n");
264
265     /* test a committed memory */
266     ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
267         "VirtualQuery failed\n");
268     ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
269     ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
270     ok(info.AllocationProtect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.AllocationProtect);
271     ok(info.RegionSize == 0x1000, "%lx != 0x1000\n", info.RegionSize);
272     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
273     /* this time NT reports PAGE_NOACCESS as well */
274     ok(info.Protect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.Protect);
275     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
276
277     /* this should fail, since not the whole range is committed yet */
278     SetLastError(0xdeadbeef);
279     ok(!VirtualProtect(addr1, 0xFFFC, PAGE_READONLY, &old_prot),
280         "VirtualProtect should fail on a not committed memory\n");
281     ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
282        GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
283         "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
284
285     ok(VirtualProtect(addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtect failed\n");
286     ok(old_prot == PAGE_NOACCESS,
287         "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot);
288
289     ok(VirtualProtect(addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtect failed\n");
290     ok(old_prot == PAGE_READONLY,
291         "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot);
292
293     ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
294         "VirtualQuery failed\n");
295     ok(info.RegionSize == 0x1000, "%lx != 0x1000\n", info.RegionSize);
296     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
297     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
298     memset( addr1, 0x55, 20 );
299     ok( *(DWORD *)addr1 == 0x55555555, "wrong data %x\n", *(DWORD *)addr1 );
300
301     addr2 = VirtualAlloc( addr1, 0x1000, MEM_RESET, PAGE_NOACCESS );
302     ok( addr2 == addr1 || broken( !addr2 && GetLastError() == ERROR_INVALID_PARAMETER), /* win9x */
303         "VirtualAlloc failed err %u\n", GetLastError() );
304     ok( *(DWORD *)addr1 == 0x55555555 || *(DWORD *)addr1 == 0, "wrong data %x\n", *(DWORD *)addr1 );
305     if (addr2)
306     {
307         ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
308            "VirtualQuery failed\n");
309         ok(info.RegionSize == 0x1000, "%lx != 0x1000\n", info.RegionSize);
310         ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
311         ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
312
313         addr2 = VirtualAlloc( (char *)addr1 + 0x1000, 0x1000, MEM_RESET, PAGE_NOACCESS );
314         ok( (char *)addr2 == (char *)addr1 + 0x1000, "VirtualAlloc failed\n" );
315
316         ok(VirtualQuery(addr2, &info, sizeof(info)) == sizeof(info),
317            "VirtualQuery failed\n");
318         ok(info.RegionSize == 0xf000, "%lx != 0xf000\n", info.RegionSize);
319         ok(info.State == MEM_RESERVE, "%x != MEM_RESERVE\n", info.State);
320         ok(info.Protect == 0, "%x != 0\n", info.Protect);
321
322         addr2 = VirtualAlloc( (char *)addr1 + 0xf000, 0x2000, MEM_RESET, PAGE_NOACCESS );
323         ok( !addr2, "VirtualAlloc failed\n" );
324         ok( GetLastError() == ERROR_INVALID_ADDRESS, "wrong error %u\n", GetLastError() );
325     }
326
327     /* invalid protection values */
328     SetLastError(0xdeadbeef);
329     addr2 = VirtualAlloc(NULL, 0x1000, MEM_RESERVE, 0);
330     ok(!addr2, "VirtualAlloc succeeded\n");
331     ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
332
333     SetLastError(0xdeadbeef);
334     addr2 = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, 0);
335     ok(!addr2, "VirtualAlloc succeeded\n");
336     ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
337
338     SetLastError(0xdeadbeef);
339     addr2 = VirtualAlloc(addr1, 0x1000, MEM_COMMIT, PAGE_READONLY | PAGE_EXECUTE);
340     ok(!addr2, "VirtualAlloc succeeded\n");
341     ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
342
343     SetLastError(0xdeadbeef);
344     ok(!VirtualProtect(addr1, 0x1000, PAGE_READWRITE | PAGE_EXECUTE_WRITECOPY, &old_prot),
345        "VirtualProtect succeeded\n");
346     ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
347
348     SetLastError(0xdeadbeef);
349     ok(!VirtualProtect(addr1, 0x1000, 0, &old_prot), "VirtualProtect succeeded\n");
350     ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
351
352     SetLastError(0xdeadbeef);
353     ok(!VirtualFree(addr1, 0x10000, 0), "VirtualFree should fail with type 0\n");
354     ok(GetLastError() == ERROR_INVALID_PARAMETER,
355         "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
356
357     ok(VirtualFree(addr1, 0x10000, MEM_DECOMMIT), "VirtualFree failed\n");
358
359     /* if the type is MEM_RELEASE, size must be 0 */
360     ok(!VirtualFree(addr1, 1, MEM_RELEASE), "VirtualFree should fail\n");
361     ok(GetLastError() == ERROR_INVALID_PARAMETER,
362         "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
363
364     ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
365 }
366
367 static void test_MapViewOfFile(void)
368 {
369     static const char testfile[] = "testfile.xxx";
370     const char *name;
371     HANDLE file, mapping, map2;
372     void *ptr, *ptr2, *addr;
373     MEMORY_BASIC_INFORMATION info;
374     BOOL ret;
375
376     SetLastError(0xdeadbeef);
377     file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
378     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
379     SetFilePointer( file, 4096, NULL, FILE_BEGIN );
380     SetEndOfFile( file );
381
382     /* read/write mapping */
383
384     SetLastError(0xdeadbeef);
385     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
386     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
387
388     SetLastError(0xdeadbeef);
389     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
390     ok( ptr != NULL, "MapViewOfFile FILE_MAPE_READ error %u\n", GetLastError() );
391     UnmapViewOfFile( ptr );
392
393     /* this fails on win9x but succeeds on NT */
394     SetLastError(0xdeadbeef);
395     ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
396     if (ptr) UnmapViewOfFile( ptr );
397     else ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
398
399     SetLastError(0xdeadbeef);
400     ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
401     ok( ptr != NULL, "MapViewOfFile 0 error %u\n", GetLastError() );
402     UnmapViewOfFile( ptr );
403
404     SetLastError(0xdeadbeef);
405     ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
406     ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
407     UnmapViewOfFile( ptr );
408
409     ret = DuplicateHandle( GetCurrentProcess(), mapping, GetCurrentProcess(), &map2,
410                            FILE_MAP_READ|FILE_MAP_WRITE, FALSE, 0 );
411     ok( ret, "DuplicateHandle failed error %u\n", GetLastError());
412     ptr = MapViewOfFile( map2, FILE_MAP_WRITE, 0, 0, 4096 );
413     ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
414     UnmapViewOfFile( ptr );
415     CloseHandle( map2 );
416
417     ret = DuplicateHandle( GetCurrentProcess(), mapping, GetCurrentProcess(), &map2,
418                            FILE_MAP_READ, FALSE, 0 );
419     ok( ret, "DuplicateHandle failed error %u\n", GetLastError());
420     ptr = MapViewOfFile( map2, FILE_MAP_WRITE, 0, 0, 4096 );
421     if (!ptr)
422     {
423         ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
424         CloseHandle( map2 );
425         ret = DuplicateHandle( GetCurrentProcess(), mapping, GetCurrentProcess(), &map2, 0, FALSE, 0 );
426         ok( ret, "DuplicateHandle failed error %u\n", GetLastError());
427         ptr = MapViewOfFile( map2, 0, 0, 0, 4096 );
428         ok( !ptr, "MapViewOfFile succeeded\n" );
429         ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
430         CloseHandle( map2 );
431         ret = DuplicateHandle( GetCurrentProcess(), mapping, GetCurrentProcess(), &map2,
432                                FILE_MAP_READ, FALSE, 0 );
433         ok( ret, "DuplicateHandle failed error %u\n", GetLastError());
434         ptr = MapViewOfFile( map2, 0, 0, 0, 4096 );
435         ok( ptr != NULL, "MapViewOfFile NO_ACCESS error %u\n", GetLastError() );
436     }
437     else win_skip( "no access checks on win9x\n" );
438
439     UnmapViewOfFile( ptr );
440     CloseHandle( map2 );
441     CloseHandle( mapping );
442
443     /* read-only mapping */
444
445     SetLastError(0xdeadbeef);
446     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
447     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
448
449     SetLastError(0xdeadbeef);
450     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
451     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
452     UnmapViewOfFile( ptr );
453
454     /* this fails on win9x but succeeds on NT */
455     SetLastError(0xdeadbeef);
456     ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
457     if (ptr) UnmapViewOfFile( ptr );
458     else ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
459
460     SetLastError(0xdeadbeef);
461     ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
462     ok( ptr != NULL, "MapViewOfFile 0 error %u\n", GetLastError() );
463     UnmapViewOfFile( ptr );
464
465     SetLastError(0xdeadbeef);
466     ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
467     ok( !ptr, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
468     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
469         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
470     CloseHandle( mapping );
471
472     /* copy-on-write mapping */
473
474     SetLastError(0xdeadbeef);
475     mapping = CreateFileMappingA( file, NULL, PAGE_WRITECOPY, 0, 4096, NULL );
476     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
477
478     SetLastError(0xdeadbeef);
479     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
480     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
481     UnmapViewOfFile( ptr );
482
483     SetLastError(0xdeadbeef);
484     ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
485     ok( ptr != NULL, "MapViewOfFile FILE_MAP_COPY error %u\n", GetLastError() );
486     UnmapViewOfFile( ptr );
487
488     SetLastError(0xdeadbeef);
489     ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
490     ok( ptr != NULL, "MapViewOfFile 0 error %u\n", GetLastError() );
491     UnmapViewOfFile( ptr );
492
493     SetLastError(0xdeadbeef);
494     ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
495     ok( !ptr, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
496     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
497         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
498     CloseHandle( mapping );
499
500     /* no access mapping */
501
502     SetLastError(0xdeadbeef);
503     mapping = CreateFileMappingA( file, NULL, PAGE_NOACCESS, 0, 4096, NULL );
504     /* fails on NT but succeeds on win9x */
505     if (!mapping) ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
506     else
507     {
508         SetLastError(0xdeadbeef);
509         ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
510         ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
511         UnmapViewOfFile( ptr );
512
513         SetLastError(0xdeadbeef);
514         ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
515         ok( !ptr, "MapViewOfFile FILE_MAP_COPY succeeded\n" );
516         ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
517
518         SetLastError(0xdeadbeef);
519         ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
520         ok( ptr != NULL, "MapViewOfFile 0 error %u\n", GetLastError() );
521         UnmapViewOfFile( ptr );
522
523         SetLastError(0xdeadbeef);
524         ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
525         ok( !ptr, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
526         ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
527
528         CloseHandle( mapping );
529     }
530
531     CloseHandle( file );
532
533     /* now try read-only file */
534
535     SetLastError(0xdeadbeef);
536     file = CreateFileA( testfile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
537     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
538
539     SetLastError(0xdeadbeef);
540     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
541     ok( !mapping, "CreateFileMapping PAGE_READWRITE succeeded\n" );
542     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
543         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
544
545     SetLastError(0xdeadbeef);
546     mapping = CreateFileMappingA( file, NULL, PAGE_WRITECOPY, 0, 4096, NULL );
547     ok( mapping != 0, "CreateFileMapping PAGE_WRITECOPY error %u\n", GetLastError() );
548     CloseHandle( mapping );
549
550     SetLastError(0xdeadbeef);
551     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
552     ok( mapping != 0, "CreateFileMapping PAGE_READONLY error %u\n", GetLastError() );
553     CloseHandle( mapping );
554     CloseHandle( file );
555
556     /* now try no access file */
557
558     SetLastError(0xdeadbeef);
559     file = CreateFileA( testfile, 0, 0, NULL, OPEN_EXISTING, 0, 0 );
560     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
561
562     SetLastError(0xdeadbeef);
563     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
564     ok( !mapping, "CreateFileMapping PAGE_READWRITE succeeded\n" );
565     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
566         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
567
568     SetLastError(0xdeadbeef);
569     mapping = CreateFileMappingA( file, NULL, PAGE_WRITECOPY, 0, 4096, NULL );
570     ok( !mapping, "CreateFileMapping PAGE_WRITECOPY succeeded\n" );
571     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
572         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
573
574     SetLastError(0xdeadbeef);
575     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
576     ok( !mapping, "CreateFileMapping PAGE_READONLY succeeded\n" );
577     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
578         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
579
580     CloseHandle( file );
581     DeleteFileA( testfile );
582
583     SetLastError(0xdeadbeef);
584     name = "Local\\Foo";
585     file = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name );
586     /* nt4 doesn't have Local\\ */
587     if (!file && GetLastError() == ERROR_PATH_NOT_FOUND)
588     {
589         name = "Foo";
590         file = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name );
591     }
592     ok( file != 0, "CreateFileMapping PAGE_READWRITE error %u\n", GetLastError() );
593
594     SetLastError(0xdeadbeef);
595     mapping = OpenFileMapping( FILE_MAP_READ, FALSE, name );
596     ok( mapping != 0, "OpenFileMapping FILE_MAP_READ error %u\n", GetLastError() );
597     SetLastError(0xdeadbeef);
598     ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
599     if (!ptr)
600     {
601         SIZE_T size;
602         ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
603         SetLastError(0xdeadbeef);
604         ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
605         ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
606         SetLastError(0xdeadbeef);
607         size = VirtualQuery( ptr, &info, sizeof(info) );
608         ok( size == sizeof(info),
609             "VirtualQuery error %u\n", GetLastError() );
610         ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
611         ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
612         ok( info.AllocationProtect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.AllocationProtect );
613         ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
614         ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
615         ok( info.Protect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.Protect );
616     }
617     else win_skip( "no access checks on win9x\n" );
618     UnmapViewOfFile( ptr );
619     CloseHandle( mapping );
620
621     SetLastError(0xdeadbeef);
622     mapping = OpenFileMapping( FILE_MAP_WRITE, FALSE, name );
623     ok( mapping != 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() );
624     SetLastError(0xdeadbeef);
625     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
626     if (!ptr)
627     {
628         SIZE_T size;
629         ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
630         SetLastError(0xdeadbeef);
631         ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
632         ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
633         SetLastError(0xdeadbeef);
634         size = VirtualQuery( ptr, &info, sizeof(info) );
635         ok( size == sizeof(info),
636             "VirtualQuery error %u\n", GetLastError() );
637         ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
638         ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
639         ok( info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect );
640         ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
641         ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
642         ok( info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect );
643     }
644     else win_skip( "no access checks on win9x\n" );
645     UnmapViewOfFile( ptr );
646     CloseHandle( mapping );
647
648     CloseHandle( file );
649
650     /* read/write mapping with SEC_RESERVE */
651     mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE, 0, MAPPING_SIZE, NULL);
652     ok(mapping != INVALID_HANDLE_VALUE, "CreateFileMappingA failed with error %d\n", GetLastError());
653
654     ptr = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
655     ok(ptr != NULL, "MapViewOfFile failed with error %d\n", GetLastError());
656
657     ptr2 = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
658     /* on NT ptr != ptr2 but on Win9x ptr == ptr2 */
659     ok(ptr2 != NULL, "MapViewOfFile failed with error %d\n", GetLastError());
660     trace("mapping same section resulted in views %p and %p\n", ptr, ptr2);
661
662     ret = VirtualQuery(ptr, &info, sizeof(info));
663     ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
664     ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
665     ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
666     ok(info.RegionSize == MAPPING_SIZE, "RegionSize should have been 0x%x but was 0x%x\n", MAPPING_SIZE, (unsigned int)info.RegionSize);
667     ok(info.State == MEM_RESERVE, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
668     if (info.Type == MEM_PRIVATE)  /* win9x is different for uncommitted mappings */
669     {
670         ok(info.AllocationProtect == PAGE_NOACCESS,
671            "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info.AllocationProtect);
672         ok(info.Protect == PAGE_NOACCESS,
673            "Protect should have been PAGE_NOACCESS instead of 0x%x\n", info.Protect);
674     }
675     else
676     {
677         ok(info.AllocationProtect == PAGE_READWRITE,
678            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
679         ok(info.Protect == 0, "Protect should have been 0 instead of 0x%x\n", info.Protect);
680         ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
681     }
682
683     if (ptr != ptr2)
684     {
685         ret = VirtualQuery(ptr2, &info, sizeof(info));
686         ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
687         ok(info.BaseAddress == ptr2,
688            "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
689         ok(info.AllocationBase == ptr2,
690            "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
691         ok(info.AllocationProtect == PAGE_READWRITE,
692            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
693         ok(info.RegionSize == MAPPING_SIZE,
694            "RegionSize should have been 0x%x but was 0x%x\n", MAPPING_SIZE, (unsigned int)info.RegionSize);
695         ok(info.State == MEM_RESERVE,
696            "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
697         ok(info.Protect == 0,
698            "Protect should have been 0 instead of 0x%x\n", info.Protect);
699         ok(info.Type == MEM_MAPPED,
700            "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
701     }
702
703     ptr = VirtualAlloc(ptr, 0x10000, MEM_COMMIT, PAGE_READONLY);
704     ok(ptr != NULL, "VirtualAlloc failed with error %d\n", GetLastError());
705
706     ret = VirtualQuery(ptr, &info, sizeof(info));
707     ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
708     ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
709     ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
710     ok(info.RegionSize == 0x10000, "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info.RegionSize);
711     ok(info.State == MEM_COMMIT, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
712     ok(info.Protect == PAGE_READONLY, "Protect should have been 0 instead of 0x%x\n", info.Protect);
713     if (info.Type == MEM_PRIVATE)  /* win9x is different for uncommitted mappings */
714     {
715         ok(info.AllocationProtect == PAGE_NOACCESS,
716            "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info.AllocationProtect);
717     }
718     else
719     {
720         ok(info.AllocationProtect == PAGE_READWRITE,
721            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
722         ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
723     }
724
725     /* shows that the VirtualAlloc above affects the mapping, not just the
726      * virtual memory in this process - it also affects all other processes
727      * with a view of the mapping, but that isn't tested here */
728     if (ptr != ptr2)
729     {
730         ret = VirtualQuery(ptr2, &info, sizeof(info));
731         ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
732         ok(info.BaseAddress == ptr2,
733            "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
734         ok(info.AllocationBase == ptr2,
735            "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
736         ok(info.AllocationProtect == PAGE_READWRITE,
737            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
738         ok(info.RegionSize == 0x10000,
739            "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info.RegionSize);
740         ok(info.State == MEM_COMMIT,
741            "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
742         ok(info.Protect == PAGE_READWRITE,
743            "Protect should have been 0 instead of 0x%x\n", info.Protect);
744         ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
745     }
746
747     addr = VirtualAlloc( ptr, MAPPING_SIZE, MEM_RESET, PAGE_READONLY );
748     ok( addr == ptr || broken(!addr && GetLastError() == ERROR_INVALID_PARAMETER), /* win9x */
749         "VirtualAlloc failed with error %u\n", GetLastError() );
750
751     ret = VirtualFree( ptr, 0x10000, MEM_DECOMMIT );
752     ok( !ret || broken(ret) /* win9x */, "VirtualFree succeeded\n" );
753     if (!ret)
754         ok( GetLastError() == ERROR_INVALID_PARAMETER, "VirtualFree failed with %u\n", GetLastError() );
755
756     ret = UnmapViewOfFile(ptr2);
757     ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError());
758     ret = UnmapViewOfFile(ptr);
759     ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError());
760     CloseHandle(mapping);
761
762     addr = VirtualAlloc(NULL, 0x10000, MEM_COMMIT, PAGE_READONLY );
763     ok( addr != NULL, "VirtualAlloc failed with error %u\n", GetLastError() );
764
765     SetLastError(0xdeadbeef);
766     ok( !UnmapViewOfFile(addr), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
767     ok( GetLastError() == ERROR_INVALID_ADDRESS,
768         "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
769     SetLastError(0xdeadbeef);
770     ok( !UnmapViewOfFile((char *)addr + 0x3000), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
771     ok( GetLastError() == ERROR_INVALID_ADDRESS,
772         "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
773     SetLastError(0xdeadbeef);
774     ok( !UnmapViewOfFile((void *)0xdeadbeef), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
775     ok( GetLastError() == ERROR_INVALID_ADDRESS,
776        "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
777
778     ok( VirtualFree(addr, 0, MEM_RELEASE), "VirtualFree failed\n" );
779 }
780
781 static DWORD (WINAPI *pNtMapViewOfSection)( HANDLE handle, HANDLE process, PVOID *addr_ptr,
782                                             ULONG zero_bits, SIZE_T commit_size,
783                                             const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
784                                             ULONG inherit, ULONG alloc_type, ULONG protect );
785 static DWORD (WINAPI *pNtUnmapViewOfSection)( HANDLE process, PVOID addr );
786
787 static void test_NtMapViewOfSection(void)
788 {
789     HANDLE hProcess;
790
791     static const char testfile[] = "testfile.xxx";
792     static const char data[] = "test data for NtMapViewOfSection";
793     char buffer[sizeof(data)];
794     HANDLE file, mapping;
795     void *ptr;
796     BOOL ret;
797     DWORD status, written;
798     SIZE_T size, result;
799     LARGE_INTEGER offset;
800
801     pNtMapViewOfSection = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"), "NtMapViewOfSection" );
802     pNtUnmapViewOfSection = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"), "NtUnmapViewOfSection" );
803     if (!pNtMapViewOfSection || !pNtUnmapViewOfSection)
804     {
805         win_skip( "NtMapViewOfSection not available\n" );
806         return;
807     }
808
809     file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
810     ok( file != INVALID_HANDLE_VALUE, "Failed to create test file\n" );
811     WriteFile( file, data, sizeof(data), &written, NULL );
812     SetFilePointer( file, 4096, NULL, FILE_BEGIN );
813     SetEndOfFile( file );
814
815     /* read/write mapping */
816
817     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
818     ok( mapping != 0, "CreateFileMapping failed\n" );
819
820     hProcess = create_target_process("sleep");
821     ok(hProcess != NULL, "Can't start process\n");
822
823     ptr = NULL;
824     size = 0;
825     offset.QuadPart = 0;
826     status = pNtMapViewOfSection( mapping, hProcess, &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE );
827     ok( !status, "NtMapViewOfSection failed status %x\n", status );
828
829     ret = ReadProcessMemory( hProcess, ptr, buffer, sizeof(buffer), &result );
830     ok( ret, "ReadProcessMemory failed\n" );
831     ok( result == sizeof(buffer), "ReadProcessMemory didn't read all data (%lx)\n", result );
832     ok( !memcmp( buffer, data, sizeof(buffer) ), "Wrong data read\n" );
833
834     status = pNtUnmapViewOfSection( hProcess, ptr );
835     ok( !status, "NtUnmapViewOfSection failed status %x\n", status );
836
837     CloseHandle( mapping );
838     CloseHandle( file );
839     DeleteFileA( testfile );
840
841     TerminateProcess(hProcess, 0);
842     CloseHandle(hProcess);
843 }
844
845 static void test_NtAreMappedFilesTheSame(void)
846 {
847     static const char testfile[] = "testfile.xxx";
848     HANDLE file, file2, mapping, map2;
849     void *ptr, *ptr2;
850     NTSTATUS status;
851     char path[MAX_PATH];
852
853     if (!pNtAreMappedFilesTheSame)
854     {
855         win_skip( "NtAreMappedFilesTheSame not available\n" );
856         return;
857     }
858
859     file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
860                         NULL, CREATE_ALWAYS, 0, 0 );
861     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
862     SetFilePointer( file, 4096, NULL, FILE_BEGIN );
863     SetEndOfFile( file );
864
865     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
866     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
867
868     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
869     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
870
871     file2 = CreateFileA( testfile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
872                          NULL, OPEN_EXISTING, 0, 0 );
873     ok( file2 != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
874
875     map2 = CreateFileMappingA( file2, NULL, PAGE_READONLY, 0, 4096, NULL );
876     ok( map2 != 0, "CreateFileMapping error %u\n", GetLastError() );
877     ptr2 = MapViewOfFile( map2, 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 );
882
883     ptr2 = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
884     ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
885     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
886     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
887     UnmapViewOfFile( ptr2 );
888     CloseHandle( map2 );
889
890     map2 = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
891     ok( map2 != 0, "CreateFileMapping error %u\n", GetLastError() );
892     ptr2 = MapViewOfFile( map2, FILE_MAP_READ, 0, 0, 4096 );
893     ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
894     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
895     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
896     UnmapViewOfFile( ptr2 );
897     CloseHandle( map2 );
898     CloseHandle( file2 );
899
900     status = pNtAreMappedFilesTheSame( ptr, ptr );
901     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
902
903     status = pNtAreMappedFilesTheSame( ptr, (char *)ptr + 30 );
904     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
905
906     status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
907     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
908
909     status = pNtAreMappedFilesTheSame( ptr, (void *)0xdeadbeef );
910     ok( status == STATUS_CONFLICTING_ADDRESSES || status == STATUS_INVALID_ADDRESS,
911         "NtAreMappedFilesTheSame returned %x\n", status );
912
913     status = pNtAreMappedFilesTheSame( ptr, NULL );
914     ok( status == STATUS_INVALID_ADDRESS, "NtAreMappedFilesTheSame returned %x\n", status );
915
916     status = pNtAreMappedFilesTheSame( ptr, (void *)GetProcessHeap() );
917     ok( status == STATUS_CONFLICTING_ADDRESSES, "NtAreMappedFilesTheSame returned %x\n", status );
918
919     status = pNtAreMappedFilesTheSame( NULL, NULL );
920     ok( status == STATUS_INVALID_ADDRESS, "NtAreMappedFilesTheSame returned %x\n", status );
921
922     ptr2 = VirtualAlloc( NULL, 0x10000, MEM_COMMIT, PAGE_READWRITE );
923     ok( ptr2 != NULL, "VirtualAlloc error %u\n", GetLastError() );
924     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
925     ok( status == STATUS_CONFLICTING_ADDRESSES, "NtAreMappedFilesTheSame returned %x\n", status );
926     VirtualFree( ptr2, 0, MEM_RELEASE );
927
928     UnmapViewOfFile( ptr );
929     CloseHandle( mapping );
930     CloseHandle( file );
931
932     status = pNtAreMappedFilesTheSame( GetModuleHandleA("ntdll.dll"),
933                                        GetModuleHandleA("kernel32.dll") );
934     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
935     status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
936                                        GetModuleHandleA("kernel32.dll") );
937     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
938     status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
939                                        (char *)GetModuleHandleA("kernel32.dll") + 4096 );
940     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
941
942     GetSystemDirectoryA( path, MAX_PATH );
943     strcat( path, "\\kernel32.dll" );
944     file = CreateFileA( path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
945     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
946
947     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
948     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
949     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
950     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
951     status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
952     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
953     UnmapViewOfFile( ptr );
954     CloseHandle( mapping );
955
956     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL );
957     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
958     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
959     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
960     status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
961     todo_wine
962     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
963
964     file2 = CreateFileA( path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
965     ok( file2 != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
966     map2 = CreateFileMappingA( file2, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL );
967     ok( map2 != 0, "CreateFileMapping error %u\n", GetLastError() );
968     ptr2 = MapViewOfFile( map2, FILE_MAP_READ, 0, 0, 0 );
969     ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
970     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
971     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
972     UnmapViewOfFile( ptr2 );
973     CloseHandle( map2 );
974     CloseHandle( file2 );
975
976     UnmapViewOfFile( ptr );
977     CloseHandle( mapping );
978
979     CloseHandle( file );
980     DeleteFileA( testfile );
981 }
982
983 static void test_CreateFileMapping(void)
984 {
985     HANDLE handle, handle2;
986
987     /* test case sensitivity */
988
989     SetLastError(0xdeadbeef);
990     handle = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, 0x1000,
991                                  "Wine Test Mapping");
992     ok( handle != NULL, "CreateFileMapping failed with error %u\n", GetLastError());
993     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
994
995     SetLastError(0xdeadbeef);
996     handle2 = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, 0x1000,
997                                   "Wine Test Mapping");
998     ok( handle2 != NULL, "CreateFileMapping failed with error %d\n", GetLastError());
999     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
1000     CloseHandle( handle2 );
1001
1002     SetLastError(0xdeadbeef);
1003     handle2 = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, 0x1000,
1004                                  "WINE TEST MAPPING");
1005     ok( handle2 != NULL, "CreateFileMapping failed with error %d\n", GetLastError());
1006     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
1007     CloseHandle( handle2 );
1008
1009     SetLastError(0xdeadbeef);
1010     handle2 = OpenFileMappingA( FILE_MAP_ALL_ACCESS, FALSE, "Wine Test Mapping");
1011     ok( handle2 != NULL, "OpenFileMapping failed with error %d\n", GetLastError());
1012     CloseHandle( handle2 );
1013
1014     SetLastError(0xdeadbeef);
1015     handle2 = OpenFileMappingA( FILE_MAP_ALL_ACCESS, FALSE, "WINE TEST MAPPING");
1016     ok( !handle2, "OpenFileMapping succeeded\n");
1017     ok( GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_NAME /* win9x */,
1018         "wrong error %u\n", GetLastError());
1019
1020     CloseHandle( handle );
1021 }
1022
1023 static void test_IsBadReadPtr(void)
1024 {
1025     BOOL ret;
1026     void *ptr = (void *)0xdeadbeef;
1027     char stackvar;
1028
1029     ret = IsBadReadPtr(NULL, 0);
1030     ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1031
1032     ret = IsBadReadPtr(NULL, 1);
1033     ok(ret == TRUE, "Expected IsBadReadPtr to return TRUE, got %d\n", ret);
1034
1035     ret = IsBadReadPtr(ptr, 0);
1036     ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1037
1038     ret = IsBadReadPtr(ptr, 1);
1039     ok(ret == TRUE, "Expected IsBadReadPtr to return TRUE, got %d\n", ret);
1040
1041     ret = IsBadReadPtr(&stackvar, 0);
1042     ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1043
1044     ret = IsBadReadPtr(&stackvar, sizeof(char));
1045     ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1046 }
1047
1048 static void test_IsBadWritePtr(void)
1049 {
1050     BOOL ret;
1051     void *ptr = (void *)0xdeadbeef;
1052     char stackval;
1053
1054     ret = IsBadWritePtr(NULL, 0);
1055     ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1056
1057     ret = IsBadWritePtr(NULL, 1);
1058     ok(ret == TRUE, "Expected IsBadWritePtr to return TRUE, got %d\n", ret);
1059
1060     ret = IsBadWritePtr(ptr, 0);
1061     ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1062
1063     ret = IsBadWritePtr(ptr, 1);
1064     ok(ret == TRUE, "Expected IsBadWritePtr to return TRUE, got %d\n", ret);
1065
1066     ret = IsBadWritePtr(&stackval, 0);
1067     ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1068
1069     ret = IsBadWritePtr(&stackval, sizeof(char));
1070     ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1071 }
1072
1073 static void test_IsBadCodePtr(void)
1074 {
1075     BOOL ret;
1076     void *ptr = (void *)0xdeadbeef;
1077     char stackval;
1078
1079     ret = IsBadCodePtr(NULL);
1080     ok(ret == TRUE, "Expected IsBadCodePtr to return TRUE, got %d\n", ret);
1081
1082     ret = IsBadCodePtr(ptr);
1083     ok(ret == TRUE, "Expected IsBadCodePtr to return TRUE, got %d\n", ret);
1084
1085     ret = IsBadCodePtr((void *)&stackval);
1086     ok(ret == FALSE, "Expected IsBadCodePtr to return FALSE, got %d\n", ret);
1087 }
1088
1089 static void test_write_watch(void)
1090 {
1091     char *base;
1092     DWORD ret, size, old_prot;
1093     MEMORY_BASIC_INFORMATION info;
1094     void *results[64];
1095     ULONG_PTR count;
1096     ULONG pagesize;
1097
1098     if (!pGetWriteWatch || !pResetWriteWatch)
1099     {
1100         win_skip( "GetWriteWatch not supported\n" );
1101         return;
1102     }
1103
1104     size = 0x10000;
1105     base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE );
1106     if (!base &&
1107         (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED))
1108     {
1109         win_skip( "MEM_WRITE_WATCH not supported\n" );
1110         return;
1111     }
1112     ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
1113     ret = VirtualQuery( base, &info, sizeof(info) );
1114     ok(ret, "VirtualQuery failed %u\n", GetLastError());
1115     ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
1116     ok( info.AllocationProtect == PAGE_READWRITE, "wrong AllocationProtect %x\n", info.AllocationProtect );
1117     ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
1118     ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
1119     ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%x\n", info.Protect );
1120     ok( info.Type == MEM_PRIVATE, "wrong Type 0x%x\n", info.Type );
1121
1122     count = 64;
1123     SetLastError( 0xdeadbeef );
1124     ret = pGetWriteWatch( 0, NULL, size, results, &count, &pagesize );
1125     ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1126     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
1127         broken( GetLastError() == 0xdeadbeef ), /* win98 */
1128         "wrong error %u\n", GetLastError() );
1129
1130     SetLastError( 0xdeadbeef );
1131     ret = pGetWriteWatch( 0, GetModuleHandle(0), size, results, &count, &pagesize );
1132     if (ret)
1133     {
1134         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1135         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1136     }
1137     else  /* win98 */
1138     {
1139         ok( count == 0, "wrong count %lu\n", count );
1140     }
1141
1142     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1143     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1144     ok( count == 0, "wrong count %lu\n", count );
1145
1146     base[pagesize + 1] = 0x44;
1147
1148     count = 64;
1149     ret = pGetWriteWatch( 0, 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] );
1153
1154     count = 64;
1155     ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1156     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1157     ok( count == 1, "wrong count %lu\n", count );
1158     ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1159
1160     count = 64;
1161     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1162     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1163     ok( count == 0, "wrong count %lu\n", count );
1164
1165     base[2*pagesize + 3] = 0x11;
1166     base[4*pagesize + 8] = 0x11;
1167
1168     count = 64;
1169     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1170     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1171     ok( count == 2, "wrong count %lu\n", count );
1172     ok( results[0] == base + 2*pagesize, "wrong result %p\n", results[0] );
1173     ok( results[1] == base + 4*pagesize, "wrong result %p\n", results[1] );
1174
1175     count = 64;
1176     ret = pGetWriteWatch( 0, base + 3*pagesize, 2*pagesize, results, &count, &pagesize );
1177     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1178     ok( count == 1, "wrong count %lu\n", count );
1179     ok( results[0] == base + 4*pagesize, "wrong result %p\n", results[0] );
1180
1181     ret = pResetWriteWatch( base, 3*pagesize );
1182     ok( !ret, "pResetWriteWatch failed %u\n", GetLastError() );
1183
1184     count = 64;
1185     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1186     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1187     ok( count == 1, "wrong count %lu\n", count );
1188     ok( results[0] == base + 4*pagesize, "wrong result %p\n", results[0] );
1189
1190     *(DWORD *)(base + 2*pagesize - 2) = 0xdeadbeef;
1191
1192     count = 64;
1193     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1194     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1195     ok( count == 3, "wrong count %lu\n", count );
1196     ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1197     ok( results[1] == base + 2*pagesize, "wrong result %p\n", results[1] );
1198     ok( results[2] == base + 4*pagesize, "wrong result %p\n", results[2] );
1199
1200     count = 1;
1201     ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1202     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1203     ok( count == 1, "wrong count %lu\n", count );
1204     ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1205
1206     count = 64;
1207     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1208     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1209     ok( count == 2, "wrong count %lu\n", count );
1210     ok( results[0] == base + 2*pagesize, "wrong result %p\n", results[0] );
1211     ok( results[1] == base + 4*pagesize, "wrong result %p\n", results[1] );
1212
1213     /* changing protections doesn't affect watches */
1214
1215     ret = VirtualProtect( base, 3*pagesize, PAGE_READONLY, &old_prot );
1216     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
1217     ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
1218
1219     ret = VirtualQuery( base, &info, sizeof(info) );
1220     ok(ret, "VirtualQuery failed %u\n", GetLastError());
1221     ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
1222     ok( info.RegionSize == 3*pagesize, "wrong RegionSize 0x%lx\n", info.RegionSize );
1223     ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
1224     ok( info.Protect == PAGE_READONLY, "wrong Protect 0x%x\n", info.Protect );
1225
1226     ret = VirtualProtect( base, 3*pagesize, PAGE_READWRITE, &old_prot );
1227     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
1228     ok( old_prot == PAGE_READONLY, "wrong old prot %x\n", old_prot );
1229
1230     count = 64;
1231     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1232     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1233     ok( count == 2, "wrong count %lu\n", count );
1234     ok( results[0] == base + 2*pagesize, "wrong result %p\n", results[0] );
1235     ok( results[1] == base + 4*pagesize, "wrong result %p\n", results[1] );
1236
1237     ret = VirtualQuery( base, &info, sizeof(info) );
1238     ok(ret, "VirtualQuery failed %u\n", GetLastError());
1239     ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
1240     ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
1241     ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
1242     ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%x\n", info.Protect );
1243
1244     /* some invalid parameter tests */
1245
1246     SetLastError( 0xdeadbeef );
1247     count = 0;
1248     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1249     if (ret)
1250     {
1251         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1252         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1253
1254         SetLastError( 0xdeadbeef );
1255         ret = pGetWriteWatch( 0, base, size, results, NULL, &pagesize );
1256         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1257         ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
1258
1259         SetLastError( 0xdeadbeef );
1260         count = 64;
1261         ret = pGetWriteWatch( 0, base, size, results, &count, NULL );
1262         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1263         ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
1264
1265         SetLastError( 0xdeadbeef );
1266         count = 64;
1267         ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
1268         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1269         ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
1270
1271         SetLastError( 0xdeadbeef );
1272         count = 0;
1273         ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
1274         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1275         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1276
1277         SetLastError( 0xdeadbeef );
1278         count = 64;
1279         ret = pGetWriteWatch( 0xdeadbeef, base, size, results, &count, &pagesize );
1280         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1281         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1282
1283         SetLastError( 0xdeadbeef );
1284         count = 64;
1285         ret = pGetWriteWatch( 0, base, 0, results, &count, &pagesize );
1286         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1287         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1288
1289         SetLastError( 0xdeadbeef );
1290         count = 64;
1291         ret = pGetWriteWatch( 0, base, size * 2, results, &count, &pagesize );
1292         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1293         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1294
1295         SetLastError( 0xdeadbeef );
1296         count = 64;
1297         ret = pGetWriteWatch( 0, base + size - pagesize, pagesize + 1, results, &count, &pagesize );
1298         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1299         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1300
1301         SetLastError( 0xdeadbeef );
1302         ret = pResetWriteWatch( base, 0 );
1303         ok( ret == ~0u, "ResetWriteWatch succeeded %u\n", ret );
1304         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1305
1306         SetLastError( 0xdeadbeef );
1307         ret = pResetWriteWatch( GetModuleHandle(0), size );
1308         ok( ret == ~0u, "ResetWriteWatch succeeded %u\n", ret );
1309         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1310     }
1311     else  /* win98 is completely different */
1312     {
1313         SetLastError( 0xdeadbeef );
1314         count = 64;
1315         ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
1316         ok( ret == ERROR_INVALID_PARAMETER, "GetWriteWatch succeeded %u\n", ret );
1317         ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
1318
1319         count = 0;
1320         ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
1321         ok( !ret, "GetWriteWatch failed %u\n", ret );
1322
1323         count = 64;
1324         ret = pGetWriteWatch( 0xdeadbeef, base, size, results, &count, &pagesize );
1325         ok( !ret, "GetWriteWatch failed %u\n", ret );
1326
1327         count = 64;
1328         ret = pGetWriteWatch( 0, base, 0, results, &count, &pagesize );
1329         ok( !ret, "GetWriteWatch failed %u\n", ret );
1330
1331         ret = pResetWriteWatch( base, 0 );
1332         ok( !ret, "ResetWriteWatch failed %u\n", ret );
1333
1334         ret = pResetWriteWatch( GetModuleHandle(0), size );
1335         ok( !ret, "ResetWriteWatch failed %u\n", ret );
1336     }
1337
1338     VirtualFree( base, 0, MEM_FREE );
1339
1340     base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE );
1341     ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
1342     VirtualFree( base, 0, MEM_FREE );
1343
1344     base = VirtualAlloc( 0, size, MEM_WRITE_WATCH, PAGE_READWRITE );
1345     ok( !base, "VirtualAlloc succeeded\n" );
1346     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1347
1348     /* initial protect doesn't matter */
1349
1350     base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_NOACCESS );
1351     ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
1352     base = VirtualAlloc( base, size, MEM_COMMIT, PAGE_NOACCESS );
1353     ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
1354
1355     count = 64;
1356     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1357     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1358     ok( count == 0, "wrong count %lu\n", count );
1359
1360     ret = VirtualProtect( base, 6*pagesize, PAGE_READWRITE, &old_prot );
1361     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
1362     ok( old_prot == PAGE_NOACCESS, "wrong old prot %x\n", old_prot );
1363
1364     base[5*pagesize + 200] = 3;
1365
1366     ret = VirtualProtect( base, 6*pagesize, PAGE_NOACCESS, &old_prot );
1367     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
1368     ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
1369
1370     count = 64;
1371     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1372     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1373     ok( count == 1, "wrong count %lu\n", count );
1374     ok( results[0] == base + 5*pagesize, "wrong result %p\n", results[0] );
1375
1376     ret = VirtualFree( base, size, MEM_DECOMMIT );
1377     ok( ret, "VirtualFree failed %u\n", GetLastError() );
1378
1379     count = 64;
1380     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1381     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1382     ok( count == 1 || broken(count == 0), /* win98 */
1383         "wrong count %lu\n", count );
1384     if (count) ok( results[0] == base + 5*pagesize, "wrong result %p\n", results[0] );
1385
1386     VirtualFree( base, 0, MEM_FREE );
1387 }
1388
1389 static void test_VirtualProtect(void)
1390 {
1391     static const struct test_data
1392     {
1393         DWORD prot_set, prot_get;
1394     } td[] =
1395     {
1396         { 0, 0 }, /* 0x00 */
1397         { PAGE_NOACCESS, PAGE_NOACCESS }, /* 0x01 */
1398         { PAGE_READONLY, PAGE_READONLY }, /* 0x02 */
1399         { PAGE_READONLY | PAGE_NOACCESS, 0 }, /* 0x03 */
1400         { PAGE_READWRITE, PAGE_READWRITE }, /* 0x04 */
1401         { PAGE_READWRITE | PAGE_NOACCESS, 0 }, /* 0x05 */
1402         { PAGE_READWRITE | PAGE_READONLY, 0 }, /* 0x06 */
1403         { PAGE_READWRITE | PAGE_READONLY | PAGE_NOACCESS, 0 }, /* 0x07 */
1404         { PAGE_WRITECOPY, 0 }, /* 0x08 */
1405         { PAGE_WRITECOPY | PAGE_NOACCESS, 0 }, /* 0x09 */
1406         { PAGE_WRITECOPY | PAGE_READONLY, 0 }, /* 0x0a */
1407         { PAGE_WRITECOPY | PAGE_NOACCESS | PAGE_READONLY, 0 }, /* 0x0b */
1408         { PAGE_WRITECOPY | PAGE_READWRITE, 0 }, /* 0x0c */
1409         { PAGE_WRITECOPY | PAGE_READWRITE | PAGE_NOACCESS, 0 }, /* 0x0d */
1410         { PAGE_WRITECOPY | PAGE_READWRITE | PAGE_READONLY, 0 }, /* 0x0e */
1411         { PAGE_WRITECOPY | PAGE_READWRITE | PAGE_READONLY | PAGE_NOACCESS, 0 }, /* 0x0f */
1412
1413         { PAGE_EXECUTE, PAGE_EXECUTE }, /* 0x10 */
1414         { PAGE_EXECUTE_READ, PAGE_EXECUTE_READ }, /* 0x20 */
1415         { PAGE_EXECUTE_READ | PAGE_EXECUTE, 0 }, /* 0x30 */
1416         { PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_READWRITE }, /* 0x40 */
1417         { PAGE_EXECUTE_READWRITE | PAGE_EXECUTE, 0 }, /* 0x50 */
1418         { PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ, 0 }, /* 0x60 */
1419         { PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE, 0 }, /* 0x70 */
1420         { PAGE_EXECUTE_WRITECOPY, 0 }, /* 0x80 */
1421         { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE, 0 }, /* 0x90 */
1422         { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READ, 0 }, /* 0xa0 */
1423         { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE, 0 }, /* 0xb0 */
1424         { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READWRITE, 0 }, /* 0xc0 */
1425         { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE, 0 }, /* 0xd0 */
1426         { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ, 0 }, /* 0xe0 */
1427         { PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE, 0 } /* 0xf0 */
1428     };
1429     char *base;
1430     DWORD ret, old_prot, rw_prot, exec_prot, i, j;
1431     MEMORY_BASIC_INFORMATION info;
1432     SYSTEM_INFO si;
1433
1434     GetSystemInfo(&si);
1435     trace("system page size %#x\n", si.dwPageSize);
1436
1437     SetLastError(0xdeadbeef);
1438     base = VirtualAlloc(0, si.dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS);
1439     ok(base != NULL, "VirtualAlloc failed %d\n", GetLastError());
1440
1441     for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
1442     {
1443         SetLastError(0xdeadbeef);
1444         ret = VirtualQuery(base, &info, sizeof(info));
1445         ok(ret, "VirtualQuery failed %d\n", GetLastError());
1446         ok(info.BaseAddress == base, "%d: got %p != expected %p\n", i, info.BaseAddress, base);
1447         ok(info.RegionSize == si.dwPageSize, "%d: got %#lx != expected %#x\n", i, info.RegionSize, si.dwPageSize);
1448         ok(info.Protect == PAGE_NOACCESS, "%d: got %#x != expected PAGE_NOACCESS\n", i, info.Protect);
1449         ok(info.AllocationBase == base, "%d: %p != %p\n", i, info.AllocationBase, base);
1450         ok(info.AllocationProtect == PAGE_NOACCESS, "%d: %#x != PAGE_NOACCESS\n", i, info.AllocationProtect);
1451         ok(info.State == MEM_COMMIT, "%d: %#x != MEM_COMMIT\n", i, info.State);
1452         ok(info.Type == MEM_PRIVATE, "%d: %#x != MEM_PRIVATE\n", i, info.Type);
1453
1454         old_prot = 0xdeadbeef;
1455         SetLastError(0xdeadbeef);
1456         ret = VirtualProtect(base, si.dwPageSize, td[i].prot_set, &old_prot);
1457         if (td[i].prot_get)
1458         {
1459             ok(ret, "%d: VirtualProtect error %d\n", i, GetLastError());
1460             ok(old_prot == PAGE_NOACCESS, "%d: got %#x != expected PAGE_NOACCESS\n", i, old_prot);
1461
1462             SetLastError(0xdeadbeef);
1463             ret = VirtualQuery(base, &info, sizeof(info));
1464             ok(ret, "VirtualQuery failed %d\n", GetLastError());
1465             ok(info.BaseAddress == base, "%d: got %p != expected %p\n", i, info.BaseAddress, base);
1466             ok(info.RegionSize == si.dwPageSize, "%d: got %#lx != expected %#x\n", i, info.RegionSize, si.dwPageSize);
1467             ok(info.Protect == td[i].prot_get, "%d: got %#x != expected %#x\n", i, info.Protect, td[i].prot_get);
1468             ok(info.AllocationBase == base, "%d: %p != %p\n", i, info.AllocationBase, base);
1469             ok(info.AllocationProtect == PAGE_NOACCESS, "%d: %#x != PAGE_NOACCESS\n", i, info.AllocationProtect);
1470             ok(info.State == MEM_COMMIT, "%d: %#x != MEM_COMMIT\n", i, info.State);
1471             ok(info.Type == MEM_PRIVATE, "%d: %#x != MEM_PRIVATE\n", i, info.Type);
1472         }
1473         else
1474         {
1475             /* FIXME: remove the condition below once Wine is fixed */
1476             if ((td[i].prot_set == PAGE_WRITECOPY) || (td[i].prot_set == PAGE_EXECUTE_WRITECOPY))
1477             todo_wine {
1478             ok(!ret, "%d: VirtualProtect should fail\n", i);
1479             ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
1480             }
1481             else {
1482             ok(!ret, "%d: VirtualProtect should fail\n", i);
1483             ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
1484             }
1485         }
1486
1487         old_prot = 0xdeadbeef;
1488         SetLastError(0xdeadbeef);
1489         ret = VirtualProtect(base, si.dwPageSize, PAGE_NOACCESS, &old_prot);
1490         ok(ret, "%d: VirtualProtect error %d\n", i, GetLastError());
1491         if (td[i].prot_get)
1492             ok(old_prot == td[i].prot_get, "%d: got %#x != expected %#x\n", i, old_prot, td[i].prot_get);
1493         else
1494         {
1495             /* FIXME: remove the condition below once Wine is fixed */
1496             if ((td[i].prot_set == PAGE_WRITECOPY) || (td[i].prot_set == PAGE_EXECUTE_WRITECOPY))
1497             todo_wine ok(old_prot == PAGE_NOACCESS, "%d: got %#x != expected PAGE_NOACCESS\n", i, old_prot);
1498             else
1499             ok(old_prot == PAGE_NOACCESS, "%d: got %#x != expected PAGE_NOACCESS\n", i, old_prot);
1500         }
1501     }
1502
1503     exec_prot = 0;
1504
1505     for (i = 0; i <= 4; i++)
1506     {
1507         rw_prot = 0;
1508
1509         for (j = 0; j <= 4; j++)
1510         {
1511             DWORD prot = exec_prot | rw_prot;
1512
1513             SetLastError(0xdeadbeef);
1514             ret = VirtualProtect(base, si.dwPageSize, prot, &old_prot);
1515             if ((rw_prot && exec_prot) || (!rw_prot && !exec_prot))
1516             {
1517                 ok(!ret, "VirtualProtect(%02x) should fail\n", prot);
1518                 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1519             }
1520             else
1521             {
1522                 if (prot & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY))
1523                 {
1524                     todo_wine {
1525                     ok(!ret, "VirtualProtect(%02x) should fail\n", prot);
1526                     ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1527                     }
1528                 }
1529                 else
1530                     ok(ret, "VirtualProtect(%02x) error %d\n", prot, GetLastError());
1531             }
1532
1533             rw_prot = 1 << j;
1534         }
1535
1536         exec_prot = 1 << (i + 4);
1537     }
1538
1539     VirtualFree(base, 0, MEM_FREE);
1540 }
1541
1542 START_TEST(virtual)
1543 {
1544     int argc;
1545     char **argv;
1546     argc = winetest_get_mainargs( &argv );
1547
1548     if (argc >= 3)
1549     {
1550         if (!strcmp(argv[2], "sleep"))
1551         {
1552             Sleep(5000); /* spawned process runs for at most 5 seconds */
1553             return;
1554         }
1555         while (1)
1556         {
1557             void *mem;
1558             BOOL ret;
1559             mem = VirtualAlloc(NULL, 1<<20, MEM_COMMIT|MEM_RESERVE,
1560                                PAGE_EXECUTE_READWRITE);
1561             ok(mem != NULL, "VirtualAlloc failed %u\n", GetLastError());
1562             if (mem == NULL) break;
1563             ret = VirtualFree(mem, 0, MEM_RELEASE);
1564             ok(ret, "VirtualFree failed %u\n", GetLastError());
1565             if (!ret) break;
1566         }
1567         return;
1568     }
1569
1570     hkernel32 = GetModuleHandleA("kernel32.dll");
1571     pVirtualAllocEx = (void *) GetProcAddress(hkernel32, "VirtualAllocEx");
1572     pVirtualFreeEx = (void *) GetProcAddress(hkernel32, "VirtualFreeEx");
1573     pGetWriteWatch = (void *) GetProcAddress(hkernel32, "GetWriteWatch");
1574     pResetWriteWatch = (void *) GetProcAddress(hkernel32, "ResetWriteWatch");
1575     pNtAreMappedFilesTheSame = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"),
1576                                                        "NtAreMappedFilesTheSame" );
1577     test_VirtualProtect();
1578     test_VirtualAllocEx();
1579     test_VirtualAlloc();
1580     test_MapViewOfFile();
1581     test_NtMapViewOfSection();
1582     test_NtAreMappedFilesTheSame();
1583     test_CreateFileMapping();
1584     test_IsBadReadPtr();
1585     test_IsBadWritePtr();
1586     test_IsBadCodePtr();
1587     test_write_watch();
1588 }