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

This commit is contained in:
Marc-André Moreau 2014-03-11 11:55:49 -04:00
commit 8b15db3b66
19 changed files with 152 additions and 42 deletions

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

@ -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);
@ -1269,6 +1270,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;
@ -1045,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)