kernel32/tests: Get rid of the Win9x support in the file sharing 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         ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
602         SetLastError(0xdeadbeef);
603         ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
604         ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
605         SetLastError(0xdeadbeef);
606         ok( VirtualQuery( ptr, &info, sizeof(info) ) == sizeof(info),
607             "VirtualQuery error %u\n", GetLastError() );
608         ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
609         ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
610         ok( info.AllocationProtect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.AllocationProtect );
611         ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
612         ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
613         ok( info.Protect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.Protect );
614     }
615     else win_skip( "no access checks on win9x\n" );
616     UnmapViewOfFile( ptr );
617     CloseHandle( mapping );
618
619     SetLastError(0xdeadbeef);
620     mapping = OpenFileMapping( FILE_MAP_WRITE, FALSE, name );
621     ok( mapping != 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() );
622     SetLastError(0xdeadbeef);
623     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
624     if (!ptr)
625     {
626         ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
627         SetLastError(0xdeadbeef);
628         ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
629         ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
630         SetLastError(0xdeadbeef);
631         ok( VirtualQuery( ptr, &info, sizeof(info) ) == sizeof(info),
632             "VirtualQuery error %u\n", GetLastError() );
633         ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
634         ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
635         ok( info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect );
636         ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
637         ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
638         ok( info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect );
639     }
640     else win_skip( "no access checks on win9x\n" );
641     UnmapViewOfFile( ptr );
642     CloseHandle( mapping );
643
644     CloseHandle( file );
645
646     /* read/write mapping with SEC_RESERVE */
647     mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE, 0, MAPPING_SIZE, NULL);
648     ok(mapping != INVALID_HANDLE_VALUE, "CreateFileMappingA failed with error %d\n", GetLastError());
649
650     ptr = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
651     ok(ptr != NULL, "MapViewOfFile failed with error %d\n", GetLastError());
652
653     ptr2 = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
654     /* on NT ptr != ptr2 but on Win9x ptr == ptr2 */
655     ok(ptr2 != NULL, "MapViewOfFile failed with error %d\n", GetLastError());
656     trace("mapping same section resulted in views %p and %p\n", ptr, ptr2);
657
658     ret = VirtualQuery(ptr, &info, sizeof(info));
659     ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
660     ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
661     ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
662     ok(info.RegionSize == MAPPING_SIZE, "RegionSize should have been 0x%x but was 0x%x\n", MAPPING_SIZE, (unsigned int)info.RegionSize);
663     ok(info.State == MEM_RESERVE, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
664     if (info.Type == MEM_PRIVATE)  /* win9x is different for uncommitted mappings */
665     {
666         ok(info.AllocationProtect == PAGE_NOACCESS,
667            "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info.AllocationProtect);
668         ok(info.Protect == PAGE_NOACCESS,
669            "Protect should have been PAGE_NOACCESS instead of 0x%x\n", info.Protect);
670     }
671     else
672     {
673         ok(info.AllocationProtect == PAGE_READWRITE,
674            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
675         ok(info.Protect == 0, "Protect should have been 0 instead of 0x%x\n", info.Protect);
676         ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
677     }
678
679     if (ptr != ptr2)
680     {
681         ret = VirtualQuery(ptr2, &info, sizeof(info));
682         ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
683         ok(info.BaseAddress == ptr2,
684            "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
685         ok(info.AllocationBase == ptr2,
686            "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
687         ok(info.AllocationProtect == PAGE_READWRITE,
688            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
689         ok(info.RegionSize == MAPPING_SIZE,
690            "RegionSize should have been 0x%x but was 0x%x\n", MAPPING_SIZE, (unsigned int)info.RegionSize);
691         ok(info.State == MEM_RESERVE,
692            "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
693         ok(info.Protect == 0,
694            "Protect should have been 0 instead of 0x%x\n", info.Protect);
695         ok(info.Type == MEM_MAPPED,
696            "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
697     }
698
699     ptr = VirtualAlloc(ptr, 0x10000, MEM_COMMIT, PAGE_READONLY);
700     ok(ptr != NULL, "VirtualAlloc failed with error %d\n", GetLastError());
701
702     ret = VirtualQuery(ptr, &info, sizeof(info));
703     ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
704     ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
705     ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
706     ok(info.RegionSize == 0x10000, "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info.RegionSize);
707     ok(info.State == MEM_COMMIT, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
708     ok(info.Protect == PAGE_READONLY, "Protect should have been 0 instead of 0x%x\n", info.Protect);
709     if (info.Type == MEM_PRIVATE)  /* win9x is different for uncommitted mappings */
710     {
711         ok(info.AllocationProtect == PAGE_NOACCESS,
712            "AllocationProtect should have been PAGE_NOACCESS but was 0x%x\n", info.AllocationProtect);
713     }
714     else
715     {
716         ok(info.AllocationProtect == PAGE_READWRITE,
717            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
718         ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
719     }
720
721     /* shows that the VirtualAlloc above affects the mapping, not just the
722      * virtual memory in this process - it also affects all other processes
723      * with a view of the mapping, but that isn't tested here */
724     if (ptr != ptr2)
725     {
726         ret = VirtualQuery(ptr2, &info, sizeof(info));
727         ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
728         ok(info.BaseAddress == ptr2,
729            "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
730         ok(info.AllocationBase == ptr2,
731            "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
732         ok(info.AllocationProtect == PAGE_READWRITE,
733            "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
734         ok(info.RegionSize == 0x10000,
735            "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info.RegionSize);
736         ok(info.State == MEM_COMMIT,
737            "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
738         ok(info.Protect == PAGE_READWRITE,
739            "Protect should have been 0 instead of 0x%x\n", info.Protect);
740         ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
741     }
742
743     addr = VirtualAlloc( ptr, MAPPING_SIZE, MEM_RESET, PAGE_READONLY );
744     ok( addr == ptr || broken(!addr && GetLastError() == ERROR_INVALID_PARAMETER), /* win9x */
745         "VirtualAlloc failed with error %u\n", GetLastError() );
746
747     ret = VirtualFree( ptr, 0x10000, MEM_DECOMMIT );
748     ok( !ret || broken(ret) /* win9x */, "VirtualFree succeeded\n" );
749     if (!ret)
750         ok( GetLastError() == ERROR_INVALID_PARAMETER, "VirtualFree failed with %u\n", GetLastError() );
751
752     ret = UnmapViewOfFile(ptr2);
753     ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError());
754     ret = UnmapViewOfFile(ptr);
755     ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError());
756     CloseHandle(mapping);
757
758     addr = VirtualAlloc(NULL, 0x10000, MEM_COMMIT, PAGE_READONLY );
759     ok( addr != NULL, "VirtualAlloc failed with error %u\n", GetLastError() );
760
761     SetLastError(0xdeadbeef);
762     ok( !UnmapViewOfFile(addr), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
763     ok( GetLastError() == ERROR_INVALID_ADDRESS,
764         "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
765     SetLastError(0xdeadbeef);
766     ok( !UnmapViewOfFile((char *)addr + 0x3000), "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((void *)0xdeadbeef), "UnmapViewOfFile should fail on VirtualAlloc mem\n" );
771     ok( GetLastError() == ERROR_INVALID_ADDRESS,
772        "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
773
774     ok( VirtualFree(addr, 0, MEM_RELEASE), "VirtualFree failed\n" );
775 }
776
777 static DWORD (WINAPI *pNtMapViewOfSection)( HANDLE handle, HANDLE process, PVOID *addr_ptr,
778                                             ULONG zero_bits, SIZE_T commit_size,
779                                             const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
780                                             ULONG inherit, ULONG alloc_type, ULONG protect );
781 static DWORD (WINAPI *pNtUnmapViewOfSection)( HANDLE process, PVOID addr );
782
783 static void test_NtMapViewOfSection(void)
784 {
785     HANDLE hProcess;
786
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;
791     void *ptr;
792     BOOL ret;
793     DWORD status, written;
794     SIZE_T size, result;
795     LARGE_INTEGER offset;
796
797     pNtMapViewOfSection = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"), "NtMapViewOfSection" );
798     pNtUnmapViewOfSection = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"), "NtUnmapViewOfSection" );
799     if (!pNtMapViewOfSection || !pNtUnmapViewOfSection)
800     {
801         win_skip( "NtMapViewOfSection not available\n" );
802         return;
803     }
804
805     file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
806     ok( file != INVALID_HANDLE_VALUE, "Failed to create test file\n" );
807     WriteFile( file, data, sizeof(data), &written, NULL );
808     SetFilePointer( file, 4096, NULL, FILE_BEGIN );
809     SetEndOfFile( file );
810
811     /* read/write mapping */
812
813     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
814     ok( mapping != 0, "CreateFileMapping failed\n" );
815
816     hProcess = create_target_process("sleep");
817     ok(hProcess != NULL, "Can't start process\n");
818
819     ptr = NULL;
820     size = 0;
821     offset.QuadPart = 0;
822     status = pNtMapViewOfSection( mapping, hProcess, &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE );
823     ok( !status, "NtMapViewOfSection failed status %x\n", status );
824
825     ret = ReadProcessMemory( hProcess, ptr, buffer, sizeof(buffer), &result );
826     ok( ret, "ReadProcessMemory failed\n" );
827     ok( result == sizeof(buffer), "ReadProcessMemory didn't read all data (%lx)\n", result );
828     ok( !memcmp( buffer, data, sizeof(buffer) ), "Wrong data read\n" );
829
830     status = pNtUnmapViewOfSection( hProcess, ptr );
831     ok( !status, "NtUnmapViewOfSection failed status %x\n", status );
832
833     CloseHandle( mapping );
834     CloseHandle( file );
835     DeleteFileA( testfile );
836
837     TerminateProcess(hProcess, 0);
838     CloseHandle(hProcess);
839 }
840
841 static void test_NtAreMappedFilesTheSame(void)
842 {
843     static const char testfile[] = "testfile.xxx";
844     HANDLE file, file2, mapping, map2;
845     void *ptr, *ptr2;
846     NTSTATUS status;
847     char path[MAX_PATH];
848
849     if (!pNtAreMappedFilesTheSame)
850     {
851         win_skip( "NtAreMappedFilesTheSame not available\n" );
852         return;
853     }
854
855     file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
856                         NULL, CREATE_ALWAYS, 0, 0 );
857     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
858     SetFilePointer( file, 4096, NULL, FILE_BEGIN );
859     SetEndOfFile( file );
860
861     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
862     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
863
864     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
865     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
866
867     file2 = CreateFileA( testfile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
868                          NULL, OPEN_EXISTING, 0, 0 );
869     ok( file2 != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
870
871     map2 = CreateFileMappingA( file2, NULL, PAGE_READONLY, 0, 4096, NULL );
872     ok( map2 != 0, "CreateFileMapping error %u\n", GetLastError() );
873     ptr2 = MapViewOfFile( map2, FILE_MAP_READ, 0, 0, 4096 );
874     ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
875     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
876     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
877     UnmapViewOfFile( ptr2 );
878
879     ptr2 = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
880     ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
881     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
882     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
883     UnmapViewOfFile( ptr2 );
884     CloseHandle( map2 );
885
886     map2 = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
887     ok( map2 != 0, "CreateFileMapping error %u\n", GetLastError() );
888     ptr2 = MapViewOfFile( map2, FILE_MAP_READ, 0, 0, 4096 );
889     ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
890     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
891     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
892     UnmapViewOfFile( ptr2 );
893     CloseHandle( map2 );
894     CloseHandle( file2 );
895
896     status = pNtAreMappedFilesTheSame( ptr, ptr );
897     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
898
899     status = pNtAreMappedFilesTheSame( ptr, (char *)ptr + 30 );
900     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
901
902     status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
903     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
904
905     status = pNtAreMappedFilesTheSame( ptr, (void *)0xdeadbeef );
906     ok( status == STATUS_CONFLICTING_ADDRESSES || status == STATUS_INVALID_ADDRESS,
907         "NtAreMappedFilesTheSame returned %x\n", status );
908
909     status = pNtAreMappedFilesTheSame( ptr, NULL );
910     ok( status == STATUS_INVALID_ADDRESS, "NtAreMappedFilesTheSame returned %x\n", status );
911
912     status = pNtAreMappedFilesTheSame( ptr, (void *)GetProcessHeap() );
913     ok( status == STATUS_CONFLICTING_ADDRESSES, "NtAreMappedFilesTheSame returned %x\n", status );
914
915     status = pNtAreMappedFilesTheSame( NULL, NULL );
916     ok( status == STATUS_INVALID_ADDRESS, "NtAreMappedFilesTheSame returned %x\n", status );
917
918     ptr2 = VirtualAlloc( NULL, 0x10000, MEM_COMMIT, PAGE_READWRITE );
919     ok( ptr2 != NULL, "VirtualAlloc error %u\n", GetLastError() );
920     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
921     ok( status == STATUS_CONFLICTING_ADDRESSES, "NtAreMappedFilesTheSame returned %x\n", status );
922     VirtualFree( ptr2, 0, MEM_RELEASE );
923
924     UnmapViewOfFile( ptr );
925     CloseHandle( mapping );
926     CloseHandle( file );
927
928     status = pNtAreMappedFilesTheSame( GetModuleHandleA("ntdll.dll"),
929                                        GetModuleHandleA("kernel32.dll") );
930     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
931     status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
932                                        GetModuleHandleA("kernel32.dll") );
933     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
934     status = pNtAreMappedFilesTheSame( GetModuleHandleA("kernel32.dll"),
935                                        (char *)GetModuleHandleA("kernel32.dll") + 4096 );
936     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
937
938     GetSystemDirectoryA( path, MAX_PATH );
939     strcat( path, "\\kernel32.dll" );
940     file = CreateFileA( path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
941     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
942
943     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
944     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
945     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
946     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
947     status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
948     ok( status == STATUS_NOT_SAME_DEVICE, "NtAreMappedFilesTheSame returned %x\n", status );
949     UnmapViewOfFile( ptr );
950     CloseHandle( mapping );
951
952     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL );
953     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
954     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
955     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
956     status = pNtAreMappedFilesTheSame( ptr, GetModuleHandleA("kernel32.dll") );
957     todo_wine
958     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
959
960     file2 = CreateFileA( path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
961     ok( file2 != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
962     map2 = CreateFileMappingA( file2, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL );
963     ok( map2 != 0, "CreateFileMapping error %u\n", GetLastError() );
964     ptr2 = MapViewOfFile( map2, FILE_MAP_READ, 0, 0, 0 );
965     ok( ptr2 != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
966     status = pNtAreMappedFilesTheSame( ptr, ptr2 );
967     ok( status == STATUS_SUCCESS, "NtAreMappedFilesTheSame returned %x\n", status );
968     UnmapViewOfFile( ptr2 );
969     CloseHandle( map2 );
970     CloseHandle( file2 );
971
972     UnmapViewOfFile( ptr );
973     CloseHandle( mapping );
974
975     CloseHandle( file );
976     DeleteFileA( testfile );
977 }
978
979 static void test_CreateFileMapping(void)
980 {
981     HANDLE handle, handle2;
982
983     /* test case sensitivity */
984
985     SetLastError(0xdeadbeef);
986     handle = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, 0x1000,
987                                  "Wine Test Mapping");
988     ok( handle != NULL, "CreateFileMapping failed with error %u\n", GetLastError());
989     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
990
991     SetLastError(0xdeadbeef);
992     handle2 = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, 0x1000,
993                                   "Wine Test Mapping");
994     ok( handle2 != NULL, "CreateFileMapping failed with error %d\n", GetLastError());
995     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
996     CloseHandle( handle2 );
997
998     SetLastError(0xdeadbeef);
999     handle2 = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, 0x1000,
1000                                  "WINE TEST MAPPING");
1001     ok( handle2 != NULL, "CreateFileMapping failed with error %d\n", GetLastError());
1002     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
1003     CloseHandle( handle2 );
1004
1005     SetLastError(0xdeadbeef);
1006     handle2 = OpenFileMappingA( FILE_MAP_ALL_ACCESS, FALSE, "Wine Test Mapping");
1007     ok( handle2 != NULL, "OpenFileMapping failed with error %d\n", GetLastError());
1008     CloseHandle( handle2 );
1009
1010     SetLastError(0xdeadbeef);
1011     handle2 = OpenFileMappingA( FILE_MAP_ALL_ACCESS, FALSE, "WINE TEST MAPPING");
1012     ok( !handle2, "OpenFileMapping succeeded\n");
1013     ok( GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID_NAME /* win9x */,
1014         "wrong error %u\n", GetLastError());
1015
1016     CloseHandle( handle );
1017 }
1018
1019 static void test_IsBadReadPtr(void)
1020 {
1021     BOOL ret;
1022     void *ptr = (void *)0xdeadbeef;
1023     char stackvar;
1024
1025     ret = IsBadReadPtr(NULL, 0);
1026     ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1027
1028     ret = IsBadReadPtr(NULL, 1);
1029     ok(ret == TRUE, "Expected IsBadReadPtr to return TRUE, got %d\n", ret);
1030
1031     ret = IsBadReadPtr(ptr, 0);
1032     ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1033
1034     ret = IsBadReadPtr(ptr, 1);
1035     ok(ret == TRUE, "Expected IsBadReadPtr to return TRUE, got %d\n", ret);
1036
1037     ret = IsBadReadPtr(&stackvar, 0);
1038     ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1039
1040     ret = IsBadReadPtr(&stackvar, sizeof(char));
1041     ok(ret == FALSE, "Expected IsBadReadPtr to return FALSE, got %d\n", ret);
1042 }
1043
1044 static void test_IsBadWritePtr(void)
1045 {
1046     BOOL ret;
1047     void *ptr = (void *)0xdeadbeef;
1048     char stackval;
1049
1050     ret = IsBadWritePtr(NULL, 0);
1051     ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1052
1053     ret = IsBadWritePtr(NULL, 1);
1054     ok(ret == TRUE, "Expected IsBadWritePtr to return TRUE, got %d\n", ret);
1055
1056     ret = IsBadWritePtr(ptr, 0);
1057     ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1058
1059     ret = IsBadWritePtr(ptr, 1);
1060     ok(ret == TRUE, "Expected IsBadWritePtr to return TRUE, got %d\n", ret);
1061
1062     ret = IsBadWritePtr(&stackval, 0);
1063     ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1064
1065     ret = IsBadWritePtr(&stackval, sizeof(char));
1066     ok(ret == FALSE, "Expected IsBadWritePtr to return FALSE, got %d\n", ret);
1067 }
1068
1069 static void test_IsBadCodePtr(void)
1070 {
1071     BOOL ret;
1072     void *ptr = (void *)0xdeadbeef;
1073     char stackval;
1074
1075     ret = IsBadCodePtr(NULL);
1076     ok(ret == TRUE, "Expected IsBadCodePtr to return TRUE, got %d\n", ret);
1077
1078     ret = IsBadCodePtr(ptr);
1079     ok(ret == TRUE, "Expected IsBadCodePtr to return TRUE, got %d\n", ret);
1080
1081     ret = IsBadCodePtr((void *)&stackval);
1082     ok(ret == FALSE, "Expected IsBadCodePtr to return FALSE, got %d\n", ret);
1083 }
1084
1085 static void test_write_watch(void)
1086 {
1087     char *base;
1088     DWORD ret, size, old_prot;
1089     MEMORY_BASIC_INFORMATION info;
1090     void *results[64];
1091     ULONG_PTR count;
1092     ULONG pagesize;
1093
1094     if (!pGetWriteWatch || !pResetWriteWatch)
1095     {
1096         win_skip( "GetWriteWatch not supported\n" );
1097         return;
1098     }
1099
1100     size = 0x10000;
1101     base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, PAGE_READWRITE );
1102     if (!base &&
1103         (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED))
1104     {
1105         win_skip( "MEM_WRITE_WATCH not supported\n" );
1106         return;
1107     }
1108     ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
1109     ret = VirtualQuery( base, &info, sizeof(info) );
1110     ok(ret, "VirtualQuery failed %u\n", GetLastError());
1111     ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
1112     ok( info.AllocationProtect == PAGE_READWRITE, "wrong AllocationProtect %x\n", info.AllocationProtect );
1113     ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
1114     ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
1115     ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%x\n", info.Protect );
1116     ok( info.Type == MEM_PRIVATE, "wrong Type 0x%x\n", info.Type );
1117
1118     count = 64;
1119     SetLastError( 0xdeadbeef );
1120     ret = pGetWriteWatch( 0, NULL, size, results, &count, &pagesize );
1121     ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1122     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
1123         broken( GetLastError() == 0xdeadbeef ), /* win98 */
1124         "wrong error %u\n", GetLastError() );
1125
1126     SetLastError( 0xdeadbeef );
1127     ret = pGetWriteWatch( 0, GetModuleHandle(0), size, results, &count, &pagesize );
1128     if (ret)
1129     {
1130         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1131         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1132     }
1133     else  /* win98 */
1134     {
1135         ok( count == 0, "wrong count %lu\n", count );
1136     }
1137
1138     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1139     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1140     ok( count == 0, "wrong count %lu\n", count );
1141
1142     base[pagesize + 1] = 0x44;
1143
1144     count = 64;
1145     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1146     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1147     ok( count == 1, "wrong count %lu\n", count );
1148     ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1149
1150     count = 64;
1151     ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1152     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1153     ok( count == 1, "wrong count %lu\n", count );
1154     ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1155
1156     count = 64;
1157     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1158     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1159     ok( count == 0, "wrong count %lu\n", count );
1160
1161     base[2*pagesize + 3] = 0x11;
1162     base[4*pagesize + 8] = 0x11;
1163
1164     count = 64;
1165     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1166     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1167     ok( count == 2, "wrong count %lu\n", count );
1168     ok( results[0] == base + 2*pagesize, "wrong result %p\n", results[0] );
1169     ok( results[1] == base + 4*pagesize, "wrong result %p\n", results[1] );
1170
1171     count = 64;
1172     ret = pGetWriteWatch( 0, base + 3*pagesize, 2*pagesize, results, &count, &pagesize );
1173     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1174     ok( count == 1, "wrong count %lu\n", count );
1175     ok( results[0] == base + 4*pagesize, "wrong result %p\n", results[0] );
1176
1177     ret = pResetWriteWatch( base, 3*pagesize );
1178     ok( !ret, "pResetWriteWatch failed %u\n", GetLastError() );
1179
1180     count = 64;
1181     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1182     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1183     ok( count == 1, "wrong count %lu\n", count );
1184     ok( results[0] == base + 4*pagesize, "wrong result %p\n", results[0] );
1185
1186     *(DWORD *)(base + 2*pagesize - 2) = 0xdeadbeef;
1187
1188     count = 64;
1189     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1190     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1191     ok( count == 3, "wrong count %lu\n", count );
1192     ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1193     ok( results[1] == base + 2*pagesize, "wrong result %p\n", results[1] );
1194     ok( results[2] == base + 4*pagesize, "wrong result %p\n", results[2] );
1195
1196     count = 1;
1197     ret = pGetWriteWatch( WRITE_WATCH_FLAG_RESET, base, size, results, &count, &pagesize );
1198     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1199     ok( count == 1, "wrong count %lu\n", count );
1200     ok( results[0] == base + pagesize, "wrong result %p\n", results[0] );
1201
1202     count = 64;
1203     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1204     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1205     ok( count == 2, "wrong count %lu\n", count );
1206     ok( results[0] == base + 2*pagesize, "wrong result %p\n", results[0] );
1207     ok( results[1] == base + 4*pagesize, "wrong result %p\n", results[1] );
1208
1209     /* changing protections doesn't affect watches */
1210
1211     ret = VirtualProtect( base, 3*pagesize, PAGE_READONLY, &old_prot );
1212     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
1213     ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
1214
1215     ret = VirtualQuery( base, &info, sizeof(info) );
1216     ok(ret, "VirtualQuery failed %u\n", GetLastError());
1217     ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
1218     ok( info.RegionSize == 3*pagesize, "wrong RegionSize 0x%lx\n", info.RegionSize );
1219     ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
1220     ok( info.Protect == PAGE_READONLY, "wrong Protect 0x%x\n", info.Protect );
1221
1222     ret = VirtualProtect( base, 3*pagesize, PAGE_READWRITE, &old_prot );
1223     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
1224     ok( old_prot == PAGE_READONLY, "wrong old prot %x\n", old_prot );
1225
1226     count = 64;
1227     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1228     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1229     ok( count == 2, "wrong count %lu\n", count );
1230     ok( results[0] == base + 2*pagesize, "wrong result %p\n", results[0] );
1231     ok( results[1] == base + 4*pagesize, "wrong result %p\n", results[1] );
1232
1233     ret = VirtualQuery( base, &info, sizeof(info) );
1234     ok(ret, "VirtualQuery failed %u\n", GetLastError());
1235     ok( info.BaseAddress == base, "BaseAddress %p instead of %p\n", info.BaseAddress, base );
1236     ok( info.RegionSize == size, "wrong RegionSize 0x%lx\n", info.RegionSize );
1237     ok( info.State == MEM_COMMIT, "wrong State 0x%x\n", info.State );
1238     ok( info.Protect == PAGE_READWRITE, "wrong Protect 0x%x\n", info.Protect );
1239
1240     /* some invalid parameter tests */
1241
1242     SetLastError( 0xdeadbeef );
1243     count = 0;
1244     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1245     if (ret)
1246     {
1247         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1248         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1249
1250         SetLastError( 0xdeadbeef );
1251         ret = pGetWriteWatch( 0, base, size, results, NULL, &pagesize );
1252         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1253         ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
1254
1255         SetLastError( 0xdeadbeef );
1256         count = 64;
1257         ret = pGetWriteWatch( 0, base, size, results, &count, NULL );
1258         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1259         ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
1260
1261         SetLastError( 0xdeadbeef );
1262         count = 64;
1263         ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
1264         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1265         ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
1266
1267         SetLastError( 0xdeadbeef );
1268         count = 0;
1269         ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
1270         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1271         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1272
1273         SetLastError( 0xdeadbeef );
1274         count = 64;
1275         ret = pGetWriteWatch( 0xdeadbeef, base, size, results, &count, &pagesize );
1276         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1277         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1278
1279         SetLastError( 0xdeadbeef );
1280         count = 64;
1281         ret = pGetWriteWatch( 0, base, 0, results, &count, &pagesize );
1282         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1283         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1284
1285         SetLastError( 0xdeadbeef );
1286         count = 64;
1287         ret = pGetWriteWatch( 0, base, size * 2, results, &count, &pagesize );
1288         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1289         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1290
1291         SetLastError( 0xdeadbeef );
1292         count = 64;
1293         ret = pGetWriteWatch( 0, base + size - pagesize, pagesize + 1, results, &count, &pagesize );
1294         ok( ret == ~0u, "GetWriteWatch succeeded %u\n", ret );
1295         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1296
1297         SetLastError( 0xdeadbeef );
1298         ret = pResetWriteWatch( base, 0 );
1299         ok( ret == ~0u, "ResetWriteWatch succeeded %u\n", ret );
1300         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1301
1302         SetLastError( 0xdeadbeef );
1303         ret = pResetWriteWatch( GetModuleHandle(0), size );
1304         ok( ret == ~0u, "ResetWriteWatch succeeded %u\n", ret );
1305         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1306     }
1307     else  /* win98 is completely different */
1308     {
1309         SetLastError( 0xdeadbeef );
1310         count = 64;
1311         ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
1312         ok( ret == ERROR_INVALID_PARAMETER, "GetWriteWatch succeeded %u\n", ret );
1313         ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
1314
1315         count = 0;
1316         ret = pGetWriteWatch( 0, base, size, NULL, &count, &pagesize );
1317         ok( !ret, "GetWriteWatch failed %u\n", ret );
1318
1319         count = 64;
1320         ret = pGetWriteWatch( 0xdeadbeef, base, size, results, &count, &pagesize );
1321         ok( !ret, "GetWriteWatch failed %u\n", ret );
1322
1323         count = 64;
1324         ret = pGetWriteWatch( 0, base, 0, results, &count, &pagesize );
1325         ok( !ret, "GetWriteWatch failed %u\n", ret );
1326
1327         ret = pResetWriteWatch( base, 0 );
1328         ok( !ret, "ResetWriteWatch failed %u\n", ret );
1329
1330         ret = pResetWriteWatch( GetModuleHandle(0), size );
1331         ok( !ret, "ResetWriteWatch failed %u\n", ret );
1332     }
1333
1334     VirtualFree( base, 0, MEM_FREE );
1335
1336     base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_READWRITE );
1337     ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
1338     VirtualFree( base, 0, MEM_FREE );
1339
1340     base = VirtualAlloc( 0, size, MEM_WRITE_WATCH, PAGE_READWRITE );
1341     ok( !base, "VirtualAlloc succeeded\n" );
1342     ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
1343
1344     /* initial protect doesn't matter */
1345
1346     base = VirtualAlloc( 0, size, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_NOACCESS );
1347     ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
1348     base = VirtualAlloc( base, size, MEM_COMMIT, PAGE_NOACCESS );
1349     ok( base != NULL, "VirtualAlloc failed %u\n", GetLastError() );
1350
1351     count = 64;
1352     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1353     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1354     ok( count == 0, "wrong count %lu\n", count );
1355
1356     ret = VirtualProtect( base, 6*pagesize, PAGE_READWRITE, &old_prot );
1357     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
1358     ok( old_prot == PAGE_NOACCESS, "wrong old prot %x\n", old_prot );
1359
1360     base[5*pagesize + 200] = 3;
1361
1362     ret = VirtualProtect( base, 6*pagesize, PAGE_NOACCESS, &old_prot );
1363     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
1364     ok( old_prot == PAGE_READWRITE, "wrong old prot %x\n", old_prot );
1365
1366     count = 64;
1367     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1368     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1369     ok( count == 1, "wrong count %lu\n", count );
1370     ok( results[0] == base + 5*pagesize, "wrong result %p\n", results[0] );
1371
1372     ret = VirtualFree( base, size, MEM_DECOMMIT );
1373     ok( ret, "VirtualFree failed %u\n", GetLastError() );
1374
1375     count = 64;
1376     ret = pGetWriteWatch( 0, base, size, results, &count, &pagesize );
1377     ok( !ret, "GetWriteWatch failed %u\n", GetLastError() );
1378     ok( count == 1 || broken(count == 0), /* win98 */
1379         "wrong count %lu\n", count );
1380     if (count) ok( results[0] == base + 5*pagesize, "wrong result %p\n", results[0] );
1381
1382     VirtualFree( base, 0, MEM_FREE );
1383 }
1384
1385 START_TEST(virtual)
1386 {
1387     int argc;
1388     char **argv;
1389     argc = winetest_get_mainargs( &argv );
1390
1391     if (argc >= 3)
1392     {
1393         if (!strcmp(argv[2], "sleep"))
1394         {
1395             Sleep(5000); /* spawned process runs for at most 5 seconds */
1396             return;
1397         }
1398         while (1)
1399         {
1400             void *mem;
1401             BOOL ret;
1402             mem = VirtualAlloc(NULL, 1<<20, MEM_COMMIT|MEM_RESERVE,
1403                                PAGE_EXECUTE_READWRITE);
1404             ok(mem != NULL, "VirtualAlloc failed %u\n", GetLastError());
1405             if (mem == NULL) break;
1406             ret = VirtualFree(mem, 0, MEM_RELEASE);
1407             ok(ret, "VirtualFree failed %u\n", GetLastError());
1408             if (!ret) break;
1409         }
1410         return;
1411     }
1412
1413     hkernel32 = GetModuleHandleA("kernel32.dll");
1414     pVirtualAllocEx = (void *) GetProcAddress(hkernel32, "VirtualAllocEx");
1415     pVirtualFreeEx = (void *) GetProcAddress(hkernel32, "VirtualFreeEx");
1416     pGetWriteWatch = (void *) GetProcAddress(hkernel32, "GetWriteWatch");
1417     pResetWriteWatch = (void *) GetProcAddress(hkernel32, "ResetWriteWatch");
1418     pNtAreMappedFilesTheSame = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"),
1419                                                        "NtAreMappedFilesTheSame" );
1420
1421     test_VirtualAllocEx();
1422     test_VirtualAlloc();
1423     test_MapViewOfFile();
1424     test_NtMapViewOfSection();
1425     test_NtAreMappedFilesTheSame();
1426     test_CreateFileMapping();
1427     test_IsBadReadPtr();
1428     test_IsBadWritePtr();
1429     test_IsBadCodePtr();
1430     test_write_watch();
1431 }