da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross *
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Support for oem <-> unicode translations.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#if !defined(_KERNEL) && !defined(_FAKE_KERNEL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <stdlib.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <thread.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <synch.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <string.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#else
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <sys/ksynch.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#endif /* _KERNEL */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <sys/byteorder.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/alloc.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/string.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * cpid The oemcpg_table index for this oempage.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * value The conversion values.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Browntypedef struct oempage {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown uint32_t cpid;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_wchar_t *value;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown} oempage_t;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * filename The actual filename contains the codepage.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * bytesperchar The codepage uses double or single bytes per char.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * oempage The oempage is used to convert Unicode characters to
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * OEM characters. Memory needs to be allocated for
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * the value field of oempage to store the table.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * ucspage The unicode page is used to convert OEM characters
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * to Unicode characters. Memory needs to be allocated
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * for the value field of ucspage to store the table.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * valid True if the codepage has been initialized.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwtypedef struct oem_codepage {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown char *filename;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown uint32_t bytesperchar;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oempage_t oempage;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oempage_t ucspage;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown boolean_t valid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw} oem_codepage_t;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic oem_codepage_t oemcpg_table[] = {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"850.cpg", 1, {0, 0}, {0, 0}, 0}, /* Multilingual Latin1 */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"950.cpg", 2, {1, 0}, {1, 0}, 0}, /* Chinese Traditional */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"1252.cpg", 1, {2, 0}, {2, 0}, 0}, /* MS Latin1 */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"949.cpg", 2, {3, 0}, {3, 0}, 0}, /* Korean */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"936.cpg", 2, {4, 0}, {4, 0}, 0}, /* Chinese Simplified */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"932.cpg", 2, {5, 0}, {5, 0}, 0}, /* Japanese */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"852.cpg", 1, {6, 0}, {6, 0}, 0}, /* Multilingual Latin2 */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"1250.cpg", 1, {7, 0}, {7, 0}, 0}, /* MS Latin2 */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"1253.cpg", 1, {8, 0}, {8, 0}, 0}, /* MS Greek */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"737.cpg", 1, {9, 0}, {9, 0}, 0}, /* Greek */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"1254.cpg", 1, {10, 0}, {10, 0}, 0}, /* MS Turkish */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"857.cpg", 1, {11, 0}, {11, 0}, 0}, /* Multilingual Latin5 */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"1251.cpg", 1, {12, 0}, {12, 0}, 0}, /* MS Cyrillic */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"866.cpg", 1, {13, 0}, {13, 0}, 0}, /* Cyrillic II */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"1255.cpg", 1, {14, 0}, {14, 0}, 0}, /* MS Hebrew */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"862.cpg", 1, {15, 0}, {15, 0}, 0}, /* Hebrew */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"1256.cpg", 1, {16, 0}, {16, 0}, 0}, /* MS Arabic */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown {"720.cpg", 1, {17, 0}, {17, 0}, 0} /* Arabic */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw};
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#define MAX_OEMPAGES (sizeof (oemcpg_table) / sizeof (oemcpg_table[0]))
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#define MAX_UNICODE_IDX 65536
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * The default SMB OEM codepage for English is codepage 850.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
8622ec4569457733001d4982ef7f5b44427069beGordon Rossconst smb_wchar_t oem_codepage_850[256] = {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw};
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * The default telnet OEM codepage for English is codepage 1252.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
8622ec4569457733001d4982ef7f5b44427069beGordon Rossconst smb_wchar_t oem_codepage_1252[256] = {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x9, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x10,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x19, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x20,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x29, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x30,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x39, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x40,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x49, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x50,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x59, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x60,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x69, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x70,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x79, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x20AC,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x81, 0x201A, 0x192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x2030, 0x160, 0x2039, 0x152, 0x8D, 0x017D, 0x8F, 0x90,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x2122, 0x161, 0x203A, 0x153, 0x9D, 0x017E, 0x178, 0x00A0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw};
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic oempage_t *oem_get_oempage(uint32_t);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic oempage_t *oem_get_ucspage(uint32_t);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic void oem_codepage_init(uint32_t);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic void oem_codepage_setup(uint32_t);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Convert a unicode string to an oem string.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * The conversion will stop at the end of the unicode string
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * or when (nbytes - 1) oem characters have been stored.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * The number of converted unicode characters is returned,
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * or 0 on error.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsize_t
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownucstooem(char *oem, const smb_wchar_t *ucs, size_t nbytes, uint32_t cpid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oempage_t *ucspage;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown uint32_t count = 0;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_wchar_t oemchar;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (ucs == NULL || oem == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if ((ucspage = oem_get_ucspage(cpid)) == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown while (nbytes != 0 && (oemchar = ucspage->value[*ucs]) != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (oemchar & 0xff00 && nbytes >= MTS_MB_CHAR_MAX) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *oem++ = oemchar >> 8;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *oem++ = (char)oemchar;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw nbytes -= 2;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (nbytes > 1) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *oem++ = (char)oemchar;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw nbytes--;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw count++;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown ucs++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *oem = '\0';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (count);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Convert an oem string to a unicode string.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * The conversion will stop at the end of the oem string or
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * when nwchars - 1 have been converted.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * The number of converted oem chars is returned, or 0 on error.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * An oem char may be either 1 or 2 bytes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsize_t
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownoemtoucs(smb_wchar_t *ucs, const char *oem, size_t nwchars, uint32_t cpid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oempage_t *oempage;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown size_t count = nwchars;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown smb_wchar_t oemchar;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (ucs == NULL || oem == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if ((oempage = oem_get_oempage(cpid)) == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown while ((oemchar = (smb_wchar_t)*oem++ & 0xff) != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Cannot find one byte oemchar in table.
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Must be a lead byte. Try two bytes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((oempage->value[oemchar] == 0) && (oemchar != 0)) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oemchar = oemchar << 8 | (*oem++ & 0xff);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (oempage->value[oemchar] == 0) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *ucs = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#ifdef _BIG_ENDIAN
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *ucs = LE_IN16(&oempage->value[oemchar]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#else
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *ucs = oempage->value[oemchar];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#endif
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw count--;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown ucs++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown *ucs = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (nwchars - count);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Get a pointer to the oem page for the specific codepage id.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic oempage_t *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownoem_get_oempage(uint32_t cpid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (cpid >= MAX_OEMPAGES)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (NULL);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (!oemcpg_table[cpid].valid) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oem_codepage_init(cpid);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (!oemcpg_table[cpid].valid)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (NULL);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (&oemcpg_table[cpid].oempage);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Get a pointer to the ucs page for the specific codepage id.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic oempage_t *
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownoem_get_ucspage(uint32_t cpid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (cpid >= MAX_OEMPAGES)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (!oemcpg_table[cpid].valid) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oem_codepage_init(cpid);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (!oemcpg_table[cpid].valid)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (NULL);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return (&oemcpg_table[cpid].ucspage);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * Initialize the oem page in the oem table.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic void
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownoem_codepage_init(uint32_t cpid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#if !defined(_KERNEL) && !defined(_FAKE_KERNEL)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown static mutex_t mutex;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (void) mutex_lock(&mutex);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oem_codepage_setup(cpid);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown (void) mutex_unlock(&mutex);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#else
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown static kmutex_t mutex;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown mutex_enter(&mutex);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oem_codepage_setup(cpid);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown mutex_exit(&mutex);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#endif /* _KERNEL */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownstatic void
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brownoem_codepage_setup(uint32_t cpid)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown{
8622ec4569457733001d4982ef7f5b44427069beGordon Ross const smb_wchar_t *default_oem_cp;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oem_codepage_t *oemcpg;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown uint32_t bytesperchar;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown uint32_t max_oem_index;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown int i;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown switch (cpid) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown case OEM_CPG_850:
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown default_oem_cp = oem_codepage_850;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown break;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown case OEM_CPG_1252:
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown default_oem_cp = oem_codepage_1252;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oemcpg = &oemcpg_table[cpid];
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (oemcpg->valid)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * max_oem_index will be 256 or 65536 dependent
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown * on the OEM codepage.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown bytesperchar = oemcpg_table[cpid].bytesperchar;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown max_oem_index = 1 << (bytesperchar * 8);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oemcpg->oempage.value =
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown MEM_ZALLOC("oem", max_oem_index * sizeof (smb_wchar_t));
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (oemcpg->oempage.value == NULL)
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oemcpg->ucspage.value =
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown MEM_ZALLOC("oem", MAX_UNICODE_IDX * sizeof (smb_wchar_t));
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (oemcpg->ucspage.value == NULL) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown MEM_FREE("oem", oemcpg->oempage.value);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oemcpg->oempage.value = NULL;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown return;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown for (i = 0; i < max_oem_index; i++) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oemcpg->oempage.value[i] = default_oem_cp[i];
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oemcpg->ucspage.value[default_oem_cp[i]] = (smb_wchar_t)i;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown oemcpg->valid = B_TRUE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}