windows-nt/Source/XPSP1/NT/termsrv/icaapi/icakey.c
2020-09-26 16:20:57 +08:00

526 lines
13 KiB
C

/*************************************************************************
* T1.C
*
* Test program for ICA DLL Interface to ICA Device Driver
*
* copyright notice: Copyright 1996, Citrix Systems Inc.
* Copyright (C) 1997-1999 Microsoft Corp.
*************************************************************************/
#include "precomp.h"
#pragma hdrstop
#include <stdio.h>
#define MAX_READ 2
/*
* Data types and definitions
*/
#define KEYBOARD_THREAD_STACKSIZE 1024 * 4
typedef struct _THREADDATA {
HANDLE handle;
} THREADDATA, * PTHREADDATA;
/*
* Global variables
*/
static HANDLE ghIca = NULL;
static HANDLE ghStack = NULL;
static HANDLE ghKeyboard = NULL;
static HANDLE ghMouse = NULL;
static HANDLE ghVideo = NULL;
static HANDLE ghBeep = NULL;
static HANDLE ghCommand = NULL;
static HANDLE ghCdm = NULL;
static HANDLE ghThreadKeyboardRead = NULL;
static HANDLE ghStopEvent = NULL;
/*
* Private procedures
*/
LONG OpenStacks( void );
LONG ConnectStacks( void );
LONG CloseStacks( void );
LONG Initialize( void );
VOID KeyboardReadThread( PTHREADDATA pThreadData );
LONG KeyboardTest( void );
/****************************************************************************
*
* main
*
* Main process entry point
*
* ENTRY:
* argc (input)
* Number of parameters
*
* argv (input)
* Array of argument strings
*
* EXIT:
* STATUS_SUCCESS - Success
* other - Error return code
*
****************************************************************************/
int _cdecl
main (int argc, char *argv[])
{
BOOL fSuccess = TRUE;
LONG rc;
/*
* Open the ICA driver, an ICA stack, and some channels
*/
if ( rc = OpenStacks() ) {
goto done;
}
/*
* Do some initialization
*/
if ( rc = Initialize() ) {
goto done;
}
printf( "Sleeping...\n" );
Sleep(3000); // Give thread some time
if ( rc = KeyboardTest() ) {
goto done;
}
/*
* Wait for stop event to be triggered.
*/
printf( "ICAKEY main: Waiting for stop event...\n" );
WaitForSingleObject( ghStopEvent, (DWORD)30000 );
printf( "ICAKEY main: ...Stop event triggered\n" );
done:
fSuccess = !rc;
if ( rc = CloseStacks() ) {
fSuccess = FALSE;
}
printf( "ICAKEY main: Test %s!\n", fSuccess ? "successful" : "failed" );
return( 0 );
}
/****************************************************************************
*
* OpenStacks
*
* Open ICA device driver, ICA stack, and ICA channels
*
* ENTRY:
* void
*
* EXIT:
* STATUS_SUCCESS - Success
* other - Error return code
*
****************************************************************************/
LONG
OpenStacks( void )
{
NTSTATUS rc;
/*
* Open an instance of the ICA device driver
*/
if ( rc = IcaOpen( &ghIca ) ) {
printf( "ICAKEY OpenStacks: Error 0x%x from IcaOpen\n",
rc );
goto done;
}
printf( "ICAKEY OpenStacks: Handle to ICA device driver: %08lX\n", ghIca );
/*
* Open an ICA stack instance
*/
if ( rc = IcaStackOpen( ghIca, Stack_Primary, &ghStack ) ) {
printf( "ICAKEY OpenStacks: Error 0x%x from IcaStackOpen\n", rc );
goto done;
}
printf( "ICAKEY OpenStacks: Handle to ICA stack: %08lX\n", ghStack );
/*
* Open the keyboard channel
*/
if ( rc = IcaChannelOpen( ghIca, Channel_Keyboard, NULL, &ghKeyboard ) ) {
printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( keyboard )\n", rc );
goto done;
}
printf( "ICAKEY OpenStacks: Handle to keyboard channel: %08lX\n", ghKeyboard );
/*
* Open the mouse channel
*/
if ( rc = IcaChannelOpen( ghIca, Channel_Mouse, NULL, &ghMouse ) ) {
printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( mouse )", rc );
goto done;
}
printf( "ICAKEY OpenStacks: Handle to mouse channel: %08lX\n", ghMouse );
/*
* Open the video channel
*/
if ( rc = IcaChannelOpen( ghIca, Channel_Video, NULL, &ghVideo ) ) {
printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( video )", rc );
goto done;
}
printf( "ICAKEY OpenStacks: Handle to video channel: %08lX\n", ghVideo );
/*
* Open the beep channel
*/
if ( rc = IcaChannelOpen( ghIca, Channel_Beep, NULL, &ghBeep ) ) {
printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( beep )", rc );
goto done;
}
printf( "ICAKEY OpenStacks: Handle to beep channel: %08lX\n", ghBeep );
/*
* Open the command channel
*/
if ( rc = IcaChannelOpen( ghIca, Channel_Command, NULL, &ghCommand ) ) {
printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( command )", rc );
goto done;
}
printf( "ICAKEY OpenStacks: Handle to command channel: %08lX\n", ghCommand );
/*
* Open the cdm channel
*/
if ( rc = IcaChannelOpen( ghIca, Channel_Virtual, VIRTUAL_CDM, &ghCdm ) ) {
printf( "ICAKEY OpenStacks: Error 0x%x from IcaChannelOpen( VIRTUAL_CDM )", rc );
goto done;
}
printf( "ICAKEY OpenStacks: Handle to cdm channel: %08lX\n", ghCdm );
done:
return( rc );
}
/****************************************************************************
*
* CloseStacks
*
* Close the ICA device driver, ICA stack, and ICA channels
*
* ENTRY:
* void
*
* EXIT:
* STATUS_SUCCESS - Success
* other - Error return code
*
****************************************************************************/
LONG
CloseStacks( void )
{
LONG rc = STATUS_SUCCESS;
/*
* Close the stop event handle
*/
if ( ghStopEvent ) {
CloseHandle( ghStopEvent );
}
/*
* Kill the keyboard read thread
*/
if ( ghThreadKeyboardRead ) {
TerminateThread( ghThreadKeyboardRead, 0 );
CloseHandle( ghThreadKeyboardRead );
}
/*
* Close the keyboard channel
*/
if ( ghKeyboard ) {
if ( rc = IcaChannelClose( ghKeyboard ) ) {
printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Keyboard )\n", rc );
}
}
/*
* Close the mouse channel
*/
if ( ghMouse ) {
if ( rc = IcaChannelClose( ghMouse ) ) {
printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Mouse )\n", rc );
}
}
/*
* Close the video channel
*/
if ( ghVideo ) {
if ( rc = IcaChannelClose( ghVideo ) ) {
printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Video )\n", rc );
}
}
/*
* Close the beep channel
*/
if ( ghBeep ) {
if ( rc = IcaChannelClose( ghBeep ) ) {
printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Beep )\n", rc );
}
}
/*
* Close the command channel
*/
if ( ghCommand ) {
if ( rc = IcaChannelClose( ghCommand ) ) {
printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Command )\n", rc );
}
}
/*
* Close the cdm channel
*/
if ( ghCdm ) {
if ( rc = IcaChannelClose( ghCdm ) ) {
printf( "ICAKEY CloseStacks: Error 0x%x from IcaChannelClose( Cdm )\n", rc );
}
}
/*
* Close the ICA stack instance
*/
if ( ghStack ) {
if ( rc = IcaStackClose( ghStack ) ) {
printf( "ICAKEY CloseStacks: Error 0x%x from IcaStackClose\n", rc );
}
}
/*
* Close the ICA device driver instance
*/
if ( ghIca ) {
if ( rc = IcaClose( ghIca ) ) {
printf( "ICAKEY CloseStacks: Error 0x%x from IcaClose\n", rc );
}
}
return( rc );
}
/****************************************************************************
*
* Initialize
*
* Do some initialization
*
* ENTRY:
* void
*
* EXIT:
* STATUS_SUCCESS - Success
* other - Error return code
*
****************************************************************************/
LONG
Initialize( void )
{
LONG rc = STATUS_SUCCESS;
DWORD tidKeyboardReadThread;
THREADDATA ThreadData;
/*
* Create stop event to wait on later.
*/
if ( !(ghStopEvent = CreateEvent( NULL, TRUE, FALSE, NULL )) ) {
printf( "ICAKEY Initialize: Error 0x%x in CreateEvent\n", GetLastError() );
goto done;
}
ThreadData.handle = ghKeyboard;
/*
* Startup the virtual channel read thread
*/
if ( !(ghThreadKeyboardRead = CreateThread( NULL,
KEYBOARD_THREAD_STACKSIZE,
(LPTHREAD_START_ROUTINE)KeyboardReadThread,
(LPVOID)&ThreadData, 0,
(LPDWORD)&tidKeyboardReadThread )) ) {
rc = GetLastError();
printf( "ICAKEY Initialize: Error 0x%x creating keyboard read thread\n", rc );
goto done;
}
done:
return( rc );
}
/*******************************************************************************
*
* Function: KeyboardReadThread
*
* Purpose: Keyboard read thread
*
* Entry:
* pThreadData
* Pointer to thread creation data
*
* Exit:
* void
*
******************************************************************************/
VOID KeyboardReadThread( PTHREADDATA pThreadData )
{
int rc;
HANDLE handle = pThreadData->handle;
KEYBOARD_INPUT_DATA KeyboardInputData;
DWORD cbRead;
OVERLAPPED Overlapped;
DWORD dwError;
int NumberRead = 0;
Overlapped.Offset = 0;
Overlapped.OffsetHigh = 0;
Overlapped.hEvent = NULL;
printf( "Keyboard read thread starting...\n" );
/*
* Now dedicate this thread to monitor the keyboard
*/
do {
cbRead = 0;
if ( !ReadFile( ghKeyboard,
&KeyboardInputData,
sizeof( KeyboardInputData ),
&cbRead, &Overlapped ) ) {
dwError = GetLastError();
if ( dwError == ERROR_IO_PENDING ) {
// check on the results of the asynchronous read
if ( !GetOverlappedResult( ghKeyboard, &Overlapped,
&cbRead, TRUE) ) { // wait for result
printf( "ICAKEY KeyboardReadThread: Error 0x%x from GetOverlappedResult( Channel_Keyboard )\n",
GetLastError() );
break;
}
}
else {
printf( "ICAKEY KeyboardReadThread: Error 0x%x from ReadFile( Channel_Keyboard )\n",
dwError );
break;
}
}
printf( "Unit number: 0x%x\nScan code: %02X\nFlags: %04X\nExtra info: %08X\n",
KeyboardInputData.UnitId,
KeyboardInputData.MakeCode,
KeyboardInputData.Flags,
KeyboardInputData.ExtraInformation );
NumberRead++;
if ( NumberRead == MAX_READ )
break;
} while ( 1 );
printf( "Keyboard read thread exiting...\n" );
SetEvent( ghStopEvent );
ExitThread( 0 );
}
/****************************************************************************
*
* KeyboardTest
*
* Stuff some data into the keyboard channel for testing purposes
*
* ENTRY:
* void
*
* EXIT:
* STATUS_SUCCESS - Success
* other - Error return code
*
****************************************************************************/
LONG
KeyboardTest( void )
{
LONG rc = STATUS_SUCCESS;
KEYBOARD_INPUT_DATA KeyboardInputData;
ULONG cbReturned;
/*
* Initialize the keystroke to fabricate
*/
KeyboardInputData.UnitId = 0;
KeyboardInputData.MakeCode = 0x32; // Capital 'M'
KeyboardInputData.Flags = KEY_MAKE;
KeyboardInputData.Reserved = 0;
KeyboardInputData.ExtraInformation = 0;
/*
* First stuff the make
*/
if ( rc = IcaChannelIoControl( ghKeyboard,
IOCTL_KEYBOARD_ICA_INPUT,
&KeyboardInputData,
sizeof( KeyboardInputData ),
NULL,
0,
&cbReturned ) ) {
printf( "ICAKEY KeyboardTest: Error 0x%x in IcaChannelIoControl\n", rc );
goto done;
}
KeyboardInputData.Flags = KEY_BREAK;
/*
* Now stuff the break
*/
if ( rc = IcaChannelIoControl( ghKeyboard,
IOCTL_KEYBOARD_ICA_INPUT,
&KeyboardInputData,
sizeof( KeyboardInputData ),
NULL,
0,
&cbReturned ) ) {
printf( "ICAKEY KeyboardTest: Error 0x%x in IcaChannelIoControl\n", rc );
goto done;
}
done:
return( rc );
}