windows-nt/Source/XPSP1/NT/termsrv/drivers/termdd/icap.h
2020-09-26 16:20:57 +08:00

388 lines
12 KiB
C

/****************************************************************************/
// icap.h
//
// TermDD private header.
//
// Copyright (C) 1998-2000 Microsoft Corporation
/****************************************************************************/
#define ICA_POOL_TAG ' acI'
/*
* Enumerated ICA object types
*/
typedef enum _ICA_TYPE {
IcaType_Connection,
IcaType_Stack,
IcaType_Channel
} ICA_TYPE;
/*
* ICA dispatch prototype
*/
typedef NTSTATUS (*PICA_DISPATCH) (
IN PVOID IcaObject,
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp);
/*
* Deferred trace structure
*/
#pragma warning(disable : 4200) // for Buffer[] nonstandard extension.
typedef struct _DEFERRED_TRACE {
struct _DEFERRED_TRACE *Next;
ULONG Length;
WCHAR Buffer[];
} DEFERRED_TRACE, *PDEFERRED_TRACE;
#pragma warning(default : 4200)
/*
* Trace Information structure
*/
typedef struct _ICA_TRACE_INFO {
ULONG TraceClass; // trace - enabled trace classes (TC_?)
ULONG TraceEnable; // trace - enabled trace types (TT_?)
BOOLEAN fTraceDebugger; // trace - send trace messages to the debugger
BOOLEAN fTraceTimestamp; // trace - time stamp trace messages
PWCHAR pTraceFileName;
PFILE_OBJECT pTraceFileObject;
PDEFERRED_TRACE pDeferredTrace;
} ICA_TRACE_INFO, *PICA_TRACE_INFO;
/*
* Common header for all ICA objects
*/
typedef struct _ICA_HEADER {
ICA_TYPE Type;
PICA_DISPATCH *pDispatchTable;
} ICA_HEADER, *PICA_HEADER;
/*
* ICA connection object
*/
typedef struct _ICA_CONNECTION {
ICA_HEADER Header; // WARNING: This field MUST ALWAYS be first
LONG RefCount; // Reference count for this connection
ERESOURCE Resource; // Resource protecting access to this object
BOOLEAN fPassthruEnabled;
LIST_ENTRY StackHead; // List of stack objects for this connection
LIST_ENTRY ChannelHead; // List of channel objects for this connection
LIST_ENTRY VcBindHead; // List of vcbind objects for this connection
ICA_TRACE_INFO TraceInfo; // trace information
/*
* Channel pointers array. This array should be indexed using the
* channel number plus the virtual channel number. This allows a
* fast lookup of any bound channel given the channel/virtual number.
*/
struct _ICA_CHANNEL *pChannel[CHANNEL_COUNT+VIRTUAL_MAXIMUM];
ERESOURCE ChannelTableLock;
} ICA_CONNECTION, *PICA_CONNECTION;
//
// define the Maximum Low Water Mark setting to resume transmission
//
#define MAX_LOW_WATERMARK ((ULONG)((ULONG_PTR)-1))
/*
* ICA stack object
*/
typedef struct _ICA_STACK {
ICA_HEADER Header; // WARNING: This field MUST ALWAYS be first
LONG RefCount; // Reference count for this stack
ERESOURCE Resource; // Resource protecting access to this object
STACKCLASS StackClass; // Stack type (primary/shadow)
LIST_ENTRY StackEntry; // Links for connection object stack list
LIST_ENTRY SdLinkHead; // Head of SDLINK list for this stack
struct _ICA_STACK *pPassthru; // Pointer to passthru stack
BOOLEAN fIoDisabled;
BOOLEAN fClosing;
BOOLEAN fDoingInput;
BOOLEAN fDisablingIo;
KEVENT IoEndEvent;
LARGE_INTEGER LastInputTime; // last time of keyboard/mouse input
PVOID pBrokenEventObject;
/*
* Pointer to connection object.
* Note this is typed as PUCHAR instead of PICA_CONNECTION to prevent use
* of it directly. All references to the connection object a stack is
* attached to should be made by calling IcaGetConnectionForStack() if
* the stack is already locked, or IcaLockConnectionForStack() otherwise.
* This is required because this is a dynamic pointer, which can be
* modified during stack reconnect.
*/
PUCHAR pConnect; // Pointer to connection object
BOOLEAN fWaitForOutBuf; // outbuf - did we hit the high watermark
ULONG OutBufLength; // outbuf - length of output buffer
ULONG OutBufCount; // outbuf - maximum number of outbufs
ULONG OutBufAllocCount; // outbuf - number of outbufs allocated
KEVENT OutBufEvent; // outbuf - allocate event
ULONG SdOutBufHeader; // reserved output buffer header bytes
ULONG SdOutBufTrailer; // reserved output buffer trailer bytes
CLIENTMODULES ClientModules; // stack driver client module data
PROTOCOLSTATUS ProtocolStatus; // stack driver protocol status
LIST_ENTRY StackNode; // for linking all stacks together
LARGE_INTEGER LastKeepAliveTime; // Time last keepalive packet sent
ULONG OutBufLowWaterMark; // low water mark to resume transmission
} ICA_STACK, *PICA_STACK;
/*
* Channel Filter Input/Output procedure prototype
*/
typedef NTSTATUS
(_stdcall * PFILTERPROC)( PVOID, PCHAR, ULONG, PINBUF * );
/*
* ICA channel filter object
*/
typedef struct _ICA_FILTER {
PFILTERPROC InputFilter; // Input filter procedure
PFILTERPROC OutputFilter; // Output filter procedure
} ICA_FILTER, *PICA_FILTER;
/*
* ICA virtual class bind structure
*/
typedef struct _ICA_VCBIND {
VIRTUALCHANNELNAME VirtualName; // Virtual channel name
VIRTUALCHANNELCLASS VirtualClass; // Virtual channel number (0-31, -1 unbound)
ULONG Flags;
LIST_ENTRY Links; // Links for vcbind structure list
} ICA_VCBIND, *PICA_VCBIND;
/*
* ICA channel object
*/
typedef struct _ICA_CHANNEL {
ICA_HEADER Header; // WARNING: This field MUST ALWAYS be first
LONG RefCount; // Reference count for this channel
ERESOURCE Resource; // Resource protecting access to this object
ULONG Flags; // Channel flags (see CHANNEL_xxx below)
LONG OpenCount; // Count of opens on this object
PICA_CONNECTION pConnect; // Pointer to connection object
PICA_FILTER pFilter; // Pointer to filter object for this channel
CHANNELCLASS ChannelClass; // Channel type
VIRTUALCHANNELNAME VirtualName; // Virtual channel name
VIRTUALCHANNELCLASS VirtualClass; // Virtual channel number (0-31, -1 unbound)
LIST_ENTRY Links; // Links for channel structure list
LIST_ENTRY InputIrpHead; // Head of pending IRP list
LIST_ENTRY InputBufHead; // Head of input buffer list
unsigned InputBufCurSize; // Bytes held in input buffers.
unsigned InputBufMaxSize; // High watermark for input buffers.
PERESOURCE pChannelTableLock;
ULONG CompletionRoutineCount;
} ICA_CHANNEL, *PICA_CHANNEL;
/*
* VirtualClass - virtual channel is not yet bound to a virtual class number
*/
#define UNBOUND_CHANNEL -1
/*
* Channel Flags
*/
#define CHANNEL_MESSAGE_MODE 0x00000001 // This is a message mode channel
#define CHANNEL_SHADOW_IO 0x00000002 // Pass shadow data
#define CHANNEL_SCREENDATA 0x00000004 // This is a screen data channel
#define CHANNEL_CLOSING 0x00000008 // This channel is being closed
#define CHANNEL_SHADOW_PERSISTENT 0x00000010 // Used for virtual channels: still up during shadow
#define CHANNEL_SESSION_DISABLEIO 0x00000020 // Used disable IO for help session while not in shadow mode
#define CHANNEL_CANCEL_READS 0x00000040 // To cancel reads to CommandChannel on Winstation termination
/*
* Stack Driver load structure
* There exists exactly one of these structures for
* each Stack Driver (WD/PD/TD) loaded in the system.
*/
typedef struct _SDLOAD {
WDNAMEW SdName; // Name of this SD
LONG RefCount; // Reference count
LIST_ENTRY Links; // Links for SDLOAD list
PVOID ImageHandle; // Image handle for this driver
PVOID ImageBase; // Image base for this driver
PSDLOADPROC DriverLoad; // Pointer to driver load routine
PFILE_OBJECT FileObject; // Reference to underlying driver
PVOID pUnloadWorkItem;// Pointer to workitem for delayed unload
PDEVICE_OBJECT DeviceObject;// Pointer device object to use the unload safe completion routine
} SDLOAD, *PSDLOAD;
/*
* Stack Driver link structure
* There exists one of these structures for each WD/PD/TD in a stack.
*/
typedef struct _SDLINK {
PICA_STACK pStack; // Pointer to ICA_STACK object for this driver
PSDLOAD pSdLoad; // Pointer to SDLOAD object for this driver
LIST_ENTRY Links; // Links for SDLINK list
LONG RefCount;
SDCONTEXT SdContext; // Contains SD proc table, context value, callup table
ERESOURCE Resource;
} SDLINK, * PSDLINK;
/*
* Lock/Unlock macros
*/
#if DBG
/*
*
* NOTE: Under DBG builds, the following routines will validate
* that the correct locking order is not violated.
* The correct order is:
* 1) Connection
* 2) Stack
* 3) Channel
*/
BOOLEAN IcaLockConnection(PICA_CONNECTION);
void IcaUnlockConnection(PICA_CONNECTION);
BOOLEAN IcaLockStack(PICA_STACK);
void IcaUnlockStack(PICA_STACK);
BOOLEAN IcaLockChannel(PICA_CHANNEL);
void IcaUnlockChannel(PICA_CHANNEL);
#else // DBG
#define IcaLockConnection(p) { \
IcaReferenceConnection( p ); \
KeEnterCriticalRegion(); /* Disable APC calls */ \
ExAcquireResourceExclusiveLite( &p->Resource, TRUE ); \
}
#define IcaUnlockConnection(p) { \
ExReleaseResourceLite( &p->Resource ); \
KeLeaveCriticalRegion(); /* Re-enable APC calls */ \
IcaDereferenceConnection( p ); \
}
#define IcaLockStack(p) { \
IcaReferenceStack( p ); \
KeEnterCriticalRegion(); /* Disable APC calls */ \
ExAcquireResourceExclusiveLite( &p->Resource, TRUE ); \
}
#define IcaUnlockStack(p) { \
ExReleaseResourceLite( &p->Resource ); \
KeLeaveCriticalRegion(); /* Re-enable APC calls */ \
IcaDereferenceStack( p ); \
}
#define IcaLockChannel(p) { \
IcaReferenceChannel( p ); \
KeEnterCriticalRegion(); /* Disable APC calls */ \
ExAcquireResourceExclusiveLite( &p->Resource, TRUE ); \
}
#define IcaUnlockChannel(p) { \
ExReleaseResourceLite( &p->Resource ); \
KeLeaveCriticalRegion(); /* Re-enable APC calls */ \
IcaDereferenceChannel(p); \
}
#endif // DBG
PICA_CONNECTION IcaGetConnectionForStack(PICA_STACK);
PICA_CONNECTION IcaLockConnectionForStack(PICA_STACK);
void IcaUnlockConnectionForStack(PICA_STACK);
/*
* Memory alloc/free macros
*/
#if DBG
PVOID IcaAllocatePool(IN POOL_TYPE, IN ULONG, PCHAR, ULONG, BOOLEAN);
#define ICA_ALLOCATE_POOL(a,b) IcaAllocatePool(a, b, __FILE__, __LINE__, FALSE)
#define ICA_ALLOCATE_POOL_WITH_QUOTA(a,b) IcaAllocatePool(a, b, __FILE__, __LINE__, TRUE)
void IcaFreePool (IN PVOID);
#define ICA_FREE_POOL(a) IcaFreePool(a)
#else // DBG
#define ICA_ALLOCATE_POOL(a,b) ExAllocatePoolWithTag(a,b,ICA_POOL_TAG)
#define ICA_ALLOCATE_POOL_WITH_QUOTA(a,b) ExAllocatePoolWithQuotaTag(a,b,ICA_POOL_TAG)
#define ICA_FREE_POOL(a) ExFreePool(a)
#endif // DBG
/*
* Spinlock acquire/release macros
*/
#if DBG
extern ULONG IcaLocksAcquired;
#define IcaAcquireSpinLock(a,b) KeAcquireSpinLock((a),(b)); IcaLocksAcquired++
#define IcaReleaseSpinLock(a,b) IcaLocksAcquired--; KeReleaseSpinLock((a),(b))
void IcaInitializeDebugData(void);
#else // DBG
#define IcaAcquireSpinLock(a,b) KeAcquireSpinLock((a),(b))
#define IcaReleaseSpinLock(a,b) KeReleaseSpinLock((a),(b))
#endif // DBG
/*
* Trace
*/
extern ICA_TRACE_INFO G_TraceInfo;
#undef TRACE
#undef TRACESTACK
#undef TRACESTACKBUF
#undef TRACECHANNEL
#if DBG
VOID _cdecl _IcaTrace( PICA_CONNECTION, ULONG, ULONG, CHAR *, ... );
VOID _cdecl _IcaStackTrace( PICA_STACK, ULONG, ULONG, CHAR *, ... );
VOID _IcaStackTraceBuffer( PICA_STACK, ULONG, ULONG, PVOID, ULONG );
VOID _cdecl _IcaChannelTrace( PICA_CHANNEL, ULONG, ULONG, CHAR *, ... );
#define TRACE(_arg) _IcaTrace _arg
#define TRACESTACK(_arg) _IcaStackTrace _arg
#define TRACESTACKBUF(_arg) _IcaStackTraceBuffer _arg
#define TRACECHANNEL(_arg) _IcaChannelTrace _arg
#else
#define TRACE(_arg)
#define TRACESTACK(_arg)
#define TRACESTACKBUF(_arg)
#define TRACECHANNEL(_arg)
#endif
/*
* Need to define these to have MP save driver ( proper locked operation will generated for x86)-Bug# 209464
*/
#define _NTSRV_
#define _NTDDK_