libfreerdp-core: encapsulate received RPC PDU

This commit is contained in:
Marc-André Moreau 2012-11-28 21:25:01 -05:00
parent 5faebcd77a
commit 3634a1bbf1
8 changed files with 86 additions and 102 deletions

View File

@ -364,7 +364,7 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc)
return header->common.frag_length; return header->common.frag_length;
printf("Receiving Out-of-Sequence RTS PDU\n"); printf("Receiving Out-of-Sequence RTS PDU\n");
rts_recv_out_of_sequence_pdu(rpc); rts_recv_out_of_sequence_pdu(rpc, rpc->FragBuffer, header->common.frag_length);
return rpc_recv_pdu_fragment(rpc); return rpc_recv_pdu_fragment(rpc);
} }
@ -400,7 +400,7 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc)
return header->common.frag_length; return header->common.frag_length;
} }
int rpc_recv_pdu(rdpRpc* rpc) RPC_PDU* rpc_recv_pdu(rdpRpc* rpc)
{ {
int status; int status;
UINT32 StubOffset; UINT32 StubOffset;
@ -416,7 +416,7 @@ int rpc_recv_pdu(rdpRpc* rpc)
rpc->pdu->Size = rpc->FragBufferSize; rpc->pdu->Size = rpc->FragBufferSize;
rpc->pdu->Length = status; rpc->pdu->Length = status;
return status; return rpc->pdu;
} }
header = (rpcconn_hdr_t*) rpc->FragBuffer; header = (rpcconn_hdr_t*) rpc->FragBuffer;
@ -424,13 +424,13 @@ int rpc_recv_pdu(rdpRpc* rpc)
if (header->common.ptype != PTYPE_RESPONSE) if (header->common.ptype != PTYPE_RESPONSE)
{ {
printf("rpc_recv_pdu: unexpected ptype 0x%02X\n", header->common.ptype); printf("rpc_recv_pdu: unexpected ptype 0x%02X\n", header->common.ptype);
return -1; return NULL;
} }
if (!rpc_get_stub_data_info(rpc, rpc->FragBuffer, &StubOffset, &StubLength)) if (!rpc_get_stub_data_info(rpc, rpc->FragBuffer, &StubOffset, &StubLength))
{ {
printf("rpc_recv_pdu: expected stub\n"); printf("rpc_recv_pdu: expected stub\n");
return -1; return NULL;
} }
if (header->response.alloc_hint > rpc->StubBufferSize) if (header->response.alloc_hint > rpc->StubBufferSize)
@ -466,7 +466,7 @@ int rpc_recv_pdu(rdpRpc* rpc)
rpc->pdu->Size = rpc->StubBufferSize; rpc->pdu->Size = rpc->StubBufferSize;
rpc->pdu->Length = rpc->StubLength; rpc->pdu->Length = rpc->StubLength;
return rpc->StubLength; return rpc->pdu;
} }
return rpc_recv_pdu(rpc); return rpc_recv_pdu(rpc);

View File

@ -23,6 +23,7 @@
#define FREERDP_CORE_RPC_H #define FREERDP_CORE_RPC_H
#include <winpr/wtypes.h> #include <winpr/wtypes.h>
#include <winpr/interlocked.h>
typedef struct rdp_rpc rdpRpc; typedef struct rdp_rpc rdpRpc;
@ -48,6 +49,17 @@ typedef struct
#define RTS_PDU_HEADER_LENGTH 20 #define RTS_PDU_HEADER_LENGTH 20
#define RPC_PDU_FLAG_STUB 0x00000001
typedef struct _RPC_PDU
{
SLIST_ENTRY ItemEntry;
BYTE* Buffer;
UINT32 Size;
UINT32 Length;
DWORD Flags;
} RPC_PDU, *PRPC_PDU;
#include "tcp.h" #include "tcp.h"
#include "rts.h" #include "rts.h"
#include "http.h" #include "http.h"
@ -697,17 +709,6 @@ struct rpc_virtual_connection_cookie_table
}; };
typedef struct rpc_virtual_connection_cookie_table RpcVirtualConnectionCookieTable; typedef struct rpc_virtual_connection_cookie_table RpcVirtualConnectionCookieTable;
#define RPC_PDU_FLAG_STUB 0x00000001
typedef struct _RPC_PDU
{
SLIST_ENTRY ItemEntry;
BYTE* Buffer;
UINT32 Size;
UINT32 Length;
DWORD Flags;
} RPC_PDU, *PRPC_PDU;
struct rpc_client struct rpc_client
{ {
HANDLE Thread; HANDLE Thread;
@ -792,7 +793,7 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* l
int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header); int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header);
int rpc_recv_pdu_fragment(rdpRpc* rpc); int rpc_recv_pdu_fragment(rdpRpc* rpc);
int rpc_recv_pdu(rdpRpc* rpc); RPC_PDU* rpc_recv_pdu(rdpRpc* rpc);
int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum); int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum);

View File

@ -213,29 +213,29 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
int rpc_recv_bind_ack_pdu(rdpRpc* rpc) int rpc_recv_bind_ack_pdu(rdpRpc* rpc)
{ {
int status; RPC_PDU* pdu;
BYTE* auth_data; BYTE* auth_data;
rpcconn_hdr_t* header; rpcconn_hdr_t* header;
status = rpc_recv_pdu(rpc); pdu = rpc_recv_pdu(rpc);
if (status > 0) if (!pdu)
{ return -1;
header = (rpcconn_hdr_t*) rpc->FragBuffer;
rpc->max_recv_frag = header->bind_ack.max_xmit_frag; header = (rpcconn_hdr_t*) pdu->Buffer;
rpc->max_xmit_frag = header->bind_ack.max_recv_frag;
rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length; rpc->max_recv_frag = header->bind_ack.max_xmit_frag;
rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.auth_length); rpc->max_xmit_frag = header->bind_ack.max_recv_frag;
auth_data = rpc->FragBuffer + (header->common.frag_length - header->common.auth_length); rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length;
CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->common.auth_length); rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.auth_length);
ntlm_authenticate(rpc->ntlm); auth_data = pdu->Buffer + (header->common.frag_length - header->common.auth_length);
} CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->common.auth_length);
return status; ntlm_authenticate(rpc->ntlm);
return pdu->Length;
} }
/** /**

View File

@ -87,18 +87,16 @@ int rpc_send_dequeue_pdu(rdpRpc* rpc)
int rpc_recv_enqueue_pdu(rdpRpc* rpc) int rpc_recv_enqueue_pdu(rdpRpc* rpc)
{ {
int status;
RPC_PDU* pdu; RPC_PDU* pdu;
status = rpc_recv_pdu(rpc); pdu = rpc_recv_pdu(rpc);
if (status <= 0) if (!pdu)
{ {
printf("rpc_recv_enqueue_pdu error\n"); printf("rpc_recv_enqueue_pdu error\n");
return -1; return -1;
} }
pdu = rpc->pdu;
rpc->pdu = (RPC_PDU*) _aligned_malloc(sizeof(RPC_PDU), MEMORY_ALLOCATION_ALIGNMENT); rpc->pdu = (RPC_PDU*) _aligned_malloc(sizeof(RPC_PDU), MEMORY_ALLOCATION_ALIGNMENT);
if (pdu->Flags & RPC_PDU_FLAG_STUB) if (pdu->Flags & RPC_PDU_FLAG_STUB)

View File

@ -57,6 +57,7 @@
BOOL rts_connect(rdpRpc* rpc) BOOL rts_connect(rdpRpc* rpc)
{ {
int status; int status;
RPC_PDU* pdu;
rpcconn_rts_hdr_t* rts; rpcconn_rts_hdr_t* rts;
HttpResponse* http_response; HttpResponse* http_response;
@ -173,12 +174,12 @@ BOOL rts_connect(rdpRpc* rpc)
* *
*/ */
status = rpc_recv_pdu(rpc); pdu = rpc_recv_pdu(rpc);
if (status < 1) if (!pdu)
return FALSE; return FALSE;
rts = (rpcconn_rts_hdr_t*) rpc->FragBuffer; rts = (rpcconn_rts_hdr_t*) pdu->Buffer;
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_A3_SIGNATURE, rts)) if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_A3_SIGNATURE, rts))
{ {
@ -186,7 +187,7 @@ BOOL rts_connect(rdpRpc* rpc)
return FALSE; return FALSE;
} }
rts_recv_CONN_A3_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize); rts_recv_CONN_A3_pdu(rpc, pdu->Buffer, pdu->Size);
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_C2; rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_C2;
DEBUG_RTS("VIRTUAL_CONNECTION_STATE_WAIT_C2"); DEBUG_RTS("VIRTUAL_CONNECTION_STATE_WAIT_C2");
@ -212,12 +213,12 @@ BOOL rts_connect(rdpRpc* rpc)
* *
*/ */
status = rpc_recv_pdu(rpc); pdu = rpc_recv_pdu(rpc);
if (status < 1) if (!pdu)
return FALSE; return FALSE;
rts = (rpcconn_rts_hdr_t*) rpc->FragBuffer; rts = (rpcconn_rts_hdr_t*) pdu->Buffer;
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts)) if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts))
{ {
@ -225,7 +226,7 @@ BOOL rts_connect(rdpRpc* rpc)
return FALSE; return FALSE;
} }
rts_recv_CONN_C2_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize); rts_recv_CONN_C2_pdu(rpc, pdu->Buffer, pdu->Size);
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_OPENED; rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_OPENED;
DEBUG_RTS("VIRTUAL_CONNECTION_STATE_OPENED"); DEBUG_RTS("VIRTUAL_CONNECTION_STATE_OPENED");
@ -952,13 +953,13 @@ int rts_command_length(rdpRpc* rpc, UINT32 CommandType, BYTE* buffer, UINT32 len
return CommandLength; return CommandLength;
} }
int rts_recv_out_of_sequence_pdu(rdpRpc* rpc) int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
{ {
UINT32 SignatureId; UINT32 SignatureId;
rpcconn_rts_hdr_t* rts; rpcconn_rts_hdr_t* rts;
RtsPduSignature signature; RtsPduSignature signature;
rts = (rpcconn_rts_hdr_t*) rpc->FragBuffer; rts = (rpcconn_rts_hdr_t*) buffer;
rts_extract_pdu_signature(rpc, &signature, rts); rts_extract_pdu_signature(rpc, &signature, rts);
rts_print_pdu_signature(rpc, &signature); rts_print_pdu_signature(rpc, &signature);
@ -966,11 +967,11 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc)
if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK) if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK)
{ {
return rts_recv_flow_control_ack_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize); return rts_recv_flow_control_ack_pdu(rpc, buffer, length);
} }
else if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION) else if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION)
{ {
return rts_recv_flow_control_ack_with_destination_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize); return rts_recv_flow_control_ack_with_destination_pdu(rpc, buffer, length);
} }
return 0; return 0;

View File

@ -139,7 +139,7 @@ int rts_send_keep_alive_pdu(rdpRpc* rpc);
int rts_send_flow_control_ack_pdu(rdpRpc* rpc); int rts_send_flow_control_ack_pdu(rdpRpc* rpc);
int rts_send_ping_pdu(rdpRpc* rpc); int rts_send_ping_pdu(rdpRpc* rpc);
int rts_recv_out_of_sequence_pdu(rdpRpc* rpc); int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length);
#include "rts_signature.h" #include "rts_signature.h"

View File

@ -198,12 +198,12 @@ BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg)
BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg) BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg)
{ {
int status;
BYTE* buffer; BYTE* buffer;
UINT32 count; UINT32 count;
UINT32 length; UINT32 length;
UINT32 offset; UINT32 offset;
UINT32 Pointer; UINT32 Pointer;
RPC_PDU* pdu;
PTSG_PACKET packet; PTSG_PACKET packet;
UINT32 SwitchValue; UINT32 SwitchValue;
rdpRpc* rpc = tsg->rpc; rdpRpc* rpc = tsg->rpc;
@ -212,13 +212,13 @@ BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg)
PTSG_PACKET_CAPS_RESPONSE packetCapsResponse; PTSG_PACKET_CAPS_RESPONSE packetCapsResponse;
PTSG_PACKET_QUARENC_RESPONSE packetQuarEncResponse; PTSG_PACKET_QUARENC_RESPONSE packetQuarEncResponse;
status = rpc_recv_pdu(rpc); pdu = rpc_recv_pdu(rpc);
if (status <= 0) if (!pdu)
return FALSE; return FALSE;
length = rpc->StubLength; length = pdu->Length;
buffer = rpc->StubBuffer; buffer = pdu->Buffer;
packet = (PTSG_PACKET) malloc(sizeof(TSG_PACKET)); packet = (PTSG_PACKET) malloc(sizeof(TSG_PACKET));
ZeroMemory(packet, sizeof(TSG_PACKET)); ZeroMemory(packet, sizeof(TSG_PACKET));
@ -549,7 +549,7 @@ BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg)
BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg) BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg)
{ {
int status; RPC_PDU* pdu;
BYTE* buffer; BYTE* buffer;
UINT32 length; UINT32 length;
UINT32 offset; UINT32 offset;
@ -560,19 +560,20 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg)
rdpRpc* rpc = tsg->rpc; rdpRpc* rpc = tsg->rpc;
PTSG_PACKET_RESPONSE packetResponse; PTSG_PACKET_RESPONSE packetResponse;
status = rpc_recv_pdu_fragment(rpc); pdu = rpc_recv_pdu(rpc);
if (status <= 0) if (!pdu)
return FALSE; return FALSE;
length = status; length = pdu->Length;
buffer = rpc->FragBuffer; buffer = pdu->Buffer;
packet = (PTSG_PACKET) malloc(sizeof(TSG_PACKET)); packet = (PTSG_PACKET) malloc(sizeof(TSG_PACKET));
ZeroMemory(packet, sizeof(TSG_PACKET)); ZeroMemory(packet, sizeof(TSG_PACKET));
packet->packetId = *((UINT32*) &buffer[28]); /* PacketId */ offset = 4;
SwitchValue = *((UINT32*) &buffer[32]); /* SwitchValue */ packet->packetId = *((UINT32*) &buffer[offset]); /* PacketId */
SwitchValue = *((UINT32*) &buffer[offset + 4]); /* SwitchValue */
if ((packet->packetId != TSG_PACKET_TYPE_RESPONSE) || if ((packet->packetId != TSG_PACKET_TYPE_RESPONSE) ||
(SwitchValue != TSG_PACKET_TYPE_RESPONSE)) (SwitchValue != TSG_PACKET_TYPE_RESPONSE))
@ -585,8 +586,8 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg)
ZeroMemory(packetResponse, sizeof(TSG_PACKET_RESPONSE)); ZeroMemory(packetResponse, sizeof(TSG_PACKET_RESPONSE));
packet->tsgPacket.packetResponse = packetResponse; packet->tsgPacket.packetResponse = packetResponse;
Pointer = *((UINT32*) &buffer[36]); /* PacketResponsePtr */ Pointer = *((UINT32*) &buffer[offset + 8]); /* PacketResponsePtr */
packetResponse->flags = *((UINT32*) &buffer[40]); /* Flags */ packetResponse->flags = *((UINT32*) &buffer[offset + 12]); /* Flags */
if (packetResponse->flags != TSG_PACKET_TYPE_QUARREQUEST) if (packetResponse->flags != TSG_PACKET_TYPE_QUARREQUEST)
{ {
@ -596,18 +597,18 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg)
} }
/* Reserved (4 bytes) */ /* Reserved (4 bytes) */
Pointer = *((UINT32*) &buffer[48]); /* ResponseDataPtr */ Pointer = *((UINT32*) &buffer[offset + 20]); /* ResponseDataPtr */
packetResponse->responseDataLen = *((UINT32*) &buffer[52]); /* ResponseDataLength */ packetResponse->responseDataLen = *((UINT32*) &buffer[offset + 24]); /* ResponseDataLength */
packetResponse->redirectionFlags.enableAllRedirections = *((UINT32*) &buffer[56]); /* EnableAllRedirections */ packetResponse->redirectionFlags.enableAllRedirections = *((UINT32*) &buffer[offset + 28]); /* EnableAllRedirections */
packetResponse->redirectionFlags.disableAllRedirections = *((UINT32*) &buffer[60]); /* DisableAllRedirections */ packetResponse->redirectionFlags.disableAllRedirections = *((UINT32*) &buffer[offset + 32]); /* DisableAllRedirections */
packetResponse->redirectionFlags.driveRedirectionDisabled = *((UINT32*) &buffer[64]); /* DriveRedirectionDisabled */ packetResponse->redirectionFlags.driveRedirectionDisabled = *((UINT32*) &buffer[offset + 36]); /* DriveRedirectionDisabled */
packetResponse->redirectionFlags.printerRedirectionDisabled = *((UINT32*) &buffer[68]); /* PrinterRedirectionDisabled */ packetResponse->redirectionFlags.printerRedirectionDisabled = *((UINT32*) &buffer[offset + 40]); /* PrinterRedirectionDisabled */
packetResponse->redirectionFlags.portRedirectionDisabled = *((UINT32*) &buffer[72]); /* PortRedirectionDisabled */ packetResponse->redirectionFlags.portRedirectionDisabled = *((UINT32*) &buffer[offset + 44]); /* PortRedirectionDisabled */
packetResponse->redirectionFlags.reserved = *((UINT32*) &buffer[76]); /* Reserved */ packetResponse->redirectionFlags.reserved = *((UINT32*) &buffer[offset + 48]); /* Reserved */
packetResponse->redirectionFlags.clipboardRedirectionDisabled = *((UINT32*) &buffer[80]); /* ClipboardRedirectionDisabled */ packetResponse->redirectionFlags.clipboardRedirectionDisabled = *((UINT32*) &buffer[offset + 52]); /* ClipboardRedirectionDisabled */
packetResponse->redirectionFlags.pnpRedirectionDisabled = *((UINT32*) &buffer[84]); /* PnpRedirectionDisabled */ packetResponse->redirectionFlags.pnpRedirectionDisabled = *((UINT32*) &buffer[offset + 56]); /* PnpRedirectionDisabled */
offset = 88; offset += 60;
SizeValue = *((UINT32*) &buffer[offset]); SizeValue = *((UINT32*) &buffer[offset]);
offset += 4; offset += 4;
@ -787,18 +788,18 @@ BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg)
BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg) BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg)
{ {
int status; RPC_PDU* pdu;
BYTE* buffer; BYTE* buffer;
UINT32 length; UINT32 length;
rdpRpc* rpc = tsg->rpc; rdpRpc* rpc = tsg->rpc;
status = rpc_recv_pdu_fragment(rpc); pdu = rpc_recv_pdu(rpc);
if (status < 0) if (!pdu)
return FALSE; return FALSE;
length = status; length = pdu->Length;
buffer = rpc->FragBuffer; buffer = pdu->Buffer;
/* ChannelContext (20 bytes) */ /* ChannelContext (20 bytes) */
CopyMemory(&tsg->ChannelContext.ContextType, &rpc->FragBuffer[24], 4); /* ContextType (4 bytes) */ CopyMemory(&tsg->ChannelContext.ContextType, &rpc->FragBuffer[24], 4); /* ContextType (4 bytes) */
@ -883,21 +884,6 @@ BOOL TsProxySetupReceivePipeWriteRequest(rdpTsg* tsg)
BOOL TsProxySetupReceivePipeReadResponse(rdpTsg* tsg) BOOL TsProxySetupReceivePipeReadResponse(rdpTsg* tsg)
{ {
#if 0
int status;
BYTE* FragBuffer;
UINT32 length;
rdpRpc* rpc = tsg->rpc;
status = rpc_recv_pdu_fragment(rpc);
if (status < 0)
return FALSE;
length = status;
FragBuffer = rpc->FragBuffer;
#endif
return TRUE; return TRUE;
} }
@ -1091,8 +1077,6 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port)
if (!TsProxySetupReceivePipe((handle_t) tsg, NULL)) if (!TsProxySetupReceivePipe((handle_t) tsg, NULL))
return FALSE; return FALSE;
tsg->state = TSG_STATE_PIPE_CREATED;
rpc->client->SynchronousSend = TRUE; rpc->client->SynchronousSend = TRUE;
return TRUE; return TRUE;
@ -1100,7 +1084,6 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port)
int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length) int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
{ {
int status;
int CopyLength; int CopyLength;
rdpRpc* rpc = tsg->rpc; rdpRpc* rpc = tsg->rpc;
@ -1110,7 +1093,7 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
{ {
CopyLength = (tsg->BytesAvailable > length) ? length : tsg->BytesAvailable; CopyLength = (tsg->BytesAvailable > length) ? length : tsg->BytesAvailable;
CopyMemory(data, &rpc->StubBuffer[tsg->BytesRead], CopyLength); CopyMemory(data, &tsg->pdu->Buffer[tsg->BytesRead], CopyLength);
tsg->BytesAvailable -= CopyLength; tsg->BytesAvailable -= CopyLength;
tsg->BytesRead += CopyLength; tsg->BytesRead += CopyLength;
@ -1121,9 +1104,9 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
} }
else else
{ {
status = rpc_recv_pdu(rpc); tsg->pdu = rpc_recv_pdu(rpc);
if (rpc->StubLength == 4) if ((tsg->pdu->Flags & RPC_PDU_FLAG_STUB) && (tsg->pdu->Length == 4))
{ {
DEBUG_TSG("Ignoring TsProxySetupReceivePipe Response"); DEBUG_TSG("Ignoring TsProxySetupReceivePipe Response");
return tsg_read(tsg, data, length); return tsg_read(tsg, data, length);
@ -1131,12 +1114,12 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
} }
tsg->PendingPdu = TRUE; tsg->PendingPdu = TRUE;
tsg->BytesAvailable = rpc->StubLength; tsg->BytesAvailable = rpc->pdu->Length;
tsg->BytesRead = 0; tsg->BytesRead = 0;
CopyLength = (tsg->BytesAvailable > length) ? length : tsg->BytesAvailable; CopyLength = (tsg->BytesAvailable > length) ? length : tsg->BytesAvailable;
CopyMemory(data, &rpc->StubBuffer[tsg->BytesRead], CopyLength); CopyMemory(data, &tsg->pdu->Buffer[tsg->BytesRead], CopyLength);
tsg->BytesAvailable -= CopyLength; tsg->BytesAvailable -= CopyLength;
tsg->BytesRead += CopyLength; tsg->BytesRead += CopyLength;

View File

@ -55,6 +55,7 @@ struct rdp_tsg
{ {
rdpRpc* rpc; rdpRpc* rpc;
UINT16 Port; UINT16 Port;
RPC_PDU* pdu;
LPWSTR Hostname; LPWSTR Hostname;
LPWSTR MachineName; LPWSTR MachineName;
TSG_STATE state; TSG_STATE state;