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
25 #include <sys/types.h>
27 #define WINE_NO_INLINE_STRING
29 #define WIN32_NO_STATUS
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
;
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.
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
;
79 volatile const char *p
= ptr
;
80 char dummy
__attribute__((unused
));
81 UINT_PTR count
= size
;
83 while (count
> system_info
.PageSize
)
86 p
+= system_info
.PageSize
;
87 count
-= system_info
.PageSize
;
92 __EXCEPT( badptr_handler
)
94 TRACE("%p caused page fault during read\n", ptr
);
102 /***********************************************************************
103 * IsBadWritePtr (KERNEL32.@)
105 * Check for write access on a memory block.
108 * ptr [I] Address of memory block.
109 * size [I] Size of block in bytes.
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
;
121 volatile char *p
= ptr
;
122 UINT_PTR count
= size
;
124 while (count
> system_info
.PageSize
)
127 p
+= system_info
.PageSize
;
128 count
-= system_info
.PageSize
;
133 __EXCEPT( badptr_handler
)
135 TRACE("%p caused page fault during write\n", ptr
);
143 /***********************************************************************
144 * IsBadHugeReadPtr (KERNEL32.@)
146 * Check for read access on a memory block.
149 * ptr [I] Address of memory block.
150 * size [I] Size of block.
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.
168 * ptr [I] Address of memory block.
169 * size [I] Size of block.
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.
187 * ptr [I] Address of function.
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.
205 * str [I] Address of string.
206 * max [I] Maximum size of string.
210 * Failure: FALSE. Read access to all bytes in string.
212 BOOL WINAPI
IsBadStringPtrA( LPCSTR str
, UINT_PTR max
)
214 if (!str
) return TRUE
;
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
);
231 /***********************************************************************
232 * IsBadStringPtrW (KERNEL32.@)
234 * See IsBadStringPtrA.
236 BOOL WINAPI
IsBadStringPtrW( LPCWSTR str
, UINT_PTR max
)
238 if (!str
) return TRUE
;
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
);
253 /***********************************************************************
254 * lstrcatA (KERNEL32.@)
255 * lstrcat (KERNEL32.@)
257 LPSTR WINAPI
lstrcatA( LPSTR dst
, LPCSTR src
)
263 __EXCEPT( badptr_handler
)
265 SetLastError( ERROR_INVALID_PARAMETER
);
273 /***********************************************************************
274 * lstrcatW (KERNEL32.@)
276 LPWSTR WINAPI
lstrcatW( LPWSTR dst
, LPCWSTR src
)
282 __EXCEPT( badptr_handler
)
284 SetLastError( ERROR_INVALID_PARAMETER
);
292 /***********************************************************************
293 * lstrcpyA (KERNEL32.@)
294 * lstrcpy (KERNEL32.@)
296 LPSTR WINAPI
lstrcpyA( LPSTR dst
, LPCSTR src
)
300 /* this is how Windows does it */
301 memmove( dst
, src
, strlen(src
)+1 );
303 __EXCEPT( badptr_handler
)
305 SetLastError( ERROR_INVALID_PARAMETER
);
313 /***********************************************************************
314 * lstrcpyW (KERNEL32.@)
316 LPWSTR WINAPI
lstrcpyW( LPWSTR dst
, LPCWSTR src
)
322 __EXCEPT( badptr_handler
)
324 SetLastError( ERROR_INVALID_PARAMETER
);