2 * Kernel string functions
4 * Copyright 1993 Yngvi Sigurjonsson
5 * Copyright 1996 Alexandre Julliard
6 * Copyright 2001 Dmitry Timoshkov for CodeWeavers
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "wine/port.h"
33 #include "wine/winbase16.h"
34 #include "wine/unicode.h"
35 #include "wine/exception.h"
38 static INT (WINAPI
*pLoadStringA
)(HINSTANCE
, UINT
, LPSTR
, INT
);
39 static INT (WINAPI
*pwvsprintfA
)(LPSTR
, LPCSTR
, va_list);
41 /* filter for page-fault exceptions */
42 static WINE_EXCEPTION_FILTER(page_fault
)
44 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
45 return EXCEPTION_EXECUTE_HANDLER
;
46 return EXCEPTION_CONTINUE_SEARCH
;
50 /***********************************************************************
51 * Helper for k32 family functions
53 static void *user32_proc_address(const char *proc_name
)
55 static HMODULE hUser32
;
57 if(!hUser32
) hUser32
= LoadLibraryA("user32.dll");
58 return GetProcAddress(hUser32
, proc_name
);
62 /***********************************************************************
63 * k32CharToOemBuffA (KERNEL32.11)
65 BOOL WINAPI
k32CharToOemBuffA(LPCSTR s
, LPSTR d
, DWORD len
)
69 if ((bufW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
71 MultiByteToWideChar( CP_ACP
, 0, s
, len
, bufW
, len
);
72 WideCharToMultiByte( CP_OEMCP
, 0, bufW
, len
, d
, len
, NULL
, NULL
);
73 HeapFree( GetProcessHeap(), 0, bufW
);
79 /***********************************************************************
80 * k32CharToOemA (KERNEL32.10)
82 BOOL WINAPI
k32CharToOemA(LPCSTR s
, LPSTR d
)
84 if (!s
|| !d
) return TRUE
;
85 return k32CharToOemBuffA( s
, d
, strlen(s
) + 1 );
89 /***********************************************************************
90 * k32OemToCharBuffA (KERNEL32.13)
92 BOOL WINAPI
k32OemToCharBuffA(LPCSTR s
, LPSTR d
, DWORD len
)
96 if ((bufW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
98 MultiByteToWideChar( CP_OEMCP
, 0, s
, len
, bufW
, len
);
99 WideCharToMultiByte( CP_ACP
, 0, bufW
, len
, d
, len
, NULL
, NULL
);
100 HeapFree( GetProcessHeap(), 0, bufW
);
106 /***********************************************************************
107 * k32OemToCharA (KERNEL32.12)
109 BOOL WINAPI
k32OemToCharA(LPCSTR s
, LPSTR d
)
111 return k32OemToCharBuffA( s
, d
, strlen(s
) + 1 );
115 /**********************************************************************
116 * k32LoadStringA (KERNEL32.14)
118 INT WINAPI
k32LoadStringA(HINSTANCE instance
, UINT resource_id
,
119 LPSTR buffer
, INT buflen
)
121 if(!pLoadStringA
) pLoadStringA
= user32_proc_address("LoadStringA");
122 return pLoadStringA(instance
, resource_id
, buffer
, buflen
);
126 /***********************************************************************
127 * k32wvsprintfA (KERNEL32.16)
129 INT WINAPI
k32wvsprintfA(LPSTR buffer
, LPCSTR spec
, va_list args
)
131 if(!pwvsprintfA
) pwvsprintfA
= user32_proc_address("wvsprintfA");
132 return (*pwvsprintfA
)(buffer
, spec
, args
);
136 /***********************************************************************
137 * k32wsprintfA (KERNEL32.15)
139 INT WINAPIV
k32wsprintfA(LPSTR buffer
, LPCSTR spec
, ...)
144 va_start(args
, spec
);
145 res
= k32wvsprintfA(buffer
, spec
, args
);
151 /***********************************************************************
152 * hmemcpy (KERNEL.348)
154 void WINAPI
hmemcpy16( LPVOID dst
, LPCVOID src
, LONG count
)
156 memcpy( dst
, src
, count
);
160 /***********************************************************************
161 * lstrcat (KERNEL.89)
163 SEGPTR WINAPI
lstrcat16( SEGPTR dst
, LPCSTR src
)
165 /* Windows does not check for NULL pointers here, so we don't either */
166 strcat( MapSL(dst
), src
);
171 /***********************************************************************
172 * lstrcat (KERNEL32.@)
173 * lstrcatA (KERNEL32.@)
175 LPSTR WINAPI
lstrcatA( LPSTR dst
, LPCSTR src
)
183 SetLastError( ERROR_INVALID_PARAMETER
);
191 /***********************************************************************
192 * lstrcatW (KERNEL32.@)
194 LPWSTR WINAPI
lstrcatW( LPWSTR dst
, LPCWSTR src
)
202 SetLastError( ERROR_INVALID_PARAMETER
);
210 /***********************************************************************
211 * lstrcatn (KERNEL.352)
213 SEGPTR WINAPI
lstrcatn16( SEGPTR dst
, LPCSTR src
, INT16 n
)
215 LPSTR p
= MapSL(dst
);
219 if ((n
-= (p
- start
)) <= 0) return dst
;
220 lstrcpynA( p
, src
, n
);
225 /***********************************************************************
226 * lstrcpy (KERNEL.88)
228 SEGPTR WINAPI
lstrcpy16( SEGPTR dst
, LPCSTR src
)
230 if (!lstrcpyA( MapSL(dst
), src
)) dst
= 0;
235 /***********************************************************************
236 * lstrcpy (KERNEL32.@)
237 * lstrcpyA (KERNEL32.@)
239 LPSTR WINAPI
lstrcpyA( LPSTR dst
, LPCSTR src
)
243 /* this is how Windows does it */
244 memmove( dst
, src
, strlen(src
)+1 );
248 SetLastError( ERROR_INVALID_PARAMETER
);
256 /***********************************************************************
257 * lstrcpyW (KERNEL32.@)
259 LPWSTR WINAPI
lstrcpyW( LPWSTR dst
, LPCWSTR src
)
267 SetLastError( ERROR_INVALID_PARAMETER
);
275 /***********************************************************************
276 * lstrcpyn (KERNEL.353)
278 SEGPTR WINAPI
lstrcpyn16( SEGPTR dst
, LPCSTR src
, INT16 n
)
280 lstrcpynA( MapSL(dst
), src
, n
);
285 /***********************************************************************
286 * lstrcpyn (KERNEL32.@)
287 * lstrcpynA (KERNEL32.@)
289 * Note: this function differs from the UNIX strncpy, it _always_ writes
292 * Note: n is an INT but Windows treats it as unsigned, and will happily
293 * copy a gazillion chars if n is negative.
295 LPSTR WINAPI
lstrcpynA( LPSTR dst
, LPCSTR src
, INT n
)
303 while ((count
> 1) && *s
)
312 SetLastError( ERROR_INVALID_PARAMETER
);
320 /***********************************************************************
321 * lstrcpynW (KERNEL32.@)
323 * Note: this function differs from the UNIX strncpy, it _always_ writes
326 * Note: n is an INT but Windows treats it as unsigned, and will happily
327 * copy a gazillion chars if n is negative.
329 LPWSTR WINAPI
lstrcpynW( LPWSTR dst
, LPCWSTR src
, INT n
)
337 while ((count
> 1) && *s
)
346 SetLastError( ERROR_INVALID_PARAMETER
);
354 /***********************************************************************
355 * lstrlen (KERNEL.90)
357 INT16 WINAPI
lstrlen16( LPCSTR str
)
359 return (INT16
)lstrlenA( str
);
363 /***********************************************************************
364 * lstrlen (KERNEL32.@)
365 * lstrlenA (KERNEL32.@)
367 INT WINAPI
lstrlenA( LPCSTR str
)
376 SetLastError( ERROR_INVALID_PARAMETER
);
384 /***********************************************************************
385 * lstrlenW (KERNEL32.@)
387 INT WINAPI
lstrlenW( LPCWSTR str
)
396 SetLastError( ERROR_INVALID_PARAMETER
);
404 /***********************************************************************
405 * UnicodeToAnsi (KERNEL.434)
407 INT16 WINAPI
UnicodeToAnsi16( LPCWSTR src
, LPSTR dst
, INT16 codepage
)
409 if ( codepage
== -1 ) codepage
= CP_ACP
;
410 return WideCharToMultiByte( codepage
, 0, src
, -1, dst
, 0x7fffffff, NULL
, NULL
);
414 /***************************************************************************
416 * Win 2.x string functions now moved to USER
418 * We rather want to implement them here instead of doing Callouts
421 /***********************************************************************
422 * Reserved1 (KERNEL.77)
424 SEGPTR WINAPI
KERNEL_AnsiNext16(SEGPTR current
)
426 return (*(char *)MapSL(current
)) ? current
+ 1 : current
;
429 /***********************************************************************
430 * Reserved2(KERNEL.78)
432 SEGPTR WINAPI
KERNEL_AnsiPrev16( SEGPTR start
, SEGPTR current
)
434 return (current
==start
)?start
:current
-1;
437 /***********************************************************************
438 * Reserved3 (KERNEL.79)
440 SEGPTR WINAPI
KERNEL_AnsiUpper16( SEGPTR strOrChar
)
442 /* uppercase only one char if strOrChar < 0x10000 */
443 if (HIWORD(strOrChar
))
445 char *s
= MapSL(strOrChar
);
453 else return toupper((char)strOrChar
);
456 /***********************************************************************
457 * Reserved4 (KERNEL.80)
459 SEGPTR WINAPI
KERNEL_AnsiLower16( SEGPTR strOrChar
)
461 /* lowercase only one char if strOrChar < 0x10000 */
462 if (HIWORD(strOrChar
))
464 char *s
= MapSL(strOrChar
);
472 else return tolower((char)strOrChar
);
476 /***********************************************************************
477 * Reserved5 (KERNEL.87)
479 INT16 WINAPI
KERNEL_lstrcmp16( LPCSTR str1
, LPCSTR str2
)
481 return (INT16
)strcmp( str1
, str2
);