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

1063 lines
32 KiB

  1. /*++
  2. Copyright (c) 1994-2000, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. intl.c
  5. Abstract:
  6. This module contains the main routines for the Regional Options applet.
  7. Revision History:
  8. --*/
  9. //
  10. // Include Files.
  11. //
  12. #include "intl.h"
  13. #include <cpl.h>
  14. #include <tchar.h>
  15. #define STRSAFE_LIB
  16. #include <strsafe.h>
  17. //
  18. // Constant Declarations.
  19. //
  20. #define MAX_PAGES 3 // limit on the number of pages on the first level
  21. #define LANGUAGE_PACK_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\LanguagePack")
  22. #define LANGUAGE_PACK_VALUE TEXT("COMPLEXSCRIPTS")
  23. #define LANGUAGE_PACK_DLL TEXT("lpk.dll")
  24. static const TCHAR c_szLanguages[] =
  25. TEXT("System\\CurrentControlSet\\Control\\Nls\\Language");
  26. static const TCHAR c_szControlPanelIntl[] =
  27. TEXT("Control Panel\\International");
  28. //
  29. // Global Variables.
  30. //
  31. TCHAR aInt_Str[cInt_Str][3] = { TEXT("0"),
  32. TEXT("1"),
  33. TEXT("2"),
  34. TEXT("3"),
  35. TEXT("4"),
  36. TEXT("5"),
  37. TEXT("6"),
  38. TEXT("7"),
  39. TEXT("8"),
  40. TEXT("9")
  41. };
  42. BOOL g_bAdmin_Privileges = FALSE;
  43. DWORD g_dwLastSorting;
  44. DWORD g_dwCurSorting;
  45. BOOL g_bCustomize = FALSE;
  46. BOOL g_bDefaultUser = FALSE;
  47. DWORD g_dwCustChange = 0L;
  48. BOOL g_bShowSortingTab = FALSE;
  49. BOOL g_bInstallComplex = FALSE;
  50. BOOL g_bInstallCJK = FALSE;
  51. TCHAR szSample_Number[] = TEXT("123456789.00");
  52. TCHAR szNegSample_Number[] = TEXT("-123456789.00");
  53. TCHAR szTimeChars[] = TEXT(" Hhmst,-./:;\\ ");
  54. TCHAR szTCaseSwap[] = TEXT(" MST");
  55. TCHAR szTLetters[] = TEXT("Hhmst");
  56. TCHAR szSDateChars[] = TEXT(" dgMy,-./:;\\ ");
  57. TCHAR szSDCaseSwap[] = TEXT(" DGmY");
  58. TCHAR szSDLetters[] = TEXT("dgMy");
  59. TCHAR szLDateChars[] = TEXT(" dgMy,-./:;\\");
  60. TCHAR szLDCaseSwap[] = TEXT(" DGmY");
  61. TCHAR szLDLetters[] = TEXT("dgHhMmsty");
  62. TCHAR szStyleH[3];
  63. TCHAR szStyleh[3];
  64. TCHAR szStyleM[3];
  65. TCHAR szStylem[3];
  66. TCHAR szStyles[3];
  67. TCHAR szStylet[3];
  68. TCHAR szStyled[3];
  69. TCHAR szStyley[3];
  70. TCHAR szLocaleGetError[SIZE_128];
  71. TCHAR szIntl[] = TEXT("intl");
  72. TCHAR szInvalidSDate[] = TEXT("Mdyg'");
  73. TCHAR szInvalidSTime[] = TEXT("Hhmst'");
  74. HINSTANCE hInstance;
  75. int Verified_Regional_Chg = 0;
  76. int RegionalChgState = 0;
  77. BOOL Styles_Localized;
  78. LCID UserLocaleID;
  79. LCID SysLocaleID;
  80. LCID RegUserLocaleID;
  81. LCID RegSysLocaleID;
  82. BOOL bShowArabic;
  83. BOOL bShowRtL;
  84. BOOL bHebrewUI;
  85. BOOL bLPKInstalled;
  86. TCHAR szSetupSourcePath[MAX_PATH];
  87. TCHAR szSetupSourcePathWithArchitecture[MAX_PATH];
  88. LPTSTR pSetupSourcePath = NULL;
  89. LPTSTR pSetupSourcePathWithArchitecture = NULL;
  90. BOOL g_bCDROM = FALSE;
  91. int g_bSetupCase = 0; // See Intl_IsSetupMode for info on possible values
  92. BOOL g_bLog = FALSE;
  93. BOOL g_bProgressBarDisplay = FALSE;
  94. BOOL g_bDisableSetupDialog = FALSE;
  95. BOOL g_bSettingsChanged = FALSE;
  96. BOOL g_bUnttendMode = FALSE;
  97. BOOL g_bMatchUIFont = FALSE;
  98. const TCHAR c_szInstalledLocales[] = TEXT("System\\CurrentControlSet\\Control\\Nls\\Locale");
  99. const TCHAR c_szLanguageGroups[] = TEXT("System\\CurrentControlSet\\Control\\Nls\\Language Groups");
  100. const TCHAR c_szMUILanguages[] = TEXT("System\\CurrentControlSet\\Control\\Nls\\MUILanguages");
  101. const TCHAR c_szLIPInstalled[] = TEXT("Software\\Microsoft\\Windows Interface Pack\\LIPInstalled");
  102. const TCHAR c_szFontSubstitute[] = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes");
  103. const TCHAR c_szGreFontInitialize[] = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\GRE_Initialize");
  104. const TCHAR c_szSetupKey[] = TEXT("System\\Setup");
  105. const TCHAR c_szCPanelIntl[] = TEXT("Control Panel\\International");
  106. const TCHAR c_szCPanelIntl_DefUser[] = TEXT(".DEFAULT\\Control Panel\\International");
  107. const TCHAR c_szCtfmon[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
  108. const TCHAR c_szCtfmon_DefUser[] = TEXT(".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Run");
  109. const TCHAR c_szCPanelDesktop[] = TEXT("Control Panel\\Desktop");
  110. const TCHAR c_szCPanelDesktop_DefUser[] = TEXT(".DEFAULT\\Control Panel\\Desktop");
  111. const TCHAR c_szKbdLayouts[] = TEXT("Keyboard Layout");
  112. const TCHAR c_szKbdLayouts_DefUser[] = TEXT(".DEFAULT\\Keyboard Layout");
  113. const TCHAR c_szInputMethod[] = TEXT("Control Panel\\Input Method");
  114. const TCHAR c_szInputMethod_DefUser[] = TEXT(".DEFAULT\\Control Panel\\Input Method");
  115. const TCHAR c_szInputTips[] = TEXT("Software\\Microsoft\\CTF");
  116. const TCHAR c_szInputTips_DefUser[] = TEXT(".DEFAULT\\Software\\Microsoft\\CTF");
  117. const TCHAR c_szMUIPolicyKeyPath[] = TEXT("Software\\Policies\\Microsoft\\Control Panel\\Desktop");
  118. const TCHAR c_szMUIValue[] = TEXT("MultiUILanguageId");
  119. const TCHAR c_szIntlRun[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\IntlRun");
  120. const TCHAR c_szSysocmgr[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\IntlRun.OC");
  121. TCHAR szIntlInf[] = TEXT("intl.inf");
  122. TCHAR szHelpFile[] = TEXT("windows.hlp");
  123. TCHAR szFontSubstitute[] = TEXT("FontSubstitute");
  124. TCHAR szLocaleListPrefix[] = TEXT("LOCALE_LIST_");
  125. TCHAR szLGBasicInstall[] = TEXT("LANGUAGE_COLLECTION.BASIC.INSTALL");
  126. TCHAR szLGComplexInstall[] = TEXT("LANGUAGE_COLLECTION.COMPLEX.INSTALL");
  127. TCHAR szLGComplexRemove[] = TEXT("LANGUAGE_COLLECTION.COMPLEX.REMOVE");
  128. TCHAR szLGExtInstall[] = TEXT("LANGUAGE_COLLECTION.EXTENDED.INSTALL");
  129. TCHAR szLGExtRemove[] = TEXT("LANGUAGE_COLLECTION.EXTENDED.REMOVE");
  130. TCHAR szCPInstallPrefix[] = TEXT("CODEPAGE_INSTALL_");
  131. TCHAR szCPRemovePrefix[] = TEXT("CODEPAGE_REMOVE_");
  132. TCHAR szKbdLayoutIds[] = TEXT("KbdLayoutIds");
  133. TCHAR szInputLibrary[] = TEXT("input.dll");
  134. TCHAR szUIFontSubstitute[] = TEXT("UIFontSubstitute");
  135. TCHAR szSetupInProgress[] = TEXT("SystemSetupInProgress");
  136. TCHAR szMiniSetupInProgress[] = TEXT("MiniSetupInProgress");
  137. TCHAR szSetupUpgrade[] = TEXT("UpgradeInProgress");
  138. TCHAR szMUILangPending[] = TEXT("MUILanguagePending");
  139. TCHAR szCtfmonValue[] = TEXT("ctfmon.exe");
  140. TCHAR szRegionalSettings[] = TEXT("RegionalSettings");
  141. TCHAR szLanguageGroup[] = TEXT("LanguageGroup");
  142. TCHAR szLanguage[] = TEXT("Language");
  143. TCHAR szSystemLocale[] = TEXT("SystemLocale");
  144. TCHAR szUserLocale[] = TEXT("UserLocale");
  145. TCHAR szInputLocale[] = TEXT("InputLocale");
  146. TCHAR szMUILanguage[] = TEXT("MUILanguage");
  147. TCHAR szUserLocale_DefUser[] = TEXT("UserLocale_DefaultUser");
  148. TCHAR szInputLocale_DefUser[] = TEXT("InputLocale_DefaultUser");
  149. TCHAR szMUILanguage_DefUSer[] = TEXT("MUILanguage_DefaultUser");
  150. HINF g_hIntlInf = NULL;
  151. LPLANGUAGEGROUP pLanguageGroups = NULL;
  152. LPCODEPAGE pCodePages = NULL;
  153. int g_NumAltSorts = 0;
  154. HANDLE hAltSorts = NULL;
  155. LPDWORD pAltSorts = NULL;
  156. HINSTANCE hInputDLL = NULL;
  157. BOOL (*pfnInstallInputLayout)(LCID, DWORD, BOOL, HKL, BOOL, BOOL) = NULL;
  158. BOOL (*pfnUninstallInputLayout)(LCID, DWORD, BOOL) = NULL;
  159. UILANGUAGEGROUP UILangGroup;
  160. //
  161. // Function Prototypes.
  162. //
  163. void
  164. DoProperties(
  165. HWND hwnd,
  166. LPCTSTR pCmdLine);
  167. ////////////////////////////////////////////////////////////////////////////
  168. //
  169. // LibMain
  170. //
  171. // This routine is called from LibInit to perform any initialization that
  172. // is required.
  173. //
  174. ////////////////////////////////////////////////////////////////////////////
  175. BOOL APIENTRY LibMain(
  176. HANDLE hDll,
  177. DWORD dwReason,
  178. LPVOID lpReserved)
  179. {
  180. switch (dwReason)
  181. {
  182. case ( DLL_PROCESS_ATTACH ) :
  183. {
  184. hInstance = hDll;
  185. DisableThreadLibraryCalls(hDll);
  186. break;
  187. }
  188. case ( DLL_PROCESS_DETACH ) :
  189. {
  190. break;
  191. }
  192. case ( DLL_THREAD_DETACH ) :
  193. {
  194. break;
  195. }
  196. case ( DLL_THREAD_ATTACH ) :
  197. default :
  198. {
  199. break;
  200. }
  201. }
  202. return (TRUE);
  203. }
  204. ////////////////////////////////////////////////////////////////////////////
  205. //
  206. // CreateGlobals
  207. //
  208. ////////////////////////////////////////////////////////////////////////////
  209. BOOL CreateGlobals()
  210. {
  211. HKEY hKey;
  212. TCHAR szData[MAX_PATH];
  213. DWORD cbData;
  214. DWORD dwDisposition;
  215. //
  216. // Get the localized strings.
  217. //
  218. LoadString(hInstance, IDS_LOCALE_GET_ERROR, szLocaleGetError, SIZE_128);
  219. LoadString(hInstance, IDS_STYLEUH, szStyleH, 3);
  220. LoadString(hInstance, IDS_STYLELH, szStyleh, 3);
  221. LoadString(hInstance, IDS_STYLEUM, szStyleM, 3);
  222. LoadString(hInstance, IDS_STYLELM, szStylem, 3);
  223. LoadString(hInstance, IDS_STYLELS, szStyles, 3);
  224. LoadString(hInstance, IDS_STYLELT, szStylet, 3);
  225. LoadString(hInstance, IDS_STYLELD, szStyled, 3);
  226. LoadString(hInstance, IDS_STYLELY, szStyley, 3);
  227. Styles_Localized = (szStyleH[0] != TEXT('H') || szStyleh[0] != TEXT('h') ||
  228. szStyleM[0] != TEXT('M') || szStylem[0] != TEXT('m') ||
  229. szStyles[0] != TEXT('s') || szStylet[0] != TEXT('t') ||
  230. szStyled[0] != TEXT('d') || szStyley[0] != TEXT('y'));
  231. //
  232. // Get the user and system default locale ids.
  233. //
  234. UserLocaleID = GetUserDefaultLCID();
  235. SysLocaleID = GetSystemDefaultLCID();
  236. //
  237. // Get the system locale id from the registry. This may be
  238. // different from the current system default locale id if the user
  239. // changed the system locale and chose not to reboot.
  240. //
  241. if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  242. c_szLanguages,
  243. 0L,
  244. KEY_READ,
  245. &hKey ) == ERROR_SUCCESS)
  246. {
  247. //
  248. // Query the default locale id.
  249. //
  250. szData[0] = 0;
  251. cbData = sizeof(szData);
  252. RegQueryValueEx(hKey, TEXT("Default"), NULL, NULL, (LPBYTE)szData, &cbData);
  253. RegCloseKey(hKey);
  254. if ((RegSysLocaleID = TransNum(szData)) == 0)
  255. {
  256. RegSysLocaleID = SysLocaleID;
  257. }
  258. }
  259. else
  260. {
  261. RegSysLocaleID = SysLocaleID;
  262. }
  263. //
  264. // Validate the user locale
  265. //
  266. if(IsValidLocale(UserLocaleID, LCID_INSTALLED))
  267. {
  268. RegUserLocaleID = UserLocaleID;
  269. }
  270. else
  271. {
  272. //
  273. // The locale is invalid, so fall back to the system locale.
  274. // Use the actual system locale on the machine at this time.
  275. //
  276. RegUserLocaleID = SysLocaleID;
  277. UserLocaleID = SysLocaleID;
  278. //
  279. // We need to fix up the registry key to avoid future problems.
  280. //
  281. if( ! (Intl_InstallUserLocale(SysLocaleID, FALSE, TRUE)))
  282. {
  283. // Unable up update the user locale, no choice but to bail.
  284. ExitProcess((DWORD)-1);
  285. }
  286. }
  287. //
  288. // Check to be sure the user intl key exists
  289. //
  290. if (RegCreateKeyEx( HKEY_CURRENT_USER,
  291. c_szControlPanelIntl,
  292. 0L,
  293. NULL,
  294. REG_OPTION_NON_VOLATILE,
  295. KEY_WRITE,
  296. NULL,
  297. &hKey,
  298. &dwDisposition ) == ERROR_SUCCESS)
  299. {
  300. RegCloseKey(hKey);
  301. if(REG_CREATED_NEW_KEY == dwDisposition)
  302. {
  303. //
  304. // We created the key, so fill it in with default values
  305. //
  306. Intl_InstallUserLocale(UserLocaleID, FALSE, TRUE);
  307. }
  308. }
  309. else
  310. {
  311. // Unable up create the key, so just open the UI
  312. }
  313. //
  314. // See if the user locale id is Arabic or/and right to left.
  315. //
  316. bShowRtL = IsRtLLocale(UserLocaleID);
  317. bShowArabic = (bShowRtL &&
  318. (PRIMARYLANGID(LANGIDFROMLCID(UserLocaleID)) != LANG_HEBREW));
  319. bHebrewUI = (PRIMARYLANGID(UserLocaleID) == LANG_HEBREW);
  320. //
  321. // See if there is an LPK installed.
  322. //
  323. if (GetModuleHandle(LANGUAGE_PACK_DLL))
  324. {
  325. bLPKInstalled = TRUE;
  326. }
  327. else
  328. {
  329. bLPKInstalled = FALSE;
  330. }
  331. //
  332. // Return success.
  333. //
  334. return (TRUE);
  335. }
  336. ////////////////////////////////////////////////////////////////////////////
  337. //
  338. // DestroyGlobals
  339. //
  340. ////////////////////////////////////////////////////////////////////////////
  341. void DestroyGlobals()
  342. {
  343. }
  344. ////////////////////////////////////////////////////////////////////////////
  345. //
  346. // CPlApplet
  347. //
  348. ////////////////////////////////////////////////////////////////////////////
  349. LONG CALLBACK CPlApplet(
  350. HWND hwnd,
  351. UINT Msg,
  352. LPARAM lParam1,
  353. LPARAM lParam2)
  354. {
  355. switch (Msg)
  356. {
  357. case ( CPL_INIT ) :
  358. {
  359. //
  360. // First message to CPlApplet(), sent once only.
  361. // Perform all control panel applet initialization and return
  362. // true for further processing.
  363. //
  364. InitCommonControls();
  365. return (CreateGlobals());
  366. }
  367. case ( CPL_GETCOUNT ) :
  368. {
  369. //
  370. // Second message to CPlApplet(), sent once only.
  371. // Return the number of control applets to be displayed in the
  372. // control panel window. For this applet, return 1.
  373. //
  374. return (1);
  375. }
  376. case ( CPL_INQUIRE ) :
  377. {
  378. //
  379. // Third message to CPlApplet().
  380. // It is sent as many times as the number of applets returned by
  381. // CPL_GETCOUNT message. Each applet must register by filling
  382. // in the CPLINFO structure referenced by lParam2 with the
  383. // applet's icon, name, and information string. Since there is
  384. // only one applet, simply set the information for this
  385. // singular case.
  386. //
  387. LPCPLINFO lpCPlInfo = (LPCPLINFO)lParam2;
  388. lpCPlInfo->idIcon = IDI_ICON;
  389. lpCPlInfo->idName = IDS_NAME;
  390. lpCPlInfo->idInfo = IDS_INFO;
  391. lpCPlInfo->lData = 0;
  392. break;
  393. }
  394. case ( CPL_NEWINQUIRE ) :
  395. {
  396. //
  397. // Third message to CPlApplet().
  398. // It is sent as many times as the number of applets returned by
  399. // CPL_GETCOUNT message. Each applet must register by filling
  400. // in the NEWCPLINFO structure referenced by lParam2 with the
  401. // applet's icon, name, and information string. Since there is
  402. // only one applet, simply set the information for this
  403. // singular case.
  404. //
  405. LPNEWCPLINFO lpNewCPlInfo = (LPNEWCPLINFO)lParam2;
  406. lpNewCPlInfo->dwSize = sizeof(NEWCPLINFO);
  407. lpNewCPlInfo->dwFlags = 0;
  408. lpNewCPlInfo->dwHelpContext = 0UL;
  409. lpNewCPlInfo->lData = 0;
  410. lpNewCPlInfo->hIcon = LoadIcon( hInstance,
  411. (LPCTSTR)MAKEINTRESOURCE(IDI_ICON) );
  412. LoadString(hInstance, IDS_NAME, lpNewCPlInfo->szName, 32);
  413. LoadString(hInstance, IDS_INFO, lpNewCPlInfo->szInfo, 64);
  414. lpNewCPlInfo->szHelpFile[0] = CHAR_NULL;
  415. break;
  416. }
  417. case ( CPL_SELECT ) :
  418. {
  419. //
  420. // Applet has been selected, do nothing.
  421. //
  422. break;
  423. }
  424. case ( CPL_DBLCLK ) :
  425. {
  426. //
  427. // Applet icon double clicked -- invoke property sheet with
  428. // the first property sheet page on top.
  429. //
  430. DoProperties(hwnd, (LPCTSTR)NULL);
  431. break;
  432. }
  433. case ( CPL_STARTWPARMS ) :
  434. {
  435. //
  436. // Same as CPL_DBLCLK, but lParam2 is a long pointer to
  437. // a string of extra directions that are to be supplied to
  438. // the property sheet that is to be initiated.
  439. //
  440. DoProperties(hwnd, (LPCTSTR)lParam2);
  441. break;
  442. }
  443. case ( CPL_STOP ) :
  444. {
  445. //
  446. // Sent once for each applet prior to the CPL_EXIT msg.
  447. // Perform applet specific cleanup.
  448. //
  449. break;
  450. }
  451. case ( CPL_EXIT ) :
  452. {
  453. //
  454. // Last message, sent once only, before MMCPL.EXE calls
  455. // FreeLibrary() on this DLL. Do non-applet specific cleanup.
  456. //
  457. DestroyGlobals();
  458. break;
  459. }
  460. default :
  461. {
  462. return (FALSE);
  463. }
  464. }
  465. //
  466. // Return success.
  467. //
  468. return (TRUE);
  469. }
  470. ////////////////////////////////////////////////////////////////////////////
  471. //
  472. // DoProperties
  473. //
  474. ////////////////////////////////////////////////////////////////////////////
  475. void DoProperties(
  476. HWND hwnd,
  477. LPCTSTR pCmdLine)
  478. {
  479. HPROPSHEETPAGE rPages[MAX_PAGES];
  480. PROPSHEETHEADER psh;
  481. LPARAM lParam = SETUP_SWITCH_NONE;
  482. LPTSTR pStartPage;
  483. LPTSTR pSrc;
  484. LPTSTR pSrcDrv;
  485. BOOL bShortDate = FALSE;
  486. BOOL bNoUI = FALSE;
  487. BOOL bUnattended = FALSE;
  488. TCHAR szUnattendFile[MAX_PATH * 2];
  489. HKEY hKey;
  490. TCHAR szSetupSourceDrive[MAX_PATH];
  491. //
  492. // Log if the command line is not null.
  493. //
  494. if (pCmdLine != NULL)
  495. {
  496. g_bLog = TRUE;
  497. }
  498. //
  499. // Begin Log and log command line parameters.
  500. //
  501. Intl_LogSimpleMessage(IDS_LOG_HEAD, NULL);
  502. Intl_LogMessage(pCmdLine);
  503. Intl_LogMessage(TEXT("")); // add a carriage return and newline
  504. //
  505. // Load the library used for Text Services.
  506. //
  507. if (!hInputDLL)
  508. {
  509. hInputDLL = LoadLibrary(szInputLibrary);
  510. }
  511. //
  512. // Initialize the Install/Remove function from the Input applet.
  513. //
  514. if (hInputDLL)
  515. {
  516. //
  517. // Initialize Install function.
  518. //
  519. pfnInstallInputLayout = (BOOL (*)(LCID, DWORD, BOOL, HKL, BOOL, BOOL))
  520. GetProcAddress(hInputDLL, MAKEINTRESOURCEA(ORD_INPUT_INST_LAYOUT));
  521. //
  522. // Initialize Uninstall function.
  523. //
  524. pfnUninstallInputLayout = (BOOL (*)(LCID, DWORD, BOOL))
  525. GetProcAddress(hInputDLL, MAKEINTRESOURCEA(ORD_INPUT_UNINST_LAYOUT));
  526. }
  527. //
  528. // See if there is a command line switch from Setup.
  529. //
  530. psh.nStartPage = (UINT)-1;
  531. while (pCmdLine && *pCmdLine)
  532. {
  533. if (*pCmdLine == TEXT('/'))
  534. {
  535. //
  536. // Legend:
  537. // gG: allow progress bar to show when setup is copying files
  538. // iI: bring up the Input Locale page only
  539. // rR: bring up the General page on top
  540. // sS: setup source string passed on command line
  541. // [example: /s:"c:\winnt"]
  542. //
  543. // NO UI IS SHOWN IF THE FOLLOWING OPTIONS ARE SPECIFIED:
  544. // fF: unattend mode file - no UI is shown
  545. // [example: /f:"c:\unattend.txt"]
  546. // uU: update short date format to 4-digit year - no UI is shown
  547. // (registry only updated if current setting is the
  548. // same as the default setting except for the
  549. // "yy" vs. "yyyy")
  550. // tT: Match system UI font with the default UI language
  551. // dD: disable the setup dialog asking for the source location
  552. //
  553. switch (*++pCmdLine)
  554. {
  555. case ( TEXT('g') ) :
  556. case ( TEXT('G') ) :
  557. {
  558. //
  559. // Log switch.
  560. //
  561. Intl_LogSimpleMessage(IDS_LOG_SWITCH_G, NULL);
  562. //
  563. // Do switch related processing.
  564. //
  565. g_bProgressBarDisplay = TRUE;
  566. pCmdLine++;
  567. break;
  568. }
  569. case ( TEXT('i') ) :
  570. case ( TEXT('I') ) :
  571. {
  572. //
  573. // Log switch.
  574. //
  575. Intl_LogSimpleMessage(IDS_LOG_SWITCH_I, NULL);
  576. //
  577. // Do switch related processing
  578. //
  579. lParam |= SETUP_SWITCH_I;
  580. psh.nStartPage = 0;
  581. pCmdLine++;
  582. break;
  583. }
  584. case ( TEXT('r') ) :
  585. case ( TEXT('R') ) :
  586. {
  587. //
  588. // Log switch.
  589. //
  590. Intl_LogSimpleMessage(IDS_LOG_SWITCH_R, NULL);
  591. //
  592. // Do switch related processing
  593. //
  594. lParam |= SETUP_SWITCH_R;
  595. psh.nStartPage = 0;
  596. pCmdLine++;
  597. break;
  598. }
  599. case ( TEXT('d') ) :
  600. case ( TEXT('D') ) :
  601. {
  602. //
  603. // Log switch.
  604. //
  605. Intl_LogSimpleMessage(IDS_LOG_SWITCH_D, NULL);
  606. //
  607. // Do switch related processing
  608. //
  609. g_bDisableSetupDialog = TRUE;
  610. pCmdLine++;
  611. break;
  612. }
  613. case ( TEXT('s') ) :
  614. case ( TEXT('S') ) :
  615. {
  616. //
  617. // Log switch.
  618. //
  619. Intl_LogSimpleMessage(IDS_LOG_SWITCH_S, NULL);
  620. //
  621. // Get the name of the setup source path.
  622. //
  623. lParam |= SETUP_SWITCH_S;
  624. if ((*++pCmdLine == TEXT(':')) && (*++pCmdLine == TEXT('"')))
  625. {
  626. pCmdLine++;
  627. pSrc = szSetupSourcePath;
  628. pSrcDrv = szSetupSourceDrive;
  629. while (*pCmdLine && (*pCmdLine != TEXT('"')))
  630. {
  631. *pSrc = *pCmdLine;
  632. pSrc++;
  633. *pSrcDrv = *pCmdLine;
  634. pSrcDrv++;
  635. pCmdLine++;
  636. }
  637. *pSrc = 0;
  638. *pSrcDrv = 0;
  639. //wcscpy(szSetupSourcePathWithArchitecture, szSetupSourcePath);
  640. if(FAILED(StringCchCopy(szSetupSourcePathWithArchitecture, MAX_PATH, szSetupSourcePath)))
  641. {
  642. // This should be impossible, but we need to avoid PREfast complaints.
  643. }
  644. pSetupSourcePathWithArchitecture = szSetupSourcePathWithArchitecture;
  645. //
  646. // Remove the architecture-specific portion of
  647. // the source path (that gui-mode setup sent us).
  648. //
  649. pSrc = wcsrchr(szSetupSourcePath, TEXT('\\'));
  650. if (pSrc)
  651. {
  652. *pSrc = TEXT('\0');
  653. }
  654. pSetupSourcePath = szSetupSourcePath;
  655. }
  656. if (*pCmdLine == TEXT('"'))
  657. {
  658. pCmdLine++;
  659. }
  660. pSrcDrv = szSetupSourceDrive;
  661. while (*pSrcDrv)
  662. {
  663. if (*pSrcDrv == TEXT('\\'))
  664. {
  665. pSrcDrv[1] = 0;
  666. }
  667. pSrcDrv++;
  668. }
  669. g_bCDROM = (GetDriveType(szSetupSourceDrive) == DRIVE_CDROM);
  670. break;
  671. }
  672. case ( TEXT('f') ) :
  673. case ( TEXT('F') ) :
  674. {
  675. //
  676. // Log switch.
  677. //
  678. Intl_LogSimpleMessage(IDS_LOG_SWITCH_F, NULL);
  679. //
  680. // Get the name of the unattend file.
  681. //
  682. g_bUnttendMode = TRUE;
  683. bNoUI = TRUE;
  684. szUnattendFile[0] = 0;
  685. if ((*++pCmdLine == TEXT(':')) && (*++pCmdLine == TEXT('"')))
  686. {
  687. pCmdLine++;
  688. pSrc = szUnattendFile;
  689. while (*pCmdLine && (*pCmdLine != TEXT('"')))
  690. {
  691. *pSrc = *pCmdLine;
  692. pSrc++;
  693. pCmdLine++;
  694. }
  695. *pSrc = 0;
  696. }
  697. if (*pCmdLine == TEXT('"'))
  698. {
  699. pCmdLine++;
  700. }
  701. break;
  702. }
  703. case ( TEXT('u') ) :
  704. case ( TEXT('U') ) :
  705. {
  706. //
  707. // Log switch.
  708. //
  709. Intl_LogSimpleMessage(IDS_LOG_SWITCH_U, NULL);
  710. //
  711. // Do switch related processing.
  712. //
  713. bShortDate = TRUE;
  714. bNoUI = TRUE;
  715. break;
  716. }
  717. case ( TEXT('t') ) :
  718. case ( TEXT('T') ) :
  719. {
  720. g_bMatchUIFont = TRUE;
  721. }
  722. default :
  723. {
  724. //
  725. // Log switch.
  726. //
  727. Intl_LogSimpleMessage(IDS_LOG_SWITCH_DEFAULT, pCmdLine);
  728. //
  729. // Fall out, maybe it's a number...
  730. //
  731. break;
  732. }
  733. }
  734. }
  735. else if (*pCmdLine == TEXT(' '))
  736. {
  737. pCmdLine++;
  738. }
  739. else
  740. {
  741. break;
  742. }
  743. }
  744. //
  745. // See if we are in setup mode.
  746. //
  747. g_bSetupCase = Intl_IsSetupMode();
  748. //
  749. // See if the user has Administrative privileges by checking for
  750. // write permission to the registry key.
  751. //
  752. if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  753. c_szInstalledLocales,
  754. 0UL,
  755. KEY_WRITE,
  756. &hKey ) == ERROR_SUCCESS)
  757. {
  758. //
  759. // See if the user can write into the registry. Due to a registry
  760. // modification, we can open a registry key with write access and
  761. // be unable to write to the key... thanks to terminal server.
  762. //
  763. if (RegSetValueEx( hKey,
  764. TEXT("Test"),
  765. 0UL,
  766. REG_SZ,
  767. (LPBYTE)TEXT("Test"),
  768. (DWORD)(lstrlen(TEXT("Test")) + 1) * sizeof(TCHAR) ) == ERROR_SUCCESS)
  769. {
  770. //
  771. // Delete the value created
  772. //
  773. RegDeleteValue(hKey, TEXT("Test"));
  774. //
  775. // We can write to the HKEY_LOCAL_MACHINE key, so the user
  776. // has Admin privileges.
  777. //
  778. g_bAdmin_Privileges = TRUE;
  779. }
  780. else
  781. {
  782. //
  783. // The user does not have admin privileges.
  784. //
  785. g_bAdmin_Privileges = FALSE;
  786. }
  787. RegCloseKey(hKey);
  788. }
  789. //
  790. // See if we are in setup mode.
  791. //
  792. if (g_bSetupCase)
  793. {
  794. //
  795. // We need to remove the hard coded LPK registry key.
  796. //
  797. if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  798. LANGUAGE_PACK_KEY,
  799. 0L,
  800. KEY_READ | KEY_WRITE,
  801. &hKey ) == ERROR_SUCCESS)
  802. {
  803. RegDeleteValue(hKey, LANGUAGE_PACK_VALUE);
  804. RegCloseKey(hKey);
  805. }
  806. }
  807. //
  808. // See if the unattend mode file switch was used.
  809. //
  810. if (g_bUnttendMode)
  811. {
  812. //
  813. // Use the unattend mode file to carry out the appropriate commands.
  814. //
  815. Region_DoUnattendModeSetup(szUnattendFile);
  816. if (Intl_IsWinntUpgrade())
  817. {
  818. //
  819. // Remove MUI files.
  820. //
  821. Intl_RemoveMUIFile();
  822. }
  823. }
  824. //
  825. // If the update to 4-digit year switch was used and the user's short
  826. // date setting is still set to the default for the chosen locale, then
  827. // update the current user's short date setting to the new 4-digit year
  828. // default.
  829. //
  830. if (bShortDate)
  831. {
  832. Region_UpdateShortDate();
  833. }
  834. //
  835. // If we're not to show any UI, then return.
  836. //
  837. if (bNoUI)
  838. {
  839. return;
  840. }
  841. //
  842. // Make sure we have a start page.
  843. //
  844. if (psh.nStartPage == (UINT)-1)
  845. {
  846. psh.nStartPage = 0;
  847. if (pCmdLine && *pCmdLine)
  848. {
  849. //
  850. // Get the start page from the command line.
  851. //
  852. pStartPage = (LPTSTR)pCmdLine;
  853. while ((*pStartPage >= TEXT('0')) && (*pStartPage <= TEXT('9')))
  854. {
  855. psh.nStartPage *= 10;
  856. psh.nStartPage += *pStartPage++ - CHAR_ZERO;
  857. }
  858. //
  859. // Make sure that the requested starting page is less than
  860. // the max page for the selected applet.
  861. //
  862. if (psh.nStartPage >= MAX_PAGES)
  863. {
  864. psh.nStartPage = 0;
  865. }
  866. }
  867. }
  868. //
  869. // Set up the property sheet information.
  870. //
  871. psh.dwSize = sizeof(psh);
  872. psh.dwFlags = 0;
  873. psh.hwndParent = hwnd;
  874. psh.hInstance = hInstance;
  875. psh.nPages = 0;
  876. psh.phpage = rPages;
  877. //
  878. // Add the appropriate property pages.
  879. //
  880. if (lParam &= SETUP_SWITCH_I)
  881. {
  882. psh.pszCaption = MAKEINTRESOURCE(IDS_TEXT_INPUT_METHODS);
  883. Intl_AddExternalPage( &psh,
  884. DLG_INPUT_LOCALES,
  885. hInputDLL,
  886. MAKEINTRESOURCEA(ORD_INPUT_DLG_PROC),
  887. MAX_PAGES ); // One page
  888. }
  889. else
  890. {
  891. psh.pszCaption = MAKEINTRESOURCE(IDS_NAME);
  892. Intl_AddPage(&psh, DLG_GENERAL, GeneralDlgProc, lParam, MAX_PAGES);
  893. Intl_AddPage(&psh, DLG_LANGUAGES, LanguageDlgProc, lParam, MAX_PAGES);
  894. if (g_bAdmin_Privileges == TRUE)
  895. {
  896. Intl_AddPage(&psh, DLG_ADVANCED, AdvancedDlgProc, lParam, MAX_PAGES);
  897. }
  898. }
  899. //
  900. // Make the property sheet.
  901. //
  902. PropertySheet(&psh);
  903. //
  904. // Free the Text Services Library.
  905. //
  906. if (hInputDLL)
  907. {
  908. FreeLibrary(hInputDLL);
  909. pfnInstallInputLayout = NULL;
  910. pfnUninstallInputLayout = NULL;
  911. }
  912. }
  913. ////////////////////////////////////////////////////////////////////////////
  914. //
  915. // IsRtLLocale
  916. //
  917. ////////////////////////////////////////////////////////////////////////////
  918. #define MAX_FONTSIGNATURE 16 // length of font signature string
  919. BOOL IsRtLLocale(
  920. LCID iLCID)
  921. {
  922. WORD wLCIDFontSignature[MAX_FONTSIGNATURE];
  923. BOOL bRet = FALSE;
  924. //
  925. // Verify that this is an RTL (BiDi) locale. Call GetLocaleInfo with
  926. // LOCALE_FONTSIGNATURE which always gives back 16 WORDs.
  927. //
  928. if (GetLocaleInfo( iLCID,
  929. LOCALE_FONTSIGNATURE,
  930. (LPTSTR) wLCIDFontSignature,
  931. (sizeof(wLCIDFontSignature) / sizeof(TCHAR)) ))
  932. {
  933. //
  934. // Verify the bits show a BiDi UI locale.
  935. //
  936. if (wLCIDFontSignature[7] & 0x0800)
  937. {
  938. bRet = TRUE;
  939. }
  940. }
  941. //
  942. // Return the result.
  943. //
  944. return (bRet);
  945. }