1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 22*bbf6f00cSJordan Brown * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23da6c28aaSamw * Use is subject to license terms. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw /* 27da6c28aaSamw * Support for oem <-> unicode translations. 28da6c28aaSamw */ 29da6c28aaSamw 30da6c28aaSamw #ifndef _KERNEL 31da6c28aaSamw #include <stdlib.h> 32da6c28aaSamw #include <thread.h> 33da6c28aaSamw #include <synch.h> 34da6c28aaSamw #include <string.h> 35*bbf6f00cSJordan Brown #else 36*bbf6f00cSJordan Brown #include <sys/ksynch.h> 37da6c28aaSamw #endif /* _KERNEL */ 38*bbf6f00cSJordan Brown 39*bbf6f00cSJordan Brown #include <sys/byteorder.h> 40da6c28aaSamw #include <smbsrv/alloc.h> 41da6c28aaSamw #include <smbsrv/string.h> 42*bbf6f00cSJordan Brown 43da6c28aaSamw /* 44*bbf6f00cSJordan Brown * cpid The oemcpg_table index for this oempage. 45*bbf6f00cSJordan Brown * value The conversion values. 46*bbf6f00cSJordan Brown */ 47*bbf6f00cSJordan Brown typedef struct oempage { 48*bbf6f00cSJordan Brown uint32_t cpid; 49*bbf6f00cSJordan Brown smb_wchar_t *value; 50*bbf6f00cSJordan Brown } oempage_t; 51*bbf6f00cSJordan Brown 52*bbf6f00cSJordan Brown /* 53*bbf6f00cSJordan Brown * filename The actual filename contains the codepage. 54*bbf6f00cSJordan Brown * bytesperchar The codepage uses double or single bytes per char. 55*bbf6f00cSJordan Brown * oempage The oempage is used to convert Unicode characters to 56*bbf6f00cSJordan Brown * OEM characters. Memory needs to be allocated for 57*bbf6f00cSJordan Brown * the value field of oempage to store the table. 58*bbf6f00cSJordan Brown * ucspage The unicode page is used to convert OEM characters 59*bbf6f00cSJordan Brown * to Unicode characters. Memory needs to be allocated 60*bbf6f00cSJordan Brown * for the value field of ucspage to store the table. 61*bbf6f00cSJordan Brown * valid True if the codepage has been initialized. 62da6c28aaSamw */ 63da6c28aaSamw typedef struct oem_codepage { 64*bbf6f00cSJordan Brown char *filename; 65*bbf6f00cSJordan Brown uint32_t bytesperchar; 66*bbf6f00cSJordan Brown oempage_t oempage; 67*bbf6f00cSJordan Brown oempage_t ucspage; 68*bbf6f00cSJordan Brown boolean_t valid; 69da6c28aaSamw } oem_codepage_t; 70da6c28aaSamw 71*bbf6f00cSJordan Brown static oem_codepage_t oemcpg_table[] = { 72*bbf6f00cSJordan Brown {"850.cpg", 1, {0, 0}, {0, 0}, 0}, /* Multilingual Latin1 */ 73*bbf6f00cSJordan Brown {"950.cpg", 2, {1, 0}, {1, 0}, 0}, /* Chinese Traditional */ 74*bbf6f00cSJordan Brown {"1252.cpg", 1, {2, 0}, {2, 0}, 0}, /* MS Latin1 */ 75*bbf6f00cSJordan Brown {"949.cpg", 2, {3, 0}, {3, 0}, 0}, /* Korean */ 76*bbf6f00cSJordan Brown {"936.cpg", 2, {4, 0}, {4, 0}, 0}, /* Chinese Simplified */ 77*bbf6f00cSJordan Brown {"932.cpg", 2, {5, 0}, {5, 0}, 0}, /* Japanese */ 78*bbf6f00cSJordan Brown {"852.cpg", 1, {6, 0}, {6, 0}, 0}, /* Multilingual Latin2 */ 79*bbf6f00cSJordan Brown {"1250.cpg", 1, {7, 0}, {7, 0}, 0}, /* MS Latin2 */ 80*bbf6f00cSJordan Brown {"1253.cpg", 1, {8, 0}, {8, 0}, 0}, /* MS Greek */ 81*bbf6f00cSJordan Brown {"737.cpg", 1, {9, 0}, {9, 0}, 0}, /* Greek */ 82*bbf6f00cSJordan Brown {"1254.cpg", 1, {10, 0}, {10, 0}, 0}, /* MS Turkish */ 83*bbf6f00cSJordan Brown {"857.cpg", 1, {11, 0}, {11, 0}, 0}, /* Multilingual Latin5 */ 84*bbf6f00cSJordan Brown {"1251.cpg", 1, {12, 0}, {12, 0}, 0}, /* MS Cyrillic */ 85*bbf6f00cSJordan Brown {"866.cpg", 1, {13, 0}, {13, 0}, 0}, /* Cyrillic II */ 86*bbf6f00cSJordan Brown {"1255.cpg", 1, {14, 0}, {14, 0}, 0}, /* MS Hebrew */ 87*bbf6f00cSJordan Brown {"862.cpg", 1, {15, 0}, {15, 0}, 0}, /* Hebrew */ 88*bbf6f00cSJordan Brown {"1256.cpg", 1, {16, 0}, {16, 0}, 0}, /* MS Arabic */ 89*bbf6f00cSJordan Brown {"720.cpg", 1, {17, 0}, {17, 0}, 0} /* Arabic */ 90da6c28aaSamw }; 91da6c28aaSamw 92*bbf6f00cSJordan Brown #define MAX_OEMPAGES (sizeof (oemcpg_table) / sizeof (oemcpg_table[0])) 93*bbf6f00cSJordan Brown #define MAX_UNICODE_IDX 65536 94da6c28aaSamw 95da6c28aaSamw /* 96*bbf6f00cSJordan Brown * The default SMB OEM codepage for English is codepage 850. 97da6c28aaSamw */ 98*bbf6f00cSJordan Brown smb_wchar_t oem_codepage_850[256] = { 99da6c28aaSamw 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 100da6c28aaSamw 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 101da6c28aaSamw 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 102da6c28aaSamw 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 103da6c28aaSamw 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 104da6c28aaSamw 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 105da6c28aaSamw 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 106da6c28aaSamw 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 107da6c28aaSamw 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 108da6c28aaSamw 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 109da6c28aaSamw 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 110da6c28aaSamw 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 111da6c28aaSamw 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 112da6c28aaSamw 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 113da6c28aaSamw 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 114da6c28aaSamw 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 115da6c28aaSamw 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 116da6c28aaSamw 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 117da6c28aaSamw 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 118da6c28aaSamw 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, 119da6c28aaSamw 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 120da6c28aaSamw 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 121da6c28aaSamw 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 122da6c28aaSamw 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, 123da6c28aaSamw 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 124da6c28aaSamw 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, 125da6c28aaSamw 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 126da6c28aaSamw 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, 127da6c28aaSamw 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 128da6c28aaSamw 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, 129da6c28aaSamw 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 130da6c28aaSamw 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 131da6c28aaSamw }; 132da6c28aaSamw 133da6c28aaSamw /* 134*bbf6f00cSJordan Brown * The default telnet OEM codepage for English is codepage 1252. 135da6c28aaSamw */ 136*bbf6f00cSJordan Brown smb_wchar_t oem_codepage_1252[256] = { 137da6c28aaSamw 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 138da6c28aaSamw 0x9, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x10, 139da6c28aaSamw 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 140da6c28aaSamw 0x19, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x20, 141da6c28aaSamw 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 142da6c28aaSamw 0x29, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x30, 143da6c28aaSamw 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 144da6c28aaSamw 0x39, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x40, 145da6c28aaSamw 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 146da6c28aaSamw 0x49, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x50, 147da6c28aaSamw 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 148da6c28aaSamw 0x59, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x60, 149da6c28aaSamw 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 150da6c28aaSamw 0x69, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x70, 151da6c28aaSamw 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 152da6c28aaSamw 0x79, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC, 153da6c28aaSamw 0x81, 0x201A, 0x192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 154da6c28aaSamw 0x2030, 0x160, 0x2039, 0x152, 0x8D, 0x017D, 0x8F, 0x90, 155da6c28aaSamw 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 156da6c28aaSamw 0x2122, 0x161, 0x203A, 0x153, 0x9D, 0x017E, 0x178, 0x00A0, 157da6c28aaSamw 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 158da6c28aaSamw 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 159da6c28aaSamw 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 160da6c28aaSamw 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, 161da6c28aaSamw 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 162da6c28aaSamw 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 163da6c28aaSamw 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 164da6c28aaSamw 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 165da6c28aaSamw 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 166da6c28aaSamw 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 167da6c28aaSamw 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 168da6c28aaSamw 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF 169da6c28aaSamw }; 170da6c28aaSamw 171*bbf6f00cSJordan Brown static oempage_t *oem_get_oempage(uint32_t); 172*bbf6f00cSJordan Brown static oempage_t *oem_get_ucspage(uint32_t); 173*bbf6f00cSJordan Brown static void oem_codepage_init(uint32_t); 174*bbf6f00cSJordan Brown static void oem_codepage_setup(uint32_t); 175da6c28aaSamw 176da6c28aaSamw /* 177*bbf6f00cSJordan Brown * Convert a unicode string to an oem string. 178da6c28aaSamw * 179*bbf6f00cSJordan Brown * The conversion will stop at the end of the unicode string 180*bbf6f00cSJordan Brown * or when (nbytes - 1) oem characters have been stored. 181da6c28aaSamw * 182*bbf6f00cSJordan Brown * The number of converted unicode characters is returned, 183*bbf6f00cSJordan Brown * or 0 on error. 184da6c28aaSamw */ 185da6c28aaSamw size_t 186*bbf6f00cSJordan Brown ucstooem(char *oem, const smb_wchar_t *ucs, size_t nbytes, uint32_t cpid) 187da6c28aaSamw { 188*bbf6f00cSJordan Brown oempage_t *ucspage; 189*bbf6f00cSJordan Brown uint32_t count = 0; 190*bbf6f00cSJordan Brown smb_wchar_t oemchar; 191da6c28aaSamw 192*bbf6f00cSJordan Brown if (ucs == NULL || oem == NULL) 193da6c28aaSamw return (0); 194da6c28aaSamw 195*bbf6f00cSJordan Brown if ((ucspage = oem_get_ucspage(cpid)) == NULL) 196da6c28aaSamw return (0); 197da6c28aaSamw 198*bbf6f00cSJordan Brown while (nbytes != 0 && (oemchar = ucspage->value[*ucs]) != 0) { 199da6c28aaSamw if (oemchar & 0xff00 && nbytes >= MTS_MB_CHAR_MAX) { 200*bbf6f00cSJordan Brown *oem++ = oemchar >> 8; 201*bbf6f00cSJordan Brown *oem++ = (char)oemchar; 202da6c28aaSamw nbytes -= 2; 203da6c28aaSamw } else if (nbytes > 1) { 204*bbf6f00cSJordan Brown *oem++ = (char)oemchar; 205da6c28aaSamw nbytes--; 206*bbf6f00cSJordan Brown } else { 207da6c28aaSamw break; 208*bbf6f00cSJordan Brown } 209da6c28aaSamw 210da6c28aaSamw count++; 211*bbf6f00cSJordan Brown ucs++; 212da6c28aaSamw } 213da6c28aaSamw 214*bbf6f00cSJordan Brown *oem = '\0'; 215da6c28aaSamw return (count); 216da6c28aaSamw } 217da6c28aaSamw 218da6c28aaSamw /* 219*bbf6f00cSJordan Brown * Convert an oem string to a unicode string. 220da6c28aaSamw * 221*bbf6f00cSJordan Brown * The conversion will stop at the end of the oem string or 222*bbf6f00cSJordan Brown * when nwchars - 1 have been converted. 223*bbf6f00cSJordan Brown * 224*bbf6f00cSJordan Brown * The number of converted oem chars is returned, or 0 on error. 225*bbf6f00cSJordan Brown * An oem char may be either 1 or 2 bytes. 226da6c28aaSamw */ 227da6c28aaSamw size_t 228*bbf6f00cSJordan Brown oemtoucs(smb_wchar_t *ucs, const char *oem, size_t nwchars, uint32_t cpid) 229da6c28aaSamw { 230*bbf6f00cSJordan Brown oempage_t *oempage; 231*bbf6f00cSJordan Brown size_t count = nwchars; 232*bbf6f00cSJordan Brown smb_wchar_t oemchar; 233da6c28aaSamw 234*bbf6f00cSJordan Brown if (ucs == NULL || oem == NULL) 235da6c28aaSamw return (0); 236da6c28aaSamw 237*bbf6f00cSJordan Brown if ((oempage = oem_get_oempage(cpid)) == NULL) 238da6c28aaSamw return (0); 239da6c28aaSamw 240*bbf6f00cSJordan Brown while ((oemchar = (smb_wchar_t)*oem++ & 0xff) != 0) { 241da6c28aaSamw /* 242*bbf6f00cSJordan Brown * Cannot find one byte oemchar in table. 243*bbf6f00cSJordan Brown * Must be a lead byte. Try two bytes. 244da6c28aaSamw */ 245da6c28aaSamw if ((oempage->value[oemchar] == 0) && (oemchar != 0)) { 246*bbf6f00cSJordan Brown oemchar = oemchar << 8 | (*oem++ & 0xff); 247da6c28aaSamw if (oempage->value[oemchar] == 0) { 248*bbf6f00cSJordan Brown *ucs = 0; 249da6c28aaSamw break; 250da6c28aaSamw } 251da6c28aaSamw } 252da6c28aaSamw #ifdef _BIG_ENDIAN 253*bbf6f00cSJordan Brown *ucs = LE_IN16(&oempage->value[oemchar]); 254da6c28aaSamw #else 255*bbf6f00cSJordan Brown *ucs = oempage->value[oemchar]; 256da6c28aaSamw #endif 257da6c28aaSamw count--; 258*bbf6f00cSJordan Brown ucs++; 259da6c28aaSamw } 260da6c28aaSamw 261*bbf6f00cSJordan Brown *ucs = 0; 262da6c28aaSamw return (nwchars - count); 263da6c28aaSamw } 264da6c28aaSamw 265da6c28aaSamw /* 266*bbf6f00cSJordan Brown * Get a pointer to the oem page for the specific codepage id. 267da6c28aaSamw */ 268*bbf6f00cSJordan Brown static oempage_t * 269*bbf6f00cSJordan Brown oem_get_oempage(uint32_t cpid) 270da6c28aaSamw { 271*bbf6f00cSJordan Brown if (cpid >= MAX_OEMPAGES) 272*bbf6f00cSJordan Brown return (NULL); 273*bbf6f00cSJordan Brown 274*bbf6f00cSJordan Brown if (!oemcpg_table[cpid].valid) { 275*bbf6f00cSJordan Brown oem_codepage_init(cpid); 276*bbf6f00cSJordan Brown 277*bbf6f00cSJordan Brown if (!oemcpg_table[cpid].valid) 278*bbf6f00cSJordan Brown return (NULL); 279*bbf6f00cSJordan Brown } 280*bbf6f00cSJordan Brown 281*bbf6f00cSJordan Brown return (&oemcpg_table[cpid].oempage); 282da6c28aaSamw } 283da6c28aaSamw 284da6c28aaSamw /* 285*bbf6f00cSJordan Brown * Get a pointer to the ucs page for the specific codepage id. 286da6c28aaSamw */ 287*bbf6f00cSJordan Brown static oempage_t * 288*bbf6f00cSJordan Brown oem_get_ucspage(uint32_t cpid) 289da6c28aaSamw { 290*bbf6f00cSJordan Brown if (cpid >= MAX_OEMPAGES) 291*bbf6f00cSJordan Brown return (NULL); 292da6c28aaSamw 293*bbf6f00cSJordan Brown if (!oemcpg_table[cpid].valid) { 294*bbf6f00cSJordan Brown oem_codepage_init(cpid); 295*bbf6f00cSJordan Brown 296*bbf6f00cSJordan Brown if (!oemcpg_table[cpid].valid) 297*bbf6f00cSJordan Brown return (NULL); 298*bbf6f00cSJordan Brown } 299*bbf6f00cSJordan Brown 300*bbf6f00cSJordan Brown return (&oemcpg_table[cpid].ucspage); 301*bbf6f00cSJordan Brown } 302da6c28aaSamw 303da6c28aaSamw /* 304*bbf6f00cSJordan Brown * Initialize the oem page in the oem table. 305da6c28aaSamw */ 306*bbf6f00cSJordan Brown static void 307*bbf6f00cSJordan Brown oem_codepage_init(uint32_t cpid) 308da6c28aaSamw { 309*bbf6f00cSJordan Brown #ifndef _KERNEL 310*bbf6f00cSJordan Brown static mutex_t mutex; 311da6c28aaSamw 312*bbf6f00cSJordan Brown (void) mutex_lock(&mutex); 313*bbf6f00cSJordan Brown oem_codepage_setup(cpid); 314*bbf6f00cSJordan Brown (void) mutex_unlock(&mutex); 315*bbf6f00cSJordan Brown #else 316*bbf6f00cSJordan Brown static kmutex_t mutex; 317da6c28aaSamw 318*bbf6f00cSJordan Brown mutex_enter(&mutex); 319*bbf6f00cSJordan Brown oem_codepage_setup(cpid); 320*bbf6f00cSJordan Brown mutex_exit(&mutex); 321*bbf6f00cSJordan Brown #endif /* _KERNEL */ 322*bbf6f00cSJordan Brown } 323da6c28aaSamw 324*bbf6f00cSJordan Brown static void 325*bbf6f00cSJordan Brown oem_codepage_setup(uint32_t cpid) 326*bbf6f00cSJordan Brown { 327*bbf6f00cSJordan Brown smb_wchar_t *default_oem_cp; 328*bbf6f00cSJordan Brown oem_codepage_t *oemcpg; 329*bbf6f00cSJordan Brown uint32_t bytesperchar; 330*bbf6f00cSJordan Brown uint32_t max_oem_index; 331*bbf6f00cSJordan Brown int i; 332*bbf6f00cSJordan Brown 333*bbf6f00cSJordan Brown switch (cpid) { 334*bbf6f00cSJordan Brown case OEM_CPG_850: 335*bbf6f00cSJordan Brown default_oem_cp = oem_codepage_850; 336*bbf6f00cSJordan Brown break; 337*bbf6f00cSJordan Brown case OEM_CPG_1252: 338*bbf6f00cSJordan Brown default_oem_cp = oem_codepage_1252; 339*bbf6f00cSJordan Brown default: 340da6c28aaSamw return; 341da6c28aaSamw } 342da6c28aaSamw 343*bbf6f00cSJordan Brown oemcpg = &oemcpg_table[cpid]; 344*bbf6f00cSJordan Brown if (oemcpg->valid) 345da6c28aaSamw return; 346da6c28aaSamw 347da6c28aaSamw /* 348*bbf6f00cSJordan Brown * max_oem_index will be 256 or 65536 dependent 349*bbf6f00cSJordan Brown * on the OEM codepage. 350da6c28aaSamw */ 351*bbf6f00cSJordan Brown bytesperchar = oemcpg_table[cpid].bytesperchar; 352*bbf6f00cSJordan Brown max_oem_index = 1 << (bytesperchar * 8); 353da6c28aaSamw 354*bbf6f00cSJordan Brown oemcpg->oempage.value = 355*bbf6f00cSJordan Brown MEM_ZALLOC("oem", max_oem_index * sizeof (smb_wchar_t)); 356*bbf6f00cSJordan Brown if (oemcpg->oempage.value == NULL) 357*bbf6f00cSJordan Brown return; 358da6c28aaSamw 359*bbf6f00cSJordan Brown oemcpg->ucspage.value = 360*bbf6f00cSJordan Brown MEM_ZALLOC("oem", MAX_UNICODE_IDX * sizeof (smb_wchar_t)); 361*bbf6f00cSJordan Brown if (oemcpg->ucspage.value == NULL) { 362*bbf6f00cSJordan Brown MEM_FREE("oem", oemcpg->oempage.value); 363*bbf6f00cSJordan Brown oemcpg->oempage.value = NULL; 364*bbf6f00cSJordan Brown return; 365*bbf6f00cSJordan Brown } 366da6c28aaSamw 367*bbf6f00cSJordan Brown for (i = 0; i < max_oem_index; i++) { 368*bbf6f00cSJordan Brown oemcpg->oempage.value[i] = default_oem_cp[i]; 369*bbf6f00cSJordan Brown oemcpg->ucspage.value[default_oem_cp[i]] = (smb_wchar_t)i; 370*bbf6f00cSJordan Brown } 371da6c28aaSamw 372*bbf6f00cSJordan Brown oemcpg->valid = B_TRUE; 373da6c28aaSamw } 374