libfreerdp-core: start asynchronous receiving
This commit is contained in:
parent
3936a19914
commit
5faebcd77a
@ -62,7 +62,6 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
|
||||
if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND")
|
||||
set(CHANNEL_SUBSYSTEMS "")
|
||||
endif()
|
||||
message(STATUS "Channel: ${STATIC_MODULE_CHANNEL} Subsystems: ${CHANNEL_SUBSYSTEMS}")
|
||||
foreach(STATIC_SUBSYSTEM ${CHANNEL_SUBSYSTEMS})
|
||||
if(${STATIC_SUBSYSTEM} MATCHES "^([^-]*)-(.*)")
|
||||
string(REGEX REPLACE "^([^-]*)-(.*)" "\\1" STATIC_SUBSYSTEM_NAME ${STATIC_SUBSYSTEM})
|
||||
|
@ -268,8 +268,8 @@ int rpc_in_write(rdpRpc* rpc, BYTE* data, int length)
|
||||
|
||||
#ifdef WITH_DEBUG_TSG
|
||||
rpc_pdu_header_print((rpcconn_hdr_t*) data);
|
||||
printf("Sending PDU (length: %d)\n", length);
|
||||
freerdp_hexdump(data, length);
|
||||
printf("Sending PDU (length: %d)\n", FragBufferSize);
|
||||
freerdp_hexdump(data, FragBufferSize);
|
||||
#endif
|
||||
|
||||
status = tls_write_all(rpc->TlsIn, data, length);
|
||||
@ -322,7 +322,9 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc)
|
||||
int bytesRead = 0;
|
||||
rpcconn_hdr_t* header;
|
||||
|
||||
status = rpc_recv_pdu_header(rpc, rpc->buffer);
|
||||
WaitForSingleObject(rpc->VirtualConnection->DefaultInChannel->Mutex, INFINITE);
|
||||
|
||||
status = rpc_recv_pdu_header(rpc, rpc->FragBuffer);
|
||||
|
||||
if (status < 1)
|
||||
{
|
||||
@ -331,23 +333,19 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc)
|
||||
}
|
||||
|
||||
headerLength = status;
|
||||
header = (rpcconn_hdr_t*) rpc->buffer;
|
||||
header = (rpcconn_hdr_t*) rpc->FragBuffer;
|
||||
bytesRead += status;
|
||||
|
||||
#ifdef WITH_DEBUG_RPC
|
||||
rpc_pdu_header_print(header);
|
||||
#endif
|
||||
|
||||
if (header->common.frag_length > rpc->length)
|
||||
if (header->common.frag_length > rpc->FragBufferSize)
|
||||
{
|
||||
rpc->length = header->common.frag_length;
|
||||
rpc->buffer = (BYTE*) realloc(rpc->buffer, rpc->length);
|
||||
header = (rpcconn_hdr_t*) rpc->buffer;
|
||||
rpc->FragBufferSize = header->common.frag_length;
|
||||
rpc->FragBuffer = (BYTE*) realloc(rpc->FragBuffer, rpc->FragBufferSize);
|
||||
header = (rpcconn_hdr_t*) rpc->FragBuffer;
|
||||
}
|
||||
|
||||
while (bytesRead < header->common.frag_length)
|
||||
{
|
||||
status = rpc_out_read(rpc, &rpc->buffer[bytesRead], header->common.frag_length - bytesRead);
|
||||
status = rpc_out_read(rpc, &rpc->FragBuffer[bytesRead], header->common.frag_length - bytesRead);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
@ -358,6 +356,8 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc)
|
||||
bytesRead += status;
|
||||
}
|
||||
|
||||
ReleaseMutex(rpc->VirtualConnection->DefaultInChannel->Mutex);
|
||||
|
||||
if (header->common.ptype == PTYPE_RTS) /* RTS PDU */
|
||||
{
|
||||
if (rpc->VirtualConnection->State < VIRTUAL_CONNECTION_STATE_OPENED)
|
||||
@ -386,13 +386,14 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc)
|
||||
|
||||
if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < (rpc->ReceiveWindow / 2))
|
||||
{
|
||||
//printf("Sending Flow Control Ack PDU\n");
|
||||
printf("Sending Flow Control Ack PDU\n");
|
||||
rts_send_flow_control_ack_pdu(rpc);
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG_RPC
|
||||
printf("rpc_recv_pdu: length: %d\n", header->common.frag_length);
|
||||
freerdp_hexdump(rpc->buffer, header->common.frag_length);
|
||||
rpc_pdu_header_print((rpcconn_hdr_t*) header);
|
||||
printf("rpc_recv_pdu_fragment: length: %d\n", header->common.frag_length);
|
||||
freerdp_hexdump(rpc->FragBuffer, header->common.frag_length);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
@ -408,7 +409,17 @@ int rpc_recv_pdu(rdpRpc* rpc)
|
||||
|
||||
status = rpc_recv_pdu_fragment(rpc);
|
||||
|
||||
header = (rpcconn_hdr_t*) rpc->buffer;
|
||||
if (rpc->State < RPC_CLIENT_STATE_CONTEXT_NEGOTIATED)
|
||||
{
|
||||
rpc->pdu->Flags = 0;
|
||||
rpc->pdu->Buffer = rpc->FragBuffer;
|
||||
rpc->pdu->Size = rpc->FragBufferSize;
|
||||
rpc->pdu->Length = status;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
header = (rpcconn_hdr_t*) rpc->FragBuffer;
|
||||
|
||||
if (header->common.ptype != PTYPE_RESPONSE)
|
||||
{
|
||||
@ -416,19 +427,19 @@ int rpc_recv_pdu(rdpRpc* rpc)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!rpc_get_stub_data_info(rpc, rpc->buffer, &StubOffset, &StubLength))
|
||||
if (!rpc_get_stub_data_info(rpc, rpc->FragBuffer, &StubOffset, &StubLength))
|
||||
{
|
||||
printf("rpc_recv_pdu: expected stub\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (header->response.alloc_hint > rpc->StubSize)
|
||||
if (header->response.alloc_hint > rpc->StubBufferSize)
|
||||
{
|
||||
rpc->StubSize = header->response.alloc_hint;
|
||||
rpc->StubBuffer = (BYTE*) realloc(rpc->StubBuffer, rpc->StubSize);
|
||||
rpc->StubBufferSize = header->response.alloc_hint;
|
||||
rpc->StubBuffer = (BYTE*) realloc(rpc->StubBuffer, rpc->StubBufferSize);
|
||||
}
|
||||
|
||||
CopyMemory(&rpc->StubBuffer[rpc->StubOffset], &rpc->buffer[StubOffset], StubLength);
|
||||
CopyMemory(&rpc->StubBuffer[rpc->StubOffset], &rpc->FragBuffer[StubOffset], StubLength);
|
||||
rpc->StubOffset += StubLength;
|
||||
rpc->StubFragCount++;
|
||||
|
||||
@ -450,13 +461,18 @@ int rpc_recv_pdu(rdpRpc* rpc)
|
||||
rpc->StubOffset = 0;
|
||||
rpc->StubFragCount = 0;
|
||||
|
||||
rpc->pdu->Flags = RPC_PDU_FLAG_STUB;
|
||||
rpc->pdu->Buffer = rpc->StubBuffer;
|
||||
rpc->pdu->Size = rpc->StubBufferSize;
|
||||
rpc->pdu->Length = rpc->StubLength;
|
||||
|
||||
return rpc->StubLength;
|
||||
}
|
||||
|
||||
return rpc_recv_pdu(rpc);
|
||||
}
|
||||
|
||||
int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
||||
int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
||||
{
|
||||
BYTE* buffer;
|
||||
UINT32 offset;
|
||||
@ -550,9 +566,6 @@ int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
|
||||
|
||||
rpc_send_enqueue_pdu(rpc, buffer, request_pdu->frag_length);
|
||||
|
||||
WaitForSingleObject(rpc->client->PduSentEvent, INFINITE);
|
||||
ResetEvent(rpc->client->PduSentEvent);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
@ -561,6 +574,8 @@ BOOL rpc_connect(rdpRpc* rpc)
|
||||
rpc->TlsIn = rpc->transport->TlsIn;
|
||||
rpc->TlsOut = rpc->transport->TlsOut;
|
||||
|
||||
rpc_client_start(rpc);
|
||||
|
||||
if (!rts_connect(rpc))
|
||||
{
|
||||
printf("rts_connect error!\n");
|
||||
@ -585,6 +600,7 @@ void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* conne
|
||||
connection->DefaultInChannel->SenderAvailableWindow = rpc->ReceiveWindow;
|
||||
connection->DefaultInChannel->PingOriginator.ConnectionTimeout = 30;
|
||||
connection->DefaultInChannel->PingOriginator.KeepAliveInterval = 0;
|
||||
connection->DefaultInChannel->Mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
connection->DefaultOutChannel->State = CLIENT_OUT_CHANNEL_STATE_INITIAL;
|
||||
connection->DefaultOutChannel->BytesReceived = 0;
|
||||
@ -592,6 +608,7 @@ void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* conne
|
||||
connection->DefaultOutChannel->ReceiveWindow = rpc->ReceiveWindow;
|
||||
connection->DefaultOutChannel->ReceiveWindowSize = rpc->ReceiveWindow;
|
||||
connection->DefaultOutChannel->AvailableWindowAdvertised = rpc->ReceiveWindow;
|
||||
connection->DefaultOutChannel->Mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
}
|
||||
|
||||
RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc)
|
||||
@ -675,14 +692,14 @@ 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->length = 20;
|
||||
rpc->buffer = (BYTE*) malloc(rpc->length);
|
||||
rpc->FragBufferSize = 20;
|
||||
rpc->FragBuffer = (BYTE*) malloc(rpc->FragBufferSize);
|
||||
|
||||
rpc->StubOffset = 0;
|
||||
rpc->StubSize = 20;
|
||||
rpc->StubBufferSize = 20;
|
||||
rpc->StubLength = 0;
|
||||
rpc->StubFragCount = 0;
|
||||
rpc->StubBuffer = (BYTE*) malloc(rpc->length);
|
||||
rpc->StubBuffer = (BYTE*) malloc(rpc->FragBufferSize);
|
||||
|
||||
rpc->rpc_vers = 5;
|
||||
rpc->rpc_vers_minor = 0;
|
||||
@ -696,9 +713,14 @@ rdpRpc* rpc_new(rdpTransport* transport)
|
||||
rpc->max_xmit_frag = 0x0FF8;
|
||||
rpc->max_recv_frag = 0x0FF8;
|
||||
|
||||
rpc->pdu = (RPC_PDU*) _aligned_malloc(sizeof(RPC_PDU), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
|
||||
rpc->SendQueue = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
InitializeSListHead(rpc->SendQueue);
|
||||
|
||||
rpc->ReceiveQueue = (PSLIST_HEADER) _aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
InitializeSListHead(rpc->ReceiveQueue);
|
||||
|
||||
rpc->ReceiveWindow = 0x00010000;
|
||||
|
||||
rpc->ChannelLifetime = 0x40000000;
|
||||
@ -713,7 +735,9 @@ rdpRpc* rpc_new(rdpTransport* transport)
|
||||
|
||||
rpc->call_id = 1;
|
||||
|
||||
rpc_client_start(rpc);
|
||||
rpc_client_new(rpc);
|
||||
|
||||
rpc->client->SynchronousSend = TRUE;
|
||||
}
|
||||
|
||||
return rpc;
|
||||
@ -723,18 +747,24 @@ void rpc_free(rdpRpc* rpc)
|
||||
{
|
||||
if (rpc != NULL)
|
||||
{
|
||||
RPC_PDU_ENTRY* PduEntry;
|
||||
RPC_PDU* PduEntry;
|
||||
|
||||
ntlm_http_free(rpc->NtlmHttpIn);
|
||||
ntlm_http_free(rpc->NtlmHttpOut);
|
||||
|
||||
while ((PduEntry = (RPC_PDU_ENTRY*) InterlockedPopEntrySList(rpc->SendQueue)) != NULL)
|
||||
_aligned_free(PduEntry);
|
||||
_aligned_free(rpc->pdu);
|
||||
|
||||
while ((PduEntry = (RPC_PDU*) InterlockedPopEntrySList(rpc->SendQueue)) != NULL)
|
||||
_aligned_free(PduEntry);
|
||||
_aligned_free(rpc->SendQueue);
|
||||
|
||||
while ((PduEntry = (RPC_PDU*) InterlockedPopEntrySList(rpc->ReceiveQueue)) != NULL)
|
||||
_aligned_free(PduEntry);
|
||||
_aligned_free(rpc->ReceiveQueue);
|
||||
|
||||
rpc_client_virtual_connection_free(rpc->VirtualConnection);
|
||||
rpc_virtual_connection_cookie_table_free(rpc->VirtualConnectionCookieTable);
|
||||
|
||||
free(rpc);
|
||||
}
|
||||
}
|
||||
|
@ -602,6 +602,8 @@ struct rpc_in_channel
|
||||
|
||||
CLIENT_IN_CHANNEL_STATE State;
|
||||
|
||||
HANDLE Mutex;
|
||||
|
||||
UINT32 PlugState;
|
||||
void* SendQueue;
|
||||
UINT32 BytesSent;
|
||||
@ -633,6 +635,8 @@ struct rpc_out_channel
|
||||
|
||||
CLIENT_OUT_CHANNEL_STATE State;
|
||||
|
||||
HANDLE Mutex;
|
||||
|
||||
UINT32 ReceiveWindow;
|
||||
UINT32 ReceiveWindowSize;
|
||||
UINT32 ReceiverAvailableWindow;
|
||||
@ -693,12 +697,16 @@ struct rpc_virtual_connection_cookie_table
|
||||
};
|
||||
typedef struct rpc_virtual_connection_cookie_table RpcVirtualConnectionCookieTable;
|
||||
|
||||
typedef struct _RPC_PDU_ENTRY
|
||||
#define RPC_PDU_FLAG_STUB 0x00000001
|
||||
|
||||
typedef struct _RPC_PDU
|
||||
{
|
||||
SLIST_ENTRY ItemEntry;
|
||||
BYTE* Buffer;
|
||||
UINT32 Size;
|
||||
UINT32 Length;
|
||||
} RPC_PDU_ENTRY, *PRPC_PDU_ENTRY;
|
||||
DWORD Flags;
|
||||
} RPC_PDU, *PRPC_PDU;
|
||||
|
||||
struct rpc_client
|
||||
{
|
||||
@ -707,6 +715,11 @@ struct rpc_client
|
||||
|
||||
HANDLE PduSentEvent;
|
||||
HANDLE SendSemaphore;
|
||||
BOOL SynchronousSend;
|
||||
|
||||
HANDLE PduReceivedEvent;
|
||||
HANDLE ReceiveSemaphore;
|
||||
BOOL SynchronousReceive;
|
||||
};
|
||||
typedef struct rpc_client RpcClient;
|
||||
|
||||
@ -731,11 +744,13 @@ struct rdp_rpc
|
||||
UINT32 call_id;
|
||||
UINT32 pipe_call_id;
|
||||
|
||||
BYTE* buffer;
|
||||
UINT32 length;
|
||||
RPC_PDU* pdu;
|
||||
|
||||
BYTE* FragBuffer;
|
||||
UINT32 FragBufferSize;
|
||||
|
||||
BYTE* StubBuffer;
|
||||
UINT32 StubSize;
|
||||
UINT32 StubBufferSize;
|
||||
UINT32 StubLength;
|
||||
UINT32 StubOffset;
|
||||
UINT32 StubFragCount;
|
||||
@ -748,6 +763,7 @@ struct rdp_rpc
|
||||
UINT16 max_recv_frag;
|
||||
|
||||
PSLIST_HEADER SendQueue;
|
||||
PSLIST_HEADER ReceiveQueue;
|
||||
|
||||
UINT32 ReceiveWindow;
|
||||
|
||||
@ -778,7 +794,7 @@ int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header);
|
||||
int rpc_recv_pdu_fragment(rdpRpc* rpc);
|
||||
int rpc_recv_pdu(rdpRpc* rpc);
|
||||
|
||||
int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum);
|
||||
int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum);
|
||||
|
||||
rdpRpc* rpc_new(rdpTransport* transport);
|
||||
void rpc_free(rdpRpc* rpc);
|
||||
|
@ -217,11 +217,11 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc)
|
||||
BYTE* auth_data;
|
||||
rpcconn_hdr_t* header;
|
||||
|
||||
status = rpc_recv_pdu_fragment(rpc);
|
||||
status = rpc_recv_pdu(rpc);
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
header = (rpcconn_hdr_t*) rpc->buffer;
|
||||
header = (rpcconn_hdr_t*) rpc->FragBuffer;
|
||||
|
||||
rpc->max_recv_frag = header->bind_ack.max_xmit_frag;
|
||||
rpc->max_xmit_frag = header->bind_ack.max_recv_frag;
|
||||
@ -229,7 +229,7 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc)
|
||||
rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length;
|
||||
rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.auth_length);
|
||||
|
||||
auth_data = rpc->buffer + (header->common.frag_length - header->common.auth_length);
|
||||
auth_data = rpc->FragBuffer + (header->common.frag_length - header->common.auth_length);
|
||||
CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->common.auth_length);
|
||||
|
||||
ntlm_authenticate(rpc->ntlm);
|
||||
|
@ -33,29 +33,39 @@
|
||||
|
||||
int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
|
||||
{
|
||||
RPC_PDU_ENTRY* PduEntry;
|
||||
RPC_PDU* pdu;
|
||||
|
||||
PduEntry = (RPC_PDU_ENTRY*) _aligned_malloc(sizeof(RPC_PDU_ENTRY), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
PduEntry->Buffer = buffer;
|
||||
PduEntry->Length = length;
|
||||
pdu = (RPC_PDU*) _aligned_malloc(sizeof(RPC_PDU), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
pdu->Buffer = buffer;
|
||||
pdu->Length = length;
|
||||
|
||||
InterlockedPushEntrySList(rpc->SendQueue, &(PduEntry->ItemEntry));
|
||||
InterlockedPushEntrySList(rpc->SendQueue, &(pdu->ItemEntry));
|
||||
ReleaseSemaphore(rpc->client->SendSemaphore, 1, NULL);
|
||||
|
||||
if (rpc->client->SynchronousSend)
|
||||
{
|
||||
WaitForSingleObject(rpc->client->PduSentEvent, INFINITE);
|
||||
ResetEvent(rpc->client->PduSentEvent);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_send_dequeue_pdu(rdpRpc* rpc)
|
||||
{
|
||||
int status;
|
||||
RPC_PDU_ENTRY* PduEntry;
|
||||
RPC_PDU* pdu;
|
||||
|
||||
PduEntry = (RPC_PDU_ENTRY*) InterlockedPopEntrySList(rpc->SendQueue);
|
||||
pdu = (RPC_PDU*) InterlockedPopEntrySList(rpc->SendQueue);
|
||||
|
||||
if (!PduEntry)
|
||||
if (!pdu)
|
||||
return 0;
|
||||
|
||||
status = rpc_in_write(rpc, PduEntry->Buffer, PduEntry->Length);
|
||||
WaitForSingleObject(rpc->VirtualConnection->DefaultInChannel->Mutex, INFINITE);
|
||||
|
||||
status = rpc_in_write(rpc, pdu->Buffer, pdu->Length);
|
||||
|
||||
ReleaseMutex(rpc->VirtualConnection->DefaultInChannel->Mutex);
|
||||
|
||||
/*
|
||||
* This protocol specifies that only RPC PDUs are subject to the flow control abstract
|
||||
@ -66,41 +76,102 @@ int rpc_send_dequeue_pdu(rdpRpc* rpc)
|
||||
rpc->VirtualConnection->DefaultInChannel->BytesSent += status;
|
||||
rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow -= status;
|
||||
|
||||
free(PduEntry->Buffer);
|
||||
_aligned_free(PduEntry);
|
||||
free(pdu->Buffer);
|
||||
_aligned_free(pdu);
|
||||
|
||||
SetEvent(rpc->client->PduSentEvent);
|
||||
if (rpc->client->SynchronousSend)
|
||||
SetEvent(rpc->client->PduSentEvent);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int rpc_recv_enqueue_pdu(rdpRpc* rpc)
|
||||
{
|
||||
int status;
|
||||
RPC_PDU* pdu;
|
||||
|
||||
status = rpc_recv_pdu(rpc);
|
||||
|
||||
if (status <= 0)
|
||||
{
|
||||
printf("rpc_recv_enqueue_pdu error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pdu = rpc->pdu;
|
||||
rpc->pdu = (RPC_PDU*) _aligned_malloc(sizeof(RPC_PDU), MEMORY_ALLOCATION_ALIGNMENT);
|
||||
|
||||
if (pdu->Flags & RPC_PDU_FLAG_STUB)
|
||||
{
|
||||
rpc->StubBufferSize = rpc->max_recv_frag;
|
||||
rpc->StubBuffer = (BYTE*) malloc(rpc->StubBufferSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
rpc->FragBufferSize = rpc->max_recv_frag;
|
||||
rpc->FragBuffer = (BYTE*) malloc(rpc->FragBufferSize);
|
||||
}
|
||||
|
||||
InterlockedPushEntrySList(rpc->ReceiveQueue, &(pdu->ItemEntry));
|
||||
ReleaseSemaphore(rpc->client->ReceiveSemaphore, 1, NULL);
|
||||
|
||||
if (rpc->client->SynchronousReceive)
|
||||
{
|
||||
WaitForSingleObject(rpc->client->PduReceivedEvent, INFINITE);
|
||||
ResetEvent(rpc->client->PduReceivedEvent);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_recv_dequeue_pdu(rdpRpc* rpc)
|
||||
{
|
||||
if (rpc->client->SynchronousReceive)
|
||||
SetEvent(rpc->client->PduReceivedEvent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* rpc_client_thread(void* arg)
|
||||
{
|
||||
rdpRpc* rpc;
|
||||
DWORD status;
|
||||
DWORD nCount;
|
||||
HANDLE events[2];
|
||||
HANDLE events[3];
|
||||
HANDLE ReadEvent;
|
||||
|
||||
rpc = (rdpRpc*) arg;
|
||||
|
||||
ReadEvent = CreateFileDescriptorEvent(NULL, TRUE, FALSE, rpc->TlsOut->sockfd);
|
||||
|
||||
nCount = 0;
|
||||
events[nCount++] = rpc->client->StopEvent;
|
||||
events[nCount++] = rpc->client->SendSemaphore;
|
||||
events[nCount++] = ReadEvent;
|
||||
|
||||
while (1)
|
||||
{
|
||||
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
|
||||
|
||||
if (WaitForSingleObject(rpc->client->StopEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
rpc_send_dequeue_pdu(rpc);
|
||||
}
|
||||
|
||||
CloseHandle(ReadEvent);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rpc_client_start(rdpRpc* rpc)
|
||||
int rpc_client_new(rdpRpc* rpc)
|
||||
{
|
||||
rpc->client = (RpcClient*) malloc(sizeof(RpcClient));
|
||||
|
||||
@ -112,6 +183,11 @@ int rpc_client_start(rdpRpc* rpc)
|
||||
rpc->client->SendSemaphore = CreateSemaphore(NULL, 0, 64, NULL);
|
||||
rpc->client->PduSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rpc_client_start(rdpRpc* rpc)
|
||||
{
|
||||
ResumeThread(rpc->client->Thread);
|
||||
|
||||
return 0;
|
||||
|
@ -27,6 +27,7 @@
|
||||
int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length);
|
||||
int rpc_send_dequeue_pdu(rdpRpc* rpc);
|
||||
|
||||
int rpc_client_new(rdpRpc* rpc);
|
||||
int rpc_client_start(rdpRpc* rpc);
|
||||
|
||||
#endif /* FREERDP_CORE_RPC_CLIENT_H */
|
||||
|
@ -173,12 +173,12 @@ BOOL rts_connect(rdpRpc* rpc)
|
||||
*
|
||||
*/
|
||||
|
||||
status = rts_recv_pdu(rpc);
|
||||
status = rpc_recv_pdu(rpc);
|
||||
|
||||
if (status < 1)
|
||||
return FALSE;
|
||||
|
||||
rts = (rpcconn_rts_hdr_t*) rpc->buffer;
|
||||
rts = (rpcconn_rts_hdr_t*) rpc->FragBuffer;
|
||||
|
||||
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_A3_SIGNATURE, rts))
|
||||
{
|
||||
@ -186,7 +186,7 @@ BOOL rts_connect(rdpRpc* rpc)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rts_recv_CONN_A3_pdu(rpc, rpc->buffer, rpc->length);
|
||||
rts_recv_CONN_A3_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize);
|
||||
|
||||
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_WAIT_C2;
|
||||
DEBUG_RTS("VIRTUAL_CONNECTION_STATE_WAIT_C2");
|
||||
@ -212,12 +212,12 @@ BOOL rts_connect(rdpRpc* rpc)
|
||||
*
|
||||
*/
|
||||
|
||||
status = rts_recv_pdu(rpc);
|
||||
status = rpc_recv_pdu(rpc);
|
||||
|
||||
if (status < 1)
|
||||
return FALSE;
|
||||
|
||||
rts = (rpcconn_rts_hdr_t*) rpc->buffer;
|
||||
rts = (rpcconn_rts_hdr_t*) rpc->FragBuffer;
|
||||
|
||||
if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts))
|
||||
{
|
||||
@ -225,7 +225,7 @@ BOOL rts_connect(rdpRpc* rpc)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rts_recv_CONN_C2_pdu(rpc, rpc->buffer, rpc->length);
|
||||
rts_recv_CONN_C2_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize);
|
||||
|
||||
rpc->VirtualConnection->State = VIRTUAL_CONNECTION_STATE_OPENED;
|
||||
DEBUG_RTS("VIRTUAL_CONNECTION_STATE_OPENED");
|
||||
@ -952,35 +952,13 @@ int rts_command_length(rdpRpc* rpc, UINT32 CommandType, BYTE* buffer, UINT32 len
|
||||
return CommandLength;
|
||||
}
|
||||
|
||||
int rts_recv_pdu(rdpRpc* rpc)
|
||||
{
|
||||
int status;
|
||||
rpcconn_rts_hdr_t* rts;
|
||||
|
||||
status = rpc_recv_pdu_fragment(rpc);
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
rts = (rpcconn_rts_hdr_t*) rpc->buffer;
|
||||
|
||||
if (rts->ptype != PTYPE_RTS)
|
||||
{
|
||||
printf("rts_recv_pdu: Unexpected type 0x%02X, Expected: PTYPE_RTS (0x%02X)\n",
|
||||
rts->ptype, PTYPE_RTS);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int rts_recv_out_of_sequence_pdu(rdpRpc* rpc)
|
||||
{
|
||||
UINT32 SignatureId;
|
||||
rpcconn_rts_hdr_t* rts;
|
||||
RtsPduSignature signature;
|
||||
|
||||
rts = (rpcconn_rts_hdr_t*) rpc->buffer;
|
||||
rts = (rpcconn_rts_hdr_t*) rpc->FragBuffer;
|
||||
|
||||
rts_extract_pdu_signature(rpc, &signature, rts);
|
||||
rts_print_pdu_signature(rpc, &signature);
|
||||
@ -988,11 +966,11 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc)
|
||||
|
||||
if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK)
|
||||
{
|
||||
return rts_recv_flow_control_ack_pdu(rpc, rpc->buffer, rpc->length);
|
||||
return rts_recv_flow_control_ack_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize);
|
||||
}
|
||||
else if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION)
|
||||
{
|
||||
return rts_recv_flow_control_ack_with_destination_pdu(rpc, rpc->buffer, rpc->length);
|
||||
return rts_recv_flow_control_ack_with_destination_pdu(rpc, rpc->FragBuffer, rpc->FragBufferSize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -139,7 +139,6 @@ int rts_send_keep_alive_pdu(rdpRpc* rpc);
|
||||
int rts_send_flow_control_ack_pdu(rdpRpc* rpc);
|
||||
int rts_send_ping_pdu(rdpRpc* rpc);
|
||||
|
||||
int rts_recv_pdu(rdpRpc* rpc);
|
||||
int rts_recv_out_of_sequence_pdu(rdpRpc* rpc);
|
||||
|
||||
#include "rts_signature.h"
|
||||
|
@ -121,13 +121,13 @@ DWORD TsProxySendToServer(handle_t IDL_handle, byte pRpcMessage[], UINT32 count,
|
||||
stream_seal(s);
|
||||
|
||||
length = s->size;
|
||||
status = rpc_tsg_write(tsg->rpc, s->data, s->size, TsProxySendToServerOpnum);
|
||||
status = rpc_write(tsg->rpc, s->data, s->size, TsProxySendToServerOpnum);
|
||||
|
||||
stream_free(s);
|
||||
|
||||
if (status <= 0)
|
||||
{
|
||||
printf("rpc_tsg_write failed!\n");
|
||||
printf("rpc_write failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg)
|
||||
|
||||
CopyMemory(&buffer[48], TsProxyCreateTunnelUnknownTrailerBytes, 60);
|
||||
|
||||
status = rpc_tsg_write(rpc, buffer, length, TsProxyCreateTunnelOpnum);
|
||||
status = rpc_write(rpc, buffer, length, TsProxyCreateTunnelOpnum);
|
||||
|
||||
if (status <= 0)
|
||||
return FALSE;
|
||||
@ -537,7 +537,7 @@ BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg)
|
||||
*((UINT32*) &buffer[offset]) = 0x00000000; /* MaxCount */
|
||||
offset += 4;
|
||||
|
||||
status = rpc_tsg_write(rpc, buffer, length, TsProxyAuthorizeTunnelOpnum);
|
||||
status = rpc_write(rpc, buffer, length, TsProxyAuthorizeTunnelOpnum);
|
||||
|
||||
if (status <= 0)
|
||||
return FALSE;
|
||||
@ -566,7 +566,7 @@ BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg)
|
||||
return FALSE;
|
||||
|
||||
length = status;
|
||||
buffer = rpc->buffer;
|
||||
buffer = rpc->FragBuffer;
|
||||
|
||||
packet = (PTSG_PACKET) malloc(sizeof(TSG_PACKET));
|
||||
ZeroMemory(packet, sizeof(TSG_PACKET));
|
||||
@ -684,7 +684,7 @@ BOOL TsProxyMakeTunnelCallWriteRequest(rdpTsg* tsg)
|
||||
|
||||
*((UINT32*) &buffer[36]) = 0x00000001; /* MaxMessagesPerBatch */
|
||||
|
||||
status = rpc_tsg_write(rpc, buffer, length, TsProxyMakeTunnelCallOpnum);
|
||||
status = rpc_write(rpc, buffer, length, TsProxyMakeTunnelCallOpnum);
|
||||
|
||||
if (status <= 0)
|
||||
return FALSE;
|
||||
@ -775,7 +775,7 @@ BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg)
|
||||
*((UINT32*) &buffer[56]) = count; /* ActualCount */
|
||||
CopyMemory(&buffer[60], tsg->Hostname, count * 2); /* Array */
|
||||
|
||||
status = rpc_tsg_write(rpc, buffer, length, TsProxyCreateChannelOpnum);
|
||||
status = rpc_write(rpc, buffer, length, TsProxyCreateChannelOpnum);
|
||||
|
||||
if (status <= 0)
|
||||
return FALSE;
|
||||
@ -798,11 +798,11 @@ BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg)
|
||||
return FALSE;
|
||||
|
||||
length = status;
|
||||
buffer = rpc->buffer;
|
||||
buffer = rpc->FragBuffer;
|
||||
|
||||
/* ChannelContext (20 bytes) */
|
||||
CopyMemory(&tsg->ChannelContext.ContextType, &rpc->buffer[24], 4); /* ContextType (4 bytes) */
|
||||
CopyMemory(tsg->ChannelContext.ContextUuid, &rpc->buffer[28], 16); /* ContextUuid (16 bytes) */
|
||||
CopyMemory(&tsg->ChannelContext.ContextType, &rpc->FragBuffer[24], 4); /* ContextType (4 bytes) */
|
||||
CopyMemory(tsg->ChannelContext.ContextUuid, &rpc->FragBuffer[28], 16); /* ContextUuid (16 bytes) */
|
||||
|
||||
/* TODO: trailing bytes */
|
||||
|
||||
@ -871,7 +871,7 @@ BOOL TsProxySetupReceivePipeWriteRequest(rdpTsg* tsg)
|
||||
CopyMemory(&buffer[0], &tsg->ChannelContext.ContextType, 4); /* ContextType */
|
||||
CopyMemory(&buffer[4], tsg->ChannelContext.ContextUuid, 16); /* ContextUuid */
|
||||
|
||||
status = rpc_tsg_write(rpc, buffer, length, TsProxySetupReceivePipeOpnum);
|
||||
status = rpc_write(rpc, buffer, length, TsProxySetupReceivePipeOpnum);
|
||||
|
||||
if (status <= 0)
|
||||
return FALSE;
|
||||
@ -885,7 +885,7 @@ BOOL TsProxySetupReceivePipeReadResponse(rdpTsg* tsg)
|
||||
{
|
||||
#if 0
|
||||
int status;
|
||||
BYTE* buffer;
|
||||
BYTE* FragBuffer;
|
||||
UINT32 length;
|
||||
rdpRpc* rpc = tsg->rpc;
|
||||
|
||||
@ -895,7 +895,7 @@ BOOL TsProxySetupReceivePipeReadResponse(rdpTsg* tsg)
|
||||
return FALSE;
|
||||
|
||||
length = status;
|
||||
buffer = rpc->buffer;
|
||||
FragBuffer = rpc->FragBuffer;
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
@ -951,6 +951,8 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port)
|
||||
|
||||
tsg->state = TSG_STATE_INITIAL;
|
||||
|
||||
rpc->client->SynchronousSend = TRUE;
|
||||
|
||||
/*
|
||||
* Sequential processing rules for connection process:
|
||||
*
|
||||
@ -1091,6 +1093,8 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port)
|
||||
|
||||
tsg->state = TSG_STATE_PIPE_CREATED;
|
||||
|
||||
rpc->client->SynchronousSend = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user