libfreerdp-core: refactor all RTS command write functions not to use STREAM utils
This commit is contained in:
parent
fe1269f1a1
commit
90188e16ad
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user