Merge branch 'master' of github.com:awakecoding/FreeRDP into mppc

This commit is contained in:
Marc-André Moreau
2014-03-11 11:57:01 -04:00
21 changed files with 286 additions and 150 deletions

View File

@@ -379,11 +379,21 @@ int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
int rdpei_recv_suspend_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
{
RdpeiClientContext* rdpei = (RdpeiClientContext*) callback->plugin->pInterface;
if (rdpei->SuspendTouch)
rdpei->SuspendTouch(rdpei);
return 0;
}
int rdpei_recv_resume_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
{
RdpeiClientContext* rdpei = (RdpeiClientContext*) callback->plugin->pInterface;
if (rdpei->ResumeTouch)
rdpei->ResumeTouch(rdpei);
return 0;
}
@@ -490,7 +500,7 @@ static int rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage
(IWTSListenerCallback*) rdpei->listener_callback, &(rdpei->listener));
rdpei->listener->pInterface = rdpei->iface.pInterface;
InitializeCriticalSection(&rdpei->lock);
rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL);
rdpei->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -675,7 +685,7 @@ int rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y)
int i;
int contactId = -1;
RDPINPUT_CONTACT_DATA contact;
RDPINPUT_CONTACT_POINT* contactPoint;
RDPINPUT_CONTACT_POINT* contactPoint = NULL;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
for (i = 0; i < rdpei->maxTouchContacts; i++)

View File

@@ -59,8 +59,13 @@ void mac_set_view_size(rdpContext* context, MRDPView* view);
- (void) applicationWillTerminate:(NSNotification*)notification
{
NSLog(@"Stopping...\n");
freerdp_client_stop(context);
[mrdpView releaseResources];
_singleDelegate = nil;
NSLog(@"Stopped.\n");
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender

View File

@@ -31,6 +31,8 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} wfreerdp-client)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
install(TARGETS ${MODULE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client)
if(VENDOR MATCHES "FreeRDP")
install(TARGETS ${MODULE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client)
endif()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Windows")

View File

@@ -31,6 +31,7 @@
#include "wf_gdi.h"
#include "wf_event.h"
#include "freerdp/event.h"
static HWND g_focus_hWnd;
@@ -575,6 +576,8 @@ BOOL wf_scale_blt(wfContext* wfc, HDC hdc, int x, int y, int w, int h, HDC hdcSr
void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
int ww, wh, dw, dh;
rdpContext* context;
MouseEventEventArgs eventArgs;
if (!wfc->client_width)
wfc->client_width = wfc->width;
@@ -591,4 +594,10 @@ void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16
input->MouseEvent(input, flags, x + wfc->xCurrentScroll, y + wfc->yCurrentScroll);
else
input->MouseEvent(input, flags, x * dw / ww + wfc->xCurrentScroll, y * dh / wh + wfc->yCurrentScroll);
eventArgs.flags = flags;
eventArgs.x = x;
eventArgs.y = y;
context = (rdpContext*) wfc;
PubSub_OnMouseEvent(context->pubSub, context, &eventArgs);
}

View File

@@ -18,6 +18,13 @@
set(MODULE_NAME "freerdp-client")
set(MODULE_PREFIX "FREERDP_CLIENT")
# Policy CMP0022: INTERFACE_LINK_LIBRARIES defines the link
# interface. Run "cmake --help-policy CMP0022" for policy details. Use the
# cmake_policy command to set the policy and suppress this warning.
if(POLICY CMP0022)
cmake_policy(SET CMP0022 NEW)
endif()
set(${MODULE_PREFIX}_SRCS
client.c
cmdline.c
@@ -53,10 +60,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHI
MODULE winpr
MODULES winpr-crt winpr-utils)
if(NOT WIN32)
set_target_properties(${MODULE_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "")
set_target_properties(${MODULE_NAME} PROPERTIES INTERFACE_LINK_LIBRARIES "")
endif()
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})

View File

@@ -70,6 +70,9 @@ typedef int (*pcRdpeiTouchBegin)(RdpeiClientContext* context, int externalId, in
typedef int (*pcRdpeiTouchUpdate)(RdpeiClientContext* context, int externalId, int x, int y);
typedef int (*pcRdpeiTouchEnd)(RdpeiClientContext* context, int externalId, int x, int y);
typedef int (*pcRdpeiSuspendTouch)(RdpeiClientContext* context);
typedef int (*pcRdpeiResumeTouch)(RdpeiClientContext* context);
struct _rdpei_client_context
{
void* handle;
@@ -82,6 +85,9 @@ struct _rdpei_client_context
pcRdpeiTouchBegin TouchBegin;
pcRdpeiTouchUpdate TouchUpdate;
pcRdpeiTouchEnd TouchEnd;
pcRdpeiSuspendTouch SuspendTouch;
pcRdpeiResumeTouch ResumeTouch;
};
#endif /* FREERDP_CHANNEL_CLIENT_RDPEI_H */

View File

@@ -146,6 +146,7 @@ extern "C" {
#define ERRINFO_ENCRYPT_FAILED 0x00001193
#define ERRINFO_ENCRYPTION_PACKAGE_MISMATCH 0x00001194
#define ERRINFO_DECRYPT_FAILED2 0x00001195
#define ERRINFO_PEER_DISCONNECTED 0x00001196
#define ERRINFO_SUCCESS 0x00000000
#define ERRINFO_NONE 0xFFFFFFFF

View File

@@ -83,6 +83,12 @@ DEFINE_EVENT_BEGIN(ChannelDisconnected)
void* pInterface;
DEFINE_EVENT_END(ChannelDisconnected)
DEFINE_EVENT_BEGIN(MouseEvent)
UINT16 flags;
UINT16 x;
UINT16 y;
DEFINE_EVENT_END(MouseEvent)
#ifdef __cplusplus
}
#endif

View File

@@ -385,6 +385,9 @@ int connectErrorCode;
#define ERRINFO_DECRYPT_FAILED2_STRING \
"Unencrypted data was encountered in a protocol stream which is meant to be encrypted with Standard RDP Security mechanisms (section 5.3.6)."
#define ERRINFO_PEER_DISCONNECTED_STRING \
"The peer connection was lost."
/* Special codes */
#define ERRINFO_SUCCESS_STRING "Success."
#define ERRINFO_NONE_STRING ""
@@ -507,6 +510,7 @@ static const ERRINFO ERRINFO_CODES[] =
ERRINFO_DEFINE(ENCRYPT_FAILED),
ERRINFO_DEFINE(ENCRYPTION_PACKAGE_MISMATCH),
ERRINFO_DEFINE(DECRYPT_FAILED2),
ERRINFO_DEFINE(PEER_DISCONNECTED),
ERRINFO_DEFINE(NONE)
};

View File

@@ -375,6 +375,7 @@ static wEventType FreeRDP_Events[] =
DEFINE_EVENT_ENTRY(ConnectionResult)
DEFINE_EVENT_ENTRY(ChannelConnected)
DEFINE_EVENT_ENTRY(ChannelDisconnected)
DEFINE_EVENT_ENTRY(MouseEvent)
};
/** Allocator function for a rdp context.

View File

@@ -447,7 +447,9 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum)
offset += Buffers[1].cbBuffer;
free(Buffers[1].pvBuffer);
rpc_send_enqueue_pdu(rpc, buffer, request_pdu->frag_length);
if (rpc_send_enqueue_pdu(rpc, buffer, request_pdu->frag_length) != 0)
length = -1;
free(request_pdu);
return length;

View File

@@ -215,7 +215,8 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
clientCall = rpc_client_call_new(bind_pdu->call_id, 0);
ArrayList_Add(rpc->client->ClientCallList, clientCall);
rpc_send_enqueue_pdu(rpc, buffer, length);
if (rpc_send_enqueue_pdu(rpc, buffer, length) != 0)
length = -1;
free(bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes);
free(bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes);
@@ -330,7 +331,8 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
clientCall = rpc_client_call_new(auth_3_pdu->call_id, 0);
ArrayList_Add(rpc->client->ClientCallList, clientCall);
rpc_send_enqueue_pdu(rpc, buffer, length);
if (rpc_send_enqueue_pdu(rpc, buffer, length) != 0)
length = -1;
free(auth_3_pdu);

View File

@@ -25,6 +25,8 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/tcp.h>
#include <winpr/crt.h>
#include <winpr/print.h>
#include <winpr/synch.h>
@@ -37,6 +39,8 @@
#include "../rdp.h"
#define SYNCHRONOUS_TIMEOUT 5000
wStream* rpc_client_fragment_pool_take(rdpRpc* rpc)
{
wStream* fragment = NULL;
@@ -364,6 +368,7 @@ void rpc_client_call_free(RpcClientCall* clientCall)
int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
{
RPC_PDU* pdu;
int status;
pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU));
pdu->s = Stream_New(buffer, length);
@@ -372,7 +377,13 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length)
if (rpc->client->SynchronousSend)
{
WaitForSingleObject(rpc->client->PduSentEvent, INFINITE);
status = WaitForSingleObject(rpc->client->PduSentEvent, SYNCHRONOUS_TIMEOUT);
if (status == WAIT_TIMEOUT)
{
fprintf(stderr, "rpc_send_enqueue_pdu: timed out waiting for pdu sent event\n");
return -1;
}
ResetEvent(rpc->client->PduSentEvent);
}
@@ -427,11 +438,19 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc)
{
RPC_PDU* pdu;
DWORD dwMilliseconds;
DWORD result;
pdu = NULL;
dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0;
dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0;
if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0)
result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds);
if (result == WAIT_TIMEOUT)
{
fprintf(stderr, "rpc_recv_dequeue_pdu: timed out waiting for receive event\n");
return NULL;
}
if (result == WAIT_OBJECT_0)
{
pdu = (RPC_PDU*) Queue_Dequeue(rpc->client->ReceiveQueue);
@@ -454,11 +473,18 @@ RPC_PDU* rpc_recv_peek_pdu(rdpRpc* rpc)
{
RPC_PDU* pdu;
DWORD dwMilliseconds;
DWORD result;
pdu = NULL;
dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0;
dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0;
if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0)
result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds);
if (result == WAIT_TIMEOUT)
{
return NULL;
}
if (result == WAIT_OBJECT_0)
{
pdu = (RPC_PDU*) Queue_Peek(rpc->client->ReceiveQueue);
return pdu;
@@ -484,24 +510,27 @@ static void* rpc_client_thread(void* arg)
events[nCount++] = Queue_Event(rpc->client->SendQueue);
events[nCount++] = ReadEvent;
while (1)
while (rpc->transport->layer != TRANSPORT_LAYER_CLOSED)
{
status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
status = WaitForMultipleObjects(nCount, events, FALSE, 100);
if (WaitForSingleObject(rpc->client->StopEvent, 0) == WAIT_OBJECT_0)
if (status != WAIT_TIMEOUT)
{
break;
}
if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0)
{
if (rpc_client_on_read_event(rpc) < 0)
if (WaitForSingleObject(rpc->client->StopEvent, 0) == WAIT_OBJECT_0)
{
break;
}
}
if (WaitForSingleObject(Queue_Event(rpc->client->SendQueue), 0) == WAIT_OBJECT_0)
{
rpc_send_dequeue_pdu(rpc);
if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0)
{
if (rpc_client_on_read_event(rpc) < 0)
break;
}
if (WaitForSingleObject(Queue_Event(rpc->client->SendQueue), 0) == WAIT_OBJECT_0)
{
rpc_send_dequeue_pdu(rpc);
}
}
}

View File

@@ -1494,6 +1494,12 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
rpc = tsg->rpc;
if (rpc->transport->layer == TRANSPORT_LAYER_CLOSED)
{
fprintf(stderr, "tsg_read error: connection lost\n");
return -1;
}
if (tsg->PendingPdu)
{
CopyLength = (length < tsg->BytesAvailable) ? length : tsg->BytesAvailable;
@@ -1546,6 +1552,12 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
int tsg_write(rdpTsg* tsg, BYTE* data, UINT32 length)
{
if (tsg->rpc->transport->layer == TRANSPORT_LAYER_CLOSED)
{
fprintf(stderr, "tsg_write error: connection lost\n");
return -1;
}
return TsProxySendToServer((handle_t) tsg, data, 1, &length);
}

View File

@@ -1220,6 +1220,7 @@ rdpRdp* rdp_new(rdpContext* context)
rdp->extension = extension_new(context->instance);
rdp->transport = transport_new(rdp->settings);
rdp->transport->rdp = rdp;
rdp->license = license_new(rdp);
rdp->input = input_new(rdp);
rdp->update = update_new(rdp);
@@ -1268,6 +1269,7 @@ void rdp_reset(rdpRdp* rdp)
settings->ClientAddress = NULL;
rdp->transport = transport_new(rdp->settings);
rdp->transport->rdp = rdp;
rdp->license = license_new(rdp);
rdp->nego = nego_new(rdp->transport);
rdp->mcs = mcs_new(rdp->transport);

View File

@@ -223,4 +223,6 @@ void rdp_free(rdpRdp* rdp);
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags);
BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo);
#endif /* __RDP_H */

View File

@@ -46,6 +46,7 @@
#include "tpkt.h"
#include "fastpath.h"
#include "transport.h"
#include "rdp.h"
#define BUFFER_SIZE 16384
@@ -82,7 +83,7 @@ BOOL transport_disconnect(rdpTransport* transport)
if ((transport->layer == TRANSPORT_LAYER_TSG) || (transport->layer == TRANSPORT_LAYER_TSG_TLS))
{
tsg_disconnect(transport->tsg);
status &= tsg_disconnect(transport->tsg);
}
else
{
@@ -129,12 +130,12 @@ static int transport_bio_tsg_write(BIO* bio, const char* buf, int num)
BIO_clear_retry_flags(bio);
if (status <= 0)
if (status == 0)
{
BIO_set_retry_write(bio);
}
return num;
return status < 0 ? 0 : num;
}
static int transport_bio_tsg_read(BIO* bio, char* buf, int size)
@@ -147,12 +148,17 @@ static int transport_bio_tsg_read(BIO* bio, char* buf, int size)
BIO_clear_retry_flags(bio);
if (status <= 0)
if (status == 0)
{
BIO_set_retry_read(bio);
status = -1;
}
else if (status == -1)
{
status = 0;
}
return status > 0 ? status : -1;
return status >= 0 ? status : -1;
}
static int transport_bio_tsg_puts(BIO* bio, const char* str)
@@ -556,7 +562,11 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes)
return status;
if (status < 0)
{
/* A read error indicates that the peer has dropped the connection */
transport->layer = TRANSPORT_LAYER_CLOSED;
return status;
}
read += status;
@@ -853,115 +863,125 @@ int transport_check_fds(rdpTransport* transport)
#endif
ResetEvent(transport->ReceiveEvent);
status = transport_read_nonblocking(transport);
if (status < 0)
return status;
while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0)
/**
* Loop through and read all available PDUs. Since multiple
* PDUs can exist, it's important to deliver them all before
* returning. Otherwise we run the risk of having a thread
* wait for a socket to get signalled that data is available
* (which may never happen).
*/
for (;;)
{
Stream_SetPosition(transport->ReceiveBuffer, 0);
status = transport_read_nonblocking(transport);
if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */
{
/* Ensure the TPKT header is available. */
if (pos <= 4)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
length = tpkt_read_header(transport->ReceiveBuffer);
}
else if (nla_verify_header(transport->ReceiveBuffer))
{
/* TSRequest */
/* Ensure the TSRequest header is available. */
if (pos <= 4)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
/* TSRequest header can be 2, 3 or 4 bytes long */
length = nla_header_length(transport->ReceiveBuffer);
if (pos < length)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
length = nla_read_header(transport->ReceiveBuffer);
}
else /* Fast Path */
{
/* Ensure the Fast Path header is available. */
if (pos <= 2)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
/* Fastpath header can be two or three bytes long. */
length = fastpath_header_length(transport->ReceiveBuffer);
if (pos < length)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
length = fastpath_read_header(NULL, transport->ReceiveBuffer);
}
if (length == 0)
{
fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos);
return -1;
}
if (pos < length)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0; /* Packet is not yet completely received. */
}
received = transport->ReceiveBuffer;
transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
Stream_SetPosition(received, length);
Stream_SealLength(received);
Stream_SetPosition(received, 0);
/**
* status:
* -1: error
* 0: success
* 1: redirection
*/
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
if (recv_status == 1)
{
/**
* Last call to ReceiveCallback resulted in a session redirection,
* which means the current rdpTransport* transport pointer has been freed.
* Return 0 for success, the rest of this function is meant for non-redirected cases.
*/
return 0;
}
Stream_Release(received);
if (recv_status < 0)
status = -1;
if (status < 0)
if (status <= 0)
return status;
while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0)
{
Stream_SetPosition(transport->ReceiveBuffer, 0);
if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */
{
/* Ensure the TPKT header is available. */
if (pos <= 4)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
length = tpkt_read_header(transport->ReceiveBuffer);
}
else if (nla_verify_header(transport->ReceiveBuffer))
{
/* TSRequest */
/* Ensure the TSRequest header is available. */
if (pos <= 4)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
/* TSRequest header can be 2, 3 or 4 bytes long */
length = nla_header_length(transport->ReceiveBuffer);
if (pos < length)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
length = nla_read_header(transport->ReceiveBuffer);
}
else /* Fast Path */
{
/* Ensure the Fast Path header is available. */
if (pos <= 2)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
/* Fastpath header can be two or three bytes long. */
length = fastpath_header_length(transport->ReceiveBuffer);
if (pos < length)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0;
}
length = fastpath_read_header(NULL, transport->ReceiveBuffer);
}
if (length == 0)
{
fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos);
return -1;
}
if (pos < length)
{
Stream_SetPosition(transport->ReceiveBuffer, pos);
return 0; /* Packet is not yet completely received. */
}
received = transport->ReceiveBuffer;
transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
Stream_SetPosition(received, length);
Stream_SealLength(received);
Stream_SetPosition(received, 0);
/**
* status:
* -1: error
* 0: success
* 1: redirection
*/
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
if (recv_status == 1)
{
/**
* Last call to ReceiveCallback resulted in a session redirection,
* which means the current rdpTransport* transport pointer has been freed.
* Return 0 for success, the rest of this function is meant for non-redirected cases.
*/
return 0;
}
Stream_Release(received);
if (recv_status < 0)
status = -1;
if (status < 0)
return status;
}
}
return 0;
@@ -1035,13 +1055,21 @@ static void* transport_client_thread(void* arg)
transport_get_read_handles(transport, (HANDLE*) &handles, &nCount);
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
status = WaitForMultipleObjects(nCount, handles, FALSE, 100);
if (transport->layer == TRANSPORT_LAYER_CLOSED)
{
rdpRdp* rdp = (rdpRdp*) transport->rdp;
rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED);
break;
}
else if (status != WAIT_TIMEOUT)
{
if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0)
break;
if (!freerdp_check_fds(instance))
break;
if (!freerdp_check_fds(instance))
break;
}
}
WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread");

View File

@@ -78,6 +78,7 @@ struct rdp_transport
CRITICAL_SECTION ReadLock;
CRITICAL_SECTION WriteLock;
wLog* log;
void* rdp;
};
wStream* transport_send_stream_init(rdpTransport* transport, int size);

View File

@@ -464,7 +464,12 @@ int tls_write(rdpTls* tls, BYTE* data, int length)
status = SSL_write(tls->ssl, data, length);
if (status <= 0)
if (status == 0)
{
return -1; /* peer disconnected */
}
if (status < 0)
{
error = SSL_get_error(tls->ssl, status);

View File

@@ -311,6 +311,10 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
PVOID Object;
BOOL status = TRUE;
if (hFile == INVALID_HANDLE_VALUE) {
return FALSE;
}
/*
* from http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx
* lpNumberOfBytesRead can be NULL only when the lpOverlapped parameter is not NULL.
@@ -464,6 +468,10 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
PVOID Object;
BOOL status = TRUE;
if (hFile == INVALID_HANDLE_VALUE) {
return FALSE;
}
if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
return FALSE;

View File

@@ -155,11 +155,8 @@ static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds)
ts->tv_sec += dwMilliseconds / 1000L;
ts->tv_nsec += (dwMilliseconds % 1000L) * 1000000L;
while(ts->tv_nsec >= 1000000000L)
{
ts->tv_sec ++;
ts->tv_nsec -= 1000000000L;
}
ts->tv_sec += ts->tv_nsec / 1000000000L;
ts->tv_nsec = ts->tv_nsec % 1000000000L;
}
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)