Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2867 lines
110 KiB

/*++
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 header
#define SORTVERINFO_HEADER 2 // size of Sort Version Info table header
#define NLSDEFINED_HEADER 2 // size of NLS Defined Code point table header
#define NLSDEFINED_ITEM_SIZE 2+2 // size of an item in the NLSDEFINED table header (VERSION is in DWORD, and offset is in DWORD)
//
// 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)
typedef DWORD NLSDEFINED; // NLS defined codepoint table
typedef NLSDEFINED *PNLSDEFINED; // ptr to NLS defined code point table
//
// 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;
//
// Sorting Version Info Structure.
//
typedef struct _sortverinfo{
LCID Locale; // Locale identifier
DWORD Version; // Sort version for this locale
}SORTVERINFO, *PSORTVERINFO;
//
// Defined Code Point Version Info Structure.
//
typedef struct _definedverinfo{
DWORD Version; // Version of the Code Point table
DWORD dwOffset; // Offset to the Defined Code Point table.
}DEFVERINFO, *PDEFVERINFO;
//
// 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
DWORD NumSortVersion; // number of sorting version
PSORTVERINFO pSortVersion; // ptr sorting version info
DWORD NumDefinedVersion; // number of defined code point version
PDEFVERINFO pDefinedVersion; // ptr defined code point version
LPWORD pSortingTableFileBase; // The base address of sorting table file
} 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,
size_t cchOutput,
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);
int FASTCALL
NlsStrLenW(
LPCWSTR pwsz);
int FASTCALL
NlsStrEqualW(
LPCWSTR pwszFirst,
LPCWSTR pwszSecond);
int FASTCALL
NlsStrNEqualW(
LPCWSTR pwszFirst,
LPCWSTR pwszSecond,
int Count);
BOOL FASTCALL
IsSortingCodePointDefined(
LPNLSVERSIONINFO lpVersionInformation,
LPCWSTR lpString,
INT cchSrc);
//
// Security Routines - security.c.
//
NTSTATUS
NlsCheckForInteractiveUser();
NTSTATUS
NlsIsInteractiveUserProcess();
NTSTATUS
NlsGetUserLocale(
LCID *Lcid);
NTSTATUS
NlsGetCurrentUserNlsInfo(
LCID Locale,
LCTYPE LCType,
PWSTR RegistryValue,
PWSTR pOutputBuffer,
size_t cchOutputBuffer,
BOOL IgnoreLocaleValue);
NTSTATUS
NlsQueryCurrentUserInfo(
PNLS_LOCAL_CACHE pNlsCache,
LPWSTR pValue,
LPWSTR pOutput,
size_t cchOutput);
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,
size_t cchYearInfo,
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 PNLS_USER_INFO pServerNlsUserInfo; // ptr to the user info cache in the csrss.exe.
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 PNLS_USER_INFO pNlsCache,
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_