Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Win32 kernel functions |
| 3 | * |
| 4 | * Copyright 1995 Martin von Loewis and Cameron Heide |
| 5 | */ |
| 6 | |
Alexandre Julliard | 84c70f5 | 1997-05-09 08:40:27 +0000 | [diff] [blame] | 7 | #include <stdlib.h> |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 8 | #include "winerror.h" |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 9 | #include "winnls.h" |
Alexandre Julliard | 7ebe1a4 | 1996-12-22 18:27:48 +0000 | [diff] [blame] | 10 | #include "heap.h" |
Alexandre Julliard | 1565709 | 1999-05-23 10:25:25 +0000 | [diff] [blame] | 11 | #include "debugtools.h" |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 12 | |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 13 | DEFAULT_DEBUG_CHANNEL(win32) |
| 14 | |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 15 | |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 16 | /****************************************************************************** |
| 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 Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 21 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 22 | UINT WINAPI GetACP(void) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 23 | { |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 24 | /* This introduces too many messages */ |
| 25 | /* FIXME(win32, "(void): stub\n"); */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 26 | return 1252; /* Windows 3.1 ISO Latin */ |
| 27 | } |
| 28 | |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 29 | |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 30 | /*********************************************************************** |
| 31 | * GetCPInfo (KERNEL32.154) |
| 32 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 33 | BOOL WINAPI GetCPInfo( UINT codepage, LPCPINFO cpinfo ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 34 | { |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 35 | cpinfo->DefaultChar[0] = '?'; |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 36 | 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 Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 63 | return 1; |
| 64 | } |
| 65 | |
| 66 | /*********************************************************************** |
| 67 | * GetOEMCP (KERNEL32.248) |
| 68 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 69 | UINT WINAPI GetOEMCP(void) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 70 | { |
| 71 | return 437; /* MS-DOS United States */ |
| 72 | } |
| 73 | |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 74 | /*********************************************************************** |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 75 | * IsValidCodePage (KERNEL32.360) |
| 76 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 77 | BOOL WINAPI IsValidCodePage(UINT CodePage) |
Alexandre Julliard | df2673b | 1997-03-29 17:20:20 +0000 | [diff] [blame] | 78 | { |
| 79 | switch ( CodePage ) |
| 80 | { |
| 81 | case 1252 : |
| 82 | case 437 : |
| 83 | return TRUE; |
| 84 | default : |
| 85 | return FALSE; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | |
| 90 | /*********************************************************************** |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 91 | * 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 Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 119 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 120 | INT WINAPI MultiByteToWideChar(UINT page, DWORD flags, |
| 121 | LPCSTR src, INT srclen, |
| 122 | LPWSTR dst, INT dstlen) |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 123 | { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 124 | int ret; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 125 | |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 126 | if (srclen == -1) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 127 | srclen = lstrlenA(src)+1; |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 128 | if (!dstlen || !dst) |
| 129 | return srclen; |
| 130 | |
| 131 | ret = srclen; |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 132 | while (srclen && dstlen) { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 133 | *dst = (WCHAR)(unsigned char)*src; |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 134 | dst++; src++; |
| 135 | dstlen--; srclen--; |
| 136 | } |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 137 | if (!dstlen && srclen) { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 138 | SetLastError(ERROR_INSUFFICIENT_BUFFER); |
| 139 | return 0; |
| 140 | } |
| 141 | return ret; |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 142 | } |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 143 | |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 144 | /*********************************************************************** |
| 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 Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 170 | * |
| 171 | * BUGS |
| 172 | * Does not properly handle codepage conversions. |
| 173 | * Does not properly handle flags. |
| 174 | * |
| 175 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 176 | INT WINAPI WideCharToMultiByte(UINT page, DWORD flags, LPCWSTR src, |
| 177 | INT srclen,LPSTR dst, INT dstlen, |
| 178 | LPCSTR defchar, BOOL *used) |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 179 | { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 180 | int count = 0; |
| 181 | int eos = 0; |
Uwe Bonnes | cd11f29 | 1998-11-06 10:58:33 +0000 | [diff] [blame] | 182 | int care_for_eos=0; |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 183 | int dont_copy= (dstlen==0); |
Alexandre Julliard | a0d7731 | 1998-09-13 16:32:00 +0000 | [diff] [blame] | 184 | |
Juergen Schmied | 96ed828 | 1999-05-01 10:21:06 +0000 | [diff] [blame] | 185 | if ((!src) || ((!dst) && (!dont_copy)) ) |
Alexandre Julliard | a0d7731 | 1998-09-13 16:32:00 +0000 | [diff] [blame] | 186 | { SetLastError(ERROR_INVALID_PARAMETER); |
| 187 | return 0; |
| 188 | } |
| 189 | |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 190 | if (page!=GetACP() && page!=CP_OEMCP && page!=CP_ACP) |
Alexandre Julliard | 1565709 | 1999-05-23 10:25:25 +0000 | [diff] [blame] | 191 | FIXME("Conversion in CP %d not supported\n",page); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 192 | #if 0 |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 193 | if (flags) |
Alexandre Julliard | 1565709 | 1999-05-23 10:25:25 +0000 | [diff] [blame] | 194 | FIXME("flags %lx not supported\n",flags); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 195 | #endif |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 196 | if(used) |
| 197 | *used=0; |
| 198 | if (srclen == -1) |
Uwe Bonnes | cd11f29 | 1998-11-06 10:58:33 +0000 | [diff] [blame] | 199 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 200 | srclen = lstrlenW(src)+1; |
Uwe Bonnes | cd11f29 | 1998-11-06 10:58:33 +0000 | [diff] [blame] | 201 | care_for_eos=1; |
| 202 | } |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 203 | 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 Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 220 | } |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 221 | count++; |
| 222 | srclen--; |
Uwe Bonnes | cd11f29 | 1998-11-06 10:58:33 +0000 | [diff] [blame] | 223 | if((!*src) && care_for_eos) { |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 224 | eos = 1; |
| 225 | break; |
| 226 | } |
| 227 | src++; |
| 228 | } |
| 229 | if (dont_copy) |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 230 | return count; |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 231 | |
| 232 | if (!eos && srclen > 0) { |
| 233 | SetLastError(ERROR_INSUFFICIENT_BUFFER); |
| 234 | return 0; |
| 235 | } |
| 236 | return count; |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 237 | } |
| 238 | |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 239 | |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 240 | /*********************************************************************** |
| 241 | * IsDBCSLeadByteEx (KERNEL32.359) |
| 242 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 243 | BOOL WINAPI IsDBCSLeadByteEx( UINT codepage, BYTE testchar ) |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 244 | { |
| 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 Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 259 | |
| 260 | /*********************************************************************** |
| 261 | * IsDBCSLeadByte16 (KERNEL.207) |
| 262 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 263 | BOOL16 WINAPI IsDBCSLeadByte16( BYTE testchar ) |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 264 | { |
| 265 | return IsDBCSLeadByteEx(GetACP(), testchar); |
| 266 | } |
| 267 | |
| 268 | |
| 269 | /*********************************************************************** |
| 270 | * IsDBCSLeadByte32 (KERNEL32.358) |
| 271 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 272 | BOOL WINAPI IsDBCSLeadByte( BYTE testchar ) |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 273 | { |
| 274 | return IsDBCSLeadByteEx(GetACP(), testchar); |
| 275 | } |
| 276 | |
| 277 | |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 278 | /*********************************************************************** |
| 279 | * EnumSystemCodePages32A (KERNEL32.92) |
| 280 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 281 | BOOL WINAPI EnumSystemCodePagesA(CODEPAGE_ENUMPROCA lpfnCodePageEnum,DWORD flags) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 282 | { |
Alexandre Julliard | 1565709 | 1999-05-23 10:25:25 +0000 | [diff] [blame] | 283 | TRACE("(%p,%08lx)\n",lpfnCodePageEnum,flags); |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 284 | lpfnCodePageEnum("437"); |
| 285 | return TRUE; |
| 286 | } |
| 287 | |
| 288 | /*********************************************************************** |
| 289 | * EnumSystemCodePages32W (KERNEL32.93) |
| 290 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 291 | BOOL WINAPI EnumSystemCodePagesW( CODEPAGE_ENUMPROCW lpfnCodePageEnum, |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 292 | DWORD flags) |
Alexandre Julliard | 7ebe1a4 | 1996-12-22 18:27:48 +0000 | [diff] [blame] | 293 | { |
| 294 | WCHAR *cp; |
Alexandre Julliard | 1565709 | 1999-05-23 10:25:25 +0000 | [diff] [blame] | 295 | TRACE("(%p,%08lx)\n",lpfnCodePageEnum,flags ); |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 296 | |
Alexandre Julliard | 7ebe1a4 | 1996-12-22 18:27:48 +0000 | [diff] [blame] | 297 | cp = HEAP_strdupAtoW( GetProcessHeap(), 0, "437" ); |
| 298 | lpfnCodePageEnum(cp); |
| 299 | HeapFree( GetProcessHeap(), 0, cp ); |
| 300 | return TRUE; |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 301 | } |