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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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);
43 /***********************************************************************
44 * Helper for k32 family functions
46 static void *user32_proc_address(const char *proc_name
)
48 static HMODULE hUser32
;
50 if(!hUser32
) hUser32
= LoadLibraryA("user32.dll");
51 return GetProcAddress(hUser32
, proc_name
);
55 /***********************************************************************
56 * k32CharToOemBuffA (KERNEL32.11)
58 BOOL WINAPI
k32CharToOemBuffA(LPCSTR s
, LPSTR d
, DWORD len
)
62 if ((bufW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
64 MultiByteToWideChar( CP_ACP
, 0, s
, len
, bufW
, len
);
65 WideCharToMultiByte( CP_OEMCP
, 0, bufW
, len
, d
, len
, NULL
, NULL
);
66 HeapFree( GetProcessHeap(), 0, bufW
);
72 /***********************************************************************
73 * k32CharToOemA (KERNEL32.10)
75 BOOL WINAPI
k32CharToOemA(LPCSTR s
, LPSTR d
)
77 if (!s
|| !d
) return TRUE
;
78 return k32CharToOemBuffA( s
, d
, strlen(s
) + 1 );
82 /***********************************************************************
83 * k32OemToCharBuffA (KERNEL32.13)
85 BOOL WINAPI
k32OemToCharBuffA(LPCSTR s
, LPSTR d
, DWORD len
)
89 if ((bufW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
91 MultiByteToWideChar( CP_OEMCP
, 0, s
, len
, bufW
, len
);
92 WideCharToMultiByte( CP_ACP
, 0, bufW
, len
, d
, len
, NULL
, NULL
);
93 HeapFree( GetProcessHeap(), 0, bufW
);
99 /***********************************************************************
100 * k32OemToCharA (KERNEL32.12)
102 BOOL WINAPI
k32OemToCharA(LPCSTR s
, LPSTR d
)
104 return k32OemToCharBuffA( s
, d
, strlen(s
) + 1 );
108 /**********************************************************************
109 * k32LoadStringA (KERNEL32.14)
111 INT WINAPI
k32LoadStringA(HINSTANCE instance
, UINT resource_id
,
112 LPSTR buffer
, INT buflen
)
114 if(!pLoadStringA
) pLoadStringA
= user32_proc_address("LoadStringA");
115 return pLoadStringA(instance
, resource_id
, buffer
, buflen
);
119 /***********************************************************************
120 * k32wvsprintfA (KERNEL32.16)
122 INT WINAPI
k32wvsprintfA(LPSTR buffer
, LPCSTR spec
, va_list args
)
124 if(!pwvsprintfA
) pwvsprintfA
= user32_proc_address("wvsprintfA");
125 return (*pwvsprintfA
)(buffer
, spec
, args
);
129 /***********************************************************************
130 * k32wsprintfA (KERNEL32.15)
132 INT WINAPIV
k32wsprintfA(LPSTR buffer
, LPCSTR spec
, ...)
137 va_start(args
, spec
);
138 res
= k32wvsprintfA(buffer
, spec
, args
);
144 /***********************************************************************
145 * hmemcpy (KERNEL.348)
147 void WINAPI
hmemcpy16( LPVOID dst
, LPCVOID src
, LONG count
)
149 memcpy( dst
, src
, count
);
153 /***********************************************************************
154 * lstrcat (KERNEL.89)
156 SEGPTR WINAPI
lstrcat16( SEGPTR dst
, LPCSTR src
)
158 /* Windows does not check for NULL pointers here, so we don't either */
159 strcat( MapSL(dst
), src
);
164 /***********************************************************************
165 * lstrcatA (KERNEL32.@)
166 * lstrcat (KERNEL32.@)
168 LPSTR WINAPI
lstrcatA( LPSTR dst
, LPCSTR src
)
176 SetLastError( ERROR_INVALID_PARAMETER
);
184 /***********************************************************************
185 * lstrcatW (KERNEL32.@)
187 LPWSTR WINAPI
lstrcatW( LPWSTR dst
, LPCWSTR src
)
195 SetLastError( ERROR_INVALID_PARAMETER
);
203 /***********************************************************************
204 * lstrcatn (KERNEL.352)
206 SEGPTR WINAPI
lstrcatn16( SEGPTR dst
, LPCSTR src
, INT16 n
)
208 LPSTR p
= MapSL(dst
);
212 if ((n
-= (p
- start
)) <= 0) return dst
;
213 lstrcpynA( p
, src
, n
);
218 /***********************************************************************
219 * lstrcpy (KERNEL.88)
221 SEGPTR WINAPI
lstrcpy16( SEGPTR dst
, LPCSTR src
)
223 if (!lstrcpyA( MapSL(dst
), src
)) dst
= 0;
228 /***********************************************************************
229 * lstrcpyA (KERNEL32.@)
230 * lstrcpy (KERNEL32.@)
232 LPSTR WINAPI
lstrcpyA( LPSTR dst
, LPCSTR src
)
236 /* this is how Windows does it */
237 memmove( dst
, src
, strlen(src
)+1 );
241 SetLastError( ERROR_INVALID_PARAMETER
);
249 /***********************************************************************
250 * lstrcpyW (KERNEL32.@)
252 LPWSTR WINAPI
lstrcpyW( LPWSTR dst
, LPCWSTR src
)
260 SetLastError( ERROR_INVALID_PARAMETER
);
268 /***********************************************************************
269 * lstrcpyn (KERNEL.353)
271 SEGPTR WINAPI
lstrcpyn16( SEGPTR dst
, LPCSTR src
, INT16 n
)
273 lstrcpynA( MapSL(dst
), src
, n
);
278 /***********************************************************************
279 * lstrcpynA (KERNEL32.@)
280 * lstrcpyn (KERNEL32.@)
282 * Note: this function differs from the UNIX strncpy, it _always_ writes
285 * Note: n is an INT but Windows treats it as unsigned, and will happily
286 * copy a gazillion chars if n is negative.
288 LPSTR WINAPI
lstrcpynA( LPSTR dst
, LPCSTR src
, INT n
)
296 while ((count
> 1) && *s
)
305 SetLastError( ERROR_INVALID_PARAMETER
);
313 /***********************************************************************
314 * lstrcpynW (KERNEL32.@)
316 * Note: this function differs from the UNIX strncpy, it _always_ writes
319 * Note: n is an INT but Windows treats it as unsigned, and will happily
320 * copy a gazillion chars if n is negative.
322 LPWSTR WINAPI
lstrcpynW( LPWSTR dst
, LPCWSTR src
, INT n
)
330 while ((count
> 1) && *s
)
339 SetLastError( ERROR_INVALID_PARAMETER
);
347 /***********************************************************************
348 * lstrlen (KERNEL.90)
350 INT16 WINAPI
lstrlen16( LPCSTR str
)
352 return (INT16
)lstrlenA( str
);
356 /***********************************************************************
357 * lstrlenA (KERNEL32.@)
358 * lstrlen (KERNEL32.@)
360 INT WINAPI
lstrlenA( LPCSTR str
)
369 SetLastError( ERROR_INVALID_PARAMETER
);
377 /***********************************************************************
378 * lstrlenW (KERNEL32.@)
380 INT WINAPI
lstrlenW( LPCWSTR str
)
389 SetLastError( ERROR_INVALID_PARAMETER
);
397 /***********************************************************************
398 * UnicodeToAnsi (KERNEL.434)
400 INT16 WINAPI
UnicodeToAnsi16( LPCWSTR src
, LPSTR dst
, INT16 codepage
)
402 if ( codepage
== -1 ) codepage
= CP_ACP
;
403 return WideCharToMultiByte( codepage
, 0, src
, -1, dst
, 0x7fffffff, NULL
, NULL
);
407 /***************************************************************************
409 * Win 2.x string functions now moved to USER
411 * We rather want to implement them here instead of doing Callouts
414 /***********************************************************************
415 * Reserved1 (KERNEL.77)
417 SEGPTR WINAPI
KERNEL_AnsiNext16(SEGPTR current
)
419 return (*(char *)MapSL(current
)) ? current
+ 1 : current
;
422 /***********************************************************************
423 * Reserved2(KERNEL.78)
425 SEGPTR WINAPI
KERNEL_AnsiPrev16( SEGPTR start
, SEGPTR current
)
427 return (current
==start
)?start
:current
-1;
430 /***********************************************************************
431 * Reserved3 (KERNEL.79)
433 SEGPTR WINAPI
KERNEL_AnsiUpper16( SEGPTR strOrChar
)
435 /* uppercase only one char if strOrChar < 0x10000 */
436 if (HIWORD(strOrChar
))
438 char *s
= MapSL(strOrChar
);
446 else return toupper((char)strOrChar
);
449 /***********************************************************************
450 * Reserved4 (KERNEL.80)
452 SEGPTR WINAPI
KERNEL_AnsiLower16( SEGPTR strOrChar
)
454 /* lowercase only one char if strOrChar < 0x10000 */
455 if (HIWORD(strOrChar
))
457 char *s
= MapSL(strOrChar
);
465 else return tolower((char)strOrChar
);
469 /***********************************************************************
470 * Reserved5 (KERNEL.87)
472 INT16 WINAPI
KERNEL_lstrcmp16( LPCSTR str1
, LPCSTR str2
)
474 return (INT16
)strcmp( str1
, str2
);