Windows2003-3790/termsrv/drivers/rdp/pdmcs/mcsimpl.h
2020-09-30 16:53:55 +02:00

496 lines
16 KiB
C

/* (C) 1997-1999 Microsoft Corp.
*
* file : MCSImpl.h
* author : Erik Mavrinac
*
* description: MCS implementation-specific defines and structures.
*/
#ifndef __MCSIMPL_H
#define __MCSIMPL_H
#include "MCSKernl.h"
#include "X224.h"
#include "MCSIOCTL.h"
#include "SList.h"
#include "Trace.h"
#include "rdperr.h"
#include "domain.h"
/*
* Defines
*/
// Memory defines.
#define MCS_POOL_TAG 'cmST'
// Used with PDU handler function tables to allow a PDU name in debug builds.
#if DBG
#define StrOnDbg(str, func) { str, func }
#else
#define StrOnDbg(str, func) { func }
#endif // DBG
#define NULL_ChannelID 0
#define NULL_TokenID 0
#define NULL_UserID 0
// Start of the dynamic MCS channel numbering space.
#define MinDynamicChannel 1002
// Types of channels possible in the MCSChannel struct below.
#define Channel_Unused 0
#define Channel_Static 1
#define Channel_UserID 2
#define Channel_Assigned 3
#define Channel_Convened 4
// Default starting sizes for allocation pools. These are provided as hints
// to data structure management code.
#define DefaultNumChannels 5
#define DefaultNumUserAttachments 2
// DomainParameters required min and max settings.
#define RequiredMinChannels 4
#define RequiredMinUsers 3
#define RequiredDomainHeight 1
#define RequiredMinPDUSize 124
#define RequiredProtocolVer 2
#define RequiredPriorities 1
// Connection states for PD.State below.
// Connection sequence like this:
// 1. Start state: Unconnected
// 2. Client socket created, state: Unconnected
// 3. X.224 Connect TPDU comes in, send accept. State: X224_Connected
// 4. MCS connect-initial comes in, send up to node controller for acceptance,
// state: ConnectProvIndPending
// 5. Node controller responds with connect-provider response: if accepted
// (RESULT_SUCCESSFUL) state = MCS_Connected; otherwise state =
// Disconnected.
// 6. Client sends MCS disconnect-provider ultimatum: state = Disconnected.
// 7. Server calls DisconnectProvider: state = Disconnected.
#define State_Unconnected 0
#define State_X224_Connected 1
#define State_X224_Requesting 2
#define State_ConnectProvIndPending 3
#define State_MCS_Connected 4
#define State_Disconnected 5
// Diagnostic codes - for RejectMCSPDU. Values per T.125 spec.
#define Diag_InconsistentMerge 0
#define Diag_ForbiddenPDUDownward 1
#define Diag_ForbiddenPDUUpward 2
#define Diag_InvalidBEREncoding 3
#define Diag_InvalidPEREncoding 4
#define Diag_MisroutedUser 5
#define Diag_UnrequestedConfirm 6
#define Diag_WrongTransportPriority 7
#define Diag_ChannelIDConflict 8
#define Diag_TokenIDConflict 9
#define Diag_NotUserIDChannel 10
#define Diag_TooManyChannels 11
#define Diag_TooManyTokens 12
#define Diag_TooManyUsers 13
/*
* PDU types and lengths
*/
#define MCS_CONNECT_PDU 0x7F
// The 101-based enumerated connect PDU type.
#define MCS_CONNECT_INITIAL_ENUM 0x65
#define MCS_CONNECT_RESPONSE_ENUM 0x66
#define MCS_CONNECT_ADDITIONAL_ENUM 0x67
#define MCS_CONNECT_RESULT_ENUM 0x68
#define MinConnectPDU MCS_CONNECT_INITIAL_ENUM
#define MaxConnectPDU MCS_CONNECT_RESULT_ENUM
// The 0-based enumerated domain PDU type, defined for creating labeled-byte
// tables for Bloodhound.
#define MCS_PLUMB_DOMAIN_INDICATION_ENUM 0
#define MCS_ERECT_DOMAIN_REQUEST_ENUM 1
#define MCS_MERGE_CHANNELS_REQUEST_ENUM 2
#define MCS_MERGE_CHANNELS_CONFIRM_ENUM 3
#define MCS_PURGE_CHANNEL_INDICATION_ENUM 4
#define MCS_MERGE_TOKENS_REQUEST_ENUM 5
#define MCS_MERGE_TOKENS_CONFIRM_ENUM 6
#define MCS_PURGE_TOKEN_INDICATION_ENUM 7
#define MCS_DISCONNECT_PROVIDER_ULTIMATUM_ENUM 8
#define MCS_REJECT_ULTIMATUM_ENUM 9
#define MCS_ATTACH_USER_REQUEST_ENUM 10
#define MCS_ATTACH_USER_CONFIRM_ENUM 11
#define MCS_DETACH_USER_REQUEST_ENUM 12
#define MCS_DETACH_USER_INDICATION_ENUM 13
#define MCS_CHANNEL_JOIN_REQUEST_ENUM 14
#define MCS_CHANNEL_JOIN_CONFIRM_ENUM 15
#define MCS_CHANNEL_LEAVE_REQUEST_ENUM 16
#define MCS_CHANNEL_CONVENE_REQUEST_ENUM 17
#define MCS_CHANNEL_CONVENE_CONFIRM_ENUM 18
#define MCS_CHANNEL_DISBAND_REQUEST_ENUM 19
#define MCS_CHANNEL_DISBAND_INDICATION_ENUM 20
#define MCS_CHANNEL_ADMIT_REQUEST_ENUM 21
#define MCS_CHANNEL_ADMIT_INDICATION_ENUM 22
#define MCS_CHANNEL_EXPEL_REQUEST_ENUM 23
#define MCS_CHANNEL_EXPEL_INDICATION_ENUM 24
#define MCS_SEND_DATA_REQUEST_ENUM 25
#define MCS_SEND_DATA_INDICATION_ENUM 26
#define MCS_UNIFORM_SEND_DATA_REQUEST_ENUM 27
#define MCS_UNIFORM_SEND_DATA_INDICATION_ENUM 28
#define MCS_TOKEN_GRAB_REQUEST_ENUM 29
#define MCS_TOKEN_GRAB_CONFIRM_ENUM 30
#define MCS_TOKEN_INHIBIT_REQUEST_ENUM 31
#define MCS_TOKEN_INHIBIT_CONFIRM_ENUM 32
#define MCS_TOKEN_GIVE_REQUEST_ENUM 33
#define MCS_TOKEN_GIVE_INDICATION_ENUM 34
#define MCS_TOKEN_GIVE_RESPONSE_ENUM 35
#define MCS_TOKEN_GIVE_CONFIRM_ENUM 36
#define MCS_TOKEN_PLEASE_REQUEST_ENUM 37
#define MCS_TOKEN_PLEASE_INDICATION_ENUM 38
#define MCS_TOKEN_RELEASE_REQUEST_ENUM 39
#define MCS_TOKEN_RELEASE_CONFIRM_ENUM 40
#define MCS_TOKEN_TEST_REQUEST_ENUM 41
#define MCS_TOKEN_TEST_CONFIRM_ENUM 42
#define MinDomainPDU MCS_PLUMB_DOMAIN_INDICATION_ENUM
#define MaxDomainPDU MCS_TOKEN_TEST_CONFIRM_ENUM
/*
* PDU size definitions for use allocating buffers for PDUs/headers.
*/
// Connect PDUs.
// Connect-response - maximum size. Includes:
// 3 bytes for Result
// 5 bytes for CalledConnectID
// 40 bytes for DomParams
// 6 bytes for UserDataSize
// UserLen bytes for user data
#define ConnectResponseHeaderSize 54
#define ConnectResponseBaseSize(UserLen) (ConnectResponseHeaderSize + UserLen)
#define ConnectResponsePDUSize(UserLen) \
(X224_DataHeaderSize + ConnectResponseBaseSize(UserLen))
// Domain PDUs.
// Prototype for function defined in DomPDU.c.
int GetTotalLengthDeterminantEncodingSize(int);
#define GetLD(x) GetTotalLengthDeterminantEncodingSize(x)
// Plumb-domain indication
#define PDinBaseSize 3
#define PDinPDUSize (X224_DataHeaderSize + PDinBaseSize)
// Erect-domain request
#define EDrqBaseSize 5
#define EDrqPDUSize (X224_DataHeaderSize + EDrqBaseSize)
// Disconnect-provider ultimatum
#define DPumBaseSize 2
#define DPumPDUSize (X224_DataHeaderSize + DPumBaseSize)
// Reject-MCSPDU ultimatum
#define RJumBaseSize(PDUSize) (2 + GetLD(PDUSize) + (PDUSize))
#define RJumPDUSize(PDUSize) (X224_DataHeaderSize + RJumBaseSize(PDUSize))
// Attach-user request
#define AUrqBaseSize 1
#define AUrqPDUSize (X224_DataHeaderSize + AUrqBaseSize)
// Attach-user confirm
#define AUcfBaseSize(bInit) ((bInit) ? 4 : 2)
#define AUcfPDUSize(bInit) (X224_DataHeaderSize + AUcfBaseSize(bInit))
// Detach-user request
#define DUrqBaseSize(NUsers) (2 + GetLD(NUsers) + sizeof(UserID) * (NUsers))
#define DUrqPDUSize(NUsers) (X224_DataHeaderSize + DUrqBaseSize(NUsers))
// Detach-user indication
#define DUinBaseSize(NUsers) DUrqBaseSize(NUsers)
#define DUinPDUSize(NUsers) DUrqPDUSize(NUsers)
// Channel-join request
#define CJrqBaseSize 5
#define CJrqPDUSize (X224_DataHeaderSize + CJrqBaseSize)
// Channel-join confirm
#define CJcfBaseSize(bJoin) ((bJoin) ? 8 : 6)
#define CJcfPDUSize(bJoin) (X224_DataHeaderSize + CJcfBaseSize(bJoin))
// Channel-leave request
#define CLrqBaseSize(NChn) (1 + GetLD(NChn) + sizeof(ChannelID) * (NChn))
#define CLrqPDUSize(NChn) (X224_DataHeaderSize + CLrqBaseSize(NChn))
// Channel-convene request
#define CCrqBaseSize 3
#define CCrqPDUSize (X224_DataHeaderSize + CCrqBaseSize)
// Channel-convene confirm
#define CCcfBaseSize(bChn) ((bChn) ? 6 : 4)
#define CCcfPDUSize(bChn) (X224_DataHeaderSize + CCcfBaseSize(bChn))
// Channel-disband request
#define CDrqBaseSize 5
#define CDrqPDUSize (X224_DataHeaderSize + CDrqBaseSize)
// Channel-disband indication
#define CDinBaseSize 3
#define CDinPDUSize (X224_DataHeaderSize + CDinBaseSize)
// Channel-admit request
#define CArqBaseSize(NUsers) (5 + sizeof(UserID) * (NUsers))
#define CArqPDUSize(NUsers) (X224_DataHeaderSize + CArqBaseSize(NUsers))
// Channel-admit indication
#define CAinBaseSize(NUsers) CArqBaseSize(NUsers)
#define CAinPDUSize(NUsers) CAinPDUSize(NUsers)
// Channel-expel request
#define CErqBaseSize(NUsers) CArqBaseSize(NUsers)
#define CErqPDUSize(NUsers) CAinPDUSize(NUsers)
// Channel-expel indication
#define CEinBaseSize(NUsers) (3 + sizeof(UserID) * (NUsers))
#define CEinPDUSize(NUsers) (X224_DataHeaderSize + CEinBaseSize(NUsers))
// Send data
#define SDBaseSize(DataSize) (6 + GetLD(DataSize) + (DataSize))
#define SDPDUSize(DataSize) (X224_DataHeaderSize + SDBaseSize(DataSize))
// Token-grab request
#define TGrqBaseSize 5
#define TGrqPDUSize (X224_DataHeaderSize + TGrqBaseSize)
// Token-grab confirm
#define TGcfBaseSize 7
#define TGcfPDUSize (X224_DataHeaderSize + TGcfBaseSize)
// Token-inhibit request
#define TIrqBaseSize 5
#define TIrqPDUSize (X224_DataHeaderSize + TIrqBaseSize)
// Token-inhibit confirm
#define TIcfBaseSize TGcfBaseSize
#define TIcfPDUSize TGcfPDUSize
// Token-give request
#define TVrqBaseSize 7
#define TVrqPDUSize (X224_DataHeaderSize + TVrqBaseSize)
// Token-give indication
#define TVinBaseSize 7
#define TVinPDUSize (X224_DataHeaderSize + TVinBaseSize)
// Token-give response
#define TVrsBaseSize 6
#define TVrsPDUSize (X224_DataHeaderSize + TVrsBaseSize)
// Token-give confirm
#define TVcfBaseSize TGcfBaseSize
#define TVcfPDUSize TGcfPDUSize
// Token-please request
#define TPrqBaseSize 5
#define TPrqPDUSize (X224_DataHeaderSize + TPrqBaseSize)
// Token-please indication
#define TPinBaseSize 5
#define TPinPDUSize (X224_DataHeaderSize + TPinBaseSize)
// Token-release request
#define TRrqBaseSize 5
#define TRrqPDUSize (X224_DataHeaderSize + TRrqBaseSize)
// Token-release confirm
#define TRcfBaseSize TGcfBaseSize
#define TRcfPDUSize TGcfPDUSize
// Token-test request
#define TTrqBaseSize 5
#define TTrqPDUSize (X224_DataHeaderSize + TTrqBaseSize)
// Token-test confirm
#define TTcfBaseSize 6
#define TTcfPDUSize (X224_DataHeaderSize + TTcfBaseSize)
/*
* Utility macros and prototypes for decoding and encoding domain PDUs.
*/
#define GetByteswappedShort(pStartByte) \
((*(pStartByte) << 8) + *((pStartByte) + 1))
#define PutByteswappedShort(pStartByte, Val) \
{ \
*(pStartByte) = ((Val) & 0xFF00) >> 8; \
*((pStartByte) + 1) = (Val) & 0x00FF; \
}
// Regular Channel ID -- 0..65535: 16 bits.
#define GetChannelID(pStartByte) GetByteswappedShort(pStartByte)
#define PutChannelID(pStartByte, ChID) PutByteswappedShort(pStartByte, ChID)
// Dynamic Channel ID -- 1001..65535: 16 bits, advanced to offset 1001.
#define GetDynamicChannelID(pStartByte) \
((GetByteswappedShort(pStartByte)) + 1001)
#define PutDynamicChannelID(pStartByte, DChID) \
PutByteswappedShort(pStartByte, (DChID) - 1001)
// Token ID -- 0..65535: 16 bits.
#define GetTokenID(pStartByte) GetByteswappedShort(pStartByte)
#define PutTokenID(pStartByte, TokID) PutByteswappedShort(pStartByte, TokID)
// User ID -- same as dynamic channel ID.
#define GetUserID(pStartByte) GetDynamicChannelID(pStartByte)
#define PutUserID(pStartByte, UsrID) PutDynamicChannelID(pStartByte, UsrID)
// Private channel ID -- same as dynamic channel ID.
#define GetPrivateChannelID(pStartByte) GetDynamicChannelID(pStartByte)
#define PutPrivateChannelID(pStartByte, PrvChID) \
PutDynamicChannelID(pStartByte, PrvChID)
// Reason field.
#define Get3BitFieldAtBit1(pStartByte) \
(((*(pStartByte) & 0x03) << 1) + ((*((pStartByte) + 1) & 0x80) >> 7))
#define Put3BitFieldAtBit1(pStartByte, Val) \
{ \
*(pStartByte) |= (((Val) & 0x06) >> 1); \
*((pStartByte) + 1) |= (((Val) & 0x01) << 7); \
}
// Result and Diagnostic fields in various PDUs.
#define Get4BitFieldAtBit0(pStartByte) \
(((*(pStartByte) & 0x01) << 3) + ((*((pStartByte) + 1) & 0xE0) >> 5))
#define Put4BitFieldAtBit0(pStartByte, Val) \
{ \
*(pStartByte) |= (((Val) & 0x08) >> 3); \
*((pStartByte) + 1) |= (((Val) & 0x07) << 5); \
}
#define Get4BitFieldAtBit1(pStartByte) \
(((*(pStartByte) & 0x03) << 2) + ((*((pStartByte) + 1) & 0xC0) >> 6))
#define Put4BitFieldAtBit1(pStartByte, Val) \
{ \
*(pStartByte) |= (((Val) & 0x0C) >> 2); \
*((pStartByte) + 1) |= (((Val) & 0x03) << 6); \
}
//
// Input buffer allocations are biased to be 8 bytes bigger
// than necessary because the decompression code prefetches
// bytes from after the end of the input buffer.
// It's evil, but it avoids a lot of branches in perf critical code.
// NOTE: We could change the decompression code to check for buffer
// end but it is performance critical so we're not touching it.
//
#define INPUT_BUFFER_BIAS 8
// T.120 request dispatch function signature.
typedef NTSTATUS (*PT120RequestFunc)(PDomain, PSD_IOCTL);
// PDU dispatch table entries.
typedef struct {
#if DBG
char *Name;
#endif
BOOLEAN (__fastcall *HandlePDUFunc)(Domain *, BYTE *, unsigned, unsigned *);
} MCSPDUInfo;
/*
* Globals
*/
// Dispatch table defined in MCSCalls.c.
extern const PT120RequestFunc g_T120RequestDispatch[];
// PDU dispatch table defined in ConPDU.c.
extern const MCSPDUInfo ConnectPDUTable[];
// PDU dispatch table defined in DomPDU.c.
extern const MCSPDUInfo DomainPDUTable[];
/*
* Prototypes.
*/
// Defined in Decode.c.
NTSTATUS SendX224Confirm(Domain *);
// Defined in DomPDU.c.
void __fastcall EncodeLengthDeterminantPER(BYTE *, unsigned, unsigned *,
BOOLEAN *, unsigned *);
void CreatePlumbDomainInd(unsigned short, BYTE *);
void CreateDisconnectProviderUlt(int, BYTE *);
NTSTATUS ReturnRejectPDU(PDomain, int, BYTE *, unsigned);
void CreateRejectMCSPDUUlt(int, BYTE *, unsigned, BYTE *);
void CreateAttachUserCon(int, BOOLEAN, UserID, BYTE *);
void CreateDetachUserInd(MCSReason, int, UserID *, BYTE *);
void CreateChannelJoinCon(int, UserID, ChannelID, BOOLEAN, ChannelID, BYTE *);
void CreateChannelConveneCon(MCSResult, UserID, BOOLEAN, ChannelID, BYTE *);
void CreateSendDataPDUHeader(int, UserID, ChannelID, MCSPriority,
Segmentation, BYTE **, unsigned *);
BOOLEAN __fastcall HandleAllSendDataPDUs(PDomain, BYTE *, unsigned, unsigned *);
// Defined in TokenPDU.c.
void CreateTokenCon(int, int, UserID, TokenID, int, BYTE *);
void CreateTokenTestCon(UserID, TokenID, int, BYTE *);
// Defined in MCSCore.c.
ChannelID GetNewDynamicChannel(Domain *);
MCSError DetachUser(Domain *, UserHandle, MCSReason, BOOLEAN);
MCSError ChannelLeave(UserHandle, ChannelHandle, BOOLEAN *);
NTSTATUS DisconnectProvider(PDomain, BOOLEAN, MCSReason);
NTSTATUS SendOutBuf(Domain *, POUTBUF);
// Defined in ConPDU.c.
void CreateConnectResponseHeader(PSDCONTEXT, MCSResult, int,
DomainParameters *, unsigned, BYTE *, unsigned *);
// Defined in IcaIFace.c.
void SignalBrokenConnection(Domain *);
#endif // !defined(__MCSIMPL_H)