Source code of Windows XP (NT5)
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.

525 lines
13 KiB

  1. /*************************************************************************
  2. * T1.C
  3. *
  4. * Test program for ICA DLL Interface to ICA Device Driver
  5. *
  6. * copyright notice: Copyright 1996, Citrix Systems Inc.
  7. * Copyright (C) 1997-1999 Microsoft Corp.
  8. *************************************************************************/
  9. #include "precomp.h"
  10. #pragma hdrstop
  11. #include <stdio.h>
  12. #define MAX_READ 2
  13. /*
  14. * Data types and definitions
  15. */
  16. #define KEYBOARD_THREAD_STACKSIZE 1024 * 4
  17. typedef struct _THREADDATA {
  18. HANDLE handle;
  19. } THREADDATA, * PTHREADDATA;
  20. /*
  21. * Global variables
  22. */
  23. static HANDLE ghIca = NULL;
  24. static HANDLE ghStack = NULL;
  25. static HANDLE ghKeyboard = NULL;
  26. static HANDLE ghMouse = NULL;
  27. static HANDLE ghVideo = NULL;
  28. static HANDLE ghBeep = NULL;
  29. static HANDLE ghCommand = NULL;
  30. static HANDLE ghCdm = NULL;
  31. static HANDLE ghThreadKeyboardRead = NULL;
  32. static HANDLE ghStopEvent = NULL;
  33. /*
  34. * Private procedures
  35. */
  36. LONG OpenStacks( void );
  37. LONG ConnectStacks( void );
  38. LONG CloseStacks( void );
  39. LONG Initialize( void );
  40. VOID KeyboardReadThread( PTHREADDATA pThreadData );
  41. LONG KeyboardTest( void );
  42. /****************************************************************************
  43. *
  44. * main
  45. *
  46. * Main process entry point
  47. *
  48. * ENTRY:
  49. * argc (input)
  50. * Number of parameters
  51. *
  52. * argv (input)
  53. * Array of argument strings
  54. *
  55. * EXIT:
  56. * STATUS_SUCCESS - Success
  57. * other - Error return code
  58. *
  59. ****************************************************************************/
  60. int _cdecl
  61. main (int argc, char *argv[])
  62. {
  63. BOOL fSuccess = TRUE;
  64. LONG rc;
  65. /*
  66. * Open the ICA driver, an ICA stack, and some channels
  67. */
  68. if ( rc = OpenStacks() ) {
  69. goto done;
  70. }
  71. /*
  72. * Do some initialization
  73. */
  74. if ( rc = Initialize() ) {
  75. goto done;
  76. }
  77. printf( "Sleeping...\n" );
  78. Sleep(3000); // Give thread some time
  79. if ( rc = KeyboardTest() ) {
  80. goto done;
  81. }
  82. /*
  83. * Wait for stop event to be triggered.
  84. */
  85. printf( "ICAKEY main: Waiting for stop event...\n" );
  86. WaitForSingleObject( ghStopEvent, (DWORD)30000 );
  87. printf( "ICAKEY main: ...Stop event triggered\n" );
  88. done:
  89. fSuccess = !rc;
  90. if ( rc = CloseStacks() ) {
  91. fSuccess = FALSE;
  92. }
  93. printf( "ICAKEY main: Test %s!\n", fSuccess ? "successful" : "failed" );
  94. return( 0 );
  95. }
  96. /****************************************************************************
  97. *
  98. * OpenStacks
  99. *
  100. * Open ICA device driver, ICA stack, and ICA channels
  101. *
  102. * ENTRY:
  103. * void
  104. *
  105. * EXIT:
  106. * STATUS_SUCCESS - Success
  107. * other - Error return code
  108. *
  109. ****************************************************************************/
  110. LONG
  111. OpenStacks( void )
  112. {
  113. NTSTATUS rc;
  114. /*
  115. * Open an instance of the ICA device driver
  116. */
  117. if ( rc = IcaOpen( &ghIca ) ) {
  118. printf( "ICAKEY OpenStacks: Error 0x%x from IcaOpen\n",
  119. rc );
  120. goto done;
  121. }
  122. printf( "ICAKEY OpenStacks: Handle to ICA device driver: %08lX\n", ghIca );
  123. /*
  124. * Open an ICA stack instance
  125. */
  126. if ( rc = IcaStackOpen( ghIca, Stack_Primary, &ghStack ) ) {
  127. printf( "ICAKEY OpenStacks: Error 0x%x from IcaStackOpen\n", rc );
  128. goto done;
  129. }
  130. printf( "ICAKEY OpenStacks: Handle to ICA stack: %08lX\n", ghStack );
  131. /*
  132. * Open the keyboard channel
  133. */
  134. if ( rc = IcaChannelOpen( ghIca, Channel_Keyboard, NULL, &ghKeyboard ) ) {
  135. printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( keyboard )\n", rc );
  136. goto done;
  137. }
  138. printf( "ICAKEY OpenStacks: Handle to keyboard channel: %08lX\n", ghKeyboard );
  139. /*
  140. * Open the mouse channel
  141. */
  142. if ( rc = IcaChannelOpen( ghIca, Channel_Mouse, NULL, &ghMouse ) ) {
  143. printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( mouse )", rc );
  144. goto done;
  145. }
  146. printf( "ICAKEY OpenStacks: Handle to mouse channel: %08lX\n", ghMouse );
  147. /*
  148. * Open the video channel
  149. */
  150. if ( rc = IcaChannelOpen( ghIca, Channel_Video, NULL, &ghVideo ) ) {
  151. printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( video )", rc );
  152. goto done;
  153. }
  154. printf( "ICAKEY OpenStacks: Handle to video channel: %08lX\n", ghVideo );
  155. /*
  156. * Open the beep channel
  157. */
  158. if ( rc = IcaChannelOpen( ghIca, Channel_Beep, NULL, &ghBeep ) ) {
  159. printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( beep )", rc );
  160. goto done;
  161. }
  162. printf( "ICAKEY OpenStacks: Handle to beep channel: %08lX\n", ghBeep );
  163. /*
  164. * Open the command channel
  165. */
  166. if ( rc = IcaChannelOpen( ghIca, Channel_Command, NULL, &ghCommand ) ) {
  167. printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( command )", rc );
  168. goto done;
  169. }
  170. printf( "ICAKEY OpenStacks: Handle to command channel: %08lX\n", ghCommand );
  171. /*
  172. * Open the cdm channel
  173. */
  174. if ( rc = IcaChannelOpen( ghIca, Channel_Virtual, VIRTUAL_CDM, &ghCdm ) ) {
  175. printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( VIRTUAL_CDM )", rc );
  176. goto done;
  177. }
  178. printf( "ICAKEY OpenStacks: Handle to cdm channel: %08lX\n", ghCdm );
  179. done:
  180. return( rc );
  181. }
  182. /****************************************************************************
  183. *
  184. * CloseStacks
  185. *
  186. * Close the ICA device driver, ICA stack, and ICA channels
  187. *
  188. * ENTRY:
  189. * void
  190. *
  191. * EXIT:
  192. * STATUS_SUCCESS - Success
  193. * other - Error return code
  194. *
  195. ****************************************************************************/
  196. LONG
  197. CloseStacks( void )
  198. {
  199. LONG rc = STATUS_SUCCESS;
  200. /*
  201. * Close the stop event handle
  202. */
  203. if ( ghStopEvent ) {
  204. CloseHandle( ghStopEvent );
  205. }
  206. /*
  207. * Kill the keyboard read thread
  208. */
  209. if ( ghThreadKeyboardRead ) {
  210. TerminateThread( ghThreadKeyboardRead, 0 );
  211. CloseHandle( ghThreadKeyboardRead );
  212. }
  213. /*
  214. * Close the keyboard channel
  215. */
  216. if ( ghKeyboard ) {
  217. if ( rc = IcaChannelClose( ghKeyboard ) ) {
  218. printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Keyboard )\n", rc );
  219. }
  220. }
  221. /*
  222. * Close the mouse channel
  223. */
  224. if ( ghMouse ) {
  225. if ( rc = IcaChannelClose( ghMouse ) ) {
  226. printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Mouse )\n", rc );
  227. }
  228. }
  229. /*
  230. * Close the video channel
  231. */
  232. if ( ghVideo ) {
  233. if ( rc = IcaChannelClose( ghVideo ) ) {
  234. printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Video )\n", rc );
  235. }
  236. }
  237. /*
  238. * Close the beep channel
  239. */
  240. if ( ghBeep ) {
  241. if ( rc = IcaChannelClose( ghBeep ) ) {
  242. printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Beep )\n", rc );
  243. }
  244. }
  245. /*
  246. * Close the command channel
  247. */
  248. if ( ghCommand ) {
  249. if ( rc = IcaChannelClose( ghCommand ) ) {
  250. printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Command )\n", rc );
  251. }
  252. }
  253. /*
  254. * Close the cdm channel
  255. */
  256. if ( ghCdm ) {
  257. if ( rc = IcaChannelClose( ghCdm ) ) {
  258. printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Cdm )\n", rc );
  259. }
  260. }
  261. /*
  262. * Close the ICA stack instance
  263. */
  264. if ( ghStack ) {
  265. if ( rc = IcaStackClose( ghStack ) ) {
  266. printf( "ICAKEY CloseStacks: Error 0x%x from IcaStackClose\n", rc );
  267. }
  268. }
  269. /*
  270. * Close the ICA device driver instance
  271. */
  272. if ( ghIca ) {
  273. if ( rc = IcaClose( ghIca ) ) {
  274. printf( "ICAKEY CloseStacks: Error 0x%x from IcaClose\n", rc );
  275. }
  276. }
  277. return( rc );
  278. }
  279. /****************************************************************************
  280. *
  281. * Initialize
  282. *
  283. * Do some initialization
  284. *
  285. * ENTRY:
  286. * void
  287. *
  288. * EXIT:
  289. * STATUS_SUCCESS - Success
  290. * other - Error return code
  291. *
  292. ****************************************************************************/
  293. LONG
  294. Initialize( void )
  295. {
  296. LONG rc = STATUS_SUCCESS;
  297. DWORD tidKeyboardReadThread;
  298. THREADDATA ThreadData;
  299. /*
  300. * Create stop event to wait on later.
  301. */
  302. if ( !(ghStopEvent = CreateEvent( NULL, TRUE, FALSE, NULL )) ) {
  303. printf( "ICAKEY Initialize: Error 0x%x in CreateEvent\n", GetLastError() );
  304. goto done;
  305. }
  306. ThreadData.handle = ghKeyboard;
  307. /*
  308. * Startup the virtual channel read thread
  309. */
  310. if ( !(ghThreadKeyboardRead = CreateThread( NULL,
  311. KEYBOARD_THREAD_STACKSIZE,
  312. (LPTHREAD_START_ROUTINE)KeyboardReadThread,
  313. (LPVOID)&ThreadData, 0,
  314. (LPDWORD)&tidKeyboardReadThread )) ) {
  315. rc = GetLastError();
  316. printf( "ICAKEY Initialize: Error 0x%x creating keyboard read thread\n", rc );
  317. goto done;
  318. }
  319. done:
  320. return( rc );
  321. }
  322. /*******************************************************************************
  323. *
  324. * Function: KeyboardReadThread
  325. *
  326. * Purpose: Keyboard read thread
  327. *
  328. * Entry:
  329. * pThreadData
  330. * Pointer to thread creation data
  331. *
  332. * Exit:
  333. * void
  334. *
  335. ******************************************************************************/
  336. VOID KeyboardReadThread( PTHREADDATA pThreadData )
  337. {
  338. int rc;
  339. HANDLE handle = pThreadData->handle;
  340. KEYBOARD_INPUT_DATA KeyboardInputData;
  341. DWORD cbRead;
  342. OVERLAPPED Overlapped;
  343. DWORD dwError;
  344. int NumberRead = 0;
  345. Overlapped.Offset = 0;
  346. Overlapped.OffsetHigh = 0;
  347. Overlapped.hEvent = NULL;
  348. printf( "Keyboard read thread starting...\n" );
  349. /*
  350. * Now dedicate this thread to monitor the keyboard
  351. */
  352. do {
  353. cbRead = 0;
  354. if ( !ReadFile( ghKeyboard,
  355. &KeyboardInputData,
  356. sizeof( KeyboardInputData ),
  357. &cbRead, &Overlapped ) ) {
  358. dwError = GetLastError();
  359. if ( dwError == ERROR_IO_PENDING ) {
  360. // check on the results of the asynchronous read
  361. if ( !GetOverlappedResult( ghKeyboard, &Overlapped,
  362. &cbRead, TRUE) ) { // wait for result
  363. printf( "ICAKEY KeyboardReadThread: Error 0x%x from GetOverlappedResult( Channel_Keyboard )\n",
  364. GetLastError() );
  365. break;
  366. }
  367. }
  368. else {
  369. printf( "ICAKEY KeyboardReadThread: Error 0x%x from ReadFile( Channel_Keyboard )\n",
  370. dwError );
  371. break;
  372. }
  373. }
  374. printf( "Unit number: 0x%x\nScan code: %02X\nFlags: %04X\nExtra info: %08X\n",
  375. KeyboardInputData.UnitId,
  376. KeyboardInputData.MakeCode,
  377. KeyboardInputData.Flags,
  378. KeyboardInputData.ExtraInformation );
  379. NumberRead++;
  380. if ( NumberRead == MAX_READ )
  381. break;
  382. } while ( 1 );
  383. printf( "Keyboard read thread exiting...\n" );
  384. SetEvent( ghStopEvent );
  385. ExitThread( 0 );
  386. }
  387. /****************************************************************************
  388. *
  389. * KeyboardTest
  390. *
  391. * Stuff some data into the keyboard channel for testing purposes
  392. *
  393. * ENTRY:
  394. * void
  395. *
  396. * EXIT:
  397. * STATUS_SUCCESS - Success
  398. * other - Error return code
  399. *
  400. ****************************************************************************/
  401. LONG
  402. KeyboardTest( void )
  403. {
  404. LONG rc = STATUS_SUCCESS;
  405. KEYBOARD_INPUT_DATA KeyboardInputData;
  406. ULONG cbReturned;
  407. /*
  408. * Initialize the keystroke to fabricate
  409. */
  410. KeyboardInputData.UnitId = 0;
  411. KeyboardInputData.MakeCode = 0x32; // Capital 'M'
  412. KeyboardInputData.Flags = KEY_MAKE;
  413. KeyboardInputData.Reserved = 0;
  414. KeyboardInputData.ExtraInformation = 0;
  415. /*
  416. * First stuff the make
  417. */
  418. if ( rc = IcaChannelIoControl( ghKeyboard,
  419. IOCTL_KEYBOARD_ICA_INPUT,
  420. &KeyboardInputData,
  421. sizeof( KeyboardInputData ),
  422. NULL,
  423. 0,
  424. &cbReturned ) ) {
  425. printf( "ICAKEY KeyboardTest: Error 0x%x in IcaChannelIoControl\n", rc );
  426. goto done;
  427. }
  428. KeyboardInputData.Flags = KEY_BREAK;
  429. /*
  430. * Now stuff the break
  431. */
  432. if ( rc = IcaChannelIoControl( ghKeyboard,
  433. IOCTL_KEYBOARD_ICA_INPUT,
  434. &KeyboardInputData,
  435. sizeof( KeyboardInputData ),
  436. NULL,
  437. 0,
  438. &cbReturned ) ) {
  439. printf( "ICAKEY KeyboardTest: Error 0x%x in IcaChannelIoControl\n", rc );
  440. goto done;
  441. }
  442. done:
  443. return( rc );
  444. }