Release 1.5.29.
[wine] / dlls / kernel32 / virtual.c
1 /*
2  * Win32 virtual memory functions
3  *
4  * Copyright 1997 Alexandre Julliard
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 "config.h"
22 #include "wine/port.h"
23
24 #include <fcntl.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32
33 #define NONAMELESSUNION
34 #define NONAMELESSSTRUCT
35 #include "ntstatus.h"
36 #define WIN32_NO_STATUS
37 #include "windef.h"
38 #include "winbase.h"
39 #include "winnls.h"
40 #include "winternl.h"
41 #include "winerror.h"
42 #include "psapi.h"
43 #include "wine/exception.h"
44 #include "wine/debug.h"
45
46 #include "kernel_private.h"
47
48 WINE_DECLARE_DEBUG_CHANNEL(seh);
49 WINE_DECLARE_DEBUG_CHANNEL(file);
50
51
52 /***********************************************************************
53  *             VirtualAlloc   (KERNEL32.@)
54  *
55  * Reserves or commits a region of pages in virtual address space.
56  *
57  * PARAMS
58  *  addr    [I] Address of region to reserve or commit.
59  *  size    [I] Size of region.
60  *  type    [I] Type of allocation.
61  *  protect [I] Type of access protection.
62  *
63  * RETURNS
64  *      Success: Base address of allocated region of pages.
65  *      Failure: NULL.
66  */
67 LPVOID WINAPI VirtualAlloc( LPVOID addr, SIZE_T size, DWORD type, DWORD protect )
68 {
69     return VirtualAllocEx( GetCurrentProcess(), addr, size, type, protect );
70 }
71
72
73 /***********************************************************************
74  *             VirtualAllocEx   (KERNEL32.@)
75  *
76  * Seems to be just as VirtualAlloc, but with process handle.
77  *
78  * PARAMS
79  *  hProcess [I] Handle to process to do mem operation.
80  *  addr     [I] Address of region to reserve or commit.
81  *  size     [I] Size of region.
82  *  type     [I] Type of allocation.
83  *  protect  [I] Type of access protection.
84  *
85  *
86  * RETURNS
87  *      Success: Base address of allocated region of pages.
88  *      Failure: NULL.
89  */
90 LPVOID WINAPI VirtualAllocEx( HANDLE hProcess, LPVOID addr, SIZE_T size,
91     DWORD type, DWORD protect )
92 {
93     LPVOID ret = addr;
94     NTSTATUS status;
95
96     if ((status = NtAllocateVirtualMemory( hProcess, &ret, 0, &size, type, protect )))
97     {
98         SetLastError( RtlNtStatusToDosError(status) );
99         ret = NULL;
100     }
101     return ret;
102 }
103
104
105 /***********************************************************************
106  *             VirtualFree   (KERNEL32.@)
107  *
108  * Releases or decommits a region of pages in virtual address space.
109  *
110  * PARAMS
111  *  addr [I] Address of region of committed pages.
112  *  size [I] Size of region.
113  *  type [I] Type of operation.
114  *
115  * RETURNS
116  *      Success: TRUE.
117  *      Failure: FALSE.
118  */
119 BOOL WINAPI VirtualFree( LPVOID addr, SIZE_T size, DWORD type )
120 {
121     return VirtualFreeEx( GetCurrentProcess(), addr, size, type );
122 }
123
124
125 /***********************************************************************
126  *             VirtualFreeEx   (KERNEL32.@)
127  *
128  * Releases or decommits a region of pages in virtual address space.
129  *
130  * PARAMS
131  *  process [I] Handle to process.
132  *  addr    [I] Address of region to free.
133  *  size    [I] Size of region.
134  *  type    [I] Type of operation.
135  *
136  * RETURNS
137  *      Success: TRUE.
138  *      Failure: FALSE.
139  */
140 BOOL WINAPI VirtualFreeEx( HANDLE process, LPVOID addr, SIZE_T size, DWORD type )
141 {
142     NTSTATUS status = NtFreeVirtualMemory( process, &addr, &size, type );
143     if (status) SetLastError( RtlNtStatusToDosError(status) );
144     return !status;
145 }
146
147
148 /***********************************************************************
149  *             VirtualLock   (KERNEL32.@)
150  *
151  * Locks the specified region of virtual address space.
152  *
153  * PARAMS
154  *  addr [I] Address of first byte of range to lock.
155  *  size [I] Number of bytes in range to lock.
156  *
157  * RETURNS
158  *      Success: TRUE.
159  *      Failure: FALSE.
160  *
161  * NOTES
162  *      Always returns TRUE.
163  *
164  */
165 BOOL WINAPI VirtualLock( LPVOID addr, SIZE_T size )
166 {
167     NTSTATUS status = NtLockVirtualMemory( GetCurrentProcess(), &addr, &size, 1 );
168     if (status) SetLastError( RtlNtStatusToDosError(status) );
169     return !status;
170 }
171
172
173 /***********************************************************************
174  *             VirtualUnlock   (KERNEL32.@)
175  *
176  * Unlocks a range of pages in the virtual address space.
177  *
178  * PARAMS
179  *  addr [I] Address of first byte of range.
180  *  size [I] Number of bytes in range.
181  *
182  * RETURNS
183  *      Success: TRUE.
184  *      Failure: FALSE.
185  *
186  * NOTES
187  *      Always returns TRUE.
188  *
189  */
190 BOOL WINAPI VirtualUnlock( LPVOID addr, SIZE_T size )
191 {
192     NTSTATUS status = NtUnlockVirtualMemory( GetCurrentProcess(), &addr, &size, 1 );
193     if (status) SetLastError( RtlNtStatusToDosError(status) );
194     return !status;
195 }
196
197
198 /***********************************************************************
199  *             VirtualProtect   (KERNEL32.@)
200  *
201  * Changes the access protection on a region of committed pages.
202  *
203  * PARAMS
204  *  addr     [I] Address of region of committed pages.
205  *  size     [I] Size of region.
206  *  new_prot [I] Desired access protection.
207  *  old_prot [O] Address of variable to get old protection.
208  *
209  * RETURNS
210  *      Success: TRUE.
211  *      Failure: FALSE.
212  */
213 BOOL WINAPI VirtualProtect( LPVOID addr, SIZE_T size, DWORD new_prot, LPDWORD old_prot)
214 {
215     return VirtualProtectEx( GetCurrentProcess(), addr, size, new_prot, old_prot );
216 }
217
218
219 /***********************************************************************
220  *             VirtualProtectEx   (KERNEL32.@)
221  *
222  * Changes the access protection on a region of committed pages in the
223  * virtual address space of a specified process.
224  *
225  * PARAMS
226  *  process  [I] Handle of process.
227  *  addr     [I] Address of region of committed pages.
228  *  size     [I] Size of region.
229  *  new_prot [I] Desired access protection.
230  *  old_prot [O] Address of variable to get old protection.
231  *
232  * RETURNS
233  *      Success: TRUE.
234  *      Failure: FALSE.
235  */
236 BOOL WINAPI VirtualProtectEx( HANDLE process, LPVOID addr, SIZE_T size,
237     DWORD new_prot, LPDWORD old_prot )
238 {
239     NTSTATUS status = NtProtectVirtualMemory( process, &addr, &size, new_prot, old_prot );
240     if (status) SetLastError( RtlNtStatusToDosError(status) );
241     return !status;
242 }
243
244
245 /***********************************************************************
246  *             VirtualQuery   (KERNEL32.@)
247  *
248  * Provides info about a range of pages in virtual address space.
249  *
250  * PARAMS
251  *  addr [I] Address of region.
252  *  info [O] Address of info buffer.
253  *  len  [I] Size of buffer.
254  *
255  * RETURNS
256  *      Number of bytes returned in information buffer or 0 if
257  *      addr >= 0xc0000000 (kernel space).
258  */
259 SIZE_T WINAPI VirtualQuery( LPCVOID addr, PMEMORY_BASIC_INFORMATION info,
260     SIZE_T len )
261 {
262     return VirtualQueryEx( GetCurrentProcess(), addr, info, len );
263 }
264
265
266 /***********************************************************************
267  *             VirtualQueryEx   (KERNEL32.@)
268  *
269  * Provides info about a range of pages in virtual address space of a
270  * specified process.
271  *
272  * PARAMS
273  *  process [I] Handle to process.
274  *  addr    [I] Address of region.
275  *  info    [O] Address of info buffer.
276  *  len     [I] Size of buffer.
277  *
278  * RETURNS
279  *      Number of bytes returned in information buffer.
280  */
281 SIZE_T WINAPI VirtualQueryEx( HANDLE process, LPCVOID addr,
282     PMEMORY_BASIC_INFORMATION info, SIZE_T len )
283 {
284     SIZE_T ret;
285     NTSTATUS status;
286
287     if ((status = NtQueryVirtualMemory( process, addr, MemoryBasicInformation, info, len, &ret )))
288     {
289         SetLastError( RtlNtStatusToDosError(status) );
290         ret = 0;
291     }
292     return ret;
293 }
294
295
296 /***********************************************************************
297  *             CreateFileMappingA   (KERNEL32.@)
298  *
299  * Creates a named or unnamed file-mapping object for the specified file.
300  *
301  * PARAMS
302  *  hFile     [I] Handle to the file to map.
303  *  sa        [I] Optional security attributes.
304  *  protect   [I] Protection for mapping object.
305  *  size_high [I] High-order 32 bits of object size.
306  *  size_low  [I] Low-order 32 bits of object size.
307  *  name      [I] Name of file-mapping object.
308  *
309  * RETURNS
310  *      Success: Handle.
311  *      Failure: NULL. Mapping object does not exist.
312  */
313 HANDLE WINAPI CreateFileMappingA( HANDLE hFile, SECURITY_ATTRIBUTES *sa,
314     DWORD protect, DWORD size_high, DWORD size_low, LPCSTR name )
315 {
316     WCHAR buffer[MAX_PATH];
317
318     if (!name) return CreateFileMappingW( hFile, sa, protect, size_high, size_low, NULL );
319
320     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
321     {
322         SetLastError( ERROR_FILENAME_EXCED_RANGE );
323         return 0;
324     }
325     return CreateFileMappingW( hFile, sa, protect, size_high, size_low, buffer );
326 }
327
328
329 /***********************************************************************
330  *             CreateFileMappingW   (KERNEL32.@)
331  *
332  * See CreateFileMappingA.
333  */
334 HANDLE WINAPI CreateFileMappingW( HANDLE hFile, LPSECURITY_ATTRIBUTES sa,
335                                   DWORD protect, DWORD size_high,
336                                   DWORD size_low, LPCWSTR name )
337 {
338     static const int sec_flags = SEC_FILE | SEC_IMAGE | SEC_RESERVE | SEC_COMMIT | SEC_NOCACHE;
339
340     HANDLE ret;
341     NTSTATUS status;
342     DWORD access, sec_type;
343     LARGE_INTEGER size;
344
345     sec_type = protect & sec_flags;
346     protect &= ~sec_flags;
347     if (!sec_type) sec_type = SEC_COMMIT;
348
349     /* Win9x compatibility */
350     if (!protect && (GetVersion() & 0x80000000)) protect = PAGE_READONLY;
351
352     switch(protect)
353     {
354     case PAGE_READONLY:
355     case PAGE_WRITECOPY:
356         access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE;
357         break;
358     case PAGE_READWRITE:
359         access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE;
360         break;
361     case PAGE_EXECUTE_READ:
362     case PAGE_EXECUTE_WRITECOPY:
363         access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_EXECUTE_EXPLICIT;
364         break;
365     case PAGE_EXECUTE_READWRITE:
366         access = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE | SECTION_MAP_EXECUTE_EXPLICIT;
367         break;
368     default:
369         SetLastError( ERROR_INVALID_PARAMETER );
370         return 0;
371     }
372
373     if (hFile == INVALID_HANDLE_VALUE)
374     {
375         hFile = 0;
376         if (!size_low && !size_high)
377         {
378             SetLastError( ERROR_INVALID_PARAMETER );
379             return 0;
380         }
381     }
382
383     size.u.LowPart  = size_low;
384     size.u.HighPart = size_high;
385
386     if (sa || name)
387     {
388         OBJECT_ATTRIBUTES attr;
389         UNICODE_STRING nameW;
390
391         attr.Length                   = sizeof(attr);
392         attr.RootDirectory            = 0;
393         attr.ObjectName               = NULL;
394         attr.Attributes               = OBJ_OPENIF | ((sa && sa->bInheritHandle) ? OBJ_INHERIT : 0);
395         attr.SecurityDescriptor       = sa ? sa->lpSecurityDescriptor : NULL;
396         attr.SecurityQualityOfService = NULL;
397         if (name)
398         {
399             RtlInitUnicodeString( &nameW, name );
400             attr.ObjectName = &nameW;
401             attr.RootDirectory = get_BaseNamedObjects_handle();
402         }
403         status = NtCreateSection( &ret, access, &attr, &size, protect, sec_type, hFile );
404     }
405     else status = NtCreateSection( &ret, access, NULL, &size, protect, sec_type, hFile );
406
407     if (status == STATUS_OBJECT_NAME_EXISTS)
408         SetLastError( ERROR_ALREADY_EXISTS );
409     else
410         SetLastError( RtlNtStatusToDosError(status) );
411     return ret;
412 }
413
414
415 /***********************************************************************
416  *             OpenFileMappingA   (KERNEL32.@)
417  *
418  * Opens a named file-mapping object.
419  *
420  * PARAMS
421  *  access  [I] Access mode.
422  *  inherit [I] Inherit flag.
423  *  name    [I] Name of file-mapping object.
424  *
425  * RETURNS
426  *      Success: Handle.
427  *      Failure: NULL.
428  */
429 HANDLE WINAPI OpenFileMappingA( DWORD access, BOOL inherit, LPCSTR name )
430 {
431     WCHAR buffer[MAX_PATH];
432
433     if (!name) return OpenFileMappingW( access, inherit, NULL );
434
435     if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH ))
436     {
437         SetLastError( ERROR_FILENAME_EXCED_RANGE );
438         return 0;
439     }
440     return OpenFileMappingW( access, inherit, buffer );
441 }
442
443
444 /***********************************************************************
445  *             OpenFileMappingW   (KERNEL32.@)
446  *
447  * See OpenFileMappingA.
448  */
449 HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name)
450 {
451     OBJECT_ATTRIBUTES attr;
452     UNICODE_STRING nameW;
453     HANDLE ret;
454     NTSTATUS status;
455
456     if (!name)
457     {
458         SetLastError( ERROR_INVALID_PARAMETER );
459         return 0;
460     }
461     attr.Length = sizeof(attr);
462     attr.RootDirectory = get_BaseNamedObjects_handle();
463     attr.ObjectName = &nameW;
464     attr.Attributes = inherit ? OBJ_INHERIT : 0;
465     attr.SecurityDescriptor = NULL;
466     attr.SecurityQualityOfService = NULL;
467     RtlInitUnicodeString( &nameW, name );
468
469     if (access == FILE_MAP_COPY) access = SECTION_MAP_READ;
470     access |= SECTION_QUERY;
471
472     if (GetVersion() & 0x80000000)
473     {
474         /* win9x doesn't do access checks, so try with full access first */
475         if (!NtOpenSection( &ret, access | SECTION_MAP_READ | SECTION_MAP_WRITE, &attr )) return ret;
476     }
477
478     if ((status = NtOpenSection( &ret, access, &attr )))
479     {
480         SetLastError( RtlNtStatusToDosError(status) );
481         ret = 0;
482     }
483     return ret;
484 }
485
486
487 /***********************************************************************
488  *             MapViewOfFile   (KERNEL32.@)
489  *
490  * Maps a view of a file into the address space.
491  *
492  * PARAMS
493  *  mapping     [I] File-mapping object to map.
494  *  access      [I] Access mode.
495  *  offset_high [I] High-order 32 bits of file offset.
496  *  offset_low  [I] Low-order 32 bits of file offset.
497  *  count       [I] Number of bytes to map.
498  *
499  * RETURNS
500  *      Success: Starting address of mapped view.
501  *      Failure: NULL.
502  */
503 LPVOID WINAPI MapViewOfFile( HANDLE mapping, DWORD access,
504     DWORD offset_high, DWORD offset_low, SIZE_T count )
505 {
506     return MapViewOfFileEx( mapping, access, offset_high,
507                             offset_low, count, NULL );
508 }
509
510
511 /***********************************************************************
512  *             MapViewOfFileEx   (KERNEL32.@)
513  *
514  * Maps a view of a file into the address space.
515  *
516  * PARAMS
517  *  handle      [I] File-mapping object to map.
518  *  access      [I] Access mode.
519  *  offset_high [I] High-order 32 bits of file offset.
520  *  offset_low  [I] Low-order 32 bits of file offset.
521  *  count       [I] Number of bytes to map.
522  *  addr        [I] Suggested starting address for mapped view.
523  *
524  * RETURNS
525  *      Success: Starting address of mapped view.
526  *      Failure: NULL.
527  */
528 LPVOID WINAPI MapViewOfFileEx( HANDLE handle, DWORD access,
529     DWORD offset_high, DWORD offset_low, SIZE_T count, LPVOID addr )
530 {
531     NTSTATUS status;
532     LARGE_INTEGER offset;
533     ULONG protect;
534     BOOL exec;
535
536     offset.u.LowPart  = offset_low;
537     offset.u.HighPart = offset_high;
538
539     exec = access & FILE_MAP_EXECUTE;
540     access &= ~FILE_MAP_EXECUTE;
541
542     if (access == FILE_MAP_COPY)
543         protect = exec ? PAGE_EXECUTE_WRITECOPY : PAGE_WRITECOPY;
544     else if (access & FILE_MAP_WRITE)
545         protect = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
546     else if (access & FILE_MAP_READ)
547         protect = exec ? PAGE_EXECUTE_READ : PAGE_READONLY;
548     else protect = PAGE_NOACCESS;
549
550     if ((status = NtMapViewOfSection( handle, GetCurrentProcess(), &addr, 0, 0, &offset,
551                                       &count, ViewShare, 0, protect )) < 0)
552     {
553         SetLastError( RtlNtStatusToDosError(status) );
554         addr = NULL;
555     }
556     return addr;
557 }
558
559
560 /***********************************************************************
561  *             UnmapViewOfFile   (KERNEL32.@)
562  *
563  * Unmaps a mapped view of a file.
564  *
565  * PARAMS
566  *  addr [I] Address where mapped view begins.
567  *
568  * RETURNS
569  *      Success: TRUE.
570  *      Failure: FALSE.
571  *
572  */
573 BOOL WINAPI UnmapViewOfFile( LPCVOID addr )
574 {
575     NTSTATUS status = NtUnmapViewOfSection( GetCurrentProcess(), (void *)addr );
576     if (status) SetLastError( RtlNtStatusToDosError(status) );
577     return !status;
578 }
579
580
581 /***********************************************************************
582  *             FlushViewOfFile   (KERNEL32.@)
583  *
584  * Writes to the disk a byte range within a mapped view of a file.
585  *
586  * PARAMS
587  *  base [I] Start address of byte range to flush.
588  *  size [I] Number of bytes in range.
589  *
590  * RETURNS
591  *      Success: TRUE.
592  *      Failure: FALSE.
593  */
594 BOOL WINAPI FlushViewOfFile( LPCVOID base, SIZE_T size )
595 {
596     NTSTATUS status = NtFlushVirtualMemory( GetCurrentProcess(), &base, &size, 0 );
597     if (status)
598     {
599         if (status == STATUS_NOT_MAPPED_DATA) status = STATUS_SUCCESS;
600         else SetLastError( RtlNtStatusToDosError(status) );
601     }
602     return !status;
603 }
604
605
606 /***********************************************************************
607  *             GetWriteWatch   (KERNEL32.@)
608  */
609 UINT WINAPI GetWriteWatch( DWORD flags, LPVOID base, SIZE_T size, LPVOID *addresses,
610                            ULONG_PTR *count, ULONG *granularity )
611 {
612     NTSTATUS status;
613
614     status = NtGetWriteWatch( GetCurrentProcess(), flags, base, size, addresses, count, granularity );
615     if (status) SetLastError( RtlNtStatusToDosError(status) );
616     return status ? ~0u : 0;
617 }
618
619
620 /***********************************************************************
621  *             ResetWriteWatch   (KERNEL32.@)
622  */
623 UINT WINAPI ResetWriteWatch( LPVOID base, SIZE_T size )
624 {
625     NTSTATUS status;
626
627     status = NtResetWriteWatch( GetCurrentProcess(), base, size );
628     if (status) SetLastError( RtlNtStatusToDosError(status) );
629     return status ? ~0u : 0;
630 }
631
632
633 /***********************************************************************
634  *             IsBadReadPtr   (KERNEL32.@)
635  *
636  * Check for read access on a memory block.
637  *
638  * ptr  [I] Address of memory block.
639  * size [I] Size of block.
640  *
641  * RETURNS
642  *  Success: TRUE.
643  *      Failure: FALSE. Process has read access to entire block.
644  */
645 BOOL WINAPI IsBadReadPtr( LPCVOID ptr, UINT size )
646 {
647     if (!size) return FALSE;  /* handle 0 size case w/o reference */
648     if (!ptr) return TRUE;
649     __TRY
650     {
651         volatile const char *p = ptr;
652         char dummy __attribute__((unused));
653         UINT count = size;
654
655         while (count > system_info.PageSize)
656         {
657             dummy = *p;
658             p += system_info.PageSize;
659             count -= system_info.PageSize;
660         }
661         dummy = p[0];
662         dummy = p[count - 1];
663     }
664     __EXCEPT_PAGE_FAULT
665     {
666         TRACE_(seh)("%p caused page fault during read\n", ptr);
667         return TRUE;
668     }
669     __ENDTRY
670     return FALSE;
671 }
672
673
674 /***********************************************************************
675  *             IsBadWritePtr   (KERNEL32.@)
676  *
677  * Check for write access on a memory block.
678  *
679  * PARAMS
680  *  ptr  [I] Address of memory block.
681  *  size [I] Size of block in bytes.
682  *
683  * RETURNS
684  *  Success: TRUE.
685  *      Failure: FALSE. Process has write access to entire block.
686  */
687 BOOL WINAPI IsBadWritePtr( LPVOID ptr, UINT size )
688 {
689     if (!size) return FALSE;  /* handle 0 size case w/o reference */
690     if (!ptr) return TRUE;
691     __TRY
692     {
693         volatile char *p = ptr;
694         UINT count = size;
695
696         while (count > system_info.PageSize)
697         {
698             *p |= 0;
699             p += system_info.PageSize;
700             count -= system_info.PageSize;
701         }
702         p[0] |= 0;
703         p[count - 1] |= 0;
704     }
705     __EXCEPT_PAGE_FAULT
706     {
707         TRACE_(seh)("%p caused page fault during write\n", ptr);
708         return TRUE;
709     }
710     __ENDTRY
711     return FALSE;
712 }
713
714
715 /***********************************************************************
716  *             IsBadHugeReadPtr   (KERNEL32.@)
717  *
718  * Check for read access on a memory block.
719  *
720  * PARAMS
721  *  ptr  [I] Address of memory block.
722  *  size [I] Size of block.
723  *
724  * RETURNS
725  *  Success: TRUE.
726  *      Failure: FALSE. Process has read access to entire block.
727  */
728 BOOL WINAPI IsBadHugeReadPtr( LPCVOID ptr, UINT size )
729 {
730     return IsBadReadPtr( ptr, size );
731 }
732
733
734 /***********************************************************************
735  *             IsBadHugeWritePtr   (KERNEL32.@)
736  *
737  * Check for write access on a memory block.
738  *
739  * PARAMS
740  *  ptr  [I] Address of memory block.
741  *  size [I] Size of block.
742  *
743  * RETURNS
744  *  Success: TRUE.
745  *      Failure: FALSE. Process has write access to entire block.
746  */
747 BOOL WINAPI IsBadHugeWritePtr( LPVOID ptr, UINT size )
748 {
749     return IsBadWritePtr( ptr, size );
750 }
751
752
753 /***********************************************************************
754  *             IsBadCodePtr   (KERNEL32.@)
755  *
756  * Check for read access on a memory address.
757  *
758  * PARAMS
759  *  ptr [I] Address of function.
760  *
761  * RETURNS
762  *      Success: TRUE.
763  *      Failure: FALSE. Process has read access to specified memory.
764  */
765 BOOL WINAPI IsBadCodePtr( FARPROC ptr )
766 {
767     return IsBadReadPtr( ptr, 1 );
768 }
769
770
771 /***********************************************************************
772  *             IsBadStringPtrA   (KERNEL32.@)
773  *
774  * Check for read access on a range of memory pointed to by a string pointer.
775  *
776  * PARAMS
777  *  str [I] Address of string.
778  *  max [I] Maximum size of string.
779  *
780  * RETURNS
781  *      Success: TRUE.
782  *      Failure: FALSE. Read access to all bytes in string.
783  */
784 BOOL WINAPI IsBadStringPtrA( LPCSTR str, UINT max )
785 {
786     if (!str) return TRUE;
787     
788     __TRY
789     {
790         volatile const char *p = str;
791         while (p != str + max) if (!*p++) break;
792     }
793     __EXCEPT_PAGE_FAULT
794     {
795         TRACE_(seh)("%p caused page fault during read\n", str);
796         return TRUE;
797     }
798     __ENDTRY
799     return FALSE;
800 }
801
802
803 /***********************************************************************
804  *             IsBadStringPtrW   (KERNEL32.@)
805  *
806  * See IsBadStringPtrA.
807  */
808 BOOL WINAPI IsBadStringPtrW( LPCWSTR str, UINT max )
809 {
810     if (!str) return TRUE;
811     
812     __TRY
813     {
814         volatile const WCHAR *p = str;
815         while (p != str + max) if (!*p++) break;
816     }
817     __EXCEPT_PAGE_FAULT
818     {
819         TRACE_(seh)("%p caused page fault during read\n", str);
820         return TRUE;
821     }
822     __ENDTRY
823     return FALSE;
824 }
825
826 /***********************************************************************
827  *           K32GetMappedFileNameA (KERNEL32.@)
828  */
829 DWORD WINAPI K32GetMappedFileNameA(HANDLE process, LPVOID lpv, LPSTR file_name, DWORD size)
830 {
831     FIXME_(file)("(%p, %p, %p, %d): stub\n", process, lpv, file_name, size);
832
833     if (file_name && size)
834         file_name[0] = '\0';
835
836     return 0;
837 }
838
839 /***********************************************************************
840  *           K32GetMappedFileNameW (KERNEL32.@)
841  */
842 DWORD WINAPI K32GetMappedFileNameW(HANDLE process, LPVOID lpv, LPWSTR file_name, DWORD size)
843 {
844     FIXME_(file)("(%p, %p, %p, %d): stub\n", process, lpv, file_name, size);
845
846     if (file_name && size)
847         file_name[0] = '\0';
848
849     return 0;
850 }
851
852 /***********************************************************************
853  *           K32EnumPageFilesA (KERNEL32.@)
854  */
855 BOOL WINAPI K32EnumPageFilesA( PENUM_PAGE_FILE_CALLBACKA callback, LPVOID context )
856 {
857     FIXME_(file)("(%p, %p) stub\n", callback, context );
858     return FALSE;
859 }
860
861 /***********************************************************************
862  *           K32EnumPageFilesW (KERNEL32.@)
863  */
864 BOOL WINAPI K32EnumPageFilesW( PENUM_PAGE_FILE_CALLBACKW callback, LPVOID context )
865 {
866     FIXME_(file)("(%p, %p) stub\n", callback, context );
867     return FALSE;
868 }
869
870 /***********************************************************************
871  *           K32GetWsChanges (KERNEL32.@)
872  */
873 BOOL WINAPI K32GetWsChanges(HANDLE process, PPSAPI_WS_WATCH_INFORMATION watchinfo, DWORD size)
874 {
875     NTSTATUS status;
876
877     TRACE_(seh)("(%p, %p, %d)\n", process, watchinfo, size);
878
879     status = NtQueryInformationProcess( process, ProcessWorkingSetWatch, watchinfo, size, NULL );
880
881     if (status)
882     {
883         SetLastError( RtlNtStatusToDosError( status ) );
884         return FALSE;
885     }
886     return TRUE;
887 }
888
889 /***********************************************************************
890  *           K32InitializeProcessForWsWatch (KERNEL32.@)
891  */
892 BOOL WINAPI K32InitializeProcessForWsWatch(HANDLE process)
893 {
894     FIXME_(seh)("(process=%p): stub\n", process);
895
896     return TRUE;
897 }