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.

507 lines
14 KiB

  1. /****************************************************************************/
  2. /* keyboard.c */
  3. /* */
  4. /* Keyboard IOCtl handling */
  5. /* */
  6. /* Copyright 1996, Citrix Systems Inc. */
  7. /* Copyright (C) 1997-1999 Microsoft Corporation */
  8. /****************************************************************************/
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif /* __cplusplus */
  12. #include <precomp.h>
  13. #pragma hdrstop
  14. #define TRC_FILE "keyboard"
  15. #define pTRCWd pWd
  16. #include <adcg.h>
  17. #include <nwdwapi.h>
  18. #include <nwdwint.h>
  19. #include <acomapi.h>
  20. /*******************************************************************************
  21. *
  22. * KeyboardQueryAttributes
  23. *
  24. * return the keyboard attributes
  25. *
  26. * typedef struct _KEYBOARD_ID {
  27. * UCHAR Type;
  28. * UCHAR Subtype;
  29. * } KEYBOARD_ID, *PKEYBOARD_ID;
  30. *
  31. * typedef struct _KEYBOARD_ATTRIBUTES {
  32. * KEYBOARD_ID KeyboardIdentifier;
  33. * USHORT KeyboardMode;
  34. * USHORT NumberOfFunctionKeys;
  35. * USHORT NumberOfIndicators;
  36. * USHORT NumberOfKeysTotal;
  37. * ULONG InputDataQueueLength;
  38. * KEYBOARD_TYPEMATIC_PARAMETERS KeyRepeatMinimum;
  39. * KEYBOARD_TYPEMATIC_PARAMETERS KeyRepeatMaximum;
  40. * } KEYBOARD_ATTRIBUTES, *PKEYBOARD_ATTRIBUTES;
  41. *
  42. *
  43. * ENTRY:
  44. * pWd (input)
  45. * Pointer to wd data structure
  46. * pSdIoctl (input/output)
  47. * input - nothing
  48. * output - KEYBOARD_ATTRIBUTES
  49. *
  50. * EXIT:
  51. * STATUS_SUCCESS - no error
  52. *
  53. ******************************************************************************/
  54. NTSTATUS
  55. KeyboardQueryAttributes( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  56. {
  57. PKEYBOARD_ATTRIBUTES pAttrib;
  58. if ( pSdIoctl->OutputBufferLength < sizeof(KEYBOARD_ATTRIBUTES) )
  59. return( STATUS_BUFFER_TOO_SMALL );
  60. pAttrib = (PKEYBOARD_ATTRIBUTES)pSdIoctl->OutputBuffer;
  61. pAttrib->KeyboardIdentifier.Type = 4;
  62. pAttrib->KeyboardIdentifier.Subtype = 0;
  63. pAttrib->KeyboardMode = 1;
  64. pAttrib->NumberOfFunctionKeys = 12;
  65. pAttrib->NumberOfIndicators = 3;
  66. pAttrib->NumberOfKeysTotal = 101;
  67. pAttrib->InputDataQueueLength = 100;
  68. pAttrib->KeyRepeatMinimum.UnitId = 0;
  69. pAttrib->KeyRepeatMinimum.Rate = 2;
  70. pAttrib->KeyRepeatMinimum.Delay = 250;
  71. pAttrib->KeyRepeatMaximum.UnitId = 0;
  72. pAttrib->KeyRepeatMaximum.Rate = 30;
  73. pAttrib->KeyRepeatMaximum.Delay = 1000;
  74. pSdIoctl->BytesReturned = sizeof(KEYBOARD_ATTRIBUTES);
  75. return( STATUS_SUCCESS );
  76. }
  77. /*******************************************************************************
  78. *
  79. * KeyboardQueryTypematic
  80. *
  81. * return the keyboard typematic rate
  82. *
  83. * typedef struct _KEYBOARD_TYPEMATIC_PARAMETERS {
  84. * USHORT UnitId;
  85. * USHORT Rate;
  86. * USHORT Delay;
  87. * } KEYBOARD_TYPEMATIC_PARAMETERS, *PKEYBOARD_TYPEMATIC_PARAMETERS;
  88. *
  89. *
  90. * ENTRY:
  91. * pWd (input)
  92. * Pointer to wd data structure
  93. * pSdIoctl (input/output)
  94. * input - nothing
  95. * output - KEYBOARD_TYPEMATIC_PARAMETERS
  96. *
  97. * EXIT:
  98. * STATUS_SUCCESS - no error
  99. *
  100. ******************************************************************************/
  101. NTSTATUS
  102. KeyboardQueryTypematic( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  103. {
  104. PKEYBOARD_TYPEMATIC_PARAMETERS pTypematic;
  105. if ( pSdIoctl->OutputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS) )
  106. return( STATUS_BUFFER_TOO_SMALL );
  107. pTypematic = (PKEYBOARD_TYPEMATIC_PARAMETERS)pSdIoctl->OutputBuffer;
  108. *pTypematic = pWd->KeyboardTypematic;
  109. pSdIoctl->BytesReturned = sizeof(KEYBOARD_TYPEMATIC_PARAMETERS);
  110. return( STATUS_SUCCESS );
  111. }
  112. /*******************************************************************************
  113. *
  114. * KeyboardSetTypematic
  115. *
  116. * set the keyboard typematic rate
  117. *
  118. * typedef struct _KEYBOARD_TYPEMATIC_PARAMETERS {
  119. * USHORT UnitId;
  120. * USHORT Rate;
  121. * USHORT Delay;
  122. * } KEYBOARD_TYPEMATIC_PARAMETERS, *PKEYBOARD_TYPEMATIC_PARAMETERS;
  123. *
  124. *
  125. * ENTRY:
  126. * pWd (input)
  127. * Pointer to wd data structure
  128. * pSdIoctl (input/output)
  129. * input - KEYBOARD_TYPEMATIC_PARAMETERS
  130. * output - nothing
  131. *
  132. * EXIT:
  133. * STATUS_SUCCESS - no error
  134. *
  135. ******************************************************************************/
  136. NTSTATUS
  137. KeyboardSetTypematic( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  138. {
  139. PKEYBOARD_TYPEMATIC_PARAMETERS pTypematic;
  140. if ( pSdIoctl->InputBufferLength < sizeof(KEYBOARD_TYPEMATIC_PARAMETERS) )
  141. return( STATUS_BUFFER_TOO_SMALL );
  142. pTypematic = (PKEYBOARD_TYPEMATIC_PARAMETERS)pSdIoctl->InputBuffer;
  143. pWd->KeyboardTypematic = *pTypematic;
  144. return( STATUS_SUCCESS );
  145. }
  146. /*******************************************************************************
  147. *
  148. * KeyboardQueryIndicators
  149. *
  150. * return the state of the keyboard indicators
  151. *
  152. * typedef struct _KEYBOARD_INDICATOR_PARAMETERS {
  153. * USHORT UnitId;
  154. * USHORT LedFlags;
  155. * } KEYBOARD_INDICATOR_PARAMETERS, *PKEYBOARD_INDICATOR_PARAMETERS;
  156. *
  157. *
  158. * ENTRY:
  159. * pWd (input)
  160. * Pointer to wd data structure
  161. * pSdIoctl (input/output)
  162. * input - nothing
  163. * output - KEYBOARD_INDICATOR_PARAMETERS
  164. *
  165. * EXIT:
  166. * STATUS_SUCCESS - no error
  167. *
  168. ******************************************************************************/
  169. NTSTATUS
  170. KeyboardQueryIndicators( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  171. {
  172. PKEYBOARD_INDICATOR_PARAMETERS pIndicator;
  173. if ( pSdIoctl->OutputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS) )
  174. return( STATUS_BUFFER_TOO_SMALL );
  175. pIndicator = (PKEYBOARD_INDICATOR_PARAMETERS)pSdIoctl->OutputBuffer;
  176. *pIndicator = pWd->KeyboardIndicators;
  177. pSdIoctl->BytesReturned = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
  178. return( STATUS_SUCCESS );
  179. }
  180. /*******************************************************************************
  181. *
  182. * KeyboardSetIndicators
  183. *
  184. * set the keyboard indicators
  185. *
  186. * typedef struct _KEYBOARD_INDICATOR_PARAMETERS {
  187. * USHORT UnitId;
  188. * USHORT LedFlags;
  189. * } KEYBOARD_INDICATOR_PARAMETERS, *PKEYBOARD_INDICATOR_PARAMETERS;
  190. *
  191. *
  192. * ENTRY:
  193. * pWd (input)
  194. * Pointer to wd data structure
  195. * pSdIoctl (input/output)
  196. * input - KEYBOARD_INDICATOR_PARAMETERS
  197. * output - nothing
  198. *
  199. * EXIT:
  200. * STATUS_SUCCESS - no error
  201. *
  202. ******************************************************************************/
  203. NTSTATUS
  204. KeyboardSetIndicators( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  205. {
  206. PKEYBOARD_INDICATOR_PARAMETERS pIndicator;
  207. NTSTATUS Status = STATUS_SUCCESS;
  208. if (pSdIoctl->InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
  209. {
  210. Status = STATUS_BUFFER_TOO_SMALL;
  211. }
  212. else
  213. {
  214. pIndicator = (PKEYBOARD_INDICATOR_PARAMETERS)pSdIoctl->InputBuffer;
  215. if (pWd->KeyboardIndicators.LedFlags != (pIndicator->LedFlags & 0x7))
  216. {
  217. pWd->KeyboardIndicators.UnitId = pIndicator->UnitId;
  218. pWd->KeyboardIndicators.LedFlags = (pIndicator->LedFlags & 0x7);
  219. if ((pWd->StackClass == Stack_Shadow) ||
  220. (pIndicator->LedFlags & KEYBOARD_LED_INJECTED)) {
  221. WDWKeyboardSetIndicators(pWd);
  222. }
  223. }
  224. }
  225. return( Status );
  226. }
  227. /*******************************************************************************
  228. *
  229. * KeyboardQueryIndicatorTranslation
  230. *
  231. * return the state of the keyboard indicators
  232. *
  233. * typedef struct _INDICATOR_LIST {
  234. * USHORT MakeCode;
  235. * USHORT IndicatorFlags;
  236. * } INDICATOR_LIST, *PINDICATOR_LIST;
  237. *
  238. * typedef struct _KEYBOARD_INDICATOR_TRANSLATION {
  239. * USHORT NumberOfIndicatorKeys;
  240. * INDICATOR_LIST IndicatorList[1];
  241. * } KEYBOARD_INDICATOR_TRANSLATION, *PKEYBOARD_INDICATOR_TRANSLATION;
  242. *
  243. *
  244. * ENTRY:
  245. * pWd (input)
  246. * Pointer to wd data structure
  247. * pSdIoctl (input/output)
  248. * input - nothing
  249. * output - ICA_STACK_CONFIG
  250. *
  251. * EXIT:
  252. * STATUS_SUCCESS - no error
  253. *
  254. ******************************************************************************/
  255. NTSTATUS
  256. KeyboardQueryIndicatorTranslation( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  257. {
  258. pSdIoctl->BytesReturned = 0;
  259. return( STATUS_INVALID_DEVICE_REQUEST );
  260. }
  261. /*******************************************************************************
  262. *
  263. * KeyboardSetLayout
  264. *
  265. * set the keyboard layouts for shadow hotkey processing
  266. *
  267. * ENTRY:
  268. * pWd (input)
  269. * pointer to wd data structure
  270. * pSdIoctl (input/output)
  271. * input - keyboard layout table
  272. * output - nothing
  273. *
  274. * EXIT:
  275. * STATUS_SUCCESS - no error
  276. *
  277. ******************************************************************************/
  278. NTSTATUS
  279. KeyboardSetLayout( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  280. {
  281. NTSTATUS Status;
  282. PVOID pKbdLayout;
  283. PVOID pKbdTbl;
  284. if ( pSdIoctl->InputBufferLength < 1 ) {
  285. Status = STATUS_BUFFER_TOO_SMALL;
  286. goto error;
  287. }
  288. /*
  289. * The keyboard layout is in winstation space so copy it to a new buffer and
  290. * adjust the pointers. The pointers where all relative to a base address before
  291. * so just duplicate the fixup code from Win32K.
  292. */
  293. pKbdLayout = COM_Malloc(pSdIoctl->InputBufferLength);
  294. if (pKbdLayout == NULL) {
  295. Status = STATUS_NO_MEMORY;
  296. goto error;
  297. }
  298. RtlCopyMemory( pKbdLayout, pSdIoctl->InputBuffer, pSdIoctl->InputBufferLength );
  299. Status = KeyboardFixupLayout( pKbdLayout, pSdIoctl->InputBuffer,
  300. pSdIoctl->InputBufferLength,
  301. pSdIoctl->OutputBuffer,
  302. &pKbdTbl );
  303. if ( !NT_SUCCESS( Status ) ) {
  304. COM_Free( pKbdLayout );
  305. pKbdLayout = NULL;
  306. goto error;
  307. }
  308. if ( pWd->pKbdLayout )
  309. COM_Free( pWd->pKbdLayout );
  310. pWd->pKbdLayout = pKbdLayout;
  311. pWd->pKbdTbl = pKbdTbl;
  312. error:
  313. TRACE(( pWd->pContext, TC_WD, TT_ERROR, "KeyboardSetLayout %X\n", Status ));
  314. return( Status );
  315. }
  316. /*******************************************************************************
  317. *
  318. * KeyboardSetScanMap
  319. *
  320. * set the keyboard scan map for shadow hotkey processing
  321. *
  322. * ENTRY:
  323. * pWd (input)
  324. * pointer to wd data structure
  325. * pSdIoctl (input/output)
  326. * input - keyboard scan map table
  327. * output - nothing
  328. *
  329. * EXIT:
  330. * STATUS_SUCCESS - no error
  331. *
  332. ******************************************************************************/
  333. NTSTATUS
  334. KeyboardSetScanMap( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  335. {
  336. NTSTATUS Status;
  337. PVOID pScanMap;
  338. DC_BEGIN_FN("KeyboardSetScanMap");
  339. if (pSdIoctl->InputBufferLength >= 1) {
  340. // The keyboard scan code map is in winstation space so copy it to
  341. // a new buffer.
  342. pScanMap = COM_Malloc( pSdIoctl->InputBufferLength );
  343. if (pScanMap != NULL ) {
  344. RtlCopyMemory(pScanMap, pSdIoctl->InputBuffer,
  345. pSdIoctl->InputBufferLength);
  346. // Scancode maps are allocated once.
  347. TRC_ASSERT((pWd->gpScancodeMap == NULL),
  348. (TB,"Previous scancode map present"));
  349. pWd->gpScancodeMap = pScanMap;
  350. Status = STATUS_SUCCESS;
  351. }
  352. else {
  353. Status = STATUS_NO_MEMORY;
  354. }
  355. }
  356. else {
  357. Status = STATUS_BUFFER_TOO_SMALL;
  358. }
  359. TRACE(( pWd->pContext, TC_WD, TT_ERROR, "KeyboardSetScanMap %X\n", Status ));
  360. DC_END_FN();
  361. return Status;
  362. }
  363. /*******************************************************************************
  364. *
  365. * KeyboardSetType
  366. *
  367. * set the keyboard scan map for shadow hotkey processing
  368. *
  369. * ENTRY:
  370. * pWd (input)
  371. * pointer to wd data structure
  372. * pSdIoctl (input/output)
  373. * input - keyboard type
  374. * output - nothing
  375. *
  376. * EXIT:
  377. * STATUS_SUCCESS - no error
  378. *
  379. ******************************************************************************/
  380. NTSTATUS
  381. KeyboardSetType( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  382. {
  383. NTSTATUS Status = STATUS_SUCCESS;
  384. if ( pSdIoctl->InputBufferLength < sizeof(BOOLEAN) ) {
  385. Status = STATUS_BUFFER_TOO_SMALL;
  386. goto error;
  387. }
  388. pWd->KeyboardType101 = *(PBOOLEAN)(pSdIoctl->InputBuffer);
  389. error:
  390. TRACE(( pWd->pContext, TC_WD, TT_ERROR, "KeyboardSetType %X\n", Status ));
  391. return( Status );
  392. }
  393. /*******************************************************************************
  394. *
  395. * KeyboardSetImeStatus
  396. *
  397. * set ime status to the keyboard
  398. *
  399. * typedef struct _KEYBOARD_IME_STATUS {
  400. * USHORT UnitId;
  401. * ULONG ImeOpen;
  402. * ULONG ImeConvMode;
  403. * } KEYBOARD_IME_STATUS, *PKEYBOARD_IME_STATUS;
  404. *
  405. *
  406. * ENTRY:
  407. * pWd (input)
  408. * Pointer to wd data structure
  409. * pSdIoctl (input/output)
  410. * input - KEYBOARD_IME_STATUS
  411. * output - nothing
  412. *
  413. * EXIT:
  414. * STATUS_SUCCESS - no error
  415. *
  416. ******************************************************************************/
  417. NTSTATUS
  418. KeyboardSetImeStatus( PTSHARE_WD pWd, PSD_IOCTL pSdIoctl )
  419. {
  420. PKEYBOARD_IME_STATUS pImeStatus;
  421. NTSTATUS Status = STATUS_SUCCESS;
  422. if (pSdIoctl->InputBufferLength < sizeof(KEYBOARD_IME_STATUS))
  423. {
  424. Status = STATUS_BUFFER_TOO_SMALL;
  425. }
  426. else
  427. {
  428. pImeStatus = (PKEYBOARD_IME_STATUS)pSdIoctl->InputBuffer;
  429. pWd->KeyboardImeStatus = *pImeStatus;
  430. WDWKeyboardSetImeStatus(pWd);
  431. }
  432. return( Status );
  433. }
  434. #ifdef __cplusplus
  435. }
  436. #endif /* __cplusplus */