/*++
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);
}