/**INC+**********************************************************************/ /* Header: cchan.h */ /* */ /* Purpose: Virtual Channel 'internal' API file */ /* */ /* Copyright(C) Microsoft Corporation 1997 */ /* */ /****************************************************************************/ /** Changes: * $Log$ **/ /**INC-**********************************************************************/ /****************************************************************************/ /* Include 'external' API file */ /****************************************************************************/ #ifndef _H_CHAN_ #define _H_CHAN_ extern "C" { #include } #include "objs.h" #include "cd.h" #include "drapi.h" // // Enable code that verifies each compression // by decompressing // // #define DEBUG_CCHAN_COMPRESSION 1 class CChan; /****************************************************************************/ /****************************************************************************/ /* TYPEDEFS */ /****************************************************************************/ /****************************************************************************/ /**STRUCT+*******************************************************************/ /* Structure: CHANNEL_INIT_HANDLE */ /* */ /* Description: Channel data held per user */ /****************************************************************************/ //NOTE: This structure needs to be exposed to 'internal' plugins e.g rdpdr // so the definition is is vchandle.h // Internal plugins need to know the structure because they access // the lpInternalAddinParam field #include "vchandle.h" #define VC_MIN_COMPRESS_INPUT_BUF 50 #define VC_MAX_COMPRESS_INPUT_BUF CHANNEL_CHUNK_LENGTH // Size of sample for MPPC compression statistics. #define VC_MPPC_SAMPLE_SIZE 65535 // Compression scaling factor #define VC_UNCOMP_BYTES 1024 // Limit to prevent off behaviour #define VC_COMP_LIMIT 25 #define VC_USER_OUTBUF (CHANNEL_CHUNK_LENGTH+sizeof(CHANNEL_PDU_HEADER)) #define VC_MAX_COMPRESSED_BUFFER (CHANNEL_CHUNK_LENGTH*2) /**STRUCT-*******************************************************************/ /**STRUCT+*******************************************************************/ /* Structure: CHANNEL_DATA */ /* */ /* Description: Information about all channels */ /****************************************************************************/ typedef struct tagCHANNEL_DATA { PCHANNEL_OPEN_EVENT_FN pOpenEventFn; PCHANNEL_OPEN_EVENT_EX_FN pOpenEventExFn; DCUINT16 MCSChannelID; DCUINT16 pad; PCHANNEL_INIT_HANDLE pInitHandle; DCUINT status; #define CHANNEL_STATUS_CLOSED 0 #define CHANNEL_STATUS_OPEN 1 DCUINT priority; DCUINT SLFlags; DCUINT VCFlags; } CHANNEL_DATA, DCPTR PCHANNEL_DATA; /**STRUCT-*******************************************************************/ /**STRUCT+*******************************************************************/ /* Structure: CHANNEL_WRITE_DECOUPLE */ /* */ /* Description:structure passed to IntChannelWrite */ /****************************************************************************/ typedef struct tagCHANNEL_WRITE_DECOUPLE { DCUINT32 signature; #define CHANNEL_DECOUPLE_SIGNATURE 0x43684465 /* "ChDe" */ LPVOID pData; HPDCVOID pNextData; ULONG dataLength; ULONG dataLeft; ULONG dataSent; DWORD openHandle; LPVOID pUserData; DCUINT32 flags; unsigned chanOptions; struct tagCHANNEL_WRITE_DECOUPLE * pPrev; struct tagCHANNEL_WRITE_DECOUPLE * pNext; } CHANNEL_WRITE_DECOUPLE, DCPTR PCHANNEL_WRITE_DECOUPLE, DCPTR DCPTR PPCHANNEL_WRITE_DECOUPLE; /**STRUCT-*******************************************************************/ typedef struct tagDEVICE_PARAMS { WPARAM wParam; LPARAM lParam; IRDPDR_INTERFACE_OBJ *deviceObj; } DEVICE_PARAMS, *PDEVICE_PARAMS; class CCD; class CSL; class CUT; class CUI; extern "C" { #ifdef OS_WIN32 BOOL DCAPI #else //OS_WIN32 BOOL __loadds DCAPI #endif //OS_WIN32 MSTSCAX_VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX pEntryPointsEx, PVOID pAxCtlInstance); } // extern "C" class CChan { public: CChan(CObjs* objs); ~CChan(); public: DCVOID DCCALLBACK ChannelOnInitialized(DCVOID); DCVOID DCCALLBACK ChannelOnTerminating(DCVOID); DCVOID DCCALLBACK ChannelOnConnected(DCUINT channelID, DCUINT32 serverVersion, PDCVOID pUserData, DCUINT userDataLength); DCVOID DCCALLBACK ChannelOnDisconnected(DCUINT reason); DCVOID DCCALLBACK ChannelOnSuspended(DCUINT reason); DCVOID DCCALLBACK ChannelOnPacketReceived(PDCUINT8 pData, DCUINT dataLen, DCUINT flags, DCUINT userID, DCUINT priority); DCVOID DCCALLBACK ChannelOnBufferAvailable(DCVOID); DCVOID DCCALLBACK ChannelOnConnecting(PPCHANNEL_DEF ppChannel, PDCUINT32 pChannelCount); DCVOID DCCALLBACK ChannelOnInitializing(DCVOID); // // Per instance versions of external channel API // UINT VCAPITYPE IntVirtualChannelInit( PVOID pParam, PVOID * ppInitHandle, PCHANNEL_DEF pChannel, INT channelCount, DWORD versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc, PCHANNEL_INIT_EVENT_EX_FN pChannelInitEventProcEx); UINT VCAPITYPE DCEXPORT IntVirtualChannelOpen( PVOID pInitHandle, PDWORD pOpenHandle, PCHAR pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc, PCHANNEL_OPEN_EVENT_EX_FN pChannelOpenEventProcEx); UINT VCAPITYPE DCEXPORT IntVirtualChannelClose(DWORD openHandle); UINT VCAPITYPE DCEXPORT IntVirtualChannelWrite(DWORD openHandle, LPVOID pData, ULONG dataLength, LPVOID pUserData); VOID SetCapabilities(LONG caps); void OnDeviceChange(ULONG_PTR); EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CChan, OnDeviceChange); public: // // Member data // /****************************************************************************/ /* Pointer to first Init Handle */ /****************************************************************************/ PCHANNEL_INIT_HANDLE _pInitHandle; /****************************************************************************/ /* Pointer to first and last queued write operations - can be accessed only */ /* on SND thread. */ /****************************************************************************/ PCHANNEL_WRITE_DECOUPLE _pFirstWrite; PCHANNEL_WRITE_DECOUPLE _pLastWrite; /****************************************************************************/ /* State informtation */ /****************************************************************************/ #define CONNECTION_NONE 0 #define CONNECTION_V1 1 #define CONNECTION_VC 2 #define CONNECTION_SUSPENDED 3 DCUINT _connected; /****************************************************************************/ /* State information used by IntChannelLoad */ /****************************************************************************/ DCBOOL _inChannelEntry; DCBOOL _ChannelInitCalled; PCHANNEL_INIT_HANDLE _newInitHandle; /****************************************************************************/ /* Channel data */ /****************************************************************************/ CHANNEL_DEF _channel[CHANNEL_MAX_COUNT]; CHANNEL_DATA _channelData[CHANNEL_MAX_COUNT]; DCUINT _channelCount; /****************************************************************************/ /* Channel entry points */ /****************************************************************************/ CHANNEL_ENTRY_POINTS _channelEntryPoints; CHANNEL_ENTRY_POINTS_EX _channelEntryPointsEx; static CChan* pStaticClientInstance; private: /****************************************************************************/ /****************************************************************************/ /* Internal functions (defined later) */ /****************************************************************************/ /****************************************************************************/ DCVOID DCINTERNAL IntChannelCallCallbacks(DCUINT event, PDCVOID pData, DCUINT dataLength); DCVOID DCINTERNAL IntChannelFreeLibrary(DCUINT value); DCVOID DCINTERNAL IntChannelSend(ULONG_PTR value); EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CChan, IntChannelSend); DCVOID DCINTERNAL IntChannelCancelSend(ULONG_PTR value); EXPOSE_CD_SIMPLE_NOTIFICATION_FN(CChan, IntChannelCancelSend); DCVOID DCINTERNAL IntChannelWrite(PDCVOID pData, DCUINT dataLength); EXPOSE_CD_NOTIFICATION_FN(CChan, IntChannelWrite); DCVOID DCINTERNAL IntChannelLoad(PDCTCHAR DLLName); DCBOOL DCINTERNAL IntChannelInitAddin(PVIRTUALCHANNELENTRY pChanEntry, PVIRTUALCHANNELENTRYEX pChanEntryEx, HMODULE hMod, PDCTCHAR DLLName, PVOID pPassParamToEx); inline UCHAR IntChannelCompressData(UCHAR* pSrcData, ULONG cbSrcLen, UCHAR* pOutBuf, ULONG* pcbOutLen); private: CObjs* _pClientObjs; CCD* _pCd; CSL* _pSl; CUT* _pUt; CUI* _pUi; BOOL _fLockInitalized; CRITICAL_SECTION _VirtualChannelInitLock; BOOL _fCapsVCCompressionSupported; // // VC flag that specifies we are compressing // channels for this session. Individual channels can choose // to be compressed or not, be compression will only take place // if this flag is set. // // Same thing for decompressing channel data, we only decompress if // this flag is set and the virtual channel header specifies the // channel is compressed. // BOOL _fCompressChannels; //Compression stats #ifdef DC_DEBUG unsigned _cbBytesRecvd; unsigned _cbCompressedBytesRecvd; unsigned _cbDecompressedBytesRecvd; unsigned _cbTotalBytesUserAskSend; //total bytes user asked to send unsigned _cbTotalBytesSent; //total bytes actually sent on net unsigned _cbComprInput; //total compression input bytes unsigned _cbComprOutput; //total compression output bytes #endif SendContext* _pMPPCContext; LONG _CompressFlushes; BOOL _fCompressionFlushed; //When decompressing, we can't just hand of a pointer to the decompressed //data as the user may corrupt the decompression context, so we need to make //a copy into a user outbuf. PUCHAR _pUserOutBuf; //Reset the compression context BOOL _fNeedToResetContext; #ifdef DEBUG_CCHAN_COMPRESSION RecvContext2_8K* _pDbgRcvDecompr8K; RecvContext1 _DbgRcvContext1; BOOL _fDbgVCTriedAllocRecvContext; BOOL _fDbgAllocFailedForVCRecvContext; #endif INT _iDbgCompressFailedCount; INT _iChanSuspendCount; INT _iChanResumeCount; INT _iChanCapsRecvdCount; }; #endif // _H_CHAN_