dbghelp: Remove DMT_ entries for .DBG and .PDB files.
[wine.git] / dlls / kernel32 / virtual.c
blob0314b362e86cfdd1242478abdfe01c964510ebcb
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 #include "windef.h"
31 #include "winbase.h"
32 #include "winnls.h"
33 #include "winternl.h"
34 #include "winerror.h"
35 #include "psapi.h"
36 #include "wine/exception.h"
37 #include "wine/debug.h"
39 #include "kernel_private.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(seh);
44 static LONG WINAPI badptr_handler( EXCEPTION_POINTERS *eptr )
46 EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
48 if (rec->ExceptionCode == STATUS_ACCESS_VIOLATION) return EXCEPTION_EXECUTE_HANDLER;
49 if (rec->ExceptionCode == STATUS_STACK_OVERFLOW)
51 /* restore stack guard page */
52 void *addr = (char *)NtCurrentTeb()->DeallocationStack + system_info.PageSize;
53 SIZE_T size = (char *)rec - (char *)addr;
54 ULONG old_prot;
55 NtProtectVirtualMemory( GetCurrentProcess(), &addr, &size, PAGE_GUARD|PAGE_READWRITE, &old_prot );
56 return EXCEPTION_EXECUTE_HANDLER;
58 return EXCEPTION_CONTINUE_SEARCH;
61 /***********************************************************************
62 * IsBadReadPtr (KERNEL32.@)
64 * Check for read access on a memory block.
66 * ptr [I] Address of memory block.
67 * size [I] Size of block.
69 * RETURNS
70 * Success: TRUE.
71 * Failure: FALSE. Process has read access to entire block.
73 BOOL WINAPI IsBadReadPtr( LPCVOID ptr, UINT_PTR size )
75 if (!size) return FALSE; /* handle 0 size case w/o reference */
76 if (!ptr) return TRUE;
77 __TRY
79 volatile const char *p = ptr;
80 char dummy __attribute__((unused));
81 UINT_PTR count = size;
83 while (count > system_info.PageSize)
85 dummy = *p;
86 p += system_info.PageSize;
87 count -= system_info.PageSize;
89 dummy = p[0];
90 dummy = p[count - 1];
92 __EXCEPT( badptr_handler )
94 TRACE("%p caused page fault during read\n", ptr);
95 return TRUE;
97 __ENDTRY
98 return FALSE;
102 /***********************************************************************
103 * IsBadWritePtr (KERNEL32.@)
105 * Check for write access on a memory block.
107 * PARAMS
108 * ptr [I] Address of memory block.
109 * size [I] Size of block in bytes.
111 * RETURNS
112 * Success: TRUE.
113 * Failure: FALSE. Process has write access to entire block.
115 BOOL WINAPI IsBadWritePtr( LPVOID ptr, UINT_PTR size )
117 if (!size) return FALSE; /* handle 0 size case w/o reference */
118 if (!ptr) return TRUE;
119 __TRY
121 volatile char *p = ptr;
122 UINT_PTR count = size;
124 while (count > system_info.PageSize)
126 *p |= 0;
127 p += system_info.PageSize;
128 count -= system_info.PageSize;
130 p[0] |= 0;
131 p[count - 1] |= 0;
133 __EXCEPT( badptr_handler )
135 TRACE("%p caused page fault during write\n", ptr);
136 return TRUE;
138 __ENDTRY
139 return FALSE;
143 /***********************************************************************
144 * IsBadHugeReadPtr (KERNEL32.@)
146 * Check for read access on a memory block.
148 * PARAMS
149 * ptr [I] Address of memory block.
150 * size [I] Size of block.
152 * RETURNS
153 * Success: TRUE.
154 * Failure: FALSE. Process has read access to entire block.
156 BOOL WINAPI IsBadHugeReadPtr( LPCVOID ptr, UINT_PTR size )
158 return IsBadReadPtr( ptr, size );
162 /***********************************************************************
163 * IsBadHugeWritePtr (KERNEL32.@)
165 * Check for write access on a memory block.
167 * PARAMS
168 * ptr [I] Address of memory block.
169 * size [I] Size of block.
171 * RETURNS
172 * Success: TRUE.
173 * Failure: FALSE. Process has write access to entire block.
175 BOOL WINAPI IsBadHugeWritePtr( LPVOID ptr, UINT_PTR size )
177 return IsBadWritePtr( ptr, size );
181 /***********************************************************************
182 * IsBadCodePtr (KERNEL32.@)
184 * Check for read access on a memory address.
186 * PARAMS
187 * ptr [I] Address of function.
189 * RETURNS
190 * Success: TRUE.
191 * Failure: FALSE. Process has read access to specified memory.
193 BOOL WINAPI IsBadCodePtr( FARPROC ptr )
195 return IsBadReadPtr( ptr, 1 );
199 /***********************************************************************
200 * IsBadStringPtrA (KERNEL32.@)
202 * Check for read access on a range of memory pointed to by a string pointer.
204 * PARAMS
205 * str [I] Address of string.
206 * max [I] Maximum size of string.
208 * RETURNS
209 * Success: TRUE.
210 * Failure: FALSE. Read access to all bytes in string.
212 BOOL WINAPI IsBadStringPtrA( LPCSTR str, UINT_PTR max )
214 if (!str) return TRUE;
216 __TRY
218 volatile const char *p = str;
219 while (p != str + max) if (!*p++) break;
221 __EXCEPT( badptr_handler )
223 TRACE("%p caused page fault during read\n", str);
224 return TRUE;
226 __ENDTRY
227 return FALSE;
231 /***********************************************************************
232 * IsBadStringPtrW (KERNEL32.@)
234 * See IsBadStringPtrA.
236 BOOL WINAPI IsBadStringPtrW( LPCWSTR str, UINT_PTR max )
238 if (!str) return TRUE;
240 __TRY
242 volatile const WCHAR *p = str;
243 while (p != str + max) if (!*p++) break;
245 __EXCEPT( badptr_handler )
247 TRACE("%p caused page fault during read\n", str);
248 return TRUE;
250 __ENDTRY
251 return FALSE;
253 /***********************************************************************
254 * lstrcatA (KERNEL32.@)
255 * lstrcat (KERNEL32.@)
257 LPSTR WINAPI lstrcatA( LPSTR dst, LPCSTR src )
259 __TRY
261 strcat( dst, src );
263 __EXCEPT( badptr_handler )
265 SetLastError( ERROR_INVALID_PARAMETER );
266 return NULL;
268 __ENDTRY
269 return dst;
273 /***********************************************************************
274 * lstrcatW (KERNEL32.@)
276 LPWSTR WINAPI lstrcatW( LPWSTR dst, LPCWSTR src )
278 __TRY
280 wcscat( dst, src );
282 __EXCEPT( badptr_handler )
284 SetLastError( ERROR_INVALID_PARAMETER );
285 return NULL;
287 __ENDTRY
288 return dst;
292 /***********************************************************************
293 * lstrcpyA (KERNEL32.@)
294 * lstrcpy (KERNEL32.@)
296 LPSTR WINAPI lstrcpyA( LPSTR dst, LPCSTR src )
298 __TRY
300 /* this is how Windows does it */
301 memmove( dst, src, strlen(src)+1 );
303 __EXCEPT( badptr_handler )
305 SetLastError( ERROR_INVALID_PARAMETER );
306 return NULL;
308 __ENDTRY
309 return dst;
313 /***********************************************************************
314 * lstrcpyW (KERNEL32.@)
316 LPWSTR WINAPI lstrcpyW( LPWSTR dst, LPCWSTR src )
318 __TRY
320 wcscpy( dst, src );
322 __EXCEPT( badptr_handler )
324 SetLastError( ERROR_INVALID_PARAMETER );
325 return NULL;
327 __ENDTRY
328 return dst;