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
22 #include "wine/port.h"
28 #include <sys/types.h>
33 #define WINE_NO_INLINE_STRING
35 #define WIN32_NO_STATUS
36 #define NONAMELESSUNION
43 #include "wine/exception.h"
44 #include "wine/unicode.h"
45 #include "wine/debug.h"
47 #include "kernel_private.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(seh
);
52 static LONG WINAPI
badptr_handler( EXCEPTION_POINTERS
*eptr
)
54 EXCEPTION_RECORD
*rec
= eptr
->ExceptionRecord
;
56 if (rec
->ExceptionCode
== STATUS_ACCESS_VIOLATION
) return EXCEPTION_EXECUTE_HANDLER
;
57 if (rec
->ExceptionCode
== STATUS_STACK_OVERFLOW
)
59 /* restore stack guard page */
60 void *addr
= (char *)NtCurrentTeb()->DeallocationStack
+ system_info
.PageSize
;
61 SIZE_T size
= (char *)rec
- (char *)addr
;
63 NtProtectVirtualMemory( GetCurrentProcess(), &addr
, &size
, PAGE_GUARD
|PAGE_READWRITE
, &old_prot
);
64 return EXCEPTION_EXECUTE_HANDLER
;
66 return EXCEPTION_CONTINUE_SEARCH
;
69 /***********************************************************************
70 * IsBadReadPtr (KERNEL32.@)
72 * Check for read access on a memory block.
74 * ptr [I] Address of memory block.
75 * size [I] Size of block.
79 * Failure: FALSE. Process has read access to entire block.
81 BOOL WINAPI
IsBadReadPtr( LPCVOID ptr
, UINT_PTR size
)
83 if (!size
) return FALSE
; /* handle 0 size case w/o reference */
84 if (!ptr
) return TRUE
;
87 volatile const char *p
= ptr
;
88 char dummy
__attribute__((unused
));
89 UINT_PTR count
= size
;
91 while (count
> system_info
.PageSize
)
94 p
+= system_info
.PageSize
;
95 count
-= system_info
.PageSize
;
100 __EXCEPT( badptr_handler
)
102 TRACE("%p caused page fault during read\n", ptr
);
110 /***********************************************************************
111 * IsBadWritePtr (KERNEL32.@)
113 * Check for write access on a memory block.
116 * ptr [I] Address of memory block.
117 * size [I] Size of block in bytes.
121 * Failure: FALSE. Process has write access to entire block.
123 BOOL WINAPI
IsBadWritePtr( LPVOID ptr
, UINT_PTR size
)
125 if (!size
) return FALSE
; /* handle 0 size case w/o reference */
126 if (!ptr
) return TRUE
;
129 volatile char *p
= ptr
;
130 UINT_PTR count
= size
;
132 while (count
> system_info
.PageSize
)
135 p
+= system_info
.PageSize
;
136 count
-= system_info
.PageSize
;
141 __EXCEPT( badptr_handler
)
143 TRACE("%p caused page fault during write\n", ptr
);
151 /***********************************************************************
152 * IsBadHugeReadPtr (KERNEL32.@)
154 * Check for read access on a memory block.
157 * ptr [I] Address of memory block.
158 * size [I] Size of block.
162 * Failure: FALSE. Process has read access to entire block.
164 BOOL WINAPI
IsBadHugeReadPtr( LPCVOID ptr
, UINT_PTR size
)
166 return IsBadReadPtr( ptr
, size
);
170 /***********************************************************************
171 * IsBadHugeWritePtr (KERNEL32.@)
173 * Check for write access on a memory block.
176 * ptr [I] Address of memory block.
177 * size [I] Size of block.
181 * Failure: FALSE. Process has write access to entire block.
183 BOOL WINAPI
IsBadHugeWritePtr( LPVOID ptr
, UINT_PTR size
)
185 return IsBadWritePtr( ptr
, size
);
189 /***********************************************************************
190 * IsBadCodePtr (KERNEL32.@)
192 * Check for read access on a memory address.
195 * ptr [I] Address of function.
199 * Failure: FALSE. Process has read access to specified memory.
201 BOOL WINAPI
IsBadCodePtr( FARPROC ptr
)
203 return IsBadReadPtr( ptr
, 1 );
207 /***********************************************************************
208 * IsBadStringPtrA (KERNEL32.@)
210 * Check for read access on a range of memory pointed to by a string pointer.
213 * str [I] Address of string.
214 * max [I] Maximum size of string.
218 * Failure: FALSE. Read access to all bytes in string.
220 BOOL WINAPI
IsBadStringPtrA( LPCSTR str
, UINT_PTR max
)
222 if (!str
) return TRUE
;
226 volatile const char *p
= str
;
227 while (p
!= str
+ max
) if (!*p
++) break;
229 __EXCEPT( badptr_handler
)
231 TRACE("%p caused page fault during read\n", str
);
239 /***********************************************************************
240 * IsBadStringPtrW (KERNEL32.@)
242 * See IsBadStringPtrA.
244 BOOL WINAPI
IsBadStringPtrW( LPCWSTR str
, UINT_PTR max
)
246 if (!str
) return TRUE
;
250 volatile const WCHAR
*p
= str
;
251 while (p
!= str
+ max
) if (!*p
++) break;
253 __EXCEPT( badptr_handler
)
255 TRACE("%p caused page fault during read\n", str
);
261 /***********************************************************************
262 * lstrcatA (KERNEL32.@)
263 * lstrcat (KERNEL32.@)
265 LPSTR WINAPI
lstrcatA( LPSTR dst
, LPCSTR src
)
271 __EXCEPT( badptr_handler
)
273 SetLastError( ERROR_INVALID_PARAMETER
);
281 /***********************************************************************
282 * lstrcatW (KERNEL32.@)
284 LPWSTR WINAPI
lstrcatW( LPWSTR dst
, LPCWSTR src
)
290 __EXCEPT( badptr_handler
)
292 SetLastError( ERROR_INVALID_PARAMETER
);
300 /***********************************************************************
301 * lstrcpyA (KERNEL32.@)
302 * lstrcpy (KERNEL32.@)
304 LPSTR WINAPI
lstrcpyA( LPSTR dst
, LPCSTR src
)
308 /* this is how Windows does it */
309 memmove( dst
, src
, strlen(src
)+1 );
311 __EXCEPT( badptr_handler
)
313 SetLastError( ERROR_INVALID_PARAMETER
);
321 /***********************************************************************
322 * lstrcpyW (KERNEL32.@)
324 LPWSTR WINAPI
lstrcpyW( LPWSTR dst
, LPCWSTR src
)
330 __EXCEPT( badptr_handler
)
332 SetLastError( ERROR_INVALID_PARAMETER
);