mirror of https://github.com/lianthony/NT4.0
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.
1116 lines
26 KiB
1116 lines
26 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dllnls.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the NLS OS/2 V2.0 API Calls
|
|
|
|
Author:
|
|
|
|
Steve Wood (stevewo) 20-Sep-1989 (Adapted from URTL\alloc.c)
|
|
|
|
Revision History:
|
|
|
|
3/31/93 - MJarus - Moved the NLS string function for the OS2SS to ssrtl
|
|
|
|
--*/
|
|
|
|
|
|
#define INCL_OS2V20_TASKING
|
|
#define INCL_OS2V20_ERRORS
|
|
#define INCL_OS2V20_NLS
|
|
#include "os2dll.h"
|
|
#include "conrqust.h"
|
|
#include "os2nls.h"
|
|
#include "os2win.h"
|
|
|
|
ULONG Or2ProcessCodePage;
|
|
ULONG Or2CurrentCodePageIsOem;
|
|
|
|
extern OD2_COUNTRY_ENTRY OD2_COUNTRY_TABLE[];
|
|
extern OD2_CODEPAGE_ENTRY OD2_CODEPAGE_TABLE[];
|
|
extern OD2_DBCS_VECTOR_ENTRY OD2_DBCS_VECTOR_TABLE[];
|
|
extern OD2_COLLATE_CTRY_ENTRY OD2_COLLATE_CTRY_TABLE[];
|
|
extern PUCHAR OD2_CASEMAP_TABLE[];
|
|
extern PUCHAR OD2_COLLATE_CP_TABLE[];
|
|
extern PUCHAR OD2_FIX_CASEMAP_TABLE[];
|
|
extern UCHAR Od2BaseCaseMapTable[];
|
|
extern UCHAR Od2BaseCollateTable[];
|
|
|
|
|
|
|
|
APIRET
|
|
DosQueryCtryInfo(
|
|
IN ULONG MaxCountryInfoLength,
|
|
IN PCOUNTRYCODE CountryCode,
|
|
OUT PCOUNTRYINFO CountryInfo,
|
|
OUT PULONG ActualCountryInfoLength
|
|
)
|
|
{
|
|
COUNTRYINFO DefaultInformation;
|
|
APIRET RetCode;
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "DosQueryCtryInfo";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Country %lu, CP %lu, (current Ctry %lu, CP %lu), Length %lu\n",
|
|
FuncName, CountryCode->country, CountryCode->codepage,
|
|
SesGrp->CountryCode, SesGrp->DosCP, MaxCountryInfoLength ));
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// zero buffer. probe parms.
|
|
//
|
|
|
|
try
|
|
{
|
|
RtlZeroMemory( (PVOID)CountryInfo, MaxCountryInfoLength );
|
|
Od2ProbeForRead (CountryCode, sizeof(COUNTRYCODE),1);
|
|
*ActualCountryInfoLength = 0;
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
Od2ExitGP();
|
|
}
|
|
|
|
RetCode = Od2GetCtryInfo(
|
|
CountryCode->country,
|
|
CountryCode->codepage,
|
|
&DefaultInformation
|
|
);
|
|
|
|
if ( !CountryCode->country && CountryCode->codepage)
|
|
{
|
|
CountryCode->country = SesGrp->CountryCode;
|
|
}
|
|
|
|
if ( RetCode )
|
|
{
|
|
return (RetCode);
|
|
}
|
|
|
|
if (MaxCountryInfoLength < sizeof( COUNTRYINFO ))
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Table trunc (%lu instead of %lu)\n",
|
|
FuncName, MaxCountryInfoLength, sizeof( COUNTRYINFO )));
|
|
}
|
|
#endif
|
|
*ActualCountryInfoLength = MaxCountryInfoLength;
|
|
RetCode = ERROR_NLS_TABLE_TRUNCATED;
|
|
} else
|
|
{
|
|
*ActualCountryInfoLength = sizeof( COUNTRYINFO );
|
|
}
|
|
|
|
RtlMoveMemory( (PVOID)CountryInfo,
|
|
(PVOID)&DefaultInformation,
|
|
*ActualCountryInfoLength
|
|
);
|
|
return (RetCode);
|
|
}
|
|
|
|
|
|
APIRET
|
|
DosQueryDBCSEnv(
|
|
IN ULONG MaxDBCSEvLength,
|
|
IN PCOUNTRYCODE CountryCode,
|
|
OUT PCHAR DBCSEv
|
|
)
|
|
{
|
|
CHAR LocalDBCSEv[12];
|
|
APIRET RetCode;
|
|
ULONG BufLength;
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "DosQueryDBCSEnv";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Country %lu, CP %lu, (current Ctry %lu, CP %lu), Length %lu\n",
|
|
FuncName, CountryCode->country, CountryCode->codepage,
|
|
SesGrp->CountryCode, SesGrp->DosCP, MaxDBCSEvLength ));
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// zero buffer. probe parms.
|
|
//
|
|
|
|
try
|
|
{
|
|
Od2ProbeForRead( CountryCode, sizeof(COUNTRYCODE), 1 );
|
|
RtlZeroMemory( (PVOID)DBCSEv, MaxDBCSEvLength );
|
|
} except( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
Od2ExitGP();
|
|
}
|
|
|
|
RetCode = Od2GetDBCSEv(
|
|
CountryCode->country,
|
|
CountryCode->codepage,
|
|
&LocalDBCSEv[0],
|
|
&BufLength
|
|
);
|
|
|
|
if ( !CountryCode->country && CountryCode->codepage)
|
|
{
|
|
CountryCode->country = SesGrp->CountryCode;
|
|
}
|
|
|
|
if ( RetCode )
|
|
{
|
|
return (RetCode);
|
|
}
|
|
|
|
if ( MaxDBCSEvLength < BufLength )
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Table trunc (%lu instead of %lu)\n",
|
|
FuncName, MaxDBCSEvLength, BufLength));
|
|
}
|
|
#endif
|
|
BufLength = MaxDBCSEvLength;
|
|
RetCode = ERROR_NLS_TABLE_TRUNCATED;
|
|
}
|
|
|
|
RtlMoveMemory( (PVOID)DBCSEv,
|
|
(PVOID)LocalDBCSEv,
|
|
BufLength
|
|
);
|
|
return (RetCode);
|
|
}
|
|
|
|
|
|
APIRET
|
|
DosMapCase(
|
|
IN ULONG StringLength,
|
|
IN PCOUNTRYCODE CountryCode,
|
|
IN OUT PUCHAR String
|
|
)
|
|
{
|
|
UCHAR CaseMapTable[256];
|
|
ULONG CharNum;
|
|
APIRET RetCode;
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "DosMapCase";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Country %lu, CP %lu, (current Ctry %lu, CP %lu), Length %lu, String %c...\n",
|
|
FuncName, CountryCode->country, CountryCode->codepage,
|
|
SesGrp->CountryCode, SesGrp->DosCP, StringLength, *String ));
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// probe parms.
|
|
//
|
|
|
|
try
|
|
{
|
|
Od2ProbeForRead (CountryCode, sizeof(COUNTRYCODE), 1);
|
|
Od2ProbeForWrite (String, StringLength, 1);
|
|
} except( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
Od2ExitGP();
|
|
}
|
|
|
|
RetCode = Od2GetCaseMapTable(
|
|
CountryCode->country,
|
|
CountryCode->codepage,
|
|
CaseMapTable);
|
|
|
|
if ( !CountryCode->country && CountryCode->codepage)
|
|
{
|
|
CountryCode->country = SesGrp->CountryCode;
|
|
}
|
|
|
|
if ( RetCode )
|
|
{
|
|
return (RetCode);
|
|
}
|
|
|
|
for ( CharNum = 0 ; CharNum < StringLength ; CharNum++ )
|
|
{
|
|
#ifdef DBCS
|
|
// MSKK Apr.18.1993 V-AkihiS
|
|
// Support DBCS for DosCaseMap API.
|
|
if (IsDBCSLeadByte(String[CharNum]))
|
|
{
|
|
CharNum++;
|
|
} else
|
|
{
|
|
String[CharNum] = CaseMapTable[String[CharNum]];
|
|
}
|
|
#else
|
|
String[CharNum] = CaseMapTable[String[CharNum]];
|
|
#endif
|
|
}
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
|
|
APIRET
|
|
DosQueryCollate(
|
|
IN ULONG MaxCollateInfoLength,
|
|
IN PCOUNTRYCODE CountryCode,
|
|
OUT PUCHAR CollateInfo,
|
|
OUT PULONG ActualCollateInfoLength
|
|
)
|
|
{
|
|
UCHAR CollateTable[256];
|
|
APIRET RetCode;
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "DosQueryCollate";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Country %lu, CP %lu, (current Ctry %lu, CP %lu), Length %lu\n",
|
|
FuncName, CountryCode->country, CountryCode->codepage,
|
|
SesGrp->CountryCode, SesGrp->DosCP, MaxCollateInfoLength ));
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// probe parms.
|
|
//
|
|
|
|
try
|
|
{
|
|
Od2ProbeForRead (CountryCode, sizeof(COUNTRYCODE),1);
|
|
RtlZeroMemory(CollateInfo, MaxCollateInfoLength);
|
|
*ActualCollateInfoLength = 0;
|
|
} except( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
Od2ExitGP();
|
|
}
|
|
|
|
RetCode = Od2GetCollateTable(
|
|
CountryCode->country,
|
|
CountryCode->codepage,
|
|
CollateTable);
|
|
|
|
if ( !CountryCode->country && CountryCode->codepage)
|
|
{
|
|
CountryCode->country = SesGrp->CountryCode;
|
|
}
|
|
|
|
if ( RetCode )
|
|
{
|
|
return (RetCode);
|
|
}
|
|
|
|
if ( MaxCollateInfoLength > 256 )
|
|
{
|
|
MaxCollateInfoLength = 256;
|
|
}
|
|
|
|
memmove( CollateInfo, CollateTable, MaxCollateInfoLength);
|
|
|
|
*ActualCollateInfoLength = MaxCollateInfoLength;
|
|
|
|
if ( MaxCollateInfoLength < 256 )
|
|
{
|
|
return( ERROR_NLS_TABLE_TRUNCATED );
|
|
}
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
|
|
APIRET
|
|
DosSetProcessCp(
|
|
IN ULONG ulCodePage,
|
|
IN ULONG ulReserved
|
|
)
|
|
{
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "DosSetProcessCp";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: CP %lu, Reserved %lu, (current %lu)\n",
|
|
FuncName, ulCodePage, ulReserved, SesGrp->DosCP));
|
|
}
|
|
#endif
|
|
|
|
if ( ulReserved != 0 )
|
|
{
|
|
return (ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
//
|
|
// Validate the CodePage parameter against the list of installed code
|
|
// pages.
|
|
//
|
|
|
|
if (( ulCodePage == 0 ) ||
|
|
(( ulCodePage != SesGrp->PrimaryCP ) &&
|
|
( ulCodePage != SesGrp->SecondaryCP )))
|
|
{
|
|
return (ERROR_INVALID_CODE_PAGE);
|
|
}
|
|
|
|
//
|
|
// Store the code page in the process structure
|
|
//
|
|
|
|
Od2ProcessCodePage = ulCodePage;
|
|
|
|
if (Od2ProcessCodePage != SesGrp->Win32OEMCP)
|
|
{
|
|
Od2CurrentCodePageIsOem = FALSE;
|
|
} else
|
|
{
|
|
Od2CurrentCodePageIsOem = TRUE;
|
|
}
|
|
|
|
return( NO_ERROR );
|
|
}
|
|
|
|
|
|
APIRET
|
|
DosQueryCp(
|
|
IN ULONG MaxLengthCodePageList,
|
|
OUT ULONG CodePages[],
|
|
OUT PULONG CountCodePages
|
|
)
|
|
{
|
|
ULONG Count, TotalCount;
|
|
APIRET rc = NO_ERROR;
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "DosQueryCp";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Length %lu, (current CP %lu)\n",
|
|
FuncName, MaxLengthCodePageList, SesGrp->DosCP));
|
|
}
|
|
#endif
|
|
|
|
try
|
|
{
|
|
Od2ProbeForWrite( CountCodePages, sizeof( USHORT ), 1);
|
|
Od2ProbeForWrite( CodePages, MaxLengthCodePageList * sizeof( USHORT ), 1);
|
|
}
|
|
except( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
Od2ExitGP();
|
|
}
|
|
|
|
if ( MaxLengthCodePageList < sizeof(ULONG) )
|
|
{
|
|
*CountCodePages = 0;
|
|
return (ERROR_CPLIST_TOO_SMALL);
|
|
}
|
|
|
|
//
|
|
// Determine the number of code pages to return. This is at least one
|
|
// for the code page associated with the current process, plus N for the
|
|
// N installed code pages.
|
|
//
|
|
|
|
Count = (SesGrp->SecondaryCP) ? 2 : 1;
|
|
|
|
//
|
|
// Determine the maximum number of code pages the caller can accept in
|
|
// their buffer. This is just the buffer length divided by sizeof( ULONG )
|
|
//
|
|
|
|
TotalCount = MaxLengthCodePageList / sizeof( ULONG ) - 1;
|
|
|
|
//
|
|
// Determine how many we will actually return and setup to return
|
|
// an error status if the list will be truncated.
|
|
//
|
|
|
|
if (Count > TotalCount)
|
|
{
|
|
Count = TotalCount;
|
|
rc = ERROR_CPLIST_TOO_SMALL;
|
|
}
|
|
|
|
//
|
|
// Return the actual length of code page information returned in the
|
|
// caller's buffer.
|
|
//
|
|
|
|
*CountCodePages = (Count + 1) * sizeof( ULONG );
|
|
|
|
//
|
|
// Return the code page for the process always.
|
|
//
|
|
|
|
*CodePages++ = Od2ProcessCodePage;
|
|
|
|
//
|
|
// Return the installed code pages.
|
|
//
|
|
|
|
RtlMoveMemory( CodePages, &SesGrp->PrimaryCP, Count * sizeof(ULONG) );
|
|
|
|
//
|
|
// Return success or error code.
|
|
//
|
|
|
|
return( rc );
|
|
}
|
|
|
|
|
|
|
|
APIRET
|
|
Od2InitNls( IN ULONG CodePage,
|
|
IN BOOLEAN StartBySM)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initialize NLS parms
|
|
|
|
Arguments:
|
|
|
|
CodePage - parent proess code-page identifier
|
|
|
|
StartBySm - flag indicates if start by SM (new session) or by
|
|
another process DosExecPgm
|
|
|
|
Return Value:
|
|
|
|
|
|
Note:
|
|
CodePage is relevamt only if (!StartBySM). Otherwise - codepage
|
|
is what os2.exe put in SesGrp->DosCp
|
|
|
|
--*/
|
|
|
|
{
|
|
if ( StartBySM )
|
|
{
|
|
Od2ProcessCodePage = SesGrp->DosCP;
|
|
} else
|
|
{
|
|
Od2ProcessCodePage = CodePage;
|
|
}
|
|
|
|
if (Od2ProcessCodePage != SesGrp->Win32OEMCP)
|
|
{
|
|
Od2CurrentCodePageIsOem = FALSE;
|
|
} else
|
|
{
|
|
Od2CurrentCodePageIsOem = TRUE;
|
|
}
|
|
#if DBG
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("InitNLS: Code Page %lu (OEM flag %lu, StartBySM %lu, SesGrp->DosCp %lu, Arg CP %lu)\n",
|
|
Od2ProcessCodePage, Od2CurrentCodePageIsOem, StartBySM, SesGrp->DosCP, CodePage ));
|
|
}
|
|
#endif
|
|
|
|
Od2SystemRoot = &SesGrp->SystemDirectory[0];
|
|
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
|
|
CHAR Spain437CurrencyStr[] = "\236\0\0\0";
|
|
CHAR Arabic864CurrencyStr[] = "\244\0\0\0";
|
|
|
|
APIRET
|
|
Od2GetCtryInfo( IN ULONG Country,
|
|
IN ULONG CodePage,
|
|
OUT PCOUNTRYINFO CountryInfo)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine fill country info struct after checking the parms
|
|
|
|
Arguments:
|
|
|
|
Country - country code ( 0 - current )
|
|
|
|
CodePage - code-page identifier ( 0 - current )
|
|
|
|
CountryInfo - where to store COUNTRYINFO
|
|
|
|
|
|
Return Value:
|
|
|
|
ERROR_NLS_BAD_TYPE - ?
|
|
ERROR_NLS_NO_CTRY_CODE - ?
|
|
ERROR_NLS_TYPE_NOT_FOUND - ?
|
|
( ERROR_NLS_TABLE_TRUNCATED - by DosGet/QueryCtryInfo )
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG CountryIndex, CodePageIndex;
|
|
PCOUNTRYINFO SrcCountryInfo;
|
|
APIRET RetCode;
|
|
BOOLEAN FromOriginalTable = FALSE;
|
|
APIRET Rc;
|
|
COUNTRYINFO LocalCountryInfo;
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "Od2GetCtryInfo";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Country %u, CodePage %u\n",
|
|
FuncName, Country, CodePage));
|
|
}
|
|
#endif
|
|
|
|
RetCode = Od2GetCtryCp( &Country, &CodePage, &CountryIndex, &CodePageIndex );
|
|
|
|
if ((Country == SesGrp->CountryCode) &&
|
|
((CodePage == SesGrp->PrimaryCP) || (CodePage == SesGrp->SecondaryCP)))
|
|
{
|
|
SrcCountryInfo = &SesGrp->CountryInfo;
|
|
} else if (RetCode)
|
|
{
|
|
Rc = Ow2NlsGetCtryInfo(
|
|
CodePage,
|
|
Country,
|
|
&LocalCountryInfo
|
|
);
|
|
if ( Rc )
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( NLS )
|
|
{
|
|
KdPrint(("%s: RetCode from LPC %lu\n", FuncName, Rc));
|
|
}
|
|
#endif
|
|
return( RetCode );
|
|
}
|
|
SrcCountryInfo = &LocalCountryInfo;
|
|
} else
|
|
{
|
|
SrcCountryInfo = OD2_COUNTRY_TABLE[CountryIndex].pCtryInfo;
|
|
FromOriginalTable = TRUE;
|
|
}
|
|
|
|
RtlMoveMemory(CountryInfo,
|
|
SrcCountryInfo,
|
|
sizeof(COUNTRYINFO));
|
|
|
|
CountryInfo->codepage = CodePage;
|
|
CountryInfo->country = Country;
|
|
|
|
if (FromOriginalTable)
|
|
{
|
|
if ((Country == COUNTRY_SPAIN) &&
|
|
(CodePage == CODEPAGE_US))
|
|
{
|
|
RtlMoveMemory(CountryInfo->szCurrency,
|
|
Spain437CurrencyStr,
|
|
5);
|
|
} else if ((Country == COUNTRY_ARABIC) &&
|
|
(CodePage == CODEPAGE_ARABIC))
|
|
{
|
|
RtlMoveMemory(CountryInfo->szCurrency,
|
|
Arabic864CurrencyStr,
|
|
5);
|
|
}
|
|
}
|
|
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
|
|
APIRET
|
|
Od2GetDBCSEv( IN ULONG Country,
|
|
IN ULONG CodePage,
|
|
IN OUT PUCHAR DBCSEv,
|
|
OUT PULONG StringLength)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine fill DBCS environment vector after checking the parms
|
|
|
|
Arguments:
|
|
|
|
Country - country code ( 0 - current )
|
|
|
|
CodePage - code-page identifier ( 0 - current )
|
|
|
|
DBVSEv - where to store the vector
|
|
|
|
StringLength - where to retutn the actual length of the output vector
|
|
|
|
|
|
Return Value:
|
|
|
|
ERROR_NLS_BAD_TYPE - ?
|
|
ERROR_NLS_NO_CTRY_CODE - ?
|
|
ERROR_NLS_TYPE_NOT_FOUND - ?
|
|
( ERROR_NLS_NO_COUNTRY_FILE - we don't keep info in file )
|
|
( ERROR_NLS_OPEN_FAILED - we don't keep info in file )
|
|
( ERROR_NLS_TABLE_TRUNCATED - by DosGet/QueryDBCSEv )
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG CountryIndex, CodePageIndex;
|
|
APIRET RetCode;
|
|
POD2_DBCS_VECTOR_ENTRY SrcDBCSVec;
|
|
OD2_DBCS_VECTOR_ENTRY LocalDBCSVec;
|
|
APIRET Rc;
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "Od2GetDBCSEv";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Country %u, CodePage %u\n",
|
|
FuncName, Country, CodePage));
|
|
}
|
|
#endif
|
|
RetCode = Od2GetCtryCp( &Country, &CodePage, &CountryIndex, &CodePageIndex );
|
|
|
|
if (((CodePage == SesGrp->PrimaryCP) || (CodePage == SesGrp->SecondaryCP)) &&
|
|
((Country == SesGrp->CountryCode) || !RetCode))
|
|
{
|
|
if(CodePage == SesGrp->PrimaryCP)
|
|
{
|
|
SrcDBCSVec = &SesGrp->PriDBCSVec;
|
|
} else
|
|
{
|
|
SrcDBCSVec = &SesGrp->SecDBCSVec;
|
|
}
|
|
} else if (RetCode)
|
|
{
|
|
#ifdef JAPAN
|
|
// MSKK Jul.02.1993 V-AkihiS
|
|
// Chechk country code, because Ow2NlsGetDBCSEn does not check country code.
|
|
if (Country != SesGrp->CountryCode)
|
|
{
|
|
return( RetCode );
|
|
}
|
|
#endif
|
|
Rc = Ow2NlsGetDBCSEn(
|
|
CodePage,
|
|
&LocalDBCSVec
|
|
);
|
|
if ( Rc )
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( NLS )
|
|
{
|
|
KdPrint(("%s: RetCode from LPC %lu\n", FuncName, Rc));
|
|
}
|
|
#endif
|
|
return( RetCode );
|
|
}
|
|
SrcDBCSVec = &LocalDBCSVec;
|
|
} else
|
|
{
|
|
SrcDBCSVec = &OD2_DBCS_VECTOR_TABLE[OD2_CODEPAGE_TABLE[CodePageIndex].DBCSVecIndex];
|
|
}
|
|
|
|
*StringLength = SrcDBCSVec->VectorSize;
|
|
|
|
RtlMoveMemory(DBCSEv,
|
|
SrcDBCSVec->Vector,
|
|
*StringLength);
|
|
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
|
|
APIRET
|
|
Od2GetCaseMapTable(
|
|
IN ULONG Country,
|
|
IN ULONG CodePage,
|
|
OUT PUCHAR CaseMapTable)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine fill creates a case map table for the CP after
|
|
checking the parms
|
|
|
|
Arguments:
|
|
|
|
Country - country code ( 0 - current )
|
|
|
|
CodePage - code-page identifier ( 0 - current )
|
|
|
|
CaseMapTable - where to store the case map table
|
|
|
|
|
|
Return Value:
|
|
|
|
ERROR_NLS_BAD_TYPE - ?
|
|
ERROR_NLS_NO_CTRY_CODE - ?
|
|
ERROR_NLS_TYPE_NOT_FOUND - ?
|
|
( ERROR_NLS_NO_COUNTRY_FILE - we don't keep info in file )
|
|
( ERROR_NLS_OPEN_FAILED - we don't keep info in file )
|
|
( ERROR_NLS_TABLE_TRUNCATED - by DosGet/QueryDBCSEv )
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG CountryIndex, i, CodePageIndex;
|
|
PUCHAR SrcTable, CPFixTable = NULL, CtryFixTable = NULL;
|
|
APIRET RetCode;
|
|
UCHAR LocalTable[256];
|
|
APIRET Rc;
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "Od2GetCaseMapTable";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Country %u, CodePage %u\n",
|
|
FuncName, Country, CodePage));
|
|
}
|
|
#endif
|
|
RetCode = Od2GetCtryCp( &Country, &CodePage, &CountryIndex, &CodePageIndex );
|
|
|
|
if ((Country == SesGrp->CountryCode) &&
|
|
((CodePage == SesGrp->PrimaryCP) || (CodePage == SesGrp->SecondaryCP)))
|
|
{
|
|
if(CodePage == SesGrp->PrimaryCP)
|
|
{
|
|
SrcTable = SesGrp->PriCaseMapTable;
|
|
} else
|
|
{
|
|
SrcTable = SesGrp->SecCaseMapTable;
|
|
}
|
|
} else
|
|
if (RetCode)
|
|
{
|
|
Rc = Ow2NlsGetCaseMapTable(
|
|
CodePage,
|
|
Country,
|
|
&LocalTable[0]
|
|
);
|
|
if ( Rc )
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( NLS )
|
|
{
|
|
KdPrint(("%s: RetCode from LPC %lu\n", FuncName, Rc));
|
|
}
|
|
#endif
|
|
return( RetCode );
|
|
}
|
|
SrcTable = &LocalTable[0];
|
|
} else
|
|
{
|
|
SrcTable = Od2BaseCaseMapTable;
|
|
CPFixTable = OD2_CASEMAP_TABLE[OD2_CODEPAGE_TABLE[CodePageIndex].CaseMapIndex];
|
|
if (CodePage == 437)
|
|
{
|
|
CtryFixTable = OD2_FIX_CASEMAP_TABLE[OD2_COUNTRY_TABLE[CountryIndex].CaseMapFixTableIndex];
|
|
}
|
|
}
|
|
|
|
RtlMoveMemory(CaseMapTable,
|
|
SrcTable,
|
|
256);
|
|
|
|
if (CPFixTable)
|
|
{
|
|
for ( i = 0 ; (CPFixTable[i] || CPFixTable[i + 1]) ; i += 2 )
|
|
{
|
|
CaseMapTable[CPFixTable[i]] = CPFixTable[i + 1];
|
|
}
|
|
}
|
|
|
|
if (CtryFixTable)
|
|
{
|
|
for ( i = 0 ; (CtryFixTable[i] || CtryFixTable[i + 1]) ; i += 2 )
|
|
{
|
|
CaseMapTable[CtryFixTable[i]] = CtryFixTable[i + 1];
|
|
}
|
|
}
|
|
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
|
|
APIRET
|
|
Od2GetCollateTable(
|
|
IN ULONG Country,
|
|
IN ULONG CodePage,
|
|
OUT PUCHAR CollateTable)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine fill creates a Collate table for the CP after
|
|
checking the parms
|
|
|
|
Arguments:
|
|
|
|
Country - country code ( 0 - current )
|
|
|
|
CodePage - code-page identifier ( 0 - current )
|
|
|
|
CollateTable - where to store the Collate table
|
|
|
|
|
|
Return Value:
|
|
|
|
ERROR_NLS_BAD_TYPE - ?
|
|
ERROR_NLS_NO_CTRY_CODE - ?
|
|
ERROR_NLS_TYPE_NOT_FOUND - ?
|
|
( ERROR_NLS_NO_COUNTRY_FILE - we don't keep info in file )
|
|
( ERROR_NLS_OPEN_FAILED - we don't keep info in file )
|
|
( ERROR_NLS_TABLE_TRUNCATED - by DosGet/QueryDBCSEv )
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG CountryIndex, i, CodePageIndex;
|
|
PUCHAR SrcTable, CPFixTable = NULL, CtryFixTable = NULL;
|
|
APIRET RetCode;
|
|
// UCHAR LocalTable[256];
|
|
#if DBG
|
|
APIRET Rc=0;
|
|
PSZ FuncName;
|
|
|
|
FuncName = "Od2GetCollateTable";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: Country %u, CodePage %u\n",
|
|
FuncName, Country, CodePage));
|
|
}
|
|
#endif // DBG
|
|
RetCode = Od2GetCtryCp( &Country, &CodePage, &CountryIndex, &CodePageIndex );
|
|
|
|
// if ((Country == SesGrp->CountryCode) &&
|
|
// ((CodePage == SesGrp->PrimaryCP) || (CodePage == SesGrp->SecondaryCP)))
|
|
// {
|
|
// if(CodePage == SesGrp->PrimaryCP)
|
|
// {
|
|
// SrcTable = SesGrp->PriCollateTable;
|
|
// } else
|
|
// {
|
|
// SrcTable = SesGrp->SecCollateTable;
|
|
// }
|
|
// } else
|
|
if (RetCode)
|
|
{
|
|
// Rc = Ow2NlsGetCollateTable(
|
|
// CodePage,
|
|
// Country,
|
|
// &LocalTable[0]
|
|
// );
|
|
// if ( Rc )
|
|
// {
|
|
#if DBG
|
|
|
|
// BUGBUG: debug statement below prints random Rc value
|
|
IF_OD2_DEBUG( NLS )
|
|
{
|
|
KdPrint(("%s: RetCode from LPC %lu\n", FuncName, Rc));
|
|
}
|
|
#endif
|
|
return( RetCode );
|
|
// }
|
|
// SrcTable = &LocalTable[0];
|
|
} else
|
|
{
|
|
SrcTable = Od2BaseCollateTable;
|
|
CPFixTable = OD2_COLLATE_CP_TABLE[OD2_CODEPAGE_TABLE[CodePageIndex].CollateIndex];
|
|
|
|
for ( i = 0 ; OD2_COLLATE_CTRY_TABLE[i].Country ; i++ )
|
|
{
|
|
if ((OD2_COLLATE_CTRY_TABLE[i].Country == Country) &&
|
|
(OD2_COLLATE_CTRY_TABLE[i].CodePage == CodePage))
|
|
{
|
|
CtryFixTable = OD2_COLLATE_CTRY_TABLE[i].FixTable;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
RtlMoveMemory(CollateTable,
|
|
SrcTable,
|
|
256);
|
|
|
|
if (CPFixTable)
|
|
{
|
|
for ( i = 0 ; (CPFixTable[i] || CPFixTable[i + 1]) ; i += 2 )
|
|
{
|
|
CollateTable[CPFixTable[i]] = CPFixTable[i + 1];
|
|
}
|
|
}
|
|
|
|
if (CtryFixTable)
|
|
{
|
|
for ( i = 0 ; (CtryFixTable[i] || CtryFixTable[i + 1]) ; i += 2 )
|
|
{
|
|
CollateTable[CtryFixTable[i]] = CtryFixTable[i + 1];
|
|
}
|
|
}
|
|
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
|
|
APIRET
|
|
Od2GetCtryCp( IN OUT PULONG Country,
|
|
IN OUT PULONG CodePage,
|
|
OUT PULONG CountryTableIndex,
|
|
OUT PULONG CodePageTableIndex)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine checks the country and code-page parms.
|
|
If zero (default) it set them properly.
|
|
If exist in table, return index.
|
|
|
|
Arguments:
|
|
|
|
Country - where to read from and update the country code ( 0 - current )
|
|
|
|
CodePage - where to read from and update the code-page identifier ( 0 - current )
|
|
|
|
CountryTableIndex - where to store the index for the language
|
|
|
|
CodePageTableIndex - where to store the index for the code page
|
|
|
|
Return Value:
|
|
|
|
ERROR_NLS_BAD_TYPE - ?
|
|
ERROR_NLS_NO_CTRY_CODE - illegal country code or illegal code page
|
|
ERROR_NLS_TYPE_NOT_FOUND - ?
|
|
( ERROR_NLS_NO_COUNTRY_FILE - we don't keep info in file )
|
|
( ERROR_NLS_OPEN_FAILED - we don't keep info in file )
|
|
( ERROR_NLS_TABLE_TRUNCATED - by DosGet/QueryCtryInfo )
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG CountryIndex;
|
|
#if DBG
|
|
PSZ FuncName;
|
|
|
|
FuncName = "Od2GetCtryCp";
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: enter\n", FuncName));
|
|
}
|
|
#endif
|
|
|
|
if ( !*Country )
|
|
{
|
|
*Country = SesGrp->CountryCode;
|
|
#if DBG
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: country set to current %lu\n",
|
|
FuncName, SesGrp->CountryCode));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if ( !*CodePage )
|
|
{
|
|
*CodePage = Od2ProcessCodePage;
|
|
#if DBG
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: code page set to current %lu\n",
|
|
FuncName, Od2ProcessCodePage));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
for ( CountryIndex = 0 ; ( OD2_COUNTRY_TABLE[CountryIndex].Country &&
|
|
( OD2_COUNTRY_TABLE[CountryIndex].Country != *Country )) ;
|
|
CountryIndex++ );
|
|
|
|
if ( !OD2_COUNTRY_TABLE[CountryIndex].Country )
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: no such country %lu\n",
|
|
FuncName, *Country));
|
|
}
|
|
#endif
|
|
return (ERROR_NLS_NO_CTRY_CODE);
|
|
}
|
|
|
|
if ( *CodePage == OD2_CODEPAGE_TABLE[OD2_COUNTRY_TABLE[CountryIndex].CodePageIndex1].CodePage )
|
|
{
|
|
*CodePageTableIndex = OD2_COUNTRY_TABLE[CountryIndex].CodePageIndex1;
|
|
} else if ( *CodePage == OD2_CODEPAGE_TABLE[OD2_COUNTRY_TABLE[CountryIndex].CodePageIndex2].CodePage )
|
|
{
|
|
*CodePageTableIndex = OD2_COUNTRY_TABLE[CountryIndex].CodePageIndex2;
|
|
#ifdef DBCS
|
|
// MSKK Apr.19.1993 V-AkihiS
|
|
// Support CodePage 850(CODEPAGE_MULTI)
|
|
} else if ( *CodePage == CODEPAGE_MULTI )
|
|
{
|
|
*CodePageTableIndex = INDEX_CODEPAGE_MULTI;
|
|
#endif
|
|
} else
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG(NLS)
|
|
{
|
|
KdPrint(("%s: no such code page %lu\n",
|
|
FuncName, *CodePage));
|
|
}
|
|
#endif
|
|
return (ERROR_NLS_NO_CTRY_CODE);
|
|
}
|
|
|
|
/* In DBCS countries, when CP == US then info is according to USA. */
|
|
|
|
if ((( *Country == COUNTRY_JAPAN ) ||
|
|
( *Country == COUNTRY_TAIWAN ) ||
|
|
( *Country == COUNTRY_PRCHINA ) ||
|
|
( *Country == COUNTRY_SOUTH_KOREA )) &&
|
|
#ifdef DBCS
|
|
// MSKK Apr.24.1993
|
|
// Support CodePage 850(CODEPAGE_MULTI)
|
|
(( *CodePage == CODEPAGE_US ) || ( *CodePage == CODEPAGE_MULTI)))
|
|
#else
|
|
( *CodePage == CODEPAGE_US ))
|
|
#endif
|
|
{
|
|
CountryIndex = 0; // US must be first in OD2_COUNTRY_TABLE
|
|
}
|
|
|
|
*CountryTableIndex = CountryIndex;
|
|
|
|
return (NO_ERROR);
|
|
}
|