blob: 3decc8208377db6ae86911b5c48a1757d27edb6d [file] [log] [blame]
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001/*
2 * Win32 kernel functions
3 *
4 * Copyright 1995 Martin von Loewis and Cameron Heide
5 */
6
Alexandre Julliard84c70f51997-05-09 08:40:27 +00007#include <stdlib.h>
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00008#include "winerror.h"
Alexandre Julliard59730ae1996-03-24 16:20:51 +00009#include "winnls.h"
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000010#include "heap.h"
Alexandre Julliard15657091999-05-23 10:25:25 +000011#include "debugtools.h"
Alexandre Julliardade697e1995-11-26 13:59:11 +000012
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000013DEFAULT_DEBUG_CHANNEL(win32)
14
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000015
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000016/******************************************************************************
17 * GetACP [KERNEL32.276] Gets current ANSI code-page identifier.
18 *
19 * RETURNS
20 * Current ANSI code-page identifier, default if no current defined
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000021 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000022UINT WINAPI GetACP(void)
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000023{
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000024 /* This introduces too many messages */
25/* FIXME(win32, "(void): stub\n"); */
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000026 return 1252; /* Windows 3.1 ISO Latin */
27}
28
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000029
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000030/***********************************************************************
31 * GetCPInfo (KERNEL32.154)
32 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000033BOOL WINAPI GetCPInfo( UINT codepage, LPCPINFO cpinfo )
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000034{
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000035 cpinfo->DefaultChar[0] = '?';
Alexandre Julliard9ea19e51997-01-01 17:29:55 +000036 switch (codepage)
37 {
38 case 932 : /* Shift JIS (japan) */
39 cpinfo->MaxCharSize = 2;
40 cpinfo->LeadByte[0]= 0x81; cpinfo->LeadByte[1] = 0x9F;
41 cpinfo->LeadByte[2]= 0xE0; cpinfo->LeadByte[3] = 0xFC;
42 cpinfo->LeadByte[4]= 0x00; cpinfo->LeadByte[5] = 0x00;
43 break;
44 case 936 : /* GB2312 (Chinese) */
45 case 949 : /* KSC5601-1987 (Korean) */
46 case 950 : /* BIG5 (Chinese) */
47 cpinfo->MaxCharSize = 2;
48 cpinfo->LeadByte[0]= 0x81; cpinfo->LeadByte[1] = 0xFE;
49 cpinfo->LeadByte[2]= 0x00; cpinfo->LeadByte[3] = 0x00;
50 break;
51 case 1361 : /* Johab (Korean) */
52 cpinfo->MaxCharSize = 2;
53 cpinfo->LeadByte[0]= 0x84; cpinfo->LeadByte[1] = 0xD3;
54 cpinfo->LeadByte[2]= 0xD8; cpinfo->LeadByte[3] = 0xDE;
55 cpinfo->LeadByte[4]= 0xE0; cpinfo->LeadByte[5] = 0xF9;
56 cpinfo->LeadByte[6]= 0x00; cpinfo->LeadByte[7] = 0x00;
57 break;
58 default :
59 cpinfo->MaxCharSize = 1;
60 cpinfo->LeadByte[0]= 0x00; cpinfo->LeadByte[1] = 0x00;
61 break;
62 }
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000063 return 1;
64}
65
66/***********************************************************************
67 * GetOEMCP (KERNEL32.248)
68 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000069UINT WINAPI GetOEMCP(void)
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000070{
71 return 437; /* MS-DOS United States */
72}
73
Alexandre Julliardade697e1995-11-26 13:59:11 +000074/***********************************************************************
Alexandre Julliarddf2673b1997-03-29 17:20:20 +000075 * IsValidCodePage (KERNEL32.360)
76 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000077BOOL WINAPI IsValidCodePage(UINT CodePage)
Alexandre Julliarddf2673b1997-03-29 17:20:20 +000078{
79 switch ( CodePage )
80 {
81 case 1252 :
82 case 437 :
83 return TRUE;
84 default :
85 return FALSE;
86 }
87}
88
89
90/***********************************************************************
Alexandre Julliard46ea8b31998-05-03 19:01:20 +000091 * MultiByteToWideChar (KERNEL32.534)
92 *
93 * PARAMS
94 * page [in] Codepage character set to convert from
95 * flags [in] Character mapping flags
96 * src [in] Source string buffer
97 * srclen [in] Length of source string buffer
98 * dst [in] Destination buffer
99 * dstlen [in] Length of destination buffer
100 *
101 * NOTES
102 * The returned length includes the null terminator character.
103 *
104 * RETURNS
105 * Success: If dstlen > 0, number of characters written to destination
106 * buffer. If dstlen == 0, number of characters needed to do
107 * conversion.
108 * Failure: 0. Occurs if not enough space is available.
109 *
110 * ERRORS
111 * ERROR_INSUFFICIENT_BUFFER
112 * ERROR_INVALID_FLAGS (not yet implemented)
113 * ERROR_INVALID_PARAMETER (not yet implemented)
114 *
115 * BUGS
116 * Does not properly handle codepage conversions.
117 * Does not properly handle flags.
118 *
Alexandre Julliardade697e1995-11-26 13:59:11 +0000119 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000120INT WINAPI MultiByteToWideChar(UINT page, DWORD flags,
121 LPCSTR src, INT srclen,
122 LPWSTR dst, INT dstlen)
Alexandre Julliardade697e1995-11-26 13:59:11 +0000123{
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000124 int ret;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000125
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000126 if (srclen == -1)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000127 srclen = lstrlenA(src)+1;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000128 if (!dstlen || !dst)
129 return srclen;
130
131 ret = srclen;
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000132 while (srclen && dstlen) {
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000133 *dst = (WCHAR)(unsigned char)*src;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000134 dst++; src++;
135 dstlen--; srclen--;
136 }
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000137 if (!dstlen && srclen) {
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000138 SetLastError(ERROR_INSUFFICIENT_BUFFER);
139 return 0;
140 }
141 return ret;
Alexandre Julliardade697e1995-11-26 13:59:11 +0000142}
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000143
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000144/***********************************************************************
145 * WideCharToMultiByte (KERNEL32.727)
146 *
147 * PARAMS
148 * page [in] Codepage character set to convert to
149 * flags [in] Character mapping flags
150 * src [in] Source string buffer
151 * srclen [in] Length of source string buffer
152 * dst [in] Destination buffer
153 * dstlen [in] Length of destination buffer
154 * defchar [in] Default character to use for conversion if no exact
155 * conversion can be made
156 * used [out] Set if default character was used in the conversion
157 *
158 * NOTES
159 * The returned length includes the null terminator character.
160 *
161 * RETURNS
162 * Success: If dstlen > 0, number of characters written to destination
163 * buffer. If dstlen == 0, number of characters needed to do
164 * conversion.
165 * Failure: 0. Occurs if not enough space is available.
166 *
167 * ERRORS
168 * ERROR_INSUFFICIENT_BUFFER
169 * ERROR_INVALID_FLAGS (not yet implemented)
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000170 *
171 * BUGS
172 * Does not properly handle codepage conversions.
173 * Does not properly handle flags.
174 *
175 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000176INT WINAPI WideCharToMultiByte(UINT page, DWORD flags, LPCWSTR src,
177 INT srclen,LPSTR dst, INT dstlen,
178 LPCSTR defchar, BOOL *used)
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000179{
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000180 int count = 0;
181 int eos = 0;
Uwe Bonnescd11f291998-11-06 10:58:33 +0000182 int care_for_eos=0;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000183 int dont_copy= (dstlen==0);
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000184
Juergen Schmied96ed8281999-05-01 10:21:06 +0000185 if ((!src) || ((!dst) && (!dont_copy)) )
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000186 { SetLastError(ERROR_INVALID_PARAMETER);
187 return 0;
188 }
189
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000190 if (page!=GetACP() && page!=CP_OEMCP && page!=CP_ACP)
Alexandre Julliard15657091999-05-23 10:25:25 +0000191 FIXME("Conversion in CP %d not supported\n",page);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000192#if 0
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000193 if (flags)
Alexandre Julliard15657091999-05-23 10:25:25 +0000194 FIXME("flags %lx not supported\n",flags);
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000195#endif
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000196 if(used)
197 *used=0;
198 if (srclen == -1)
Uwe Bonnescd11f291998-11-06 10:58:33 +0000199 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000200 srclen = lstrlenW(src)+1;
Uwe Bonnescd11f291998-11-06 10:58:33 +0000201 care_for_eos=1;
202 }
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000203 while(srclen && (dont_copy || dstlen))
204 {
205 if(!dont_copy){
206 if(*src<256)
207 *dst = *src;
208 else
209 {
210 /* ??? The WC_DEFAULTCHAR flag only gets used in
211 * combination with the WC_COMPOSITECHECK flag or at
212 * least this is what it seems from using the function
213 * on NT4.0 in combination with reading the documentation.
214 */
215 *dst = defchar ? *defchar : '?';
216 if(used)*used=1;
217 }
218 dstlen--;
219 dst++;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000220 }
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000221 count++;
222 srclen--;
Uwe Bonnescd11f291998-11-06 10:58:33 +0000223 if((!*src) && care_for_eos) {
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000224 eos = 1;
225 break;
226 }
227 src++;
228 }
229 if (dont_copy)
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000230 return count;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000231
232 if (!eos && srclen > 0) {
233 SetLastError(ERROR_INSUFFICIENT_BUFFER);
234 return 0;
235 }
236 return count;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000237}
238
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000239
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000240/***********************************************************************
241 * IsDBCSLeadByteEx (KERNEL32.359)
242 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000243BOOL WINAPI IsDBCSLeadByteEx( UINT codepage, BYTE testchar )
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000244{
245 CPINFO cpinfo;
246 int i;
247
248 GetCPInfo(codepage, &cpinfo);
249 for (i = 0 ; i < sizeof(cpinfo.LeadByte)/sizeof(cpinfo.LeadByte[0]); i+=2)
250 {
251 if (cpinfo.LeadByte[i] == 0)
252 return FALSE;
253 if (cpinfo.LeadByte[i] <= testchar && testchar <= cpinfo.LeadByte[i+1])
254 return TRUE;
255 }
256 return FALSE;
257}
258
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000259
260/***********************************************************************
261 * IsDBCSLeadByte16 (KERNEL.207)
262 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000263BOOL16 WINAPI IsDBCSLeadByte16( BYTE testchar )
Alexandre Julliardc6c09441997-01-12 18:32:19 +0000264{
265 return IsDBCSLeadByteEx(GetACP(), testchar);
266}
267
268
269/***********************************************************************
270 * IsDBCSLeadByte32 (KERNEL32.358)
271 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000272BOOL WINAPI IsDBCSLeadByte( BYTE testchar )
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000273{
274 return IsDBCSLeadByteEx(GetACP(), testchar);
275}
276
277
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000278/***********************************************************************
279 * EnumSystemCodePages32A (KERNEL32.92)
280 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000281BOOL WINAPI EnumSystemCodePagesA(CODEPAGE_ENUMPROCA lpfnCodePageEnum,DWORD flags)
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000282{
Alexandre Julliard15657091999-05-23 10:25:25 +0000283 TRACE("(%p,%08lx)\n",lpfnCodePageEnum,flags);
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000284 lpfnCodePageEnum("437");
285 return TRUE;
286}
287
288/***********************************************************************
289 * EnumSystemCodePages32W (KERNEL32.93)
290 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000291BOOL WINAPI EnumSystemCodePagesW( CODEPAGE_ENUMPROCW lpfnCodePageEnum,
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000292 DWORD flags)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000293{
294 WCHAR *cp;
Alexandre Julliard15657091999-05-23 10:25:25 +0000295 TRACE("(%p,%08lx)\n",lpfnCodePageEnum,flags );
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000296
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000297 cp = HEAP_strdupAtoW( GetProcessHeap(), 0, "437" );
298 lpfnCodePageEnum(cp);
299 HeapFree( GetProcessHeap(), 0, cp );
300 return TRUE;
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000301}