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.
1410 lines
36 KiB
1410 lines
36 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
srvnls.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the support for NLS for the OS/2 Subsystem Server
|
|
|
|
Author:
|
|
|
|
Michael Jarus (mjarus) 25-Aug-1992
|
|
|
|
Environment:
|
|
|
|
User Mode Only
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <windows.h>
|
|
#define WIN32_ONLY
|
|
#include "sesport.h"
|
|
#include "os2nt.h"
|
|
#include "os2dbg.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "os2crt.h"
|
|
|
|
// Flag to let OS2SRV know whether or not to ignore LOGOFF (when started as a service)
|
|
extern BOOLEAN fService;
|
|
|
|
//
|
|
// Counted String
|
|
//
|
|
|
|
typedef struct _STRING {
|
|
USHORT Length;
|
|
USHORT MaximumLength;
|
|
#ifdef MIDL_PASS
|
|
[size_is(MaximumLength), length_is(Length) ]
|
|
#endif // MIDL_PASS
|
|
PCHAR Buffer;
|
|
} STRING;
|
|
typedef STRING *PSTRING;
|
|
|
|
typedef STRING ANSI_STRING;
|
|
typedef PSTRING PANSI_STRING;
|
|
|
|
//
|
|
// Unicode strings are counted 16-bit character strings. If they are
|
|
// NULL terminated, Length does not include trailing NULL.
|
|
//
|
|
|
|
typedef struct _UNICODE_STRING {
|
|
USHORT Length;
|
|
USHORT MaximumLength;
|
|
#ifdef MIDL_PASS
|
|
[size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
|
|
#else // MIDL_PASS
|
|
PWSTR Buffer;
|
|
#endif // MIDL_PASS
|
|
} UNICODE_STRING;
|
|
typedef UNICODE_STRING *PUNICODE_STRING;
|
|
|
|
VOID
|
|
RtlInitUnicodeString(
|
|
PUNICODE_STRING DestinationString,
|
|
PCWSTR SourceString
|
|
);
|
|
|
|
APIRET
|
|
Or2UnicodeStringToMBString(
|
|
PANSI_STRING DestinationString,
|
|
PUNICODE_STRING SourceString,
|
|
BOOLEAN AllocateDestinationString);
|
|
|
|
ULONG Or2ProcessCodePage;
|
|
ULONG Or2CurrentCodePageIsOem;
|
|
PSZ Os2ServerSystemDirectory;
|
|
HKEY KeyboardLayoutKeyHandle = NULL;
|
|
HANDLE hKeyEvent;
|
|
BOOL KeyboardFromConfigSysRegistry = FALSE;
|
|
OS2_SES_GROUP_PARMS ServerSesGrp;
|
|
|
|
#define XCPT_SIGNAL_KILLPROC 3
|
|
#define WBUFFER_SIZE 6
|
|
|
|
BOOL
|
|
Os2SrvHandleCtrlEvent(
|
|
IN int CtrlType
|
|
);
|
|
|
|
ULONG
|
|
Or2NlsUnicodeStringToInteger(
|
|
IN WCHAR *WString,
|
|
IN ULONG Base
|
|
);
|
|
|
|
extern WCHAR Os2SystemDirectory[];
|
|
extern ULONG Os2Debug;
|
|
extern ULONG Os2ssCountryCode;
|
|
extern ULONG Os2ssCodePage[2];
|
|
extern UCHAR Os2ssKeyboardLayout[2];
|
|
#if PMNT
|
|
extern UCHAR Os2ssKeyboardName[4];
|
|
#endif
|
|
extern ULONG Os2ssKeysOnFlag;
|
|
extern ULONG Os2SrvExitNow;
|
|
|
|
#if DBG
|
|
BYTE SetEventHandlersAndErrorModeStr[] = "SetEventHandlersAndErrorMode";
|
|
BYTE Os2InitializeNLSStr[] = "Os2InitializeNLS";
|
|
#endif
|
|
|
|
typedef struct _LANG_TABLE_ENTRY {
|
|
ULONG Ctry;
|
|
ULONG Lang;
|
|
ULONG SubLang;
|
|
ULONG Cp1;
|
|
ULONG Cp2;
|
|
ULONG MessageLanguage;
|
|
} LANG_TABLE_ENTRY, *PLANG_TABLE_ENTRY;
|
|
|
|
|
|
PLANG_TABLE_ENTRY
|
|
CheckCountryCodePage(
|
|
IN ULONG CountryCode,
|
|
IN ULONG *Os2srvCodePages,
|
|
OUT ULONG *CodePages
|
|
);
|
|
|
|
ULONG
|
|
InitKeyboardRegistry(
|
|
VOID
|
|
);
|
|
|
|
ULONG
|
|
ReadKeyboardLayoutFromRegistry(
|
|
OUT PULONG pKeyBoardCountry
|
|
);
|
|
|
|
LANG_TABLE_ENTRY LANG_TABLE [] =
|
|
{
|
|
{ /* United States */
|
|
|
|
CTRY_UNITED_STATES,
|
|
LANG_ENGLISH,
|
|
SUBLANG_ENGLISH_US,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_ENGLISH,
|
|
},
|
|
{ /* Canadian-French */
|
|
|
|
CTRY_CANADA,
|
|
LANG_FRENCH,
|
|
SUBLANG_FRENCH_CANADIAN,
|
|
CODEPAGE_CANADIAN,
|
|
CODEPAGE_MULTI,
|
|
LANG_ENGLISH,
|
|
},
|
|
{ /* Latin-America */
|
|
|
|
COUNTRY_LATIN_AMERICA,
|
|
LANG_SPANISH,
|
|
SUBLANG_SPANISH_MEXICAN,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_SPANISH,
|
|
},
|
|
{ /* Netherlands */
|
|
|
|
CTRY_NETHERLANDS,
|
|
LANG_DUTCH,
|
|
SUBLANG_DUTCH,
|
|
CODEPAGE_MULTI,
|
|
CODEPAGE_US,
|
|
LANG_DUTCH,
|
|
},
|
|
{ /* Belgiun */
|
|
|
|
CTRY_BELGIUM,
|
|
LANG_FRENCH,
|
|
SUBLANG_FRENCH_BELGIAN,
|
|
CODEPAGE_MULTI,
|
|
CODEPAGE_US,
|
|
LANG_DUTCH,
|
|
},
|
|
{ /* France */
|
|
|
|
CTRY_FRANCE,
|
|
LANG_FRENCH,
|
|
SUBLANG_FRENCH,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_FRENCH,
|
|
},
|
|
{ /* Spain */
|
|
|
|
CTRY_SPAIN,
|
|
LANG_SPANISH,
|
|
SUBLANG_SPANISH,
|
|
CODEPAGE_MULTI,
|
|
CODEPAGE_US,
|
|
LANG_SPANISH,
|
|
},
|
|
{ /* Italy */
|
|
|
|
CTRY_ITALY,
|
|
LANG_ITALIAN,
|
|
SUBLANG_ITALIAN,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_ITALIAN,
|
|
},
|
|
{ /* Switzerland */
|
|
|
|
CTRY_SWITZERLAND,
|
|
LANG_GERMAN,
|
|
SUBLANG_GERMAN_SWISS,
|
|
CODEPAGE_MULTI,
|
|
CODEPAGE_US,
|
|
LANG_GERMAN,
|
|
},
|
|
{ /* Austria */
|
|
|
|
CTRY_AUSTRIA,
|
|
LANG_GERMAN,
|
|
SUBLANG_GERMAN_AUSTRIAN,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_GERMAN,
|
|
},
|
|
{ /* United Kingdom */
|
|
|
|
CTRY_UNITED_KINGDOM,
|
|
LANG_ENGLISH,
|
|
SUBLANG_ENGLISH_UK,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_ENGLISH,
|
|
},
|
|
{ /* Denmark */
|
|
|
|
CTRY_DENMARK,
|
|
LANG_DANISH,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_MULTI,
|
|
CODEPAGE_NORDIC,
|
|
LANG_DANISH,
|
|
},
|
|
{ /* Sweden */
|
|
|
|
CTRY_SWEDEN,
|
|
LANG_SWEDISH,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_SWEDISH,
|
|
},
|
|
{ /* Norway */
|
|
|
|
CTRY_NORWAY,
|
|
LANG_NORWEGIAN,
|
|
SUBLANG_NORWEGIAN_BOKMAL, /* or SUBLANG_NORWEGIAN_NYNORSK */
|
|
CODEPAGE_MULTI,
|
|
CODEPAGE_NORDIC,
|
|
LANG_NORWEGIAN,
|
|
},
|
|
{ /* Germany */
|
|
|
|
CTRY_GERMANY,
|
|
LANG_GERMAN,
|
|
SUBLANG_GERMAN,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_GERMAN,
|
|
},
|
|
{ /* Mexico */
|
|
|
|
CTRY_MEXICO,
|
|
LANG_SPANISH,
|
|
SUBLANG_SPANISH_MEXICAN,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_SPANISH,
|
|
},
|
|
{ /* Brazil */
|
|
|
|
CTRY_BRAZIL,
|
|
LANG_PORTUGUESE,
|
|
SUBLANG_PORTUGUESE_BRAZILIAN,
|
|
CODEPAGE_PORTUGESE,
|
|
CODEPAGE_MULTI,
|
|
LANG_PORTUGUESE,
|
|
},
|
|
{ /* Australia */
|
|
|
|
CTRY_AUSTRALIA,
|
|
LANG_ENGLISH,
|
|
SUBLANG_ENGLISH_AUS,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_ENGLISH,
|
|
},
|
|
{ /* New Zeland */
|
|
|
|
CTRY_NEW_ZEALAND,
|
|
LANG_ENGLISH,
|
|
SUBLANG_ENGLISH_NZ,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_ENGLISH,
|
|
},
|
|
{ /* Portugal */
|
|
|
|
CTRY_PORTUGAL,
|
|
LANG_PORTUGUESE,
|
|
SUBLANG_PORTUGUESE,
|
|
CODEPAGE_PORTUGESE,
|
|
CODEPAGE_MULTI,
|
|
LANG_PORTUGUESE,
|
|
},
|
|
{ /* Ireland */
|
|
|
|
CTRY_IRELAND,
|
|
LANG_ENGLISH,
|
|
SUBLANG_ENGLISH_UK,
|
|
CODEPAGE_US,
|
|
CODEPAGE_MULTI,
|
|
LANG_ENGLISH,
|
|
},
|
|
{ /* Iceland */
|
|
|
|
CTRY_ICELAND,
|
|
LANG_ICELANDIC,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_MULTI,
|
|
CODEPAGE_NORDIC,
|
|
LANG_DANISH,
|
|
},
|
|
{ /* Finland */
|
|
|
|
CTRY_FINLAND,
|
|
LANG_FINNISH,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_MULTI,
|
|
CODEPAGE_US,
|
|
LANG_FINNISH,
|
|
},
|
|
{ /* Japan */
|
|
|
|
CTRY_JAPAN,
|
|
LANG_JAPANESE,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_JAPAN,
|
|
CODEPAGE_US,
|
|
LANG_JAPANESE,
|
|
},
|
|
{ /* Korea */
|
|
|
|
CTRY_SOUTH_KOREA,
|
|
LANG_KOREAN,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_KOREA,
|
|
CODEPAGE_US,
|
|
LANG_KOREAN,
|
|
},
|
|
#if 0
|
|
{ /* Taiwan */
|
|
|
|
CTRY_TAIWAN,
|
|
LANG_THAI,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_TAIWAN,
|
|
CODEPAGE_US,
|
|
LANG_THAI,
|
|
},
|
|
{ /* Taiwan */
|
|
|
|
COUNTRY_TAIWAN,
|
|
LANG_THAI,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_TAIWAN,
|
|
CODEPAGE_US,
|
|
LANG_THAI,
|
|
},
|
|
#ifdef OS2SS_INCLUDE_HEBREW
|
|
{ /* Hebrew speaking */
|
|
|
|
COUNTRY_HEBREW,
|
|
LANG_HEBREW,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_HEBREW,
|
|
CODEPAGE_MULTI,
|
|
LANG_ENGLISH,
|
|
},
|
|
#endif
|
|
#ifdef OS2SS_INCLUDE_ARABIC
|
|
{ /* Arabic speaking */
|
|
|
|
COUNTRY_ARABIC,
|
|
LANG_ARABIC,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_ARABIC,
|
|
CODEPAGE_MULTI,
|
|
LANG_ENGLISH,
|
|
},
|
|
#endif
|
|
#endif
|
|
#ifdef OS2SS_INCLUDE_PRCHINA
|
|
{ /* Peoples Republic of China */
|
|
|
|
CTRY_PRCHINA,
|
|
LANG_CHINESE,
|
|
SUBLANG_NEUTRAL,
|
|
CODEPAGE_PRC,
|
|
CODEPAGE_US,
|
|
LANG_CHINESE,
|
|
},
|
|
#endif
|
|
{ /* End of Table */
|
|
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
}
|
|
};
|
|
|
|
|
|
#ifdef JAPAN
|
|
// MSKK Nov.02.1992 V-AkihiS
|
|
UINT CPTable[] =
|
|
{
|
|
932, 437, 850
|
|
, 0 /* end */
|
|
};
|
|
#else
|
|
UINT CPTable[] =
|
|
{
|
|
437, 850
|
|
, 860, 862, 863, 864, 865, 932, 934, 936, 938 //WinNLS doesn't support NLS yet
|
|
, 0 /* end */
|
|
};
|
|
#endif
|
|
|
|
|
|
VOID
|
|
Os2SrvExitProcess(
|
|
IN ULONG uExitCode
|
|
)
|
|
{
|
|
ExitProcess((UINT) uExitCode);
|
|
}
|
|
|
|
|
|
BOOL
|
|
Os2SrvEventHandlerRoutine(
|
|
IN DWORD CtrlType
|
|
)
|
|
{
|
|
BOOL Rc = TRUE;
|
|
int Signal = XCPT_SIGNAL_KILLPROC;
|
|
|
|
#if DBG
|
|
IF_OS2_DEBUG( SIG )
|
|
{
|
|
KdPrint(("OS2SRV(EventHandlerRoutine): Ctr-Type %u\n", CtrlType));
|
|
}
|
|
#endif
|
|
|
|
if ((CtrlType == CTRL_LOGOFF_EVENT) && fService)
|
|
{
|
|
#if DBG
|
|
DbgPrint("OS2SRV: running as a service - ignoring CTRL_LOGOFF_EVENT !\n");
|
|
#endif //DBG
|
|
return FALSE;
|
|
}
|
|
|
|
if ((CtrlType == CTRL_CLOSE_EVENT) ||
|
|
(CtrlType == CTRL_LOGOFF_EVENT) ||
|
|
(CtrlType == CTRL_SHUTDOWN_EVENT))
|
|
{
|
|
Rc = Os2SrvHandleCtrlEvent(Signal);
|
|
}
|
|
|
|
return(Rc);
|
|
}
|
|
|
|
|
|
VOID
|
|
SetEventHandlersAndErrorMode(
|
|
IN BOOL fSet
|
|
)
|
|
{
|
|
if (fSet)
|
|
{
|
|
Os2SrvExitNow = 0;
|
|
SetErrorMode(1);
|
|
}
|
|
|
|
Or2WinSetConsoleCtrlHandler(
|
|
#if DBG
|
|
SetEventHandlersAndErrorModeStr,
|
|
#endif
|
|
Os2SrvEventHandlerRoutine,
|
|
fSet
|
|
);
|
|
}
|
|
|
|
|
|
APIRET
|
|
Os2InitializeNLS()
|
|
{
|
|
PLANG_TABLE_ENTRY pLangEntry;
|
|
ULONG i, j, AvailableCp[256], NumAvailableCp, TestCountry;
|
|
USHORT LocaleLang;
|
|
ANSI_STRING SystemDirectory_A;
|
|
UNICODE_STRING SystemDirectory_U;
|
|
|
|
memset(&ServerSesGrp,
|
|
0,
|
|
sizeof(OS2_SES_GROUP_PARMS));
|
|
/*
|
|
* Get Current CP, Country, Language and Console CP
|
|
*/
|
|
|
|
ServerSesGrp.Win32OEMCP = Or2WinGetOEMCP(
|
|
#if DBG
|
|
Os2InitializeNLSStr
|
|
#endif
|
|
);
|
|
ServerSesGrp.Win32ACP = Or2WinGetACP(
|
|
#if DBG
|
|
Os2InitializeNLSStr
|
|
#endif
|
|
);
|
|
ServerSesGrp.Win32LANGID = (ULONG)Or2WinGetUserDefaultLangID(
|
|
#if DBG
|
|
Os2InitializeNLSStr
|
|
#endif
|
|
);
|
|
ServerSesGrp.Win32LCID = (ULONG)Or2WinGetThreadLocale(
|
|
#if DBG
|
|
Os2InitializeNLSStr
|
|
#endif
|
|
);
|
|
|
|
Or2NlsGetCountryFromLocale((LCID)ServerSesGrp.Win32LCID, &ServerSesGrp.Win32CountryCode);
|
|
|
|
/*
|
|
* find all available CPs
|
|
*/
|
|
|
|
for ( i = 0, NumAvailableCp = 0 ; CPTable[i] && (NumAvailableCp < 200) ; i++ )
|
|
{
|
|
if( Or2WinIsValidCodePage(
|
|
#if DBG
|
|
Os2InitializeNLSStr,
|
|
#endif
|
|
CPTable[i]
|
|
))
|
|
{
|
|
AvailableCp[NumAvailableCp++] = CPTable[i];
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Try to work with the definitions in the registry
|
|
*/
|
|
|
|
ServerSesGrp.Os2srvUseRegisterInfo = TRUE;
|
|
|
|
if (pLangEntry = CheckCountryCodePage(Os2ssCountryCode,
|
|
Os2ssCodePage,
|
|
&ServerSesGrp.PrimaryCP))
|
|
{
|
|
while (TRUE) // this is done to enable break
|
|
{
|
|
if (ServerSesGrp.SecondaryCP)
|
|
{
|
|
for ( i = 0 ; (i < NumAvailableCp) &&
|
|
(AvailableCp[i] != ServerSesGrp.SecondaryCP) ; i++ ) ;
|
|
|
|
if ( i == NumAvailableCp )
|
|
{
|
|
ServerSesGrp.SecondaryCP = 0;
|
|
}
|
|
}
|
|
|
|
for ( i = 0 ; (i < NumAvailableCp) &&
|
|
(AvailableCp[i] != ServerSesGrp.PrimaryCP) ; i++ ) ;
|
|
|
|
if ( i == NumAvailableCp )
|
|
{
|
|
ServerSesGrp.PrimaryCP = ServerSesGrp.SecondaryCP;
|
|
ServerSesGrp.SecondaryCP = 0;
|
|
}
|
|
|
|
if (ServerSesGrp.PrimaryCP)
|
|
{
|
|
ServerSesGrp.CountryCode = Os2ssCountryCode;
|
|
ServerSesGrp.LanguageID = pLangEntry->MessageLanguage;
|
|
ServerSesGrp.Os2ssLCID = (ULONG)
|
|
MAKELANGID(pLangEntry->Lang, pLangEntry->SubLang);
|
|
|
|
// check CTRY, LANG legalty. (fall down if fail)
|
|
|
|
Or2NlsGetCountryFromLocale(
|
|
(LCID)ServerSesGrp.Os2ssLCID,
|
|
&TestCountry
|
|
);
|
|
|
|
if (TestCountry == Os2ssCountryCode)
|
|
{
|
|
// BUGBUG: change locale
|
|
|
|
Or2WinSetThreadLocale(
|
|
#if DBG
|
|
Os2InitializeNLSStr,
|
|
#endif
|
|
(LCID)ServerSesGrp.Os2ssLCID
|
|
);
|
|
#if DBG
|
|
IF_OS2_DEBUG( NLS )
|
|
{
|
|
KdPrint(("InitNls: user NLS definitions: Ctry %lu, CP %lu & %lu\n",
|
|
Os2ssCountryCode, Os2ssCodePage[0], Os2ssCodePage[1]));
|
|
}
|
|
#endif
|
|
break; // SUCCESS
|
|
}
|
|
}
|
|
#if DBG
|
|
IF_OS2_DEBUG( NLS )
|
|
{
|
|
KdPrint(("InitNls: illegal NLS definitions: Ctry %lu, CP %lu & %lu\n",
|
|
Os2ssCountryCode, Os2ssCodePage[0], Os2ssCodePage[1]));
|
|
}
|
|
#endif
|
|
pLangEntry = NULL;
|
|
break; // FAIL
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Inherit NLS definitions from Win32
|
|
*/
|
|
|
|
if (pLangEntry == NULL)
|
|
{
|
|
ServerSesGrp.Os2srvUseRegisterInfo = FALSE;
|
|
ServerSesGrp.PrimaryCP = ServerSesGrp.Win32OEMCP;
|
|
ServerSesGrp.CountryCode = ServerSesGrp.Win32CountryCode;
|
|
ServerSesGrp.Os2ssLCID = ServerSesGrp.Win32LCID;
|
|
#ifdef JAPAN
|
|
// MSKK Nov.04.1992 V-AkihiS
|
|
ServerSesGrp.LanguageID = LANG_JAPANESE;
|
|
#else
|
|
ServerSesGrp.LanguageID = LANG_ENGLISH;
|
|
#endif
|
|
|
|
/*
|
|
* Find if we can second code page to this country
|
|
*/
|
|
|
|
for ( j = 0 ; (LANG_TABLE[j].Ctry) && // find the country entry
|
|
(LANG_TABLE[j].Ctry != ServerSesGrp.CountryCode) ; j++ );
|
|
|
|
if (LANG_TABLE[j].Ctry == ServerSesGrp.CountryCode)
|
|
{
|
|
if (ServerSesGrp.PrimaryCP != LANG_TABLE[j].Cp1)
|
|
{
|
|
// OEM CP is not the Cp1, so if Cp1 is available add it as secondary CP
|
|
|
|
for ( i = 0 ; (i < NumAvailableCp) &&
|
|
(AvailableCp[i] != LANG_TABLE[j].Cp1) ; i++ ) ;
|
|
|
|
if ( i < NumAvailableCp )
|
|
{
|
|
ServerSesGrp.SecondaryCP = LANG_TABLE[j].Cp1;
|
|
}
|
|
}
|
|
|
|
if ((ServerSesGrp.SecondaryCP == 0) &&
|
|
(ServerSesGrp.PrimaryCP != LANG_TABLE[j].Cp2))
|
|
{
|
|
// OEM CP is not the Cp2, so if Cp2 is available add it as secondary CP
|
|
|
|
for ( i = 0 ; (i < NumAvailableCp) &&
|
|
(AvailableCp[i] != LANG_TABLE[j].Cp2) ; i++ ) ;
|
|
|
|
if ( i < NumAvailableCp )
|
|
{
|
|
ServerSesGrp.SecondaryCP = LANG_TABLE[j].Cp2;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
LocaleLang = PRIMARYLANGID(LANGIDFROMLCID(ServerSesGrp.Win32LCID));
|
|
for ( i = 0 ; Or2NlsLangIdTable[i] ; i++ )
|
|
{
|
|
if (Or2NlsLangIdTable[i] == LocaleLang)
|
|
{
|
|
ServerSesGrp.LanguageID = Or2NlsLangIdTable[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
ServerSesGrp.VioCP = ServerSesGrp.KbdCP = ServerSesGrp.DosCP = ServerSesGrp.PrimaryCP;
|
|
|
|
/*
|
|
* Get CtryInfo, DBCSEv, CollateTable, CaseMapTable for the default
|
|
*/
|
|
|
|
Or2NlsGetCPInfo(
|
|
(UINT)ServerSesGrp.PrimaryCP,
|
|
&ServerSesGrp.PriDBCSVec
|
|
);
|
|
|
|
Or2NlsGetMapTable(
|
|
(LCID)ServerSesGrp.Os2ssLCID,
|
|
ServerSesGrp.PrimaryCP,
|
|
LCMAP_SORTKEY,
|
|
ServerSesGrp.PriCollateTable
|
|
);
|
|
|
|
Or2NlsGetMapTable(
|
|
(LCID)ServerSesGrp.Os2ssLCID,
|
|
ServerSesGrp.PrimaryCP,
|
|
LCMAP_UPPERCASE,
|
|
ServerSesGrp.PriCaseMapTable
|
|
);
|
|
|
|
if ( ServerSesGrp.SecondaryCP )
|
|
{
|
|
Or2NlsGetCPInfo(
|
|
(UINT)ServerSesGrp.SecondaryCP,
|
|
&ServerSesGrp.SecDBCSVec
|
|
);
|
|
|
|
Or2NlsGetMapTable(
|
|
(LCID)ServerSesGrp.Os2ssLCID,
|
|
ServerSesGrp.SecondaryCP,
|
|
LCMAP_SORTKEY,
|
|
ServerSesGrp.SecCollateTable
|
|
);
|
|
|
|
Or2NlsGetMapTable(
|
|
(LCID)ServerSesGrp.Os2ssLCID,
|
|
ServerSesGrp.SecondaryCP,
|
|
LCMAP_UPPERCASE,
|
|
ServerSesGrp.SecCaseMapTable
|
|
);
|
|
}
|
|
|
|
Or2NlsGetCtryInfo(
|
|
(LCID)ServerSesGrp.Os2ssLCID,
|
|
(UINT)ServerSesGrp.PrimaryCP,
|
|
&ServerSesGrp.CountryInfo
|
|
);
|
|
|
|
if (ServerSesGrp.PriDBCSVec.Vector[0] || ServerSesGrp.PriDBCSVec.Vector[1] ||
|
|
ServerSesGrp.SecDBCSVec.Vector[0] || ServerSesGrp.SecDBCSVec.Vector[1])
|
|
{
|
|
ServerSesGrp.DBCSCountryFlag = TRUE;
|
|
}
|
|
|
|
ServerSesGrp.KeysOnFlag = Os2ssKeysOnFlag;
|
|
|
|
InitKeyboardRegistry();
|
|
|
|
// BugBug: maybe according to ServerSesGrp.PrimaryCP or in the future
|
|
// according to the Process' CodePage
|
|
|
|
Or2CurrentCodePageIsOem = TRUE;
|
|
Or2ProcessCodePage = ServerSesGrp.Win32OEMCP;
|
|
|
|
RtlInitUnicodeString(&SystemDirectory_U, Os2SystemDirectory);
|
|
|
|
SystemDirectory_A.Buffer = ServerSesGrp.SystemDirectory;
|
|
SystemDirectory_A.MaximumLength = CCHMAXSYSTEMPATH;
|
|
SystemDirectory_A.Length = 0;
|
|
|
|
Os2ServerSystemDirectory = &ServerSesGrp.SystemDirectory[0];
|
|
|
|
Or2UnicodeStringToMBString(
|
|
&SystemDirectory_A,
|
|
&SystemDirectory_U,
|
|
FALSE
|
|
);
|
|
|
|
#if DBG
|
|
|
|
/*
|
|
* Dump all NLS info to the debugger
|
|
*/
|
|
|
|
IF_OS2_DEBUG( NLS )
|
|
{
|
|
KdPrint(("OS2SRV(Os2-NLS): CP %lu (%lu,%lu), Country %lu, LangID %lx ,LCID %lx\n",
|
|
ServerSesGrp.DosCP, ServerSesGrp.PrimaryCP,
|
|
ServerSesGrp.SecondaryCP, ServerSesGrp.CountryCode,
|
|
ServerSesGrp.LanguageID, ServerSesGrp.Os2ssLCID));
|
|
|
|
KdPrint(("OS2SRV(Win32-NLS): OEMCP %lu, ACP %lu, Country %lu, LangID %lx\n",
|
|
ServerSesGrp.Win32OEMCP, ServerSesGrp.Win32ACP,
|
|
ServerSesGrp.Win32CountryCode, ServerSesGrp.Win32LANGID));
|
|
|
|
KdPrint((" LCID %lx, ConCP %lu, ConOutCP %lu\n",
|
|
ServerSesGrp.Win32LCID, Or2WinGetConsoleCP(Os2InitializeNLSStr),
|
|
Or2WinGetConsoleOutputCP(Os2InitializeNLSStr)));
|
|
|
|
KdPrint((" SystemDirectory %s\n",
|
|
ServerSesGrp.SystemDirectory));
|
|
}
|
|
#endif
|
|
|
|
return (NO_ERROR);
|
|
}
|
|
|
|
|
|
PLANG_TABLE_ENTRY
|
|
CheckCountryCodePage(
|
|
IN ULONG CountryCode,
|
|
IN ULONG *Os2srvCodePages,
|
|
OUT ULONG *CodePages
|
|
)
|
|
{
|
|
ULONG i, j = 0;
|
|
|
|
if (!CountryCode)
|
|
{
|
|
return(NULL);
|
|
}
|
|
|
|
for ( i = 0 ; LANG_TABLE[i].Ctry ; i++ )
|
|
{
|
|
if (LANG_TABLE[i].Ctry == CountryCode)
|
|
{
|
|
if (Os2srvCodePages[0] != 0)
|
|
{
|
|
if (Os2srvCodePages[1] == 0)
|
|
{
|
|
if ((Os2srvCodePages[0] == LANG_TABLE[i].Cp1) ||
|
|
(Os2srvCodePages[0] == LANG_TABLE[i].Cp2))
|
|
{
|
|
CodePages[0] = Os2srvCodePages[0];
|
|
return(&LANG_TABLE[i]);
|
|
}
|
|
} else if (((Os2srvCodePages[0] == LANG_TABLE[i].Cp1) &&
|
|
(Os2srvCodePages[1] == LANG_TABLE[i].Cp2)) ||
|
|
((Os2srvCodePages[1] == LANG_TABLE[i].Cp1) &&
|
|
(Os2srvCodePages[0] == LANG_TABLE[i].Cp2)))
|
|
{
|
|
CodePages[0] = Os2srvCodePages[0];
|
|
CodePages[1] = Os2srvCodePages[1];
|
|
return(&LANG_TABLE[i]);
|
|
} else if ((Os2srvCodePages[0] == LANG_TABLE[i].Cp1) ||
|
|
(Os2srvCodePages[0] == LANG_TABLE[i].Cp2))
|
|
{
|
|
CodePages[0] = Os2srvCodePages[0];
|
|
return(&LANG_TABLE[i]);
|
|
} else if ((Os2srvCodePages[1] == LANG_TABLE[i].Cp1) ||
|
|
(Os2srvCodePages[1] == LANG_TABLE[i].Cp2))
|
|
{
|
|
CodePages[0] = Os2srvCodePages[1];
|
|
return(&LANG_TABLE[i]);
|
|
}
|
|
}
|
|
|
|
CodePages[0] = LANG_TABLE[i].Cp1;
|
|
CodePages[1] = LANG_TABLE[i].Cp2;
|
|
return(&LANG_TABLE[i]);
|
|
}
|
|
}
|
|
|
|
// end of table
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
struct
|
|
{
|
|
ULONG Country;
|
|
UCHAR Prefix[2];
|
|
} KBD_PREFIX_TABLE[] =
|
|
{
|
|
{ CTRY_BELGIUM, "BE" },
|
|
{ CTRY_CANADA, "CF" },
|
|
{ CTRY_DENMARK, "DK" },
|
|
{ CTRY_FRANCE, "FR" },
|
|
{ CTRY_GERMANY, "GR" },
|
|
{ CTRY_ITALY, "IT" },
|
|
{ COUNTRY_LATIN_AMERICA, "LA" },
|
|
{ CTRY_NETHERLANDS, "NL" },
|
|
{ CTRY_NORWAY, "NO" },
|
|
{ CTRY_PORTUGAL, "PO" },
|
|
{ CTRY_SWITZERLAND, "SF" },
|
|
{ CTRY_SWITZERLAND, "SG" },
|
|
{ CTRY_SPAIN, "SP" },
|
|
{ CTRY_FINLAND, "SU" },
|
|
{ CTRY_SWEDEN, "SV" },
|
|
{ CTRY_UNITED_KINGDOM, "UK" },
|
|
{ CTRY_UNITED_STATES, "US" },
|
|
{ 0, "XX" }
|
|
};
|
|
|
|
ULONG
|
|
InitKeyboardRegistry(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This initialization function reads the keybaord layout from the registry
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The value is an ULONG type that is returned when some failure occurs. It
|
|
may indicate any of several errors that occur during the APIs called in
|
|
this function. The return value should be tested if NZ.
|
|
|
|
--*/
|
|
|
|
{
|
|
#ifdef JAPAN
|
|
// MSKK Aug.10.1993 V-AkihiS
|
|
ServerSesGrp.KeyboardCountry = CTRY_JAPAN;
|
|
ServerSesGrp.KeyboardType = OS2SS_EN_KBD;
|
|
#else
|
|
LONG Rc;
|
|
int KbdType, i;
|
|
ULONG KeyBoardCountry = CTRY_UNITED_STATES;
|
|
|
|
|
|
if (((KbdType = GetKeyboardType(0)) == 2) || (KbdType == 4))
|
|
{
|
|
ServerSesGrp.KeyboardType = OS2SS_EN_KBD; // EN
|
|
} else
|
|
{
|
|
ServerSesGrp.KeyboardType = OS2SS_AT_KBD; // AT
|
|
}
|
|
|
|
ServerSesGrp.KeyboardCountry = CTRY_UNITED_STATES;
|
|
|
|
#if PMNT
|
|
// Keyboard sub-code must be 3 digits or 4 (Swiss-german 150G + 150F only)
|
|
// Check that we have at least 3 valid digits.
|
|
// Note that the string is padded with blanks (not null-terminated)
|
|
if (isdigit(Os2ssKeyboardName[0])
|
|
&& isdigit(Os2ssKeyboardName[1])
|
|
&& isdigit(Os2ssKeyboardName[2]))
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
&Os2ssKeyboardName[0],
|
|
4);
|
|
}
|
|
else
|
|
{
|
|
// Keyboard layout not specified or in incorrect format. Pick default
|
|
// layout according to specified keyboard layout. See OS/2
|
|
// documentation (user's guide)
|
|
if (!strnicmp(&Os2ssKeyboardLayout[0], "BE", 2)) // Belgium
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"120 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "CF", 2)) // Canada (French)
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"058 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "DK", 2)) // Denmark
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"159 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "FR", 2)) // France
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"189 ", // Other possible choice is 120
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "GR", 2)) // Germany
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"129 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "IT", 2)) // Italy
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"141 ", // Other possible choice is 142
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "LA", 2)) // Latin America
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"171 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "NL", 2)) // Netherlands
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"143 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "NO", 2)) // Norway
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"155 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "PO", 2)) // Poland
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"163 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "SF", 2)) // Switerland (FR)
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"150F",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "SG", 2)) // Switzerland (GR)
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"150G",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "SP", 2)) // Spain
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"172 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "SU", 2)) // Finland
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"153 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "SV", 2)) // Sweden
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"153 ",
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "UK", 2)) // UK
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"166 ", // Other possible choice is 168
|
|
4);
|
|
}
|
|
else if (!strnicmp(&Os2ssKeyboardLayout[0], "US", 2)) // US
|
|
{
|
|
memcpy(&ServerSesGrp.KeyboardName[0],
|
|
"103 ",
|
|
4);
|
|
}
|
|
else
|
|
{
|
|
// Use US default keyboard
|
|
strcpy(&ServerSesGrp.KeyboardName[0], "103 ");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (Os2ssKeyboardLayout[0] && Os2ssKeyboardLayout[1])
|
|
{
|
|
for ( i = 0 ; KBD_PREFIX_TABLE[i].Country ; i++ )
|
|
{
|
|
if ((KBD_PREFIX_TABLE[i].Prefix[0] == Os2ssKeyboardLayout[0]) &&
|
|
(KBD_PREFIX_TABLE[i].Prefix[1] == Os2ssKeyboardLayout[1]))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (KBD_PREFIX_TABLE[i].Country)
|
|
{
|
|
ServerSesGrp.KeyboardCountry = KBD_PREFIX_TABLE[i].Country;
|
|
KeyboardFromConfigSysRegistry = TRUE;
|
|
ServerSesGrp.KeyboardLayout[0] = Os2ssKeyboardLayout[0];
|
|
ServerSesGrp.KeyboardLayout[1] = Os2ssKeyboardLayout[1];
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
#if PMNT
|
|
// Keyboard layout not found, use default (US)
|
|
ServerSesGrp.KeyboardLayout[0] = 'U';
|
|
ServerSesGrp.KeyboardLayout[1] = 'S';
|
|
#endif // PMNT
|
|
|
|
Rc = RegOpenKeyExW(
|
|
HKEY_CURRENT_USER,
|
|
L"Keyboard Layout",
|
|
0,
|
|
KEY_READ,
|
|
&KeyboardLayoutKeyHandle
|
|
);
|
|
|
|
if (Rc != ERROR_SUCCESS)
|
|
{
|
|
#if DBG
|
|
IF_OS2_DEBUG3( INIT, KBD, NLS )
|
|
{
|
|
KdPrint(("InitKeyboardRegistry: Can't open key, rc %lx\n",
|
|
Rc));
|
|
}
|
|
#endif
|
|
return((ULONG)Rc);
|
|
}
|
|
|
|
hKeyEvent = CreateEventW(
|
|
NULL,
|
|
FALSE, /* auto reset */
|
|
FALSE,
|
|
NULL
|
|
);
|
|
|
|
if (hKeyEvent == NULL)
|
|
{
|
|
ULONG Rc1 = GetLastError();
|
|
|
|
#if DBG
|
|
IF_OS2_DEBUG3( INIT, KBD, NLS )
|
|
{
|
|
KdPrint(("InitKeyboardRegistry: Can't create event, rc %lx\n",
|
|
Rc1));
|
|
}
|
|
#endif
|
|
return(Rc1);
|
|
}
|
|
|
|
Rc = ReadKeyboardLayoutFromRegistry(&KeyBoardCountry);
|
|
|
|
if (Rc == 0)
|
|
{
|
|
ServerSesGrp.KeyboardCountry = KeyBoardCountry;
|
|
}
|
|
|
|
#if DBG
|
|
IF_OS2_DEBUG3( NLS, INIT, KBD )
|
|
{
|
|
KdPrint(("InitKeyboardRegistry: Country %d, Type %s (%d)\n",
|
|
ServerSesGrp.KeyboardCountry,
|
|
(ServerSesGrp.KeyboardType == OS2SS_AT_KBD) ? "AT" :
|
|
((ServerSesGrp.KeyboardType == OS2SS_ENNEW_KBD) ? "EN-NEW" : "EN"),
|
|
KbdType));
|
|
}
|
|
#endif
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
|
|
ULONG
|
|
ReadKeyboardLayoutFromRegistry(
|
|
OUT PULONG pKeyBoardCountry
|
|
)
|
|
{
|
|
LONG Rc;
|
|
DWORD ValueType;
|
|
DWORD DataSize = 40;
|
|
WCHAR DataBuffer[40];
|
|
#ifdef JAPAN
|
|
// MSKK Jul.29.1993 V-AkihiS
|
|
LCID KeyBoardLayOut = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL), 0);
|
|
#else
|
|
LCID KeyBoardLayOut = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0);
|
|
#endif
|
|
int CountryLength;
|
|
WCHAR sCountryCode[WBUFFER_SIZE];
|
|
|
|
Rc = RegQueryValueExW(
|
|
KeyboardLayoutKeyHandle,
|
|
L"Active",
|
|
NULL,
|
|
&ValueType,
|
|
(LPBYTE)&DataBuffer[0],
|
|
&DataSize
|
|
);
|
|
|
|
if ((Rc == ERROR_FILE_NOT_FOUND) || (Rc == ERROR_KEY_DELETED))
|
|
{
|
|
if (KeyboardLayoutKeyHandle)
|
|
{
|
|
RegCloseKey(KeyboardLayoutKeyHandle);
|
|
KeyboardLayoutKeyHandle = NULL;
|
|
}
|
|
|
|
//
|
|
// In NT4 the key was changed - try it.
|
|
//
|
|
Rc = RegOpenKeyExW(
|
|
HKEY_CURRENT_USER,
|
|
L"Keyboard Layout\\Preload",
|
|
0,
|
|
KEY_READ,
|
|
&KeyboardLayoutKeyHandle
|
|
);
|
|
if (Rc == ERROR_SUCCESS)
|
|
{
|
|
Rc = RegQueryValueExW(
|
|
KeyboardLayoutKeyHandle,
|
|
L"1",
|
|
NULL,
|
|
&ValueType,
|
|
(LPBYTE)&DataBuffer[0],
|
|
&DataSize
|
|
);
|
|
}
|
|
}
|
|
|
|
if (Rc != ERROR_SUCCESS)
|
|
{
|
|
#if DBG
|
|
IF_OS2_DEBUG3( NLS, KBD, INIT )
|
|
{
|
|
KdPrint(("ReadKeyboardLayoutFromRegistry: Can't query value, rc %lx\n",
|
|
Rc));
|
|
}
|
|
#endif
|
|
return((ULONG)Rc);
|
|
}
|
|
|
|
if (ValueType != REG_SZ)
|
|
{
|
|
return((ULONG)-1);
|
|
}
|
|
|
|
KeyBoardLayOut = (LCID)Or2NlsUnicodeStringToInteger(
|
|
DataBuffer,
|
|
16
|
|
);
|
|
|
|
CountryLength = GetLocaleInfoW(
|
|
KeyBoardLayOut,
|
|
LOCALE_ICOUNTRY,
|
|
sCountryCode,
|
|
WBUFFER_SIZE
|
|
);
|
|
|
|
*pKeyBoardCountry = Or2NlsUnicodeStringToInteger(
|
|
sCountryCode,
|
|
10
|
|
);
|
|
|
|
if ((*pKeyBoardCountry == CTRY_AUSTRALIA) ||
|
|
(*pKeyBoardCountry == CTRY_NEW_ZEALAND))
|
|
{
|
|
*pKeyBoardCountry = CTRY_UNITED_STATES;
|
|
} else if (*pKeyBoardCountry == CTRY_AUSTRIA)
|
|
{
|
|
*pKeyBoardCountry = CTRY_GERMANY;
|
|
} else if (*pKeyBoardCountry == CTRY_BRAZIL)
|
|
{
|
|
*pKeyBoardCountry = CTRY_PORTUGAL;
|
|
} else if (*pKeyBoardCountry == CTRY_ICELAND)
|
|
{
|
|
*pKeyBoardCountry = CTRY_NORWAY; // BUGBUG: or CTRY_DENMARK
|
|
} else if (*pKeyBoardCountry == CTRY_IRELAND)
|
|
{
|
|
*pKeyBoardCountry = CTRY_UNITED_KINGDOM;
|
|
} else if (*pKeyBoardCountry == CTRY_MEXICO)
|
|
{
|
|
*pKeyBoardCountry = COUNTRY_LATIN_AMERICA;
|
|
}
|
|
|
|
#if DBG
|
|
IF_OS2_DEBUG2( NLS, KBD )
|
|
{
|
|
KdPrint(("ReadKeyboardLayoutFromRegistry: Value %ws-%x, Country %d\n",
|
|
DataBuffer, KeyBoardLayOut, *pKeyBoardCountry));
|
|
}
|
|
#endif
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
ULONG
|
|
GetKeyboardRegistryChange(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This initialization function wait for a change in the keybaord layout
|
|
in the registry and update all sessions.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The Keyboard Country code
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG Rc;
|
|
ULONG KeyBoardCountry = ServerSesGrp.KeyboardCountry;
|
|
|
|
|
|
if (KeyboardFromConfigSysRegistry)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
if (KeyboardLayoutKeyHandle == NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
while ( 1 )
|
|
{
|
|
Rc = RegNotifyChangeKeyValue(
|
|
KeyboardLayoutKeyHandle,
|
|
TRUE,
|
|
REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_NAME,
|
|
hKeyEvent, // hEvent (async)
|
|
TRUE // aSync
|
|
);
|
|
|
|
if (Rc != ERROR_SUCCESS)
|
|
{
|
|
#if DBG
|
|
IF_OS2_DEBUG2( KBD, NLS )
|
|
{
|
|
KdPrint(("GetKeyboardRegistryChange: Can't wait for notify, rc %lx\n",
|
|
Rc));
|
|
}
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
WaitForSingleObject( hKeyEvent, INFINITE );
|
|
|
|
Rc = ReadKeyboardLayoutFromRegistry(&KeyBoardCountry);
|
|
|
|
if ((Rc == 0) && KeyBoardCountry &&
|
|
(KeyBoardCountry != ServerSesGrp.KeyboardCountry))
|
|
{
|
|
break;
|
|
}
|
|
|
|
while ((Rc == ERROR_FILE_NOT_FOUND) || (Rc == ERROR_KEY_DELETED))
|
|
{
|
|
//
|
|
// In NT4 the when the key is being updated, it's actually
|
|
// being deleted and recreated. We may have to wait for its
|
|
// recreaction.
|
|
//
|
|
#if DBG
|
|
IF_OS2_DEBUG2( KBD, NLS )
|
|
{
|
|
KdPrint(("GetKeyboardRegistryChange: Waiting for registry key to be created.\n"));
|
|
}
|
|
#endif // DBG
|
|
Sleep(200L); // 0.2 sec
|
|
Rc = ReadKeyboardLayoutFromRegistry(&KeyBoardCountry);
|
|
|
|
if ((Rc == 0) && KeyBoardCountry &&
|
|
(KeyBoardCountry != ServerSesGrp.KeyboardCountry))
|
|
{
|
|
goto Change;
|
|
}
|
|
}
|
|
}
|
|
|
|
Change:
|
|
#if DBG
|
|
IF_OS2_DEBUG2( KBD, NLS )
|
|
{
|
|
KdPrint(("GetKeyboardRegistryChange: KbdCountry %u, Old %lu\n",
|
|
KeyBoardCountry, ServerSesGrp.KeyboardCountry));
|
|
}
|
|
#endif
|
|
ServerSesGrp.KeyboardCountry = KeyBoardCountry;
|
|
|
|
return(KeyBoardCountry);
|
|
}
|