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.

629 lines
16 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1999 **
  4. //*********************************************************************
  5. //
  6. // LANGUAGE.CPP - Header for the implementation of CLanguage
  7. //
  8. // HISTORY:
  9. //
  10. // 1/27/99 a-jaswed Created.
  11. //
  12. #include "precomp.h"
  13. #include "msobmain.h"
  14. #include "language.h"
  15. #include "appdefs.h"
  16. #include "dispids.h"
  17. #define DEFAULT_BUFFER_SIZE BYTES_REQUIRED_BY_CCH(2048)
  18. DISPATCHLIST LanguageExternalInterface[] =
  19. {
  20. {L"get_NumOfRegions", DISPID_GETNUMOFREGIONS },
  21. {L"get_RegionName", DISPID_GETREGIONNAME },
  22. {L"get_RegionIndex", DISPID_GETREGIONINDEX },
  23. {L"set_RegionIndex", DISPID_SETREGIONINDEX },
  24. {L"get_NumOfLangs", DISPID_GETNUMOFLANGS },
  25. {L"get_LangName", DISPID_GETLANGNAME },
  26. {L"get_LangIndex", DISPID_GETLANGINDEX },
  27. {L"set_LangIndex", DISPID_SETLANGINDEX },
  28. {L"get_NumOfKeyboardLayouts", DISPID_GETNUMOFKEYLAYOUTS },
  29. {L"get_KeyboardLayoutName", DISPID_GETKEYNAME },
  30. {L"get_KeyboardLayoutIndex", DISPID_GETKEYLAYOUTINDEX },
  31. {L"set_KeyboardLayoutIndex", DISPID_SETKEYLAYOUTINDEX },
  32. {L"get_RebootState", DISPID_LANGUAGE_GETREBOOTSTATE },
  33. {L"SaveSettings", DISPID_LANGUAGE_SAVESETTINGS },
  34. {L"get_PhoneCountries", DISPID_GETPHONECOUNTRIES }
  35. };
  36. //+---------------------------------------------------------------------------
  37. //
  38. // Function: CompareNameLookUpElements()
  39. //
  40. // Synopsis: Function to compare names used by sort
  41. //
  42. //+---------------------------------------------------------------------------
  43. int __cdecl CompareNameLookUpElements(const void *e1, const void *e2)
  44. {
  45. LPNAMELOOKUPELEMENT pCUE1 = (LPNAMELOOKUPELEMENT)e1;
  46. LPNAMELOOKUPELEMENT pCUE2 = (LPNAMELOOKUPELEMENT)e2;
  47. return CompareString(LOCALE_USER_DEFAULT, 0,
  48. pCUE1->pszName,
  49. -1,
  50. pCUE2->pszName,
  51. -1) - 2;
  52. }
  53. /////////////////////////////////////////////////////////////
  54. // CLanguage::CLanguage
  55. CLanguage::CLanguage()
  56. {
  57. WCHAR szINIPath[MAX_PATH] = L"";
  58. WCHAR Answer[MAX_PATH];
  59. // Init member vars
  60. m_cRef = 0;
  61. m_lRebootState = LANGUAGE_REBOOT_NEVER;
  62. m_poliRegions = NULL;
  63. m_lRegionTotal = 0;
  64. m_lRegionDefault = -1;
  65. m_poliLangs = NULL;
  66. m_lLangTotal = 0;
  67. m_lLangDefault = -1;
  68. m_poliKeyboards = NULL;
  69. m_lKeyboardLayoutTotal = 0;
  70. m_lKeyboardLayoutDefault = -1;
  71. GetCanonicalizedPath(szINIPath, INI_SETTINGS_FILENAME);
  72. m_DefaultRegion = GetPrivateProfileInt(
  73. OPTIONS_SECTION,
  74. DEFAULT_REGION,
  75. 0,
  76. szINIPath
  77. );
  78. GetPrivateProfileString(
  79. OPTIONS_SECTION,
  80. DEFAULT_LANGUAGE,
  81. L"",
  82. Answer,
  83. MAX_PATH,
  84. szINIPath
  85. );
  86. m_DefaultLanguage = wcstoul(Answer, NULL, 16);
  87. GetPrivateProfileString(
  88. OPTIONS_SECTION,
  89. DEFAULT_KEYBOARD,
  90. L"",
  91. Answer,
  92. MAX_PATH,
  93. szINIPath
  94. );
  95. m_DefaultKeyboard = wcstoul(Answer, NULL, 16);
  96. SetupGetGeoOptions(
  97. m_DefaultRegion,
  98. &m_poliRegions,
  99. (LPDWORD) &m_lRegionTotal,
  100. (LPDWORD) &m_lRegionDefault
  101. );
  102. MYASSERT( m_poliRegions );
  103. SetupGetLocaleOptions(
  104. m_DefaultLanguage,
  105. &m_poliLangs,
  106. (LPDWORD) &m_lLangTotal,
  107. (LPDWORD) &m_lLangDefault
  108. );
  109. MYASSERT( m_poliLangs );
  110. SetupGetKeyboardOptions(
  111. m_DefaultKeyboard,
  112. &m_poliKeyboards,
  113. (LPDWORD) &m_lKeyboardLayoutTotal,
  114. (LPDWORD) &m_lKeyboardLayoutDefault);
  115. MYASSERT( m_poliKeyboards );
  116. // The current index should be the defaults.
  117. //
  118. m_lRegionIndex = m_lRegionDefault;
  119. m_lLangIndex = m_lLangDefault;
  120. m_lKeyboardLayoutIndex = m_lKeyboardLayoutDefault;
  121. }
  122. /////////////////////////////////////////////////////////////
  123. // CLanguage::~CLanguage
  124. CLanguage::~CLanguage()
  125. {
  126. if ( m_poliRegions )
  127. SetupDestroyLanguageList( m_poliRegions, m_lRegionTotal );
  128. if ( m_poliLangs )
  129. SetupDestroyLanguageList( m_poliLangs, m_lLangTotal );
  130. if ( m_poliKeyboards )
  131. SetupDestroyLanguageList( m_poliKeyboards, m_lKeyboardLayoutTotal );
  132. MYASSERT(m_cRef == 0);
  133. }
  134. HRESULT CLanguage::get_NumOfRegions(long* plVal)
  135. {
  136. *plVal = m_lRegionTotal;
  137. return S_OK;
  138. }
  139. HRESULT CLanguage::get_NumOfKeyboardLayouts(long* plVal)
  140. {
  141. *plVal = m_lKeyboardLayoutTotal;
  142. return S_OK;
  143. }
  144. HRESULT CLanguage::get_RegionName(long lIndex, BSTR* pbstrVal)
  145. {
  146. if ( lIndex >= m_lRegionTotal )
  147. return E_FAIL;
  148. // *pbstrVal = SysAllocString(m_pRegionNameLookUp[lIndex].pszName);
  149. *pbstrVal = SysAllocString( m_poliRegions[lIndex].Name );
  150. return S_OK;
  151. }
  152. HRESULT CLanguage::get_KeyboardLayoutName(long lIndex, BSTR* pbstrVal)
  153. {
  154. if ( lIndex >= m_lKeyboardLayoutTotal )
  155. return E_FAIL;
  156. // *pbstrVal = SysAllocString(m_pKeyboardNameLookUp[lIndex].pszName);
  157. *pbstrVal = SysAllocString( m_poliKeyboards[lIndex].Name );
  158. return S_OK;
  159. }
  160. HRESULT CLanguage::get_RebootState(long* plVal)
  161. {
  162. *plVal = m_lRebootState;
  163. return S_OK;
  164. }
  165. HRESULT CLanguage::SaveSettings()
  166. {
  167. // Only save the settings if they changed.
  168. //
  169. if ( ( m_lRegionIndex >= 0 ) &&
  170. ( m_lLangIndex >= 0 ) &&
  171. ( m_lKeyboardLayoutIndex >= 0 ) &&
  172. m_poliRegions &&
  173. m_poliLangs &&
  174. m_poliKeyboards
  175. )
  176. //( m_lRegionDefault != m_lRegionIndex ) ||
  177. //( m_lKeyboardLayoutDefault != m_lKeyboardLayoutIndex ) )
  178. {
  179. if (SetupSetIntlOptions(
  180. m_poliRegions[m_lRegionIndex].Id,
  181. m_poliLangs[m_lLangIndex].Id,
  182. m_poliKeyboards[m_lKeyboardLayoutIndex].Id
  183. ))
  184. {
  185. // BUGBUG: The return value from SetIntlOptions on Win9x is
  186. // interpreted as a reboot state. How do we determine reboot state
  187. // on Whistler?
  188. // Now the defaults are what is currently saved.
  189. //
  190. m_lRegionDefault = m_lRegionIndex;
  191. m_lLangDefault = m_lLangIndex;
  192. m_lKeyboardLayoutDefault = m_lKeyboardLayoutIndex;
  193. }
  194. }
  195. return S_OK;
  196. }
  197. ////////////////////////////////////////////////
  198. ////////////////////////////////////////////////
  199. //// GET / SET :: RegionIndex
  200. ////
  201. HRESULT CLanguage::get_RegionIndex(long* plVal)
  202. {
  203. *plVal = m_lRegionIndex;
  204. return S_OK;
  205. }
  206. HRESULT CLanguage::set_RegionIndex(long lVal)
  207. {
  208. m_lRegionIndex = lVal;
  209. // m_lRegionIndex = m_pRegionNameLookUp[lVal].nIndex;
  210. return S_OK;
  211. }
  212. ////////////////////////////////////////////////
  213. ////////////////////////////////////////////////
  214. //// GET / SET :: KeyboardLayoutIndex
  215. ////
  216. HRESULT CLanguage::get_KeyboardLayoutIndex(long* plVal)
  217. {
  218. *plVal = m_lKeyboardLayoutIndex;
  219. return S_OK;
  220. }
  221. HRESULT CLanguage::set_KeyboardLayoutIndex(long lVal)
  222. {
  223. m_lKeyboardLayoutIndex = lVal;
  224. // m_lKeyboardLayoutIndex = m_pKeyboardNameLookUp[lVal].nIndex;;
  225. return S_OK;
  226. }
  227. /////////////////////////////////////////////////////////////
  228. /////////////////////////////////////////////////////////////
  229. /////////////////////////////////////////////////////////////
  230. /////// IUnknown implementation
  231. ///////
  232. ///////
  233. /////////////////////////////////////////////////////////////
  234. // CLanguage::QueryInterface
  235. STDMETHODIMP CLanguage::QueryInterface(REFIID riid, LPVOID* ppvObj)
  236. {
  237. // must set out pointer parameters to NULL
  238. *ppvObj = NULL;
  239. if ( riid == IID_IUnknown)
  240. {
  241. AddRef();
  242. *ppvObj = (IUnknown*)this;
  243. return ResultFromScode(S_OK);
  244. }
  245. if (riid == IID_IDispatch)
  246. {
  247. AddRef();
  248. *ppvObj = (IDispatch*)this;
  249. return ResultFromScode(S_OK);
  250. }
  251. // Not a supported interface
  252. return ResultFromScode(E_NOINTERFACE);
  253. }
  254. /////////////////////////////////////////////////////////////
  255. // CLanguage::AddRef
  256. STDMETHODIMP_(ULONG) CLanguage::AddRef()
  257. {
  258. return ++m_cRef;
  259. }
  260. /////////////////////////////////////////////////////////////
  261. // CLanguage::Release
  262. STDMETHODIMP_(ULONG) CLanguage::Release()
  263. {
  264. return --m_cRef;
  265. }
  266. /////////////////////////////////////////////////////////////
  267. /////////////////////////////////////////////////////////////
  268. /////////////////////////////////////////////////////////////
  269. /////// IDispatch implementation
  270. ///////
  271. ///////
  272. /////////////////////////////////////////////////////////////
  273. // CLanguage::GetTypeInfo
  274. STDMETHODIMP CLanguage::GetTypeInfo(UINT, LCID, ITypeInfo**)
  275. {
  276. return E_NOTIMPL;
  277. }
  278. /////////////////////////////////////////////////////////////
  279. // CLanguage::GetTypeInfoCount
  280. STDMETHODIMP CLanguage::GetTypeInfoCount(UINT* pcInfo)
  281. {
  282. return E_NOTIMPL;
  283. }
  284. /////////////////////////////////////////////////////////////
  285. // CLanguage::GetIDsOfNames
  286. STDMETHODIMP CLanguage::GetIDsOfNames(REFIID riid,
  287. OLECHAR** rgszNames,
  288. UINT cNames,
  289. LCID lcid,
  290. DISPID* rgDispId)
  291. {
  292. HRESULT hr = DISP_E_UNKNOWNNAME;
  293. rgDispId[0] = DISPID_UNKNOWN;
  294. for (int iX = 0; iX < sizeof(LanguageExternalInterface)/sizeof(DISPATCHLIST); iX ++)
  295. {
  296. if(lstrcmp(LanguageExternalInterface[iX].szName, rgszNames[0]) == 0)
  297. {
  298. rgDispId[0] = LanguageExternalInterface[iX].dwDispID;
  299. hr = NOERROR;
  300. break;
  301. }
  302. }
  303. // Set the disid's for the parameters
  304. if (cNames > 1)
  305. {
  306. // Set a DISPID for function parameters
  307. for (UINT i = 1; i < cNames ; i++)
  308. rgDispId[i] = DISPID_UNKNOWN;
  309. }
  310. return hr;
  311. }
  312. /////////////////////////////////////////////////////////////
  313. // CLanguage::Invoke
  314. HRESULT CLanguage::Invoke
  315. (
  316. DISPID dispidMember,
  317. REFIID riid,
  318. LCID lcid,
  319. WORD wFlags,
  320. DISPPARAMS* pdispparams,
  321. VARIANT* pvarResult,
  322. EXCEPINFO* pexcepinfo,
  323. UINT* puArgErr
  324. )
  325. {
  326. HRESULT hr = S_OK;
  327. switch(dispidMember)
  328. {
  329. case DISPID_GETNUMOFREGIONS:
  330. {
  331. TRACE(L"DISPID_GETNUMOFREGIONS\n");
  332. if(pvarResult)
  333. {
  334. VariantInit(pvarResult);
  335. V_VT(pvarResult) = VT_I4;
  336. get_NumOfRegions(&(pvarResult->lVal));
  337. }
  338. break;
  339. }
  340. case DISPID_GETREGIONINDEX:
  341. {
  342. TRACE(L"DISPID_GETREGIONINDEX\n");
  343. if(pvarResult)
  344. {
  345. VariantInit(pvarResult);
  346. V_VT(pvarResult) = VT_I4;
  347. get_RegionIndex(&(pvarResult->lVal));
  348. }
  349. break;
  350. }
  351. case DISPID_SETREGIONINDEX:
  352. {
  353. TRACE(L"DISPID_SETREGIONINDEX\n");
  354. if(pdispparams && &pdispparams[0].rgvarg[0])
  355. set_RegionIndex(pdispparams[0].rgvarg[0].lVal);
  356. break;
  357. }
  358. case DISPID_GETREGIONNAME:
  359. {
  360. TRACE(L"DISPID_GETREGIONNAME\n");
  361. if(pvarResult)
  362. {
  363. VariantInit(pvarResult);
  364. V_VT(pvarResult) = VT_BSTR;
  365. if(pdispparams && &pdispparams[0].rgvarg[0])
  366. get_RegionName(pdispparams[0].rgvarg[0].lVal, &(pvarResult->bstrVal));
  367. }
  368. break;
  369. }
  370. // BUGBUG: Need to Lang processing to syssetup.dll
  371. case DISPID_GETNUMOFLANGS:
  372. {
  373. TRACE(L"DISPID_GETNUMOFFLANGS\n");
  374. if(pvarResult)
  375. {
  376. VariantInit(pvarResult);
  377. V_VT(pvarResult) = VT_I4;
  378. pvarResult->lVal = m_lLangTotal;
  379. }
  380. break;
  381. }
  382. case DISPID_GETLANGINDEX:
  383. {
  384. TRACE(L"DISPID_GETLANGINDEX\n");
  385. if(pvarResult)
  386. {
  387. VariantInit(pvarResult);
  388. V_VT(pvarResult) = VT_I4;
  389. pvarResult->lVal = m_lLangIndex;
  390. }
  391. break;
  392. }
  393. case DISPID_SETLANGINDEX:
  394. {
  395. TRACE(L"DISPID_SETLANGINDEX\n");
  396. if(pdispparams && &pdispparams[0].rgvarg[0]) {
  397. m_lLangIndex = pdispparams[0].rgvarg[0].lVal;
  398. }
  399. break;
  400. }
  401. case DISPID_GETLANGNAME:
  402. {
  403. TRACE(L"DISPID_GETLANGNAME\n");
  404. if(pvarResult)
  405. {
  406. VariantInit(pvarResult);
  407. V_VT(pvarResult) = VT_BSTR;
  408. if(pdispparams && &pdispparams[0].rgvarg[0]) {
  409. long lIndex = pdispparams[0].rgvarg[0].lVal;
  410. // BUGBUG: What if lIndex < 0??
  411. if ( lIndex >= m_lLangTotal )
  412. return E_FAIL;
  413. pvarResult->bstrVal = SysAllocString( m_poliLangs[lIndex].Name );
  414. }
  415. }
  416. break;
  417. }
  418. case DISPID_GETNUMOFKEYLAYOUTS:
  419. {
  420. TRACE(L"DISPID_GETNUMOFKEYLAYOUTS\n");
  421. if(pvarResult)
  422. {
  423. VariantInit(pvarResult);
  424. V_VT(pvarResult) = VT_I4;
  425. get_NumOfKeyboardLayouts(&(pvarResult->lVal));
  426. }
  427. break;
  428. }
  429. case DISPID_GETKEYLAYOUTINDEX:
  430. {
  431. TRACE(L"DISPID_GETKEYLAYOUTINDEX\n");
  432. if(pvarResult)
  433. {
  434. VariantInit(pvarResult);
  435. V_VT(pvarResult) = VT_I4;
  436. get_KeyboardLayoutIndex(&(pvarResult->lVal));
  437. }
  438. break;
  439. }
  440. case DISPID_SETKEYLAYOUTINDEX:
  441. {
  442. TRACE(L"DISPID_SETKEYLAYOUTINDEX\n");
  443. if(pdispparams && &pdispparams[0].rgvarg[0])
  444. set_KeyboardLayoutIndex(pdispparams[0].rgvarg[0].lVal);
  445. break;
  446. }
  447. case DISPID_GETKEYNAME:
  448. {
  449. TRACE(L"DISPID_GETKEYNAME\n");
  450. if(pvarResult)
  451. {
  452. VariantInit(pvarResult);
  453. V_VT(pvarResult) = VT_BSTR;
  454. if(pdispparams && &pdispparams[0].rgvarg[0])
  455. get_KeyboardLayoutName(pdispparams[0].rgvarg[0].lVal, &(pvarResult->bstrVal));
  456. }
  457. break;
  458. }
  459. case DISPID_LANGUAGE_GETREBOOTSTATE:
  460. {
  461. TRACE(L"DISPID_LANGUAGE_GETREBOOTSTATE\n");
  462. if(pvarResult)
  463. {
  464. VariantInit(pvarResult);
  465. V_VT(pvarResult) = VT_I4;
  466. get_RebootState(&(pvarResult->lVal));
  467. }
  468. break;
  469. }
  470. case DISPID_LANGUAGE_SAVESETTINGS:
  471. {
  472. TRACE(L"DISPID_LANGUAGE_SAVESETTINGS\n");
  473. SaveSettings();
  474. break;
  475. }
  476. case DISPID_GETPHONECOUNTRIES:
  477. {
  478. TRACE(L"DISPID_GETPHONECOUNTRIES");
  479. if(pvarResult)
  480. {
  481. WCHAR PhoneInfName[MAX_PATH];
  482. GetOOBEMUIPath( PhoneInfName );
  483. lstrcat( PhoneInfName, L"\\phone.inf" );
  484. VariantInit(pvarResult);
  485. V_VT(pvarResult) = VT_BSTR;
  486. pvarResult->bstrVal = SysAllocString(
  487. SetupReadPhoneList( PhoneInfName ) );
  488. }
  489. break;
  490. }
  491. default:
  492. {
  493. hr = DISP_E_MEMBERNOTFOUND;
  494. break;
  495. }
  496. }
  497. return hr;
  498. }