kernel32/tests: Fix a couple of tests failing on NT4.
[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 "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wine/test.h"
28
29 #define NUM_THREADS 4
30 #define MAPPING_SIZE 0x100000
31
32 static HINSTANCE hkernel32;
33 static LPVOID (WINAPI *pVirtualAllocEx)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD);
34 static BOOL   (WINAPI *pVirtualFreeEx)(HANDLE, LPVOID, SIZE_T, DWORD);
35
36 /* ############################### */
37
38 static HANDLE create_target_process(const char *arg)
39 {
40     char **argv;
41     char cmdline[MAX_PATH];
42     PROCESS_INFORMATION pi;
43     STARTUPINFO si = { 0 };
44     si.cb = sizeof(si);
45
46     winetest_get_mainargs( &argv );
47     sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
48     ok(CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
49                      &si, &pi) != 0, "error: %u\n", GetLastError());
50     ok(CloseHandle(pi.hThread) != 0, "error %u\n", GetLastError());
51     return pi.hProcess;
52 }
53
54 static void test_VirtualAllocEx(void)
55 {
56     const unsigned int alloc_size = 1<<15;
57     char *src, *dst;
58     unsigned long bytes_written = 0, bytes_read = 0, i;
59     void *addr1, *addr2;
60     BOOL b;
61     DWORD old_prot;
62     MEMORY_BASIC_INFORMATION info;
63     HANDLE hProcess;
64
65     /* not exported in all windows-versions  */
66     if ((!pVirtualAllocEx) || (!pVirtualFreeEx)) {
67         skip("VirtualAllocEx not found\n");
68         return;
69     }
70
71     hProcess = create_target_process("sleep");
72     ok(hProcess != NULL, "Can't start process\n");
73
74     SetLastError(0xdeadbeef);
75     addr1 = pVirtualAllocEx(hProcess, NULL, alloc_size, MEM_COMMIT,
76                            PAGE_EXECUTE_READWRITE);
77     if (!addr1 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
78     {   /* Win9x */
79         skip("VirtualAllocEx not implemented\n");
80         TerminateProcess(hProcess, 0);
81         CloseHandle(hProcess);
82         return;
83     }
84
85     src = HeapAlloc( GetProcessHeap(), 0, alloc_size );
86     dst = HeapAlloc( GetProcessHeap(), 0, alloc_size );
87     for (i = 0; i < alloc_size; i++)
88         src[i] = i & 0xff;
89
90     ok(addr1 != NULL, "VirtualAllocEx error %u\n", GetLastError());
91     b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
92     ok(b && (bytes_written == alloc_size), "%lu bytes written\n",
93        bytes_written);
94     b = ReadProcessMemory(hProcess, addr1, dst, alloc_size, &bytes_read);
95     ok(b && (bytes_read == alloc_size), "%lu bytes read\n", bytes_read);
96     ok(!memcmp(src, dst, alloc_size), "Data from remote process differs\n");
97     b = pVirtualFreeEx(hProcess, addr1, 0, MEM_RELEASE);
98     ok(b != 0, "VirtualFreeEx, error %u\n", GetLastError());
99
100     HeapFree( GetProcessHeap(), 0, src );
101     HeapFree( GetProcessHeap(), 0, dst );
102
103     /*
104      * The following tests parallel those in test_VirtualAlloc()
105      */
106
107     SetLastError(0xdeadbeef);
108     addr1 = pVirtualAllocEx(hProcess, 0, 0, MEM_RESERVE, PAGE_NOACCESS);
109     ok(addr1 == NULL, "VirtualAllocEx should fail on zero-sized allocation\n");
110     ok(GetLastError() == ERROR_INVALID_PARAMETER /* NT */ ||
111        GetLastError() == ERROR_NOT_ENOUGH_MEMORY, /* Win9x */
112         "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
113
114     addr1 = pVirtualAllocEx(hProcess, 0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS);
115     ok(addr1 != NULL, "VirtualAllocEx failed\n");
116
117     /* test a not committed memory */
118     memset(&info, 'q', sizeof(info));
119     ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info)) == sizeof(info), "VirtualQueryEx failed\n");
120     ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
121     ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
122     ok(info.AllocationProtect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.AllocationProtect);
123     ok(info.RegionSize == 0x10000, "%lx != 0x10000\n", info.RegionSize);
124     ok(info.State == MEM_RESERVE, "%x != MEM_RESERVE\n", info.State);
125     /* NT reports Protect == 0 for a not committed memory block */
126     ok(info.Protect == 0 /* NT */ ||
127        info.Protect == PAGE_NOACCESS, /* Win9x */
128         "%x != PAGE_NOACCESS\n", info.Protect);
129     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
130
131     SetLastError(0xdeadbeef);
132     ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
133        "VirtualProtectEx should fail on a not committed memory\n");
134     ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
135        GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
136         "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
137
138     addr2 = pVirtualAllocEx(hProcess, addr1, 0x1000, MEM_COMMIT, PAGE_NOACCESS);
139     ok(addr1 == addr2, "VirtualAllocEx failed\n");
140
141     /* test a committed memory */
142     ok(VirtualQueryEx(hProcess, addr1, &info, sizeof(info)) == sizeof(info),
143         "VirtualQueryEx failed\n");
144     ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
145     ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
146     ok(info.AllocationProtect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.AllocationProtect);
147     ok(info.RegionSize == 0x1000, "%lx != 0x1000\n", info.RegionSize);
148     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
149     /* this time NT reports PAGE_NOACCESS as well */
150     ok(info.Protect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.Protect);
151     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
152
153     /* this should fail, since not the whole range is committed yet */
154     SetLastError(0xdeadbeef);
155     ok(!VirtualProtectEx(hProcess, addr1, 0xFFFC, PAGE_READONLY, &old_prot),
156         "VirtualProtectEx should fail on a not committed memory\n");
157     ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
158        GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
159         "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError());
160
161     old_prot = 0;
162     ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtectEx failed\n");
163     ok(old_prot == PAGE_NOACCESS, "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot);
164
165     old_prot = 0;
166     ok(VirtualProtectEx(hProcess, addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtectEx failed\n");
167     ok(old_prot == PAGE_READONLY, "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot);
168
169     ok(!pVirtualFreeEx(hProcess, addr1, 0x10000, 0),
170        "VirtualFreeEx should fail with type 0\n");
171     ok(GetLastError() == ERROR_INVALID_PARAMETER,
172         "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
173
174     ok(pVirtualFreeEx(hProcess, addr1, 0x10000, MEM_DECOMMIT), "VirtualFreeEx failed\n");
175
176     /* if the type is MEM_RELEASE, size must be 0 */
177     ok(!pVirtualFreeEx(hProcess, addr1, 1, MEM_RELEASE),
178        "VirtualFreeEx should fail\n");
179     ok(GetLastError() == ERROR_INVALID_PARAMETER,
180         "got %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
181
182     ok(pVirtualFreeEx(hProcess, addr1, 0, MEM_RELEASE), "VirtualFreeEx failed\n");
183
184     TerminateProcess(hProcess, 0);
185     CloseHandle(hProcess);
186 }
187
188 static void test_VirtualAlloc(void)
189 {
190     void *addr1, *addr2;
191     DWORD old_prot;
192     MEMORY_BASIC_INFORMATION info;
193
194     SetLastError(0xdeadbeef);
195     addr1 = VirtualAlloc(0, 0, MEM_RESERVE, PAGE_NOACCESS);
196     ok(addr1 == NULL, "VirtualAlloc should fail on zero-sized allocation\n");
197     ok(GetLastError() == ERROR_INVALID_PARAMETER /* NT */ ||
198        GetLastError() == ERROR_NOT_ENOUGH_MEMORY, /* Win9x */
199         "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
200
201     addr1 = VirtualAlloc(0, 0xFFFC, MEM_RESERVE, PAGE_NOACCESS);
202     ok(addr1 != NULL, "VirtualAlloc failed\n");
203
204     /* test a not committed memory */
205     ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
206         "VirtualQuery failed\n");
207     ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
208     ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
209     ok(info.AllocationProtect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.AllocationProtect);
210     ok(info.RegionSize == 0x10000, "%lx != 0x10000\n", info.RegionSize);
211     ok(info.State == MEM_RESERVE, "%x != MEM_RESERVE\n", info.State);
212     /* NT reports Protect == 0 for a not committed memory block */
213     ok(info.Protect == 0 /* NT */ ||
214        info.Protect == PAGE_NOACCESS, /* Win9x */
215         "%x != PAGE_NOACCESS\n", info.Protect);
216     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
217
218     SetLastError(0xdeadbeef);
219     ok(!VirtualProtect(addr1, 0xFFFC, PAGE_READONLY, &old_prot),
220        "VirtualProtect should fail on a not committed memory\n");
221     ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
222        GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
223         "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
224
225     addr2 = VirtualAlloc(addr1, 0x1000, MEM_COMMIT, PAGE_NOACCESS);
226     ok(addr1 == addr2, "VirtualAlloc failed\n");
227
228     /* test a committed memory */
229     ok(VirtualQuery(addr1, &info, sizeof(info)) == sizeof(info),
230         "VirtualQuery failed\n");
231     ok(info.BaseAddress == addr1, "%p != %p\n", info.BaseAddress, addr1);
232     ok(info.AllocationBase == addr1, "%p != %p\n", info.AllocationBase, addr1);
233     ok(info.AllocationProtect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.AllocationProtect);
234     ok(info.RegionSize == 0x1000, "%lx != 0x1000\n", info.RegionSize);
235     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
236     /* this time NT reports PAGE_NOACCESS as well */
237     ok(info.Protect == PAGE_NOACCESS, "%x != PAGE_NOACCESS\n", info.Protect);
238     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
239
240     /* this should fail, since not the whole range is committed yet */
241     SetLastError(0xdeadbeef);
242     ok(!VirtualProtect(addr1, 0xFFFC, PAGE_READONLY, &old_prot),
243         "VirtualProtect should fail on a not committed memory\n");
244     ok(GetLastError() == ERROR_INVALID_ADDRESS /* NT */ ||
245        GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x */
246         "got %d, expected ERROR_INVALID_ADDRESS\n", GetLastError());
247
248     ok(VirtualProtect(addr1, 0x1000, PAGE_READONLY, &old_prot), "VirtualProtect failed\n");
249     ok(old_prot == PAGE_NOACCESS,
250         "wrong old protection: got %04x instead of PAGE_NOACCESS\n", old_prot);
251
252     ok(VirtualProtect(addr1, 0x1000, PAGE_READWRITE, &old_prot), "VirtualProtect failed\n");
253     ok(old_prot == PAGE_READONLY,
254         "wrong old protection: got %04x instead of PAGE_READONLY\n", old_prot);
255
256     ok(!VirtualFree(addr1, 0x10000, 0), "VirtualFree should fail with type 0\n");
257     ok(GetLastError() == ERROR_INVALID_PARAMETER,
258         "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
259
260     ok(VirtualFree(addr1, 0x10000, MEM_DECOMMIT), "VirtualFree failed\n");
261
262     /* if the type is MEM_RELEASE, size must be 0 */
263     ok(!VirtualFree(addr1, 1, MEM_RELEASE), "VirtualFree should fail\n");
264     ok(GetLastError() == ERROR_INVALID_PARAMETER,
265         "got %d, expected ERROR_INVALID_PARAMETER\n", GetLastError());
266
267     ok(VirtualFree(addr1, 0, MEM_RELEASE), "VirtualFree failed\n");
268 }
269
270 static void test_MapViewOfFile(void)
271 {
272     static const char testfile[] = "testfile.xxx";
273     const char *name;
274     HANDLE file, mapping;
275     void *ptr, *ptr2;
276     MEMORY_BASIC_INFORMATION info;
277     BOOL ret;
278
279     SetLastError(0xdeadbeef);
280     file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
281     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
282     SetFilePointer( file, 4096, NULL, FILE_BEGIN );
283     SetEndOfFile( file );
284
285     /* read/write mapping */
286
287     SetLastError(0xdeadbeef);
288     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
289     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
290
291     SetLastError(0xdeadbeef);
292     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
293     ok( ptr != NULL, "MapViewOfFile FILE_MAPE_READ error %u\n", GetLastError() );
294     UnmapViewOfFile( ptr );
295
296     /* this fails on win9x but succeeds on NT */
297     SetLastError(0xdeadbeef);
298     ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
299     if (ptr) UnmapViewOfFile( ptr );
300     else ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
301
302     SetLastError(0xdeadbeef);
303     ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
304     ok( ptr != NULL, "MapViewOfFile 0 error %u\n", GetLastError() );
305     UnmapViewOfFile( ptr );
306
307     SetLastError(0xdeadbeef);
308     ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
309     ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
310     UnmapViewOfFile( ptr );
311     CloseHandle( mapping );
312
313     /* read-only mapping */
314
315     SetLastError(0xdeadbeef);
316     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
317     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
318
319     SetLastError(0xdeadbeef);
320     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
321     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
322     UnmapViewOfFile( ptr );
323
324     /* this fails on win9x but succeeds on NT */
325     SetLastError(0xdeadbeef);
326     ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
327     if (ptr) UnmapViewOfFile( ptr );
328     else ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
329
330     SetLastError(0xdeadbeef);
331     ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
332     ok( ptr != NULL, "MapViewOfFile 0 error %u\n", GetLastError() );
333     UnmapViewOfFile( ptr );
334
335     SetLastError(0xdeadbeef);
336     ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
337     ok( !ptr, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
338     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
339         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
340     CloseHandle( mapping );
341
342     /* copy-on-write mapping */
343
344     SetLastError(0xdeadbeef);
345     mapping = CreateFileMappingA( file, NULL, PAGE_WRITECOPY, 0, 4096, NULL );
346     ok( mapping != 0, "CreateFileMapping error %u\n", GetLastError() );
347
348     SetLastError(0xdeadbeef);
349     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
350     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
351     UnmapViewOfFile( ptr );
352
353     SetLastError(0xdeadbeef);
354     ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
355     ok( ptr != NULL, "MapViewOfFile FILE_MAP_COPY error %u\n", GetLastError() );
356     UnmapViewOfFile( ptr );
357
358     SetLastError(0xdeadbeef);
359     ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
360     ok( ptr != NULL, "MapViewOfFile 0 error %u\n", GetLastError() );
361     UnmapViewOfFile( ptr );
362
363     SetLastError(0xdeadbeef);
364     ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
365     ok( !ptr, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
366     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
367         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
368     CloseHandle( mapping );
369
370     /* no access mapping */
371
372     SetLastError(0xdeadbeef);
373     mapping = CreateFileMappingA( file, NULL, PAGE_NOACCESS, 0, 4096, NULL );
374     /* fails on NT but succeeds on win9x */
375     if (!mapping) ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
376     else
377     {
378         SetLastError(0xdeadbeef);
379         ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4096 );
380         ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
381         UnmapViewOfFile( ptr );
382
383         SetLastError(0xdeadbeef);
384         ptr = MapViewOfFile( mapping, FILE_MAP_COPY, 0, 0, 4096 );
385         ok( !ptr, "MapViewOfFile FILE_MAP_COPY succeeded\n" );
386         ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
387
388         SetLastError(0xdeadbeef);
389         ptr = MapViewOfFile( mapping, 0, 0, 0, 4096 );
390         ok( ptr != NULL, "MapViewOfFile 0 error %u\n", GetLastError() );
391         UnmapViewOfFile( ptr );
392
393         SetLastError(0xdeadbeef);
394         ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 4096 );
395         ok( !ptr, "MapViewOfFile FILE_MAP_WRITE succeeded\n" );
396         ok( GetLastError() == ERROR_INVALID_PARAMETER, "Wrong error %d\n", GetLastError() );
397
398         CloseHandle( mapping );
399     }
400
401     CloseHandle( file );
402
403     /* now try read-only file */
404
405     SetLastError(0xdeadbeef);
406     file = CreateFileA( testfile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
407     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
408
409     SetLastError(0xdeadbeef);
410     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
411     ok( !mapping, "CreateFileMapping PAGE_READWRITE succeeded\n" );
412     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
413         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
414
415     SetLastError(0xdeadbeef);
416     mapping = CreateFileMappingA( file, NULL, PAGE_WRITECOPY, 0, 4096, NULL );
417     ok( mapping != 0, "CreateFileMapping PAGE_WRITECOPY error %u\n", GetLastError() );
418     CloseHandle( mapping );
419
420     SetLastError(0xdeadbeef);
421     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
422     ok( mapping != 0, "CreateFileMapping PAGE_READONLY error %u\n", GetLastError() );
423     CloseHandle( mapping );
424     CloseHandle( file );
425
426     /* now try no access file */
427
428     SetLastError(0xdeadbeef);
429     file = CreateFileA( testfile, 0, 0, NULL, OPEN_EXISTING, 0, 0 );
430     ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() );
431
432     SetLastError(0xdeadbeef);
433     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
434     ok( !mapping, "CreateFileMapping PAGE_READWRITE succeeded\n" );
435     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
436         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
437
438     SetLastError(0xdeadbeef);
439     mapping = CreateFileMappingA( file, NULL, PAGE_WRITECOPY, 0, 4096, NULL );
440     ok( !mapping, "CreateFileMapping PAGE_WRITECOPY succeeded\n" );
441     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
442         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
443
444     SetLastError(0xdeadbeef);
445     mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 4096, NULL );
446     ok( !mapping, "CreateFileMapping PAGE_READONLY succeeded\n" );
447     ok( GetLastError() == ERROR_INVALID_PARAMETER ||
448         GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
449
450     CloseHandle( file );
451     DeleteFileA( testfile );
452
453     SetLastError(0xdeadbeef);
454     name = "Local\\Foo";
455     file = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name );
456     /* nt4 doesn't have Local\\ */
457     if (!file && GetLastError() == ERROR_PATH_NOT_FOUND)
458     {
459         name = "Foo";
460         file = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, name );
461     }
462     ok( file != 0, "CreateFileMapping PAGE_READWRITE error %u\n", GetLastError() );
463
464     SetLastError(0xdeadbeef);
465     mapping = OpenFileMapping( FILE_MAP_READ, FALSE, name );
466     ok( mapping != 0, "OpenFileMapping FILE_MAP_READ error %u\n", GetLastError() );
467     SetLastError(0xdeadbeef);
468     ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
469 todo_wine ok( !ptr, "MapViewOfFile FILE_MAP_WRITE should fail\n" );
470 todo_wine ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
471     SetLastError(0xdeadbeef);
472     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
473     ok( ptr != NULL, "MapViewOfFile FILE_MAP_READ error %u\n", GetLastError() );
474     SetLastError(0xdeadbeef);
475     ok( VirtualQuery( ptr, &info, sizeof(info) ) == sizeof(info),
476         "VirtualQuery error %u\n", GetLastError() );
477     ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
478     ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
479 todo_wine ok( info.AllocationProtect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.AllocationProtect );
480     ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
481     ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
482 todo_wine ok( info.Protect == PAGE_READONLY, "%x != PAGE_READONLY\n", info.Protect );
483     UnmapViewOfFile( ptr );
484     CloseHandle( mapping );
485
486     SetLastError(0xdeadbeef);
487     mapping = OpenFileMapping( FILE_MAP_WRITE, FALSE, name );
488     ok( mapping != 0, "OpenFileMapping FILE_MAP_WRITE error %u\n", GetLastError() );
489     SetLastError(0xdeadbeef);
490     ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
491 todo_wine ok( !ptr, "MapViewOfFile FILE_MAP_READ should fail\n" );
492 todo_wine ok( GetLastError() == ERROR_ACCESS_DENIED, "Wrong error %d\n", GetLastError() );
493     SetLastError(0xdeadbeef);
494     ptr = MapViewOfFile( mapping, FILE_MAP_WRITE, 0, 0, 0 );
495     ok( ptr != NULL, "MapViewOfFile FILE_MAP_WRITE error %u\n", GetLastError() );
496     SetLastError(0xdeadbeef);
497     ok( VirtualQuery( ptr, &info, sizeof(info) ) == sizeof(info),
498         "VirtualQuery error %u\n", GetLastError() );
499     ok( info.BaseAddress == ptr, "%p != %p\n", info.BaseAddress, ptr );
500     ok( info.AllocationBase == ptr, "%p != %p\n", info.AllocationBase, ptr );
501     ok( info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect );
502     ok( info.RegionSize == 4096, "%lx != 4096\n", info.RegionSize );
503     ok( info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State );
504     ok( info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect );
505     UnmapViewOfFile( ptr );
506     CloseHandle( mapping );
507
508     CloseHandle( file );
509
510     /* read/write mapping with SEC_RESERVE */
511     mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE, 0, MAPPING_SIZE, NULL);
512     ok(mapping != INVALID_HANDLE_VALUE, "CreateFileMappingA failed with error %d\n", GetLastError());
513
514     ptr = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
515     ok(ptr != NULL, "MapViewOfFile failed with error %d\n", GetLastError());
516
517     ret = VirtualQuery(ptr, &info, sizeof(info));
518     ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
519     ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
520     ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
521     ok(info.AllocationProtect == PAGE_READWRITE, "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
522     ok(info.RegionSize == MAPPING_SIZE, "RegionSize should have been 0x%x but was 0x%x\n", MAPPING_SIZE, (unsigned int)info.RegionSize);
523 todo_wine
524     ok(info.State == MEM_RESERVE, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
525 todo_wine
526     ok(info.Protect == 0, "Protect should have been 0 instead of 0x%x\n", info.Protect);
527     ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
528
529     ptr = VirtualAlloc(ptr, 0x10000, MEM_COMMIT, PAGE_READWRITE);
530     ok(ptr != NULL, "VirtualAlloc failed with error %d\n", GetLastError());
531
532     ret = VirtualQuery(ptr, &info, sizeof(info));
533     ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
534     ok(info.BaseAddress == ptr, "BaseAddress should have been %p but was %p instead\n", ptr, info.BaseAddress);
535     ok(info.AllocationBase == ptr, "AllocationBase should have been %p but was %p instead\n", ptr, info.AllocationBase);
536     ok(info.AllocationProtect == PAGE_READWRITE, "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
537 todo_wine
538     ok(info.RegionSize == 0x10000, "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info.RegionSize);
539     ok(info.State == MEM_COMMIT, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
540     ok(info.Protect == PAGE_READWRITE, "Protect should have been 0 instead of 0x%x\n", info.Protect);
541     ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
542
543     ptr2 = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
544     /* on NT ptr != ptr2 but on Win9x ptr == ptr2 */
545     ok(ptr2 != NULL, "MapViewOfFile failed with error %d\n", GetLastError());
546     trace("mapping same section resulted in views %p and %p\n", ptr, ptr2);
547
548     /* shows that the VirtualAlloc above affects the mapping, not just the
549      * virtual memory in this process - it also affects all other processes
550      * with a view of the mapping, but that isn't tested here */
551     ret = VirtualQuery(ptr2, &info, sizeof(info));
552     ok(ret, "VirtualQuery failed with error %d\n", GetLastError());
553     ok(info.BaseAddress == ptr2, "BaseAddress should have been %p but was %p instead\n", ptr2, info.BaseAddress);
554     ok(info.AllocationBase == ptr2, "AllocationBase should have been %p but was %p instead\n", ptr2, info.AllocationBase);
555     ok(info.AllocationProtect == PAGE_READWRITE, "AllocationProtect should have been PAGE_READWRITE but was 0x%x\n", info.AllocationProtect);
556 todo_wine
557     ok(info.RegionSize == 0x10000, "RegionSize should have been 0x10000 but was 0x%x\n", (unsigned int)info.RegionSize);
558     ok(info.State == MEM_COMMIT, "State should have been MEM_RESERVE instead of 0x%x\n", info.State);
559     ok(info.Protect == PAGE_READWRITE, "Protect should have been 0 instead of 0x%x\n", info.Protect);
560     ok(info.Type == MEM_MAPPED, "Type should have been MEM_MAPPED instead of 0x%x\n", info.Type);
561
562     ret = UnmapViewOfFile(ptr2);
563     ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError());
564     ret = UnmapViewOfFile(ptr);
565     ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError());
566     CloseHandle(mapping);
567 }
568
569 static DWORD (WINAPI *pNtMapViewOfSection)( HANDLE handle, HANDLE process, PVOID *addr_ptr,
570                                             ULONG zero_bits, SIZE_T commit_size,
571                                             const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr,
572                                             ULONG inherit, ULONG alloc_type, ULONG protect );
573 static DWORD (WINAPI *pNtUnmapViewOfSection)( HANDLE process, PVOID addr );
574
575 static void test_NtMapViewOfSection(void)
576 {
577     HANDLE hProcess;
578
579     static const char testfile[] = "testfile.xxx";
580     static const char data[] = "test data for NtMapViewOfSection";
581     char buffer[sizeof(data)];
582     HANDLE file, mapping;
583     void *ptr;
584     BOOL ret;
585     DWORD status, written;
586     SIZE_T size, result;
587     LARGE_INTEGER offset;
588
589     pNtMapViewOfSection = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"), "NtMapViewOfSection" );
590     pNtUnmapViewOfSection = (void *)GetProcAddress( GetModuleHandle("ntdll.dll"), "NtUnmapViewOfSection" );
591     if (!pNtMapViewOfSection || !pNtUnmapViewOfSection)
592     {
593         skip( "NtMapViewOfSection not found\n" );
594         return;
595     }
596
597     file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
598     ok( file != INVALID_HANDLE_VALUE, "Failed to create test file\n" );
599     WriteFile( file, data, sizeof(data), &written, NULL );
600     SetFilePointer( file, 4096, NULL, FILE_BEGIN );
601     SetEndOfFile( file );
602
603     /* read/write mapping */
604
605     mapping = CreateFileMappingA( file, NULL, PAGE_READWRITE, 0, 4096, NULL );
606     ok( mapping != 0, "CreateFileMapping failed\n" );
607
608     hProcess = create_target_process("sleep");
609     ok(hProcess != NULL, "Can't start process\n");
610
611     ptr = NULL;
612     size = 0;
613     offset.QuadPart = 0;
614     status = pNtMapViewOfSection( mapping, hProcess, &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READWRITE );
615     ok( !status, "NtMapViewOfSection failed status %x\n", status );
616
617     ret = ReadProcessMemory( hProcess, ptr, buffer, sizeof(buffer), &result );
618     ok( ret, "ReadProcessMemory failed\n" );
619     ok( result == sizeof(buffer), "ReadProcessMemory didn't read all data (%lx)\n", result );
620     ok( !memcmp( buffer, data, sizeof(buffer) ), "Wrong data read\n" );
621
622     status = pNtUnmapViewOfSection( hProcess, ptr );
623     ok( !status, "NtUnmapViewOfSection failed status %x\n", status );
624
625     CloseHandle( mapping );
626     CloseHandle( file );
627     DeleteFileA( testfile );
628
629     TerminateProcess(hProcess, 0);
630     CloseHandle(hProcess);
631 }
632
633 static void test_CreateFileMapping(void)
634 {
635     HANDLE handle, handle2;
636
637     /* test case sensitivity */
638
639     SetLastError(0xdeadbeef);
640     handle = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, 0x1000,
641                                  __FILE__ ": Test Mapping");
642     ok( handle != NULL, "CreateFileMapping failed with error %u\n", GetLastError());
643     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
644
645     SetLastError(0xdeadbeef);
646     handle2 = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, 0x1000,
647                                   __FILE__ ": Test Mapping");
648     ok( handle2 != NULL, "CreateFileMapping failed with error %d\n", GetLastError());
649     ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
650     CloseHandle( handle2 );
651
652     SetLastError(0xdeadbeef);
653     handle2 = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE, 0, 0x1000,
654                                  __FILE__ ": TEST MAPPING");
655     ok( handle2 != NULL, "CreateFileMapping failed with error %d\n", GetLastError());
656     ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
657     CloseHandle( handle2 );
658
659     SetLastError(0xdeadbeef);
660     handle2 = OpenFileMappingA( FILE_MAP_ALL_ACCESS, FALSE, __FILE__ ": Test Mapping");
661     ok( handle2 != NULL, "OpenFileMapping failed with error %d\n", GetLastError());
662     CloseHandle( handle2 );
663
664     SetLastError(0xdeadbeef);
665     handle2 = OpenFileMappingA( FILE_MAP_ALL_ACCESS, FALSE, __FILE__ ": TEST MAPPING");
666     ok( !handle2, "OpenFileMapping succeeded\n");
667     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
668
669     CloseHandle( handle );
670 }
671
672 static void test_BadPtr(void)
673 {
674     void *ptr = (void*)1;
675     /* We assume address 1 is not mapped. */
676     ok(IsBadReadPtr(ptr,1),"IsBadReadPtr(1) failed.\n");
677     ok(IsBadWritePtr(ptr,1),"IsBadWritePtr(1) failed.\n");
678     ok(IsBadCodePtr(ptr),"IsBadCodePtr(1) failed.\n");
679 }
680
681 START_TEST(virtual)
682 {
683     int argc;
684     char **argv;
685     argc = winetest_get_mainargs( &argv );
686
687     if (argc >= 3)
688     {
689         if (!strcmp(argv[2], "sleep"))
690         {
691             Sleep(5000); /* spawned process runs for at most 5 seconds */
692             return;
693         }
694         while (1)
695         {
696             void *mem;
697             BOOL ret;
698             mem = VirtualAlloc(NULL, 1<<20, MEM_COMMIT|MEM_RESERVE,
699                                PAGE_EXECUTE_READWRITE);
700             ok(mem != NULL, "VirtualAlloc failed %u\n", GetLastError());
701             if (mem == NULL) break;
702             ret = VirtualFree(mem, 0, MEM_RELEASE);
703             ok(ret, "VirtualFree failed %u\n", GetLastError());
704             if (!ret) break;
705         }
706         return;
707     }
708
709     hkernel32 = GetModuleHandleA("kernel32.dll");
710     pVirtualAllocEx = (void *) GetProcAddress(hkernel32, "VirtualAllocEx");
711     pVirtualFreeEx = (void *) GetProcAddress(hkernel32, "VirtualFreeEx");
712
713     test_VirtualAllocEx();
714     test_VirtualAlloc();
715     test_MapViewOfFile();
716     test_NtMapViewOfSection();
717     test_CreateFileMapping();
718     test_BadPtr();
719 }