mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-core: TSG partial cleanup
This commit is contained in:
@@ -267,6 +267,10 @@ void http_request_free(HttpRequest* http_request)
|
||||
{
|
||||
if (http_request != NULL)
|
||||
{
|
||||
free(http_request->AuthParam);
|
||||
free(http_request->AuthScheme);
|
||||
free(http_request->Authorization);
|
||||
free(http_request->Content);
|
||||
free(http_request->Method);
|
||||
free(http_request->URI);
|
||||
free(http_request);
|
||||
@@ -397,10 +401,12 @@ HttpResponse* http_response_recv(rdpTls* tls)
|
||||
|
||||
nbytes = 0;
|
||||
length = 10000;
|
||||
content = NULL;
|
||||
buffer = malloc(length);
|
||||
http_response = http_response_new();
|
||||
|
||||
p = buffer;
|
||||
http_response->ContentLength = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
|
||||
@@ -345,15 +345,6 @@ int rpc_in_write(rdpRpc* rpc, BYTE* data, int length)
|
||||
return status;
|
||||
}
|
||||
|
||||
RPC_PDU* rpc_recv_pdu(rdpRpc* rpc)
|
||||
{
|
||||
RPC_PDU* pdu;
|
||||
|
||||
pdu = rpc_recv_dequeue_pdu(rpc);
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
||||
{
|
||||
BYTE* buffer;
|
||||
@@ -382,13 +373,13 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
||||
request_pdu->ptype = PTYPE_REQUEST;
|
||||
request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG;
|
||||
request_pdu->auth_length = ntlm->ContextSizes.cbMaxSignature;
|
||||
request_pdu->call_id = rpc->call_id++;
|
||||
request_pdu->call_id = rpc->CallId++;
|
||||
request_pdu->alloc_hint = length;
|
||||
request_pdu->p_cont_id = 0x0000;
|
||||
request_pdu->opnum = opnum;
|
||||
|
||||
client_call = rpc_client_call_new(request_pdu->call_id, request_pdu->opnum);
|
||||
ArrayList_Add(rpc->ClientCalls, client_call);
|
||||
ArrayList_Add(rpc->client->ClientCallList, client_call);
|
||||
|
||||
if (request_pdu->opnum == TsProxySetupReceivePipeOpnum)
|
||||
rpc->PipeCallId = request_pdu->call_id;
|
||||
@@ -439,7 +430,7 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
||||
Message.ulVersion = SECBUFFER_VERSION;
|
||||
Message.pBuffers = (PSecBuffer) &Buffers;
|
||||
|
||||
encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->send_seq_num++);
|
||||
encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->SendSeqNum++);
|
||||
|
||||
if (encrypt_status != SEC_E_OK)
|
||||
{
|
||||
@@ -452,12 +443,9 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
||||
|
||||
rpc_send_enqueue_pdu(rpc, buffer, request_pdu->frag_length);
|
||||
|
||||
return length;
|
||||
}
|
||||
free(request_pdu);
|
||||
|
||||
int rpc_recv(rdpRpc* rpc, RPC_PDU* pdu)
|
||||
{
|
||||
return 0;
|
||||
return length;
|
||||
}
|
||||
|
||||
BOOL rpc_connect(rdpRpc* rpc)
|
||||
@@ -526,39 +514,6 @@ void rpc_client_virtual_connection_free(RpcVirtualConnection* virtual_connection
|
||||
}
|
||||
}
|
||||
|
||||
/* Virtual Connection Cookie Table */
|
||||
|
||||
RpcVirtualConnectionCookieTable* rpc_virtual_connection_cookie_table_new(rdpRpc* rpc)
|
||||
{
|
||||
RpcVirtualConnectionCookieTable* table;
|
||||
|
||||
table = (RpcVirtualConnectionCookieTable*) malloc(sizeof(RpcVirtualConnectionCookieTable));
|
||||
|
||||
if (table != NULL)
|
||||
{
|
||||
ZeroMemory(table, sizeof(RpcVirtualConnectionCookieTable));
|
||||
|
||||
table->Count = 0;
|
||||
table->ArraySize = 32;
|
||||
|
||||
table->Entries = (RpcVirtualConnectionCookieEntry*) malloc(sizeof(RpcVirtualConnectionCookieEntry) * table->ArraySize);
|
||||
ZeroMemory(table->Entries, sizeof(RpcVirtualConnectionCookieEntry) * table->ArraySize);
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
void rpc_virtual_connection_cookie_table_free(RpcVirtualConnectionCookieTable* table)
|
||||
{
|
||||
if (table != NULL)
|
||||
{
|
||||
free(table->Entries);
|
||||
free(table);
|
||||
}
|
||||
}
|
||||
|
||||
/* RPC Core Module */
|
||||
|
||||
rdpRpc* rpc_new(rdpTransport* transport)
|
||||
{
|
||||
rdpRpc* rpc = (rdpRpc*) malloc(sizeof(rdpRpc));
|
||||
@@ -572,7 +527,7 @@ rdpRpc* rpc_new(rdpTransport* transport)
|
||||
rpc->transport = transport;
|
||||
rpc->settings = transport->settings;
|
||||
|
||||
rpc->send_seq_num = 0;
|
||||
rpc->SendSeqNum = 0;
|
||||
rpc->ntlm = ntlm_new();
|
||||
|
||||
rpc->NtlmHttpIn = ntlm_http_new();
|
||||
@@ -581,16 +536,13 @@ rdpRpc* rpc_new(rdpTransport* transport)
|
||||
rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpIn, TSG_CHANNEL_IN);
|
||||
rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT);
|
||||
|
||||
rpc->FragBufferSize = 20;
|
||||
rpc->FragBuffer = (BYTE*) malloc(rpc->FragBufferSize);
|
||||
|
||||
rpc->PipeCallId = 0;
|
||||
|
||||
rpc->StubOffset = 0;
|
||||
rpc->StubBufferSize = 20;
|
||||
rpc->StubLength = 0;
|
||||
rpc->StubFragCount = 0;
|
||||
rpc->StubBuffer = (BYTE*) malloc(rpc->FragBufferSize);
|
||||
rpc->StubBuffer = (BYTE*) malloc(0x0FF8);
|
||||
rpc->StubCallId = 0;
|
||||
|
||||
rpc->rpc_vers = 5;
|
||||
@@ -607,13 +559,8 @@ rdpRpc* rpc_new(rdpTransport* transport)
|
||||
|
||||
rpc->pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU));
|
||||
|
||||
rpc->SendQueue = Queue_New(TRUE, -1, -1);
|
||||
rpc->ReceiveQueue = Queue_New(TRUE, -1, -1);
|
||||
|
||||
rpc->RecvFrag = Stream_New(NULL, rpc->max_recv_frag);
|
||||
|
||||
rpc->ClientCalls = ArrayList_New(TRUE);
|
||||
|
||||
rpc->ReceiveWindow = 0x00010000;
|
||||
|
||||
rpc->ChannelLifetime = 0x40000000;
|
||||
@@ -624,9 +571,9 @@ rdpRpc* rpc_new(rdpTransport* transport)
|
||||
rpc->CurrentKeepAliveTime = 0;
|
||||
|
||||
rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc);
|
||||
rpc->VirtualConnectionCookieTable = rpc_virtual_connection_cookie_table_new(rpc);
|
||||
rpc->VirtualConnectionCookieTable = ArrayList_New(TRUE);
|
||||
|
||||
rpc->call_id = 2;
|
||||
rpc->CallId = 2;
|
||||
|
||||
rpc_client_new(rpc);
|
||||
|
||||
@@ -646,17 +593,10 @@ void rpc_free(rdpRpc* rpc)
|
||||
|
||||
free(rpc->pdu);
|
||||
|
||||
Queue_Clear(rpc->SendQueue);
|
||||
Queue_Free(rpc->SendQueue);
|
||||
|
||||
Queue_Clear(rpc->ReceiveQueue);
|
||||
Queue_Free(rpc->ReceiveQueue);
|
||||
|
||||
ArrayList_Clear(rpc->ClientCalls);
|
||||
ArrayList_Free(rpc->ClientCalls);
|
||||
|
||||
rpc_client_virtual_connection_free(rpc->VirtualConnection);
|
||||
rpc_virtual_connection_cookie_table_free(rpc->VirtualConnectionCookieTable);
|
||||
|
||||
ArrayList_Clear(rpc->VirtualConnectionCookieTable);
|
||||
ArrayList_Free(rpc->VirtualConnectionCookieTable);
|
||||
|
||||
free(rpc);
|
||||
}
|
||||
|
||||
@@ -453,77 +453,62 @@ typedef struct
|
||||
{
|
||||
DEFINE_RPC_COMMON_FIELDS();
|
||||
|
||||
/* needed for request, response, fault */
|
||||
UINT32 alloc_hint;
|
||||
p_context_id_t p_cont_id;
|
||||
|
||||
UINT32 alloc_hint; /* 16:04 allocation hint */
|
||||
p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */
|
||||
BYTE cancel_count;
|
||||
BYTE reserved;
|
||||
|
||||
/* needed for response or fault */
|
||||
UINT32 status;
|
||||
|
||||
BYTE cancel_count; /* 22:01 received cancel count */
|
||||
BYTE reserved; /* 23:01 reserved, m.b.z. */
|
||||
/* align(8) */
|
||||
|
||||
/* fault code */
|
||||
|
||||
UINT32 status; /* 24:04 run-time fault code or zero */
|
||||
|
||||
/* always pad to next 8-octet boundary */
|
||||
|
||||
BYTE reserved2[4]; /* 28:04 reserved padding, m.b.z. */
|
||||
|
||||
/* stub data here, 8-octet aligned */
|
||||
BYTE* stub_data;
|
||||
|
||||
auth_verifier_co_t auth_verifier; /* xx:yy */
|
||||
auth_verifier_co_t auth_verifier;
|
||||
} rpcconn_fault_hdr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DEFINE_RPC_COMMON_FIELDS();
|
||||
|
||||
auth_verifier_co_t auth_verifier; /* xx:yy */
|
||||
auth_verifier_co_t auth_verifier;
|
||||
} rpcconn_orphaned_hdr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DEFINE_RPC_COMMON_FIELDS();
|
||||
|
||||
/* needed on request, response, fault */
|
||||
UINT32 alloc_hint;
|
||||
|
||||
UINT32 alloc_hint; /* 16:04 allocation hint */
|
||||
|
||||
p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */
|
||||
UINT16 opnum; /* 22:02 operation number within the interface */
|
||||
p_context_id_t p_cont_id;
|
||||
UINT16 opnum;
|
||||
|
||||
/* optional field for request, only present if the PFC_OBJECT_UUID field is non-zero */
|
||||
p_uuid_t object;
|
||||
|
||||
p_uuid_t object; /* 24:16 object UUID */
|
||||
|
||||
/* stub data, 8-octet aligned */
|
||||
/* align(8) */
|
||||
|
||||
BYTE* stub_data;
|
||||
|
||||
auth_verifier_co_t auth_verifier; /* xx:yy */
|
||||
auth_verifier_co_t auth_verifier;
|
||||
} rpcconn_request_hdr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DEFINE_RPC_COMMON_FIELDS();
|
||||
|
||||
/* needed for request, response, fault */
|
||||
UINT32 alloc_hint;
|
||||
p_context_id_t p_cont_id;
|
||||
|
||||
UINT32 alloc_hint; /* 16:04 allocation hint */
|
||||
p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */
|
||||
BYTE cancel_count;
|
||||
BYTE reserved;
|
||||
|
||||
/* needed for response or fault */
|
||||
/* align(8) */
|
||||
|
||||
BYTE cancel_count; /* 22:01 cancel count */
|
||||
BYTE reserved; /* 23:01 reserved, m.b.z. */
|
||||
|
||||
/* stub data here, 8-octet aligned */
|
||||
BYTE* stub_data;
|
||||
|
||||
auth_verifier_co_t auth_verifier; /* xx:yy */
|
||||
auth_verifier_co_t auth_verifier;
|
||||
} rpcconn_response_hdr_t;
|
||||
|
||||
typedef struct
|
||||
@@ -711,24 +696,20 @@ struct rpc_virtual_connection_cookie_entry
|
||||
};
|
||||
typedef struct rpc_virtual_connection_cookie_entry RpcVirtualConnectionCookieEntry;
|
||||
|
||||
struct rpc_virtual_connection_cookie_table
|
||||
{
|
||||
UINT32 Count;
|
||||
UINT32 ArraySize;
|
||||
RpcVirtualConnectionCookieEntry* Entries;
|
||||
};
|
||||
typedef struct rpc_virtual_connection_cookie_table RpcVirtualConnectionCookieTable;
|
||||
|
||||
struct rpc_client
|
||||
{
|
||||
HANDLE Thread;
|
||||
HANDLE StopEvent;
|
||||
|
||||
wQueue* SendQueue;
|
||||
wQueue* ReceiveQueue;
|
||||
|
||||
wQueue* FragmentPool;
|
||||
wQueue* FragmentQueue;
|
||||
|
||||
wArrayList* ClientCallList;
|
||||
|
||||
HANDLE PduSentEvent;
|
||||
HANDLE SendSemaphore;
|
||||
|
||||
BOOL SynchronousSend;
|
||||
BOOL SynchronousReceive;
|
||||
@@ -743,7 +724,7 @@ struct rdp_rpc
|
||||
rdpTls* TlsOut;
|
||||
|
||||
rdpNtlm* ntlm;
|
||||
int send_seq_num;
|
||||
int SendSeqNum;
|
||||
|
||||
RpcClient* client;
|
||||
|
||||
@@ -753,14 +734,11 @@ struct rdp_rpc
|
||||
rdpSettings* settings;
|
||||
rdpTransport* transport;
|
||||
|
||||
UINT32 call_id;
|
||||
UINT32 CallId;
|
||||
UINT32 PipeCallId;
|
||||
|
||||
RPC_PDU* pdu;
|
||||
|
||||
BYTE* FragBuffer;
|
||||
UINT32 FragBufferSize;
|
||||
|
||||
BYTE* StubBuffer;
|
||||
UINT32 StubBufferSize;
|
||||
UINT32 StubLength;
|
||||
@@ -777,11 +755,6 @@ struct rdp_rpc
|
||||
|
||||
wStream* RecvFrag;
|
||||
|
||||
wQueue* SendQueue;
|
||||
wQueue* ReceiveQueue;
|
||||
|
||||
wArrayList* ClientCalls;
|
||||
|
||||
UINT32 ReceiveWindow;
|
||||
|
||||
UINT32 ChannelLifetime;
|
||||
@@ -792,11 +765,13 @@ struct rdp_rpc
|
||||
UINT32 CurrentKeepAliveInterval;
|
||||
|
||||
RpcVirtualConnection* VirtualConnection;
|
||||
RpcVirtualConnectionCookieTable* VirtualConnectionCookieTable;
|
||||
|
||||
wArrayList* VirtualConnectionCookieTable;
|
||||
};
|
||||
|
||||
BOOL rpc_connect(rdpRpc* rpc);
|
||||
|
||||
void rpc_pdu_header_print(rpcconn_hdr_t* header);
|
||||
void rpc_pdu_header_init(rdpRpc* rpc, rpcconn_hdr_t* header);
|
||||
|
||||
UINT32 rpc_offset_align(UINT32* offset, UINT32 alignment);
|
||||
@@ -808,13 +783,9 @@ int rpc_out_write(rdpRpc* rpc, BYTE* data, int length);
|
||||
int rpc_in_write(rdpRpc* rpc, BYTE* data, int length);
|
||||
|
||||
BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* length);
|
||||
int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header);
|
||||
|
||||
RPC_PDU* rpc_recv_pdu(rdpRpc* rpc);
|
||||
int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum);
|
||||
|
||||
int rpc_recv(rdpRpc* rpc, RPC_PDU* pdu);
|
||||
|
||||
rdpRpc* rpc_new(rdpTransport* transport);
|
||||
void rpc_free(rdpRpc* rpc);
|
||||
|
||||
|
||||
@@ -66,7 +66,8 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
|
||||
|
||||
buffer = (BYTE*) Stream_Buffer(fragment);
|
||||
header = (rpcconn_hdr_t*) Stream_Buffer(fragment);
|
||||
rpc->FragBuffer = fragment->buffer;
|
||||
|
||||
rpc_pdu_header_print(header);
|
||||
|
||||
if (rpc->State < RPC_CLIENT_STATE_CONTEXT_NEGOTIATED)
|
||||
{
|
||||
@@ -76,45 +77,21 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
|
||||
rpc->pdu->Length = Stream_Length(fragment);
|
||||
rpc->pdu->CallId = header->common.call_id;
|
||||
|
||||
Queue_Enqueue(rpc->ReceiveQueue, rpc->pdu);
|
||||
Queue_Enqueue(rpc->client->ReceiveQueue, rpc->pdu);
|
||||
rpc->pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (header->common.ptype != PTYPE_RESPONSE)
|
||||
if (header->common.ptype == PTYPE_RTS)
|
||||
{
|
||||
printf("unexpected ptype: %d\n", header->common.ptype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (header->common.ptype == PTYPE_RESPONSE)
|
||||
{
|
||||
rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length;
|
||||
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length;
|
||||
|
||||
if (!rpc_get_stub_data_info(rpc, buffer, &StubOffset, &StubLength))
|
||||
if (rpc->VirtualConnection->State >= VIRTUAL_CONNECTION_STATE_OPENED)
|
||||
{
|
||||
printf("rpc_recv_pdu_fragment: expected stub\n");
|
||||
return -1;
|
||||
}
|
||||
printf("Receiving Out-of-Sequence RTS PDU\n");
|
||||
rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length);
|
||||
|
||||
if (StubLength == 4)
|
||||
{
|
||||
printf("Ignoring TsProxySendToServer Response\n");
|
||||
rpc_client_fragment_pool_return(rpc, fragment);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (header->common.ptype == PTYPE_RTS)
|
||||
{
|
||||
if (rpc->VirtualConnection->State < VIRTUAL_CONNECTION_STATE_OPENED)
|
||||
return header->common.frag_length;
|
||||
|
||||
printf("Receiving Out-of-Sequence RTS PDU\n");
|
||||
rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length);
|
||||
|
||||
rpc_client_fragment_pool_return(rpc, fragment);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -124,6 +101,28 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (header->common.ptype != PTYPE_RESPONSE)
|
||||
{
|
||||
printf("Unexpected RPC PDU type: %d\n", header->common.ptype);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length;
|
||||
rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length;
|
||||
|
||||
if (!rpc_get_stub_data_info(rpc, buffer, &StubOffset, &StubLength))
|
||||
{
|
||||
printf("rpc_recv_pdu_fragment: expected stub\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (StubLength == 4)
|
||||
{
|
||||
printf("Ignoring TsProxySendToServer Response\n");
|
||||
rpc_client_fragment_pool_return(rpc, fragment);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (header->response.alloc_hint > rpc->StubBufferSize)
|
||||
{
|
||||
rpc->StubBufferSize = header->response.alloc_hint;
|
||||
@@ -174,7 +173,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
|
||||
rpc->StubBufferSize = rpc->max_recv_frag;
|
||||
rpc->StubBuffer = (BYTE*) malloc(rpc->StubBufferSize);
|
||||
|
||||
Queue_Enqueue(rpc->ReceiveQueue, rpc->pdu);
|
||||
Queue_Enqueue(rpc->client->ReceiveQueue, rpc->pdu);
|
||||
rpc->pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU));
|
||||
|
||||
return 0;
|
||||
@@ -267,20 +266,20 @@ RpcClientCall* rpc_client_call_find_by_id(rdpRpc* rpc, UINT32 CallId)
|
||||
int count;
|
||||
RpcClientCall* client_call;
|
||||
|
||||
ArrayList_Lock(rpc->ClientCalls);
|
||||
ArrayList_Lock(rpc->client->ClientCallList);
|
||||
|
||||
client_call = NULL;
|
||||
count = ArrayList_Count(rpc->ClientCalls);
|
||||
count = ArrayList_Count(rpc->client->ClientCallList);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
client_call = (RpcClientCall*) ArrayList_GetItem(rpc->ClientCalls, index);
|
||||
client_call = (RpcClientCall*) ArrayList_GetItem(rpc->client->ClientCallList, index);
|
||||
|
||||
if (client_call->CallId == CallId)
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayList_Unlock(rpc->ClientCalls);
|
||||
ArrayList_Unlock(rpc->client->ClientCallList);
|
||||
|
||||
return client_call;
|
||||
}
|
||||
@@ -314,7 +313,7 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
pdu->Buffer = buffer;
|
||||
pdu->Length = length;
|
||||
|
||||
Queue_Enqueue(rpc->SendQueue, pdu);
|
||||
Queue_Enqueue(rpc->client->SendQueue, pdu);
|
||||
|
||||
if (rpc->client->SynchronousSend)
|
||||
{
|
||||
@@ -332,7 +331,7 @@ int rpc_send_dequeue_pdu(rdpRpc* rpc)
|
||||
RpcClientCall* client_call;
|
||||
rpcconn_common_hdr_t* header;
|
||||
|
||||
pdu = (RPC_PDU*) Queue_Dequeue(rpc->SendQueue);
|
||||
pdu = (RPC_PDU*) Queue_Dequeue(rpc->client->SendQueue);
|
||||
|
||||
if (!pdu)
|
||||
return 0;
|
||||
@@ -373,9 +372,9 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc)
|
||||
pdu = NULL;
|
||||
dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0;
|
||||
|
||||
if (WaitForSingleObject(Queue_Event(rpc->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0)
|
||||
if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0)
|
||||
{
|
||||
pdu = (RPC_PDU*) Queue_Dequeue(rpc->ReceiveQueue);
|
||||
pdu = (RPC_PDU*) Queue_Dequeue(rpc->client->ReceiveQueue);
|
||||
return pdu;
|
||||
}
|
||||
|
||||
@@ -396,7 +395,7 @@ static void* rpc_client_thread(void* arg)
|
||||
|
||||
nCount = 0;
|
||||
events[nCount++] = rpc->client->StopEvent;
|
||||
events[nCount++] = Queue_Event(rpc->SendQueue);
|
||||
events[nCount++] = Queue_Event(rpc->client->SendQueue);
|
||||
events[nCount++] = ReadEvent;
|
||||
|
||||
while (1)
|
||||
@@ -410,10 +409,11 @@ static void* rpc_client_thread(void* arg)
|
||||
|
||||
if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
rpc_client_on_read_event(rpc);
|
||||
if (rpc_client_on_read_event(rpc) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(Queue_Event(rpc->SendQueue), 0) == WAIT_OBJECT_0)
|
||||
if (WaitForSingleObject(Queue_Event(rpc->client->SendQueue), 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
rpc_send_dequeue_pdu(rpc);
|
||||
}
|
||||
@@ -421,9 +421,22 @@ static void* rpc_client_thread(void* arg)
|
||||
|
||||
CloseHandle(ReadEvent);
|
||||
|
||||
rpc_client_free(rpc);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rpc_pdu_free(RPC_PDU* pdu)
|
||||
{
|
||||
free(pdu->Buffer);
|
||||
free(pdu);
|
||||
}
|
||||
|
||||
static void rpc_fragment_free(wStream* fragment)
|
||||
{
|
||||
Stream_Free(fragment, TRUE);
|
||||
}
|
||||
|
||||
int rpc_client_new(rdpRpc* rpc)
|
||||
{
|
||||
rpc->client = (RpcClient*) malloc(sizeof(RpcClient));
|
||||
@@ -435,9 +448,21 @@ int rpc_client_new(rdpRpc* rpc)
|
||||
rpc->client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
rpc->client->PduSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
rpc->client->SendQueue = Queue_New(TRUE, -1, -1);
|
||||
rpc->client->ReceiveQueue = Queue_New(TRUE, -1, -1);
|
||||
|
||||
Queue_Object(rpc->client->SendQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
|
||||
Queue_Object(rpc->client->ReceiveQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free;
|
||||
|
||||
rpc->client->FragmentPool = Queue_New(TRUE, -1, -1);
|
||||
rpc->client->FragmentQueue = Queue_New(TRUE, -1, -1);
|
||||
|
||||
Queue_Object(rpc->client->FragmentPool)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
|
||||
Queue_Object(rpc->client->FragmentQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free;
|
||||
|
||||
rpc->client->ClientCallList = ArrayList_New(TRUE);
|
||||
ArrayList_Object(rpc->client->ClientCallList)->fnObjectFree = (OBJECT_FREE_FN) rpc_client_call_free;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -447,3 +472,24 @@ int rpc_client_start(rdpRpc* rpc)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_client_stop(rdpRpc* rpc)
|
||||
{
|
||||
SetEvent(rpc->client->StopEvent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_client_free(rdpRpc* rpc)
|
||||
{
|
||||
Queue_Clear(rpc->client->SendQueue);
|
||||
Queue_Free(rpc->client->SendQueue);
|
||||
|
||||
Queue_Clear(rpc->client->ReceiveQueue);
|
||||
Queue_Free(rpc->client->ReceiveQueue);
|
||||
|
||||
ArrayList_Clear(rpc->client->ClientCallList);
|
||||
ArrayList_Free(rpc->client->ClientCallList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -40,5 +40,7 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc);
|
||||
|
||||
int rpc_client_new(rdpRpc* rpc);
|
||||
int rpc_client_start(rdpRpc* rpc);
|
||||
int rpc_client_stop(rdpRpc* rpc);
|
||||
int rpc_client_free(rdpRpc* rpc);
|
||||
|
||||
#endif /* FREERDP_CORE_RPC_CLIENT_H */
|
||||
|
||||
@@ -981,6 +981,10 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
return rts_recv_flow_control_ack_with_destination_pdu(rpc, buffer, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unimplemented signature id: 0x%08X\n", SignatureId);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -160,14 +160,17 @@ void rdp_write_share_data_header(STREAM* s, UINT16 length, BYTE type, UINT32 sha
|
||||
stream_write_UINT16(s, 0); /* compressedLength (2 bytes) */
|
||||
}
|
||||
|
||||
static int RdpSecurity_stream_init(rdpRdp* rdp, STREAM* s)
|
||||
static int rdp_security_stream_init(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (rdp->do_crypt)
|
||||
{
|
||||
stream_seek(s, 12);
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
stream_seek(s, 4);
|
||||
|
||||
rdp->sec_flags |= SEC_ENCRYPT;
|
||||
|
||||
if (rdp->do_secure_checksum)
|
||||
rdp->sec_flags |= SEC_SECURE_CHECKSUM;
|
||||
}
|
||||
@@ -175,6 +178,7 @@ static int RdpSecurity_stream_init(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
stream_seek(s, 4);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -190,7 +194,7 @@ STREAM* rdp_send_stream_init(rdpRdp* rdp)
|
||||
|
||||
s = transport_send_stream_init(rdp->transport, 2048);
|
||||
stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
|
||||
RdpSecurity_stream_init(rdp, s);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -200,7 +204,7 @@ STREAM* rdp_pdu_init(rdpRdp* rdp)
|
||||
STREAM* s;
|
||||
s = transport_send_stream_init(rdp->transport, 2048);
|
||||
stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
|
||||
RdpSecurity_stream_init(rdp, s);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
|
||||
return s;
|
||||
}
|
||||
@@ -210,7 +214,7 @@ STREAM* rdp_data_pdu_init(rdpRdp* rdp)
|
||||
STREAM* s;
|
||||
s = transport_send_stream_init(rdp->transport, 2048);
|
||||
stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
|
||||
RdpSecurity_stream_init(rdp, s);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
|
||||
stream_seek(s, RDP_SHARE_DATA_HEADER_LENGTH);
|
||||
return s;
|
||||
@@ -284,6 +288,7 @@ void rdp_write_header(rdpRdp* rdp, STREAM* s, UINT16 length, UINT16 channel_id)
|
||||
|
||||
body_length = length - RDP_PACKET_HEADER_MAX_LENGTH - 16;
|
||||
pad = 8 - (body_length % 8);
|
||||
|
||||
if (pad != 8)
|
||||
length += pad;
|
||||
}
|
||||
@@ -302,7 +307,7 @@ void rdp_write_header(rdpRdp* rdp, STREAM* s, UINT16 length, UINT16 channel_id)
|
||||
stream_write_UINT16_be(s, length); /* userData (OCTET_STRING) */
|
||||
}
|
||||
|
||||
static UINT32 RdpSecurity_stream_out(rdpRdp* rdp, STREAM* s, int length)
|
||||
static UINT32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length)
|
||||
{
|
||||
BYTE* data;
|
||||
UINT32 sec_flags;
|
||||
@@ -403,7 +408,7 @@ BOOL rdp_send(rdpRdp* rdp, STREAM* s, UINT16 channel_id)
|
||||
stream_seek(s, sec_bytes);
|
||||
|
||||
s->p = sec_hold;
|
||||
length += RdpSecurity_stream_out(rdp, s, length);
|
||||
length += rdp_security_stream_out(rdp, s, length);
|
||||
|
||||
stream_set_pos(s, length);
|
||||
if (transport_write(rdp->transport, s) < 0)
|
||||
@@ -430,7 +435,7 @@ BOOL rdp_send_pdu(rdpRdp* rdp, STREAM* s, UINT16 type, UINT16 channel_id)
|
||||
rdp_write_share_control_header(s, length - sec_bytes, type, channel_id);
|
||||
|
||||
s->p = sec_hold;
|
||||
length += RdpSecurity_stream_out(rdp, s, length);
|
||||
length += rdp_security_stream_out(rdp, s, length);
|
||||
|
||||
stream_set_pos(s, length);
|
||||
if (transport_write(rdp->transport, s) < 0)
|
||||
@@ -458,7 +463,7 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, BYTE type, UINT16 channel_id)
|
||||
rdp_write_share_data_header(s, length - sec_bytes, type, rdp->settings->ShareId);
|
||||
|
||||
s->p = sec_hold;
|
||||
length += RdpSecurity_stream_out(rdp, s, length);
|
||||
length += rdp_security_stream_out(rdp, s, length);
|
||||
|
||||
stream_set_pos(s, length);
|
||||
if (transport_write(rdp->transport, s) < 0)
|
||||
|
||||
@@ -29,6 +29,16 @@
|
||||
|
||||
#include <winpr/synch.h>
|
||||
|
||||
typedef void (*OBJECT_EQUALS_FN)(void* objA, void* objB);
|
||||
typedef void (*OBJECT_FREE_FN)(void* obj);
|
||||
|
||||
struct _wObject
|
||||
{
|
||||
OBJECT_EQUALS_FN fnObjectEquals;
|
||||
OBJECT_FREE_FN fnObjectFree;
|
||||
};
|
||||
typedef struct _wObject wObject;
|
||||
|
||||
/* System.Collections.Queue */
|
||||
|
||||
struct _wQueue
|
||||
@@ -43,6 +53,8 @@ struct _wQueue
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
HANDLE event;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
typedef struct _wQueue wQueue;
|
||||
|
||||
@@ -51,7 +63,10 @@ WINPR_API BOOL Queue_IsSynchronized(wQueue* queue);
|
||||
WINPR_API HANDLE Queue_SyncRoot(wQueue* queue);
|
||||
WINPR_API HANDLE Queue_Event(wQueue* queue);
|
||||
|
||||
#define Queue_Object(_queue) (&_queue->object)
|
||||
|
||||
WINPR_API void Queue_Clear(wQueue* queue);
|
||||
|
||||
WINPR_API BOOL Queue_Contains(wQueue* queue, void* obj);
|
||||
|
||||
WINPR_API void Queue_Enqueue(wQueue* queue, void* obj);
|
||||
@@ -67,12 +82,15 @@ WINPR_API void Queue_Free(wQueue* queue);
|
||||
struct _wStack
|
||||
{
|
||||
BOOL synchronized;
|
||||
wObject object;
|
||||
};
|
||||
typedef struct _wStack wStack;
|
||||
|
||||
WINPR_API int Stack_Count(wStack* stack);
|
||||
WINPR_API BOOL Stack_IsSynchronized(wStack* stack);
|
||||
|
||||
#define Stack_Object(_stack) (&_stack->object)
|
||||
|
||||
WINPR_API void Stack_Clear(wStack* stack);
|
||||
WINPR_API BOOL Stack_Contains(wStack* stack, void* obj);
|
||||
|
||||
@@ -95,6 +113,8 @@ struct _wArrayList
|
||||
int size;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
typedef struct _wArrayList wArrayList;
|
||||
|
||||
@@ -110,6 +130,8 @@ WINPR_API BOOL ArrayList_Unlock(wArrayList* arrayList);
|
||||
WINPR_API void* ArrayList_GetItem(wArrayList* arrayList, int index);
|
||||
WINPR_API void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj);
|
||||
|
||||
#define ArrayList_Object(_arrayList) (&_arrayList->object)
|
||||
|
||||
WINPR_API void ArrayList_Clear(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_Contains(wArrayList* arrayList, void* obj);
|
||||
|
||||
|
||||
@@ -377,6 +377,8 @@ wArrayList* ArrayList_New(BOOL synchronized)
|
||||
arrayList->array = (void**) malloc(sizeof(void*) * arrayList->capacity);
|
||||
|
||||
arrayList->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
ZeroMemory(&arrayList->object, sizeof(wObject));
|
||||
}
|
||||
|
||||
return arrayList;
|
||||
|
||||
@@ -87,6 +87,9 @@ void Queue_Clear(wQueue* queue)
|
||||
|
||||
for (index = 0; index < queue->size; index++)
|
||||
{
|
||||
if (queue->object.fnObjectFree)
|
||||
queue->object.fnObjectFree(queue->array[index]);
|
||||
|
||||
queue->array[index] = NULL;
|
||||
}
|
||||
|
||||
@@ -228,6 +231,8 @@ wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor)
|
||||
|
||||
queue->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
ZeroMemory(&queue->object, sizeof(wObject));
|
||||
}
|
||||
|
||||
return queue;
|
||||
|
||||
Reference in New Issue
Block a user