diff options
Diffstat (limited to 'usr/src/common/smbsrv/smb_oem.c')
-rw-r--r-- | usr/src/common/smbsrv/smb_oem.c | 747 |
1 files changed, 179 insertions, 568 deletions
diff --git a/usr/src/common/smbsrv/smb_oem.c b/usr/src/common/smbsrv/smb_oem.c index 4dca80402b..92d6aec029 100644 --- a/usr/src/common/smbsrv/smb_oem.c +++ b/usr/src/common/smbsrv/smb_oem.c @@ -19,108 +19,83 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Support for oem <-> unicode translations. */ #ifndef _KERNEL -#include <stdio.h> #include <stdlib.h> #include <thread.h> #include <synch.h> #include <string.h> +#else +#include <sys/ksynch.h> #endif /* _KERNEL */ + +#include <sys/byteorder.h> #include <smbsrv/alloc.h> #include <smbsrv/string.h> -#include <smbsrv/oem.h> -#include <sys/byteorder.h> + /* - * name: Name used to show on the telnet/GUI. - * filename: The actual filename contains the codepage. - * doublebytes: The codepage is double or single byte. - * oempage: The oempage is used to convert Unicode to OEM chars. - * Memory needs to be allocated for value field of oempage - * to store the entire table. - * unipage: The unipage is used to convert OEM to Unicode chars. - * Memory needs to be allocated for value field of unipage - * to store the entire table. - * valid: This field indicates if the page is valid or not. - * ref: This ref count is used to keep track of the usage of BOTH - * oempage and unipage. - * Note: If the cpid of the table is changed, please change the - * codepage_id in oem.h as well. + * cpid The oemcpg_table index for this oempage. + * value The conversion values. + */ +typedef struct oempage { + uint32_t cpid; + smb_wchar_t *value; +} oempage_t; + +/* + * filename The actual filename contains the codepage. + * bytesperchar The codepage uses double or single bytes per char. + * oempage The oempage is used to convert Unicode characters to + * OEM characters. Memory needs to be allocated for + * the value field of oempage to store the table. + * ucspage The unicode page is used to convert OEM characters + * to Unicode characters. Memory needs to be allocated + * for the value field of ucspage to store the table. + * valid True if the codepage has been initialized. */ typedef struct oem_codepage { - char *filename; - unsigned int bytesperchar; - oempage_t oempage; - oempage_t unicodepage; - unsigned int valid; - unsigned int ref; + char *filename; + uint32_t bytesperchar; + oempage_t oempage; + oempage_t ucspage; + boolean_t valid; } oem_codepage_t; -static oem_codepage_t oemcp_table[] = { - {"850.cpg", 1, {0, 0}, {0, 0}, 0, 0}, /* Multilingual Latin1 */ - {"950.cpg", 2, {1, 0}, {1, 0}, 0, 0}, /* Chinese Traditional */ - {"1252.cpg", 1, {2, 0}, {2, 0}, 0, 0}, /* MS Latin1 */ - {"949.cpg", 2, {3, 0}, {3, 0}, 0, 0}, /* Korean */ - {"936.cpg", 2, {4, 0}, {4, 0}, 0, 0}, /* Chinese Simplified */ - {"932.cpg", 2, {5, 0}, {5, 0}, 0, 0}, /* Japanese */ - {"852.cpg", 1, {6, 0}, {6, 0}, 0, 0}, /* Multilingual Latin2 */ - {"1250.cpg", 1, {7, 0}, {7, 0}, 0, 0}, /* MS Latin2 */ - {"1253.cpg", 1, {8, 0}, {8, 0}, 0, 0}, /* MS Greek */ - {"737.cpg", 1, {9, 0}, {9, 0}, 0, 0}, /* Greek */ - {"1254.cpg", 1, {10, 0}, {10, 0}, 0, 0}, /* MS Turkish */ - {"857.cpg", 1, {11, 0}, {11, 0}, 0, 0}, /* Multilingual Latin5 */ - {"1251.cpg", 1, {12, 0}, {12, 0}, 0, 0}, /* MS Cyrillic */ - {"866.cpg", 1, {13, 0}, {13, 0}, 0, 0}, /* Cyrillic II */ - {"1255.cpg", 1, {14, 0}, {14, 0}, 0, 0}, /* MS Hebrew */ - {"862.cpg", 1, {15, 0}, {15, 0}, 0, 0}, /* Hebrew */ - {"1256.cpg", 1, {16, 0}, {16, 0}, 0, 0}, /* MS Arabic */ - {"720.cpg", 1, {17, 0}, {17, 0}, 0, 0} /* Arabic */ -}; - -static language lang_table[] = { - {"Arabic", OEM_CP_IND_720, OEM_CP_IND_1256}, - {"Brazilian", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"Chinese Traditional", OEM_CP_IND_950, OEM_CP_IND_950}, - {"Chinese Simplified", OEM_CP_IND_936, OEM_CP_IND_936}, - {"Czech", OEM_CP_IND_852, OEM_CP_IND_1250}, - {"Danish", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"Dutch", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"English", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"Finnish", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"French", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"German", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"Greek", OEM_CP_IND_737, OEM_CP_IND_1253}, - {"Hebrew", OEM_CP_IND_862, OEM_CP_IND_1255}, - {"Hungarian", OEM_CP_IND_852, OEM_CP_IND_1250}, - {"Italian", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"Japanese", OEM_CP_IND_932, OEM_CP_IND_932}, - {"Korean", OEM_CP_IND_949, OEM_CP_IND_949}, - {"Norwegian", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"Polish", OEM_CP_IND_852, OEM_CP_IND_1250}, - {"Russian", OEM_CP_IND_866, OEM_CP_IND_1251}, - {"Slovak", OEM_CP_IND_852, OEM_CP_IND_1250}, - {"Slovenian", OEM_CP_IND_852, OEM_CP_IND_1250}, - {"Spanish", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"Swedish", OEM_CP_IND_850, OEM_CP_IND_1252}, - {"Turkish", OEM_CP_IND_857, OEM_CP_IND_1254} +static oem_codepage_t oemcpg_table[] = { + {"850.cpg", 1, {0, 0}, {0, 0}, 0}, /* Multilingual Latin1 */ + {"950.cpg", 2, {1, 0}, {1, 0}, 0}, /* Chinese Traditional */ + {"1252.cpg", 1, {2, 0}, {2, 0}, 0}, /* MS Latin1 */ + {"949.cpg", 2, {3, 0}, {3, 0}, 0}, /* Korean */ + {"936.cpg", 2, {4, 0}, {4, 0}, 0}, /* Chinese Simplified */ + {"932.cpg", 2, {5, 0}, {5, 0}, 0}, /* Japanese */ + {"852.cpg", 1, {6, 0}, {6, 0}, 0}, /* Multilingual Latin2 */ + {"1250.cpg", 1, {7, 0}, {7, 0}, 0}, /* MS Latin2 */ + {"1253.cpg", 1, {8, 0}, {8, 0}, 0}, /* MS Greek */ + {"737.cpg", 1, {9, 0}, {9, 0}, 0}, /* Greek */ + {"1254.cpg", 1, {10, 0}, {10, 0}, 0}, /* MS Turkish */ + {"857.cpg", 1, {11, 0}, {11, 0}, 0}, /* Multilingual Latin5 */ + {"1251.cpg", 1, {12, 0}, {12, 0}, 0}, /* MS Cyrillic */ + {"866.cpg", 1, {13, 0}, {13, 0}, 0}, /* Cyrillic II */ + {"1255.cpg", 1, {14, 0}, {14, 0}, 0}, /* MS Hebrew */ + {"862.cpg", 1, {15, 0}, {15, 0}, 0}, /* Hebrew */ + {"1256.cpg", 1, {16, 0}, {16, 0}, 0}, /* MS Arabic */ + {"720.cpg", 1, {17, 0}, {17, 0}, 0} /* Arabic */ }; - +#define MAX_OEMPAGES (sizeof (oemcpg_table) / sizeof (oemcpg_table[0])) +#define MAX_UNICODE_IDX 65536 /* - * The oem_default_smb_cp is the default smb codepage for English. - * It is actually codepage 850. + * The default SMB OEM codepage for English is codepage 850. */ -mts_wchar_t oem_default_smb_cp[256] = { +smb_wchar_t oem_codepage_850[256] = { 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, @@ -155,13 +130,10 @@ mts_wchar_t oem_default_smb_cp[256] = { 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 }; - - /* - * The oem_default_telnet_cp is the default telnet codepage for English. - * It is actually codepage 1252. + * The default telnet OEM codepage for English is codepage 1252. */ -mts_wchar_t oem_default_telnet_cp[256] = { +smb_wchar_t oem_codepage_1252[256] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, @@ -196,567 +168,206 @@ mts_wchar_t oem_default_telnet_cp[256] = { 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF }; - -#define MAX_OEMPAGES (sizeof (oemcp_table) / sizeof (oemcp_table[0])) -#define MAX_UNI_IDX 65536 - - - -/* - * oem_codepage_bytesperchar - * - * This function returns the max bytes per oem char for the specified - * oem table. This basically shows if the oem codepage is single or - * double bytes. - */ -static unsigned int -oem_codepage_bytesperchar(unsigned int cpid) -{ - if (cpid >= MAX_OEMPAGES) - return (0); - else - return (oemcp_table[cpid].bytesperchar); -} - - +static oempage_t *oem_get_oempage(uint32_t); +static oempage_t *oem_get_ucspage(uint32_t); +static void oem_codepage_init(uint32_t); +static void oem_codepage_setup(uint32_t); /* - * oem_get_codepage_path + * Convert a unicode string to an oem string. * - * This function will get the codepage path. - */ -const char * -oem_get_codepage_path(void) -{ -#ifdef PBSHORTCUT /* */ - const char *path = getenv("codepage.oem.directory"); - if (path == 0) - return ("/"); - else - return (path); -#else /* PBSHORTCUT */ - return ("/"); -#endif /* PBSHORTCUT */ -} - -/* - * oem_codepage_init + * The conversion will stop at the end of the unicode string + * or when (nbytes - 1) oem characters have been stored. * - * This function will init oem page via the cpid of the oem table. - * The function oem_codepage_free must be called when the oempage is - * no longer needed to free up the allocated memory. If the codepage is - * successfully initialized, zero will be the return value; otherwise - * -1 will be the return value. - */ -int -oem_codepage_init(unsigned int cpid) -{ -#ifndef _KERNEL - FILE *fp; - static mutex_t mutex; - char buf[32]; - char filePath[100]; -#endif /* _KERNEL */ - unsigned int max_oem_index; - const char *codepagePath = oem_get_codepage_path(); - mts_wchar_t *default_oem_cp = 0; - oem_codepage_t *oemcp; - - /* - * The OEM codepages 850 and 1252 are stored in kernel; therefore, - * no need for codepagePath to be defined to work. - */ - if (cpid >= MAX_OEMPAGES || - (codepagePath == 0 && - cpid != oem_default_smb_cpid && cpid != oem_default_telnet_cpid)) - return (-1); - - max_oem_index = 1 << oem_codepage_bytesperchar(cpid) * 8; - /* - * Use mutex so no two same index can be initialize - * at the same time. - */ -#ifndef _KERNEL - (void) mutex_lock(&mutex); -#endif /* _KERNEL */ - - oemcp = &oemcp_table[cpid]; - if (oemcp->valid) { - oemcp->valid++; -#ifndef _KERNEL - (void) mutex_unlock(&mutex); -#endif /* _KERNEL */ - return (0); - } - - oemcp->oempage.value = - MEM_ZALLOC("oem", max_oem_index * sizeof (mts_wchar_t)); - if (oemcp->oempage.value == 0) { -#ifndef _KERNEL - (void) mutex_unlock(&mutex); -#endif /* _KERNEL */ - return (-1); - } - - oemcp->unicodepage.value = - MEM_ZALLOC("oem", MAX_UNI_IDX * sizeof (mts_wchar_t)); - if (oemcp->unicodepage.value == 0) { - MEM_FREE("oem", oemcp->oempage.value); - oemcp->oempage.value = 0; -#ifndef _KERNEL - (void) mutex_unlock(&mutex); -#endif /* _KERNEL */ - return (-1); - } - - /* - * The default English page is stored in kernel. - * Therefore, no need to go to codepage files. - */ -#ifndef _KERNEL - if (cpid == oem_default_smb_cpid) - default_oem_cp = oem_default_smb_cp; - else if (cpid == oem_default_telnet_cpid) - default_oem_cp = oem_default_telnet_cp; - else - default_oem_cp = 0; -#else /* _KERNEL */ - default_oem_cp = oem_default_smb_cp; -#endif /* _KERNEL */ - - if (default_oem_cp) { - int i; - - for (i = 0; i < max_oem_index; i++) { - oemcp->oempage.value[i] = default_oem_cp[i]; - oemcp->unicodepage.value[default_oem_cp[i]] = - (mts_wchar_t)i; - } -#ifdef _KERNEL - } - /* - * XXX This doesn't seem right. How do we handle the situation - * where default_oem_cp == 0 in the kernel? - * Is this a PBSHORTCUT? - */ -#else - } else { - - /* - * The codepage is not one of the default that stores - * in the include - * file; therefore, we need to read from the file. - */ - (void) snprintf(filePath, sizeof (filePath), - "%s/%s", codepagePath, oemcp->filename); - fp = fopen(filePath, "r"); - - if (fp == 0) { - MEM_FREE("oem", oemcp->oempage.value); - MEM_FREE("oem", oemcp->unicodepage.value); -#ifndef _KERNEL - (void) mutex_unlock(&mutex); -#endif /* _KERNEL */ - return (-1); - } - - while (fgets(buf, 32, fp) != 0) { - char *endptr; - unsigned int oemval, unival; - - endptr = (char *)strchr(buf, ' '); - if (endptr == 0) { - continue; - } - - oemval = strtol(buf, &endptr, 0); - unival = strtol(endptr+1, 0, 0); - - if (oemval >= max_oem_index || unival >= MAX_UNI_IDX) { - continue; - } - - oemcp->oempage.value[oemval] = unival; - oemcp->unicodepage.value[unival] = oemval; - } - (void) fclose(fp); - } -#endif /* _KERNEL */ - - oemcp->valid = 1; -#ifndef _KERNEL - (void) mutex_unlock(&mutex); -#endif /* _KERNEL */ - return (0); -} - - - - -/* - * oem_codepage_free - * - * This function will clear the valid bit and free the memory - * allocated to the oem/unipage by oem_codepage_init if the ref count - * is zero. - */ -void -oem_codepage_free(unsigned int cpid) -{ - oem_codepage_t *oemcp; - - if (cpid >= MAX_OEMPAGES || !oemcp_table[cpid].valid) - return; - - oemcp = &oemcp_table[cpid]; - oemcp->valid--; - - if (oemcp->ref != 0 || oemcp->valid != 0) - return; - - if (oemcp->oempage.value != 0) { - MEM_FREE("oem", oemcp->oempage.value); - oemcp->oempage.value = 0; - } - - if (oemcp->unicodepage.value != 0) { - MEM_FREE("oem", oemcp->unicodepage.value); - oemcp->unicodepage.value = 0; - } -} - - - -/* - * oem_get_oempage - * - * This function will return the current oempage and increment - * the ref count. The function oem_release_page should always - * be called when finish using the oempage to decrement the - * ref count. - */ -static oempage_t * -oem_get_oempage(unsigned int cpid) -{ - if (cpid >= MAX_OEMPAGES) - return (0); - - if (oemcp_table[cpid].valid) { - oemcp_table[cpid].ref++; - return (&oemcp_table[cpid].oempage); - } - return (0); -} - - - -/* - * oem_get_unipage - * - * This function will return the current unipage and increment - * the ref count. The function oem_release_page should always - * be called when finish using the unipage to decrement the - * ref count. - */ -static oempage_t * -oem_get_unipage(unsigned int cpid) -{ - if (cpid >= MAX_OEMPAGES) - return (0); - - if (oemcp_table[cpid].valid) { - oemcp_table[cpid].ref++; - return (&oemcp_table[cpid].unicodepage); - } - return (0); -} - - - -/* - * oem_release_page - * - * This function will decrement the ref count and check the valid - * bit. It will free the memory allocated for the pages - * if the - * valid bit is not set, ref count is zero and the page is not - * already freed. - */ -static void -oem_release_page(oempage_t *page) -{ - oem_codepage_t *oemcp = &oemcp_table[page->cpid]; - - page = 0; - - if (oemcp->ref > 0) - oemcp->ref--; - - if (oemcp->ref != 0 || oemcp->valid) - return; - - if (oemcp->oempage.value != 0) { - MEM_FREE("oem", oemcp->oempage.value); - oemcp->oempage.value = 0; - } - - if (oemcp->unicodepage.value != 0) { - MEM_FREE("oem", oemcp->unicodepage.value); - oemcp->unicodepage.value = 0; - } -} - - - -/* - * unicodestooems - * - * Convert unicode string to oem string. The function will stop - * converting the unicode string when size nbytes - 1 is reached - * or when there is not enough room to store another unicode. - * If the function is called when the codepage is not initialized - * or when the codepage initialize failed, it will return 0. - * Otherwise, the total # of the converted unicode is returned. + * The number of converted unicode characters is returned, + * or 0 on error. */ size_t -unicodestooems( - char *oemstring, - const mts_wchar_t *unicodestring, - size_t nbytes, - unsigned int cpid) +ucstooem(char *oem, const smb_wchar_t *ucs, size_t nbytes, uint32_t cpid) { - oempage_t *unipage; - unsigned int count = 0; - mts_wchar_t oemchar; - - if (cpid >= MAX_OEMPAGES) - return (0); + oempage_t *ucspage; + uint32_t count = 0; + smb_wchar_t oemchar; - if (unicodestring == 0 || oemstring == 0) + if (ucs == NULL || oem == NULL) return (0); - if ((unipage = oem_get_unipage(cpid)) == 0) + if ((ucspage = oem_get_ucspage(cpid)) == NULL) return (0); - while ((oemchar = unipage->value[*unicodestring]) != 0) { + while (nbytes != 0 && (oemchar = ucspage->value[*ucs]) != 0) { if (oemchar & 0xff00 && nbytes >= MTS_MB_CHAR_MAX) { - *oemstring++ = oemchar >> 8; - *oemstring++ = (char)oemchar; + *oem++ = oemchar >> 8; + *oem++ = (char)oemchar; nbytes -= 2; } else if (nbytes > 1) { - *oemstring++ = (char)oemchar; + *oem++ = (char)oemchar; nbytes--; - } else + } else { break; + } count++; - unicodestring++; + ucs++; } - *oemstring = 0; - - oem_release_page(unipage); - + *oem = '\0'; return (count); } - - /* - * oemstounicodes + * Convert an oem string to a unicode string. * - * Convert oem string to unicode string. The function will stop - * converting the oem string when unicodestring len reaches nwchars - 1. - * or when there is not enough room to store another oem char. - * If the function is called when the codepage is not initialized - * or when the codepage initialize failed, it will return 0. - * Otherwise, the total # of the converted oem chars is returned. - * The oem char can be either 1 or 2 bytes. + * The conversion will stop at the end of the oem string or + * when nwchars - 1 have been converted. + * + * The number of converted oem chars is returned, or 0 on error. + * An oem char may be either 1 or 2 bytes. */ size_t -oemstounicodes( - mts_wchar_t *unicodestring, - const char *oemstring, - size_t nwchars, - unsigned int cpid) +oemtoucs(smb_wchar_t *ucs, const char *oem, size_t nwchars, uint32_t cpid) { - oempage_t *oempage; - size_t count = nwchars; - mts_wchar_t oemchar; + oempage_t *oempage; + size_t count = nwchars; + smb_wchar_t oemchar; - if (cpid >= MAX_OEMPAGES) + if (ucs == NULL || oem == NULL) return (0); - if (unicodestring == 0 || oemstring == 0) + if ((oempage = oem_get_oempage(cpid)) == NULL) return (0); - if ((oempage = oem_get_oempage(cpid)) == 0) - return (0); - - while ((oemchar = (mts_wchar_t)*oemstring++ & 0xff) != 0) { + while ((oemchar = (smb_wchar_t)*oem++ & 0xff) != 0) { /* - * Cannot find one byte oemchar in table. Must be - * a lead byte. Try two bytes. + * Cannot find one byte oemchar in table. + * Must be a lead byte. Try two bytes. */ - if ((oempage->value[oemchar] == 0) && (oemchar != 0)) { - oemchar = oemchar << 8 | (*oemstring++ & 0xff); + oemchar = oemchar << 8 | (*oem++ & 0xff); if (oempage->value[oemchar] == 0) { - *unicodestring = 0; + *ucs = 0; break; } } #ifdef _BIG_ENDIAN - *unicodestring = LE_IN16(&oempage->value[oemchar]); + *ucs = LE_IN16(&oempage->value[oemchar]); #else - *unicodestring = oempage->value[oemchar]; + *ucs = oempage->value[oemchar]; #endif count--; - unicodestring++; + ucs++; } - *unicodestring = 0; - - oem_release_page(oempage); - + *ucs = 0; return (nwchars - count); } /* - * oem_get_lang_table - * - * This function returns a pointer to the language table. + * Get a pointer to the oem page for the specific codepage id. */ -language * -oem_get_lang_table(void) +static oempage_t * +oem_get_oempage(uint32_t cpid) { - return (lang_table); + if (cpid >= MAX_OEMPAGES) + return (NULL); + + if (!oemcpg_table[cpid].valid) { + oem_codepage_init(cpid); + + if (!oemcpg_table[cpid].valid) + return (NULL); + } + + return (&oemcpg_table[cpid].oempage); } /* - * oem_no_of_languages - * - * This function returns total languages support in the system. + * Get a pointer to the ucs page for the specific codepage id. */ -int -oem_no_of_languages(void) +static oempage_t * +oem_get_ucspage(uint32_t cpid) { - return (sizeof (lang_table)/sizeof (lang_table[0])); -} + if (cpid >= MAX_OEMPAGES) + return (NULL); + if (!oemcpg_table[cpid].valid) { + oem_codepage_init(cpid); + + if (!oemcpg_table[cpid].valid) + return (NULL); + } + + return (&oemcpg_table[cpid].ucspage); +} -#ifndef _KERNEL -#if 1 /* - * TESTING Functions + * Initialize the oem page in the oem table. */ -void -oemcp_print(unsigned int cpid) +static void +oem_codepage_init(uint32_t cpid) { - unsigned int bytesperchar, max_index, i; - oempage_t *oempage, *unipage; - unsigned int counter = 0; +#ifndef _KERNEL + static mutex_t mutex; - if (cpid >= MAX_OEMPAGES) { - (void) printf("oemcp cpid %d is invalid\n", cpid); - return; - } + (void) mutex_lock(&mutex); + oem_codepage_setup(cpid); + (void) mutex_unlock(&mutex); +#else + static kmutex_t mutex; - if ((oempage = oem_get_oempage(cpid)) == 0) { - (void) printf("oemcp of cpid %d is invalid\n", cpid); - return; - } + mutex_enter(&mutex); + oem_codepage_setup(cpid); + mutex_exit(&mutex); +#endif /* _KERNEL */ +} - if ((unipage = oem_get_unipage(cpid)) == 0) { - (void) printf("unicp of cpid %d is invalid\n", cpid); +static void +oem_codepage_setup(uint32_t cpid) +{ + smb_wchar_t *default_oem_cp; + oem_codepage_t *oemcpg; + uint32_t bytesperchar; + uint32_t max_oem_index; + int i; + + switch (cpid) { + case OEM_CPG_850: + default_oem_cp = oem_codepage_850; + break; + case OEM_CPG_1252: + default_oem_cp = oem_codepage_1252; + default: return; } - if ((bytesperchar = oem_codepage_bytesperchar(cpid)) == 0) { - (void) printf("bytesperchar of cpid %d is not correct\n", cpid); + oemcpg = &oemcpg_table[cpid]; + if (oemcpg->valid) return; - } - - max_index = 1 << bytesperchar * 8; - - (void) printf("OEMPAGE:\n"); - for (i = 0; i < max_index; i++) { - if ((counter + 1) % 4 == 0 && - (oempage->value[i] != 0 || i == 0)) { - (void) printf("%x %x\n", i, oempage->value[i]); - counter++; - } else if (oempage->value[i] != 0 || i == 0) { - (void) printf("%x %x, ", i, oempage->value[i]); - counter++; - } - } - counter = 0; - (void) printf("\n\nUNIPAGE:\n"); - for (i = 0; i < 65536; i++) { - if ((counter + 1) % 8 == 0 && - (unipage->value[i] != 0 || i == 0)) { - (void) printf("%x %x\n", i, unipage->value[i]); - counter++; - } else if (unipage->value[i] != 0 || i == 0) { - (void) printf("%x %x, ", i, unipage->value[i]); - counter++; - } - } - (void) printf("\n"); - oem_release_page(oempage); - oem_release_page(unipage); -} - - - -void -oemstringtest(unsigned int cpid) -{ - unsigned char *c, *cbuf; - unsigned char cbuf1[100] = {0xfe, 0xfd, 0xf2, 0xe9, - 0x63, 0xce, 0xdb, 0x8c, 0x9c, 0x21, 0}; - unsigned char cbuf2[100] = {0xfe, 0xfc, 0x63, 0x81, 0x42, - 0x91, 0x40, 0x24, 0xff, 0x49}; - mts_wchar_t buf[100], *wc; - - if (cpid == 1) - cbuf = cbuf1; - else if (cpid == 2) - cbuf = cbuf2; /* - * Before oem->uni conversion. + * max_oem_index will be 256 or 65536 dependent + * on the OEM codepage. */ - (void) printf("Before oem->uni conversion: "); - for (c = cbuf; *c != 0; c++) - (void) printf("%x ", *c); - (void) printf("\n"); + bytesperchar = oemcpg_table[cpid].bytesperchar; + max_oem_index = 1 << (bytesperchar * 8); - /* - * oem->uni conversion - */ - (void) oemstounicodes(buf, (const char *)cbuf, 100, cpid); + oemcpg->oempage.value = + MEM_ZALLOC("oem", max_oem_index * sizeof (smb_wchar_t)); + if (oemcpg->oempage.value == NULL) + return; - /* - * After oem->uni conversion. - */ - (void) printf("After oem->uni conversion: "); - for (wc = buf; *wc != 0; wc++) - (void) printf("%x ", *wc); - (void) printf("\n"); + oemcpg->ucspage.value = + MEM_ZALLOC("oem", MAX_UNICODE_IDX * sizeof (smb_wchar_t)); + if (oemcpg->ucspage.value == NULL) { + MEM_FREE("oem", oemcpg->oempage.value); + oemcpg->oempage.value = NULL; + return; + } - /* - * uni->oem conversion - */ - (void) unicodestooems((char *)cbuf, buf, 100, cpid); + for (i = 0; i < max_oem_index; i++) { + oemcpg->oempage.value[i] = default_oem_cp[i]; + oemcpg->ucspage.value[default_oem_cp[i]] = (smb_wchar_t)i; + } - /* - * After uni->oem conversion. - */ - (void) printf("After uni->oem conversion: "); - for (c = cbuf; *c != 0; c++) - (void) printf("%x ", *c); - (void) printf("\n"); + oemcpg->valid = B_TRUE; } -#endif -#endif /* _KERNEL */ |