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"
30 #define WINE_NO_INLINE_STRING
34 #include "wine/winbase16.h"
35 #include "wine/unicode.h"
36 #include "wine/exception.h"
39 static INT (WINAPI
*pLoadStringA
)(HINSTANCE
, UINT
, LPSTR
, INT
);
40 static INT (WINAPI
*pwvsprintfA
)(LPSTR
, LPCSTR
, va_list);
42 /* filter for page-fault exceptions */
43 static WINE_EXCEPTION_FILTER(page_fault
)
45 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
46 return EXCEPTION_EXECUTE_HANDLER
;
47 return EXCEPTION_CONTINUE_SEARCH
;
51 /***********************************************************************
52 * Helper for k32 family functions
54 static void *user32_proc_address(const char *proc_name
)
56 static HMODULE hUser32
;
58 if(!hUser32
) hUser32
= LoadLibraryA("user32.dll");
59 return GetProcAddress(hUser32
, proc_name
);
63 /***********************************************************************
64 * k32CharToOemBuffA (KERNEL32.11)
66 BOOL WINAPI
k32CharToOemBuffA(LPCSTR s
, LPSTR d
, DWORD len
)
70 if ((bufW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
72 MultiByteToWideChar( CP_ACP
, 0, s
, len
, bufW
, len
);
73 WideCharToMultiByte( CP_OEMCP
, 0, bufW
, len
, d
, len
, NULL
, NULL
);
74 HeapFree( GetProcessHeap(), 0, bufW
);
80 /***********************************************************************
81 * k32CharToOemA (KERNEL32.10)
83 BOOL WINAPI
k32CharToOemA(LPCSTR s
, LPSTR d
)
85 if (!s
|| !d
) return TRUE
;
86 return k32CharToOemBuffA( s
, d
, strlen(s
) + 1 );
90 /***********************************************************************
91 * k32OemToCharBuffA (KERNEL32.13)
93 BOOL WINAPI
k32OemToCharBuffA(LPCSTR s
, LPSTR d
, DWORD len
)
97 if ((bufW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
99 MultiByteToWideChar( CP_OEMCP
, 0, s
, len
, bufW
, len
);
100 WideCharToMultiByte( CP_ACP
, 0, bufW
, len
, d
, len
, NULL
, NULL
);
101 HeapFree( GetProcessHeap(), 0, bufW
);
107 /***********************************************************************
108 * k32OemToCharA (KERNEL32.12)
110 BOOL WINAPI
k32OemToCharA(LPCSTR s
, LPSTR d
)
112 return k32OemToCharBuffA( s
, d
, strlen(s
) + 1 );
116 /**********************************************************************
117 * k32LoadStringA (KERNEL32.14)
119 INT WINAPI
k32LoadStringA(HINSTANCE instance
, UINT resource_id
,
120 LPSTR buffer
, INT buflen
)
122 if(!pLoadStringA
) pLoadStringA
= user32_proc_address("LoadStringA");
123 return pLoadStringA(instance
, resource_id
, buffer
, buflen
);
127 /***********************************************************************
128 * k32wvsprintfA (KERNEL32.16)
130 INT WINAPI
k32wvsprintfA(LPSTR buffer
, LPCSTR spec
, va_list args
)
132 if(!pwvsprintfA
) pwvsprintfA
= user32_proc_address("wvsprintfA");
133 return (*pwvsprintfA
)(buffer
, spec
, args
);
137 /***********************************************************************
138 * k32wsprintfA (KERNEL32.15)
140 INT WINAPIV
k32wsprintfA(LPSTR buffer
, LPCSTR spec
, ...)
145 va_start(args
, spec
);
146 res
= k32wvsprintfA(buffer
, spec
, args
);
152 /***********************************************************************
153 * hmemcpy (KERNEL.348)
155 void WINAPI
hmemcpy16( LPVOID dst
, LPCVOID src
, LONG count
)
157 memcpy( dst
, src
, count
);
161 /***********************************************************************
162 * lstrcat (KERNEL.89)
164 SEGPTR WINAPI
lstrcat16( SEGPTR dst
, LPCSTR src
)
166 /* Windows does not check for NULL pointers here, so we don't either */
167 strcat( MapSL(dst
), src
);
172 /***********************************************************************
173 * lstrcat (KERNEL32.@)
174 * lstrcatA (KERNEL32.@)
176 LPSTR WINAPI
lstrcatA( LPSTR dst
, LPCSTR src
)
184 SetLastError( ERROR_INVALID_PARAMETER
);
192 /***********************************************************************
193 * lstrcatW (KERNEL32.@)
195 LPWSTR WINAPI
lstrcatW( LPWSTR dst
, LPCWSTR src
)
203 SetLastError( ERROR_INVALID_PARAMETER
);
211 /***********************************************************************
212 * lstrcatn (KERNEL.352)
214 SEGPTR WINAPI
lstrcatn16( SEGPTR dst
, LPCSTR src
, INT16 n
)
216 LPSTR p
= MapSL(dst
);
220 if ((n
-= (p
- start
)) <= 0) return dst
;
221 lstrcpynA( p
, src
, n
);
226 /***********************************************************************
227 * lstrcpy (KERNEL.88)
229 SEGPTR WINAPI
lstrcpy16( SEGPTR dst
, LPCSTR src
)
231 if (!lstrcpyA( MapSL(dst
), src
)) dst
= 0;
236 /***********************************************************************
237 * lstrcpy (KERNEL32.@)
238 * lstrcpyA (KERNEL32.@)
240 LPSTR WINAPI
lstrcpyA( LPSTR dst
, LPCSTR src
)
244 /* this is how Windows does it */
245 memmove( dst
, src
, strlen(src
)+1 );
249 SetLastError( ERROR_INVALID_PARAMETER
);
257 /***********************************************************************
258 * lstrcpyW (KERNEL32.@)
260 LPWSTR WINAPI
lstrcpyW( LPWSTR dst
, LPCWSTR src
)
268 SetLastError( ERROR_INVALID_PARAMETER
);
276 /***********************************************************************
277 * lstrcpyn (KERNEL.353)
279 SEGPTR WINAPI
lstrcpyn16( SEGPTR dst
, LPCSTR src
, INT16 n
)
281 lstrcpynA( MapSL(dst
), src
, n
);
286 /***********************************************************************
287 * lstrcpyn (KERNEL32.@)
288 * lstrcpynA (KERNEL32.@)
290 * Note: this function differs from the UNIX strncpy, it _always_ writes
293 * Note: n is an INT but Windows treats it as unsigned, and will happily
294 * copy a gazillion chars if n is negative.
296 LPSTR WINAPI
lstrcpynA( LPSTR dst
, LPCSTR src
, INT n
)
304 while ((count
> 1) && *s
)
313 SetLastError( ERROR_INVALID_PARAMETER
);
321 /***********************************************************************
322 * lstrcpynW (KERNEL32.@)
324 * Note: this function differs from the UNIX strncpy, it _always_ writes
327 * Note: n is an INT but Windows treats it as unsigned, and will happily
328 * copy a gazillion chars if n is negative.
330 LPWSTR WINAPI
lstrcpynW( LPWSTR dst
, LPCWSTR src
, INT n
)
338 while ((count
> 1) && *s
)
347 SetLastError( ERROR_INVALID_PARAMETER
);
355 /***********************************************************************
356 * lstrlen (KERNEL.90)
358 INT16 WINAPI
lstrlen16( LPCSTR str
)
360 return (INT16
)lstrlenA( str
);
364 /***********************************************************************
365 * lstrlen (KERNEL32.@)
366 * lstrlenA (KERNEL32.@)
368 INT WINAPI
lstrlenA( LPCSTR str
)
377 SetLastError( ERROR_INVALID_PARAMETER
);
385 /***********************************************************************
386 * lstrlenW (KERNEL32.@)
388 INT WINAPI
lstrlenW( LPCWSTR str
)
397 SetLastError( ERROR_INVALID_PARAMETER
);
405 /***********************************************************************
406 * UnicodeToAnsi (KERNEL.434)
408 INT16 WINAPI
UnicodeToAnsi16( LPCWSTR src
, LPSTR dst
, INT16 codepage
)
410 if ( codepage
== -1 ) codepage
= CP_ACP
;
411 return WideCharToMultiByte( codepage
, 0, src
, -1, dst
, 0x7fffffff, NULL
, NULL
);
415 /***************************************************************************
417 * Win 2.x string functions now moved to USER
419 * We rather want to implement them here instead of doing Callouts
422 /***********************************************************************
423 * Reserved1 (KERNEL.77)
425 SEGPTR WINAPI
KERNEL_AnsiNext16(SEGPTR current
)
427 return (*(char *)MapSL(current
)) ? current
+ 1 : current
;
430 /***********************************************************************
431 * Reserved2(KERNEL.78)
433 SEGPTR WINAPI
KERNEL_AnsiPrev16( SEGPTR start
, SEGPTR current
)
435 return (current
==start
)?start
:current
-1;
438 /***********************************************************************
439 * Reserved3 (KERNEL.79)
441 SEGPTR WINAPI
KERNEL_AnsiUpper16( SEGPTR strOrChar
)
443 /* uppercase only one char if strOrChar < 0x10000 */
444 if (HIWORD(strOrChar
))
446 char *s
= MapSL(strOrChar
);
454 else return toupper((char)strOrChar
);
457 /***********************************************************************
458 * Reserved4 (KERNEL.80)
460 SEGPTR WINAPI
KERNEL_AnsiLower16( SEGPTR strOrChar
)
462 /* lowercase only one char if strOrChar < 0x10000 */
463 if (HIWORD(strOrChar
))
465 char *s
= MapSL(strOrChar
);
473 else return tolower((char)strOrChar
);
477 /***********************************************************************
478 * Reserved5 (KERNEL.87)
480 INT16 WINAPI
KERNEL_lstrcmp16( LPCSTR str1
, LPCSTR str2
)
482 return (INT16
)strcmp( str1
, str2
);