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
30 #define NONAMELESSUNION
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
;
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.
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
;
80 volatile const char *p
= ptr
;
81 char dummy
__attribute__((unused
));
82 UINT_PTR count
= size
;
84 while (count
> system_info
.PageSize
)
87 p
+= system_info
.PageSize
;
88 count
-= system_info
.PageSize
;
93 __EXCEPT( badptr_handler
)
95 TRACE("%p caused page fault during read\n", ptr
);
103 /***********************************************************************
104 * IsBadWritePtr (KERNEL32.@)
106 * Check for write access on a memory block.
109 * ptr [I] Address of memory block.
110 * size [I] Size of block in bytes.
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
;
122 volatile char *p
= ptr
;
123 UINT_PTR count
= size
;
125 while (count
> system_info
.PageSize
)
128 p
+= system_info
.PageSize
;
129 count
-= system_info
.PageSize
;
134 __EXCEPT( badptr_handler
)
136 TRACE("%p caused page fault during write\n", ptr
);
144 /***********************************************************************
145 * IsBadHugeReadPtr (KERNEL32.@)
147 * Check for read access on a memory block.
150 * ptr [I] Address of memory block.
151 * size [I] Size of block.
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.
169 * ptr [I] Address of memory block.
170 * size [I] Size of block.
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.
188 * ptr [I] Address of function.
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.
206 * str [I] Address of string.
207 * max [I] Maximum size of string.
211 * Failure: FALSE. Read access to all bytes in string.
213 BOOL WINAPI
IsBadStringPtrA( LPCSTR str
, UINT_PTR max
)
215 if (!str
) return TRUE
;
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
);
232 /***********************************************************************
233 * IsBadStringPtrW (KERNEL32.@)
235 * See IsBadStringPtrA.
237 BOOL WINAPI
IsBadStringPtrW( LPCWSTR str
, UINT_PTR max
)
239 if (!str
) return TRUE
;
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
);
254 /***********************************************************************
255 * lstrcatA (KERNEL32.@)
256 * lstrcat (KERNEL32.@)
258 LPSTR WINAPI
lstrcatA( LPSTR dst
, LPCSTR src
)
264 __EXCEPT( badptr_handler
)
266 SetLastError( ERROR_INVALID_PARAMETER
);
274 /***********************************************************************
275 * lstrcatW (KERNEL32.@)
277 LPWSTR WINAPI
lstrcatW( LPWSTR dst
, LPCWSTR src
)
283 __EXCEPT( badptr_handler
)
285 SetLastError( ERROR_INVALID_PARAMETER
);
293 /***********************************************************************
294 * lstrcpyA (KERNEL32.@)
295 * lstrcpy (KERNEL32.@)
297 LPSTR WINAPI
lstrcpyA( LPSTR dst
, LPCSTR src
)
301 /* this is how Windows does it */
302 memmove( dst
, src
, strlen(src
)+1 );
304 __EXCEPT( badptr_handler
)
306 SetLastError( ERROR_INVALID_PARAMETER
);
314 /***********************************************************************
315 * lstrcpyW (KERNEL32.@)
317 LPWSTR WINAPI
lstrcpyW( LPWSTR dst
, LPCWSTR src
)
323 __EXCEPT( badptr_handler
)
325 SetLastError( ERROR_INVALID_PARAMETER
);