2850 lines
106 KiB
C
2850 lines
106 KiB
C
/*++
|
|
|
|
Copyright (c) 1991-2000, Microsoft Corporation All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
nls.h
|
|
|
|
Abstract:
|
|
|
|
This file contains the header information shared by all of the modules
|
|
of NLS.
|
|
|
|
Revision History:
|
|
|
|
05-31-91 JulieB Created.
|
|
03-07-00 lguindon Began Geo API port
|
|
|
|
--*/
|
|
|
|
|
|
|
|
#ifndef _NLS_
|
|
#define _NLS_
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RTL Includes Files.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef RC_INVOKED
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#endif
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Include Files.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <base.h>
|
|
#include <ntcsrdll.h>
|
|
#include <ntcsrsrv.h>
|
|
#include <basemsg.h>
|
|
#include <windows.h>
|
|
#include <winnlsp.h>
|
|
#include <winerror.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Constant Declarations.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Code Page Ranges.
|
|
//
|
|
#define NLS_CP_TABLE_RANGE 0 // begin code page Table range
|
|
#define NLS_CP_DLL_RANGE 50000 // begin code page DLL range
|
|
#define NLS_CP_ALGORITHM_RANGE 60000 // begin code page Algorithm range
|
|
|
|
|
|
//
|
|
// Table Values.
|
|
//
|
|
#define MB_TBL_SIZE 256 // size of MB tables
|
|
#define GLYPH_TBL_SIZE 256 // size of GLYPH tables
|
|
#define DBCS_TBL_SIZE 256 // size of DBCS tables
|
|
|
|
#define CP_TBL_SIZE 197 // size of code page hash table (prime #)
|
|
#define LOC_TBL_SIZE 197 // size of locale hash table (prime #)
|
|
|
|
|
|
//
|
|
// String Constants.
|
|
//
|
|
#define MAX_PATH_LEN 512 // max length of path name
|
|
#define MAX_STRING_LEN 128 // max string length for static buffer
|
|
#define MAX_SMALL_BUF_LEN 64 // max length of small buffer
|
|
|
|
#define MAX_COMPOSITE 5 // max number of composite characters
|
|
#define MAX_EXPANSION 3 // max number of expansion characters
|
|
#define MAX_TBL_EXPANSION 2 // max expansion chars per table entry
|
|
#define MAX_WEIGHTS 9 // max number of words in all weights
|
|
|
|
#define MAX_SECURITY_BUF_LEN 128 // max length of security descriptor buffer
|
|
|
|
// length of sortkey static buffer
|
|
#define MAX_SORTKEY_BUF_LEN ( MAX_SMALL_BUF_LEN * MAX_EXPANSION * MAX_WEIGHTS )
|
|
|
|
|
|
#define MAX_FONTSIGNATURE 16 // length of font signature string
|
|
|
|
// SetLocaleInfo string constants
|
|
#define MAX_SLIST 4 // max wide chars in sList
|
|
#define MAX_IMEASURE 2 // max wide chars in iMeasure
|
|
#define MAX_SDECIMAL 4 // max wide chars in sDecimal
|
|
#define MAX_STHOUSAND 4 // max wide chars in sThousand
|
|
#define MAX_SGROUPING 10 // max wide chars in sGrouping
|
|
#define MAX_IDIGITS 2 // max wide chars in iDigits
|
|
#define MAX_ILZERO 2 // max wide chars in iLZero
|
|
#define MAX_INEGNUMBER 2 // max wide chars in iNegNumber
|
|
#define MAX_SNATIVEDIGITS 11 // max wide chars in sNativeDigits
|
|
#define MAX_IDIGITSUBST 2 // max wide chars in iDigitSubstitution
|
|
#define MAX_SCURRENCY 6 // max wide chars in sCurrency
|
|
#define MAX_SMONDECSEP 4 // max wide chars in sMonDecimalSep
|
|
#define MAX_SMONTHOUSEP 4 // max wide chars in sMonThousandSep
|
|
#define MAX_SMONGROUPING 10 // max wide chars in sMonGrouping
|
|
#define MAX_ICURRENCY 2 // max wide chars in iCurrency
|
|
#define MAX_SPOSSIGN 5 // max wide chars in sPositiveSign
|
|
#define MAX_SNEGSIGN 5 // max wide chars in sNegativeSign
|
|
#define MAX_STIMEFORMAT MAX_REG_VAL_SIZE // max wide chars in sTimeFormat
|
|
#define MAX_STIME 4 // max wide chars in sTime
|
|
#define MAX_ITIME 2 // max wide chars in iTime
|
|
#define MAX_S1159 15 // max wide chars in s1159
|
|
#define MAX_S2359 15 // max wide chars in s2359
|
|
#define MAX_SSHORTDATE MAX_REG_VAL_SIZE // max wide chars in sShortDate
|
|
#define MAX_SDATE 4 // max wide chars in sDate
|
|
#define MAX_SYEARMONTH MAX_REG_VAL_SIZE // max wide chars in sYearMonth
|
|
#define MAX_SLONGDATE MAX_REG_VAL_SIZE // max wide chars in sLongDate
|
|
#define MAX_ICALTYPE 3 // max wide chars in iCalendarType
|
|
#define MAX_IFIRSTDAY 2 // max wide chars in iFirstDayOfWeek
|
|
#define MAX_IFIRSTWEEK 2 // max wide chars in iFirstWeekOfYear
|
|
|
|
//
|
|
// NOTE: If any of the MAX_VALUE_ values change, then the corresponding
|
|
// MAX_CHAR_ value must also change.
|
|
//
|
|
#define MAX_VALUE_IMEASURE 1 // max value for iMeasure
|
|
#define MAX_VALUE_IDIGITS 9 // max value for iDigits
|
|
#define MAX_VALUE_ILZERO 1 // max value for iLZero
|
|
#define MAX_VALUE_INEGNUMBER 4 // max value for iNegNumber
|
|
#define MAX_VALUE_IDIGITSUBST 2 // max value for iDigitSubstitution
|
|
#define MAX_VALUE_ICURRDIGITS 99 // max value for iCurrDigits
|
|
#define MAX_VALUE_ICURRENCY 3 // max value for iCurrency
|
|
#define MAX_VALUE_INEGCURR 15 // max value for iNegCurr
|
|
#define MAX_VALUE_ITIME 1 // max value for iTime
|
|
#define MAX_VALUE_IFIRSTDAY 6 // max value for iFirstDayOfWeek
|
|
#define MAX_VALUE_IFIRSTWEEK 2 // max value for iFirstWeekOfYear
|
|
|
|
#define MAX_CHAR_IMEASURE L'1' // max char value for iMeasure
|
|
#define MAX_CHAR_IDIGITS L'9' // max char value for iDigits
|
|
#define MAX_CHAR_ILZERO L'1' // max char value for iLZero
|
|
#define MAX_CHAR_INEGNUMBER L'4' // max char value for iNegNumber
|
|
#define MAX_CHAR_IDIGITSUBST L'2' // max char value for iDigitSubstitution
|
|
#define MAX_CHAR_ICURRENCY L'3' // max char value for iCurrency
|
|
#define MAX_CHAR_ITIME L'1' // max char value for iTime
|
|
#define MAX_CHAR_IFIRSTDAY L'6' // max char value for iFirstDayOfWeek
|
|
#define MAX_CHAR_IFIRSTWEEK L'2' // max char value for iFirstWeekOfYear
|
|
|
|
|
|
// SetCalendarInfo string constants
|
|
#define MAX_ITWODIGITYEAR 5 // max wide chars in TwoDigitYearMax
|
|
|
|
|
|
#define NLS_CHAR_ZERO L'0' // digit 0 character
|
|
#define NLS_CHAR_ONE L'1' // digit 1 character
|
|
#define NLS_CHAR_NINE L'9' // digit 9 character
|
|
#define NLS_CHAR_SEMICOLON L';' // semicolon character
|
|
#define NLS_CHAR_PERIOD L'.' // period character
|
|
#define NLS_CHAR_QUOTE L'\'' // single quote character
|
|
#define NLS_CHAR_SPACE L' ' // space character
|
|
#define NLS_CHAR_HYPHEN L'-' // hyphen/minus character
|
|
#define NLS_CHAR_OPEN_PAREN L'(' // open parenthesis character
|
|
#define NLS_CHAR_CLOSE_PAREN L')' // close parenthesis character
|
|
|
|
#define MAX_BLANKS 1 // max successive blanks in number string
|
|
|
|
|
|
//
|
|
// RC File Constants.
|
|
//
|
|
#define NLS_SORT_RES_PREFIX L"SORT_"
|
|
#define NLS_SORT_RES_DEFAULT L"SORT_00000000"
|
|
|
|
|
|
//
|
|
// Size of stack buffer for PKEY_VALUE_FULL_INFORMATION pointer.
|
|
//
|
|
#define MAX_KEY_VALUE_FULLINFO \
|
|
( FIELD_OFFSET( KEY_VALUE_FULL_INFORMATION, Name ) + MAX_PATH_LEN )
|
|
|
|
|
|
//
|
|
// Paths to registry keys.
|
|
//
|
|
#define NLS_HKLM_SYSTEM L"\\Registry\\Machine\\System\\CurrentControlSet\\Control"
|
|
#define NLS_HKLM_SOFTWARE L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion"
|
|
|
|
|
|
//
|
|
// Names of Registry Key Entries.
|
|
//
|
|
#define NLS_CODEPAGE_KEY L"\\Nls\\Codepage"
|
|
#define NLS_LANGUAGE_GROUPS_KEY L"\\Nls\\Language Groups"
|
|
#define NLS_LOCALE_KEY L"\\Nls\\Locale"
|
|
#define NLS_ALT_SORTS_KEY L"\\Nls\\Locale\\Alternate Sorts"
|
|
#define NLS_MUILANG_KEY L"\\Nls\\MUILanguages"
|
|
|
|
//
|
|
// User Info.
|
|
//
|
|
#define NLS_CTRL_PANEL_KEY L"Control Panel\\International"
|
|
#define NLS_CALENDARS_KEY L"Control Panel\\International\\Calendars"
|
|
#define NLS_TWO_DIGIT_YEAR_KEY L"Control Panel\\International\\Calendars\\TwoDigitYearMax"
|
|
#define NLS_POLICY_TWO_DIGIT_YEAR_KEY L"Software\\Policies\\Microsoft\\Control Panel\\International\\Calendars\\TwoDigitYearMax"
|
|
|
|
//
|
|
// GEO Registry Keys.
|
|
//
|
|
#define GEO_REG_KEY L"Control Panel\\International\\Geo"
|
|
#define GEO_REG_NATION L"Nation"
|
|
#define GEO_REG_REGION L"Region"
|
|
#define GEO_REG_STATE L"State"
|
|
#define GEO_REG_CITY L"City"
|
|
|
|
//
|
|
// Name of NLS Object Directory.
|
|
// Must create this in order to have "create access" on the fly.
|
|
//
|
|
#define NLS_OBJECT_DIRECTORY_NAME L"\\NLS"
|
|
|
|
//
|
|
// Default values.
|
|
//
|
|
#define NLS_DEFAULT_ACP 1252
|
|
#define NLS_DEFAULT_OEMCP 437
|
|
#define NLS_DEFAULT_MACCP 10000
|
|
#define NLS_DEFAULT_LANGID 0x0409
|
|
#define NLS_DEFAULT_UILANG 0x0409
|
|
|
|
|
|
//
|
|
// DLL Translation Function Names.
|
|
//
|
|
// **** Must be an ANSI string for GetProcAddress call. ****
|
|
//
|
|
#define NLS_CP_DLL_PROC_NAME "NlsDllCodePageTranslation"
|
|
|
|
|
|
//
|
|
// Flag Constants.
|
|
//
|
|
#define MSB_FLAG 0x80000000 // most significant bit set
|
|
|
|
|
|
//
|
|
// Table Header Constants (all sizes in WORDS).
|
|
//
|
|
#define CP_HEADER 1 // size of CP Info table header
|
|
#define MB_HEADER 1 // size of MB table header
|
|
#define GLYPH_HEADER 1 // size of GLYPH table header
|
|
#define DBCS_HEADER 1 // size of DBCS table header
|
|
#define WC_HEADER 1 // size of WC table header
|
|
#define CT_HEADER 2 // size of CTYPE table header
|
|
#define LANG_HDR_OFFSET 0 // offset to LANGUAGE file header
|
|
#define LANG_HEADER 1 // size of language file header
|
|
#define UP_HEADER 1 // size of UPPERCASE table header
|
|
#define LO_HEADER 1 // size of LOWERCASE table header
|
|
#define L_EXCEPT_HDR_OFFSET 2 // offset to LANGUAGE EXCEPTION header
|
|
#define AD_HEADER 1 // size of ASCIIDIGITS table header
|
|
#define CZ_HEADER 1 // size of FOLDCZONE table header
|
|
#define HG_HEADER 1 // size of HIRAGANA table header
|
|
#define KK_HEADER 1 // size of KATAKANA table header
|
|
#define HW_HEADER 1 // size of HALF WIDTH table header
|
|
#define FW_HEADER 1 // size of FULL WIDTH table header
|
|
#define TR_HEADER 1 // size of TRADITIONAL CHINESE table header
|
|
#define SP_HEADER 1 // size of SIMPLIFIED CHINESE table header
|
|
#define PC_HEADER 1 // size of PRECOMPOSED table header
|
|
#define CO_HEADER 3 // size of COMPOSITE table header
|
|
#define SORTKEY_HEADER 2 // size of SORTKEY table header
|
|
#define REV_DW_HEADER 2 // size of REVERSE DW table header
|
|
#define DBL_COMP_HEADER 2 // size of DOUBLE COMPRESS table header
|
|
#define IDEO_LCID_HEADER 2 // size of IDEOGRAPH LCID table header
|
|
#define EXPAND_HEADER 2 // size of EXPANSION table header
|
|
#define COMPRESS_HDR_OFFSET 2 // offset to COMPRESSION header
|
|
#define EXCEPT_HDR_OFFSET 2 // offset to EXCEPTION header
|
|
#define MULTI_WT_HEADER 1 // size of MULTIPLE WEIGHTS table header
|
|
#define JAMO_INDEX_HEADER 1 // size of Jamo Index table header
|
|
#define JAMO_COMPOSITION_HEADER 1 // size of Jamo Composition state machine table hader
|
|
|
|
|
|
//
|
|
// Invalid Flag Checks.
|
|
//
|
|
#define MB_INVALID_FLAG (~(MB_PRECOMPOSED | MB_COMPOSITE | \
|
|
MB_USEGLYPHCHARS | MB_ERR_INVALID_CHARS))
|
|
#define WC_INVALID_FLAG (~(WC_NO_BEST_FIT_CHARS | WC_COMPOSITECHECK | \
|
|
WC_DISCARDNS | WC_SEPCHARS | WC_DEFAULTCHAR))
|
|
#define CS_INVALID_FLAG (~(NORM_IGNORECASE | NORM_IGNORENONSPACE | \
|
|
NORM_IGNORESYMBOLS | NORM_IGNOREKANATYPE | \
|
|
NORM_IGNOREWIDTH | SORT_STRINGSORT | \
|
|
LOCALE_USE_CP_ACP | NORM_STOP_ON_NULL))
|
|
#define FS_INVALID_FLAG (~(MAP_FOLDCZONE | MAP_PRECOMPOSED | \
|
|
MAP_COMPOSITE | MAP_FOLDDIGITS))
|
|
#define LCMS_INVALID_FLAG (~(LCMAP_LOWERCASE | LCMAP_UPPERCASE | \
|
|
LCMAP_LINGUISTIC_CASING | \
|
|
LCMAP_SORTKEY | LCMAP_BYTEREV | \
|
|
LCMAP_HIRAGANA | LCMAP_KATAKANA | \
|
|
LCMAP_HALFWIDTH | LCMAP_FULLWIDTH | \
|
|
LCMAP_TRADITIONAL_CHINESE | \
|
|
LCMAP_SIMPLIFIED_CHINESE | \
|
|
NORM_IGNORECASE | NORM_IGNORENONSPACE | \
|
|
NORM_IGNORESYMBOLS | NORM_IGNOREKANATYPE | \
|
|
NORM_IGNOREWIDTH | SORT_STRINGSORT | \
|
|
LOCALE_USE_CP_ACP))
|
|
#define GTF_INVALID_FLAG (~(LOCALE_NOUSEROVERRIDE | LOCALE_USE_CP_ACP | \
|
|
TIME_NOMINUTESORSECONDS | \
|
|
TIME_NOSECONDS | TIME_NOTIMEMARKER | \
|
|
TIME_FORCE24HOURFORMAT))
|
|
#define GDF_INVALID_FLAG (~(LOCALE_NOUSEROVERRIDE | LOCALE_USE_CP_ACP | \
|
|
DATE_LTRREADING | DATE_RTLREADING | \
|
|
DATE_SHORTDATE | DATE_LONGDATE | \
|
|
DATE_YEARMONTH | DATE_USE_ALT_CALENDAR |\
|
|
DATE_ADDHIJRIDATETEMP))
|
|
#define IVLG_INVALID_FLAG (~(LGRPID_INSTALLED | LGRPID_SUPPORTED))
|
|
#define IVL_INVALID_FLAG (~(LCID_INSTALLED | LCID_SUPPORTED))
|
|
#define GNF_INVALID_FLAG (~(LOCALE_NOUSEROVERRIDE | LOCALE_USE_CP_ACP))
|
|
#define GCF_INVALID_FLAG (~(LOCALE_NOUSEROVERRIDE | LOCALE_USE_CP_ACP))
|
|
#define ESLG_INVALID_FLAG (~(LGRPID_INSTALLED | LGRPID_SUPPORTED))
|
|
#define ESL_INVALID_FLAG (~(LCID_INSTALLED | LCID_SUPPORTED | \
|
|
LCID_ALTERNATE_SORTS))
|
|
#define ESCP_INVALID_FLAG (~(CP_INSTALLED | CP_SUPPORTED))
|
|
#define ETF_INVALID_FLAG (~(LOCALE_USE_CP_ACP))
|
|
|
|
|
|
//
|
|
// Single Flags (only one at a time is valid).
|
|
//
|
|
#define LCMS1_SINGLE_FLAG (LCMAP_LOWERCASE | LCMAP_UPPERCASE | \
|
|
LCMAP_SORTKEY)
|
|
#define LCMS2_SINGLE_FLAG (LCMAP_HIRAGANA | LCMAP_KATAKANA | \
|
|
LCMAP_SORTKEY)
|
|
#define LCMS3_SINGLE_FLAG (LCMAP_HALFWIDTH | LCMAP_FULLWIDTH | \
|
|
LCMAP_SORTKEY)
|
|
#define LCMS4_SINGLE_FLAG (LCMAP_TRADITIONAL_CHINESE | \
|
|
LCMAP_SIMPLIFIED_CHINESE | \
|
|
LCMAP_SORTKEY)
|
|
#define GDF_SINGLE_FLAG (DATE_LTRREADING | DATE_RTLREADING)
|
|
#define IVLG_SINGLE_FLAG (LGRPID_INSTALLED | LGRPID_SUPPORTED)
|
|
#define IVL_SINGLE_FLAG (LCID_INSTALLED | LCID_SUPPORTED)
|
|
#define ESLG_SINGLE_FLAG (LGRPID_INSTALLED | LGRPID_SUPPORTED)
|
|
#define ESL_SINGLE_FLAG (LCID_INSTALLED | LCID_SUPPORTED)
|
|
#define ESCP_SINGLE_FLAG (CP_INSTALLED | CP_SUPPORTED)
|
|
|
|
|
|
//
|
|
// Flag combinations.
|
|
//
|
|
#define WC_COMPCHK_FLAGS (WC_DISCARDNS | WC_SEPCHARS | WC_DEFAULTCHAR)
|
|
#define NORM_ALL (NORM_IGNORECASE | NORM_IGNORENONSPACE | \
|
|
NORM_IGNORESYMBOLS | NORM_IGNOREKANATYPE | \
|
|
NORM_IGNOREWIDTH)
|
|
#define NORM_SORTKEY_ONLY (NORM_IGNORECASE | NORM_IGNOREKANATYPE | \
|
|
NORM_IGNOREWIDTH | SORT_STRINGSORT)
|
|
#define NORM_ALL_CASE (NORM_IGNORECASE | NORM_IGNOREKANATYPE | \
|
|
NORM_IGNOREWIDTH)
|
|
#define LCMAP_NO_NORM (LCMAP_LOWERCASE | LCMAP_UPPERCASE | \
|
|
LCMAP_HIRAGANA | LCMAP_KATAKANA | \
|
|
LCMAP_HALFWIDTH | LCMAP_FULLWIDTH | \
|
|
LCMAP_TRADITIONAL_CHINESE | \
|
|
LCMAP_SIMPLIFIED_CHINESE)
|
|
|
|
//
|
|
// Get the LCType value from an LCType.
|
|
//
|
|
#define NLS_GET_LCTYPE_VALUE(x) (x & ~(LOCALE_NOUSEROVERRIDE | \
|
|
LOCALE_USE_CP_ACP | \
|
|
LOCALE_RETURN_NUMBER))
|
|
|
|
//
|
|
// Get the CalType value from a CalType.
|
|
//
|
|
#define NLS_GET_CALTYPE_VALUE(x) (x & ~(CAL_NOUSEROVERRIDE | \
|
|
CAL_USE_CP_ACP | \
|
|
CAL_RETURN_NUMBER))
|
|
|
|
//
|
|
// Separator and Terminator Values - Sortkey String.
|
|
//
|
|
#define SORTKEY_SEPARATOR 0x01
|
|
#define SORTKEY_TERMINATOR 0x00
|
|
|
|
|
|
//
|
|
// Lowest weight values.
|
|
// Used to remove trailing DW and CW values.
|
|
//
|
|
#define MIN_DW 2
|
|
#define MIN_CW 2
|
|
|
|
|
|
//
|
|
// Bit mask values.
|
|
//
|
|
// Case Weight (CW) - 8 bits:
|
|
// bit 0 => width
|
|
// bit 1,2 => small kana, sei-on
|
|
// bit 3,4 => upper/lower case
|
|
// bit 5 => kana
|
|
// bit 6,7 => compression
|
|
//
|
|
#define COMPRESS_3_MASK 0xc0 // compress 3-to-1 or 2-to-1
|
|
#define COMPRESS_2_MASK 0x80 // compress 2-to-1
|
|
|
|
#define CASE_MASK 0x3f // zero out compression bits
|
|
|
|
#define CASE_UPPER_MASK 0xe7 // zero out case bits
|
|
#define CASE_SMALL_MASK 0xf9 // zero out small modifier bits
|
|
#define CASE_KANA_MASK 0xdf // zero out kana bit
|
|
#define CASE_WIDTH_MASK 0xfe // zero out width bit
|
|
|
|
#define SW_POSITION_MASK 0x8003 // avoid 0 or 1 in bytes of word
|
|
|
|
//
|
|
// Bit Mask Values for CompareString.
|
|
//
|
|
// NOTE: Due to intel byte reversal, the DWORD value is backwards:
|
|
// CW DW SM AW
|
|
//
|
|
// Case Weight (CW) - 8 bits:
|
|
// bit 0 => width
|
|
// bit 4 => case
|
|
// bit 5 => kana
|
|
// bit 6,7 => compression
|
|
//
|
|
#define CMP_MASKOFF_NONE 0xffffffff
|
|
#define CMP_MASKOFF_DW 0xff00ffff
|
|
#define CMP_MASKOFF_CW 0xe7ffffff
|
|
#define CMP_MASKOFF_DW_CW 0xe700ffff
|
|
#define CMP_MASKOFF_COMPRESSION 0x3fffffff
|
|
|
|
#define CMP_MASKOFF_KANA 0xdfffffff
|
|
#define CMP_MASKOFF_WIDTH 0xfeffffff
|
|
#define CMP_MASKOFF_KANA_WIDTH 0xdeffffff
|
|
|
|
//
|
|
// Masks to isolate the various bits in the case weight.
|
|
//
|
|
// NOTE: Bit 2 must always equal 1 to avoid getting a byte value
|
|
// of either 0 or 1.
|
|
//
|
|
#define CASE_XW_MASK 0xc4
|
|
|
|
#define ISOLATE_SMALL ( (BYTE)((~CASE_SMALL_MASK) | CASE_XW_MASK) )
|
|
#define ISOLATE_KANA ( (BYTE)((~CASE_KANA_MASK) | CASE_XW_MASK) )
|
|
#define ISOLATE_WIDTH ( (BYTE)((~CASE_WIDTH_MASK) | CASE_XW_MASK) )
|
|
|
|
//
|
|
// UW Mask for Cho-On:
|
|
// Leaves bit 7 on in AW, so it becomes Repeat if it follows Kana N.
|
|
//
|
|
#define CHO_ON_UW_MASK 0xff87
|
|
|
|
//
|
|
// Values for fareast special case alphanumeric weights.
|
|
//
|
|
#define AW_REPEAT 0
|
|
#define AW_CHO_ON 1
|
|
#define MAX_SPECIAL_AW AW_CHO_ON
|
|
|
|
//
|
|
// Values for weight 5 - East Asia Extra Weights.
|
|
//
|
|
#define WT_FIVE_KANA 3
|
|
#define WT_FIVE_REPEAT 4
|
|
#define WT_FIVE_CHO_ON 5
|
|
|
|
//
|
|
// Values for CJK Unified Ideographs Extension A range.
|
|
// 0x3400 thru 0x4dbf
|
|
//
|
|
#define SM_EXT_A 254 // SM for Extension A
|
|
#define AW_EXT_A 255 // AW for Extension A
|
|
|
|
//
|
|
// Values for UW extra weights (e.g. Jamo (old Hangul)).
|
|
//
|
|
#define SM_UW_XW 255 // SM for extra UW weights
|
|
|
|
|
|
//
|
|
// Script Member Values.
|
|
//
|
|
#define UNSORTABLE 0
|
|
#define NONSPACE_MARK 1
|
|
#define EXPANSION 2
|
|
#define FAREAST_SPECIAL 3
|
|
#define JAMO_SPECIAL 4
|
|
#define EXTENSION_A 5
|
|
|
|
#define PUNCTUATION 6
|
|
|
|
#define SYMBOL_1 7
|
|
#define SYMBOL_2 8
|
|
#define SYMBOL_3 9
|
|
#define SYMBOL_4 10
|
|
#define SYMBOL_5 11
|
|
|
|
#define NUMERIC_1 12
|
|
#define NUMERIC_2 13
|
|
|
|
#define LATIN 14
|
|
#define GREEK 15
|
|
#define CYRILLIC 16
|
|
#define ARMENIAN 17
|
|
#define HEBREW 18
|
|
#define ARABIC 19
|
|
#define DEVANAGARI 20
|
|
#define BENGALI 21
|
|
#define GURMUKKHI 22
|
|
#define GUJARATI 23
|
|
#define ORIYA 24
|
|
#define TAMIL 25
|
|
#define TELUGU 26
|
|
#define KANNADA 27
|
|
#define MALAYLAM 28
|
|
#define SINHALESE 29
|
|
#define THAI 30
|
|
#define LAO 31
|
|
#define TIBETAN 32
|
|
#define GEORGIAN 33
|
|
#define KANA 34
|
|
#define BOPOMOFO 35
|
|
#define HANGUL 36
|
|
#define IDEOGRAPH 128
|
|
|
|
#define MAX_SPECIAL_CASE SYMBOL_5
|
|
#define FIRST_SCRIPT LATIN
|
|
|
|
|
|
//
|
|
// Calendar Type Values.
|
|
//
|
|
#define CAL_NO_OPTIONAL 0 // no optional calendars
|
|
#define CAL_LAST CAL_GREGORIAN_XLIT_FRENCH // greatest calendar value
|
|
|
|
//
|
|
// The following calendars are defined in winnls.w:
|
|
//
|
|
// #define CAL_GREGORIAN 1
|
|
// #define CAL_GREGORIAN_US 2
|
|
// #define CAL_JAPAN 3
|
|
// #define CAL_TAIWAN 4
|
|
// #define CAL_KOREA 5
|
|
// #define CAL_HIJRI 6
|
|
// #define CAL_THAI 7
|
|
// #define CAL_HEBREW 8
|
|
// #define CAL_GREGORIAN_ME_FRENCH 9
|
|
// #define CAL_GREGORIAN_ARABIC 10
|
|
// #define CAL_GREGORIAN_XLIT_ENGLISH 11
|
|
// #define CAL_GREGORIAN_XLIT_FRENCH 12
|
|
//
|
|
|
|
|
|
//
|
|
// Constants to define range of Unicode private use area.
|
|
//
|
|
#define PRIVATE_USE_BEGIN 0xe000
|
|
#define PRIVATE_USE_END 0xf8ff
|
|
|
|
|
|
//
|
|
// Internal flag for SpecialMBToWC routine.
|
|
//
|
|
#define MB_INVALID_CHAR_CHECK MB_ERR_INVALID_CHARS
|
|
|
|
//
|
|
// Geo values.
|
|
//
|
|
#define MAX_GEO_STRING_SIZE 1024
|
|
|
|
//
|
|
// Resource String Table Values.
|
|
//
|
|
#define RC_STRING_SEPARATOR '$'
|
|
|
|
#define RC_LANGUAGE_NAME 0
|
|
#define RC_COUNTRY_NAME 1
|
|
#define RC_LANGUAGE_GROUP_NAME 2
|
|
#define RC_CODE_PAGE_NAME 3
|
|
#define RC_GEO_FRIENDLY_NAME 4
|
|
#define RC_GEO_OFFICIAL_NAME 5
|
|
#define RC_SORT_NAMES 6
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Typedef Declarations.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Constant Types
|
|
//
|
|
typedef LPWORD P844_TABLE; // ptr to 8:4:4 table
|
|
|
|
typedef LPWORD PMB_TABLE; // ptr to MB translation table
|
|
typedef PMB_TABLE PGLYPH_TABLE; // ptr to GLYPH translation table
|
|
typedef LPWORD PDBCS_RANGE; // ptr to DBCS range
|
|
typedef LPWORD PDBCS_OFFSETS; // ptr to DBCS offset section
|
|
typedef LPWORD PDBCS_TABLE; // ptr to DBCS translation table
|
|
typedef PVOID PWC_TABLE; // ptr to WC translation table
|
|
typedef P844_TABLE PCTYPE; // ptr to Character Type table
|
|
typedef P844_TABLE PCASE; // ptr to Lower or Upper Case table
|
|
typedef P844_TABLE PADIGIT; // ptr to Ascii Digits table
|
|
typedef P844_TABLE PCZONE; // ptr to Fold Compat. Zone table
|
|
typedef P844_TABLE PKANA; // ptr to Hiragana/Katakana table
|
|
typedef P844_TABLE PHALFWIDTH; // ptr to Half Width table
|
|
typedef P844_TABLE PFULLWIDTH; // ptr to Full Width table
|
|
typedef P844_TABLE PCHINESE; // ptr to Traditional/Simplified Chinese table
|
|
typedef P844_TABLE PPRECOMP; // ptr to PreComposed table
|
|
typedef LPWORD PCOMP_GRID; // ptr to Composite table 2D grid
|
|
typedef LPWORD PLOC_INFO; // ptr to locale information
|
|
typedef LPWORD PCAL_INFO; // ptr to calendar information
|
|
|
|
typedef DWORD REVERSE_DW; // reverse diacritic table
|
|
typedef REVERSE_DW *PREVERSE_DW; // ptr to reverse diacritic table
|
|
typedef DWORD DBL_COMPRESS; // double compression table
|
|
typedef DBL_COMPRESS *PDBL_COMPRESS; // ptr to double compression table
|
|
typedef LPWORD PCOMPRESS; // ptr to compression table (2 or 3)
|
|
|
|
|
|
//
|
|
// Proc Definition for Code Page DLL Routine.
|
|
//
|
|
typedef DWORD (*LPFN_CP_PROC)(DWORD, DWORD, LPSTR, int, LPWSTR, int, LPCPINFO);
|
|
|
|
|
|
//
|
|
// CP Information Table Structure (as it is in the data file).
|
|
//
|
|
typedef struct cp_table_s {
|
|
WORD CodePage; // code page number
|
|
WORD MaxCharSize; // max length (bytes) of a char
|
|
WORD wDefaultChar; // default character (MB)
|
|
WORD wUniDefaultChar; // default character (Unicode)
|
|
WORD wTransDefaultChar; // translation of wDefaultChar (Unicode)
|
|
WORD wTransUniDefaultChar; // translation of wUniDefaultChar (MB)
|
|
BYTE LeadByte[MAX_LEADBYTES]; // lead byte ranges
|
|
} CP_TABLE, *PCP_TABLE;
|
|
|
|
|
|
//
|
|
// Composite Information Structure.
|
|
//
|
|
typedef struct comp_info_s {
|
|
BYTE NumBase; // number base chars in grid
|
|
BYTE NumNonSp; // number non space chars in grid
|
|
P844_TABLE pBase; // ptr to base char table
|
|
P844_TABLE pNonSp; // ptr to nonspace char table
|
|
PCOMP_GRID pGrid; // ptr to 2D grid
|
|
} COMP_INFO, *PCOMP_INFO;
|
|
|
|
|
|
//
|
|
// Code Page Hash Table Structure.
|
|
//
|
|
typedef struct cp_hash_s {
|
|
UINT CodePage; // codepage ID
|
|
LPFN_CP_PROC pfnCPProc; // ptr to code page function proc
|
|
PCP_TABLE pCPInfo; // ptr to CPINFO table
|
|
PMB_TABLE pMBTbl; // ptr to MB translation table
|
|
PGLYPH_TABLE pGlyphTbl; // ptr to GLYPH translation table
|
|
PDBCS_RANGE pDBCSRanges; // ptr to DBCS ranges
|
|
PDBCS_OFFSETS pDBCSOffsets; // ptr to DBCS offsets
|
|
PWC_TABLE pWC; // ptr to WC table
|
|
struct cp_hash_s *pNext; // ptr to next CP hash node
|
|
} CP_HASH, *PCP_HASH;
|
|
|
|
|
|
//
|
|
// Language Exception Header Structure.
|
|
//
|
|
typedef struct l_except_hdr_s {
|
|
DWORD Locale; // locale id
|
|
DWORD Offset; // offset to exception nodes (words)
|
|
DWORD NumUpEntries; // number of upper case entries
|
|
DWORD NumLoEntries; // number of lower case entries
|
|
} L_EXCEPT_HDR, *PL_EXCEPT_HDR;
|
|
|
|
|
|
//
|
|
// Language Exception Structure.
|
|
//
|
|
typedef struct l_except_s
|
|
{
|
|
WORD UCP; // unicode code point
|
|
WORD AddAmount; // amount to add to code point
|
|
} L_EXCEPT, *PL_EXCEPT;
|
|
|
|
|
|
//
|
|
// CType header structure.
|
|
//
|
|
typedef struct ctype_hdr_s {
|
|
WORD TblSize; // size of ctype table
|
|
WORD MapSize; // size of mapping table
|
|
} CTYPE_HDR, *PCTYPE_HDR;
|
|
|
|
|
|
//
|
|
// CType Table Structure (Mapping table structure).
|
|
//
|
|
typedef struct ct_values_s {
|
|
WORD CType1; // ctype 1 value
|
|
WORD CType2; // ctype 2 value
|
|
WORD CType3; // ctype 3 value
|
|
} CT_VALUES, *PCT_VALUES;
|
|
|
|
|
|
//
|
|
// Sortkey Structure.
|
|
//
|
|
typedef struct sortkey_s {
|
|
|
|
union {
|
|
struct sm_aw_s {
|
|
BYTE Alpha; // alphanumeric weight
|
|
BYTE Script; // script member
|
|
} SM_AW;
|
|
|
|
WORD Unicode; // unicode weight
|
|
|
|
} UW;
|
|
|
|
BYTE Diacritic; // diacritic weight
|
|
BYTE Case; // case weight (with COMP)
|
|
|
|
} SORTKEY, *PSORTKEY;
|
|
|
|
|
|
//
|
|
// Extra Weight Structure.
|
|
//
|
|
typedef struct extra_wt_s {
|
|
BYTE Four; // weight 4
|
|
BYTE Five; // weight 5
|
|
BYTE Six; // weight 6
|
|
BYTE Seven; // weight 7
|
|
} EXTRA_WT, *PEXTRA_WT;
|
|
|
|
|
|
//
|
|
// Compression Header Structure.
|
|
// This is the header for the compression tables.
|
|
//
|
|
typedef struct compress_hdr_s {
|
|
DWORD Locale; // locale id
|
|
DWORD Offset; // offset (in words)
|
|
WORD Num2; // Number of 2 compressions
|
|
WORD Num3; // Number of 3 compressions
|
|
} COMPRESS_HDR, *PCOMPRESS_HDR;
|
|
|
|
|
|
//
|
|
// Compression 2 Structure.
|
|
// This is for a 2 code point compression - 2 code points
|
|
// compress to ONE weight.
|
|
//
|
|
typedef struct compress_2_s {
|
|
WCHAR UCP1; // Unicode code point 1
|
|
WCHAR UCP2; // Unicode code point 2
|
|
SORTKEY Weights; // sortkey weights
|
|
} COMPRESS_2, *PCOMPRESS_2;
|
|
|
|
|
|
//
|
|
// Compression 3 Structure.
|
|
// This is for a 3 code point compression - 3 code points
|
|
// compress to ONE weight.
|
|
//
|
|
typedef struct compress_3_s {
|
|
WCHAR UCP1; // Unicode code point 1
|
|
WCHAR UCP2; // Unicode code point 2
|
|
WCHAR UCP3; // Unicode code point 3
|
|
WCHAR Reserved; // dword alignment
|
|
SORTKEY Weights; // sortkey weights
|
|
} COMPRESS_3, *PCOMPRESS_3;
|
|
|
|
|
|
//
|
|
// Multiple Weight Structure.
|
|
//
|
|
typedef struct multiwt_s {
|
|
BYTE FirstSM; // value of first script member
|
|
BYTE NumSM; // number of script members in range
|
|
} MULTI_WT, *PMULTI_WT;
|
|
|
|
|
|
//
|
|
// Ideograph Lcid Exception Structure.
|
|
//
|
|
typedef struct ideograph_lcid_s {
|
|
DWORD Locale; // locale id
|
|
WORD pFileName[14]; // ptr to file name
|
|
} IDEOGRAPH_LCID, *PIDEOGRAPH_LCID;
|
|
|
|
|
|
//
|
|
// Expansion Structure.
|
|
//
|
|
typedef struct expand_s {
|
|
WCHAR UCP1; // Unicode code point 1
|
|
WCHAR UCP2; // Unicode code point 2
|
|
} EXPAND, *PEXPAND;
|
|
|
|
|
|
//
|
|
// Exception Header Structure.
|
|
// This is the header for the exception tables.
|
|
//
|
|
typedef struct except_hdr_s {
|
|
DWORD Locale; // locale id
|
|
DWORD Offset; // offset to exception nodes (words)
|
|
DWORD NumEntries; // number of entries for locale id
|
|
} EXCEPT_HDR, *PEXCEPT_HDR;
|
|
|
|
|
|
//
|
|
// Exception Structure.
|
|
//
|
|
// NOTE: May also be used for Ideograph Exceptions (4 column tables).
|
|
//
|
|
typedef struct except_s
|
|
{
|
|
WORD UCP; // unicode code point
|
|
WORD Unicode; // unicode weight
|
|
BYTE Diacritic; // diacritic weight
|
|
BYTE Case; // case weight
|
|
} EXCEPT, *PEXCEPT;
|
|
|
|
|
|
//
|
|
// Ideograph Exception Header Structure.
|
|
//
|
|
typedef struct ideograph_except_hdr_s
|
|
{
|
|
DWORD NumEntries; // number of entries in table
|
|
DWORD NumColumns; // number of columns in table (2 or 4)
|
|
} IDEOGRAPH_EXCEPT_HDR, *PIDEOGRAPH_EXCEPT_HDR;
|
|
|
|
|
|
//
|
|
// Ideograph Exception Structure.
|
|
//
|
|
typedef struct ideograph_except_s
|
|
{
|
|
WORD UCP; // unicode code point
|
|
WORD Unicode; // unicode weight
|
|
} IDEOGRAPH_EXCEPT, *PIDEOGRAPH_EXCEPT;
|
|
|
|
|
|
//
|
|
// Locale Information Structures.
|
|
//
|
|
// This is the format in which the locale information is kept in the
|
|
// locale data file. These structures are only used for offsets into
|
|
// the data file, not to store information.
|
|
//
|
|
|
|
//
|
|
// Header at the top of the locale.nls file.
|
|
//
|
|
typedef struct loc_cal_hdr_s
|
|
{
|
|
DWORD NumLocales; // number of locales
|
|
DWORD NumCalendars; // number of calendars
|
|
DWORD CalOffset; // offset to calendar info (words)
|
|
} LOC_CAL_HDR, *PLOC_CAL_HDR;
|
|
|
|
#define LOCALE_HDR_OFFSET (sizeof(LOC_CAL_HDR) / sizeof(WORD))
|
|
|
|
//
|
|
// Per entry locale header.
|
|
//
|
|
// The locale header structure contains the information given in one entry
|
|
// of the header for the locale information.
|
|
//
|
|
typedef struct locale_hdr_s {
|
|
DWORD Locale; // locale ID
|
|
DWORD Offset; // offset to locale information
|
|
} LOCALE_HDR, *PLOCALE_HDR;
|
|
|
|
#define LOCALE_HDR_SIZE (sizeof(LOCALE_HDR) / sizeof(WORD))
|
|
|
|
//
|
|
// The fixed structure contains the locale information that is of
|
|
// fixed length and in the order in which it is given in the file.
|
|
//
|
|
typedef struct locale_fixed_s
|
|
{
|
|
WORD DefaultACP; // default ACP - integer format
|
|
WORD szILanguage[5]; // language id
|
|
WORD szICountry[6]; // country id
|
|
WORD szIGeoID[8]; // geographical location identifier
|
|
WORD szIDefaultLang[5]; // default language ID
|
|
WORD szIDefaultCtry[6]; // default country ID
|
|
WORD szIDefaultACP[6]; // default ansi code page ID
|
|
WORD szIDefaultOCP[6]; // default oem code page ID
|
|
WORD szIDefaultMACCP[6]; // default mac code page ID
|
|
WORD szIDefaultEBCDICCP[6]; // default ebcdic code page ID
|
|
WORD szIMeasure[2]; // system of measurement
|
|
WORD szIPaperSize[2]; // default paper size
|
|
WORD szIDigits[3]; // number of fractional digits
|
|
WORD szILZero[2]; // leading zeros for decimal
|
|
WORD szINegNumber[2]; // negative number format
|
|
WORD szIDigitSubstitution[2]; // digit substitution
|
|
WORD szICurrDigits[3]; // # local monetary fractional digits
|
|
WORD szIIntlCurrDigits[3]; // # intl monetary fractional digits
|
|
WORD szICurrency[2]; // positive currency format
|
|
WORD szINegCurr[3]; // negative currency format
|
|
WORD szIPosSignPosn[2]; // format of positive sign
|
|
WORD szIPosSymPrecedes[2]; // if mon symbol precedes positive
|
|
WORD szIPosSepBySpace[2]; // if mon symbol separated by space
|
|
WORD szINegSignPosn[2]; // format of negative sign
|
|
WORD szINegSymPrecedes[2]; // if mon symbol precedes negative
|
|
WORD szINegSepBySpace[2]; // if mon symbol separated by space
|
|
WORD szITime[2]; // time format
|
|
WORD szITLZero[2]; // leading zeros for time field
|
|
WORD szITimeMarkPosn[2]; // time marker position
|
|
WORD szIDate[2]; // short date order
|
|
WORD szICentury[2]; // century format (short date)
|
|
WORD szIDayLZero[2]; // leading zeros for day field (short date)
|
|
WORD szIMonLZero[2]; // leading zeros for month field (short date)
|
|
WORD szILDate[2]; // long date order
|
|
WORD szICalendarType[3]; // type of calendar
|
|
WORD szIFirstDayOfWk[2]; // first day of week
|
|
WORD szIFirstWkOfYr[2]; // first week of year
|
|
WORD szFontSignature[MAX_FONTSIGNATURE];
|
|
} LOCALE_FIXED, *PLOCALE_FIXED;
|
|
|
|
//
|
|
// The variable structure contains the offsets to the various pieces of
|
|
// locale information that is of variable length. It is in the order
|
|
// in which it is given in the file.
|
|
//
|
|
typedef struct locale_var_s
|
|
{
|
|
WORD SEngLanguage; // English language name
|
|
WORD SAbbrevLang; // abbreviated language name
|
|
WORD SAbbrevLangISO; // ISO abbreviated language name
|
|
WORD SNativeLang; // native language name
|
|
WORD SEngCountry; // English country name
|
|
WORD SAbbrevCtry; // abbreviated country name
|
|
WORD SAbbrevCtryISO; // ISO abbreviated country name
|
|
WORD SNativeCtry; // native country name
|
|
WORD SList; // list separator
|
|
WORD SDecimal; // decimal separator
|
|
WORD SThousand; // thousands separator
|
|
WORD SGrouping; // grouping of digits
|
|
WORD SNativeDigits; // native digits 0-9
|
|
WORD SCurrency; // local monetary symbol
|
|
WORD SIntlSymbol; // international monetary symbol
|
|
WORD SEngCurrName; // English currency name
|
|
WORD SNativeCurrName; // native currency name
|
|
WORD SMonDecSep; // monetary decimal separator
|
|
WORD SMonThousSep; // monetary thousands separator
|
|
WORD SMonGrouping; // monetary grouping of digits
|
|
WORD SPositiveSign; // positive sign
|
|
WORD SNegativeSign; // negative sign
|
|
WORD STimeFormat; // time format
|
|
WORD STime; // time separator
|
|
WORD S1159; // AM designator
|
|
WORD S2359; // PM designator
|
|
WORD SShortDate; // short date format
|
|
WORD SDate; // date separator
|
|
WORD SYearMonth; // year month format
|
|
WORD SLongDate; // long date format
|
|
WORD IOptionalCal; // additional calendar type(s)
|
|
WORD SDayName1; // day name 1
|
|
WORD SDayName2; // day name 2
|
|
WORD SDayName3; // day name 3
|
|
WORD SDayName4; // day name 4
|
|
WORD SDayName5; // day name 5
|
|
WORD SDayName6; // day name 6
|
|
WORD SDayName7; // day name 7
|
|
WORD SAbbrevDayName1; // abbreviated day name 1
|
|
WORD SAbbrevDayName2; // abbreviated day name 2
|
|
WORD SAbbrevDayName3; // abbreviated day name 3
|
|
WORD SAbbrevDayName4; // abbreviated day name 4
|
|
WORD SAbbrevDayName5; // abbreviated day name 5
|
|
WORD SAbbrevDayName6; // abbreviated day name 6
|
|
WORD SAbbrevDayName7; // abbreviated day name 7
|
|
WORD SMonthName1; // month name 1
|
|
WORD SMonthName2; // month name 2
|
|
WORD SMonthName3; // month name 3
|
|
WORD SMonthName4; // month name 4
|
|
WORD SMonthName5; // month name 5
|
|
WORD SMonthName6; // month name 6
|
|
WORD SMonthName7; // month name 7
|
|
WORD SMonthName8; // month name 8
|
|
WORD SMonthName9; // month name 9
|
|
WORD SMonthName10; // month name 10
|
|
WORD SMonthName11; // month name 11
|
|
WORD SMonthName12; // month name 12
|
|
WORD SMonthName13; // month name 13 (if exists)
|
|
WORD SAbbrevMonthName1; // abbreviated month name 1
|
|
WORD SAbbrevMonthName2; // abbreviated month name 2
|
|
WORD SAbbrevMonthName3; // abbreviated month name 3
|
|
WORD SAbbrevMonthName4; // abbreviated month name 4
|
|
WORD SAbbrevMonthName5; // abbreviated month name 5
|
|
WORD SAbbrevMonthName6; // abbreviated month name 6
|
|
WORD SAbbrevMonthName7; // abbreviated month name 7
|
|
WORD SAbbrevMonthName8; // abbreviated month name 8
|
|
WORD SAbbrevMonthName9; // abbreviated month name 9
|
|
WORD SAbbrevMonthName10; // abbreviated month name 10
|
|
WORD SAbbrevMonthName11; // abbreviated month name 11
|
|
WORD SAbbrevMonthName12; // abbreviated month name 12
|
|
WORD SAbbrevMonthName13; // abbreviated month name 13 (if exists)
|
|
WORD SEndOfLocale; // end of locale information
|
|
} LOCALE_VAR, *PLOCALE_VAR;
|
|
|
|
|
|
//
|
|
// Per entry calendar header.
|
|
//
|
|
// The calendar header structure contains the information given in one entry
|
|
// of the header for the calendar information.
|
|
//
|
|
typedef struct calendar_hdr_s
|
|
{
|
|
WORD Calendar; // calendar id
|
|
WORD Offset; // offset to calendar info (words)
|
|
} CALENDAR_HDR, *PCALENDAR_HDR;
|
|
|
|
#define CALENDAR_HDR_SIZE (sizeof(CALENDAR_HDR) / sizeof(WORD))
|
|
|
|
//
|
|
// The variable structure contains the offsets to the various pieces of
|
|
// calendar information that is of variable length. It is in the order
|
|
// in which it is given in the file.
|
|
//
|
|
// The NumRanges value is the number of era ranges. If this value is zero,
|
|
// then there are no year offsets.
|
|
//
|
|
// The IfNames value is a boolean. If it is 0, then there are NO special
|
|
// day or month names for the calendar. If it is 1, then there ARE
|
|
// special day and month names for the calendar.
|
|
//
|
|
// The rest of the values are offsets to the appropriate strings.
|
|
//
|
|
typedef struct calendar_var_s
|
|
{
|
|
WORD NumRanges; // number of era ranges
|
|
WORD IfNames; // if any day or month names exist
|
|
WORD SCalendar; // calendar id
|
|
WORD STwoDigitYearMax; // two digit year max
|
|
WORD SEraRanges; // era ranges
|
|
WORD SShortDate; // short date format
|
|
WORD SYearMonth; // year month format
|
|
WORD SLongDate; // long date format
|
|
WORD SDayName1; // day name 1
|
|
WORD SDayName2; // day name 2
|
|
WORD SDayName3; // day name 3
|
|
WORD SDayName4; // day name 4
|
|
WORD SDayName5; // day name 5
|
|
WORD SDayName6; // day name 6
|
|
WORD SDayName7; // day name 7
|
|
WORD SAbbrevDayName1; // abbreviated day name 1
|
|
WORD SAbbrevDayName2; // abbreviated day name 2
|
|
WORD SAbbrevDayName3; // abbreviated day name 3
|
|
WORD SAbbrevDayName4; // abbreviated day name 4
|
|
WORD SAbbrevDayName5; // abbreviated day name 5
|
|
WORD SAbbrevDayName6; // abbreviated day name 6
|
|
WORD SAbbrevDayName7; // abbreviated day name 7
|
|
WORD SMonthName1; // month name 1
|
|
WORD SMonthName2; // month name 2
|
|
WORD SMonthName3; // month name 3
|
|
WORD SMonthName4; // month name 4
|
|
WORD SMonthName5; // month name 5
|
|
WORD SMonthName6; // month name 6
|
|
WORD SMonthName7; // month name 7
|
|
WORD SMonthName8; // month name 8
|
|
WORD SMonthName9; // month name 9
|
|
WORD SMonthName10; // month name 10
|
|
WORD SMonthName11; // month name 11
|
|
WORD SMonthName12; // month name 12
|
|
WORD SMonthName13; // month name 13
|
|
WORD SAbbrevMonthName1; // abbreviated month name 1
|
|
WORD SAbbrevMonthName2; // abbreviated month name 2
|
|
WORD SAbbrevMonthName3; // abbreviated month name 3
|
|
WORD SAbbrevMonthName4; // abbreviated month name 4
|
|
WORD SAbbrevMonthName5; // abbreviated month name 5
|
|
WORD SAbbrevMonthName6; // abbreviated month name 6
|
|
WORD SAbbrevMonthName7; // abbreviated month name 7
|
|
WORD SAbbrevMonthName8; // abbreviated month name 8
|
|
WORD SAbbrevMonthName9; // abbreviated month name 9
|
|
WORD SAbbrevMonthName10; // abbreviated month name 10
|
|
WORD SAbbrevMonthName11; // abbreviated month name 11
|
|
WORD SAbbrevMonthName12; // abbreviated month name 12
|
|
WORD SAbbrevMonthName13; // abbreviated month name 13
|
|
WORD SEndOfCalendar; // end of calendar information
|
|
} CALENDAR_VAR, *PCALENDAR_VAR;
|
|
|
|
//
|
|
// IOptionalCalendar structure (locale info).
|
|
//
|
|
typedef struct opt_cal_s
|
|
{
|
|
WORD CalId; // calendar id
|
|
WORD Offset; // offset to next optional calendar
|
|
WORD pCalStr[1]; // calendar id string (variable length)
|
|
// WORD pCalNameStr[1]; // calendar name string (variable length)
|
|
} OPT_CAL, *POPT_CAL;
|
|
|
|
|
|
//
|
|
// SEraRanges structure inside calendar info.
|
|
//
|
|
typedef struct era_range_s
|
|
{
|
|
WORD Month; // month of era beginning
|
|
WORD Day; // day of era beginning
|
|
WORD Year; // year of era beginning
|
|
WORD Offset; // offset to next era info block
|
|
WORD pYearStr[1]; // year string (variable length)
|
|
// WORD pEraNameStr[1]; // era name string (variable length)
|
|
} ERA_RANGE, *PERA_RANGE;
|
|
|
|
|
|
//
|
|
// Locale Hash Table Structure.
|
|
//
|
|
typedef struct loc_hash_s {
|
|
LCID Locale; // locale ID
|
|
PLOCALE_VAR pLocaleHdr; // ptr to locale header info
|
|
PLOCALE_FIXED pLocaleFixed; // ptr to locale fixed size info
|
|
PCASE pUpperCase; // ptr to Upper Case table
|
|
PCASE pLowerCase; // ptr to Lower Case table
|
|
PCASE pUpperLinguist; // ptr to Upper Case Linguistic table
|
|
PCASE pLowerLinguist; // ptr to Lower Case Linguistic table
|
|
PSORTKEY pSortkey; // ptr to sortkey table
|
|
BOOL IfReverseDW; // if DW should go from right to left
|
|
BOOL IfCompression; // if compression code points exist
|
|
BOOL IfDblCompression; // if double compression exists
|
|
BOOL IfIdeographFailure; // if ideograph table failed to load
|
|
PCOMPRESS_HDR pCompHdr; // ptr to compression header
|
|
PCOMPRESS_2 pCompress2; // ptr to 2 compression table
|
|
PCOMPRESS_3 pCompress3; // ptr to 3 compression table
|
|
struct loc_hash_s *pNext; // ptr to next locale hash node
|
|
} LOC_HASH, *PLOC_HASH;
|
|
|
|
|
|
//
|
|
// Hash Table Pointers.
|
|
//
|
|
typedef PCP_HASH *PCP_HASH_TBL; // ptr to a code page hash table
|
|
typedef PLOC_HASH *PLOC_HASH_TBL; // ptr to a locale hash table
|
|
|
|
|
|
//
|
|
// Geo Information structure. This structure holds information about
|
|
// a geographical location on earth.
|
|
//
|
|
typedef struct tagGeoInfo {
|
|
GEOID GeoId;
|
|
WCHAR szLatitude[12];
|
|
WCHAR szLongitude[12];
|
|
GEOCLASS GeoClass;
|
|
GEOID ParentGeoId;
|
|
WCHAR szISO3166Abbrev2[4];
|
|
WCHAR szISO3166Abbrev3[4];
|
|
WORD wISO3166;
|
|
WORD Reserved; // dword alignment
|
|
} GEOINFO, *PGEOINFO;
|
|
|
|
|
|
//
|
|
// GEOID/LCID structure. This structure is used to navigate through
|
|
// the table that maps corresponding Language ID and Geo ID.
|
|
//
|
|
typedef struct tagGEOIDLCID {
|
|
LCID lcid;
|
|
GEOID GeoId;
|
|
LANGID LangId;
|
|
WORD Reserved; // dword alignment
|
|
} GEOLCID, *PGEOLCID;
|
|
|
|
|
|
//
|
|
// GEO tables structure. This structure is used to get information
|
|
// related to all geo tables.
|
|
//
|
|
typedef struct tagGeoTableHdr {
|
|
WCHAR szSig[4];
|
|
unsigned long nFileSize;
|
|
DWORD dwOffsetGeoInfo;
|
|
long nGeoInfo;
|
|
DWORD dwOffsetGeoLCID;
|
|
long nGeoLCID;
|
|
} GEOTABLEHDR, *PGEOTABLEHDR;
|
|
|
|
|
|
//
|
|
// Jamo Sequence Sorting Info.
|
|
//
|
|
typedef struct {
|
|
BYTE m_bOld; // sequence occurs only in old Hangul flag
|
|
CHAR m_chLeadingIndex; // indices used to locate prior modern Hangul syllable
|
|
CHAR m_chVowelIndex;
|
|
CHAR m_chTrailingIndex;
|
|
BYTE m_ExtraWeight; // extra weights that distinguish this from
|
|
// other old Hangul syllables, depending
|
|
// on the jamo, this can be a weight for
|
|
// leading jamo, vowel jamo, or trailing jamo.
|
|
} JAMO_SORT_INFO, *PJAMO_SORT_INFO;
|
|
|
|
//
|
|
// Jamo Index Table Entry.
|
|
//
|
|
typedef struct {
|
|
JAMO_SORT_INFO SortInfo; // sequence sorting info
|
|
BYTE Index; // index into the composition array
|
|
BYTE TransitionCount; // # of possible transitions from this state
|
|
BYTE Reserved; // word alignment
|
|
} JAMO_TABLE, *PJAMO_TABLE;
|
|
|
|
|
|
//
|
|
// Jamo Combination Table Entry.
|
|
//
|
|
// NOTE: Make sure this structure is WORD aligned. Otherwise, code will
|
|
// fail in GetDefaultSortTable().
|
|
//
|
|
typedef struct {
|
|
WCHAR m_wcCodePoint; // Code point value that enters this state
|
|
JAMO_SORT_INFO m_SortInfo; // Sequence sorting info
|
|
BYTE m_bTransitionCount; // # of possible transitions from this state
|
|
} JAMO_COMPOSE_STATE, *PJAMO_COMPOSE_STATE;
|
|
|
|
|
|
//
|
|
// Table Pointers Structure. This structure contains pointers to
|
|
// the various tables needed for the NLS APIs. There should be only
|
|
// ONE of these for each process, and the information should be
|
|
// global to the process.
|
|
//
|
|
#define NUM_SM 256 // total number of script members
|
|
#define NUM_CAL 64 // total number calendars allowed
|
|
|
|
typedef struct tbl_ptrs_s {
|
|
PCP_HASH_TBL pCPHashTbl; // ptr to Code Page hash table
|
|
PLOC_HASH_TBL pLocHashTbl; // ptr to Locale hash table
|
|
PLOC_INFO pLocaleInfo; // ptr to locale table (all locales)
|
|
DWORD NumCalendars; // number of calendars
|
|
PCAL_INFO pCalendarInfo; // ptr to beginning of calendar info
|
|
PCAL_INFO pCalTbl[NUM_CAL]; // ptr to calendar table array
|
|
P844_TABLE pDefaultLanguage; // ptr to default language table
|
|
P844_TABLE pLinguistLanguage; // ptr to default linguistic lang table
|
|
LARGE_INTEGER LinguistLangSize; // size of linguistic lang table
|
|
int NumLangException; // number of language exceptions
|
|
PL_EXCEPT_HDR pLangExceptHdr; // ptr to lang exception table header
|
|
PL_EXCEPT pLangException; // ptr to lang exception tables
|
|
PCT_VALUES pCTypeMap; // ptr to Ctype Mapping table
|
|
PCTYPE pCType844; // ptr to Ctype 8:4:4 table
|
|
PADIGIT pADigit; // ptr to Ascii Digits table
|
|
PCZONE pCZone; // ptr to Compatibility Zone table
|
|
PKANA pHiragana; // ptr to Hiragana table
|
|
PKANA pKatakana; // ptr to Katakana table
|
|
PHALFWIDTH pHalfWidth; // ptr to Half Width table
|
|
PFULLWIDTH pFullWidth; // ptr to Full Width table
|
|
PCHINESE pTraditional; // ptr to Traditional Chinese table
|
|
PCHINESE pSimplified; // ptr to Simplified Chinese table
|
|
PPRECOMP pPreComposed; // ptr to PreComposed Table
|
|
PCOMP_INFO pComposite; // ptr to Composite info structure
|
|
DWORD NumReverseDW; // number of REVERSE DIACRITICS
|
|
DWORD NumDblCompression; // number of DOUBLE COMPRESSION locales
|
|
DWORD NumIdeographLcid; // number of IDEOGRAPH LCIDs
|
|
DWORD NumExpansion; // number of EXPANSIONS
|
|
DWORD NumCompression; // number of COMPRESSION locales
|
|
DWORD NumException; // number of EXCEPTION locales
|
|
DWORD NumMultiWeight; // number of MULTIPLE WEIGHTS
|
|
int NumJamoIndex; // number of entires for Jamo Index Table
|
|
int NumJamoComposition; // number of entires for Jamo Composition Table
|
|
PSORTKEY pDefaultSortkey; // ptr to default sortkey table
|
|
LARGE_INTEGER DefaultSortkeySize; // size of default sortkey section
|
|
PREVERSE_DW pReverseDW; // ptr to reverse diacritic table
|
|
PDBL_COMPRESS pDblCompression; // ptr to double compression table
|
|
PIDEOGRAPH_LCID pIdeographLcid; // ptr to ideograph lcid table
|
|
PEXPAND pExpansion; // ptr to expansion table
|
|
PCOMPRESS_HDR pCompressHdr; // ptr to compression table header
|
|
PCOMPRESS pCompression; // ptr to compression tables
|
|
PEXCEPT_HDR pExceptHdr; // ptr to exception table header
|
|
PEXCEPT pException; // ptr to exception tables
|
|
PMULTI_WT pMultiWeight; // ptr to multiple weights table
|
|
BYTE SMWeight[NUM_SM]; // script member weights
|
|
PJAMO_TABLE pJamoIndex; // ptr ot Jamo Index table
|
|
PJAMO_COMPOSE_STATE pJamoComposition; // ptr to Jamo Composition state machine table
|
|
long nGeoInfo; // number of GEOINFO entries
|
|
PGEOINFO pGeoInfo; // ptr to gegraphical info location table
|
|
long nGeoLCID; // number of GEOID/LCID entries
|
|
PGEOLCID pGeoLCID; // ptr to GEOID/LCID mapping table
|
|
} TBL_PTRS, *PTBL_PTRS;
|
|
|
|
typedef struct nls_locale_cache
|
|
{
|
|
NLS_USER_INFO NlsInfo; // NLS cached information
|
|
HKEY CurrentUserKeyHandle; // Cached key handle thread impersonation
|
|
|
|
} NLS_LOCAL_CACHE, *PNLS_LOCAL_CACHE;
|
|
|
|
|
|
//
|
|
// Generic Enum Proc Definitions.
|
|
//
|
|
typedef BOOL (CALLBACK* NLS_ENUMPROC)(PVOID);
|
|
typedef BOOL (CALLBACK* NLS_ENUMPROCEX)(PVOID, DWORD);
|
|
typedef BOOL (CALLBACK* NLS_ENUMPROC2)(DWORD, DWORD, PVOID, LONG_PTR);
|
|
typedef BOOL (CALLBACK* NLS_ENUMPROC3)(DWORD, PVOID, PVOID, DWORD, LONG_PTR);
|
|
typedef BOOL (CALLBACK* NLS_ENUMPROC4)(PVOID, LONG_PTR);
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Macro Definitions.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Get the wide character count from a byte count.
|
|
//
|
|
#define GET_WC_COUNT(bc) ((bc) / sizeof(WCHAR))
|
|
|
|
//
|
|
// Get the data pointer for the KEY_VALUE_FULL_INFORMATION structure.
|
|
//
|
|
#define GET_VALUE_DATA_PTR(p) ((LPWSTR)((PBYTE)(p) + (p)->DataOffset))
|
|
|
|
//
|
|
// Macros For High and Low Nibbles of a BYTE.
|
|
//
|
|
#define LO_NIBBLE(b) ((BYTE)((BYTE)(b) & 0xF))
|
|
#define HI_NIBBLE(b) ((BYTE)(((BYTE)(b) >> 4) & 0xF))
|
|
|
|
//
|
|
// Macros for Extracting the 8:4:4 Index Values.
|
|
//
|
|
#define GET8(w) (HIBYTE(w))
|
|
#define GETHI4(w) (HI_NIBBLE(LOBYTE(w)))
|
|
#define GETLO4(w) (LO_NIBBLE(LOBYTE(w)))
|
|
|
|
|
|
//
|
|
// Macros for setting and checking most significant bit of flag.
|
|
//
|
|
#define SET_MSB(fl) (fl |= MSB_FLAG)
|
|
#define IS_MSB(fl) (fl & MSB_FLAG)
|
|
|
|
//
|
|
// Macro to check if more than one bit is set.
|
|
// Returns 1 if more than one bit set, 0 otherwise.
|
|
//
|
|
#define MORE_THAN_ONE(f, bits) (((f & bits) - 1) & (f & bits))
|
|
|
|
//
|
|
// Macros for single and double byte code pages.
|
|
//
|
|
#define IS_SBCS_CP(pHash) (pHash->pCPInfo->MaxCharSize == 1)
|
|
#define IS_DBCS_CP(pHash) (pHash->pCPInfo->MaxCharSize == 2)
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// TRAVERSE_844_B
|
|
//
|
|
// Traverses the 8:4:4 translation table for the given wide character. It
|
|
// returns the final value of the 8:4:4 table, which is a BYTE in length.
|
|
//
|
|
// NOTE: Offsets in table are in BYTES.
|
|
//
|
|
// Broken Down Version:
|
|
// --------------------
|
|
// Incr = pTable[GET8(wch)] / sizeof(WORD);
|
|
// Incr = pTable[Incr + GETHI4(wch)];
|
|
// Value = (BYTE *)pTable[Incr + GETLO4(wch)];
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define TRAVERSE_844_B(pTable, wch) \
|
|
(((BYTE *)pTable)[pTable[(pTable[GET8(wch)] / sizeof(WORD)) + \
|
|
GETHI4(wch)] + \
|
|
GETLO4(wch)])
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// TRAVERSE_844_W
|
|
//
|
|
// Traverses the 8:4:4 translation table for the given wide character. It
|
|
// returns the final value of the 8:4:4 table, which is a WORD in length.
|
|
//
|
|
// Broken Down Version:
|
|
// --------------------
|
|
// Incr = pTable[GET8(wch)];
|
|
// Incr = pTable[Incr + GETHI4(wch)];
|
|
// Value = pTable[Incr + GETLO4(wch)];
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define TRAVERSE_844_W(pTable, wch) \
|
|
(pTable[pTable[pTable[GET8(wch)] + GETHI4(wch)] + GETLO4(wch)])
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// TRAVERSE_844_D
|
|
//
|
|
// Traverses the 8:4:4 translation table for the given wide character. It
|
|
// fills in the final word values, Value1 and Value2. The final value of the
|
|
// 8:4:4 table is a DWORD, so both Value1 and Value2 are filled in.
|
|
//
|
|
// Broken Down Version:
|
|
// --------------------
|
|
// Incr = pTable[GET8(wch)];
|
|
// Incr = pTable[Incr + GETHI4(wch)];
|
|
// pTable += Incr + (GETLO4(wch) * 2);
|
|
// Value1 = pTable[0];
|
|
// Value2 = pTable[1];
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define TRAVERSE_844_D(pTable, wch, Value1, Value2) \
|
|
{ \
|
|
pTable += pTable[pTable[GET8(wch)] + GETHI4(wch)] + (GETLO4(wch) * 2); \
|
|
Value1 = pTable[0]; \
|
|
Value2 = pTable[1]; \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_INCR_VALUE
|
|
//
|
|
// Gets the value of a given wide character from the given 8:4:4 table. It
|
|
// then uses the value as an increment by adding it to the given wide
|
|
// character code point.
|
|
//
|
|
// NOTE: Whenever there is no translation for the given code point, the
|
|
// tables will return an increment value of 0. This way, the
|
|
// wide character passed in is the same value that is returned.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_INCR_VALUE(p844Tbl, wch) \
|
|
((WCHAR)(wch + TRAVERSE_844_W(p844Tbl, wch)))
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_LOWER_UPPER_CASE
|
|
//
|
|
// Gets the lower/upper case value of a given wide character. If a
|
|
// lower/upper case value exists, it returns the lower/upper case wide
|
|
// character. Otherwise, it returns the same character passed in wch.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_LOWER_UPPER_CASE(pCaseTbl, wch) \
|
|
(GET_INCR_VALUE(pCaseTbl, wch))
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_ASCII_DIGITS
|
|
//
|
|
// Gets the ascii translation for the given digit character. If no
|
|
// translation is found, then the given character is returned.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_ASCII_DIGITS(pADigit, wch) \
|
|
(GET_INCR_VALUE(pADigit, wch))
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_FOLD_CZONE
|
|
//
|
|
// Gets the translation for the given compatibility zone character. If no
|
|
// translation is found, then the given character is returned.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_FOLD_CZONE(pCZone, wch) \
|
|
(GET_INCR_VALUE(pCZone, wch))
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_KANA
|
|
//
|
|
// Gets the Hiragana/Katakana equivalent for the given Katakana/Hiragana
|
|
// character. If no translation is found, then the given character is
|
|
// returned.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 07-14-93 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_KANA(pKana, wch) \
|
|
(GET_INCR_VALUE(pKana, wch))
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_HALF_WIDTH
|
|
//
|
|
// Gets the Half Width equivalent for the given Full Width character. If no
|
|
// translation is found, then the given character is returned.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 07-14-93 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_HALF_WIDTH(pHalf, wch) \
|
|
(GET_INCR_VALUE(pHalf, wch))
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_FULL_WIDTH
|
|
//
|
|
// Gets the Full Width equivalent for the given Half Width character. If no
|
|
// translation is found, then the given character is returned.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 07-14-93 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_FULL_WIDTH(pFull, wch) \
|
|
(GET_INCR_VALUE(pFull, wch))
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_CHINESE
|
|
//
|
|
// Gets the Traditional/Simplified Chinese translation for the given
|
|
// Simplified/Traditional Chinese character. If no translation is found,
|
|
// then the given character is returned.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-07-96 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_CHINESE(pChinese, wch) \
|
|
(GET_INCR_VALUE(pChinese, wch))
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_CTYPE
|
|
//
|
|
// Gets the ctype information for a given wide character. If the ctype
|
|
// information exists, it returns it. Otherwise, it returns 0.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_CTYPE(wch, offset) \
|
|
((((PCT_VALUES)(pTblPtrs->pCTypeMap)) + \
|
|
(TRAVERSE_844_B((pTblPtrs->pCType844), wch)))->offset)
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GET_BASE_CHAR
|
|
//
|
|
// Gets the base character of a given precomposed character. If the
|
|
// composite form is found, it returns the base character. Otherwise,
|
|
// it returns 0 for failure.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_BASE_CHAR(wch, Base) \
|
|
{ \
|
|
WCHAR NonSp; /* nonspacing character */ \
|
|
WCHAR NewBase; /* base character - temp holder */ \
|
|
\
|
|
\
|
|
/* \
|
|
* Get composite characters. \
|
|
*/ \
|
|
if (GetCompositeChars(wch, &NonSp, &Base)) \
|
|
{ \
|
|
while (GetCompositeChars(Base, &NonSp, &NewBase)) \
|
|
{ \
|
|
Base = NewBase; \
|
|
} \
|
|
} \
|
|
else \
|
|
{ \
|
|
/* \
|
|
* Return failure - no composite form. \
|
|
*/ \
|
|
Base = 0; \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SORTKEY WEIGHT MACROS
|
|
//
|
|
// Parse out the different sortkey weights from a DWORD value.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define GET_SCRIPT_MEMBER(pwt) ( (BYTE)(((PSORTKEY)(pwt))->UW.SM_AW.Script) )
|
|
#define GET_ALPHA_NUMERIC(pwt) ( (BYTE)(((PSORTKEY)(pwt))->UW.SM_AW.Alpha) )
|
|
|
|
#define GET_UNICODE(pwt) ( (WORD)(((PSORTKEY)(pwt))->UW.Unicode) )
|
|
|
|
#define GET_UNICODE_SM(pwt, sm) ( (WORD)(((PSORTKEY)(pwt))->UW.Unicode) )
|
|
|
|
#define GET_UNICODE_MOD(pwt, modify_sm) \
|
|
( (modify_sm) ? \
|
|
((WORD) \
|
|
((((WORD)((pTblPtrs->SMWeight)[GET_SCRIPT_MEMBER(pwt)])) << 8) | \
|
|
(WORD)GET_ALPHA_NUMERIC(pwt))) : \
|
|
((WORD)(((PSORTKEY)(pwt))->UW.Unicode)) )
|
|
|
|
#define GET_UNICODE_SM_MOD(pwt, sm, modify_sm) \
|
|
( (modify_sm) ? \
|
|
((WORD) \
|
|
((((WORD)((pTblPtrs->SMWeight)[sm])) << 8) | \
|
|
(WORD)GET_ALPHA_NUMERIC(pwt))) : \
|
|
((WORD)(((PSORTKEY)(pwt))->UW.Unicode)) )
|
|
|
|
#define MAKE_UNICODE_WT(sm, aw, modify_sm) \
|
|
( (modify_sm) ? \
|
|
((WORD)((((WORD)((pTblPtrs->SMWeight)[sm])) << 8) | (WORD)(aw))) : \
|
|
((WORD)((((WORD)(sm)) << 8) | (WORD)(aw))) )
|
|
|
|
#define UNICODE_WT(pwt) ( (WORD)(((PSORTKEY)(pwt))->UW.Unicode) )
|
|
|
|
#define GET_DIACRITIC(pwt) ( (BYTE)(((PSORTKEY)(pwt))->Diacritic) )
|
|
|
|
#define GET_CASE(pwt) ( (BYTE)((((PSORTKEY)(pwt))->Case) & CASE_MASK) )
|
|
|
|
#define CASE_WT(pwt) ( (BYTE)(((PSORTKEY)(pwt))->Case) )
|
|
|
|
#define GET_COMPRESSION(pwt) ( (BYTE)((((PSORTKEY)(pwt))->Case) & COMPRESS_3_MASK) )
|
|
|
|
#define GET_EXPAND_INDEX(pwt) ( (BYTE)(((PSORTKEY)(pwt))->UW.SM_AW.Alpha) )
|
|
|
|
#define GET_SPECIAL_WEIGHT(pwt) ( (WORD)(((PSORTKEY)(pwt))->UW.Unicode) )
|
|
|
|
// position returned is backwards - byte reversal
|
|
#define GET_POSITION_SW(pos) ( (WORD)(((pos) << 2) | SW_POSITION_MASK) )
|
|
|
|
|
|
#define GET_WT_FOUR(pwt) ( (BYTE)(((PEXTRA_WT)(pwt))->Four) )
|
|
#define GET_WT_FIVE(pwt) ( (BYTE)(((PEXTRA_WT)(pwt))->Five) )
|
|
#define GET_WT_SIX(pwt) ( (BYTE)(((PEXTRA_WT)(pwt))->Six) )
|
|
#define GET_WT_SEVEN(pwt) ( (BYTE)(((PEXTRA_WT)(pwt))->Seven) )
|
|
|
|
|
|
#define MAKE_SORTKEY_DWORD(wt) ( (DWORD)(*((LPDWORD)(&(wt)))) )
|
|
|
|
#define MAKE_EXTRA_WT_DWORD(wt) ( (DWORD)(*((LPDWORD)(&(wt)))) )
|
|
|
|
#define GET_DWORD_WEIGHT(pHashN, wch) \
|
|
( MAKE_SORTKEY_DWORD(((pHashN)->pSortkey)[wch]) )
|
|
|
|
#define GET_EXPANSION_1(pwt) \
|
|
( ((pTblPtrs->pExpansion)[GET_EXPAND_INDEX(pwt)]).UCP1 )
|
|
|
|
#define GET_EXPANSION_2(pwt) \
|
|
( ((pTblPtrs->pExpansion)[GET_EXPAND_INDEX(pwt)]).UCP2 )
|
|
|
|
|
|
|
|
|
|
#define IS_SYMBOL(pSkey, wch) \
|
|
( (GET_SCRIPT_MEMBER(&((pSkey)[wch])) >= PUNCTUATION) && \
|
|
(GET_SCRIPT_MEMBER(&((pSkey)[wch])) <= SYMBOL_5) )
|
|
|
|
#define IS_NONSPACE_ONLY(pSkey, wch) \
|
|
( GET_SCRIPT_MEMBER(&((pSkey)[wch])) == NONSPACE_MARK )
|
|
|
|
#define IS_NONSPACE(pSkey, wch) \
|
|
( (GET_SCRIPT_MEMBER(&((pSkey)[wch])) == NONSPACE_MARK) || \
|
|
(GET_DIACRITIC(&((pSkey)[wch])) > MIN_DW) )
|
|
|
|
#define IS_ALPHA(ctype1) ( (ctype1) & C1_ALPHA )
|
|
|
|
|
|
|
|
|
|
#define IS_KOREAN(lcid) \
|
|
( LANGIDFROMLCID(lcid) == MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN) )
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CHECK_SPECIAL_LOCALES
|
|
//
|
|
// Checks for the special locale values and sets the Locale to the
|
|
// appropriate value.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define CHECK_SPECIAL_LOCALES(Locale, UseCachedLocaleId) \
|
|
{ \
|
|
/* \
|
|
* Check for special locale values. \
|
|
*/ \
|
|
if (Locale == LOCALE_SYSTEM_DEFAULT) \
|
|
{ \
|
|
/* \
|
|
* Get the System Default locale value. \
|
|
*/ \
|
|
Locale = gSystemLocale; \
|
|
} \
|
|
else if ((Locale == LOCALE_NEUTRAL) || (Locale == LOCALE_USER_DEFAULT)) \
|
|
{ \
|
|
/* \
|
|
* Get the User locale value. \
|
|
*/ \
|
|
if (!UseCachedLocaleId) \
|
|
{ \
|
|
Locale = GetUserDefaultLCID(); \
|
|
} \
|
|
else \
|
|
{ \
|
|
Locale = pNlsUserInfo->UserLocaleId; \
|
|
} \
|
|
} \
|
|
/* \
|
|
* Check for a valid primary language and a neutral sublanguage. \
|
|
*/ \
|
|
else if (SUBLANGID(LANGIDFROMLCID(Locale)) == SUBLANG_NEUTRAL) \
|
|
{ \
|
|
/* \
|
|
* Re-form the locale id using the primary language and the \
|
|
* default sublanguage. \
|
|
*/ \
|
|
Locale = MAKELCID(MAKELANGID(PRIMARYLANGID(LANGIDFROMLCID(Locale)), \
|
|
SUBLANG_DEFAULT), \
|
|
SORTIDFROMLCID(Locale)); \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IS_INVALID_LOCALE
|
|
//
|
|
// Checks to see that only the proper bits are used in the locale.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define NLS_VALID_LOCALE_MASK 0x000fffff
|
|
#define IS_INVALID_LOCALE(Locale) ( Locale & ~NLS_VALID_LOCALE_MASK )
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// VALIDATE_LANGUAGE
|
|
//
|
|
// Checks that the given Locale contains a valid language id. It does so
|
|
// by making sure the appropriate casing and sorting tables are present.
|
|
// If the language is valid, pLocHashN will be non-NULL. Otherwise,
|
|
// pLocHashN will be NULL.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define VALIDATE_LANGUAGE(Locale, pLocHashN, dwFlags, UseCachedLocaleId) \
|
|
{ \
|
|
/* \
|
|
* Check the system locale first for speed. This is the most \
|
|
* likely one to be used. \
|
|
*/ \
|
|
if (Locale == gSystemLocale) \
|
|
{ \
|
|
pLocHashN = gpSysLocHashN; \
|
|
} \
|
|
/* \
|
|
* Check the invariant locale second for speed. This is the second \
|
|
* most likely one to be used. \
|
|
*/ \
|
|
else if (Locale == LOCALE_INVARIANT) \
|
|
{ \
|
|
pLocHashN = gpInvLocHashN; \
|
|
} \
|
|
else \
|
|
{ \
|
|
/* \
|
|
* Check special locale values. \
|
|
*/ \
|
|
CHECK_SPECIAL_LOCALES(Locale, UseCachedLocaleId); \
|
|
\
|
|
/* \
|
|
* If the locale is the system default, then the hash node is \
|
|
* already stored in a global. \
|
|
*/ \
|
|
if (Locale == gSystemLocale) \
|
|
{ \
|
|
pLocHashN = gpSysLocHashN; \
|
|
} \
|
|
else if (IS_INVALID_LOCALE(Locale)) \
|
|
{ \
|
|
pLocHashN = NULL; \
|
|
} \
|
|
else \
|
|
{ \
|
|
/* \
|
|
* Need to make sure the locale value is valid. Need to \
|
|
* check the locale file to see if the locale is supported. \
|
|
*/ \
|
|
pLocHashN = GetLocHashNode(Locale); \
|
|
\
|
|
if (pLocHashN != NULL) \
|
|
{ \
|
|
/* \
|
|
* Make sure the appropriate casing and sorting tables \
|
|
* are in the system. \
|
|
* \
|
|
* NOTE: If the call fails, pLocHashN will be NULL. \
|
|
*/ \
|
|
pLocHashN = GetLangHashNode(Locale, dwFlags); \
|
|
} \
|
|
} \
|
|
} \
|
|
\
|
|
/* \
|
|
* Make sure we don't need to get the linguistic tables. \
|
|
*/ \
|
|
if ((dwFlags) && (pLocHashN) && (pLocHashN->pLowerLinguist == NULL)) \
|
|
{ \
|
|
/* \
|
|
* Get locale hash node to make sure the appropriate \
|
|
* casing and sorting tables are in the system. \
|
|
*/ \
|
|
pLocHashN = GetLangHashNode(Locale, dwFlags); \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// VALIDATE_LOCALE
|
|
//
|
|
// Checks that the given LCID contains a valid locale id. It does so
|
|
// by making sure the appropriate locale information is present. If the
|
|
// locale is valid, pLocHashN will be non-NULL. Otherwise, pLocHashN
|
|
// will be NULL.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define VALIDATE_LOCALE(Locale, pLocHashN, UseCachedLocaleId) \
|
|
{ \
|
|
/* \
|
|
* Check the system locale first for speed. This is the most \
|
|
* likely one to be used. \
|
|
*/ \
|
|
if (Locale == gSystemLocale) \
|
|
{ \
|
|
pLocHashN = gpSysLocHashN; \
|
|
} \
|
|
/* \
|
|
* Check the invariant locale second for speed. This is the second \
|
|
* most likely one to be used. \
|
|
*/ \
|
|
else if (Locale == LOCALE_INVARIANT) \
|
|
{ \
|
|
pLocHashN = gpInvLocHashN; \
|
|
} \
|
|
else \
|
|
{ \
|
|
/* \
|
|
* Check special locale values. \
|
|
*/ \
|
|
CHECK_SPECIAL_LOCALES(Locale, UseCachedLocaleId); \
|
|
\
|
|
/* \
|
|
* If the locale is the system default, then the hash node \
|
|
* is already stored in a global. \
|
|
*/ \
|
|
if (Locale == gSystemLocale) \
|
|
{ \
|
|
pLocHashN = gpSysLocHashN; \
|
|
} \
|
|
else if (IS_INVALID_LOCALE(Locale)) \
|
|
{ \
|
|
pLocHashN = NULL; \
|
|
} \
|
|
else \
|
|
{ \
|
|
/* \
|
|
* Get locale hash node to make sure the appropriate \
|
|
* locale table is in the system. \
|
|
* \
|
|
* NOTE: If the call fails, pLocHashN will be NULL. \
|
|
*/ \
|
|
pLocHashN = GetLocHashNode(Locale); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OPEN_CODEPAGE_KEY
|
|
//
|
|
// Opens the key for the code page section of the registry for read access.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 09-01-93 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define OPEN_CODEPAGE_KEY(ReturnVal) \
|
|
{ \
|
|
/* \
|
|
* Make sure code page key is open. \
|
|
*/ \
|
|
if (hCodePageKey == NULL) \
|
|
{ \
|
|
RtlEnterCriticalSection(&gcsTblPtrs); \
|
|
if (hCodePageKey == NULL) \
|
|
{ \
|
|
if (OpenRegKey( &hCodePageKey, \
|
|
NLS_HKLM_SYSTEM, \
|
|
NLS_CODEPAGE_KEY, \
|
|
KEY_READ )) \
|
|
{ \
|
|
SetLastError(ERROR_BADDB); \
|
|
RtlLeaveCriticalSection(&gcsTblPtrs); \
|
|
return (ReturnVal); \
|
|
} \
|
|
} \
|
|
RtlLeaveCriticalSection(&gcsTblPtrs); \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OPEN_LOCALE_KEY
|
|
//
|
|
// Opens the key for the locale section of the registry for read access.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 09-01-93 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define OPEN_LOCALE_KEY(ReturnVal) \
|
|
{ \
|
|
/* \
|
|
* Make sure locale key is open. \
|
|
*/ \
|
|
if (hLocaleKey == NULL) \
|
|
{ \
|
|
RtlEnterCriticalSection(&gcsTblPtrs); \
|
|
if (hLocaleKey == NULL) \
|
|
{ \
|
|
if (OpenRegKey( &hLocaleKey, \
|
|
NLS_HKLM_SYSTEM, \
|
|
NLS_LOCALE_KEY, \
|
|
KEY_READ )) \
|
|
{ \
|
|
SetLastError(ERROR_BADDB); \
|
|
RtlLeaveCriticalSection(&gcsTblPtrs); \
|
|
return (ReturnVal); \
|
|
} \
|
|
} \
|
|
RtlLeaveCriticalSection(&gcsTblPtrs); \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OPEN_ALT_SORTS_KEY
|
|
//
|
|
// Opens the key for the alternate sorts section of the registry for read
|
|
// access.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 11-15-96 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define OPEN_ALT_SORTS_KEY(ReturnVal) \
|
|
{ \
|
|
/* \
|
|
* Make sure alternate sorts key is open. \
|
|
*/ \
|
|
if (hAltSortsKey == NULL) \
|
|
{ \
|
|
RtlEnterCriticalSection(&gcsTblPtrs); \
|
|
if (hAltSortsKey == NULL) \
|
|
{ \
|
|
if (OpenRegKey( &hAltSortsKey, \
|
|
NLS_HKLM_SYSTEM, \
|
|
NLS_ALT_SORTS_KEY, \
|
|
KEY_READ )) \
|
|
{ \
|
|
SetLastError(ERROR_BADDB); \
|
|
RtlLeaveCriticalSection(&gcsTblPtrs); \
|
|
return (ReturnVal); \
|
|
} \
|
|
} \
|
|
RtlLeaveCriticalSection(&gcsTblPtrs); \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OPEN_LANG_GROUPS_KEY
|
|
//
|
|
// Opens the key for the language groups section of the registry for
|
|
// read access.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 09-01-93 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define OPEN_LANG_GROUPS_KEY(ReturnVal) \
|
|
{ \
|
|
/* \
|
|
* Make sure language groups key is open. \
|
|
*/ \
|
|
if (hLangGroupsKey == NULL) \
|
|
{ \
|
|
RtlEnterCriticalSection(&gcsTblPtrs); \
|
|
if (hLangGroupsKey == NULL) \
|
|
{ \
|
|
if (OpenRegKey( &hLangGroupsKey, \
|
|
NLS_HKLM_SYSTEM, \
|
|
NLS_LANGUAGE_GROUPS_KEY, \
|
|
KEY_READ )) \
|
|
{ \
|
|
SetLastError(ERROR_BADDB); \
|
|
RtlLeaveCriticalSection(&gcsTblPtrs); \
|
|
return (ReturnVal); \
|
|
} \
|
|
} \
|
|
RtlLeaveCriticalSection(&gcsTblPtrs); \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OPEN_MUILANG_KEY
|
|
//
|
|
// Opens the key for the multilingual UI language section of the registry
|
|
// for read access. It is acceptable if this key is not in the registry,
|
|
// so do not call SetLastError if the key cannot be opened.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 03-10-98 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define OPEN_MUILANG_KEY(hKey, ReturnVal) \
|
|
{ \
|
|
if ((hKey) == NULL) \
|
|
{ \
|
|
if (OpenRegKey( &(hKey), \
|
|
NLS_HKLM_SYSTEM, \
|
|
NLS_MUILANG_KEY, \
|
|
KEY_READ )) \
|
|
{ \
|
|
return (ReturnVal); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OPEN_CPANEL_INTL_KEY
|
|
//
|
|
// Opens the key for the control panel international section of the
|
|
// registry for the given access.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 09-01-93 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define OPEN_CPANEL_INTL_KEY(hKey, ReturnVal, Access) \
|
|
{ \
|
|
if ((hKey) == NULL) \
|
|
{ \
|
|
if (OpenRegKey( &(hKey), \
|
|
NULL, \
|
|
NLS_CTRL_PANEL_KEY, \
|
|
Access )) \
|
|
{ \
|
|
SetLastError(ERROR_BADDB); \
|
|
return (ReturnVal); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OPEN_GEO_KEY
|
|
//
|
|
// Opens the key for the geographic information section of the registry
|
|
// for read access.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 03-10-00 lguindon Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define OPEN_GEO_KEY(hKey, ReturnVal, Access) \
|
|
{ \
|
|
if ((hKey) == NULL) \
|
|
{ \
|
|
if (OpenRegKey( &(hKey), \
|
|
NULL, \
|
|
GEO_REG_KEY, \
|
|
Access )) \
|
|
{ \
|
|
SetLastError(ERROR_BADDB); \
|
|
return (ReturnVal); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CLOSE_REG_KEY
|
|
//
|
|
// Closes the given registry key.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 09-01-93 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define CLOSE_REG_KEY(hKey) \
|
|
{ \
|
|
if ((hKey) != NULL) \
|
|
{ \
|
|
NtClose(hKey); \
|
|
hKey = NULL; \
|
|
} \
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// NLS_ALLOC_MEM
|
|
//
|
|
// Allocates the given number of bytes of memory from the process heap,
|
|
// zeros the memory buffer, and returns the handle.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define NLS_ALLOC_MEM(dwBytes) \
|
|
( RtlAllocateHeap( RtlProcessHeap(), \
|
|
HEAP_ZERO_MEMORY, \
|
|
dwBytes ) )
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// NLS_FREE_MEM
|
|
//
|
|
// Frees the memory of the given handle from the process heap.
|
|
//
|
|
// DEFINED AS A MACRO.
|
|
//
|
|
// 05-31-91 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define NLS_FREE_MEM(hMem) \
|
|
( (hMem) ? (RtlFreeHeap( RtlProcessHeap(), \
|
|
0, \
|
|
(PVOID)hMem )) \
|
|
: 0 )
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// NLS_FREE_TMP_BUFFER
|
|
//
|
|
// Checks to see if the buffer is the same as the static buffer. If it
|
|
// is NOT the same, then the buffer is freed.
|
|
//
|
|
// 11-04-92 JulieB Created.
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define NLS_FREE_TMP_BUFFER(pBuf, pStaticBuf) \
|
|
{ \
|
|
if (pBuf != pStaticBuf) \
|
|
{ \
|
|
NLS_FREE_MEM(pBuf); \
|
|
} \
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ARRAYSIZE
|
|
//
|
|
// Hnady utility macro to get the size of an array (such as an array of
|
|
// WCHARs).
|
|
////////////////////////////////////////////////////////////////////////////
|
|
#ifndef ARRAYSIZE
|
|
#define ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0]))
|
|
#endif
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Function Prototypes
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Table Routines - tables.c.
|
|
//
|
|
ULONG
|
|
AllocTables(void);
|
|
|
|
ULONG
|
|
GetUnicodeFileInfo(void);
|
|
|
|
ULONG
|
|
GetGeoFileInfo(void);
|
|
|
|
ULONG
|
|
GetCTypeFileInfo(void);
|
|
|
|
ULONG
|
|
GetDefaultSortkeyFileInfo(void);
|
|
|
|
ULONG
|
|
GetDefaultSortTablesFileInfo(void);
|
|
|
|
ULONG
|
|
GetSortkeyFileInfo(
|
|
LCID Locale,
|
|
PLOC_HASH pHashN);
|
|
|
|
void
|
|
GetSortTablesFileInfo(
|
|
LCID Locale,
|
|
PLOC_HASH pHashN);
|
|
|
|
ULONG
|
|
GetCodePageFileInfo(
|
|
UINT CodePage,
|
|
PCP_HASH *ppNode);
|
|
|
|
ULONG
|
|
GetLanguageFileInfo(
|
|
LCID Locale,
|
|
PLOC_HASH *ppNode,
|
|
BOOLEAN fCreateNode,
|
|
DWORD dwFlags);
|
|
|
|
ULONG
|
|
GetLocaleFileInfo(
|
|
LCID Locale,
|
|
PLOC_HASH *ppNode,
|
|
BOOLEAN fCreateNode);
|
|
|
|
ULONG
|
|
MakeCPHashNode(
|
|
UINT CodePage,
|
|
LPWORD pBaseAddr,
|
|
PCP_HASH *ppNode,
|
|
BOOL IsDLL,
|
|
LPFN_CP_PROC pfnCPProc);
|
|
|
|
ULONG
|
|
MakeLangHashNode(
|
|
LCID Locale,
|
|
LPWORD pBaseAddr,
|
|
PLOC_HASH *ppNode,
|
|
BOOLEAN fCreateNode);
|
|
|
|
ULONG
|
|
MakeLocHashNode(
|
|
LCID Locale,
|
|
LPWORD pBaseAddr,
|
|
PLOC_HASH *ppNode,
|
|
BOOLEAN fCreateNode);
|
|
|
|
PCP_HASH FASTCALL
|
|
GetCPHashNode(
|
|
UINT CodePage);
|
|
|
|
PLOC_HASH FASTCALL
|
|
GetLangHashNode(
|
|
LCID Locale,
|
|
DWORD dwFlags);
|
|
|
|
BOOL
|
|
IsCPHashNodeLoaded(
|
|
UINT CodePage);
|
|
|
|
PLOC_HASH FASTCALL
|
|
GetLocHashNode(
|
|
LCID Locale);
|
|
|
|
ULONG
|
|
GetCalendar(
|
|
CALID Calendar,
|
|
PCAL_INFO *ppCalInfo);
|
|
|
|
|
|
//
|
|
// Section Routines - section.c.
|
|
//
|
|
ULONG
|
|
CreateNlsObjectDirectory(void);
|
|
|
|
ULONG
|
|
CreateRegKey(
|
|
PHANDLE phKeyHandle,
|
|
LPWSTR pBaseName,
|
|
LPWSTR pKey,
|
|
ULONG fAccess);
|
|
|
|
ULONG
|
|
OpenRegKey(
|
|
PHANDLE phKeyHandle,
|
|
LPWSTR pBaseName,
|
|
LPWSTR pKey,
|
|
ULONG fAccess);
|
|
|
|
ULONG
|
|
QueryRegValue(
|
|
HANDLE hKeyHandle,
|
|
LPWSTR pValue,
|
|
PKEY_VALUE_FULL_INFORMATION *ppKeyValueFull,
|
|
ULONG Length,
|
|
LPBOOL pIfAlloc);
|
|
|
|
ULONG
|
|
SetRegValue(
|
|
HANDLE hKeyHandle,
|
|
LPCWSTR pValue,
|
|
LPCWSTR pData,
|
|
ULONG DataLength);
|
|
|
|
ULONG
|
|
CreateSectionTemp(
|
|
HANDLE *phSec,
|
|
LPWSTR pwszFileName);
|
|
|
|
ULONG
|
|
OpenSection(
|
|
HANDLE *phSec,
|
|
PUNICODE_STRING pObSectionName,
|
|
PVOID *ppBaseAddr,
|
|
ULONG AccessMask,
|
|
BOOL bCloseHandle);
|
|
|
|
ULONG
|
|
MapSection(
|
|
HANDLE hSec,
|
|
PVOID *ppBaseAddr,
|
|
ULONG PageProtection,
|
|
BOOL bCloseHandle);
|
|
|
|
ULONG
|
|
UnMapSection(
|
|
PVOID pBaseAddr);
|
|
|
|
ULONG
|
|
GetNlsSectionName(
|
|
UINT Value,
|
|
UINT Base,
|
|
UINT Padding,
|
|
LPWSTR pwszPrefix,
|
|
LPWSTR pwszSecName,
|
|
UINT cchSecName);
|
|
|
|
ULONG
|
|
GetCodePageDLLPathName(
|
|
UINT CodePage,
|
|
LPWSTR pDllName,
|
|
USHORT cchLen);
|
|
|
|
|
|
//
|
|
// Utility Routines - util.c.
|
|
//
|
|
BOOL GetCPFileNameFromRegistry(
|
|
UINT CodePage,
|
|
LPWSTR pResultBuf,
|
|
UINT Size);
|
|
|
|
BOOL GetUserInfoFromRegistry(
|
|
LPWSTR pValue,
|
|
LPWSTR pOutput,
|
|
LCID Locale);
|
|
|
|
int
|
|
GetStringTableEntry(
|
|
UINT ResourceID,
|
|
LANGID UILangId,
|
|
LPWSTR pBuffer,
|
|
int cchBuffer,
|
|
int WhichString);
|
|
|
|
BOOL
|
|
IsValidSeparatorString(
|
|
LPCWSTR pString,
|
|
ULONG MaxLength,
|
|
BOOL fCheckZeroLen);
|
|
|
|
BOOL
|
|
IsValidGroupingString(
|
|
LPCWSTR pString,
|
|
ULONG MaxLength,
|
|
BOOL fCheckZeroLen);
|
|
|
|
LPWORD
|
|
IsValidCalendarType(
|
|
PLOC_HASH pHashN,
|
|
CALID CalId);
|
|
|
|
LPWORD
|
|
IsValidCalendarTypeStr(
|
|
PLOC_HASH pHashN,
|
|
LPCWSTR pCalStr);
|
|
|
|
BOOL
|
|
GetUserInfo(
|
|
LCID Locale,
|
|
LCTYPE LCType ,
|
|
SIZE_T CacheOffset,
|
|
LPWSTR pValue,
|
|
LPWSTR pOutput,
|
|
size_t cchOutput,
|
|
BOOL fCheckNull);
|
|
|
|
WCHAR FASTCALL
|
|
GetPreComposedChar(
|
|
WCHAR wcNonSp,
|
|
WCHAR wcBase);
|
|
|
|
BOOL FASTCALL
|
|
GetCompositeChars(
|
|
WCHAR wch,
|
|
WCHAR *pNonSp,
|
|
WCHAR *pBase);
|
|
|
|
int FASTCALL
|
|
InsertPreComposedForm(
|
|
LPCWSTR pWCStr,
|
|
LPWSTR pEndWCStr,
|
|
LPWSTR pPreComp);
|
|
|
|
int FASTCALL
|
|
InsertFullWidthPreComposedForm(
|
|
LPCWSTR pWCStr,
|
|
LPWSTR pEndWCStr,
|
|
LPWSTR pPreComp,
|
|
PCASE pCase);
|
|
|
|
int FASTCALL
|
|
InsertCompositeForm(
|
|
LPWSTR pWCStr,
|
|
LPWSTR pEndWCStr);
|
|
|
|
ULONG
|
|
NlsConvertIntegerToString(
|
|
UINT Value,
|
|
UINT Base,
|
|
UINT Padding,
|
|
LPWSTR pResultBuf,
|
|
UINT Size);
|
|
|
|
BOOL FASTCALL
|
|
NlsConvertIntegerToHexStringW(
|
|
UINT Value,
|
|
BOOL UpperCase,
|
|
PWSTR Str,
|
|
UINT Width);
|
|
|
|
BOOL FASTCALL
|
|
NlsConvertStringToIntegerW(
|
|
PWSTR str,
|
|
UINT Base,
|
|
int CharCount,
|
|
UINT* Result);
|
|
|
|
BOOL FASTCALL
|
|
NlsIsDll(
|
|
LPCWSTR pFileName);
|
|
|
|
LPWSTR FASTCALL
|
|
NlsStrCpyW(
|
|
LPWSTR pwszDest,
|
|
LPCWSTR pwszSrc);
|
|
|
|
LPWSTR FASTCALL
|
|
NlsStrCatW(
|
|
LPWSTR pwsz1,
|
|
LPCWSTR pwsz2);
|
|
|
|
int FASTCALL
|
|
NlsStrLenW(
|
|
LPCWSTR pwsz);
|
|
|
|
LPWSTR FASTCALL
|
|
NlsStrNCatW(
|
|
LPWSTR pwszFront,
|
|
LPCWSTR pwszBack,
|
|
int Count);
|
|
|
|
int FASTCALL
|
|
NlsStrEqualW(
|
|
LPCWSTR pwszFirst,
|
|
LPCWSTR pwszSecond);
|
|
|
|
int FASTCALL
|
|
NlsStrNEqualW(
|
|
LPCWSTR pwszFirst,
|
|
LPCWSTR pwszSecond,
|
|
int Count);
|
|
|
|
//
|
|
// Security Routines - security.c.
|
|
//
|
|
|
|
NTSTATUS
|
|
NlsCheckForInteractiveUser();
|
|
|
|
NTSTATUS
|
|
NlsIsInteractiveUserProcess();
|
|
|
|
NTSTATUS
|
|
NlsGetUserLocale(
|
|
LCID *Lcid);
|
|
|
|
NTSTATUS
|
|
NlsGetCurrentUserNlsInfo(
|
|
LCID Locale,
|
|
LCTYPE LCType,
|
|
PWSTR RegistryValue,
|
|
PWSTR pOutputBuffer,
|
|
BOOL IgnoreLocaleValue);
|
|
|
|
|
|
NTSTATUS
|
|
NlsQueryCurrentUserInfo(
|
|
PNLS_LOCAL_CACHE pNlsCache,
|
|
LPWSTR pValue,
|
|
LPWSTR pOutput);
|
|
|
|
NTSTATUS
|
|
NlsFlushProcessCache(
|
|
LCTYPE LCType);
|
|
|
|
|
|
//
|
|
// Internal Enumeration routines - enum.c.
|
|
//
|
|
BOOL
|
|
Internal_EnumSystemLanguageGroups(
|
|
NLS_ENUMPROC lpLanguageGroupEnumProc,
|
|
DWORD dwFlags,
|
|
LONG_PTR lParam,
|
|
BOOL fUnicodeVer);
|
|
|
|
BOOL
|
|
Internal_EnumLanguageGroupLocales(
|
|
NLS_ENUMPROC lpLangGroupLocaleEnumProc,
|
|
LGRPID LanguageGroup,
|
|
DWORD dwFlags,
|
|
LONG_PTR lParam,
|
|
BOOL fUnicodeVer);
|
|
|
|
BOOL
|
|
Internal_EnumUILanguages(
|
|
NLS_ENUMPROC lpUILanguageEnumProc,
|
|
DWORD dwFlags,
|
|
LONG_PTR lParam,
|
|
BOOL fUnicodeVer);
|
|
|
|
BOOL
|
|
Internal_EnumSystemLocales(
|
|
NLS_ENUMPROC lpLocaleEnumProc,
|
|
DWORD dwFlags,
|
|
BOOL fUnicodeVer);
|
|
|
|
BOOL
|
|
Internal_EnumSystemCodePages(
|
|
NLS_ENUMPROC lpCodePageEnumProc,
|
|
DWORD dwFlags,
|
|
BOOL fUnicodeVer);
|
|
|
|
BOOL
|
|
Internal_EnumCalendarInfo(
|
|
NLS_ENUMPROC lpCalInfoEnumProc,
|
|
LCID Locale,
|
|
CALID Calendar,
|
|
CALTYPE CalType,
|
|
BOOL fUnicodeVer,
|
|
BOOL fExVersion);
|
|
|
|
BOOL
|
|
Internal_EnumTimeFormats(
|
|
NLS_ENUMPROC lpTimeFmtEnumProc,
|
|
LCID Locale,
|
|
DWORD dwFlags,
|
|
BOOL fUnicodeVer);
|
|
|
|
BOOL
|
|
Internal_EnumDateFormats(
|
|
NLS_ENUMPROC lpDateFmtEnumProc,
|
|
LCID Locale,
|
|
DWORD dwFlags,
|
|
BOOL fUnicodeVer,
|
|
BOOL fExVersion);
|
|
|
|
|
|
//
|
|
// Ansi routines - ansi.c.
|
|
//
|
|
BOOL
|
|
NlsDispatchAnsiEnumProc(
|
|
LCID Locale,
|
|
NLS_ENUMPROC pNlsEnumProc,
|
|
DWORD dwFlags,
|
|
LPWSTR pUnicodeBuffer1,
|
|
LPWSTR pUnicodeBuffer2,
|
|
DWORD dwValue1,
|
|
DWORD dwValue2,
|
|
LONG_PTR lParam,
|
|
BOOL fVersion);
|
|
|
|
|
|
//
|
|
// Translation Routines - mbcs.c.
|
|
//
|
|
int
|
|
SpecialMBToWC(
|
|
PCP_HASH pHashN,
|
|
DWORD dwFlags,
|
|
LPCSTR lpMultiByteStr,
|
|
int cbMultiByte,
|
|
LPWSTR lpWideCharStr,
|
|
int cchWideChar);
|
|
|
|
|
|
//
|
|
// UTF Translation Routines - utf.c.
|
|
//
|
|
BOOL
|
|
UTFCPInfo(
|
|
UINT CodePage,
|
|
LPCPINFO lpCPInfo,
|
|
BOOL fExVer);
|
|
|
|
int
|
|
UTFToUnicode(
|
|
UINT CodePage,
|
|
DWORD dwFlags,
|
|
LPCSTR lpMultiByteStr,
|
|
int cbMultiByte,
|
|
LPWSTR lpWideCharStr,
|
|
int cchWideChar);
|
|
|
|
int
|
|
UnicodeToUTF(
|
|
UINT CodePage,
|
|
DWORD dwFlags,
|
|
LPCWSTR lpWideCharStr,
|
|
int cchWideChar,
|
|
LPSTR lpMultiByteStr,
|
|
int cbMultiByte,
|
|
LPCSTR lpDefaultChar,
|
|
LPBOOL lpUsedDefaultChar);
|
|
|
|
|
|
//
|
|
// Locale/Calendar Info (locale.c)
|
|
//
|
|
BOOL
|
|
GetTwoDigitYearInfo(
|
|
CALID Calendar,
|
|
LPWSTR pYearInfo,
|
|
PWSTR pwszKeyPath);
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Global Variables
|
|
//
|
|
// All of the global variables for the NLSAPI should be put here. These are
|
|
// all instance-specific. In general, there shouldn't be much reason to
|
|
// create instance globals.
|
|
//
|
|
// Globals are included last because they may require some of the types
|
|
// being defined above.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
extern PTBL_PTRS pTblPtrs; // ptr to structure of table ptrs
|
|
extern HANDLE hModule; // handle to module
|
|
extern RTL_CRITICAL_SECTION gcsTblPtrs; // critical section for tbl ptrs
|
|
|
|
extern UINT gAnsiCodePage; // Ansi code page value
|
|
extern UINT gOemCodePage; // OEM code page value
|
|
extern UINT gMacCodePage; // MAC code page value
|
|
extern LCID gSystemLocale; // system locale value
|
|
extern LANGID gSystemInstallLang; // system's original install language
|
|
extern PLOC_HASH gpSysLocHashN; // ptr to system loc hash node
|
|
extern PLOC_HASH gpInvLocHashN; // ptr to invariant loc hash node
|
|
extern PCP_HASH gpACPHashN; // ptr to ACP hash node
|
|
extern PCP_HASH gpOEMCPHashN; // ptr to OEMCP hash node
|
|
extern PCP_HASH gpMACCPHashN; // ptr to MAC hash node
|
|
|
|
extern HANDLE hCodePageKey; // handle to System\Nls\CodePage key
|
|
extern HANDLE hLocaleKey; // handle to System\Nls\Locale key
|
|
extern HANDLE hAltSortsKey; // handle to Locale\Alternate Sorts key
|
|
extern HANDLE hLangGroupsKey; // handle to System\Nls\Language Groups key
|
|
|
|
extern PNLS_USER_INFO pNlsUserInfo; // ptr to the user info cache
|
|
|
|
extern BOOL gInteractiveLogonUserProcess; // running in interactive user session or not.
|
|
extern RTL_CRITICAL_SECTION gcsNlsProcessCache; // Nls process cache critical section
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Functions used to communicate with CSRSS.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
NTSTATUS
|
|
CsrBasepNlsGetUserInfo(
|
|
IN LCID Locale,
|
|
IN SIZE_T CacheOffset,
|
|
OUT LPWSTR pData,
|
|
IN ULONG DataLength);
|
|
|
|
|
|
NTSTATUS
|
|
CsrBasepNlsSetUserInfo(
|
|
IN LCTYPE LCType,
|
|
IN LPWSTR pData,
|
|
IN ULONG DataLength);
|
|
|
|
NTSTATUS
|
|
CsrBasepNlsSetMultipleUserInfo(
|
|
IN DWORD dwFlags,
|
|
IN int cchData,
|
|
IN LPCWSTR pPicture,
|
|
IN LPCWSTR pSeparator,
|
|
IN LPCWSTR pOrder,
|
|
IN LPCWSTR pTLZero,
|
|
IN LPCWSTR pTimeMarkPosn);
|
|
|
|
NTSTATUS
|
|
CsrBasepNlsCreateSection(
|
|
IN UINT uiType,
|
|
IN LCID Locale,
|
|
OUT PHANDLE phSection);
|
|
|
|
NTSTATUS
|
|
CsrBasepNlsUpdateCacheCount(VOID);
|
|
|
|
#endif // _NLS_
|