libfreerdp-core: refactor all RTS command write functions not to use STREAM utils

This commit is contained in:
Marc-André Moreau 2012-11-15 16:25:22 -05:00
parent fe1269f1a1
commit 90188e16ad
6 changed files with 317 additions and 256 deletions

View File

@ -77,6 +77,8 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm);
BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL confidentiality, char* user, char* domain, char* password);
void ntlm_client_uninit(rdpNtlm* ntlm);
BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname);
rdpNtlm* ntlm_new();
void ntlm_free(rdpNtlm* ntlm);

View File

@ -214,50 +214,47 @@ const RPC_FAULT_CODE RPC_FAULT_CODES[] =
{ 0, NULL }
};
void rpc_pdu_header_print(RPC_PDU_HEADER* header)
void rpc_pdu_header_print(rpcconn_hdr_t* header)
{
printf("rpc_vers: %d\n", header->rpc_vers);
printf("rpc_vers_minor: %d\n", header->rpc_vers_minor);
printf("rpc_vers: %d\n", header->common.rpc_vers);
printf("rpc_vers_minor: %d\n", header->common.rpc_vers_minor);
if (header->ptype > PTYPE_RTS)
printf("ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->ptype);
if (header->common.ptype > PTYPE_RTS)
printf("ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->common.ptype);
else
printf("ptype: %s (%d)\n", PTYPE_STRINGS[header->ptype], header->ptype);
printf("ptype: %s (%d)\n", PTYPE_STRINGS[header->common.ptype], header->common.ptype);
printf("pfc_flags (0x%02X) = {", header->pfc_flags);
if (header->pfc_flags & PFC_FIRST_FRAG)
printf("pfc_flags (0x%02X) = {", header->common.pfc_flags);
if (header->common.pfc_flags & PFC_FIRST_FRAG)
printf(" PFC_FIRST_FRAG");
if (header->pfc_flags & PFC_LAST_FRAG)
if (header->common.pfc_flags & PFC_LAST_FRAG)
printf(" PFC_LAST_FRAG");
if (header->pfc_flags & PFC_PENDING_CANCEL)
if (header->common.pfc_flags & PFC_PENDING_CANCEL)
printf(" PFC_PENDING_CANCEL");
if (header->pfc_flags & PFC_RESERVED_1)
if (header->common.pfc_flags & PFC_RESERVED_1)
printf(" PFC_RESERVED_1");
if (header->pfc_flags & PFC_CONC_MPX)
if (header->common.pfc_flags & PFC_CONC_MPX)
printf(" PFC_CONC_MPX");
if (header->pfc_flags & PFC_DID_NOT_EXECUTE)
if (header->common.pfc_flags & PFC_DID_NOT_EXECUTE)
printf(" PFC_DID_NOT_EXECUTE");
if (header->pfc_flags & PFC_OBJECT_UUID)
if (header->common.pfc_flags & PFC_OBJECT_UUID)
printf(" PFC_OBJECT_UUID");
printf(" }\n");
printf("packed_drep[4]: %02X %02X %02X %02X\n",
header->packed_drep[0], header->packed_drep[1],
header->packed_drep[2], header->packed_drep[3]);
header->common.packed_drep[0], header->common.packed_drep[1],
header->common.packed_drep[2], header->common.packed_drep[3]);
printf("frag_length: %d\n", header->frag_length);
printf("auth_length: %d\n", header->auth_length);
printf("call_id: %d\n", header->call_id);
printf("frag_length: %d\n", header->common.frag_length);
printf("auth_length: %d\n", header->common.auth_length);
printf("call_id: %d\n", header->common.call_id);
if (header->ptype == PTYPE_RESPONSE)
if (header->common.ptype == PTYPE_RESPONSE)
{
rpcconn_response_hdr_t* response;
response = (rpcconn_response_hdr_t*) header;
printf("alloc_hint: %d\n", response->alloc_hint);
printf("p_cont_id: %d\n", response->p_cont_id);
printf("cancel_count: %d\n", response->cancel_count);
printf("reserved: %d\n", response->reserved);
printf("alloc_hint: %d\n", header->response.alloc_hint);
printf("p_cont_id: %d\n", header->response.p_cont_id);
printf("cancel_count: %d\n", header->response.cancel_count);
printf("reserved: %d\n", header->response.reserved);
}
}
@ -426,21 +423,21 @@ BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc)
return TRUE;
}
void rpc_pdu_header_init(rdpRpc* rpc, RPC_PDU_HEADER* header)
void rpc_pdu_header_init(rdpRpc* rpc, rpcconn_hdr_t* header)
{
header->rpc_vers = rpc->rpc_vers;
header->rpc_vers_minor = rpc->rpc_vers_minor;
header->packed_drep[0] = rpc->packed_drep[0];
header->packed_drep[1] = rpc->packed_drep[1];
header->packed_drep[2] = rpc->packed_drep[2];
header->packed_drep[3] = rpc->packed_drep[3];
header->common.rpc_vers = rpc->rpc_vers;
header->common.rpc_vers_minor = rpc->rpc_vers_minor;
header->common.packed_drep[0] = rpc->packed_drep[0];
header->common.packed_drep[1] = rpc->packed_drep[1];
header->common.packed_drep[2] = rpc->packed_drep[2];
header->common.packed_drep[3] = rpc->packed_drep[3];
}
int rpc_out_write(rdpRpc* rpc, BYTE* data, int length)
{
int status;
rpc_pdu_header_print((RPC_PDU_HEADER*) data);
rpc_pdu_header_print((rpcconn_hdr_t*) data);
#ifdef WITH_DEBUG_RPC
printf("rpc_out_write(): length: %d\n", length);
@ -457,7 +454,7 @@ int rpc_in_write(rdpRpc* rpc, BYTE* data, int length)
{
int status;
rpc_pdu_header_print((RPC_PDU_HEADER*) data);
rpc_pdu_header_print((rpcconn_hdr_t*) data);
#ifdef WITH_DEBUG_RPC
printf("rpc_in_write() length: %d\n", length);
@ -509,7 +506,7 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc)
bind_pdu = (rpcconn_bind_hdr_t*) malloc(sizeof(rpcconn_bind_hdr_t));
ZeroMemory(bind_pdu, sizeof(rpcconn_bind_hdr_t));
rpc_pdu_header_init(rpc, (RPC_PDU_HEADER*) bind_pdu);
rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) bind_pdu);
bind_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer;
bind_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer;
@ -518,8 +515,8 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc)
bind_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_PENDING_CANCEL | PFC_CONC_MPX;
bind_pdu->call_id = 2;
bind_pdu->max_xmit_frag = 0x0FF8;
bind_pdu->max_recv_frag = 0x0FF8;
bind_pdu->max_xmit_frag = rpc->max_xmit_frag;
bind_pdu->max_recv_frag = rpc->max_recv_frag;
bind_pdu->assoc_group_id = 0;
bind_pdu->p_context_elem.n_context_elem = 2;
@ -594,19 +591,19 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc)
{
int status;
BYTE* auth_data;
RPC_PDU_HEADER* header;
rpcconn_hdr_t* header;
status = rpc_recv_pdu(rpc);
if (status > 0)
{
header = (RPC_PDU_HEADER*) rpc->buffer;
header = (rpcconn_hdr_t*) rpc->buffer;
rpc->ntlm->inputBuffer.cbBuffer = header->auth_length;
rpc->ntlm->inputBuffer.pvBuffer = malloc(header->auth_length);
rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length;
rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.auth_length);
auth_data = rpc->buffer + (header->frag_length - header->auth_length);
CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->auth_length);
auth_data = rpc->buffer + (header->common.frag_length - header->common.auth_length);
CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->common.auth_length);
ntlm_authenticate(rpc->ntlm);
}
@ -625,7 +622,7 @@ BOOL rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
auth_3_pdu = (rpcconn_rpc_auth_3_hdr_t*) malloc(sizeof(rpcconn_rpc_auth_3_hdr_t));
ZeroMemory(auth_3_pdu, sizeof(rpcconn_rpc_auth_3_hdr_t));
rpc_pdu_header_init(rpc, (RPC_PDU_HEADER*) auth_3_pdu);
rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) auth_3_pdu);
auth_3_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer;
auth_3_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer;
@ -636,8 +633,8 @@ BOOL rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
offset = 20;
auth_3_pdu->max_xmit_frag = 0x0FF8;
auth_3_pdu->max_recv_frag = 0x0FF8;
auth_3_pdu->max_xmit_frag = rpc->max_xmit_frag;
auth_3_pdu->max_recv_frag = rpc->max_recv_frag;
offset += 4;
auth_3_pdu->auth_verifier.auth_pad_length = rpc_offset_align(&offset, 4);
@ -672,7 +669,7 @@ BOOL rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
int rpc_out_read(rdpRpc* rpc, BYTE* data, int length)
{
int status;
RPC_PDU_HEADER* header;
rpcconn_hdr_t* header;
//if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < 0x00008FFF) /* Just a simple workaround */
// rts_send_flow_control_ack_pdu(rpc); /* Send FlowControlAck every time AvailableWindow reaches the half */
@ -683,16 +680,16 @@ int rpc_out_read(rdpRpc* rpc, BYTE* data, int length)
if (status <= 0)
return status;
header = (RPC_PDU_HEADER*) data;
header = (rpcconn_hdr_t*) data;
rpc_pdu_header_print(header);
status = tls_read(rpc->TlsOut, &data[20], header->frag_length - 20);
status = tls_read(rpc->TlsOut, &data[20], header->common.frag_length - 20);
if (status < 0)
return status;
if (header->ptype == PTYPE_RTS) /* RTS PDU */
if (header->common.ptype == PTYPE_RTS) /* RTS PDU */
{
printf("rpc_out_read error: Unexpected RTS PDU\n");
return -1;
@ -700,76 +697,74 @@ int rpc_out_read(rdpRpc* rpc, BYTE* data, int length)
else
{
/* RTS PDUs are not subject to flow control */
rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->frag_length;
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->frag_length;
rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length;
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length;
}
if (length < header->frag_length)
if (length < header->common.frag_length)
{
printf("rpc_out_read error! receive buffer is not large enough: %d < %d\n", length, header->frag_length);
printf("rpc_out_read error! receive buffer is not large enough: %d < %d\n",
length, header->common.frag_length);
return -1;
}
#ifdef WITH_DEBUG_RPC
printf("rpc_out_read(): length: %d\n", header->frag_length);
freerdp_hexdump(data, header->frag_length);
printf("rpc_out_read(): length: %d\n", header->common.frag_length);
freerdp_hexdump(data, header->common.frag_length);
printf("\n");
#endif
return header->frag_length;
return header->common.frag_length;
}
int rpc_recv_fault_pdu(RPC_PDU_HEADER* header)
int rpc_recv_fault_pdu(rpcconn_hdr_t* header)
{
int index;
rpcconn_fault_hdr_t* fault_pdu;
fault_pdu = (rpcconn_fault_hdr_t*) header;
printf("RPC Fault PDU:\n");
for (index = 0; RPC_FAULT_CODES[index].name != NULL; index++)
{
if (RPC_FAULT_CODES[index].code == fault_pdu->status)
if (RPC_FAULT_CODES[index].code == header->fault.status)
{
printf("status: %s (0x%08X)\n", RPC_FAULT_CODES[index].name, fault_pdu->status);
printf("status: %s (0x%08X)\n", RPC_FAULT_CODES[index].name, header->fault.status);
return 0;
}
}
for (index = 0; RPC_FAULT_CODES[index].name != NULL; index++)
{
if (RPC_TSG_FAULT_CODES[index].code == fault_pdu->status)
if (RPC_TSG_FAULT_CODES[index].code == header->fault.status)
{
printf("status: %s (0x%08X)\n", RPC_TSG_FAULT_CODES[index].name, fault_pdu->status);
printf("status: %s (0x%08X)\n", RPC_TSG_FAULT_CODES[index].name, header->fault.status);
return 0;
}
}
printf("status: %s (0x%08X)\n", "UNKNOWN", fault_pdu->status);
printf("status: %s (0x%08X)\n", "UNKNOWN", header->fault.status);
return 0;
}
BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* length)
BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* length)
{
UINT32 alloc_hint = 0;
RPC_PDU_HEADER* pCommonFields;
rpcconn_hdr_t* header;
*offset = RPC_COMMON_FIELDS_LENGTH;
pCommonFields = ((RPC_PDU_HEADER*) header);
header = ((rpcconn_hdr_t*) buffer);
if (pCommonFields->ptype == PTYPE_RESPONSE)
if (header->common.ptype == PTYPE_RESPONSE)
{
*offset += 4;
rpc_offset_align(offset, 8);
alloc_hint = *((UINT32*) &header[16]);
alloc_hint = header->response.alloc_hint;
}
else if (pCommonFields->ptype == PTYPE_REQUEST)
else if (header->common.ptype == PTYPE_REQUEST)
{
*offset += 4;
rpc_offset_align(offset, 8);
alloc_hint = *((UINT32*) &header[16]);
alloc_hint = header->request.alloc_hint;
}
else
{
@ -778,15 +773,10 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* l
if (length)
{
UINT16 frag_length;
UINT16 auth_length;
BYTE auth_pad_length;
frag_length = pCommonFields->frag_length;
auth_length = pCommonFields->auth_length;
auth_pad_length = *(header + frag_length - auth_length - 6);
*length = frag_length - (auth_length + *offset + 8 + auth_pad_length);
auth_pad_length = *(buffer + header->common.frag_length - header->common.auth_length - 6);
*length = header->common.frag_length - (header->common.auth_length + *offset + 8 + auth_pad_length);
}
return TRUE;
@ -815,7 +805,7 @@ int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header)
bytesRead += status;
}
rpc_pdu_header_print((RPC_PDU_HEADER*) header);
rpc_pdu_header_print((rpcconn_hdr_t*) header);
rpc_get_stub_data_info(rpc, header, &offset, NULL);
@ -837,7 +827,7 @@ int rpc_recv_pdu(rdpRpc* rpc)
int status;
int headerLength;
int bytesRead = 0;
RPC_PDU_HEADER* header;
rpcconn_hdr_t* header;
status = rpc_recv_pdu_header(rpc, rpc->buffer);
@ -848,19 +838,19 @@ int rpc_recv_pdu(rdpRpc* rpc)
}
headerLength = status;
header = (RPC_PDU_HEADER*) rpc->buffer;
header = (rpcconn_hdr_t*) rpc->buffer;
bytesRead += status;
if (header->frag_length > rpc->length)
if (header->common.frag_length > rpc->length)
{
rpc->length = header->frag_length;
rpc->length = header->common.frag_length;
rpc->buffer = (BYTE*) realloc(rpc->buffer, rpc->length);
header = (RPC_PDU_HEADER*) rpc->buffer;
header = (rpcconn_hdr_t*) rpc->buffer;
}
while (bytesRead < header->frag_length)
while (bytesRead < header->common.frag_length)
{
status = tls_read(rpc->TlsOut, &rpc->buffer[bytesRead], header->frag_length - bytesRead);
status = tls_read(rpc->TlsOut, &rpc->buffer[bytesRead], header->common.frag_length - bytesRead);
if (status < 0)
{
@ -871,17 +861,17 @@ int rpc_recv_pdu(rdpRpc* rpc)
bytesRead += status;
}
if (!(header->pfc_flags & PFC_LAST_FRAG))
if (!(header->common.pfc_flags & PFC_LAST_FRAG))
{
printf("Fragmented PDU\n");
}
if (header->ptype == PTYPE_RTS) /* RTS PDU */
if (header->common.ptype == PTYPE_RTS) /* RTS PDU */
{
printf("rpc_recv_pdu error: Unexpected RTS PDU\n");
return -1;
}
else if (header->ptype == PTYPE_FAULT)
else if (header->common.ptype == PTYPE_FAULT)
{
rpc_recv_fault_pdu(header);
return -1;
@ -889,17 +879,17 @@ int rpc_recv_pdu(rdpRpc* rpc)
else
{
/* RTS PDUs are not subject to flow control */
rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->frag_length;
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->frag_length;
rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length;
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length;
}
#ifdef WITH_DEBUG_RPC
printf("rpc_recv_pdu: length: %d\n", header->frag_length);
freerdp_hexdump(rpc->buffer, header->frag_length);
printf("rpc_recv_pdu: length: %d\n", header->common.frag_length);
freerdp_hexdump(rpc->buffer, header->common.frag_length);
printf("\n");
#endif
return header->frag_length;
return header->common.frag_length;
}
int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
@ -925,7 +915,7 @@ int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
request_pdu = (rpcconn_request_hdr_t*) malloc(sizeof(rpcconn_request_hdr_t));
ZeroMemory(request_pdu, sizeof(rpcconn_request_hdr_t));
rpc_pdu_header_init(rpc, (RPC_PDU_HEADER*) request_pdu);
rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) request_pdu);
request_pdu->ptype = PTYPE_REQUEST;
request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
@ -1013,22 +1003,6 @@ int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
return length;
}
int rpc_read(rdpRpc* rpc, BYTE* data, int length)
{
int status;
RPC_PDU_HEADER header;
status = rpc_out_read(rpc, data, length);
if (status > 0)
{
CopyMemory(&header, data, 20);
status = rpc_out_read(rpc, data, header.frag_length - 20);
}
return status;
}
BOOL rpc_connect(rdpRpc* rpc)
{
rpc->TlsIn = rpc->transport->TlsIn;
@ -1183,6 +1157,9 @@ rdpRpc* rpc_new(rdpTransport* transport)
rpc->packed_drep[2] = 0x00;
rpc->packed_drep[3] = 0x00;
rpc->max_xmit_frag = 0x0FF8;
rpc->max_recv_frag = 0x0FF8;
rpc->ReceiveWindow = 0x00010000;
rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);

View File

@ -24,6 +24,18 @@
typedef struct rdp_rpc rdpRpc;
#define DEFINE_RPC_COMMON_FIELDS() \
BYTE rpc_vers; \
BYTE rpc_vers_minor; \
BYTE ptype; \
BYTE pfc_flags; \
BYTE packed_drep[4]; \
UINT16 frag_length; \
UINT16 auth_length; \
UINT32 call_id
#define RPC_COMMON_FIELDS_LENGTH 20
#include "tcp.h"
#include "rts.h"
#include "http.h"
@ -50,17 +62,40 @@ typedef struct rdp_rpc rdpRpc;
* http://pubs.opengroup.org/onlinepubs/9629399/
*/
#define DEFINE_RPC_COMMON_FIELDS() \
BYTE rpc_vers; \
BYTE rpc_vers_minor; \
BYTE ptype; \
BYTE pfc_flags; \
BYTE packed_drep[4]; \
UINT16 frag_length; \
UINT16 auth_length; \
UINT32 call_id
#define PTYPE_REQUEST 0x00
#define PTYPE_PING 0x01
#define PTYPE_RESPONSE 0x02
#define PTYPE_FAULT 0x03
#define PTYPE_WORKING 0x04
#define PTYPE_NOCALL 0x05
#define PTYPE_REJECT 0x06
#define PTYPE_ACK 0x07
#define PTYPE_CL_CANCEL 0x08
#define PTYPE_FACK 0x09
#define PTYPE_CANCEL_ACK 0x0A
#define PTYPE_BIND 0x0B
#define PTYPE_BIND_ACK 0x0C
#define PTYPE_BIND_NAK 0x0D
#define PTYPE_ALTER_CONTEXT 0x0E
#define PTYPE_ALTER_CONTEXT_RESP 0x0F
#define PTYPE_RPC_AUTH_3 0x10
#define PTYPE_SHUTDOWN 0x11
#define PTYPE_CO_CANCEL 0x12
#define PTYPE_ORPHANED 0x13
#define PTYPE_RTS 0x14
#define RPC_COMMON_FIELDS_LENGTH 20
#define PFC_FIRST_FRAG 0x01
#define PFC_LAST_FRAG 0x02
#define PFC_PENDING_CANCEL 0x04
#define PFC_RESERVED_1 0x08
#define PFC_CONC_MPX 0x10
#define PFC_DID_NOT_EXECUTE 0x20
#define PFC_MAYBE 0x40
#define PFC_OBJECT_UUID 0x80
/* Minimum fragment sizes */
#define RPC_CO_MUST_RECV_FRAG_SIZE 1432
#define RPC_CL_MUST_RECV_FRAG_SIZE 1464
/**
* The PDU maximum header length is enough
@ -70,11 +105,10 @@ typedef struct rdp_rpc rdpRpc;
*/
#define RPC_PDU_HEADER_MAX_LENGTH 32
struct _rpc_pdu_header
typedef struct
{
DEFINE_RPC_COMMON_FIELDS();
};
typedef struct _rpc_pdu_header RPC_PDU_HEADER;
} rpcconn_common_hdr_t;
typedef UINT16 p_context_id_t;
typedef UINT16 p_reject_reason_t;
@ -464,6 +498,23 @@ typedef struct
DEFINE_RPC_COMMON_FIELDS();
} rpcconn_shutdown_hdr_t;
typedef union
{
rpcconn_common_hdr_t common;
rpcconn_alter_context_hdr_t alter_context;
rpcconn_alter_context_response_hdr_t alter_context_response;
rpcconn_bind_hdr_t bind;
rpcconn_bind_ack_hdr_t bind_ack;
rpcconn_rpc_auth_3_hdr_t rpc_auth_3;
rpcconn_bind_nak_hdr_t bind_nak;
rpcconn_cancel_hdr_t cancel;
rpcconn_fault_hdr_t fault;
rpcconn_orphaned_hdr_t orphaned;
rpcconn_request_hdr_t request;
rpcconn_response_hdr_t response;
rpcconn_shutdown_hdr_t shutdown;
} rpcconn_hdr_t;
enum _TSG_CHANNEL
{
TSG_CHANNEL_IN,
@ -566,6 +617,9 @@ struct rdp_rpc
BYTE rpc_vers_minor;
BYTE packed_drep[4];
UINT16 max_xmit_frag;
UINT16 max_recv_frag;
UINT32 ReceiveWindow;
RpcVirtualConnection* VirtualConnection;
@ -576,7 +630,7 @@ BOOL rpc_connect(rdpRpc* rpc);
BOOL rpc_ntlm_http_out_connect(rdpRpc* rpc);
BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc);
void rpc_pdu_header_init(rdpRpc* rpc, RPC_PDU_HEADER* header);
void rpc_pdu_header_init(rdpRpc* rpc, rpcconn_hdr_t* header);
UINT32 rpc_offset_align(UINT32* offset, UINT32 alignment);
UINT32 rpc_offset_pad(UINT32* offset, UINT32 pad);
@ -591,7 +645,6 @@ int rpc_recv_pdu(rdpRpc* rpc);
int rpc_out_read(rdpRpc* rpc, BYTE* data, int length);
int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum);
int rpc_read(rdpRpc* rpc, BYTE* data, int length);
rdpRpc* rpc_new(rdpTransport* transport);
void rpc_free(rdpRpc* rpc);

View File

@ -21,6 +21,8 @@
#include "config.h"
#endif
#include <winpr/crt.h>
#include "rts.h"
/**
@ -127,6 +129,37 @@ static const char* const RTS_CMD_STRINGS[] =
#endif
/**
* RTS PDU Header
*
* The RTS PDU Header has the same layout as the common header of the connection-oriented RPC
* PDU as specified in [C706] section 12.6.1, with a few additional requirements around the contents
* of the header fields. The additional requirements are as follows:
*
* All fields MUST use little-endian byte order.
*
* Fragmentation MUST NOT occur for an RTS PDU.
*
* PFC_FIRST_FRAG and PFC_LAST_FRAG MUST be present in all RTS PDUs, and all other PFC flags
* MUST NOT be present.
*
* The rpc_vers and rpc_vers_minor fields MUST contain version information as described in
* [MS-RPCE] section 1.7.
*
* PTYPE MUST be set to a value of 20 (0x14). This field differentiates RTS packets from other RPC packets.
*
* The packed_drep MUST indicate little-endian integer and floating-pointer byte order, IEEE float-point
* format representation, and ASCII character format as specified in [C706] section 12.6.
*
* The auth_length MUST be set to 0.
*
* The frag_length field MUST reflect the size of the header plus the size of all commands, including
* the variable portion of variable-sized commands.
*
* The call_id MUST be set to 0 by senders and MUST be 0 on receipt.
*
*/
void rts_pdu_header_init(rdpRpc* rpc, RTS_PDU_HEADER* header)
{
header->rpc_vers = rpc->rpc_vers;
@ -142,10 +175,11 @@ void rts_receive_window_size_command_read(rdpRpc* rpc, STREAM* s)
stream_seek_UINT32(s); /* ReceiveWindowSize (4 bytes) */
}
void rts_receive_window_size_command_write(STREAM* s, UINT32 ReceiveWindowSize)
int rts_receive_window_size_command_write(BYTE* buffer, UINT32 ReceiveWindowSize)
{
stream_write_UINT32(s, RTS_CMD_RECEIVE_WINDOW_SIZE); /* CommandType (4 bytes) */
stream_write_UINT32(s, ReceiveWindowSize); /* ReceiveWindowSize (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_RECEIVE_WINDOW_SIZE; /* CommandType (4 bytes) */
*((UINT32*) &buffer[4]) = ReceiveWindowSize; /* ReceiveWindowSize (4 bytes) */
return 8;
}
void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s)
@ -156,14 +190,16 @@ void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s)
stream_seek(s, 16); /* ChannelCookie (16 bytes) */
}
void rts_flow_control_ack_command_write(STREAM* s, UINT32 BytesReceived, UINT32 AvailableWindow, BYTE* ChannelCookie)
int rts_flow_control_ack_command_write(BYTE* buffer, UINT32 BytesReceived, UINT32 AvailableWindow, BYTE* ChannelCookie)
{
stream_write_UINT32(s, RTS_CMD_FLOW_CONTROL_ACK); /* CommandType (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_FLOW_CONTROL_ACK; /* CommandType (4 bytes) */
/* Ack (24 bytes) */
stream_write_UINT32(s, BytesReceived); /* BytesReceived (4 bytes) */
stream_write_UINT32(s, AvailableWindow); /* AvailableWindow (4 bytes) */
stream_write(s, ChannelCookie, 16); /* ChannelCookie (16 bytes) */
*((UINT32*) &buffer[4]) = BytesReceived; /* BytesReceived (4 bytes) */
*((UINT32*) &buffer[8]) = AvailableWindow; /* AvailableWindow (4 bytes) */
CopyMemory(&buffer[12], ChannelCookie, 16); /* ChannelCookie (16 bytes) */
return 28;
}
void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s)
@ -171,10 +207,11 @@ void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s)
stream_seek_UINT32(s); /* ConnectionTimeout (4 bytes) */
}
void rts_connection_timeout_command_write(STREAM* s, UINT32 ConnectionTimeout)
int rts_connection_timeout_command_write(BYTE* buffer, UINT32 ConnectionTimeout)
{
stream_write_UINT32(s, RTS_CMD_CONNECTION_TIMEOUT); /* CommandType (4 bytes) */
stream_write_UINT32(s, ConnectionTimeout); /* ConnectionTimeout (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_CONNECTION_TIMEOUT; /* CommandType (4 bytes) */
*((UINT32*) &buffer[4]) = ConnectionTimeout; /* ConnectionTimeout (4 bytes) */
return 8;
}
void rts_cookie_command_read(rdpRpc* rpc, STREAM* s)
@ -182,10 +219,11 @@ void rts_cookie_command_read(rdpRpc* rpc, STREAM* s)
stream_seek(s, 16); /* Cookie (16 bytes) */
}
void rts_cookie_command_write(STREAM* s, BYTE* Cookie)
int rts_cookie_command_write(BYTE* buffer, BYTE* Cookie)
{
stream_write_UINT32(s, RTS_CMD_COOKIE); /* CommandType (4 bytes) */
stream_write(s, Cookie, 16); /* Cookie (16 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_COOKIE; /* CommandType (4 bytes) */
CopyMemory(&buffer[4], Cookie, 16); /* Cookie (16 bytes) */
return 20;
}
void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s)
@ -193,10 +231,11 @@ void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s)
stream_seek_UINT32(s); /* ChannelLifetime (4 bytes) */
}
void rts_channel_lifetime_command_write(STREAM* s, UINT32 ChannelLifetime)
int rts_channel_lifetime_command_write(BYTE* buffer, UINT32 ChannelLifetime)
{
stream_write_UINT32(s, RTS_CMD_CHANNEL_LIFETIME); /* CommandType (4 bytes) */
stream_write_UINT32(s, ChannelLifetime); /* ChannelLifetime (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_CHANNEL_LIFETIME; /* CommandType (4 bytes) */
*((UINT32*) &buffer[4]) = ChannelLifetime; /* ChannelLifetime (4 bytes) */
return 8;
}
void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s)
@ -204,10 +243,11 @@ void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s)
stream_seek_UINT32(s); /* ClientKeepalive (4 bytes) */
}
void rts_client_keepalive_command_write(STREAM* s, UINT32 ClientKeepalive)
int rts_client_keepalive_command_write(BYTE* buffer, UINT32 ClientKeepalive)
{
stream_write_UINT32(s, RTS_CMD_CLIENT_KEEPALIVE); /* CommandType (4 bytes) */
stream_write_UINT32(s, ClientKeepalive); /* ClientKeepalive (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_CLIENT_KEEPALIVE; /* CommandType (4 bytes) */
*((UINT32*) &buffer[4]) = ClientKeepalive; /* ClientKeepalive (4 bytes) */
return 8;
}
void rts_version_command_read(rdpRpc* rpc, STREAM* s)
@ -215,10 +255,11 @@ void rts_version_command_read(rdpRpc* rpc, STREAM* s)
stream_seek_UINT32(s); /* Version (4 bytes) */
}
void rts_version_command_write(STREAM* s)
int rts_version_command_write(BYTE* buffer)
{
stream_write_UINT32(s, RTS_CMD_VERSION); /* CommandType (4 bytes) */
stream_write_UINT32(s, 1); /* Version (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_VERSION; /* CommandType (4 bytes) */
*((UINT32*) &buffer[4]) = 1; /* Version (4 bytes) */
return 8;
}
void rts_empty_command_read(rdpRpc* rpc, STREAM* s)
@ -226,9 +267,10 @@ void rts_empty_command_read(rdpRpc* rpc, STREAM* s)
}
void rts_empty_command_write(STREAM* s)
int rts_empty_command_write(BYTE* buffer)
{
stream_write_UINT32(s, RTS_CMD_EMPTY); /* CommandType (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_EMPTY; /* CommandType (4 bytes) */
return 4;
}
void rts_padding_command_read(rdpRpc* rpc, STREAM* s)
@ -239,10 +281,12 @@ void rts_padding_command_read(rdpRpc* rpc, STREAM* s)
stream_seek(s, ConformanceCount); /* Padding (variable) */
}
void rts_padding_command_write(STREAM* s, UINT32 ConformanceCount)
int rts_padding_command_write(BYTE* buffer, UINT32 ConformanceCount)
{
stream_write_UINT32(s, ConformanceCount); /* ConformanceCount (4 bytes) */
stream_write_zero(s, ConformanceCount); /* Padding (variable) */
*((UINT32*) &buffer[0]) = RTS_CMD_PADDING; /* CommandType (4 bytes) */
*((UINT32*) &buffer[4]) = ConformanceCount; /* ConformanceCount (4 bytes) */
ZeroMemory(&buffer[8], ConformanceCount); /* Padding (variable) */
return 8 + ConformanceCount;
}
void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s)
@ -250,9 +294,10 @@ void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s)
}
void rts_negative_ance_command_write(STREAM* s)
int rts_negative_ance_command_write(BYTE* buffer)
{
stream_write_UINT32(s, RTS_CMD_NEGATIVE_ANCE); /* CommandType (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_NEGATIVE_ANCE; /* CommandType (4 bytes) */
return 4;
}
void rts_ance_command_read(rdpRpc* rpc, STREAM* s)
@ -260,9 +305,10 @@ void rts_ance_command_read(rdpRpc* rpc, STREAM* s)
}
void rts_ance_command_write(STREAM* s)
int rts_ance_command_write(BYTE* buffer)
{
stream_write_UINT32(s, RTS_CMD_ANCE); /* CommandType (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_ANCE; /* CommandType (4 bytes) */
return 4;
}
void rts_client_address_command_read(rdpRpc* rpc, STREAM* s)
@ -283,21 +329,23 @@ void rts_client_address_command_read(rdpRpc* rpc, STREAM* s)
stream_seek(s, 12); /* padding (12 bytes) */
}
void rts_client_address_command_write(STREAM* s, UINT32 AddressType, BYTE* ClientAddress)
int rts_client_address_command_write(BYTE* buffer, UINT32 AddressType, BYTE* ClientAddress)
{
stream_write_UINT32(s, RTS_CMD_CLIENT_ADDRESS); /* CommandType (4 bytes) */
stream_write_UINT32(s, AddressType); /* AddressType (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_CLIENT_ADDRESS; /* CommandType (4 bytes) */
*((UINT32*) &buffer[4]) = AddressType; /* AddressType (4 bytes) */
if (AddressType == 0)
{
stream_write(s, ClientAddress, 4); /* ClientAddress (4 bytes) */
CopyMemory(&buffer[8], ClientAddress, 4); /* ClientAddress (4 bytes) */
ZeroMemory(&buffer[12], 12); /* padding (12 bytes) */
return 24;
}
else
{
stream_write(s, ClientAddress, 16); /* ClientAddress (16 bytes) */
CopyMemory(&buffer[8], ClientAddress, 16); /* ClientAddress (16 bytes) */
ZeroMemory(&buffer[24], 12); /* padding (12 bytes) */
return 36;
}
stream_write_zero(s, 12); /* padding (12 bytes) */
}
void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s)
@ -305,10 +353,11 @@ void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s)
stream_seek(s, 16); /* AssociationGroupId (16 bytes) */
}
void rts_association_group_id_command_write(STREAM* s, BYTE* associationGroupId)
int rts_association_group_id_command_write(BYTE* buffer, BYTE* AssociationGroupId)
{
stream_write_UINT32(s, RTS_CMD_ASSOCIATION_GROUP_ID); /* CommandType (4 bytes) */
stream_write(s, associationGroupId, 16); /* AssociationGroupId (16 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_ASSOCIATION_GROUP_ID; /* CommandType (4 bytes) */
CopyMemory(&buffer[4], AssociationGroupId, 16); /* AssociationGroupId (16 bytes) */
return 20;
}
void rts_destination_command_read(rdpRpc* rpc, STREAM* s)
@ -316,10 +365,11 @@ void rts_destination_command_read(rdpRpc* rpc, STREAM* s)
stream_seek_UINT32(s); /* Destination (4 bytes) */
}
void rts_destination_command_write(STREAM* s, UINT32 Destination)
int rts_destination_command_write(BYTE* buffer, UINT32 Destination)
{
stream_write_UINT32(s, RTS_CMD_DESTINATION); /* CommandType (4 bytes) */
stream_write_UINT32(s, Destination); /* Destination (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_DESTINATION; /* CommandType (4 bytes) */
*((UINT32*) &buffer[4]) = Destination; /* Destination (4 bytes) */
return 8;
}
void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s)
@ -327,10 +377,11 @@ void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s)
stream_seek_UINT32(s); /* PingTrafficSent (4 bytes) */
}
void rts_ping_traffic_sent_notify_command_write(STREAM* s, UINT32 PingTrafficSent)
int rts_ping_traffic_sent_notify_command_write(BYTE* buffer, UINT32 PingTrafficSent)
{
stream_write_UINT32(s, RTS_CMD_PING_TRAFFIC_SENT_NOTIFY); /* CommandType (4 bytes) */
stream_write_UINT32(s, PingTrafficSent); /* PingTrafficSent (4 bytes) */
*((UINT32*) &buffer[0]) = RTS_CMD_PING_TRAFFIC_SENT_NOTIFY; /* CommandType (4 bytes) */
*((UINT32*) &buffer[4]) = PingTrafficSent; /* PingTrafficSent (4 bytes) */
return 8;
}
void rts_generate_cookie(BYTE* cookie)
@ -368,10 +419,10 @@ BOOL rts_send_CONN_A1_pdu(rdpRpc* rpc)
ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow;
stream_write(s, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
rts_version_command_write(s); /* Version (8 bytes) */
rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
rts_cookie_command_write(s, OUTChannelCookie); /* OUTChannelCookie (20 bytes) */
rts_receive_window_size_command_write(s, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
s->p += rts_version_command_write(s->p); /* Version (8 bytes) */
s->p += rts_cookie_command_write(s->p, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
s->p += rts_cookie_command_write(s->p, OUTChannelCookie); /* OUTChannelCookie (20 bytes) */
s->p += rts_receive_window_size_command_write(s->p, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */
stream_seal(s);
rpc_out_write(rpc, s->data, s->size);
@ -411,12 +462,12 @@ BOOL rts_send_CONN_B1_pdu(rdpRpc* rpc)
AssociationGroupId = (BYTE*) &(rpc->VirtualConnection->AssociationGroupId);
stream_write(s, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
rts_version_command_write(s); /* Version (8 bytes) */
rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
rts_cookie_command_write(s, INChannelCookie); /* INChannelCookie (20 bytes) */
rts_channel_lifetime_command_write(s, 0x40000000); /* ChannelLifetime (8 bytes) */
rts_client_keepalive_command_write(s, 0x000493E0); /* ClientKeepalive (8 bytes) */
rts_association_group_id_command_write(s, AssociationGroupId); /* AssociationGroupId (20 bytes) */
s->p += rts_version_command_write(s->p); /* Version (8 bytes) */
s->p += rts_cookie_command_write(s->p, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */
s->p += rts_cookie_command_write(s->p, INChannelCookie); /* INChannelCookie (20 bytes) */
s->p += rts_channel_lifetime_command_write(s->p, 0x40000000); /* ChannelLifetime (8 bytes) */
s->p += rts_client_keepalive_command_write(s->p, 0x000493E0); /* ClientKeepalive (8 bytes) */
s->p += rts_association_group_id_command_write(s->p, AssociationGroupId); /* AssociationGroupId (20 bytes) */
stream_seal(s);
rpc_in_write(rpc, s->data, s->size);
@ -429,6 +480,7 @@ BOOL rts_send_CONN_B1_pdu(rdpRpc* rpc)
BOOL rts_send_keep_alive_pdu(rdpRpc* rpc)
{
STREAM* s;
BYTE* buffer;
RTS_PDU_HEADER header;
rts_pdu_header_init(rpc, &header);
@ -443,14 +495,13 @@ BOOL rts_send_keep_alive_pdu(rdpRpc* rpc)
DEBUG_RPC("Sending Keep-Alive RTS PDU");
s = stream_new(header.frag_length);
stream_write(s, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
rts_client_keepalive_command_write(s, 0x00007530); /* ClientKeepalive (8 bytes) */
stream_seal(s);
buffer = (BYTE*) malloc(header.frag_length);
CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
rts_client_keepalive_command_write(&buffer[20], 0x00007530); /* ClientKeepalive (8 bytes) */
rpc_in_write(rpc, s->data, s->size);
rpc_in_write(rpc, buffer, header.frag_length);
stream_free(s);
free(buffer);
return TRUE;
}
@ -481,10 +532,10 @@ BOOL rts_send_flow_control_ack_pdu(rdpRpc* rpc)
s = stream_new(header.frag_length);
stream_write(s, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */
rts_destination_command_write(s, FDOutProxy); /* Destination Command (8 bytes) */
s->p += rts_destination_command_write(s->p, FDOutProxy); /* Destination Command (8 bytes) */
/* FlowControlAck Command (28 bytes) */
rts_flow_control_ack_command_write(s, BytesReceived, AvailableWindow, ChannelCookie);
s->p += rts_flow_control_ack_command_write(s->p, BytesReceived, AvailableWindow, ChannelCookie);
stream_seal(s);

View File

@ -20,48 +20,20 @@
#ifndef FREERDP_CORE_RTS_H
#define FREERDP_CORE_RTS_H
#include "rpc.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
typedef struct _rts_pdu RTS_PDU;
typedef struct _rts_pdu_header RTS_PDU_HEADER;
#include "rpc.h"
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/utils/debug.h>
#include <freerdp/utils/stream.h>
#define PTYPE_REQUEST 0x00
#define PTYPE_PING 0x01
#define PTYPE_RESPONSE 0x02
#define PTYPE_FAULT 0x03
#define PTYPE_WORKING 0x04
#define PTYPE_NOCALL 0x05
#define PTYPE_REJECT 0x06
#define PTYPE_ACK 0x07
#define PTYPE_CL_CANCEL 0x08
#define PTYPE_FACK 0x09
#define PTYPE_CANCEL_ACK 0x0A
#define PTYPE_BIND 0x0B
#define PTYPE_BIND_ACK 0x0C
#define PTYPE_BIND_NAK 0x0D
#define PTYPE_ALTER_CONTEXT 0x0E
#define PTYPE_ALTER_CONTEXT_RESP 0x0F
#define PTYPE_RPC_AUTH_3 0x10
#define PTYPE_SHUTDOWN 0x11
#define PTYPE_CO_CANCEL 0x12
#define PTYPE_ORPHANED 0x13
#define PTYPE_RTS 0x14
#define PFC_FIRST_FRAG 0x01
#define PFC_LAST_FRAG 0x02
#define PFC_PENDING_CANCEL 0x04
#define PFC_RESERVED_1 0x08
#define PFC_CONC_MPX 0x10
#define PFC_DID_NOT_EXECUTE 0x20
#define PFC_MAYBE 0x40
#define PFC_OBJECT_UUID 0x80
#define RTS_FLAG_NONE 0x0000
#define RTS_FLAG_PING 0x0001
#define RTS_FLAG_OTHER_CMD 0x0002
@ -94,58 +66,64 @@
struct _rts_pdu_header
{
BYTE rpc_vers;
BYTE rpc_vers_minor;
BYTE ptype;
BYTE pfc_flags;
BYTE packed_drep[4];
UINT16 frag_length;
UINT16 auth_length;
UINT32 call_id;
DEFINE_RPC_COMMON_FIELDS();
UINT16 flags;
UINT16 numberOfCommands;
};
typedef struct _rts_pdu_header RTS_PDU_HEADER;
struct _rts_pdu
{
RTS_PDU_HEADER header;
BYTE* content;
};
typedef struct _rts_pdu RTS_PDU;
BOOL rts_connect(rdpRpc* rpc);
void rts_receive_window_size_command_read(rdpRpc* rpc, STREAM* s);
void rts_receive_window_size_command_write(STREAM* s, UINT32 ReceiveWindowSize);
int rts_receive_window_size_command_write(BYTE* buffer, UINT32 ReceiveWindowSize);
void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s);
void rts_flow_control_ack_command_write(STREAM* s, UINT32 BytesReceived, UINT32 AvailableWindow, BYTE* ChannelCookie);
int rts_flow_control_ack_command_write(BYTE* buffer, UINT32 BytesReceived, UINT32 AvailableWindow, BYTE* ChannelCookie);
void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s);
void rts_connection_timeout_command_write(STREAM* s, UINT32 ConnectionTimeout);
int rts_connection_timeout_command_write(BYTE* buffer, UINT32 ConnectionTimeout);
void rts_cookie_command_read(rdpRpc* rpc, STREAM* s);
void rts_cookie_command_write(STREAM* s, BYTE* Cookie);
int rts_cookie_command_write(BYTE* buffer, BYTE* Cookie);
void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s);
void rts_channel_lifetime_command_write(STREAM* s, UINT32 ChannelLifetime);
int rts_channel_lifetime_command_write(BYTE* buffer, UINT32 ChannelLifetime);
void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s);
void rts_client_keepalive_command_write(STREAM* s, UINT32 ClientKeepalive);
int rts_client_keepalive_command_write(BYTE* buffer, UINT32 ClientKeepalive);
void rts_version_command_read(rdpRpc* rpc, STREAM* s);
void rts_version_command_write(STREAM* s);
int rts_version_command_write(BYTE* buffer);
void rts_empty_command_read(rdpRpc* rpc, STREAM* s);
void rts_empty_command_write(STREAM* s);
int rts_empty_command_write(BYTE* buffer);
void rts_padding_command_read(rdpRpc* rpc, STREAM* s);
void rts_padding_command_write(STREAM* s, UINT32 ConformanceCount);
int rts_padding_command_write(BYTE* buffer, UINT32 ConformanceCount);
void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s);
void rts_negative_ance_command_write(STREAM* s);
int rts_negative_ance_command_write(BYTE* buffer);
void rts_ance_command_read(rdpRpc* rpc, STREAM* s);
void rts_ance_command_write(STREAM* s);
int rts_ance_command_write(BYTE* buffer);
void rts_client_address_command_read(rdpRpc* rpc, STREAM* s);
void rts_client_address_command_write(STREAM* s, UINT32 AddressType, BYTE* ClientAddress);
int rts_client_address_command_write(BYTE* buffer, UINT32 AddressType, BYTE* ClientAddress);
void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s);
void rts_association_group_id_command_write(STREAM* s, BYTE* AssociationGroupId);
int rts_association_group_id_command_write(BYTE* buffer, BYTE* AssociationGroupId);
void rts_destination_command_read(rdpRpc* rpc, STREAM* s);
void rts_destination_command_write(STREAM* s, UINT32 Destination);
int rts_destination_command_write(BYTE* buffer, UINT32 Destination);
void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s);
void rts_ping_traffic_sent_notify_command_write(STREAM* s, UINT32 PingTrafficSent);
int rts_ping_traffic_sent_notify_command_write(BYTE* buffer, UINT32 PingTrafficSent);
BOOL rts_send_CONN_A1_pdu(rdpRpc* rpc);
BOOL rts_send_CONN_B1_pdu(rdpRpc* rpc);

View File

@ -1115,14 +1115,14 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
{
int status;
int CopyLength;
RPC_PDU_HEADER* header;
rpcconn_common_hdr_t* header;
rdpRpc* rpc = tsg->rpc;
printf("tsg_read: %d, pending: %d\n", length, tsg->PendingPdu);
if (tsg->PendingPdu)
{
header = (RPC_PDU_HEADER*) rpc->buffer;
header = (rpcconn_common_hdr_t*) rpc->buffer;
CopyLength = (tsg->BytesAvailable > length) ? length : tsg->BytesAvailable;