widl: Generate helper macros for WinRT implementation.
[wine/zf.git] / dlls / kernel32 / virtual.c
blobf5693de4e28a596b47758091ea64b64f47f200ae
1 /*
2 * Win32 virtual memory functions
4 * Copyright 1997 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <fcntl.h>
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
27 #define WINE_NO_INLINE_STRING
28 #include "ntstatus.h"
29 #define WIN32_NO_STATUS
30 #define NONAMELESSUNION
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winnls.h"
34 #include "winternl.h"
35 #include "winerror.h"
36 #include "psapi.h"
37 #include "wine/exception.h"
38 #include "wine/debug.h"
40 #include "kernel_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(seh);
45 static LONG WINAPI badptr_handler( EXCEPTION_POINTERS *eptr )
47 EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
49 if (rec->ExceptionCode == STATUS_ACCESS_VIOLATION) return EXCEPTION_EXECUTE_HANDLER;
50 if (rec->ExceptionCode == STATUS_STACK_OVERFLOW)
52 /* restore stack guard page */
53 void *addr = (char *)NtCurrentTeb()->DeallocationStack + system_info.PageSize;
54 SIZE_T size = (char *)rec - (char *)addr;
55 ULONG old_prot;
56 NtProtectVirtualMemory( GetCurrentProcess(), &addr, &size, PAGE_GUARD|PAGE_READWRITE, &old_prot );
57 return EXCEPTION_EXECUTE_HANDLER;
59 return EXCEPTION_CONTINUE_SEARCH;
62 /***********************************************************************
63 * IsBadReadPtr (KERNEL32.@)
65 * Check for read access on a memory block.
67 * ptr [I] Address of memory block.
68 * size [I] Size of block.
70 * RETURNS
71 * Success: TRUE.
72 * Failure: FALSE. Process has read access to entire block.
74 BOOL WINAPI IsBadReadPtr( LPCVOID ptr, UINT_PTR size )
76 if (!size) return FALSE; /* handle 0 size case w/o reference */
77 if (!ptr) return TRUE;
78 __TRY
80 volatile const char *p = ptr;
81 char dummy __attribute__((unused));
82 UINT_PTR count = size;
84 while (count > system_info.PageSize)
86 dummy = *p;
87 p += system_info.PageSize;
88 count -= system_info.PageSize;
90 dummy = p[0];
91 dummy = p[count - 1];
93 __EXCEPT( badptr_handler )
95 TRACE("%p caused page fault during read\n", ptr);
96 return TRUE;
98 __ENDTRY
99 return FALSE;
103 /***********************************************************************
104 * IsBadWritePtr (KERNEL32.@)
106 * Check for write access on a memory block.
108 * PARAMS
109 * ptr [I] Address of memory block.
110 * size [I] Size of block in bytes.
112 * RETURNS
113 * Success: TRUE.
114 * Failure: FALSE. Process has write access to entire block.
116 BOOL WINAPI IsBadWritePtr( LPVOID ptr, UINT_PTR size )
118 if (!size) return FALSE; /* handle 0 size case w/o reference */
119 if (!ptr) return TRUE;
120 __TRY
122 volatile char *p = ptr;
123 UINT_PTR count = size;
125 while (count > system_info.PageSize)
127 *p |= 0;
128 p += system_info.PageSize;
129 count -= system_info.PageSize;
131 p[0] |= 0;
132 p[count - 1] |= 0;
134 __EXCEPT( badptr_handler )
136 TRACE("%p caused page fault during write\n", ptr);
137 return TRUE;
139 __ENDTRY
140 return FALSE;
144 /***********************************************************************
145 * IsBadHugeReadPtr (KERNEL32.@)
147 * Check for read access on a memory block.
149 * PARAMS
150 * ptr [I] Address of memory block.
151 * size [I] Size of block.
153 * RETURNS
154 * Success: TRUE.
155 * Failure: FALSE. Process has read access to entire block.
157 BOOL WINAPI IsBadHugeReadPtr( LPCVOID ptr, UINT_PTR size )
159 return IsBadReadPtr( ptr, size );
163 /***********************************************************************
164 * IsBadHugeWritePtr (KERNEL32.@)
166 * Check for write access on a memory block.
168 * PARAMS
169 * ptr [I] Address of memory block.
170 * size [I] Size of block.
172 * RETURNS
173 * Success: TRUE.
174 * Failure: FALSE. Process has write access to entire block.
176 BOOL WINAPI IsBadHugeWritePtr( LPVOID ptr, UINT_PTR size )
178 return IsBadWritePtr( ptr, size );
182 /***********************************************************************
183 * IsBadCodePtr (KERNEL32.@)
185 * Check for read access on a memory address.
187 * PARAMS
188 * ptr [I] Address of function.
190 * RETURNS
191 * Success: TRUE.
192 * Failure: FALSE. Process has read access to specified memory.
194 BOOL WINAPI IsBadCodePtr( FARPROC ptr )
196 return IsBadReadPtr( ptr, 1 );
200 /***********************************************************************
201 * IsBadStringPtrA (KERNEL32.@)
203 * Check for read access on a range of memory pointed to by a string pointer.
205 * PARAMS
206 * str [I] Address of string.
207 * max [I] Maximum size of string.
209 * RETURNS
210 * Success: TRUE.
211 * Failure: FALSE. Read access to all bytes in string.
213 BOOL WINAPI IsBadStringPtrA( LPCSTR str, UINT_PTR max )
215 if (!str) return TRUE;
217 __TRY
219 volatile const char *p = str;
220 while (p != str + max) if (!*p++) break;
222 __EXCEPT( badptr_handler )
224 TRACE("%p caused page fault during read\n", str);
225 return TRUE;
227 __ENDTRY
228 return FALSE;
232 /***********************************************************************
233 * IsBadStringPtrW (KERNEL32.@)
235 * See IsBadStringPtrA.
237 BOOL WINAPI IsBadStringPtrW( LPCWSTR str, UINT_PTR max )
239 if (!str) return TRUE;
241 __TRY
243 volatile const WCHAR *p = str;
244 while (p != str + max) if (!*p++) break;
246 __EXCEPT( badptr_handler )
248 TRACE("%p caused page fault during read\n", str);
249 return TRUE;
251 __ENDTRY
252 return FALSE;
254 /***********************************************************************
255 * lstrcatA (KERNEL32.@)
256 * lstrcat (KERNEL32.@)
258 LPSTR WINAPI lstrcatA( LPSTR dst, LPCSTR src )
260 __TRY
262 strcat( dst, src );
264 __EXCEPT( badptr_handler )
266 SetLastError( ERROR_INVALID_PARAMETER );
267 return NULL;
269 __ENDTRY
270 return dst;
274 /***********************************************************************
275 * lstrcatW (KERNEL32.@)
277 LPWSTR WINAPI lstrcatW( LPWSTR dst, LPCWSTR src )
279 __TRY
281 wcscat( dst, src );
283 __EXCEPT( badptr_handler )
285 SetLastError( ERROR_INVALID_PARAMETER );
286 return NULL;
288 __ENDTRY
289 return dst;
293 /***********************************************************************
294 * lstrcpyA (KERNEL32.@)
295 * lstrcpy (KERNEL32.@)
297 LPSTR WINAPI lstrcpyA( LPSTR dst, LPCSTR src )
299 __TRY
301 /* this is how Windows does it */
302 memmove( dst, src, strlen(src)+1 );
304 __EXCEPT( badptr_handler )
306 SetLastError( ERROR_INVALID_PARAMETER );
307 return NULL;
309 __ENDTRY
310 return dst;
314 /***********************************************************************
315 * lstrcpyW (KERNEL32.@)
317 LPWSTR WINAPI lstrcpyW( LPWSTR dst, LPCWSTR src )
319 __TRY
321 wcscpy( dst, src );
323 __EXCEPT( badptr_handler )
325 SetLastError( ERROR_INVALID_PARAMETER );
326 return NULL;
328 __ENDTRY
329 return dst;