403 lines
9.9 KiB
C
403 lines
9.9 KiB
C
/*************************************************************************
|
|
* 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 );
|
|
}
|