15331Samw /*
25331Samw * CDDL HEADER START
35331Samw *
45331Samw * The contents of this file are subject to the terms of the
55331Samw * Common Development and Distribution License (the "License").
65331Samw * You may not use this file except in compliance with the License.
75331Samw *
85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw * or http://www.opensolaris.org/os/licensing.
105331Samw * See the License for the specific language governing permissions
115331Samw * and limitations under the License.
125331Samw *
135331Samw * When distributing Covered Code, include this CDDL HEADER in each
145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw * If applicable, add the following below this CDDL HEADER, with the
165331Samw * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw *
195331Samw * CDDL HEADER END
205331Samw */
215331Samw /*
22*10966SJordan.Brown@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
235331Samw * Use is subject to license terms.
245331Samw */
255331Samw
265331Samw /*
275331Samw * Support for oem <-> unicode translations.
285331Samw */
295331Samw
305331Samw #ifndef _KERNEL
315331Samw #include <stdlib.h>
325331Samw #include <thread.h>
335331Samw #include <synch.h>
345331Samw #include <string.h>
35*10966SJordan.Brown@Sun.COM #else
36*10966SJordan.Brown@Sun.COM #include <sys/ksynch.h>
375331Samw #endif /* _KERNEL */
38*10966SJordan.Brown@Sun.COM
39*10966SJordan.Brown@Sun.COM #include <sys/byteorder.h>
405331Samw #include <smbsrv/alloc.h>
415331Samw #include <smbsrv/string.h>
42*10966SJordan.Brown@Sun.COM
435331Samw /*
44*10966SJordan.Brown@Sun.COM * cpid The oemcpg_table index for this oempage.
45*10966SJordan.Brown@Sun.COM * value The conversion values.
46*10966SJordan.Brown@Sun.COM */
47*10966SJordan.Brown@Sun.COM typedef struct oempage {
48*10966SJordan.Brown@Sun.COM uint32_t cpid;
49*10966SJordan.Brown@Sun.COM smb_wchar_t *value;
50*10966SJordan.Brown@Sun.COM } oempage_t;
51*10966SJordan.Brown@Sun.COM
52*10966SJordan.Brown@Sun.COM /*
53*10966SJordan.Brown@Sun.COM * filename The actual filename contains the codepage.
54*10966SJordan.Brown@Sun.COM * bytesperchar The codepage uses double or single bytes per char.
55*10966SJordan.Brown@Sun.COM * oempage The oempage is used to convert Unicode characters to
56*10966SJordan.Brown@Sun.COM * OEM characters. Memory needs to be allocated for
57*10966SJordan.Brown@Sun.COM * the value field of oempage to store the table.
58*10966SJordan.Brown@Sun.COM * ucspage The unicode page is used to convert OEM characters
59*10966SJordan.Brown@Sun.COM * to Unicode characters. Memory needs to be allocated
60*10966SJordan.Brown@Sun.COM * for the value field of ucspage to store the table.
61*10966SJordan.Brown@Sun.COM * valid True if the codepage has been initialized.
625331Samw */
635331Samw typedef struct oem_codepage {
64*10966SJordan.Brown@Sun.COM char *filename;
65*10966SJordan.Brown@Sun.COM uint32_t bytesperchar;
66*10966SJordan.Brown@Sun.COM oempage_t oempage;
67*10966SJordan.Brown@Sun.COM oempage_t ucspage;
68*10966SJordan.Brown@Sun.COM boolean_t valid;
695331Samw } oem_codepage_t;
705331Samw
71*10966SJordan.Brown@Sun.COM static oem_codepage_t oemcpg_table[] = {
72*10966SJordan.Brown@Sun.COM {"850.cpg", 1, {0, 0}, {0, 0}, 0}, /* Multilingual Latin1 */
73*10966SJordan.Brown@Sun.COM {"950.cpg", 2, {1, 0}, {1, 0}, 0}, /* Chinese Traditional */
74*10966SJordan.Brown@Sun.COM {"1252.cpg", 1, {2, 0}, {2, 0}, 0}, /* MS Latin1 */
75*10966SJordan.Brown@Sun.COM {"949.cpg", 2, {3, 0}, {3, 0}, 0}, /* Korean */
76*10966SJordan.Brown@Sun.COM {"936.cpg", 2, {4, 0}, {4, 0}, 0}, /* Chinese Simplified */
77*10966SJordan.Brown@Sun.COM {"932.cpg", 2, {5, 0}, {5, 0}, 0}, /* Japanese */
78*10966SJordan.Brown@Sun.COM {"852.cpg", 1, {6, 0}, {6, 0}, 0}, /* Multilingual Latin2 */
79*10966SJordan.Brown@Sun.COM {"1250.cpg", 1, {7, 0}, {7, 0}, 0}, /* MS Latin2 */
80*10966SJordan.Brown@Sun.COM {"1253.cpg", 1, {8, 0}, {8, 0}, 0}, /* MS Greek */
81*10966SJordan.Brown@Sun.COM {"737.cpg", 1, {9, 0}, {9, 0}, 0}, /* Greek */
82*10966SJordan.Brown@Sun.COM {"1254.cpg", 1, {10, 0}, {10, 0}, 0}, /* MS Turkish */
83*10966SJordan.Brown@Sun.COM {"857.cpg", 1, {11, 0}, {11, 0}, 0}, /* Multilingual Latin5 */
84*10966SJordan.Brown@Sun.COM {"1251.cpg", 1, {12, 0}, {12, 0}, 0}, /* MS Cyrillic */
85*10966SJordan.Brown@Sun.COM {"866.cpg", 1, {13, 0}, {13, 0}, 0}, /* Cyrillic II */
86*10966SJordan.Brown@Sun.COM {"1255.cpg", 1, {14, 0}, {14, 0}, 0}, /* MS Hebrew */
87*10966SJordan.Brown@Sun.COM {"862.cpg", 1, {15, 0}, {15, 0}, 0}, /* Hebrew */
88*10966SJordan.Brown@Sun.COM {"1256.cpg", 1, {16, 0}, {16, 0}, 0}, /* MS Arabic */
89*10966SJordan.Brown@Sun.COM {"720.cpg", 1, {17, 0}, {17, 0}, 0} /* Arabic */
905331Samw };
915331Samw
92*10966SJordan.Brown@Sun.COM #define MAX_OEMPAGES (sizeof (oemcpg_table) / sizeof (oemcpg_table[0]))
93*10966SJordan.Brown@Sun.COM #define MAX_UNICODE_IDX 65536
945331Samw
955331Samw /*
96*10966SJordan.Brown@Sun.COM * The default SMB OEM codepage for English is codepage 850.
975331Samw */
98*10966SJordan.Brown@Sun.COM smb_wchar_t oem_codepage_850[256] = {
995331Samw 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
1005331Samw 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
1015331Samw 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
1025331Samw 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
1035331Samw 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
1045331Samw 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
1055331Samw 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
1065331Samw 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
1075331Samw 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
1085331Samw 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
1095331Samw 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
1105331Samw 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
1115331Samw 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
1125331Samw 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
1135331Samw 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
1145331Samw 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
1155331Samw 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
1165331Samw 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
1175331Samw 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
1185331Samw 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
1195331Samw 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
1205331Samw 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
1215331Samw 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
1225331Samw 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
1235331Samw 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
1245331Samw 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
1255331Samw 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
1265331Samw 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
1275331Samw 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
1285331Samw 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
1295331Samw 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
1305331Samw 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
1315331Samw };
1325331Samw
1335331Samw /*
134*10966SJordan.Brown@Sun.COM * The default telnet OEM codepage for English is codepage 1252.
1355331Samw */
136*10966SJordan.Brown@Sun.COM smb_wchar_t oem_codepage_1252[256] = {
1375331Samw 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
1385331Samw 0x9, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x10,
1395331Samw 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
1405331Samw 0x19, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x20,
1415331Samw 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
1425331Samw 0x29, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x30,
1435331Samw 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1445331Samw 0x39, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x40,
1455331Samw 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
1465331Samw 0x49, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x50,
1475331Samw 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
1485331Samw 0x59, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x60,
1495331Samw 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
1505331Samw 0x69, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x70,
1515331Samw 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
1525331Samw 0x79, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC,
1535331Samw 0x81, 0x201A, 0x192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
1545331Samw 0x2030, 0x160, 0x2039, 0x152, 0x8D, 0x017D, 0x8F, 0x90,
1555331Samw 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC,
1565331Samw 0x2122, 0x161, 0x203A, 0x153, 0x9D, 0x017E, 0x178, 0x00A0,
1575331Samw 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8,
1585331Samw 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0,
1595331Samw 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8,
1605331Samw 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0,
1615331Samw 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8,
1625331Samw 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0,
1635331Samw 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8,
1645331Samw 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0,
1655331Samw 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8,
1665331Samw 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0,
1675331Samw 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8,
1685331Samw 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
1695331Samw };
1705331Samw
171*10966SJordan.Brown@Sun.COM static oempage_t *oem_get_oempage(uint32_t);
172*10966SJordan.Brown@Sun.COM static oempage_t *oem_get_ucspage(uint32_t);
173*10966SJordan.Brown@Sun.COM static void oem_codepage_init(uint32_t);
174*10966SJordan.Brown@Sun.COM static void oem_codepage_setup(uint32_t);
1755331Samw
1765331Samw /*
177*10966SJordan.Brown@Sun.COM * Convert a unicode string to an oem string.
1785331Samw *
179*10966SJordan.Brown@Sun.COM * The conversion will stop at the end of the unicode string
180*10966SJordan.Brown@Sun.COM * or when (nbytes - 1) oem characters have been stored.
181*10966SJordan.Brown@Sun.COM *
182*10966SJordan.Brown@Sun.COM * The number of converted unicode characters is returned,
183*10966SJordan.Brown@Sun.COM * or 0 on error.
1845331Samw */
185*10966SJordan.Brown@Sun.COM size_t
ucstooem(char * oem,const smb_wchar_t * ucs,size_t nbytes,uint32_t cpid)186*10966SJordan.Brown@Sun.COM ucstooem(char *oem, const smb_wchar_t *ucs, size_t nbytes, uint32_t cpid)
1875331Samw {
188*10966SJordan.Brown@Sun.COM oempage_t *ucspage;
189*10966SJordan.Brown@Sun.COM uint32_t count = 0;
190*10966SJordan.Brown@Sun.COM smb_wchar_t oemchar;
191*10966SJordan.Brown@Sun.COM
192*10966SJordan.Brown@Sun.COM if (ucs == NULL || oem == NULL)
1935331Samw return (0);
1945331Samw
195*10966SJordan.Brown@Sun.COM if ((ucspage = oem_get_ucspage(cpid)) == NULL)
196*10966SJordan.Brown@Sun.COM return (0);
197*10966SJordan.Brown@Sun.COM
198*10966SJordan.Brown@Sun.COM while (nbytes != 0 && (oemchar = ucspage->value[*ucs]) != 0) {
199*10966SJordan.Brown@Sun.COM if (oemchar & 0xff00 && nbytes >= MTS_MB_CHAR_MAX) {
200*10966SJordan.Brown@Sun.COM *oem++ = oemchar >> 8;
201*10966SJordan.Brown@Sun.COM *oem++ = (char)oemchar;
202*10966SJordan.Brown@Sun.COM nbytes -= 2;
203*10966SJordan.Brown@Sun.COM } else if (nbytes > 1) {
204*10966SJordan.Brown@Sun.COM *oem++ = (char)oemchar;
205*10966SJordan.Brown@Sun.COM nbytes--;
206*10966SJordan.Brown@Sun.COM } else {
207*10966SJordan.Brown@Sun.COM break;
208*10966SJordan.Brown@Sun.COM }
209*10966SJordan.Brown@Sun.COM
210*10966SJordan.Brown@Sun.COM count++;
211*10966SJordan.Brown@Sun.COM ucs++;
212*10966SJordan.Brown@Sun.COM }
213*10966SJordan.Brown@Sun.COM
214*10966SJordan.Brown@Sun.COM *oem = '\0';
215*10966SJordan.Brown@Sun.COM return (count);
2165331Samw }
2175331Samw
2185331Samw /*
219*10966SJordan.Brown@Sun.COM * Convert an oem string to a unicode string.
220*10966SJordan.Brown@Sun.COM *
221*10966SJordan.Brown@Sun.COM * The conversion will stop at the end of the oem string or
222*10966SJordan.Brown@Sun.COM * when nwchars - 1 have been converted.
2235331Samw *
224*10966SJordan.Brown@Sun.COM * The number of converted oem chars is returned, or 0 on error.
225*10966SJordan.Brown@Sun.COM * An oem char may be either 1 or 2 bytes.
2265331Samw */
227*10966SJordan.Brown@Sun.COM size_t
oemtoucs(smb_wchar_t * ucs,const char * oem,size_t nwchars,uint32_t cpid)228*10966SJordan.Brown@Sun.COM oemtoucs(smb_wchar_t *ucs, const char *oem, size_t nwchars, uint32_t cpid)
2295331Samw {
230*10966SJordan.Brown@Sun.COM oempage_t *oempage;
231*10966SJordan.Brown@Sun.COM size_t count = nwchars;
232*10966SJordan.Brown@Sun.COM smb_wchar_t oemchar;
2335331Samw
234*10966SJordan.Brown@Sun.COM if (ucs == NULL || oem == NULL)
2355331Samw return (0);
2365331Samw
237*10966SJordan.Brown@Sun.COM if ((oempage = oem_get_oempage(cpid)) == NULL)
2385331Samw return (0);
2395331Samw
240*10966SJordan.Brown@Sun.COM while ((oemchar = (smb_wchar_t)*oem++ & 0xff) != 0) {
2415331Samw /*
242*10966SJordan.Brown@Sun.COM * Cannot find one byte oemchar in table.
243*10966SJordan.Brown@Sun.COM * Must be a lead byte. Try two bytes.
2445331Samw */
2455331Samw if ((oempage->value[oemchar] == 0) && (oemchar != 0)) {
246*10966SJordan.Brown@Sun.COM oemchar = oemchar << 8 | (*oem++ & 0xff);
2475331Samw if (oempage->value[oemchar] == 0) {
248*10966SJordan.Brown@Sun.COM *ucs = 0;
2495331Samw break;
2505331Samw }
2515331Samw }
2525331Samw #ifdef _BIG_ENDIAN
253*10966SJordan.Brown@Sun.COM *ucs = LE_IN16(&oempage->value[oemchar]);
2545331Samw #else
255*10966SJordan.Brown@Sun.COM *ucs = oempage->value[oemchar];
2565331Samw #endif
2575331Samw count--;
258*10966SJordan.Brown@Sun.COM ucs++;
2595331Samw }
2605331Samw
261*10966SJordan.Brown@Sun.COM *ucs = 0;
2625331Samw return (nwchars - count);
2635331Samw }
2645331Samw
2655331Samw /*
266*10966SJordan.Brown@Sun.COM * Get a pointer to the oem page for the specific codepage id.
2675331Samw */
268*10966SJordan.Brown@Sun.COM static oempage_t *
oem_get_oempage(uint32_t cpid)269*10966SJordan.Brown@Sun.COM oem_get_oempage(uint32_t cpid)
2705331Samw {
271*10966SJordan.Brown@Sun.COM if (cpid >= MAX_OEMPAGES)
272*10966SJordan.Brown@Sun.COM return (NULL);
273*10966SJordan.Brown@Sun.COM
274*10966SJordan.Brown@Sun.COM if (!oemcpg_table[cpid].valid) {
275*10966SJordan.Brown@Sun.COM oem_codepage_init(cpid);
276*10966SJordan.Brown@Sun.COM
277*10966SJordan.Brown@Sun.COM if (!oemcpg_table[cpid].valid)
278*10966SJordan.Brown@Sun.COM return (NULL);
279*10966SJordan.Brown@Sun.COM }
280*10966SJordan.Brown@Sun.COM
281*10966SJordan.Brown@Sun.COM return (&oemcpg_table[cpid].oempage);
2825331Samw }
2835331Samw
2845331Samw /*
285*10966SJordan.Brown@Sun.COM * Get a pointer to the ucs page for the specific codepage id.
2865331Samw */
287*10966SJordan.Brown@Sun.COM static oempage_t *
oem_get_ucspage(uint32_t cpid)288*10966SJordan.Brown@Sun.COM oem_get_ucspage(uint32_t cpid)
2895331Samw {
290*10966SJordan.Brown@Sun.COM if (cpid >= MAX_OEMPAGES)
291*10966SJordan.Brown@Sun.COM return (NULL);
292*10966SJordan.Brown@Sun.COM
293*10966SJordan.Brown@Sun.COM if (!oemcpg_table[cpid].valid) {
294*10966SJordan.Brown@Sun.COM oem_codepage_init(cpid);
295*10966SJordan.Brown@Sun.COM
296*10966SJordan.Brown@Sun.COM if (!oemcpg_table[cpid].valid)
297*10966SJordan.Brown@Sun.COM return (NULL);
298*10966SJordan.Brown@Sun.COM }
299*10966SJordan.Brown@Sun.COM
300*10966SJordan.Brown@Sun.COM return (&oemcpg_table[cpid].ucspage);
3015331Samw }
3025331Samw
3035331Samw /*
304*10966SJordan.Brown@Sun.COM * Initialize the oem page in the oem table.
3055331Samw */
306*10966SJordan.Brown@Sun.COM static void
oem_codepage_init(uint32_t cpid)307*10966SJordan.Brown@Sun.COM oem_codepage_init(uint32_t cpid)
3085331Samw {
309*10966SJordan.Brown@Sun.COM #ifndef _KERNEL
310*10966SJordan.Brown@Sun.COM static mutex_t mutex;
311*10966SJordan.Brown@Sun.COM
312*10966SJordan.Brown@Sun.COM (void) mutex_lock(&mutex);
313*10966SJordan.Brown@Sun.COM oem_codepage_setup(cpid);
314*10966SJordan.Brown@Sun.COM (void) mutex_unlock(&mutex);
315*10966SJordan.Brown@Sun.COM #else
316*10966SJordan.Brown@Sun.COM static kmutex_t mutex;
3175331Samw
318*10966SJordan.Brown@Sun.COM mutex_enter(&mutex);
319*10966SJordan.Brown@Sun.COM oem_codepage_setup(cpid);
320*10966SJordan.Brown@Sun.COM mutex_exit(&mutex);
321*10966SJordan.Brown@Sun.COM #endif /* _KERNEL */
322*10966SJordan.Brown@Sun.COM }
3235331Samw
324*10966SJordan.Brown@Sun.COM static void
oem_codepage_setup(uint32_t cpid)325*10966SJordan.Brown@Sun.COM oem_codepage_setup(uint32_t cpid)
326*10966SJordan.Brown@Sun.COM {
327*10966SJordan.Brown@Sun.COM smb_wchar_t *default_oem_cp;
328*10966SJordan.Brown@Sun.COM oem_codepage_t *oemcpg;
329*10966SJordan.Brown@Sun.COM uint32_t bytesperchar;
330*10966SJordan.Brown@Sun.COM uint32_t max_oem_index;
331*10966SJordan.Brown@Sun.COM int i;
3325331Samw
333*10966SJordan.Brown@Sun.COM switch (cpid) {
334*10966SJordan.Brown@Sun.COM case OEM_CPG_850:
335*10966SJordan.Brown@Sun.COM default_oem_cp = oem_codepage_850;
336*10966SJordan.Brown@Sun.COM break;
337*10966SJordan.Brown@Sun.COM case OEM_CPG_1252:
338*10966SJordan.Brown@Sun.COM default_oem_cp = oem_codepage_1252;
339*10966SJordan.Brown@Sun.COM default:
3405331Samw return;
3415331Samw }
3425331Samw
343*10966SJordan.Brown@Sun.COM oemcpg = &oemcpg_table[cpid];
344*10966SJordan.Brown@Sun.COM if (oemcpg->valid)
345*10966SJordan.Brown@Sun.COM return;
3465331Samw
3475331Samw /*
348*10966SJordan.Brown@Sun.COM * max_oem_index will be 256 or 65536 dependent
349*10966SJordan.Brown@Sun.COM * on the OEM codepage.
3505331Samw */
351*10966SJordan.Brown@Sun.COM bytesperchar = oemcpg_table[cpid].bytesperchar;
352*10966SJordan.Brown@Sun.COM max_oem_index = 1 << (bytesperchar * 8);
3535331Samw
354*10966SJordan.Brown@Sun.COM oemcpg->oempage.value =
355*10966SJordan.Brown@Sun.COM MEM_ZALLOC("oem", max_oem_index * sizeof (smb_wchar_t));
356*10966SJordan.Brown@Sun.COM if (oemcpg->oempage.value == NULL)
357*10966SJordan.Brown@Sun.COM return;
3585331Samw
359*10966SJordan.Brown@Sun.COM oemcpg->ucspage.value =
360*10966SJordan.Brown@Sun.COM MEM_ZALLOC("oem", MAX_UNICODE_IDX * sizeof (smb_wchar_t));
361*10966SJordan.Brown@Sun.COM if (oemcpg->ucspage.value == NULL) {
362*10966SJordan.Brown@Sun.COM MEM_FREE("oem", oemcpg->oempage.value);
363*10966SJordan.Brown@Sun.COM oemcpg->oempage.value = NULL;
364*10966SJordan.Brown@Sun.COM return;
365*10966SJordan.Brown@Sun.COM }
366*10966SJordan.Brown@Sun.COM
367*10966SJordan.Brown@Sun.COM for (i = 0; i < max_oem_index; i++) {
368*10966SJordan.Brown@Sun.COM oemcpg->oempage.value[i] = default_oem_cp[i];
369*10966SJordan.Brown@Sun.COM oemcpg->ucspage.value[default_oem_cp[i]] = (smb_wchar_t)i;
370*10966SJordan.Brown@Sun.COM }
371*10966SJordan.Brown@Sun.COM
372*10966SJordan.Brown@Sun.COM oemcpg->valid = B_TRUE;
3735331Samw }
374