/*++ Copyright (c) 1994-2000, Microsoft Corporation All rights reserved. Module Name: intl.c Abstract: This module contains the main routines for the Regional Options applet. Revision History: --*/ // // Include Files. // #include "intl.h" #include #include // // Constant Declarations. // #define MAX_PAGES 3 // limit on the number of pages on the first level #define LANGUAGE_PACK_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\LanguagePack") #define LANGUAGE_PACK_VALUE TEXT("COMPLEXSCRIPTS") #define LANGUAGE_PACK_DLL TEXT("lpk.dll") static const TCHAR c_szLanguages[] = TEXT("System\\CurrentControlSet\\Control\\Nls\\Language"); static const TCHAR c_szControlPanelIntl[] = TEXT("Control Panel\\International"); // // Global Variables. // HANDLE g_hMutex = NULL; TCHAR szMutexName[] = TEXT("RegionalSettings_InputLocaleMutex"); HANDLE g_hEvent = NULL; TCHAR szEventName[] = TEXT("RegionalSettings_InputLocaleEvent"); TCHAR aInt_Str[cInt_Str][3] = { TEXT("0"), TEXT("1"), TEXT("2"), TEXT("3"), TEXT("4"), TEXT("5"), TEXT("6"), TEXT("7"), TEXT("8"), TEXT("9") }; BOOL g_bAdmin_Privileges = FALSE; DWORD g_dwLastSorting; DWORD g_dwCurSorting; BOOL g_bCustomize = FALSE; BOOL g_bDefaultUser = FALSE; DWORD g_dwCustChange = 0L; BOOL g_bShowSortingTab = FALSE; BOOL g_bInstallComplex = FALSE; BOOL g_bInstallCJK = FALSE; TCHAR szSample_Number[] = TEXT("123456789.00"); TCHAR szNegSample_Number[] = TEXT("-123456789.00"); TCHAR szTimeChars[] = TEXT(" Hhmst,-./:;\\ "); TCHAR szTCaseSwap[] = TEXT(" MST"); TCHAR szTLetters[] = TEXT("Hhmst"); TCHAR szSDateChars[] = TEXT(" dgMy,-./:;\\ "); TCHAR szSDCaseSwap[] = TEXT(" DGmY"); TCHAR szSDLetters[] = TEXT("dgMy"); TCHAR szLDateChars[] = TEXT(" dgMy,-./:;\\"); TCHAR szLDCaseSwap[] = TEXT(" DGmY"); TCHAR szLDLetters[] = TEXT("dgHhMmsty"); TCHAR szStyleH[3]; TCHAR szStyleh[3]; TCHAR szStyleM[3]; TCHAR szStylem[3]; TCHAR szStyles[3]; TCHAR szStylet[3]; TCHAR szStyled[3]; TCHAR szStyley[3]; TCHAR szLocaleGetError[SIZE_128]; TCHAR szIntl[] = TEXT("intl"); TCHAR szInvalidSDate[] = TEXT("Mdyg'"); TCHAR szInvalidSTime[] = TEXT("Hhmst'"); HINSTANCE hInstance; int Verified_Regional_Chg = 0; int RegionalChgState = 0; BOOL Styles_Localized; LCID UserLocaleID; LCID SysLocaleID; LCID RegUserLocaleID; LCID RegSysLocaleID; BOOL bShowArabic; BOOL bShowRtL; BOOL bHebrewUI; BOOL bLPKInstalled; TCHAR szSetupSourcePath[MAX_PATH]; TCHAR szSetupSourcePathWithArchitecture[MAX_PATH]; LPTSTR pSetupSourcePath = NULL; LPTSTR pSetupSourcePathWithArchitecture = NULL; BOOL g_bCDROM = FALSE; BOOL g_bSetupCase = FALSE; BOOL g_bLog = FALSE; BOOL g_bProgressBarDisplay = FALSE; BOOL g_bSettingsChanged = FALSE; BOOL g_bUnttendMode = FALSE; BOOL g_bMatchUIFont = FALSE; const TCHAR c_szInstalledLocales[] = TEXT("System\\CurrentControlSet\\Control\\Nls\\Locale"); const TCHAR c_szLanguageGroups[] = TEXT("System\\CurrentControlSet\\Control\\Nls\\Language Groups"); const TCHAR c_szMUILanguages[] = TEXT("System\\CurrentControlSet\\Control\\Nls\\MUILanguages"); const TCHAR c_szLIPInstalled[] = TEXT("Software\\Microsoft\\Windows Interface Pack\\LIPInstalled"); const TCHAR c_szFontSubstitute[] = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes"); const TCHAR c_szSetupKey[] = TEXT("System\\Setup"); const TCHAR c_szCPanelIntl[] = TEXT("Control Panel\\International"); const TCHAR c_szCPanelIntl_DefUser[] = TEXT(".DEFAULT\\Control Panel\\International"); const TCHAR c_szCtfmon[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"); const TCHAR c_szCtfmon_DefUser[] = TEXT(".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"); const TCHAR c_szCPanelDesktop[] = TEXT("Control Panel\\Desktop"); const TCHAR c_szCPanelDesktop_DefUser[] = TEXT(".DEFAULT\\Control Panel\\Desktop"); const TCHAR c_szKbdLayouts[] = TEXT("Keyboard Layout"); const TCHAR c_szKbdLayouts_DefUser[] = TEXT(".DEFAULT\\Keyboard Layout"); const TCHAR c_szInputMethod[] = TEXT("Control Panel\\Input Method"); const TCHAR c_szInputMethod_DefUser[] = TEXT(".DEFAULT\\Control Panel\\Input Method"); const TCHAR c_szInputTips[] = TEXT("Software\\Microsoft\\CTF"); const TCHAR c_szInputTips_DefUser[] = TEXT(".DEFAULT\\Software\\Microsoft\\CTF"); const TCHAR c_szMUIPolicyKeyPath[] = TEXT("Software\\Policies\\Microsoft\\Control Panel\\Desktop"); const TCHAR c_szMUIValue[] = TEXT("MultiUILanguageId"); const TCHAR c_szIntlRun[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\IntlRun"); const TCHAR c_szSysocmgr[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\IntlRun.OC"); TCHAR szIntlInf[] = TEXT("intl.inf"); TCHAR szHelpFile[] = TEXT("windows.hlp"); TCHAR szFontSubstitute[] = TEXT("FontSubstitute"); TCHAR szLocaleListPrefix[] = TEXT("LOCALE_LIST_"); TCHAR szLGBasicInstall[] = TEXT("LANGUAGE_COLLECTION.BASIC.INSTALL"); TCHAR szLGComplexInstall[] = TEXT("LANGUAGE_COLLECTION.COMPLEX.INSTALL"); TCHAR szLGComplexRemove[] = TEXT("LANGUAGE_COLLECTION.COMPLEX.REMOVE"); TCHAR szLGExtInstall[] = TEXT("LANGUAGE_COLLECTION.EXTENDED.INSTALL"); TCHAR szLGExtRemove[] = TEXT("LANGUAGE_COLLECTION.EXTENDED.REMOVE"); TCHAR szCPInstallPrefix[] = TEXT("CODEPAGE_INSTALL_"); TCHAR szCPRemovePrefix[] = TEXT("CODEPAGE_REMOVE_"); TCHAR szKbdLayoutIds[] = TEXT("KbdLayoutIds"); TCHAR szInputLibrary[] = TEXT("input.dll"); TCHAR szUIFontSubstitute[] = TEXT("UIFontSubstitute"); TCHAR szSetupInProgress[] = TEXT("SystemSetupInProgress"); TCHAR szSetupUpgrade[] = TEXT("UpgradeInProgress"); TCHAR szMUILangPending[] = TEXT("MUILanguagePending"); TCHAR szCtfmonValue[] = TEXT("ctfmon.exe"); TCHAR szRegionalSettings[] = TEXT("RegionalSettings"); TCHAR szLanguageGroup[] = TEXT("LanguageGroup"); TCHAR szLanguage[] = TEXT("Language"); TCHAR szSystemLocale[] = TEXT("SystemLocale"); TCHAR szUserLocale[] = TEXT("UserLocale"); TCHAR szInputLocale[] = TEXT("InputLocale"); TCHAR szMUILanguage[] = TEXT("MUILanguage"); TCHAR szUserLocale_DefUser[] = TEXT("UserLocale_DefaultUser"); TCHAR szInputLocale_DefUser[] = TEXT("InputLocale_DefaultUser"); TCHAR szMUILanguage_DefUSer[] = TEXT("MUILanguage_DefaultUser"); HINF g_hIntlInf = NULL; LPLANGUAGEGROUP pLanguageGroups = NULL; LPCODEPAGE pCodePages = NULL; int g_NumAltSorts = 0; HANDLE hAltSorts = NULL; LPDWORD pAltSorts = NULL; HINSTANCE hInputDLL = NULL; BOOL (*pfnInstallInputLayout)(LCID, DWORD, BOOL, HKL, BOOL, BOOL) = NULL; BOOL (*pfnUninstallInputLayout)(LCID, DWORD, BOOL) = NULL; UILANGUAGEGROUP UILangGroup; // // Function Prototypes. // void DoProperties( HWND hwnd, LPCTSTR pCmdLine); //////////////////////////////////////////////////////////////////////////// // // LibMain // // This routine is called from LibInit to perform any initialization that // is required. // //////////////////////////////////////////////////////////////////////////// BOOL APIENTRY LibMain( HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case ( DLL_PROCESS_ATTACH ) : { hInstance = hDll; // // Create the mutex used for the Input Locale property page. // g_hMutex = CreateMutex(NULL, FALSE, szMutexName); g_hEvent = CreateEvent(NULL, TRUE, TRUE, szEventName); DisableThreadLibraryCalls(hDll); break; } case ( DLL_PROCESS_DETACH ) : { if (g_hMutex) { CloseHandle(g_hMutex); } if (g_hEvent) { CloseHandle(g_hEvent); } break; } case ( DLL_THREAD_DETACH ) : { break; } case ( DLL_THREAD_ATTACH ) : default : { break; } } return (TRUE); } //////////////////////////////////////////////////////////////////////////// // // CreateGlobals // //////////////////////////////////////////////////////////////////////////// BOOL CreateGlobals() { HKEY hKey; TCHAR szData[MAX_PATH]; DWORD cbData; // // Get the localized strings. // LoadString(hInstance, IDS_LOCALE_GET_ERROR, szLocaleGetError, SIZE_128); LoadString(hInstance, IDS_STYLEUH, szStyleH, 3); LoadString(hInstance, IDS_STYLELH, szStyleh, 3); LoadString(hInstance, IDS_STYLEUM, szStyleM, 3); LoadString(hInstance, IDS_STYLELM, szStylem, 3); LoadString(hInstance, IDS_STYLELS, szStyles, 3); LoadString(hInstance, IDS_STYLELT, szStylet, 3); LoadString(hInstance, IDS_STYLELD, szStyled, 3); LoadString(hInstance, IDS_STYLELY, szStyley, 3); Styles_Localized = (szStyleH[0] != TEXT('H') || szStyleh[0] != TEXT('h') || szStyleM[0] != TEXT('M') || szStylem[0] != TEXT('m') || szStyles[0] != TEXT('s') || szStylet[0] != TEXT('t') || szStyled[0] != TEXT('d') || szStyley[0] != TEXT('y')); // // Get the user and system default locale ids. // UserLocaleID = GetUserDefaultLCID(); SysLocaleID = GetSystemDefaultLCID(); // // Get the system locale id from the registry. This may be // different from the current system default locale id if the user // changed the system locale and chose not to reboot. // if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szLanguages, 0L, KEY_READ, &hKey ) == ERROR_SUCCESS) { // // Query the default locale id. // szData[0] = 0; cbData = sizeof(szData); RegQueryValueEx(hKey, TEXT("Default"), NULL, NULL, (LPBYTE)szData, &cbData); RegCloseKey(hKey); if ((RegSysLocaleID = TransNum(szData)) == 0) { RegSysLocaleID = SysLocaleID; } } else { RegSysLocaleID = SysLocaleID; } // // Get the user locale id from the registry. // if (RegOpenKeyEx( HKEY_CURRENT_USER, c_szControlPanelIntl, 0L, KEY_READ, &hKey ) == ERROR_SUCCESS) { // // Query the locale id. // szData[0] = 0; cbData = sizeof(szData); RegQueryValueEx(hKey, TEXT("Locale"), NULL, NULL, (LPBYTE)szData, &cbData); RegCloseKey(hKey); if ((RegUserLocaleID = TransNum(szData)) == 0) { RegUserLocaleID = UserLocaleID; } } else { RegUserLocaleID = UserLocaleID; } // // See if the user locale id is Arabic or/and right to left. // bShowRtL = IsRtLLocale(UserLocaleID); bShowArabic = (bShowRtL && (PRIMARYLANGID(LANGIDFROMLCID(UserLocaleID)) != LANG_HEBREW)); bHebrewUI = (PRIMARYLANGID(UserLocaleID) == LANG_HEBREW); // // See if there is an LPK installed. // if (GetModuleHandle(LANGUAGE_PACK_DLL)) { bLPKInstalled = TRUE; } else { bLPKInstalled = FALSE; } // // Return success. // return (TRUE); } //////////////////////////////////////////////////////////////////////////// // // DestroyGlobals // //////////////////////////////////////////////////////////////////////////// void DestroyGlobals() { } //////////////////////////////////////////////////////////////////////////// // // CPlApplet // //////////////////////////////////////////////////////////////////////////// LONG CALLBACK CPlApplet( HWND hwnd, UINT Msg, LPARAM lParam1, LPARAM lParam2) { switch (Msg) { case ( CPL_INIT ) : { // // First message to CPlApplet(), sent once only. // Perform all control panel applet initialization and return // true for further processing. // InitCommonControls(); return (CreateGlobals()); } case ( CPL_GETCOUNT ) : { // // Second message to CPlApplet(), sent once only. // Return the number of control applets to be displayed in the // control panel window. For this applet, return 1. // return (1); } case ( CPL_INQUIRE ) : { // // Third message to CPlApplet(). // It is sent as many times as the number of applets returned by // CPL_GETCOUNT message. Each applet must register by filling // in the CPLINFO structure referenced by lParam2 with the // applet's icon, name, and information string. Since there is // only one applet, simply set the information for this // singular case. // LPCPLINFO lpCPlInfo = (LPCPLINFO)lParam2; lpCPlInfo->idIcon = IDI_ICON; lpCPlInfo->idName = IDS_NAME; lpCPlInfo->idInfo = IDS_INFO; lpCPlInfo->lData = 0; break; } case ( CPL_NEWINQUIRE ) : { // // Third message to CPlApplet(). // It is sent as many times as the number of applets returned by // CPL_GETCOUNT message. Each applet must register by filling // in the NEWCPLINFO structure referenced by lParam2 with the // applet's icon, name, and information string. Since there is // only one applet, simply set the information for this // singular case. // LPNEWCPLINFO lpNewCPlInfo = (LPNEWCPLINFO)lParam2; lpNewCPlInfo->dwSize = sizeof(NEWCPLINFO); lpNewCPlInfo->dwFlags = 0; lpNewCPlInfo->dwHelpContext = 0UL; lpNewCPlInfo->lData = 0; lpNewCPlInfo->hIcon = LoadIcon( hInstance, (LPCTSTR)MAKEINTRESOURCE(IDI_ICON) ); LoadString(hInstance, IDS_NAME, lpNewCPlInfo->szName, 32); LoadString(hInstance, IDS_INFO, lpNewCPlInfo->szInfo, 64); lpNewCPlInfo->szHelpFile[0] = CHAR_NULL; break; } case ( CPL_SELECT ) : { // // Applet has been selected, do nothing. // break; } case ( CPL_DBLCLK ) : { // // Applet icon double clicked -- invoke property sheet with // the first property sheet page on top. // DoProperties(hwnd, (LPCTSTR)NULL); break; } case ( CPL_STARTWPARMS ) : { // // Same as CPL_DBLCLK, but lParam2 is a long pointer to // a string of extra directions that are to be supplied to // the property sheet that is to be initiated. // DoProperties(hwnd, (LPCTSTR)lParam2); break; } case ( CPL_STOP ) : { // // Sent once for each applet prior to the CPL_EXIT msg. // Perform applet specific cleanup. // break; } case ( CPL_EXIT ) : { // // Last message, sent once only, before MMCPL.EXE calls // FreeLibrary() on this DLL. Do non-applet specific cleanup. // DestroyGlobals(); break; } default : { return (FALSE); } } // // Return success. // return (TRUE); } //////////////////////////////////////////////////////////////////////////// // // DoProperties // //////////////////////////////////////////////////////////////////////////// void DoProperties( HWND hwnd, LPCTSTR pCmdLine) { HPROPSHEETPAGE rPages[MAX_PAGES]; PROPSHEETHEADER psh; LPARAM lParam = SETUP_SWITCH_NONE; LPTSTR pStartPage; LPTSTR pSrc; LPTSTR pSrcDrv; BOOL bShortDate = FALSE; BOOL bNoUI = FALSE; BOOL bUnattended = FALSE; TCHAR szUnattendFile[MAX_PATH * 2]; HKEY hKey; TCHAR szSetupSourceDrive[MAX_PATH]; // // Log if the command line is not null. // if (pCmdLine != NULL) { g_bLog = TRUE; } // // Begin Log and log command line parameters. // Intl_LogSimpleMessage(IDS_LOG_HEAD, NULL); Intl_LogMessage(pCmdLine); Intl_LogMessage(TEXT("")); // add a carriage return and newline // // Load the library used for Text Services. // if (!hInputDLL) { hInputDLL = LoadLibrary(szInputLibrary); } // // Initialize the Install/Remove function from the Input applet. // if (hInputDLL) { // // Initialize Install function. // pfnInstallInputLayout = (BOOL (*)(LCID, DWORD, BOOL, HKL, BOOL, BOOL)) GetProcAddress(hInputDLL, MAKEINTRESOURCEA(ORD_INPUT_INST_LAYOUT)); // // Initialize Uninstall function. // pfnUninstallInputLayout = (BOOL (*)(LCID, DWORD, BOOL)) GetProcAddress(hInputDLL, MAKEINTRESOURCEA(ORD_INPUT_UNINST_LAYOUT)); } // // See if there is a command line switch from Setup. // psh.nStartPage = (UINT)-1; while (pCmdLine && *pCmdLine) { if (*pCmdLine == TEXT('/')) { // // Legend: // gG: allow progress bar to show when setup is copying files // iI: bring up the Input Locale page only // rR: bring up the General page on top // sS: setup source string passed on command line // [example: /s:"c:\winnt"] // // NO UI IS SHOWN IF THE FOLLOWING OPTIONS ARE SPECIFIED: // fF: unattend mode file - no UI is shown // [example: /f:"c:\unattend.txt"] // uU: update short date format to 4-digit year - no UI is shown // (registry only updated if current setting is the // same as the default setting except for the // "yy" vs. "yyyy") // tT: Match system UI font with the default UI language // switch (*++pCmdLine) { case ( TEXT('g') ) : case ( TEXT('G') ) : { // // Log switch. // Intl_LogSimpleMessage(IDS_LOG_SWITCH_G, NULL); // // Do switch related processing. // g_bProgressBarDisplay = TRUE; pCmdLine++; break; } case ( TEXT('i') ) : case ( TEXT('I') ) : { // // Log switch. // Intl_LogSimpleMessage(IDS_LOG_SWITCH_I, NULL); // // Do switch related processing // lParam |= SETUP_SWITCH_I; psh.nStartPage = 0; pCmdLine++; break; } case ( TEXT('r') ) : case ( TEXT('R') ) : { // // Log switch. // Intl_LogSimpleMessage(IDS_LOG_SWITCH_R, NULL); // // Do switch related processing // lParam |= SETUP_SWITCH_R; psh.nStartPage = 0; pCmdLine++; break; } case ( TEXT('s') ) : case ( TEXT('S') ) : { // // Log switch. // Intl_LogSimpleMessage(IDS_LOG_SWITCH_S, NULL); // // Get the name of the setup source path. // lParam |= SETUP_SWITCH_S; if ((*++pCmdLine == TEXT(':')) && (*++pCmdLine == TEXT('"'))) { pCmdLine++; pSrc = szSetupSourcePath; pSrcDrv = szSetupSourceDrive; while (*pCmdLine && (*pCmdLine != TEXT('"'))) { *pSrc = *pCmdLine; pSrc++; *pSrcDrv = *pCmdLine; pSrcDrv++; pCmdLine++; } *pSrc = 0; *pSrcDrv = 0; wcscpy(szSetupSourcePathWithArchitecture, szSetupSourcePath); pSetupSourcePathWithArchitecture = szSetupSourcePathWithArchitecture; // // Remove the architecture-specific portion of // the source path (that gui-mode setup sent us). // pSrc = wcsrchr(szSetupSourcePath, TEXT('\\')); if (pSrc) { *pSrc = TEXT('\0'); } pSetupSourcePath = szSetupSourcePath; } if (*pCmdLine == TEXT('"')) { pCmdLine++; } pSrcDrv = szSetupSourceDrive; while (*pSrcDrv) { if (*pSrcDrv == TEXT('\\')) { pSrcDrv[1] = 0; } pSrcDrv++; } g_bCDROM = (GetDriveType(szSetupSourceDrive) == DRIVE_CDROM); break; } case ( TEXT('f') ) : case ( TEXT('F') ) : { // // Log switch. // Intl_LogSimpleMessage(IDS_LOG_SWITCH_F, NULL); // // Get the name of the unattend file. // g_bUnttendMode = TRUE; bNoUI = TRUE; szUnattendFile[0] = 0; if ((*++pCmdLine == TEXT(':')) && (*++pCmdLine == TEXT('"'))) { pCmdLine++; pSrc = szUnattendFile; while (*pCmdLine && (*pCmdLine != TEXT('"'))) { *pSrc = *pCmdLine; pSrc++; pCmdLine++; } *pSrc = 0; } if (*pCmdLine == TEXT('"')) { pCmdLine++; } break; } case ( TEXT('u') ) : case ( TEXT('U') ) : { // // Log switch. // Intl_LogSimpleMessage(IDS_LOG_SWITCH_U, NULL); // // Do switch related processing. // bShortDate = TRUE; bNoUI = TRUE; break; } case ( TEXT('t') ) : case ( TEXT('T') ) : { g_bMatchUIFont = TRUE; } default : { // // Log switch. // Intl_LogSimpleMessage(IDS_LOG_SWITCH_DEFAULT, pCmdLine); // // Fall out, maybe it's a number... // break; } } } else if (*pCmdLine == TEXT(' ')) { pCmdLine++; } else { break; } } // // See if we are in setup mode. // g_bSetupCase = Intl_IsSetupMode(); // // See if the user has Administrative privileges by checking for // write permission to the registry key. // if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, c_szInstalledLocales, 0UL, KEY_WRITE, &hKey ) == ERROR_SUCCESS) { // // See if the user can write into the registry. Due to a registry // modification, we can open a registry key with write access and // be unable to write to the key... thanks to terminal server. // if (RegSetValueEx( hKey, TEXT("Test"), 0UL, REG_SZ, (LPBYTE)TEXT("Test"), (DWORD)(lstrlen(TEXT("Test")) + 1) * sizeof(TCHAR) ) == ERROR_SUCCESS) { // // Delete the value created // RegDeleteValue(hKey, TEXT("Test")); // // We can write to the HKEY_LOCAL_MACHINE key, so the user // has Admin privileges. // g_bAdmin_Privileges = TRUE; } else { // // The user does not have admin privileges. // g_bAdmin_Privileges = FALSE; } RegCloseKey(hKey); } // // See if we are in setup mode. // if (g_bSetupCase) { // // We need to remove the hard coded LPK registry key. // if (RegOpenKey( HKEY_LOCAL_MACHINE, LANGUAGE_PACK_KEY, &hKey ) == ERROR_SUCCESS) { RegDeleteValue(hKey, LANGUAGE_PACK_VALUE); RegCloseKey(hKey); } } // // See if the unattend mode file switch was used. // if (g_bUnttendMode) { // // Use the unattend mode file to carry out the appropriate commands. // Region_DoUnattendModeSetup(szUnattendFile); if (Intl_IsWinntUpgrade()) { // // Remove MUI files. // Intl_RemoveMUIFile(); } } // // If the update to 4-digit year switch was used and the user's short // date setting is still set to the default for the chosen locale, then // update the current user's short date setting to the new 4-digit year // default. // if (bShortDate) { Region_UpdateShortDate(); } // // If we're not to show any UI, then return. // if (bNoUI) { return; } // // Make sure we have a start page. // if (psh.nStartPage == (UINT)-1) { psh.nStartPage = 0; if (pCmdLine && *pCmdLine) { // // Get the start page from the command line. // pStartPage = (LPTSTR)pCmdLine; while ((*pStartPage >= TEXT('0')) && (*pStartPage <= TEXT('9'))) { psh.nStartPage *= 10; psh.nStartPage += *pStartPage++ - CHAR_ZERO; } // // Make sure that the requested starting page is less than // the max page for the selected applet. // if (psh.nStartPage >= MAX_PAGES) { psh.nStartPage = 0; } } } // // Set up the property sheet information. // psh.dwSize = sizeof(psh); psh.dwFlags = 0; psh.hwndParent = hwnd; psh.hInstance = hInstance; psh.nPages = 0; psh.phpage = rPages; // // Add the appropriate property pages. // if (lParam &= SETUP_SWITCH_I) { psh.pszCaption = MAKEINTRESOURCE(IDS_TEXT_INPUT_METHODS); Intl_AddExternalPage( &psh, DLG_INPUT_LOCALES, hInputDLL, MAKEINTRESOURCEA(ORD_INPUT_DLG_PROC), MAX_PAGES ); // One page } else { psh.pszCaption = MAKEINTRESOURCE(IDS_NAME); Intl_AddPage(&psh, DLG_GENERAL, GeneralDlgProc, lParam, MAX_PAGES); Intl_AddPage(&psh, DLG_LANGUAGES, LanguageDlgProc, lParam, MAX_PAGES); if (g_bAdmin_Privileges == TRUE) { Intl_AddPage(&psh, DLG_ADVANCED, AdvancedDlgProc, lParam, MAX_PAGES); } } // // Make the property sheet. // PropertySheet(&psh); // // Free the Text Services Library. // if (hInputDLL) { FreeLibrary(hInputDLL); pfnInstallInputLayout = NULL; pfnUninstallInputLayout = NULL; } } //////////////////////////////////////////////////////////////////////////// // // IsRtLLocale // //////////////////////////////////////////////////////////////////////////// #define MAX_FONTSIGNATURE 16 // length of font signature string BOOL IsRtLLocale( LCID iLCID) { WORD wLCIDFontSignature[MAX_FONTSIGNATURE]; BOOL bRet = FALSE; // // Verify that this is an RTL (BiDi) locale. Call GetLocaleInfo with // LOCALE_FONTSIGNATURE which always gives back 16 WORDs. // if (GetLocaleInfo( iLCID, LOCALE_FONTSIGNATURE, (LPTSTR) &wLCIDFontSignature, (sizeof(wLCIDFontSignature) / sizeof(TCHAR)) )) { // // Verify the bits show a BiDi UI locale. // if (wLCIDFontSignature[7] & 0x0800) { bRet = TRUE; } } // // Return the result. // return (bRet); }