|
|
/*************************************************************************
* ICAAPI.C * * ICA DLL Interface for ICA Device Driver * * Copyright 1996, Citrix Systems Inc. * Copyright (C) 1997-1999 Microsoft Corp. * * Author: Marc Bloomfield * Terry Treder * Brad Pedersen *************************************************************************/
#include "precomp.h"
#pragma hdrstop
/*=============================================================================
== External procedures defined =============================================================================*/
#ifdef BUILD_AS_DLL
BOOL WINAPI DllEntryPoint( HINSTANCE, DWORD, LPVOID ); #endif
NTSTATUS IcaOpen( HANDLE * phIca ); NTSTATUS IcaClose( HANDLE hIca ); VOID cdecl IcaSystemTrace( IN HANDLE hIca, ULONG, ULONG, char *, ... ); VOID cdecl IcaTrace( IN HANDLE hIca, ULONG, ULONG, char *, ... ); NTSTATUS IcaIoControl( HANDLE hIca, ULONG, PVOID, ULONG, PVOID, ULONG, PULONG );
/*=============================================================================
== Internal procedures defined =============================================================================*/
NTSTATUS _IcaOpen( PHANDLE hIca, PVOID, ULONG );
/*=============================================================================
== Procedures used =============================================================================*/
#ifdef BUILD_AS_DLL
/****************************************************************************
* * DllEntryPoint * * Function is called when the DLL is loaded and unloaded. * * ENTRY: * hinstDLL (input) * Handle of DLL module * fdwReason (input) * Why function was called * lpvReserved (input) * Reserved; must be NULL * * EXIT: * TRUE - Success * FALSE - Error occurred * ****************************************************************************/
BOOL WINAPI DllEntryPoint( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { switch ( fdwReason ) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); break; default: break; }
return( TRUE ); } #endif
/****************************************************************************
* * IcaOpen * * Open an instance to the ICA Device Driver * * ENTRY: * phIca (output) * Pointer to ICA instance handle * * EXIT: * STATUS_SUCCESS - Success * other - Error return code * ****************************************************************************/
NTSTATUS IcaOpen( OUT HANDLE * phIca ) { NTSTATUS Status;
Status = _IcaOpen( phIca, NULL, 0 ); if ( !NT_SUCCESS(Status) ) goto badopen;
TRACE(( *phIca, TC_ICAAPI, TT_API1, "TSAPI: IcaOpen, success\n" ));
return( STATUS_SUCCESS );
/*=============================================================================
== Error returns =============================================================================*/
badopen: *phIca = NULL; return( Status ); }
/****************************************************************************
* * IcaClose * * Close an instance to the ICA Device Driver * * ENTRY: * hIca (input) * ICA instance handle * * EXIT: * STATUS_SUCCESS - Success * other - Error return code * ****************************************************************************/
NTSTATUS IcaClose( IN HANDLE hIca ) { NTSTATUS Status;
TRACE(( hIca, TC_ICAAPI, TT_API1, "TSAPI: IcaClose\n" ));
/*
* Close the ICA device driver instance */ Status = NtClose( hIca );
ASSERT( NT_SUCCESS(Status) ); return( Status ); }
/*******************************************************************************
* * IcaSystemTrace * * Write a trace record to the system trace file * * ENTRY: * hIca (input) * ICA instance handle * TraceClass (input) * trace class bit mask * TraceEnable (input) * trace type bit mask * Format (input) * format string * ... (input) * enough arguments to satisfy format string * * EXIT: * nothing * ******************************************************************************/
VOID cdecl IcaSystemTrace( IN HANDLE hIca, IN ULONG TraceClass, IN ULONG TraceEnable, IN char * Format, IN ... ) { ICA_TRACE_BUFFER Buffer; va_list arg_marker; ULONG Length;
va_start( arg_marker, Format );
Length = (ULONG) _vsnprintf( Buffer.Data, sizeof(Buffer.Data), Format, arg_marker );
Buffer.TraceClass = TraceClass; Buffer.TraceEnable = TraceEnable; Buffer.DataLength = Length;
(void) IcaIoControl( hIca, IOCTL_ICA_SYSTEM_TRACE, &Buffer, sizeof(Buffer) - sizeof(Buffer.Data) + Length, NULL, 0, NULL ); }
/*******************************************************************************
* * IcaTrace * * Write a trace record to the winstation trace file * * ENTRY: * hIca (input) * ICA instance handle * TraceClass (input) * trace class bit mask * TraceEnable (input) * trace type bit mask * Format (input) * format string * ... (input) * enough arguments to satisfy format string * * EXIT: * nothing * ******************************************************************************/
VOID cdecl IcaTrace( IN HANDLE hIca, IN ULONG TraceClass, IN ULONG TraceEnable, IN char * Format, IN ... ) { ICA_TRACE_BUFFER Buffer; va_list arg_marker; ULONG Length; va_start( arg_marker, Format );
Length = (ULONG) _vsnprintf( Buffer.Data, sizeof(Buffer.Data), Format, arg_marker );
Buffer.TraceClass = TraceClass; Buffer.TraceEnable = TraceEnable; Buffer.DataLength = Length;
(void) IcaIoControl( hIca, IOCTL_ICA_TRACE, &Buffer, sizeof(Buffer) - sizeof(Buffer.Data) + Length, NULL, 0, NULL ); }
/****************************************************************************
* * IcaIoControl * * Generic interface to the ICA Device Driver * * ENTRY: * hIca (input) * ICA instance handle * * IoControlCode (input) * I/O control code * * pInBuffer (input) * Pointer to input parameters * * InBufferSize (input) * Size of pInBuffer * * pOutBuffer (output) * Pointer to output buffer * * OutBufferSize (input) * Size of pOutBuffer * * pBytesReturned (output) * Pointer to number of bytes returned * * EXIT: * STATUS_SUCCESS - Success * other - Error return code * ****************************************************************************/
NTSTATUS IcaIoControl( IN HANDLE hIca, IN ULONG IoControlCode, IN PVOID pInBuffer, IN ULONG InBufferSize, OUT PVOID pOutBuffer, IN ULONG OutBufferSize, OUT PULONG pBytesReturned ) { IO_STATUS_BLOCK Iosb; NTSTATUS Status;
/*
* Issue ioctl */ Status = NtDeviceIoControlFile( hIca, NULL, NULL, NULL, &Iosb, IoControlCode, pInBuffer, InBufferSize, pOutBuffer, OutBufferSize );
/*
* Wait for ioctl to complete */ if ( Status == STATUS_PENDING ) { Status = NtWaitForSingleObject( hIca, FALSE, NULL ); if ( NT_SUCCESS(Status)) Status = Iosb.Status; }
/*
* Convert warning into error */ if ( Status == STATUS_BUFFER_OVERFLOW ) Status = STATUS_BUFFER_TOO_SMALL;
/*
* Initialize bytes returned */ if ( pBytesReturned ) *pBytesReturned = (ULONG)Iosb.Information;
return( Status ); }
/****************************************************************************
* * _IcaOpen * * Open an instance to the ICA Device Driver or an ICA stack * * ENTRY: * ph (output) * Pointer to ICA or ICA stack instance handle * * pEa (input) * Pointer to extended attribute buffer * * cbEa (input) * Size of extended attribute buffer * * EXIT: * STATUS_SUCCESS - Success * other - Error return code * ****************************************************************************/
NTSTATUS _IcaOpen( PHANDLE ph, PVOID pEa, ULONG cbEa ) { NTSTATUS Status; OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING IcaName; IO_STATUS_BLOCK ioStatusBlock;
/*
* Initialize the object attributes */ RtlInitUnicodeString( &IcaName, ICA_DEVICE_NAME );
InitializeObjectAttributes( &objectAttributes, &IcaName, OBJ_CASE_INSENSITIVE, NULL, NULL );
/*
* Open an instance to the ICA device driver */ Status = NtCreateFile( ph, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &objectAttributes, &ioStatusBlock, NULL, // AllocationSize
0L, // FileAttributes
FILE_SHARE_READ | FILE_SHARE_WRITE, // ShareAccess
FILE_OPEN_IF, // CreateDisposition
0, pEa, cbEa );
return( Status ); }
|