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