|
|
/*************************************************************************
* 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 ); }
|