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
30 #include "wine/winbase16.h"
31 #include "wine/unicode.h"
32 #include "wine/exception.h"
35 static INT (WINAPI
*pLoadStringA
)(HINSTANCE
, UINT
, LPSTR
, INT
);
36 static INT (WINAPI
*pwvsprintfA
)(LPSTR
, LPCSTR
, va_list);
38 /* filter for page-fault exceptions */
39 static WINE_EXCEPTION_FILTER(page_fault
)
41 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
42 return EXCEPTION_EXECUTE_HANDLER
;
43 return EXCEPTION_CONTINUE_SEARCH
;
47 /***********************************************************************
48 * Helper for k32 family functions
50 static void *user32_proc_address(const char *proc_name
)
52 static HMODULE hUser32
;
54 if(!hUser32
) hUser32
= LoadLibraryA("user32.dll");
55 return GetProcAddress(hUser32
, proc_name
);
59 /***********************************************************************
60 * k32CharToOemBuffA (KERNEL32.11)
62 BOOL WINAPI
k32CharToOemBuffA(LPCSTR s
, LPSTR d
, DWORD len
)
66 if ((bufW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
68 MultiByteToWideChar( CP_ACP
, 0, s
, len
, bufW
, len
);
69 WideCharToMultiByte( CP_OEMCP
, 0, bufW
, len
, d
, len
, NULL
, NULL
);
70 HeapFree( GetProcessHeap(), 0, bufW
);
76 /***********************************************************************
77 * k32CharToOemA (KERNEL32.10)
79 BOOL WINAPI
k32CharToOemA(LPCSTR s
, LPSTR d
)
81 if (!s
|| !d
) return TRUE
;
82 return k32CharToOemBuffA( s
, d
, strlen(s
) + 1 );
86 /***********************************************************************
87 * k32OemToCharBuffA (KERNEL32.13)
89 BOOL WINAPI
k32OemToCharBuffA(LPCSTR s
, LPSTR d
, DWORD len
)
93 if ((bufW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
95 MultiByteToWideChar( CP_OEMCP
, 0, s
, len
, bufW
, len
);
96 WideCharToMultiByte( CP_ACP
, 0, bufW
, len
, d
, len
, NULL
, NULL
);
97 HeapFree( GetProcessHeap(), 0, bufW
);
103 /***********************************************************************
104 * k32OemToCharA (KERNEL32.12)
106 BOOL WINAPI
k32OemToCharA(LPCSTR s
, LPSTR d
)
108 return k32OemToCharBuffA( s
, d
, strlen(s
) + 1 );
112 /**********************************************************************
113 * k32LoadStringA (KERNEL32.14)
115 INT WINAPI
k32LoadStringA(HINSTANCE instance
, UINT resource_id
,
116 LPSTR buffer
, INT buflen
)
118 if(!pLoadStringA
) pLoadStringA
= user32_proc_address("LoadStringA");
119 return pLoadStringA(instance
, resource_id
, buffer
, buflen
);
123 /***********************************************************************
124 * k32wvsprintfA (KERNEL32.16)
126 INT WINAPI
k32wvsprintfA(LPSTR buffer
, LPCSTR spec
, va_list args
)
128 if(!pwvsprintfA
) pwvsprintfA
= user32_proc_address("wvsprintfA");
129 return (*pwvsprintfA
)(buffer
, spec
, args
);
133 /***********************************************************************
134 * k32wsprintfA (KERNEL32.15)
136 INT WINAPIV
k32wsprintfA(LPSTR buffer
, LPCSTR spec
, ...)
141 va_start(args
, spec
);
142 res
= k32wvsprintfA(buffer
, spec
, args
);
148 /***********************************************************************
149 * hmemcpy (KERNEL.348)
151 void WINAPI
hmemcpy16( LPVOID dst
, LPCVOID src
, LONG count
)
153 memcpy( dst
, src
, count
);
157 /***********************************************************************
158 * lstrcat (KERNEL.89)
160 SEGPTR WINAPI
lstrcat16( SEGPTR dst
, LPCSTR src
)
162 /* Windows does not check for NULL pointers here, so we don't either */
163 strcat( MapSL(dst
), src
);
168 /***********************************************************************
169 * lstrcat (KERNEL32.@)
170 * lstrcatA (KERNEL32.@)
172 LPSTR WINAPI
lstrcatA( LPSTR dst
, LPCSTR src
)
180 SetLastError( ERROR_INVALID_PARAMETER
);
188 /***********************************************************************
189 * lstrcatW (KERNEL32.@)
191 LPWSTR WINAPI
lstrcatW( LPWSTR dst
, LPCWSTR src
)
199 SetLastError( ERROR_INVALID_PARAMETER
);
207 /***********************************************************************
208 * lstrcatn (KERNEL.352)
210 SEGPTR WINAPI
lstrcatn16( SEGPTR dst
, LPCSTR src
, INT16 n
)
212 LPSTR p
= MapSL(dst
);
216 if ((n
-= (p
- start
)) <= 0) return dst
;
217 lstrcpynA( p
, src
, n
);
222 /***********************************************************************
223 * lstrcpy (KERNEL.88)
225 SEGPTR WINAPI
lstrcpy16( SEGPTR dst
, LPCSTR src
)
227 if (!lstrcpyA( MapSL(dst
), src
)) dst
= 0;
232 /***********************************************************************
233 * lstrcpy (KERNEL32.@)
234 * lstrcpyA (KERNEL32.@)
236 LPSTR WINAPI
lstrcpyA( LPSTR dst
, LPCSTR src
)
240 /* this is how Windows does it */
241 memmove( dst
, src
, strlen(src
)+1 );
245 SetLastError( ERROR_INVALID_PARAMETER
);
253 /***********************************************************************
254 * lstrcpyW (KERNEL32.@)
256 LPWSTR WINAPI
lstrcpyW( LPWSTR dst
, LPCWSTR src
)
264 SetLastError( ERROR_INVALID_PARAMETER
);
272 /***********************************************************************
273 * lstrcpyn (KERNEL.353)
275 SEGPTR WINAPI
lstrcpyn16( SEGPTR dst
, LPCSTR src
, INT16 n
)
277 lstrcpynA( MapSL(dst
), src
, n
);
282 /***********************************************************************
283 * lstrlen (KERNEL.90)
285 INT16 WINAPI
lstrlen16( LPCSTR str
)
287 return (INT16
)lstrlenA( str
);
291 /***********************************************************************
292 * lstrlen (KERNEL32.@)
293 * lstrlenA (KERNEL32.@)
295 INT WINAPI
lstrlenA( LPCSTR str
)
304 SetLastError( ERROR_INVALID_PARAMETER
);
312 /***********************************************************************
313 * lstrlenW (KERNEL32.@)
315 INT WINAPI
lstrlenW( LPCWSTR str
)
324 SetLastError( ERROR_INVALID_PARAMETER
);
332 /***********************************************************************
333 * UnicodeToAnsi (KERNEL.434)
335 INT16 WINAPI
UnicodeToAnsi16( LPCWSTR src
, LPSTR dst
, INT16 codepage
)
337 if ( codepage
== -1 ) codepage
= CP_ACP
;
338 return WideCharToMultiByte( codepage
, 0, src
, -1, dst
, 0x7fffffff, NULL
, NULL
);
342 /***************************************************************************
344 * Win 2.x string functions now moved to USER
346 * We rather want to implement them here instead of doing Callouts
349 /***********************************************************************
350 * Reserved1 (KERNEL.77)
352 SEGPTR WINAPI
KERNEL_AnsiNext16(SEGPTR current
)
354 return (*(char *)MapSL(current
)) ? current
+ 1 : current
;
357 /***********************************************************************
358 * Reserved2(KERNEL.78)
360 SEGPTR WINAPI
KERNEL_AnsiPrev16( SEGPTR start
, SEGPTR current
)
362 return (current
==start
)?start
:current
-1;
365 /***********************************************************************
366 * Reserved3 (KERNEL.79)
368 SEGPTR WINAPI
KERNEL_AnsiUpper16( SEGPTR strOrChar
)
370 /* uppercase only one char if strOrChar < 0x10000 */
371 if (HIWORD(strOrChar
))
373 char *s
= MapSL(strOrChar
);
381 else return toupper((char)strOrChar
);
384 /***********************************************************************
385 * Reserved4 (KERNEL.80)
387 SEGPTR WINAPI
KERNEL_AnsiLower16( SEGPTR strOrChar
)
389 /* lowercase only one char if strOrChar < 0x10000 */
390 if (HIWORD(strOrChar
))
392 char *s
= MapSL(strOrChar
);
400 else return tolower((char)strOrChar
);
404 /***********************************************************************
405 * Reserved5 (KERNEL.87)
407 INT16 WINAPI
KERNEL_lstrcmp16( LPCSTR str1
, LPCSTR str2
)
409 return (INT16
)strcmp( str1
, str2
);