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.

1274 lines
38 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: fekbd.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * OEM-specific tables and routines for FarEast keyboards.
  7. *
  8. * History:
  9. * 16-07-96 hideyukn Created.
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. /*
  14. * This macro will clear Virtual key code.
  15. */
  16. #define NLS_CLEAR_VK(Vk) \
  17. ((Vk) &= (KBDEXT|KBDMULTIVK|KBDSPECIAL|KBDNUMPAD|KBDBREAK))
  18. /*
  19. * This macro will clear Virtual key code and 'make'/'break' bit.
  20. */
  21. #define NLS_CLEAR_VK_AND_ATTR(Vk) \
  22. ((Vk) &= (KBDEXT|KBDMULTIVK|KBDSPECIAL|KBDNUMPAD))
  23. /*
  24. * VK_DBE_xxx tables.
  25. */
  26. BYTE NlsAlphaNumMode[] = {VK_DBE_ALPHANUMERIC,VK_DBE_HIRAGANA,VK_DBE_KATAKANA,0};
  27. BYTE NlsSbcsDbcsMode[] = {VK_DBE_SBCSCHAR,VK_DBE_DBCSCHAR,0};
  28. BYTE NlsRomanMode[] = {VK_DBE_NOROMAN,VK_DBE_ROMAN,0};
  29. BYTE NlsCodeInputMode[] = {VK_DBE_NOCODEINPUT,VK_DBE_CODEINPUT,0};
  30. /*
  31. * Modifiers for generate NLS Virtual Key.
  32. */
  33. VK_TO_BIT aVkToBits_NLSKBD[] = {
  34. { VK_SHIFT, KBDSHIFT},
  35. { VK_CONTROL, KBDCTRL},
  36. { VK_MENU, KBDALT},
  37. { 0, 0}
  38. };
  39. MODIFIERS Modifiers_NLSKBD = {
  40. &aVkToBits_NLSKBD[0],
  41. 7,
  42. {
  43. 0, // modifier keys (VK modification number 0)
  44. 1, // modifier keys (VK modification number 1)
  45. 2, // modifier keys (VK modification number 2)
  46. 3, // modifier keys (VK modification number 3)
  47. 4, // modifier keys (VK modification number 4)
  48. 5, // modifier keys (VK modification number 5)
  49. 6, // modifier keys (VK modification number 6)
  50. 7, // modifier keys (VK modification number 7)
  51. }
  52. };
  53. /*
  54. * For PC-9800 Series configuration.
  55. */
  56. #define GEN_KANA_AWARE 0x1 // Switch generation for VK_END/VK_HELP based on Kana On/Off.
  57. #define GEN_VK_END 0x2 // Generate VK_END, otherwise VK_HELP.
  58. #define GEN_VK_HOME 0x4 // Generate VK_HOME, otherwise VK_CLEAR.
  59. #define IS_KANA_AWARE() (fNlsKbdConfiguration & GEN_KANA_AWARE)
  60. #define IS_SEND_VK_END() (fNlsKbdConfiguration & GEN_VK_END)
  61. #define IS_SEND_VK_HOME() (fNlsKbdConfiguration & GEN_VK_HOME)
  62. BYTE fNlsKbdConfiguration = GEN_KANA_AWARE | GEN_VK_END | GEN_VK_HOME;
  63. /***************************************************************************\
  64. * NlsTestKeyStateToggle()
  65. *
  66. * History:
  67. * 16-07-96 hideyukn Created.
  68. \***************************************************************************/
  69. BOOL NlsTestKeyStateToggle(BYTE Vk)
  70. {
  71. if (gpqForeground) {
  72. return (TestKeyStateToggle(gpqForeground,Vk));
  73. } else {
  74. return (TestAsyncKeyStateToggle(Vk));
  75. }
  76. }
  77. /***************************************************************************\
  78. * NlsSetKeyStateToggle(BYTE Vk)
  79. *
  80. * History:
  81. * 27-09-96 hideyukn Created.
  82. \***************************************************************************/
  83. VOID NlsSetKeyStateToggle(BYTE Vk)
  84. {
  85. if (gpqForeground)
  86. SetKeyStateToggle(gpqForeground,Vk);
  87. SetAsyncKeyStateToggle(Vk);
  88. }
  89. /***************************************************************************\
  90. * NlsClearKeyStateToggle()
  91. *
  92. * History:
  93. * 16-07-96 hideyukn Created.
  94. \***************************************************************************/
  95. VOID NlsClearKeyStateToggle(BYTE Vk)
  96. {
  97. if (gpqForeground)
  98. ClearKeyStateToggle(gpqForeground,Vk);
  99. ClearAsyncKeyStateToggle(Vk);
  100. }
  101. /***************************************************************************\
  102. * NlsGetCurrentInputMode()
  103. *
  104. * History:
  105. * 16-07-96 hideyukn Created.
  106. \***************************************************************************/
  107. BYTE NlsGetCurrentInputMode(BYTE *QueryMode)
  108. {
  109. BYTE *VkTable = QueryMode;
  110. BYTE VkDefault;
  111. /*
  112. * Get VkDefault, we will return this, if no bit is toggled.
  113. */
  114. VkDefault = *VkTable;
  115. while (*VkTable) {
  116. if (NlsTestKeyStateToggle(*VkTable)) {
  117. return *VkTable;
  118. }
  119. VkTable++;
  120. }
  121. /* Something error */
  122. return VkDefault;
  123. }
  124. /***************************************************************************\
  125. * NlsNullProc() - nothing to do
  126. *
  127. * History:
  128. * 16-07-96 hideyukn Created.
  129. \***************************************************************************/
  130. BOOL NlsNullProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  131. {
  132. UNREFERENCED_PARAMETER(pKe);
  133. UNREFERENCED_PARAMETER(dwExtraInfo);
  134. UNREFERENCED_PARAMETER(dwParam);
  135. /*
  136. * Actually we should not get here...
  137. */
  138. return TRUE;
  139. }
  140. /***************************************************************************\
  141. * NlsSendBaseVk() - nothing to do
  142. *
  143. * History:
  144. * 16-07-96 hideyukn Created.
  145. \***************************************************************************/
  146. BOOL NlsSendBaseVk(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  147. {
  148. UNREFERENCED_PARAMETER(pKe);
  149. UNREFERENCED_PARAMETER(dwExtraInfo);
  150. UNREFERENCED_PARAMETER(dwParam);
  151. /*
  152. * We don't need to modify Original data.
  153. */
  154. return TRUE;
  155. }
  156. /***************************************************************************\
  157. * NlsSendParamVk() - Replace original message with parameter
  158. *
  159. * History:
  160. * 16-07-96 hideyukn Created.
  161. \***************************************************************************/
  162. BOOL NlsSendParamVk(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  163. {
  164. UNREFERENCED_PARAMETER(dwExtraInfo);
  165. /*
  166. * Clear Virtual code.
  167. */
  168. NLS_CLEAR_VK(pKe->usFlaggedVk);
  169. /*
  170. * Set parameter as new VK key.
  171. */
  172. pKe->usFlaggedVk |= (BYTE)dwParam;
  173. return TRUE;
  174. }
  175. /***************************************************************************\
  176. * NlsLapseProc() - Lapse handle (Locale dependent)
  177. *
  178. * History:
  179. * 16-07-96 hideyukn Created.
  180. \***************************************************************************/
  181. BOOL NlsLapseProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  182. {
  183. UNREFERENCED_PARAMETER(pKe);
  184. UNREFERENCED_PARAMETER(dwExtraInfo);
  185. UNREFERENCED_PARAMETER(dwParam);
  186. /*
  187. * Just throw away this event.
  188. */
  189. return FALSE;
  190. }
  191. /***************************************************************************\
  192. * AlphanumericModeProc() - handle special case Alphanumeric key
  193. *
  194. * History:
  195. * 16-07-96 hideyukn Created.
  196. \***************************************************************************/
  197. BOOL NlsAlphanumericModeProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  198. {
  199. if (!(pKe->usFlaggedVk & KBDBREAK)) {
  200. /*
  201. * We are in 'make' sequence.
  202. */
  203. /*
  204. * Clear Virtual code.
  205. */
  206. NLS_CLEAR_VK(pKe->usFlaggedVk);
  207. if (!NlsTestKeyStateToggle(VK_DBE_ALPHANUMERIC)) {
  208. /*
  209. * Query current mode.
  210. */
  211. BYTE CurrentMode = NlsGetCurrentInputMode(NlsAlphaNumMode);
  212. /*
  213. * Off toggle for previous key mode.
  214. */
  215. NlsClearKeyStateToggle(CurrentMode);
  216. /*
  217. * We are not in 'AlphaNumeric' mode, before enter 'AlphaNumeric'
  218. * mode, we should send 'break' for previous key mode.
  219. */
  220. xxxKeyEvent((USHORT)(pKe->usFlaggedVk | CurrentMode | KBDBREAK),
  221. pKe->bScanCode, pKe->dwTime, dwExtraInfo,
  222. #ifdef GENERIC_INPUT
  223. pKe->hDevice,
  224. &pKe->data,
  225. #endif
  226. FALSE);
  227. }
  228. /*
  229. * Switch to 'AlphaNumeric' mode.
  230. */
  231. pKe->usFlaggedVk |= VK_DBE_ALPHANUMERIC;
  232. /*
  233. * Call i/o control.
  234. */
  235. if ((!gdwIMEOpenStatus) && NlsTestKeyStateToggle(VK_KANA)) {
  236. NlsKbdSendIMEProc(TRUE, IME_CMODE_KATAKANA);
  237. }
  238. } else {
  239. return NlsLapseProc(pKe,dwExtraInfo,dwParam);
  240. }
  241. return TRUE;
  242. }
  243. /***************************************************************************\
  244. * KatakanaModeProc() - handle special case Katakana key
  245. *
  246. * History:
  247. * 16-07-96 hideyukn Created.
  248. \***************************************************************************/
  249. BOOL NlsKatakanaModeProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  250. {
  251. if (!(pKe->usFlaggedVk & KBDBREAK)) {
  252. /*
  253. * We are in 'make' sequence.
  254. */
  255. /*
  256. * Clear Virtual code.
  257. */
  258. NLS_CLEAR_VK(pKe->usFlaggedVk);
  259. if (!NlsTestKeyStateToggle(VK_DBE_KATAKANA)) {
  260. /*
  261. * Query current mode.
  262. */
  263. BYTE CurrentMode = NlsGetCurrentInputMode(NlsAlphaNumMode);
  264. /*
  265. * Off toggle for previous key mode.
  266. */
  267. NlsClearKeyStateToggle(CurrentMode);
  268. /*
  269. * We are not in 'Katakana' mode, yet. Before enter 'Katakana'
  270. * mode, we should make 'break key' for previous mode.
  271. */
  272. xxxKeyEvent((USHORT)(pKe->usFlaggedVk | CurrentMode | KBDBREAK),
  273. pKe->bScanCode, pKe->dwTime, dwExtraInfo,
  274. #ifdef GENERIC_INPUT
  275. pKe->hDevice,
  276. &pKe->data,
  277. #endif
  278. FALSE);
  279. }
  280. /*
  281. * Switch to 'Katakana' mode.
  282. */
  283. pKe->usFlaggedVk |= VK_DBE_KATAKANA;
  284. /*
  285. * Call i/o control.
  286. */
  287. if ((!gdwIMEOpenStatus) && (!(NlsTestKeyStateToggle(VK_KANA)))) {
  288. NlsKbdSendIMEProc(FALSE, IME_CMODE_ALPHANUMERIC);
  289. }
  290. } else {
  291. return(NlsLapseProc(pKe,dwExtraInfo,dwParam));
  292. }
  293. return TRUE;
  294. }
  295. /***************************************************************************\
  296. * HiraganaModeProc() - handle special case Hiragana key (Locale dependent)
  297. *
  298. * History:
  299. * 16-07-96 hideyukn Created.
  300. \***************************************************************************/
  301. BOOL NlsHiraganaModeProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  302. {
  303. if (!(pKe->usFlaggedVk & KBDBREAK)) {
  304. /*
  305. * We are in 'make' sequence.
  306. */
  307. /*
  308. * Clear Virtual code.
  309. */
  310. NLS_CLEAR_VK(pKe->usFlaggedVk);
  311. if (!NlsTestKeyStateToggle(VK_DBE_HIRAGANA)) {
  312. /*
  313. * Query current mode.
  314. */
  315. BYTE CurrentMode = NlsGetCurrentInputMode(NlsAlphaNumMode);
  316. /*
  317. * Off toggle for previous key mode.
  318. */
  319. NlsClearKeyStateToggle(CurrentMode);
  320. /*
  321. * We are not in 'Hiragana' mode, yet. Before enter 'Hiragana'
  322. * mode, we should make 'break key' for previous key.
  323. */
  324. xxxKeyEvent((USHORT)(pKe->usFlaggedVk | CurrentMode | KBDBREAK),
  325. pKe->bScanCode, pKe->dwTime, dwExtraInfo,
  326. #ifdef GENERIC_INPUT
  327. pKe->hDevice,
  328. &pKe->data,
  329. #endif
  330. FALSE);
  331. }
  332. /*
  333. * Switch to 'Hiragana' mode.
  334. */
  335. pKe->usFlaggedVk |= VK_DBE_HIRAGANA;
  336. /*
  337. * Call i/o control.
  338. */
  339. if ((!gdwIMEOpenStatus) && (!(NlsTestKeyStateToggle(VK_KANA)))) {
  340. NlsKbdSendIMEProc(FALSE, IME_CMODE_ALPHANUMERIC);
  341. }
  342. } else {
  343. return (NlsLapseProc(pKe,dwExtraInfo,dwParam));
  344. }
  345. return TRUE;
  346. }
  347. /***************************************************************************\
  348. * SbcsDbcsToggleProc() - handle special case SBCS/DBCS key
  349. *
  350. * History:
  351. * 16-07-96 hideyukn Created.
  352. \***************************************************************************/
  353. BOOL NlsSbcsDbcsToggleProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  354. {
  355. if (!(pKe->usFlaggedVk & KBDBREAK)) {
  356. /*
  357. * We are in 'make' sequence.
  358. */
  359. /*
  360. * Query current 'Sbcs'/'Dbcs' mode.
  361. */
  362. BYTE CurrentMode = NlsGetCurrentInputMode(NlsSbcsDbcsMode);
  363. /*
  364. * Clear Virtual code.
  365. */
  366. NLS_CLEAR_VK(pKe->usFlaggedVk);
  367. /*
  368. * Off toggle for previous key mode.
  369. */
  370. NlsClearKeyStateToggle(CurrentMode);
  371. switch (CurrentMode) {
  372. case VK_DBE_SBCSCHAR:
  373. /*
  374. * We are in 'SbcsChar' mode, let us send 'break key' for that.
  375. */
  376. xxxKeyEvent((USHORT)(pKe->usFlaggedVk|VK_DBE_SBCSCHAR|KBDBREAK),
  377. pKe->bScanCode, pKe->dwTime, dwExtraInfo,
  378. #ifdef GENERIC_INPUT
  379. pKe->hDevice,
  380. &pKe->data,
  381. #endif
  382. FALSE);
  383. /*
  384. * Then, switch to 'DbcsChar' mode.
  385. */
  386. pKe->usFlaggedVk |= VK_DBE_DBCSCHAR;
  387. break;
  388. case VK_DBE_DBCSCHAR:
  389. /*
  390. * We are in 'DbcsChar' mode, let us send 'break key' for that.
  391. */
  392. xxxKeyEvent((USHORT)(pKe->usFlaggedVk|VK_DBE_DBCSCHAR|KBDBREAK),
  393. pKe->bScanCode, pKe->dwTime, dwExtraInfo,
  394. #ifdef GENERIC_INPUT
  395. pKe->hDevice,
  396. &pKe->data,
  397. #endif
  398. FALSE);
  399. /*
  400. * Then, switch to 'SbcsChar' mode.
  401. */
  402. pKe->usFlaggedVk |= VK_DBE_SBCSCHAR;
  403. break;
  404. }
  405. } else {
  406. return(NlsLapseProc(pKe,dwExtraInfo,dwParam));
  407. }
  408. return TRUE;
  409. }
  410. /***************************************************************************\
  411. * RomanToggleProc() - handle special case Roman key (Locale dependent)
  412. *
  413. * History:
  414. * 16-07-96 hideyukn Created.
  415. \***************************************************************************/
  416. BOOL NlsRomanToggleProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  417. {
  418. if (!(pKe->usFlaggedVk & KBDBREAK)) {
  419. /*
  420. * We are in 'make' sequence.
  421. */
  422. /*
  423. * Query current 'Roman'/'NoRoman' mode.
  424. */
  425. BYTE CurrentMode = NlsGetCurrentInputMode(NlsRomanMode);
  426. /*
  427. * Clear Virtual code.
  428. */
  429. NLS_CLEAR_VK(pKe->usFlaggedVk);
  430. /*
  431. * Off toggle for previous key mode.
  432. */
  433. NlsClearKeyStateToggle(CurrentMode);
  434. switch (CurrentMode) {
  435. case VK_DBE_NOROMAN:
  436. /*
  437. * We are in 'NoRoman' mode, let us send 'break key' for that.
  438. */
  439. xxxKeyEvent((USHORT)(pKe->usFlaggedVk|VK_DBE_NOROMAN|KBDBREAK),
  440. pKe->bScanCode, pKe->dwTime, dwExtraInfo,
  441. #ifdef GENERIC_INPUT
  442. pKe->hDevice,
  443. &pKe->data,
  444. #endif
  445. FALSE);
  446. /*
  447. * Then, switch to 'Roman' mode.
  448. */
  449. pKe->usFlaggedVk |= VK_DBE_ROMAN;
  450. break;
  451. case VK_DBE_ROMAN:
  452. /*
  453. * We are in 'Roman' mode, let us send 'break key' for that.
  454. */
  455. xxxKeyEvent((USHORT)(pKe->usFlaggedVk|VK_DBE_ROMAN|KBDBREAK),
  456. pKe->bScanCode, pKe->dwTime, dwExtraInfo,
  457. #ifdef GENERIC_INPUT
  458. pKe->hDevice,
  459. &pKe->data,
  460. #endif
  461. FALSE);
  462. /*
  463. * Then, switch to 'NoRoman' mode.
  464. */
  465. pKe->usFlaggedVk |= VK_DBE_NOROMAN;
  466. break;
  467. }
  468. } else {
  469. return(NlsLapseProc(pKe,dwExtraInfo,dwParam));
  470. }
  471. return TRUE;
  472. }
  473. /***************************************************************************\
  474. * CodeInputToggleProc() - handle special case Code Input key
  475. *
  476. * History:
  477. * 16-07-96 hideyukn Created.
  478. \***************************************************************************/
  479. BOOL NlsCodeInputToggleProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  480. {
  481. if (!(pKe->usFlaggedVk & KBDBREAK)) {
  482. /*
  483. * We are in 'make' sequence.
  484. */
  485. /*
  486. * Query current 'CodeInput'/'NoCodeInput' mode.
  487. */
  488. BYTE CurrentMode = NlsGetCurrentInputMode(NlsCodeInputMode);
  489. /*
  490. * Clear Virtual code.
  491. */
  492. NLS_CLEAR_VK(pKe->usFlaggedVk);
  493. /*
  494. * Off toggle for previous key mode.
  495. */
  496. NlsClearKeyStateToggle(CurrentMode);
  497. switch (CurrentMode) {
  498. case VK_DBE_NOCODEINPUT:
  499. /*
  500. * We are in 'NoCodeInput' mode, let us send 'break key' for that.
  501. */
  502. xxxKeyEvent((USHORT)(pKe->usFlaggedVk|VK_DBE_NOCODEINPUT|KBDBREAK),
  503. pKe->bScanCode, pKe->dwTime, dwExtraInfo,
  504. #ifdef GENERIC_INPUT
  505. pKe->hDevice,
  506. &pKe->data,
  507. #endif
  508. FALSE);
  509. /*
  510. * Then, switch to 'CodeInput' mode.
  511. */
  512. pKe->usFlaggedVk |= VK_DBE_CODEINPUT;
  513. break;
  514. case VK_DBE_CODEINPUT:
  515. /*
  516. * We are in 'CodeInput' mode, let us send 'break key' for that.
  517. */
  518. xxxKeyEvent((USHORT)(pKe->usFlaggedVk|VK_DBE_CODEINPUT|KBDBREAK),
  519. pKe->bScanCode, pKe->dwTime, dwExtraInfo,
  520. #ifdef GENERIC_INPUT
  521. pKe->hDevice,
  522. &pKe->data,
  523. #endif
  524. FALSE);
  525. /*
  526. * Then, switch to 'NoCodeInput' mode.
  527. */
  528. pKe->usFlaggedVk |= VK_DBE_NOCODEINPUT;
  529. break;
  530. }
  531. } else {
  532. return(NlsLapseProc(pKe,dwExtraInfo,dwParam));
  533. }
  534. return TRUE;
  535. }
  536. /***************************************************************************\
  537. * KanaToggleProc() - handle special case Kana key (Locale dependent)
  538. *
  539. * History:
  540. * 16-07-96 hideyukn Created.
  541. \***************************************************************************/
  542. BOOL NlsKanaModeToggleProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  543. {
  544. /*
  545. * Check this is 'make' or 'break'.
  546. */
  547. BOOL bMake = !(pKe->usFlaggedVk & KBDBREAK);
  548. /*
  549. * Check we are in 'kana' mode or not.
  550. */
  551. BOOL bKana = NlsTestKeyStateToggle(VK_KANA);
  552. /*
  553. * Clear virtual code and key attributes.
  554. */
  555. NLS_CLEAR_VK_AND_ATTR(pKe->usFlaggedVk);
  556. if (bMake) {
  557. /*
  558. * We are in 'make' sequence.
  559. */
  560. if (bKana) {
  561. /*
  562. * Make 'break' for VK_KANA.
  563. */
  564. pKe->usFlaggedVk |= (VK_KANA|KBDBREAK);
  565. } else {
  566. /*
  567. * Not yet in 'kana' mode, Let generate 'make' for VK_KANA...
  568. */
  569. pKe->usFlaggedVk |= VK_KANA;
  570. }
  571. return TRUE;
  572. } else {
  573. /*
  574. * We will keep 'down' & 'toggled' in 'kana' mode,
  575. * then don't need to generate 'break' for VK_KANA.
  576. * when next time generate 'make' for this, we will generate
  577. * 'break' for this.
  578. */
  579. return(NlsLapseProc(pKe,dwExtraInfo,dwParam));
  580. }
  581. }
  582. /**********************************************************************\
  583. * NlsHelpOrEndProc()
  584. *
  585. * History:
  586. * 26-09-96 hideyukn Ported from NEC code.
  587. \**********************************************************************/
  588. BOOL NlsHelpOrEndProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  589. {
  590. UNREFERENCED_PARAMETER(dwExtraInfo);
  591. UNREFERENCED_PARAMETER(dwParam);
  592. if (!(pKe->usFlaggedVk & KBDNUMPAD)) {
  593. /*
  594. * Clear Virtual code.
  595. */
  596. NLS_CLEAR_VK(pKe->usFlaggedVk);
  597. if (!IS_KANA_AWARE()) {
  598. /*
  599. * We don't care 'kana' status. just check VK_END or VK_HELP.
  600. */
  601. if (IS_SEND_VK_END()) {
  602. pKe->usFlaggedVk |= VK_END;
  603. } else {
  604. pKe->usFlaggedVk |= VK_HELP;
  605. }
  606. } else {
  607. /*
  608. * We care 'kana' status.
  609. */
  610. if (IS_SEND_VK_END()) {
  611. if (NlsTestKeyStateToggle(VK_KANA)) {
  612. pKe->usFlaggedVk |= VK_HELP;
  613. } else {
  614. pKe->usFlaggedVk |= VK_END;
  615. }
  616. } else {
  617. if (NlsTestKeyStateToggle(VK_KANA)) {
  618. pKe->usFlaggedVk |= VK_END;
  619. } else {
  620. pKe->usFlaggedVk |= VK_HELP;
  621. }
  622. }
  623. }
  624. }
  625. return TRUE;
  626. }
  627. /**********************************************************************\
  628. * NlsHelpOrEndProc()
  629. *
  630. * History:
  631. * 26-09-96 hideyukn Ported from NEC code.
  632. \**********************************************************************/
  633. BOOL NlsHomeOrClearProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  634. {
  635. UNREFERENCED_PARAMETER(dwExtraInfo);
  636. UNREFERENCED_PARAMETER(dwParam);
  637. if (!(pKe->usFlaggedVk & KBDNUMPAD)) {
  638. /*
  639. * Clear virtual code.
  640. */
  641. NLS_CLEAR_VK(pKe->usFlaggedVk);
  642. if (IS_SEND_VK_HOME()) {
  643. pKe->usFlaggedVk |= VK_HOME;
  644. } else {
  645. pKe->usFlaggedVk |= VK_CLEAR;
  646. }
  647. }
  648. return TRUE;
  649. }
  650. /**********************************************************************\
  651. * NlsNumpadModeProc()
  652. *
  653. * History:
  654. * 26-09-96 hideyukn Ported from NEC code.
  655. \**********************************************************************/
  656. BOOL NlsNumpadModeProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  657. {
  658. /*
  659. * Get current Virtual key.
  660. */
  661. BYTE Vk = LOBYTE(pKe->usFlaggedVk);
  662. UNREFERENCED_PARAMETER(dwExtraInfo);
  663. UNREFERENCED_PARAMETER(dwParam);
  664. if (!NlsTestKeyStateToggle(VK_NUMLOCK)) {
  665. /*
  666. * Clear virtual code.
  667. */
  668. NLS_CLEAR_VK(pKe->usFlaggedVk);
  669. switch (Vk) {
  670. case VK_NUMPAD0:
  671. pKe->usFlaggedVk |= VK_INSERT;
  672. break;
  673. case VK_NUMPAD1:
  674. pKe->usFlaggedVk |= VK_END;
  675. break;
  676. case VK_NUMPAD2:
  677. pKe->usFlaggedVk |= VK_DOWN;
  678. break;
  679. case VK_NUMPAD3:
  680. pKe->usFlaggedVk |= VK_NEXT;
  681. break;
  682. case VK_NUMPAD4:
  683. pKe->usFlaggedVk |= VK_LEFT;
  684. break;
  685. case VK_NUMPAD5:
  686. pKe->usFlaggedVk |= VK_CLEAR;
  687. break;
  688. case VK_NUMPAD6:
  689. pKe->usFlaggedVk |= VK_RIGHT;
  690. break;
  691. case VK_NUMPAD7:
  692. pKe->usFlaggedVk |= VK_HOME;
  693. break;
  694. case VK_NUMPAD8:
  695. pKe->usFlaggedVk |= VK_UP;
  696. break;
  697. case VK_NUMPAD9:
  698. pKe->usFlaggedVk |= VK_PRIOR;
  699. break;
  700. case VK_DECIMAL:
  701. pKe->usFlaggedVk |= VK_DELETE;
  702. break;
  703. }
  704. } else if (TestRawKeyDown(VK_SHIFT)) {
  705. /*
  706. * Clear virtual code.
  707. */
  708. NLS_CLEAR_VK(pKe->usFlaggedVk);
  709. switch (Vk) {
  710. case VK_NUMPAD0:
  711. pKe->usFlaggedVk |= VK_INSERT;
  712. break;
  713. case VK_NUMPAD1:
  714. pKe->usFlaggedVk |= VK_END;
  715. break;
  716. case VK_NUMPAD2:
  717. pKe->usFlaggedVk |= VK_DOWN;
  718. break;
  719. case VK_NUMPAD3:
  720. pKe->usFlaggedVk |= VK_NEXT;
  721. break;
  722. case VK_NUMPAD4:
  723. pKe->usFlaggedVk |= VK_LEFT;
  724. break;
  725. case VK_NUMPAD5:
  726. pKe->usFlaggedVk |= VK_CLEAR;
  727. break;
  728. case VK_NUMPAD6:
  729. pKe->usFlaggedVk |= VK_RIGHT;
  730. break;
  731. case VK_NUMPAD7:
  732. pKe->usFlaggedVk |= VK_HOME;
  733. break;
  734. case VK_NUMPAD8:
  735. pKe->usFlaggedVk |= VK_UP;
  736. break;
  737. case VK_NUMPAD9:
  738. pKe->usFlaggedVk |= VK_PRIOR;
  739. break;
  740. case VK_DECIMAL:
  741. pKe->usFlaggedVk |= VK_DELETE;
  742. break;
  743. }
  744. } else {
  745. /*
  746. * Otherwise, just pass through...
  747. */
  748. }
  749. return TRUE;
  750. }
  751. /**********************************************************************\
  752. * NlsKanaEventProc() - Fujitsu FMV oyayubi shift keyboard use only.
  753. *
  754. * History:
  755. * 10-10-96 v-kazuta Created.
  756. \**********************************************************************/
  757. BOOL NlsKanaEventProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  758. {
  759. UNREFERENCED_PARAMETER(dwExtraInfo);
  760. /*
  761. * Clear Virtual code.
  762. */
  763. NLS_CLEAR_VK(pKe->usFlaggedVk);
  764. /*
  765. * Set parameter as new VK key.
  766. */
  767. pKe->usFlaggedVk |= (BYTE)dwParam;
  768. /*
  769. * Send notification to kernel mode keyboard driver.
  770. */
  771. if (!(pKe->usFlaggedVk & KBDBREAK)) {
  772. if (NlsTestKeyStateToggle(VK_KANA)) {
  773. /*
  774. * Call i/o control.
  775. */
  776. NlsKbdSendIMEProc(FALSE, IME_CMODE_ALPHANUMERIC);
  777. } else {
  778. /*
  779. * Call i/o control.
  780. */
  781. NlsKbdSendIMEProc(TRUE, IME_CMODE_KATAKANA);
  782. }
  783. }
  784. return TRUE;
  785. }
  786. /**********************************************************************\
  787. * NlsConvOrNonConvProc() - Fujitsu FMV oyayubi shift keyboard only.
  788. *
  789. * History:
  790. * 10-10-96 v-kazuta Created.
  791. \**********************************************************************/
  792. BOOL NlsConvOrNonConvProc(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam)
  793. {
  794. UNREFERENCED_PARAMETER(pKe);
  795. UNREFERENCED_PARAMETER(dwExtraInfo);
  796. UNREFERENCED_PARAMETER(dwParam);
  797. /*
  798. *
  799. */
  800. if ((!gdwIMEOpenStatus) && (!(NlsTestKeyStateToggle(VK_KANA)))) {
  801. NlsKbdSendIMEProc(FALSE, IME_CMODE_ALPHANUMERIC);
  802. }
  803. /*
  804. * We don't need to modify Original data.
  805. */
  806. return TRUE;
  807. }
  808. /**********************************************************************\
  809. * Index to function body dispatcher table
  810. *
  811. * History:
  812. * 16-07-96 hideyukn Created.
  813. \**********************************************************************/
  814. NLSKEPROC aNLSKEProc[] = {
  815. NlsNullProc, // KBDNLS_NULL (Invalid function)
  816. NlsLapseProc, // KBDNLS_NOEVENT (Drop keyevent)
  817. NlsSendBaseVk, // KBDNLS_SEND_BASE_VK (Send Base VK_xxx)
  818. NlsSendParamVk, // KBDNLS_SEND_PARAM_VK (Send Parameter VK_xxx)
  819. NlsKanaModeToggleProc, // KBDNLS_KANAMODE (VK_KANA (Special case))
  820. NlsAlphanumericModeProc, // KBDNLS_ALPHANUM (VK_DBE_ALPHANUMERIC)
  821. NlsHiraganaModeProc, // KBDNLS_HIRAGANA (VK_DBE_HIRAGANA)
  822. NlsKatakanaModeProc, // KBDNLS_KATAKANA (VK_DBE_KATAKANA)
  823. NlsSbcsDbcsToggleProc, // KBDNLS_SBCSDBCS (VK_DBE_SBCSCHAR/VK_DBE_DBCSCHAR)
  824. NlsRomanToggleProc, // KBDNLS_ROMAN (VK_DBE_ROMAN/VK_DBE_NOROMAN)
  825. NlsCodeInputToggleProc, // KBDNLS_CODEINPUT (VK_DBE_CODEINPUT/VK_DBE_NOCODEINPUT)
  826. NlsHelpOrEndProc, // KBDNLS_HELP_OR_END (VK_HELP or VK_END) [NEC PC-9800 Only]
  827. NlsHomeOrClearProc, // KBDNLS_HOME_OR_CLEAR (VK_HOME or VK_CLEAR) [NEC PC-9800 Only]
  828. NlsNumpadModeProc, // KBDNLS_NUMPAD (VK_xxx for Numpad) [NEC PC-9800 Only]
  829. NlsKanaEventProc, // KBDNLS_KANAEVENT (VK_KANA) [Fujitsu FMV oyayubi Only]
  830. NlsConvOrNonConvProc, // KBDNLS_CONV_OR_NONCONV (VK_CONVERT and VK_NONCONVERT) [Fujitsu FMV oyayubi Only]
  831. };
  832. BOOL GenerateNlsVkKey(PVK_F pVkToF, WORD nMod, PKE pKe, ULONG_PTR dwExtraInfo)
  833. {
  834. BYTE iFuncIndex;
  835. DWORD dwParam;
  836. iFuncIndex = pVkToF->NLSFEProc[nMod].NLSFEProcIndex;
  837. dwParam = pVkToF->NLSFEProc[nMod].NLSFEProcParam;
  838. return((aNLSKEProc[iFuncIndex])(pKe, dwExtraInfo, dwParam));
  839. }
  840. BOOL GenerateNlsVkAltKey(PVK_F pVkToF, WORD nMod, PKE pKe, ULONG_PTR dwExtraInfo)
  841. {
  842. BYTE iFuncIndex;
  843. DWORD dwParam;
  844. iFuncIndex = pVkToF->NLSFEProcAlt[nMod].NLSFEProcIndex;
  845. dwParam = pVkToF->NLSFEProcAlt[nMod].NLSFEProcParam;
  846. return((aNLSKEProc[iFuncIndex])(pKe,dwExtraInfo,dwParam));
  847. }
  848. /***************************************************************************\
  849. * KbdNlsFuncTypeDummy() - KBDNLS_FUNC_TYPE_NULL
  850. *
  851. * History:
  852. * 16-07-96 hideyukn Created.
  853. \***************************************************************************/
  854. BOOL KbdNlsFuncTypeDummy(PVK_F pVkToF, PKE pKe, ULONG_PTR dwExtraInfo)
  855. {
  856. UNREFERENCED_PARAMETER(pVkToF);
  857. UNREFERENCED_PARAMETER(pKe);
  858. UNREFERENCED_PARAMETER(dwExtraInfo);
  859. /*
  860. * We don't need to modify Original data.
  861. */
  862. return TRUE;
  863. }
  864. /***************************************************************************\
  865. * KbdNlsFuncTypeNormal - KBDNLS_FUNC_TYPE_NORMAL
  866. *
  867. * History:
  868. * 16-07-96 hideyukn Created.
  869. \***************************************************************************/
  870. BOOL KbdNlsFuncTypeNormal(PVK_F pVkToF, PKE pKe, ULONG_PTR dwExtraInfo)
  871. {
  872. WORD nMod;
  873. if (pKe == NULL) {
  874. /*
  875. * Clear state and deactivate this key processor
  876. */
  877. return FALSE;
  878. }
  879. nMod = GetModificationNumber(&Modifiers_NLSKBD,
  880. GetModifierBits(&Modifiers_NLSKBD,
  881. gafRawKeyState));
  882. if (nMod != SHFT_INVALID) {
  883. return(GenerateNlsVkKey(pVkToF, nMod, pKe, dwExtraInfo));
  884. }
  885. return FALSE;
  886. }
  887. /***************************************************************************\
  888. * KbdNlsFuncTypeAlt - KBDNLS_FUNC_TYPE_ALT
  889. *
  890. * History:
  891. * 16-07-96 hideyukn Created.
  892. \***************************************************************************/
  893. BOOL KbdNlsFuncTypeAlt(PVK_F pVkToF, PKE pKe, ULONG_PTR dwExtraInfo)
  894. {
  895. WORD nMod;
  896. BOOL fRet = FALSE;
  897. if (pKe == NULL) {
  898. /*
  899. * Clear state and deactivate this key processor
  900. */
  901. return FALSE;
  902. }
  903. nMod = GetModificationNumber(&Modifiers_NLSKBD,
  904. GetModifierBits(&Modifiers_NLSKBD,
  905. gafRawKeyState));
  906. if (nMod != SHFT_INVALID) {
  907. if (!(pKe->usFlaggedVk & KBDBREAK)) {
  908. if (pVkToF->NLSFEProcCurrent == KBDNLS_INDEX_ALT) {
  909. fRet = GenerateNlsVkAltKey(pVkToF, nMod, pKe, dwExtraInfo);
  910. } else {
  911. fRet = GenerateNlsVkKey(pVkToF, nMod, pKe, dwExtraInfo);
  912. }
  913. if (pVkToF->NLSFEProcSwitch & (1 << nMod)) {
  914. TAGMSG0(DBGTAG_IMM, "USERKM:FEKBD Switching Alt table");
  915. /*
  916. * Switch to "alt".
  917. */
  918. pVkToF->NLSFEProcCurrent = KBDNLS_INDEX_ALT;
  919. }
  920. } else {
  921. if (pVkToF->NLSFEProcCurrent == KBDNLS_INDEX_ALT) {
  922. fRet = GenerateNlsVkAltKey(pVkToF, nMod, pKe, dwExtraInfo);
  923. /*
  924. * Back to "normal"
  925. */
  926. pVkToF->NLSFEProcCurrent = KBDNLS_INDEX_NORMAL;
  927. } else {
  928. fRet = GenerateNlsVkKey(pVkToF, nMod, pKe, dwExtraInfo);
  929. }
  930. }
  931. }
  932. return fRet;
  933. }
  934. /***************************************************************************\
  935. * KENLSProcs()
  936. *
  937. * History:
  938. * 16-07-96 hideyukn Created.
  939. \***************************************************************************/
  940. NLSVKFPROC aNLSVKFProc[] = {
  941. KbdNlsFuncTypeDummy, // KBDNLS_TYPE_NULL 0
  942. KbdNlsFuncTypeNormal, // KBDNLS_TYPE_NORMAL 1
  943. KbdNlsFuncTypeAlt // KBDNLS_TYPE_TOGGLE 2
  944. };
  945. /*
  946. * Returning FALSE means the Key Event has been deleted by a special-case
  947. * KeyEvent processor.
  948. * Returning TRUE means the Key Event should be passed on (although it may
  949. * have been altered.
  950. */
  951. BOOL xxxKENLSProcs(PKE pKe, ULONG_PTR dwExtraInfo)
  952. {
  953. CheckCritIn();
  954. if (gpKbdNlsTbl != NULL) {
  955. PVK_F pVkToF = gpKbdNlsTbl->pVkToF;
  956. UINT iNumVk = gpKbdNlsTbl->NumOfVkToF;
  957. while(iNumVk) {
  958. if (pVkToF[iNumVk-1].Vk == LOBYTE(pKe->usFlaggedVk)) {
  959. return aNLSVKFProc[pVkToF[iNumVk-1].NLSFEProcType](&pVkToF[iNumVk-1], pKe, dwExtraInfo);
  960. }
  961. iNumVk--;
  962. }
  963. }
  964. /*
  965. * Other special Key Event processors
  966. */
  967. return TRUE;
  968. }
  969. /***************************************************************************\
  970. * NlsKbdSendIMENotification()
  971. *
  972. * History:
  973. * 10-09-96 hideyukn Created.
  974. \***************************************************************************/
  975. VOID NlsKbdSendIMENotification(DWORD dwImeOpen, DWORD dwImeConversion)
  976. {
  977. PKBDNLSTABLES pKbdNlsTable = gpKbdNlsTbl;
  978. if (pKbdNlsTable == NULL) {
  979. /*
  980. * 'Active' layout driver does not have NLSKBD table.
  981. */
  982. return;
  983. }
  984. /*
  985. * Let us send notification to kernel mode keyboard driver, if nessesary.
  986. */
  987. if ((pKbdNlsTable->LayoutInformation) & NLSKBD_INFO_SEND_IME_NOTIFICATION) {
  988. PDEVICEINFO pDeviceInfo;
  989. /*
  990. * Fill up the KEYBOARD_IME_STATUS structure.
  991. */
  992. gKbdImeStatus.UnitId = 0;
  993. gKbdImeStatus.ImeOpen = dwImeOpen;
  994. gKbdImeStatus.ImeConvMode = dwImeConversion;
  995. EnterDeviceInfoListCrit();
  996. BEGINATOMICDEVICEINFOLISTCHECK();
  997. for (pDeviceInfo = gpDeviceInfoList; pDeviceInfo; pDeviceInfo = pDeviceInfo->pNext) {
  998. if ((pDeviceInfo->type == DEVICE_TYPE_KEYBOARD) && (pDeviceInfo->handle)) {
  999. RequestDeviceChange(pDeviceInfo, GDIAF_IME_STATUS, TRUE);
  1000. }
  1001. }
  1002. ENDATOMICDEVICEINFOLISTCHECK();
  1003. LeaveDeviceInfoListCrit();
  1004. }
  1005. }
  1006. VOID NlsKbdSendIMEProc(DWORD dwImeOpen, DWORD dwImeConversion)
  1007. {
  1008. if (gpqForeground != NULL && gpqForeground->ptiKeyboard != NULL &&
  1009. (!(GetAppImeCompatFlags(gpqForeground->ptiKeyboard) & IMECOMPAT_HYDRACLIENT))) {
  1010. NlsKbdSendIMENotification(dwImeOpen, dwImeConversion);
  1011. }
  1012. }
  1013. /*
  1014. * Compatibility for Windows NT 3.xx and Windows 3.x for NEC PC-9800 Series
  1015. */
  1016. #define NLSKBD_CONFIG_PATH L"WOW\\keyboard"
  1017. /***************************************************************************\
  1018. * NlsKbdInitializePerSystem()
  1019. *
  1020. * History:
  1021. * 26-09-96 hideyukn Created.
  1022. \***************************************************************************/
  1023. VOID NlsKbdInitializePerSystem(VOID)
  1024. {
  1025. RTL_QUERY_REGISTRY_TABLE QueryTable[4];
  1026. UNICODE_STRING EndString, HelpString;
  1027. UNICODE_STRING YesString, NoString;
  1028. UNICODE_STRING HomeString, ClearString;
  1029. UNICODE_STRING HelpKeyString;
  1030. UNICODE_STRING KanaHelpString;
  1031. UNICODE_STRING ClearKeyString;
  1032. NTSTATUS Status;
  1033. //
  1034. // Set default VK_DBE_xxx status.
  1035. //
  1036. //
  1037. // AlphaNumeric input mode.
  1038. //
  1039. NlsSetKeyStateToggle(VK_DBE_ALPHANUMERIC);
  1040. //
  1041. // Single byte character input mode.
  1042. //
  1043. NlsSetKeyStateToggle(VK_DBE_SBCSCHAR);
  1044. //
  1045. // No roman input mode.
  1046. //
  1047. NlsSetKeyStateToggle(VK_DBE_NOROMAN);
  1048. //
  1049. // No code input mode.
  1050. //
  1051. NlsSetKeyStateToggle(VK_DBE_NOCODEINPUT);
  1052. //
  1053. // From Here, below code is for compatibility for Windows NT 3.xx
  1054. // for NEC PC-9800 verion.
  1055. //
  1056. //
  1057. // Initialize default strings.
  1058. //
  1059. RtlInitUnicodeString(&EndString, L"end");
  1060. RtlInitUnicodeString(&HelpString,L"help");
  1061. RtlInitUnicodeString(&YesString,L"yes");
  1062. RtlInitUnicodeString(&NoString, L"no");
  1063. RtlInitUnicodeString(&HomeString, L"home");
  1064. RtlInitUnicodeString(&ClearString,L"clear");
  1065. //
  1066. // Initialize recieve buffer.
  1067. //
  1068. RtlInitUnicodeString(&HelpKeyString,NULL);
  1069. RtlInitUnicodeString(&KanaHelpString,NULL);
  1070. RtlInitUnicodeString(&ClearKeyString,NULL);
  1071. //
  1072. // Initalize query tables.
  1073. //
  1074. // ValueName : "helpkey"
  1075. // ValueData : if "end" VK_END, otherwise VK_HELP
  1076. //
  1077. QueryTable[0].QueryRoutine = NULL;
  1078. QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
  1079. QueryTable[0].Name = (PWSTR) L"helpkey",
  1080. QueryTable[0].EntryContext = (PVOID) &HelpKeyString;
  1081. QueryTable[0].DefaultType = REG_SZ;
  1082. QueryTable[0].DefaultData = &EndString;
  1083. QueryTable[0].DefaultLength = 0;
  1084. //
  1085. // ValueName : "KanaHelpKey"
  1086. // ValueData : if "yes" if kana on switch VK_HELP and VK_END
  1087. //
  1088. QueryTable[1].QueryRoutine = NULL;
  1089. QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
  1090. QueryTable[1].Name = (PWSTR) L"KanaHelpKey",
  1091. QueryTable[1].EntryContext = (PVOID) &KanaHelpString;
  1092. QueryTable[1].DefaultType = REG_SZ;
  1093. QueryTable[1].DefaultData = &YesString;
  1094. QueryTable[1].DefaultLength = 0;
  1095. //
  1096. // ValueName : "clrkey"
  1097. // ValueData : if "home" VK_HOME, otherwise VK_CLEAR
  1098. //
  1099. QueryTable[2].QueryRoutine = NULL;
  1100. QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
  1101. QueryTable[2].Name = (PWSTR) L"clrkey",
  1102. QueryTable[2].EntryContext = (PVOID) &ClearKeyString;
  1103. QueryTable[2].DefaultType = REG_SZ;
  1104. QueryTable[2].DefaultData = &HomeString;
  1105. QueryTable[2].DefaultLength = 0;
  1106. QueryTable[3].QueryRoutine = NULL;
  1107. QueryTable[3].Flags = 0;
  1108. QueryTable[3].Name = NULL;
  1109. Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
  1110. NLSKBD_CONFIG_PATH,
  1111. QueryTable,
  1112. NULL,
  1113. NULL);
  1114. if (!NT_SUCCESS(Status)) {
  1115. RIPMSG1(RIP_WARNING, "FEKBD:RtlQueryRegistryValues fails (%x)", Status);
  1116. return;
  1117. }
  1118. if (RtlEqualUnicodeString(&HelpKeyString,&HelpString,TRUE)) {
  1119. /*
  1120. * Generate VK_HELP, when NLSKBD_HELP_OR_END is called.
  1121. */
  1122. fNlsKbdConfiguration &= ~GEN_VK_END;
  1123. }
  1124. if (RtlEqualUnicodeString(&KanaHelpString,&NoString,TRUE)) {
  1125. /*
  1126. * In case of "yes":
  1127. * If 'kana' is on, when NLSKBD_HELP_OR_END is called, switch VK_END and VK_HELP.
  1128. * Else, in case of "no":
  1129. * Doesn't generate by 'kana' toggle state.
  1130. */
  1131. fNlsKbdConfiguration &= ~GEN_KANA_AWARE;
  1132. }
  1133. if (RtlEqualUnicodeString(&ClearKeyString,&ClearString,TRUE)) {
  1134. /*
  1135. * Generate VK_CLEAR, when KBDNLS_HOME_OR_CLEAR is called.
  1136. */
  1137. fNlsKbdConfiguration &= ~GEN_VK_HOME;
  1138. }
  1139. ExFreePool(HelpKeyString.Buffer);
  1140. ExFreePool(KanaHelpString.Buffer);
  1141. ExFreePool(ClearKeyString.Buffer);
  1142. }