Fix unchecked CreateEvent calls and misc fixes
1) Added missing checks for CreateEvent which also required the following related changes: - changed freerdp_context_new API to BOOL - changed freerdp_peer_context_new API to BOOL - changed pRdpClientNew callback to BOOL - changed pContextNew callback to BOOL - changed psPeerAccepted callback to BOOL - changed psPeerContextNew callback to BOOL 2) Fixed lots of missing alloc and error checks in the changed code's neighbourhood. 3) Check freerdp_client_codecs_prepare result to avoid segfaults caused by using non-initialized codecs. 4) Fixed deadlocks in x11 caused by missing xf_unlock_x11() calls in some error handlers 5) Some fixes in thread pool: - DEFAULT_POOL assignment did not match TP_POOL definition - don't free the pool pointer if it points to the static DEFAULT_POOL - added error handling and cleanup in InitializeThreadpool
This commit is contained in:
parent
19dc7b7440
commit
ef1fd12b15
@ -326,12 +326,23 @@ int android_cliprdr_server_file_contents_response(CliprdrClientContext* cliprdr,
|
||||
|
||||
int android_cliprdr_init(androidContext* afc, CliprdrClientContext* cliprdr)
|
||||
{
|
||||
cliprdr->custom = (void*) afc;
|
||||
wClipboard* clipboard;
|
||||
HANDLE hevent;
|
||||
|
||||
if (!(hevent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
return 0;
|
||||
|
||||
if (!(clipboard = ClipboardCreate()))
|
||||
{
|
||||
CloseHandle(hevent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
afc->cliprdr = cliprdr;
|
||||
afc->clipboard = clipboard;
|
||||
afc->clipboardRequestEvent = hevent;
|
||||
|
||||
afc->clipboard = ClipboardCreate();
|
||||
afc->clipboardRequestEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
cliprdr->custom = (void*) afc;
|
||||
cliprdr->MonitorReady = android_cliprdr_monitor_ready;
|
||||
cliprdr->ServerCapabilities = android_cliprdr_server_capabilities;
|
||||
cliprdr->ServerFormatList = android_cliprdr_server_format_list;
|
||||
|
@ -48,17 +48,22 @@
|
||||
#include "jni/prof.h"
|
||||
#endif
|
||||
|
||||
int android_context_new(freerdp* instance, rdpContext* context)
|
||||
BOOL android_context_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
context->channels = freerdp_channels_new();
|
||||
if (!(context->channels = freerdp_channels_new()))
|
||||
return FALSE;
|
||||
android_event_queue_init(instance);
|
||||
return 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void android_context_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
freerdp_channels_close(instance->context->channels, instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
if (context && context->channels)
|
||||
{
|
||||
freerdp_channels_close(context->channels, instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
context->channels = NULL;
|
||||
}
|
||||
android_event_queue_uninit(instance);
|
||||
}
|
||||
|
||||
@ -622,7 +627,8 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls)
|
||||
#endif
|
||||
|
||||
// create instance
|
||||
instance = freerdp_new();
|
||||
if (!(instance = freerdp_new()))
|
||||
return NULL;
|
||||
instance->PreConnect = android_pre_connect;
|
||||
instance->PostConnect = android_post_connect;
|
||||
instance->PostDisconnect = android_post_disconnect;
|
||||
@ -634,7 +640,12 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls)
|
||||
instance->ContextSize = sizeof(androidContext);
|
||||
instance->ContextNew = android_context_new;
|
||||
instance->ContextFree = android_context_free;
|
||||
freerdp_context_new(instance);
|
||||
|
||||
if (!freerdp_context_new(instance))
|
||||
{
|
||||
freerdp_free(instance);
|
||||
instance = NULL;
|
||||
}
|
||||
|
||||
return (jint) instance;
|
||||
}
|
||||
|
@ -49,15 +49,22 @@ struct thread_data
|
||||
freerdp* instance;
|
||||
};
|
||||
|
||||
int df_context_new(freerdp* instance, rdpContext* context)
|
||||
BOOL df_context_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
context->channels = freerdp_channels_new();
|
||||
return 0;
|
||||
if (!(context->channels = freerdp_channels_new()))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void df_context_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
|
||||
if (context && context->channels)
|
||||
{
|
||||
freerdp_channels_close(context->channels, instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
context->channels = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void df_begin_paint(rdpContext* context)
|
||||
@ -458,7 +465,12 @@ int main(int argc, char* argv[])
|
||||
instance->ContextSize = sizeof(dfContext);
|
||||
instance->ContextNew = df_context_new;
|
||||
instance->ContextFree = df_context_free;
|
||||
freerdp_context_new(instance);
|
||||
|
||||
if (!freerdp_context_new(instance))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create FreeRDP context");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
context = (dfContext*) instance->context;
|
||||
channels = instance->context->channels;
|
||||
|
@ -45,10 +45,12 @@ struct tf_context
|
||||
};
|
||||
typedef struct tf_context tfContext;
|
||||
|
||||
static int tf_context_new(freerdp* instance, rdpContext* context)
|
||||
static BOOL tf_context_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
context->channels = freerdp_channels_new();
|
||||
return 0;
|
||||
if (!(context->channels = freerdp_channels_new()))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void tf_context_free(freerdp* instance, rdpContext* context)
|
||||
@ -57,6 +59,7 @@ static void tf_context_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
freerdp_channels_close(context->channels, instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
context->channels = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,7 +187,8 @@ int main(int argc, char* argv[])
|
||||
instance->ContextSize = sizeof(tfContext);
|
||||
instance->ContextNew = tf_context_new;
|
||||
instance->ContextFree = tf_context_free;
|
||||
if (freerdp_context_new(instance) != 0)
|
||||
|
||||
if (!freerdp_context_new(instance))
|
||||
{
|
||||
WLog_ERR(TAG, "Couldn't create context");
|
||||
exit(1);
|
||||
|
@ -26,11 +26,12 @@
|
||||
|
||||
#include "wlfreerdp.h"
|
||||
|
||||
static int wl_context_new(freerdp* instance, rdpContext* context)
|
||||
static BOOL wl_context_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
context->channels = freerdp_channels_new();
|
||||
if (!(context->channels = freerdp_channels_new()))
|
||||
return FALSE;
|
||||
|
||||
return 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wl_context_free(freerdp* instance, rdpContext* context)
|
||||
@ -39,6 +40,7 @@ static void wl_context_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
freerdp_channels_close(context->channels, instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
context->channels = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,11 +1012,15 @@ void wfreerdp_client_global_uninit(void)
|
||||
WSACleanup();
|
||||
}
|
||||
|
||||
int wfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
BOOL wfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
wfContext* wfc = (wfContext*) context;
|
||||
|
||||
wfreerdp_client_global_init();
|
||||
if (!(wfreerdp_client_global_init()))
|
||||
return FALSE;
|
||||
|
||||
if (!(context->channels = freerdp_channels_new()))
|
||||
return FALSE;
|
||||
|
||||
instance->PreConnect = wf_pre_connect;
|
||||
instance->PostConnect = wf_post_connect;
|
||||
@ -1025,20 +1029,27 @@ int wfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
|
||||
wfc->instance = instance;
|
||||
wfc->settings = instance->settings;
|
||||
context->channels = freerdp_channels_new();
|
||||
|
||||
return 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void wfreerdp_client_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
rdpChannels* channels = context->channels;
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
if (context->channels)
|
||||
{
|
||||
freerdp_channels_close(context->channels, instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
context->channels = NULL;
|
||||
}
|
||||
|
||||
if (context->cache)
|
||||
{
|
||||
cache_free(context->cache);
|
||||
|
||||
freerdp_channels_close(channels, instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
context->cache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int wfreerdp_client_start(rdpContext* context)
|
||||
|
@ -1975,10 +1975,36 @@ void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr)
|
||||
clipboard = wfc->clipboard;
|
||||
clipboard->wfc = wfc;
|
||||
clipboard->context = cliprdr;
|
||||
|
||||
cliprdr->custom = (void*) wfc->clipboard;
|
||||
clipboard->context = cliprdr;
|
||||
|
||||
clipboard->channels = context->channels;
|
||||
clipboard->sync = FALSE;
|
||||
|
||||
clipboard->map_capacity = 32;
|
||||
clipboard->map_size = 0;
|
||||
|
||||
if (!(clipboard->format_mappings = (formatMapping*) calloc(1, sizeof(formatMapping) * clipboard->map_capacity)))
|
||||
goto fail_format_mappings;
|
||||
|
||||
clipboard->file_array_size = 32;
|
||||
if (!(clipboard->file_names = (WCHAR**) calloc(1, clipboard->file_array_size * sizeof(WCHAR*))))
|
||||
goto fail_file_names;
|
||||
|
||||
if (!(clipboard->fileDescriptor = (FILEDESCRIPTORW**) calloc(1, clipboard->file_array_size * sizeof(FILEDESCRIPTORW*))))
|
||||
goto fail_file_descriptor;
|
||||
|
||||
if (!(clipboard->response_data_event = CreateEvent(NULL, TRUE, FALSE, _T("response_data_event"))))
|
||||
goto fail_data_event;
|
||||
|
||||
if (!(clipboard->req_fevent = CreateEvent(NULL, TRUE, FALSE, _T("request_filecontents_event"))))
|
||||
goto fail_filecontents_event;
|
||||
|
||||
clipboard->ID_FILEDESCRIPTORW = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW);
|
||||
clipboard->ID_FILECONTENTS = RegisterClipboardFormatW(CFSTR_FILECONTENTS);
|
||||
clipboard->ID_PREFERREDDROPEFFECT = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT);
|
||||
|
||||
if (!(clipboard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) cliprdr_thread_func, clipboard, 0, NULL)))
|
||||
goto fail_clipboard_thread;
|
||||
|
||||
cliprdr->MonitorReady = wf_cliprdr_monitor_ready;
|
||||
cliprdr->ServerCapabilities = wf_cliprdr_server_capabilities;
|
||||
cliprdr->ServerFormatList = wf_cliprdr_server_format_list;
|
||||
@ -1989,27 +2015,30 @@ void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr)
|
||||
cliprdr->ServerFormatDataResponse = wf_cliprdr_server_format_data_response;
|
||||
cliprdr->ServerFileContentsRequest = wf_cliprdr_server_file_contents_request;
|
||||
cliprdr->ServerFileContentsResponse = wf_cliprdr_server_file_contents_response;
|
||||
cliprdr->custom = (void*) wfc->clipboard;
|
||||
|
||||
clipboard->channels = context->channels;
|
||||
clipboard->sync = FALSE;
|
||||
return;
|
||||
|
||||
clipboard->map_capacity = 32;
|
||||
clipboard->map_size = 0;
|
||||
fail_clipboard_thread:
|
||||
CloseHandle(clipboard->req_fevent);
|
||||
clipboard->req_fevent = NULL;
|
||||
fail_filecontents_event:
|
||||
CloseHandle(clipboard->response_data_event);
|
||||
clipboard->response_data_event = NULL;
|
||||
fail_data_event:
|
||||
free(clipboard->fileDescriptor);
|
||||
clipboard->fileDescriptor = NULL;
|
||||
fail_file_descriptor:
|
||||
free(clipboard->file_names);
|
||||
clipboard->file_names = NULL;
|
||||
fail_file_names:
|
||||
free(clipboard->format_mappings);
|
||||
clipboard->format_mappings = NULL;
|
||||
fail_format_mappings:
|
||||
free(wfc->clipboard);
|
||||
wfc->clipboard = NULL;
|
||||
|
||||
clipboard->format_mappings = (formatMapping*) calloc(1, sizeof(formatMapping) * clipboard->map_capacity);
|
||||
|
||||
clipboard->file_array_size = 32;
|
||||
clipboard->file_names = (WCHAR**) calloc(1, clipboard->file_array_size * sizeof(WCHAR*));
|
||||
clipboard->fileDescriptor = (FILEDESCRIPTORW**) calloc(1, clipboard->file_array_size * sizeof(FILEDESCRIPTORW*));
|
||||
|
||||
clipboard->response_data_event = CreateEvent(NULL, TRUE, FALSE, _T("response_data_event"));
|
||||
|
||||
clipboard->req_fevent = CreateEvent(NULL, TRUE, FALSE, _T("request_filecontents_event"));
|
||||
clipboard->ID_FILEDESCRIPTORW = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW);
|
||||
clipboard->ID_FILECONTENTS = RegisterClipboardFormatW(CFSTR_FILECONTENTS);
|
||||
clipboard->ID_PREFERREDDROPEFFECT = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT);
|
||||
|
||||
clipboard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) cliprdr_thread_func, clipboard, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
void wf_cliprdr_uninit(wfContext* wfc, CliprdrClientContext* cliprdr)
|
||||
|
@ -406,14 +406,16 @@ BOOL wf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
|
||||
|
||||
if (bitsPerPixel < 32)
|
||||
{
|
||||
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED);
|
||||
if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED))
|
||||
return FALSE;
|
||||
|
||||
status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel,
|
||||
&pDstData, PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR);
|
||||
if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR))
|
||||
return FALSE;
|
||||
|
||||
status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData,
|
||||
PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight, TRUE);
|
||||
@ -675,7 +677,9 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
|
||||
|
||||
if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX)
|
||||
{
|
||||
freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_REMOTEFX);
|
||||
if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_REMOTEFX))
|
||||
return;
|
||||
|
||||
if (!(message = rfx_process_message(wfc->codecs->rfx, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength)))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to process RemoteFX message");
|
||||
@ -715,7 +719,9 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
|
||||
}
|
||||
else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC)
|
||||
{
|
||||
freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_NSCODEC);
|
||||
if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_NSCODEC))
|
||||
return;
|
||||
|
||||
nsc_process_message(wfc->codecs->nsc, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
|
||||
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
|
||||
ZeroMemory(&bitmap_info, sizeof(bitmap_info));
|
||||
|
@ -171,14 +171,16 @@ void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap,
|
||||
{
|
||||
if (bpp < 32)
|
||||
{
|
||||
freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_INTERLEAVED);
|
||||
if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_INTERLEAVED))
|
||||
return;
|
||||
|
||||
status = interleaved_decompress(wfc->codecs->interleaved, pSrcData, SrcSize, bpp,
|
||||
&pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_PLANAR);
|
||||
if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_PLANAR))
|
||||
return;
|
||||
|
||||
status = planar_decompress(wfc->codecs->planar, pSrcData, SrcSize, &pDstData,
|
||||
PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height, TRUE);
|
||||
|
@ -1658,19 +1658,27 @@ static int xfreerdp_client_stop(rdpContext* context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
rdpSettings* settings;
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
|
||||
assert(context);
|
||||
assert(xfc);
|
||||
assert(!context->channels);
|
||||
assert(!xfc->display);
|
||||
assert(!xfc->mutex);
|
||||
assert(!xfc->x11event);
|
||||
|
||||
if (!(context->channels = freerdp_channels_new()))
|
||||
goto fail_channels_new;
|
||||
|
||||
instance->PreConnect = xf_pre_connect;
|
||||
instance->PostConnect = xf_post_connect;
|
||||
instance->PostDisconnect = xf_post_disconnect;
|
||||
instance->Authenticate = xf_authenticate;
|
||||
instance->VerifyCertificate = xf_verify_certificate;
|
||||
instance->LogonErrorInfo = xf_logon_error_info;
|
||||
assert(!context->channels);
|
||||
context->channels = freerdp_channels_new();
|
||||
|
||||
settings = instance->settings;
|
||||
xfc->settings = instance->context->settings;
|
||||
@ -1693,23 +1701,21 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
}
|
||||
}
|
||||
|
||||
assert(!xfc->display);
|
||||
xfc->display = XOpenDisplay(NULL);
|
||||
|
||||
if (!xfc->display)
|
||||
{
|
||||
WLog_ERR(TAG, "failed to open display: %s", XDisplayName(NULL));
|
||||
WLog_ERR(TAG, "Please check that the $DISPLAY environment variable is properly set.");
|
||||
return -1;
|
||||
goto fail_open_display;
|
||||
}
|
||||
|
||||
assert(!xfc->mutex);
|
||||
xfc->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
if (!xfc->mutex)
|
||||
{
|
||||
WLog_ERR(TAG, "Could not create mutex!");
|
||||
return -1;
|
||||
goto fail_create_mutex;
|
||||
}
|
||||
|
||||
xfc->_NET_WM_ICON = XInternAtom(xfc->display, "_NET_WM_ICON", False);
|
||||
@ -1741,8 +1747,13 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
xfc->invert = (ImageByteOrder(xfc->display) == MSBFirst) ? TRUE : FALSE;
|
||||
xfc->complex_regions = TRUE;
|
||||
|
||||
assert(!xfc->x11event);
|
||||
xfc->x11event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds);
|
||||
if (!xfc->x11event)
|
||||
{
|
||||
WLog_ERR(TAG, "Could not create xfds event");
|
||||
goto fail_xfds_event;
|
||||
}
|
||||
|
||||
xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number);
|
||||
xfc->format = PIXEL_FORMAT_XRGB32;
|
||||
|
||||
@ -1767,14 +1778,33 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
xf_check_extensions(xfc);
|
||||
|
||||
if (!xf_get_pixmap_info(xfc))
|
||||
return -1;
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to get pixmap info");
|
||||
goto fail_pixmap_info;
|
||||
}
|
||||
|
||||
xfc->vscreen.monitors = calloc(16, sizeof(MONITOR_INFO));
|
||||
|
||||
if (!xfc->vscreen.monitors)
|
||||
return -1;
|
||||
goto fail_vscreen_monitors;
|
||||
|
||||
return 0;
|
||||
return TRUE;
|
||||
|
||||
fail_vscreen_monitors:
|
||||
fail_pixmap_info:
|
||||
CloseHandle(xfc->x11event);
|
||||
xfc->x11event = NULL;
|
||||
fail_xfds_event:
|
||||
CloseHandle(xfc->mutex);
|
||||
xfc->mutex = NULL;
|
||||
fail_create_mutex:
|
||||
XCloseDisplay(xfc->display);
|
||||
xfc->display = NULL;
|
||||
fail_open_display:
|
||||
freerdp_channels_free(context->channels);
|
||||
context->channels = NULL;
|
||||
fail_channels_new:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void xfreerdp_client_free(freerdp* instance, rdpContext* context)
|
||||
|
@ -385,14 +385,16 @@ BOOL xf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
|
||||
|
||||
if (bitsPerPixel < 32)
|
||||
{
|
||||
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED);
|
||||
if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED))
|
||||
return FALSE;
|
||||
|
||||
status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel,
|
||||
&pDstData, xfc->format, -1, 0, 0, nWidth, nHeight, xfc->palette);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR);
|
||||
if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR))
|
||||
return FALSE;
|
||||
|
||||
status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData,
|
||||
xfc->format, -1, 0, 0, nWidth, nHeight, TRUE);
|
||||
@ -1176,11 +1178,16 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
|
||||
|
||||
if (cmd->codecID == RDP_CODEC_ID_REMOTEFX)
|
||||
{
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX))
|
||||
{
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(message = rfx_process_message(xfc->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength)))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to process RemoteFX message");
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1196,7 +1203,12 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
|
||||
xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16);
|
||||
|
||||
if (!xfc->bitmap_buffer)
|
||||
{
|
||||
rfx_message_free(xfc->codecs->rfx, message);
|
||||
XSetClipMask(xfc->display, xfc->gc, None);
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the tiles to primary surface, each is 64x64. */
|
||||
@ -1241,7 +1253,11 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
|
||||
}
|
||||
else if (cmd->codecID == RDP_CODEC_ID_NSCODEC)
|
||||
{
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC))
|
||||
{
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nsc_process_message(xfc->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength);
|
||||
|
||||
@ -1254,7 +1270,10 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
|
||||
xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16);
|
||||
|
||||
if (!xfc->bitmap_buffer)
|
||||
{
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
pSrcData = xfc->codecs->nsc->BitmapData;
|
||||
@ -1286,7 +1305,10 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
|
||||
xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16);
|
||||
|
||||
if (!xfc->bitmap_buffer)
|
||||
{
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
pSrcData = cmd->bitmapData;
|
||||
|
@ -263,7 +263,8 @@ int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDP
|
||||
REGION16 clippingRects;
|
||||
RECTANGLE_16 clippingRect;
|
||||
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX))
|
||||
return -1;
|
||||
|
||||
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
@ -337,7 +338,8 @@ int xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, R
|
||||
xfGfxSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC))
|
||||
return -1;
|
||||
|
||||
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
@ -375,7 +377,8 @@ int xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGF
|
||||
xfGfxSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR))
|
||||
return -1;
|
||||
|
||||
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
@ -410,7 +413,8 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_
|
||||
RDPGFX_H264_METABLOCK* meta;
|
||||
RDPGFX_H264_BITMAP_STREAM* bs;
|
||||
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_H264);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_H264))
|
||||
return -1;
|
||||
|
||||
h264 = xfc->codecs->h264;
|
||||
|
||||
@ -455,7 +459,8 @@ int xf_SurfaceCommand_Alpha(xfContext* xfc, RdpgfxClientContext* context, RDPGFX
|
||||
xfGfxSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_ALPHACODEC);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_ALPHACODEC))
|
||||
return -1;
|
||||
|
||||
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
@ -500,7 +505,8 @@ int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context,
|
||||
RFX_PROGRESSIVE_TILE* tile;
|
||||
PROGRESSIVE_BLOCK_REGION* region;
|
||||
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PROGRESSIVE);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PROGRESSIVE))
|
||||
return -1;
|
||||
|
||||
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
|
@ -64,10 +64,11 @@ BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
|
||||
|
||||
if (depth != xfc->depth)
|
||||
{
|
||||
data = _aligned_malloc(bitmap->width * bitmap->height * 4, 16);
|
||||
|
||||
if (!data)
|
||||
if (!(data = _aligned_malloc(bitmap->width * bitmap->height * 4, 16)))
|
||||
{
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SrcFormat = gdi_get_pixel_format(bitmap->bpp, TRUE);
|
||||
|
||||
@ -162,14 +163,16 @@ BOOL xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
{
|
||||
if (bpp < 32)
|
||||
{
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_INTERLEAVED);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_INTERLEAVED))
|
||||
return FALSE;
|
||||
|
||||
status = interleaved_decompress(xfc->codecs->interleaved, pSrcData, SrcSize, bpp,
|
||||
&pDstData, xfc->format, -1, 0, 0, width, height, xfc->palette);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR);
|
||||
if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR))
|
||||
return FALSE;
|
||||
|
||||
status = planar_decompress(xfc->codecs->planar, pSrcData, SrcSize,
|
||||
&pDstData, xfc->format, -1, 0, 0, width, height, TRUE);
|
||||
@ -228,10 +231,11 @@ BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
ci.xhot = pointer->xPos;
|
||||
ci.yhot = pointer->yPos;
|
||||
|
||||
ci.pixels = (XcursorPixel*) calloc(1, ci.width * ci.height * 4);
|
||||
|
||||
if (!ci.pixels)
|
||||
if (!(ci.pixels = (XcursorPixel*) calloc(1, ci.width * ci.height * 4)))
|
||||
{
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((pointer->andMaskData != 0) && (pointer->xorMaskData != 0))
|
||||
{
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <freerdp/client/cmdline.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
|
||||
int freerdp_client_common_new(freerdp* instance, rdpContext* context)
|
||||
BOOL freerdp_client_common_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints;
|
||||
return pEntryPoints->ClientNew(instance, context);
|
||||
@ -64,7 +64,7 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
||||
|
||||
|
||||
CopyMemory(instance->pClientEntryPoints, pEntryPoints, pEntryPoints->Size);
|
||||
if (freerdp_context_new(instance) != 0)
|
||||
if (!freerdp_context_new(instance))
|
||||
goto out_fail2;
|
||||
|
||||
context = instance->context;
|
||||
|
@ -34,7 +34,7 @@ extern "C" {
|
||||
typedef BOOL (*pRdpGlobalInit)(void);
|
||||
typedef void (*pRdpGlobalUninit)(void);
|
||||
|
||||
typedef int (*pRdpClientNew)(freerdp* instance, rdpContext* context);
|
||||
typedef BOOL (*pRdpClientNew)(freerdp* instance, rdpContext* context);
|
||||
typedef void (*pRdpClientFree)(freerdp* instance, rdpContext* context);
|
||||
|
||||
typedef int (*pRdpClientStart)(rdpContext* context);
|
||||
|
@ -59,8 +59,8 @@ struct rdp_codecs
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags);
|
||||
FREERDP_API int freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags);
|
||||
FREERDP_API BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags);
|
||||
FREERDP_API BOOL freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags);
|
||||
|
||||
FREERDP_API rdpCodecs* codecs_new(rdpContext* context);
|
||||
FREERDP_API void codecs_free(rdpCodecs* codecs);
|
||||
|
@ -59,7 +59,7 @@ typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int (*pContextNew)(freerdp* instance, rdpContext* context);
|
||||
typedef BOOL (*pContextNew)(freerdp* instance, rdpContext* context);
|
||||
typedef void (*pContextFree)(freerdp* instance, rdpContext* context);
|
||||
|
||||
typedef BOOL (*pPreConnect)(freerdp* instance);
|
||||
@ -237,7 +237,7 @@ struct rdp_freerdp
|
||||
UINT64 paddingE[80 - 66]; /* 66 */
|
||||
};
|
||||
|
||||
FREERDP_API int freerdp_context_new(freerdp* instance);
|
||||
FREERDP_API BOOL freerdp_context_new(freerdp* instance);
|
||||
FREERDP_API void freerdp_context_free(freerdp* instance);
|
||||
|
||||
FREERDP_API BOOL freerdp_connect(freerdp* instance);
|
||||
|
@ -37,7 +37,7 @@ typedef BOOL (*psListenerGetFileDescriptor)(freerdp_listener* instance, void** r
|
||||
typedef DWORD (*psListenerGetEventHandles)(freerdp_listener* instance, HANDLE* events, DWORD nCount);
|
||||
typedef BOOL (*psListenerCheckFileDescriptor)(freerdp_listener* instance);
|
||||
typedef void (*psListenerClose)(freerdp_listener* instance);
|
||||
typedef void (*psPeerAccepted)(freerdp_listener* instance, freerdp_peer* client);
|
||||
typedef BOOL (*psPeerAccepted)(freerdp_listener* instance, freerdp_peer* client);
|
||||
|
||||
struct rdp_freerdp_listener
|
||||
{
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include <winpr/sspi.h>
|
||||
|
||||
typedef void (*psPeerContextNew)(freerdp_peer* client, rdpContext* context);
|
||||
typedef BOOL (*psPeerContextNew)(freerdp_peer* client, rdpContext* context);
|
||||
typedef void (*psPeerContextFree)(freerdp_peer* client, rdpContext* context);
|
||||
|
||||
typedef BOOL (*psPeerInitialize)(freerdp_peer* client);
|
||||
@ -112,7 +112,7 @@ struct rdp_freerdp_peer
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API void freerdp_peer_context_new(freerdp_peer* client);
|
||||
FREERDP_API BOOL freerdp_peer_context_new(freerdp_peer* client);
|
||||
FREERDP_API void freerdp_peer_context_free(freerdp_peer* client);
|
||||
|
||||
FREERDP_API freerdp_peer* freerdp_peer_new(int sockfd);
|
||||
|
@ -989,6 +989,9 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length
|
||||
BOOL ok = TRUE;
|
||||
UINT16 expectedDataBlockType = WBT_FRAME_BEGIN;
|
||||
|
||||
if (!context || !data || !length)
|
||||
goto fail;
|
||||
|
||||
if (!(s = Stream_New(data, length)))
|
||||
goto fail;
|
||||
|
||||
|
@ -103,6 +103,9 @@ void freerdp_channels_free(rdpChannels* channels)
|
||||
ULONG_PTR* pKeys = NULL;
|
||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||
|
||||
if (!channels)
|
||||
return;
|
||||
|
||||
if (channels->queue)
|
||||
{
|
||||
MessageQueue_Free(channels->queue);
|
||||
|
@ -25,45 +25,52 @@
|
||||
|
||||
#include <freerdp/codecs.h>
|
||||
|
||||
int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags)
|
||||
#define TAG FREERDP_TAG("core.codecs")
|
||||
|
||||
BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags)
|
||||
{
|
||||
if (flags & FREERDP_CODEC_INTERLEAVED)
|
||||
if (flags & FREERDP_CODEC_INTERLEAVED && !codecs->interleaved)
|
||||
{
|
||||
if (!codecs->interleaved)
|
||||
if (!(codecs->interleaved = bitmap_interleaved_context_new(FALSE)))
|
||||
{
|
||||
codecs->interleaved = bitmap_interleaved_context_new(FALSE);
|
||||
WLog_ERR(TAG, "Failed to create interleaved codec context");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FREERDP_CODEC_PLANAR)
|
||||
if (flags & FREERDP_CODEC_PLANAR && !codecs->planar)
|
||||
{
|
||||
if (!codecs->planar)
|
||||
if (!(codecs->planar = freerdp_bitmap_planar_context_new(FALSE, 64, 64)))
|
||||
{
|
||||
codecs->planar = freerdp_bitmap_planar_context_new(FALSE, 64, 64);
|
||||
WLog_ERR(TAG, "Failed to create planar bitmap codec context");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FREERDP_CODEC_NSCODEC)
|
||||
if (flags & FREERDP_CODEC_NSCODEC && !codecs->nsc)
|
||||
{
|
||||
if (!codecs->nsc)
|
||||
if (!(codecs->nsc = nsc_context_new()))
|
||||
{
|
||||
codecs->nsc = nsc_context_new();
|
||||
WLog_ERR(TAG, "Failed to create nsc codec context");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FREERDP_CODEC_REMOTEFX)
|
||||
if (flags & FREERDP_CODEC_REMOTEFX && !codecs->rfx)
|
||||
{
|
||||
if (!codecs->rfx)
|
||||
if (!(codecs->rfx = rfx_context_new(FALSE)))
|
||||
{
|
||||
codecs->rfx = rfx_context_new(FALSE);
|
||||
WLog_ERR(TAG, "Failed to create rfx codec context");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FREERDP_CODEC_CLEARCODEC)
|
||||
if (flags & FREERDP_CODEC_CLEARCODEC && !codecs->clear)
|
||||
{
|
||||
if (!codecs->clear)
|
||||
if (!(codecs->clear = clear_context_new(FALSE)))
|
||||
{
|
||||
codecs->clear = clear_context_new(FALSE);
|
||||
WLog_ERR(TAG, "Failed to create clear codec context");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,26 +79,28 @@ int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags)
|
||||
|
||||
}
|
||||
|
||||
if (flags & FREERDP_CODEC_PROGRESSIVE)
|
||||
if (flags & FREERDP_CODEC_PROGRESSIVE && !codecs->progressive)
|
||||
{
|
||||
if (!codecs->progressive)
|
||||
if (!(codecs->progressive = progressive_context_new(FALSE)))
|
||||
{
|
||||
codecs->progressive = progressive_context_new(FALSE);
|
||||
WLog_ERR(TAG, "Failed to create progressive codec context");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FREERDP_CODEC_H264)
|
||||
if (flags & FREERDP_CODEC_H264 && !codecs->h264)
|
||||
{
|
||||
if (!codecs->h264)
|
||||
if (!(codecs->h264 = h264_context_new(FALSE)))
|
||||
{
|
||||
codecs->h264 = h264_context_new(FALSE);
|
||||
WLog_ERR(TAG, "Failed to create h264 codec context");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags)
|
||||
BOOL freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags)
|
||||
{
|
||||
if (flags & FREERDP_CODEC_INTERLEAVED)
|
||||
{
|
||||
@ -154,7 +163,7 @@ int freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags)
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
rdpCodecs* codecs_new(rdpContext* context)
|
||||
|
@ -441,14 +441,15 @@ static wEventType FreeRDP_Events[] =
|
||||
*
|
||||
* @param instance - Pointer to the rdp_freerdp structure that will be initialized with the new context.
|
||||
*/
|
||||
int freerdp_context_new(freerdp* instance)
|
||||
BOOL freerdp_context_new(freerdp* instance)
|
||||
{
|
||||
rdpRdp* rdp;
|
||||
rdpContext* context;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
instance->context = (rdpContext*) calloc(1, instance->ContextSize);
|
||||
if (!instance->context)
|
||||
return -1;
|
||||
return FALSE;
|
||||
|
||||
context = instance->context;
|
||||
context->instance = instance;
|
||||
@ -497,8 +498,10 @@ int freerdp_context_new(freerdp* instance)
|
||||
|
||||
update_register_client_callbacks(rdp->update);
|
||||
|
||||
IFCALL(instance->ContextNew, instance, instance->context);
|
||||
return 0;
|
||||
IFCALLRET(instance->ContextNew, ret, instance, instance->context);
|
||||
|
||||
if (ret)
|
||||
return TRUE;
|
||||
|
||||
out_error_graphics_new:
|
||||
rdp_free(rdp);
|
||||
@ -508,7 +511,7 @@ out_error_metrics_new:
|
||||
PubSub_Free(context->pubSub);
|
||||
out_error_pubsub:
|
||||
free(instance->context);
|
||||
return -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** Deallocator function for a rdp context.
|
||||
|
@ -284,6 +284,7 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance)
|
||||
struct sockaddr_storage peer_addr;
|
||||
rdpListener* listener = (rdpListener*) instance->listener;
|
||||
static const BYTE localhost6_bytes[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||
BOOL peer_accepted;
|
||||
|
||||
if (listener->num_sockfds < 1)
|
||||
return FALSE;
|
||||
@ -292,6 +293,7 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance)
|
||||
{
|
||||
peer_addr_size = sizeof(peer_addr);
|
||||
peer_sockfd = accept(listener->sockfds[i], (struct sockaddr*) &peer_addr, &peer_addr_size);
|
||||
peer_accepted = FALSE;
|
||||
|
||||
if (peer_sockfd == -1)
|
||||
{
|
||||
@ -340,7 +342,14 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance)
|
||||
if (sin_addr)
|
||||
inet_ntop(peer_addr.ss_family, sin_addr, client->hostname, sizeof(client->hostname));
|
||||
|
||||
IFCALL(instance->PeerAccepted, instance, client);
|
||||
IFCALLRET(instance->PeerAccepted, peer_accepted, instance, client);
|
||||
|
||||
if (!peer_accepted)
|
||||
{
|
||||
WLog_ERR(TAG, "PeerAccepted callback failed");
|
||||
closesocket((SOCKET) peer_sockfd);
|
||||
freerdp_peer_free(client);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -621,36 +621,27 @@ static int freerdp_peer_drain_output_buffer(freerdp_peer* peer)
|
||||
return transport_drain_output_buffer(transport);
|
||||
}
|
||||
|
||||
void freerdp_peer_context_new(freerdp_peer* client)
|
||||
BOOL freerdp_peer_context_new(freerdp_peer* client)
|
||||
{
|
||||
rdpRdp* rdp;
|
||||
rdpContext* context;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
context = client->context = (rdpContext*) calloc(1, client->ContextSize);
|
||||
if (!client)
|
||||
return FALSE;
|
||||
|
||||
if (!context)
|
||||
return;
|
||||
if (!(context = (rdpContext*) calloc(1, client->ContextSize)))
|
||||
goto fail_context;
|
||||
|
||||
client->context = context;
|
||||
|
||||
context->ServerMode = TRUE;
|
||||
|
||||
context->metrics = metrics_new(context);
|
||||
if (!(context->metrics = metrics_new(context)))
|
||||
goto fail_metrics;
|
||||
|
||||
if (!context->metrics)
|
||||
{
|
||||
client->context = NULL;
|
||||
free(context);
|
||||
return;
|
||||
}
|
||||
|
||||
rdp = rdp_new(context);
|
||||
|
||||
if (!rdp)
|
||||
{
|
||||
metrics_free(context->metrics);
|
||||
free(context);
|
||||
client->context = NULL;
|
||||
return;
|
||||
}
|
||||
if (!(rdp = rdp_new(context)))
|
||||
goto fail_rdp;
|
||||
|
||||
client->input = rdp->input;
|
||||
client->update = rdp->update;
|
||||
@ -671,7 +662,8 @@ void freerdp_peer_context_new(freerdp_peer* client)
|
||||
update_register_server_callbacks(client->update);
|
||||
autodetect_register_server_callbacks(client->autodetect);
|
||||
|
||||
transport_attach(rdp->transport, client->sockfd);
|
||||
if (!transport_attach(rdp->transport, client->sockfd))
|
||||
goto fail_transport_attach;
|
||||
|
||||
rdp->transport->ReceiveCallback = peer_recv_callback;
|
||||
rdp->transport->ReceiveExtra = client;
|
||||
@ -680,8 +672,24 @@ void freerdp_peer_context_new(freerdp_peer* client)
|
||||
client->IsWriteBlocked = freerdp_peer_is_write_blocked;
|
||||
client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
|
||||
|
||||
IFCALL(client->ContextNew, client, client->context);
|
||||
IFCALLRET(client->ContextNew, ret, client, client->context);
|
||||
|
||||
if (ret)
|
||||
return TRUE;
|
||||
|
||||
WLog_ERR(TAG, "ContextNew callback failed");
|
||||
|
||||
fail_transport_attach:
|
||||
rdp_free(client->context->rdp);
|
||||
fail_rdp:
|
||||
metrics_free(context->metrics);
|
||||
fail_metrics:
|
||||
free(client->context);
|
||||
fail_context:
|
||||
client->context = NULL;
|
||||
|
||||
WLog_ERR(TAG, "Failed to create new peer context");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void freerdp_peer_context_free(freerdp_peer* client)
|
||||
|
@ -264,7 +264,8 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
|
||||
if (sockfd < 1)
|
||||
return FALSE;
|
||||
|
||||
transport_attach(transport, sockfd);
|
||||
if (!transport_attach(transport, sockfd))
|
||||
return FALSE;
|
||||
|
||||
status = TRUE;
|
||||
}
|
||||
@ -273,9 +274,20 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
|
||||
{
|
||||
if (transport->async)
|
||||
{
|
||||
transport->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
transport->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL);
|
||||
if (!(transport->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create transport stop event");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(transport->thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create transport client thread");
|
||||
CloseHandle(transport->stopEvent);
|
||||
transport->stopEvent = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,14 +486,16 @@ static BOOL gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
|
||||
|
||||
if (bitsPerPixel < 32)
|
||||
{
|
||||
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED);
|
||||
if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED))
|
||||
return FALSE;
|
||||
|
||||
status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel,
|
||||
&pDstData, gdi->format, -1, 0, 0, nWidth, nHeight, gdi->palette);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR);
|
||||
if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR))
|
||||
return FALSE;
|
||||
|
||||
status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData,
|
||||
gdi->format, -1, 0, 0, nWidth, nHeight, TRUE);
|
||||
@ -1023,7 +1025,8 @@ static BOOL gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
|
||||
|
||||
if (cmd->codecID == RDP_CODEC_ID_REMOTEFX)
|
||||
{
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX))
|
||||
return FALSE;
|
||||
|
||||
if (!(message = rfx_process_message(gdi->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength)))
|
||||
{
|
||||
@ -1068,7 +1071,8 @@ static BOOL gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
|
||||
}
|
||||
else if (cmd->codecID == RDP_CODEC_ID_NSCODEC)
|
||||
{
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_NSCODEC);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_NSCODEC))
|
||||
return FALSE;
|
||||
|
||||
nsc_process_message(gdi->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength);
|
||||
|
||||
|
@ -192,7 +192,8 @@ int gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* context, RDPGF
|
||||
REGION16 clippingRects;
|
||||
RECTANGLE_16 clippingRect;
|
||||
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX))
|
||||
return -1;
|
||||
|
||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
@ -264,7 +265,8 @@ int gdi_SurfaceCommand_ClearCodec(rdpGdi* gdi, RdpgfxClientContext* context, RDP
|
||||
gdiGfxSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_CLEARCODEC);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_CLEARCODEC))
|
||||
return -1;
|
||||
|
||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
@ -303,7 +305,8 @@ int gdi_SurfaceCommand_Planar(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_
|
||||
gdiGfxSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR))
|
||||
return -1;
|
||||
|
||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
@ -337,7 +340,8 @@ int gdi_SurfaceCommand_H264(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SU
|
||||
RDPGFX_H264_METABLOCK* meta;
|
||||
RDPGFX_H264_BITMAP_STREAM* bs;
|
||||
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_H264);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_H264))
|
||||
return -1;
|
||||
|
||||
bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra;
|
||||
|
||||
@ -380,7 +384,8 @@ int gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_S
|
||||
gdiGfxSurface* surface;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_ALPHACODEC);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_ALPHACODEC))
|
||||
return -1;
|
||||
|
||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
@ -426,7 +431,8 @@ int gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* context, RD
|
||||
RFX_PROGRESSIVE_TILE* tile;
|
||||
PROGRESSIVE_BLOCK_REGION* region;
|
||||
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PROGRESSIVE);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PROGRESSIVE))
|
||||
return -1;
|
||||
|
||||
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
|
||||
|
||||
|
@ -175,14 +175,16 @@ BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
{
|
||||
if (bpp < 32)
|
||||
{
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_INTERLEAVED);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_INTERLEAVED))
|
||||
return FALSE;
|
||||
|
||||
status = interleaved_decompress(gdi->codecs->interleaved, pSrcData, SrcSize, bpp,
|
||||
&pDstData, gdi->format, -1, 0, 0, width, height, gdi->palette);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR);
|
||||
if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR))
|
||||
return FALSE;
|
||||
|
||||
status = planar_decompress(gdi->codecs->planar, pSrcData, SrcSize, &pDstData,
|
||||
gdi->format, -1, 0, 0, width, height, TRUE);
|
||||
|
@ -175,25 +175,44 @@ void mf_peer_rfx_update(freerdp_peer* client)
|
||||
}
|
||||
|
||||
/* Called when we have a new peer connecting */
|
||||
int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context)
|
||||
BOOL mf_peer_context_new(freerdp_peer* client, mfPeerContext* context)
|
||||
{
|
||||
context->info = mf_info_get_instance();
|
||||
context->rfx_context = rfx_context_new(TRUE);
|
||||
if (!(context->info = mf_info_get_instance()))
|
||||
return FALSE;
|
||||
|
||||
if (!(context->rfx_context = rfx_context_new(TRUE)))
|
||||
goto fail_rfx_context;
|
||||
|
||||
context->rfx_context->mode = RLGR3;
|
||||
context->rfx_context->width = client->settings->DesktopWidth;
|
||||
context->rfx_context->height = client->settings->DesktopHeight;
|
||||
rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
|
||||
//context->nsc_context = nsc_context_new();
|
||||
//if (!(context->nsc_context = nsc_context_new()))
|
||||
// goto fail_nsc_context;
|
||||
//nsc_context_set_pixel_format(context->nsc_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
|
||||
context->s = Stream_New(NULL, 0xFFFF);
|
||||
if (!(context->s = Stream_New(NULL, 0xFFFF)))
|
||||
goto fail_stream_new;
|
||||
|
||||
context->vcm = WTSOpenServerA((LPSTR) client->context);
|
||||
|
||||
if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE)
|
||||
goto fail_open_server;
|
||||
|
||||
mf_info_peer_register(context->info, context);
|
||||
|
||||
return 0;
|
||||
return TRUE;
|
||||
|
||||
fail_open_server:
|
||||
Stream_Free(context->s, TRUE);
|
||||
context->s = NULL;
|
||||
fail_stream_new:
|
||||
rfx_context_free(context->rfx_context);
|
||||
context->rfx_context = NULL;
|
||||
fail_rfx_context:
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Called after a peer disconnects */
|
||||
@ -226,12 +245,14 @@ void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context)
|
||||
}
|
||||
|
||||
/* Called when a new client connects */
|
||||
void mf_peer_init(freerdp_peer* client)
|
||||
BOOL mf_peer_init(freerdp_peer* client)
|
||||
{
|
||||
client->ContextSize = sizeof(mfPeerContext);
|
||||
client->ContextNew = (psPeerContextNew) mf_peer_context_new;
|
||||
client->ContextFree = (psPeerContextFree) mf_peer_context_free;
|
||||
freerdp_peer_context_new(client);
|
||||
|
||||
if (!freerdp_peer_context_new(client))
|
||||
return FALSE;
|
||||
|
||||
info_event_queue = mf_event_queue_new();
|
||||
|
||||
@ -249,6 +270,8 @@ void mf_peer_init(freerdp_peer* client)
|
||||
);
|
||||
dispatch_resume(info_timer);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL mf_peer_post_connect(freerdp_peer* client)
|
||||
@ -330,12 +353,17 @@ static void mf_peer_suppress_output(rdpContext* context, BYTE allow, RECTANGLE_1
|
||||
|
||||
}
|
||||
|
||||
void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
BOOL mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
{
|
||||
pthread_t th;
|
||||
|
||||
pthread_create(&th, 0, mf_peer_main_loop, client);
|
||||
pthread_detach(th);
|
||||
if (pthread_create(&th, 0, mf_peer_main_loop, client) == 0)
|
||||
{
|
||||
pthread_detach(th);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void* mf_peer_main_loop(void* arg)
|
||||
@ -351,7 +379,11 @@ void* mf_peer_main_loop(void* arg)
|
||||
|
||||
memset(rfds, 0, sizeof(rfds));
|
||||
|
||||
mf_peer_init(client);
|
||||
if (!mf_peer_init(client))
|
||||
{
|
||||
freerdp_peer_free(client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the real server settings here */
|
||||
client->settings->CertificateFile = _strdup("server.crt");
|
||||
|
@ -27,17 +27,17 @@ BOOL mf_peer_check_fds(freerdp_peer* client);
|
||||
|
||||
void mf_peer_rfx_update(freerdp_peer* client);
|
||||
|
||||
int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context);
|
||||
BOOL mf_peer_context_new(freerdp_peer* client, mfPeerContext* context);
|
||||
void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context);
|
||||
|
||||
void mf_peer_init(freerdp_peer* client);
|
||||
BOOL mf_peer_init(freerdp_peer* client);
|
||||
|
||||
BOOL mf_peer_post_connect(freerdp_peer* client);
|
||||
BOOL mf_peer_activate(freerdp_peer* client);
|
||||
|
||||
void mf_peer_synchronize_event(rdpInput* input, UINT32 flags);
|
||||
|
||||
void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);
|
||||
BOOL mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);
|
||||
|
||||
void* mf_peer_main_loop(void* arg);
|
||||
|
||||
|
@ -108,7 +108,8 @@ int main(int argc, char* argv[])
|
||||
|
||||
WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi());
|
||||
|
||||
instance = freerdp_listener_new();
|
||||
if (!(instance = freerdp_listener_new()))
|
||||
return 1;
|
||||
|
||||
instance->PeerAccepted = mf_peer_accepted;
|
||||
|
||||
|
@ -52,23 +52,46 @@
|
||||
static char* test_pcap_file = NULL;
|
||||
static BOOL test_dump_rfx_realtime = TRUE;
|
||||
|
||||
void test_peer_context_new(freerdp_peer* client, testPeerContext* context)
|
||||
BOOL test_peer_context_new(freerdp_peer* client, testPeerContext* context)
|
||||
{
|
||||
context->rfx_context = rfx_context_new(TRUE);
|
||||
if (!(context->rfx_context = rfx_context_new(TRUE)))
|
||||
goto fail_rfx_context;
|
||||
|
||||
context->rfx_context->mode = RLGR3;
|
||||
context->rfx_context->width = SAMPLE_SERVER_DEFAULT_WIDTH;
|
||||
context->rfx_context->height = SAMPLE_SERVER_DEFAULT_HEIGHT;
|
||||
rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_R8G8B8);
|
||||
|
||||
context->nsc_context = nsc_context_new();
|
||||
if (!(context->nsc_context = nsc_context_new()))
|
||||
goto fail_nsc_context;
|
||||
|
||||
nsc_context_set_pixel_format(context->nsc_context, RDP_PIXEL_FORMAT_R8G8B8);
|
||||
|
||||
context->s = Stream_New(NULL, 65536);
|
||||
if (!(context->s = Stream_New(NULL, 65536)))
|
||||
goto fail_stream_new;
|
||||
|
||||
context->icon_x = -1;
|
||||
context->icon_y = -1;
|
||||
|
||||
context->vcm = WTSOpenServerA((LPSTR) client->context);
|
||||
|
||||
if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE)
|
||||
goto fail_open_server;
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail_open_server:
|
||||
context->vcm = NULL;
|
||||
Stream_Free(context->s, TRUE);
|
||||
context->s = NULL;
|
||||
fail_stream_new:
|
||||
nsc_context_free(context->nsc_context);
|
||||
context->nsc_context = NULL;
|
||||
fail_nsc_context:
|
||||
rfx_context_free(context->rfx_context);
|
||||
context->rfx_context = NULL;
|
||||
fail_rfx_context:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void test_peer_context_free(freerdp_peer* client, testPeerContext* context)
|
||||
@ -105,12 +128,12 @@ void test_peer_context_free(freerdp_peer* client, testPeerContext* context)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_peer_init(freerdp_peer* client)
|
||||
static BOOL test_peer_init(freerdp_peer* client)
|
||||
{
|
||||
client->ContextSize = sizeof(testPeerContext);
|
||||
client->ContextNew = (psPeerContextNew) test_peer_context_new;
|
||||
client->ContextFree = (psPeerContextFree) test_peer_context_free;
|
||||
freerdp_peer_context_new(client);
|
||||
return freerdp_peer_context_new(client);
|
||||
}
|
||||
|
||||
static wStream* test_peer_stream_init(testPeerContext* context)
|
||||
@ -509,10 +532,20 @@ BOOL tf_peer_post_connect(freerdp_peer* client)
|
||||
if (context->debug_channel != NULL)
|
||||
{
|
||||
WLog_DBG(TAG, "Open channel rdpdbg.");
|
||||
context->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!(context->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create stop event");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
context->debug_channel_thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) tf_debug_channel_thread_func, (void*) context, 0, NULL);
|
||||
if (!(context->debug_channel_thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) tf_debug_channel_thread_func, (void*) context, 0, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create debug channel thread");
|
||||
CloseHandle(context->stopEvent);
|
||||
context->stopEvent = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -674,7 +707,11 @@ static void* test_peer_mainloop(void* arg)
|
||||
testPeerContext* context;
|
||||
freerdp_peer* client = (freerdp_peer*) arg;
|
||||
|
||||
test_peer_init(client);
|
||||
if (!test_peer_init(client))
|
||||
{
|
||||
freerdp_peer_free(client);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the real server settings here */
|
||||
client->settings->CertificateFile = _strdup("server.crt");
|
||||
@ -740,12 +777,16 @@ static void* test_peer_mainloop(void* arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void test_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
static BOOL test_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
{
|
||||
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_peer_mainloop, (void*) client, 0, NULL);
|
||||
|
||||
if (hThread != NULL) {
|
||||
CloseHandle(hThread);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void test_server_mainloop(freerdp_listener* instance)
|
||||
|
@ -37,7 +37,7 @@
|
||||
static wfInfo* wfInfoInstance = NULL;
|
||||
static int _IDcount = 0;
|
||||
|
||||
int wf_info_lock(wfInfo* wfi)
|
||||
BOOL wf_info_lock(wfInfo* wfi)
|
||||
{
|
||||
DWORD dRes;
|
||||
|
||||
@ -54,13 +54,13 @@ int wf_info_lock(wfInfo* wfi)
|
||||
|
||||
case WAIT_FAILED:
|
||||
WLog_ERR(TAG, "wf_info_lock failed with 0x%08X", GetLastError());
|
||||
return -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds)
|
||||
BOOL wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds)
|
||||
{
|
||||
DWORD dRes;
|
||||
|
||||
@ -77,18 +77,18 @@ int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds)
|
||||
|
||||
case WAIT_FAILED:
|
||||
WLog_ERR(TAG, "wf_info_try_lock failed with 0x%08X", GetLastError());
|
||||
return -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int wf_info_unlock(wfInfo* wfi)
|
||||
BOOL wf_info_unlock(wfInfo* wfi)
|
||||
{
|
||||
if (ReleaseMutex(wfi->mutex) == 0)
|
||||
if (!ReleaseMutex(wfi->mutex))
|
||||
{
|
||||
WLog_ERR(TAG, "wf_info_unlock failed with 0x%08X", GetLastError());
|
||||
return -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -185,61 +185,70 @@ wfInfo* wf_info_get_instance()
|
||||
return wfInfoInstance;
|
||||
}
|
||||
|
||||
void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
|
||||
BOOL wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
|
||||
{
|
||||
if (wf_info_lock(wfi) > 0)
|
||||
{
|
||||
int i;
|
||||
int peerId;
|
||||
if (wfi->peerCount == WF_INFO_MAXPEERS)
|
||||
{
|
||||
context->socketClose = TRUE;
|
||||
wf_info_unlock(wfi);
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
int peerId;
|
||||
|
||||
context->info = wfi;
|
||||
context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!wfi || !context)
|
||||
return FALSE;
|
||||
|
||||
//get the offset of the top left corner of selected screen
|
||||
EnumDisplayMonitors(NULL, NULL, wf_info_monEnumCB, 0);
|
||||
_IDcount = 0;
|
||||
if (!wf_info_lock(wfi))
|
||||
return FALSE;
|
||||
|
||||
if (wfi->peerCount == WF_INFO_MAXPEERS)
|
||||
goto fail_peer_count;
|
||||
|
||||
context->info = wfi;
|
||||
if (!(context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
goto fail_update_event;
|
||||
|
||||
//get the offset of the top left corner of selected screen
|
||||
EnumDisplayMonitors(NULL, NULL, wf_info_monEnumCB, 0);
|
||||
_IDcount = 0;
|
||||
|
||||
#ifdef WITH_DXGI_1_2
|
||||
if (wfi->peerCount == 0)
|
||||
wf_dxgi_init(wfi);
|
||||
if (wfi->peerCount == 0)
|
||||
if (wf_dxgi_init(wfi) != 0)
|
||||
goto fail_driver_init;
|
||||
#else
|
||||
if (wf_mirror_driver_activate(wfi) == FALSE)
|
||||
{
|
||||
context->socketClose = TRUE;
|
||||
wf_info_unlock(wfi);
|
||||
return;
|
||||
}
|
||||
if (!wf_mirror_driver_activate(wfi))
|
||||
goto fail_driver_init;
|
||||
#endif
|
||||
//look through the array of peers until an empty slot
|
||||
for(i=0; i<WF_INFO_MAXPEERS; ++i)
|
||||
//look through the array of peers until an empty slot
|
||||
for (i = 0; i < WF_INFO_MAXPEERS; ++i)
|
||||
{
|
||||
//empty index will be our peer id
|
||||
if (wfi->peers[i] == NULL)
|
||||
{
|
||||
//empty index will be our peer id
|
||||
if (wfi->peers[i] == NULL)
|
||||
{
|
||||
peerId = i;
|
||||
break;
|
||||
}
|
||||
peerId = i;
|
||||
break;
|
||||
}
|
||||
|
||||
wfi->peers[peerId] = ((rdpContext*) context)->peer;
|
||||
wfi->peers[peerId]->pId = peerId;
|
||||
wfi->peerCount++;
|
||||
WLog_INFO(TAG, "Registering Peer: id=%d #=%d", peerId, wfi->peerCount);
|
||||
wf_info_unlock(wfi);
|
||||
|
||||
wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_CONNECT);
|
||||
}
|
||||
|
||||
wfi->peers[peerId] = ((rdpContext*) context)->peer;
|
||||
wfi->peers[peerId]->pId = peerId;
|
||||
wfi->peerCount++;
|
||||
|
||||
WLog_INFO(TAG, "Registering Peer: id=%d #=%d", peerId, wfi->peerCount);
|
||||
wf_info_unlock(wfi);
|
||||
wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_CONNECT);
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail_driver_init:
|
||||
CloseHandle(context->updateEvent);
|
||||
context->updateEvent = NULL;
|
||||
fail_update_event:
|
||||
fail_peer_count:
|
||||
context->socketClose = TRUE;
|
||||
wf_info_unlock(wfi);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context)
|
||||
{
|
||||
if (wf_info_lock(wfi) > 0)
|
||||
if (wf_info_lock(wfi))
|
||||
{
|
||||
int peerId;
|
||||
|
||||
|
@ -25,12 +25,12 @@
|
||||
#define WF_INFO_DEFAULT_FPS 24
|
||||
#define WF_INFO_MAXPEERS 32
|
||||
|
||||
int wf_info_lock(wfInfo* wfi);
|
||||
int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds);
|
||||
int wf_info_unlock(wfInfo* wfi);
|
||||
BOOL wf_info_lock(wfInfo* wfi);
|
||||
BOOL wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds);
|
||||
BOOL wf_info_unlock(wfInfo* wfi);
|
||||
|
||||
wfInfo* wf_info_get_instance(void);
|
||||
void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context);
|
||||
BOOL wf_info_peer_register(wfInfo* wfi, wfPeerContext* context);
|
||||
void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context);
|
||||
|
||||
BOOL wf_info_have_updates(wfInfo* wfi);
|
||||
|
@ -38,11 +38,24 @@
|
||||
|
||||
#include "wf_peer.h"
|
||||
|
||||
void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context)
|
||||
BOOL wf_peer_context_new(freerdp_peer* client, wfPeerContext* context)
|
||||
{
|
||||
context->info = wf_info_get_instance();
|
||||
if (!(context->info = wf_info_get_instance()))
|
||||
return FALSE;
|
||||
|
||||
context->vcm = WTSOpenServerA((LPSTR) client->context);
|
||||
wf_info_peer_register(context->info, context);
|
||||
|
||||
if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
if (!wf_info_peer_register(context->info, context))
|
||||
{
|
||||
WTSCloseServer(context->vcm);
|
||||
context->vcm = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)
|
||||
@ -60,13 +73,13 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)
|
||||
WTSCloseServer(context->vcm);
|
||||
}
|
||||
|
||||
void wf_peer_init(freerdp_peer* client)
|
||||
BOOL wf_peer_init(freerdp_peer* client)
|
||||
{
|
||||
client->ContextSize = sizeof(wfPeerContext);
|
||||
client->ContextNew = (psPeerContextNew) wf_peer_context_new;
|
||||
client->ContextFree = (psPeerContextFree) wf_peer_context_free;
|
||||
|
||||
freerdp_peer_context_new(client);
|
||||
|
||||
return freerdp_peer_context_new(client);
|
||||
}
|
||||
|
||||
BOOL wf_peer_post_connect(freerdp_peer* client)
|
||||
@ -75,14 +88,14 @@ BOOL wf_peer_post_connect(freerdp_peer* client)
|
||||
wfInfo* wfi;
|
||||
rdpSettings* settings;
|
||||
wfPeerContext* context = (wfPeerContext*) client->context;
|
||||
|
||||
|
||||
wfi = context->info;
|
||||
settings = client->settings;
|
||||
|
||||
if ((get_screen_info(wfi->screenID, NULL, &wfi->servscreen_width, &wfi->servscreen_height, &wfi->bitsPerPixel) == 0) ||
|
||||
(wfi->servscreen_width == 0) ||
|
||||
(wfi->servscreen_height == 0) ||
|
||||
(wfi->bitsPerPixel == 0) )
|
||||
(wfi->servscreen_width == 0) ||
|
||||
(wfi->servscreen_height == 0) ||
|
||||
(wfi->bitsPerPixel == 0) )
|
||||
{
|
||||
WLog_ERR(TAG, "postconnect: error getting screen info for screen %d", wfi->screenID);
|
||||
WLog_ERR(TAG, "\t%dx%dx%d", wfi->servscreen_height, wfi->servscreen_width, wfi->bitsPerPixel);
|
||||
@ -95,11 +108,11 @@ BOOL wf_peer_post_connect(freerdp_peer* client)
|
||||
WLog_DBG(TAG, "Client requested resolution %dx%d, but will resize to %dx%d",
|
||||
settings->DesktopWidth, settings->DesktopHeight, wfi->servscreen_width, wfi->servscreen_height);
|
||||
*/
|
||||
|
||||
|
||||
settings->DesktopWidth = wfi->servscreen_width;
|
||||
settings->DesktopHeight = wfi->servscreen_height;
|
||||
settings->ColorDepth = wfi->bitsPerPixel;
|
||||
|
||||
|
||||
client->update->DesktopResize(client->update->context);
|
||||
}
|
||||
|
||||
@ -115,13 +128,13 @@ BOOL wf_peer_activate(freerdp_peer* client)
|
||||
{
|
||||
wfInfo* wfi;
|
||||
wfPeerContext* context = (wfPeerContext*) client->context;
|
||||
|
||||
|
||||
wfi = context->info;
|
||||
client->activated = TRUE;
|
||||
wf_update_peer_activate(wfi, context);
|
||||
|
||||
|
||||
wfreerdp_server_peer_callback_event(((rdpContext*) context)->peer->pId, WF_SRV_CALLBACK_EVENT_ACTIVATE);
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -133,12 +146,15 @@ BOOL wf_peer_logon(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, BOOL
|
||||
|
||||
void wf_peer_synchronize_event(rdpInput* input, UINT32 flags)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
BOOL wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
{
|
||||
CreateThread(NULL, 0, wf_peer_main_loop, client, 0, NULL);
|
||||
if (!CreateThread(NULL, 0, wf_peer_main_loop, client, 0, NULL))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
|
||||
@ -150,7 +166,7 @@ DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
|
||||
fd_set rfds_set;
|
||||
wfPeerContext* context;
|
||||
freerdp_peer* client = (freerdp_peer*) lpParam;
|
||||
|
||||
|
||||
ZeroMemory(rfds, sizeof(rfds));
|
||||
context = (wfPeerContext*) client->context;
|
||||
|
||||
@ -181,7 +197,7 @@ DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
|
||||
break;
|
||||
|
||||
select(max_fds + 1, &rfds_set, NULL, NULL, NULL);
|
||||
|
||||
|
||||
SetEvent(context->socketEvent);
|
||||
WaitForSingleObject(context->socketSemaphore, INFINITE);
|
||||
|
||||
@ -219,30 +235,33 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
||||
_putenv(home);
|
||||
}
|
||||
|
||||
wf_peer_init(client);
|
||||
|
||||
if (!wf_peer_init(client))
|
||||
goto fail_peer_init;
|
||||
|
||||
settings = client->settings;
|
||||
settings->RemoteFxCodec = TRUE;
|
||||
settings->ColorDepth = 32;
|
||||
settings->NSCodec = FALSE;
|
||||
settings->JpegCodec = FALSE;
|
||||
wf_peer_read_settings(client);
|
||||
|
||||
|
||||
client->PostConnect = wf_peer_post_connect;
|
||||
client->Activate = wf_peer_activate;
|
||||
client->Logon = wf_peer_logon;
|
||||
|
||||
|
||||
client->input->SynchronizeEvent = wf_peer_synchronize_event;
|
||||
client->input->KeyboardEvent = wf_peer_keyboard_event;
|
||||
client->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event;
|
||||
client->input->MouseEvent = wf_peer_mouse_event;
|
||||
client->input->ExtendedMouseEvent = wf_peer_extended_mouse_event;
|
||||
|
||||
client->Initialize(client);
|
||||
context = (wfPeerContext*) client->context;
|
||||
|
||||
if (!client->Initialize(client))
|
||||
goto fail_client_initialize;
|
||||
|
||||
if (context->socketClose)
|
||||
return 0;
|
||||
goto fail_socked_closed;
|
||||
|
||||
context = (wfPeerContext*) client->context;
|
||||
|
||||
wfi = context->info;
|
||||
|
||||
@ -255,10 +274,15 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
||||
client->input->ExtendedMouseEvent = wf_peer_extended_mouse_event_dummy;
|
||||
}
|
||||
|
||||
context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
|
||||
context->socketThread = CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL);
|
||||
if (!(context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
goto fail_socket_event;
|
||||
|
||||
if (!(context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL)))
|
||||
goto fail_socket_semaphore;
|
||||
|
||||
if (!(context->socketThread = CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL)))
|
||||
goto fail_socket_thread;
|
||||
|
||||
WLog_INFO(TAG, "We've got a client %s", client->local ? "(local)" : client->hostname);
|
||||
nCount = 0;
|
||||
handles[nCount++] = context->updateEvent;
|
||||
@ -319,11 +343,21 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
||||
}
|
||||
|
||||
wf_update_peer_deactivate(wfi, context);
|
||||
|
||||
|
||||
client->Disconnect(client);
|
||||
|
||||
|
||||
fail_socket_thread:
|
||||
CloseHandle(context->socketSemaphore);
|
||||
context->socketSemaphore = NULL;
|
||||
fail_socket_semaphore:
|
||||
CloseHandle(context->socketEvent);
|
||||
context->socketEvent = NULL;
|
||||
fail_socket_event:
|
||||
fail_socked_closed:
|
||||
fail_client_initialize:
|
||||
freerdp_peer_context_free(client);
|
||||
fail_peer_init:
|
||||
freerdp_peer_free(client);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,10 +26,10 @@
|
||||
|
||||
|
||||
|
||||
void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context);
|
||||
BOOL wf_peer_context_new(freerdp_peer* client, wfPeerContext* context);
|
||||
void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context);
|
||||
|
||||
void wf_peer_init(freerdp_peer* client);
|
||||
BOOL wf_peer_init(freerdp_peer* client);
|
||||
|
||||
void wf_dxgi_encode(freerdp_peer* client, UINT timeout);
|
||||
void wf_rfx_encode(freerdp_peer* client);
|
||||
@ -43,7 +43,7 @@ void wf_peer_send_changes(freerdp_peer* client);
|
||||
|
||||
void wf_detect_win_ver(void);
|
||||
|
||||
void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);
|
||||
BOOL wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client);
|
||||
|
||||
DWORD WINAPI wf_peer_main_loop(LPVOID lpParam);
|
||||
|
||||
|
@ -285,23 +285,29 @@ int shw_freerdp_client_stop(rdpContext* context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int shw_freerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
BOOL shw_freerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
shwContext* shw;
|
||||
rdpSettings* settings;
|
||||
|
||||
shw = (shwContext*) instance->context;
|
||||
|
||||
if (!(shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
return FALSE;
|
||||
|
||||
if (!(context->channels = freerdp_channels_new()))
|
||||
{
|
||||
CloseHandle(shw->StopEvent);
|
||||
shw->StopEvent = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
instance->PreConnect = shw_pre_connect;
|
||||
instance->PostConnect = shw_post_connect;
|
||||
instance->Authenticate = shw_authenticate;
|
||||
instance->VerifyCertificate = shw_verify_certificate;
|
||||
instance->VerifyX509Certificate = shw_verify_x509_certificate;
|
||||
|
||||
context->channels = freerdp_channels_new();
|
||||
|
||||
shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
settings = instance->settings;
|
||||
shw->settings = instance->context->settings;
|
||||
|
||||
@ -355,7 +361,7 @@ int shw_freerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
settings->RedirectClipboard = TRUE;
|
||||
settings->SupportDynamicChannels = TRUE;
|
||||
|
||||
return 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void shw_freerdp_client_free(freerdp* instance, rdpContext* context)
|
||||
@ -392,16 +398,28 @@ int win_shadow_rdp_init(winShadowSubsystem* subsystem)
|
||||
|
||||
shw_RdpClientEntry(&clientEntryPoints);
|
||||
|
||||
context = freerdp_client_context_new(&clientEntryPoints);
|
||||
if (!(subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
goto fail_enter_event;
|
||||
|
||||
if (!(subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
goto fail_leave_event;
|
||||
|
||||
if (!(context = freerdp_client_context_new(&clientEntryPoints)))
|
||||
goto fail_context;
|
||||
|
||||
subsystem->shw = (shwContext*) context;
|
||||
subsystem->shw->settings = context->settings;
|
||||
subsystem->shw->subsystem = subsystem;
|
||||
|
||||
subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
return 1;
|
||||
|
||||
fail_context:
|
||||
CloseHandle(subsystem->RdpUpdateLeaveEvent);
|
||||
fail_leave_event:
|
||||
CloseHandle(subsystem->RdpUpdateEnterEvent);
|
||||
fail_enter_event:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int win_shadow_rdp_start(winShadowSubsystem* subsystem)
|
||||
|
@ -47,20 +47,19 @@ int main(int argc, char** argv)
|
||||
server = shadow_server_new();
|
||||
|
||||
if (!server)
|
||||
return 0;
|
||||
goto fail_server_new;
|
||||
|
||||
status = shadow_server_parse_command_line(server, argc, argv);
|
||||
if ((status = shadow_server_parse_command_line(server, argc, argv)) < 0)
|
||||
{
|
||||
shadow_server_command_line_status_print(server, argc, argv, status);
|
||||
goto fail_parse_command_line;
|
||||
}
|
||||
|
||||
status = shadow_server_command_line_status_print(server, argc, argv, status);
|
||||
if ((status = shadow_server_init(server)) < 0)
|
||||
goto fail_server_init;
|
||||
|
||||
if (status < 0)
|
||||
return 0;
|
||||
|
||||
if (shadow_server_init(server) < 0)
|
||||
return 0;
|
||||
|
||||
if (shadow_server_start(server) < 0)
|
||||
return 0;
|
||||
if ((status = shadow_server_start(server)) < 0)
|
||||
goto fail_server_start;
|
||||
|
||||
if (g_MessagePump)
|
||||
{
|
||||
@ -73,10 +72,18 @@ int main(int argc, char** argv)
|
||||
|
||||
WaitForSingleObject(server->thread, INFINITE);
|
||||
|
||||
GetExitCodeThread(server->thread, &dwExitCode);
|
||||
if (!GetExitCodeThread(server->thread, &dwExitCode))
|
||||
status = -1;
|
||||
else
|
||||
status = (int)dwExitCode;
|
||||
|
||||
|
||||
fail_server_start:
|
||||
shadow_server_uninit(server);
|
||||
fail_server_init:
|
||||
fail_parse_command_line:
|
||||
shadow_server_free(server);
|
||||
|
||||
return 0;
|
||||
fail_server_new:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
#define TAG CLIENT_TAG("shadow")
|
||||
|
||||
void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
|
||||
BOOL shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
|
||||
{
|
||||
rdpSettings* settings;
|
||||
rdpShadowServer* server;
|
||||
@ -62,10 +62,13 @@ void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
|
||||
settings->TlsSecurity = TRUE;
|
||||
settings->NlaSecurity = FALSE;
|
||||
|
||||
settings->CertificateFile = _strdup(server->CertificateFile);
|
||||
settings->PrivateKeyFile = _strdup(server->PrivateKeyFile);
|
||||
if (!(settings->CertificateFile = _strdup(server->CertificateFile)))
|
||||
goto fail_cert_file;
|
||||
if (!(settings->PrivateKeyFile = _strdup(server->PrivateKeyFile)))
|
||||
goto fail_privkey_file;
|
||||
if (!(settings->RdpKeyFile = _strdup(settings->PrivateKeyFile)))
|
||||
goto fail_rdpkey_file;
|
||||
|
||||
settings->RdpKeyFile = _strdup(settings->PrivateKeyFile);
|
||||
|
||||
if (server->ipcSocket)
|
||||
{
|
||||
@ -77,17 +80,45 @@ void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
|
||||
client->mayView = server->mayView;
|
||||
client->mayInteract = server->mayInteract;
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&(client->lock), 4000);
|
||||
if (!InitializeCriticalSectionAndSpinCount(&(client->lock), 4000))
|
||||
goto fail_client_lock;
|
||||
|
||||
region16_init(&(client->invalidRegion));
|
||||
|
||||
client->vcm = WTSOpenServerA((LPSTR) peer->context);
|
||||
if (!client->vcm || client->vcm == INVALID_HANDLE_VALUE)
|
||||
goto fail_open_server;
|
||||
|
||||
client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!(client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
goto fail_stop_event;
|
||||
|
||||
client->encoder = shadow_encoder_new(client);
|
||||
if (!(client->encoder = shadow_encoder_new(client)))
|
||||
goto fail_encoder_new;
|
||||
|
||||
ArrayList_Add(server->clients, (void*) client);
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail_encoder_new:
|
||||
CloseHandle(client->encoder);
|
||||
client->encoder = NULL;
|
||||
fail_stop_event:
|
||||
WTSCloseServer((HANDLE) client->vcm);
|
||||
client->vcm = NULL;
|
||||
fail_open_server:
|
||||
DeleteCriticalSection(&(client->lock));
|
||||
fail_client_lock:
|
||||
free(settings->RdpKeyFile);
|
||||
settings->RdpKeyFile = NULL;
|
||||
fail_rdpkey_file:
|
||||
free(settings->PrivateKeyFile);
|
||||
settings->PrivateKeyFile = NULL;
|
||||
fail_privkey_file:
|
||||
free(settings->CertificateFile);
|
||||
settings->CertificateFile = NULL;
|
||||
fail_cert_file:
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client)
|
||||
@ -1035,13 +1066,11 @@ void* shadow_client_thread(rdpShadowClient* client)
|
||||
|
||||
freerdp_peer_context_free(peer);
|
||||
freerdp_peer_free(peer);
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer)
|
||||
BOOL shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer)
|
||||
{
|
||||
rdpShadowClient* client;
|
||||
rdpShadowServer* server;
|
||||
@ -1052,10 +1081,14 @@ void shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer)
|
||||
peer->ContextSize = sizeof(rdpShadowClient);
|
||||
peer->ContextNew = (psPeerContextNew) shadow_client_context_new;
|
||||
peer->ContextFree = (psPeerContextFree) shadow_client_context_free;
|
||||
freerdp_peer_context_new(peer);
|
||||
|
||||
if (!freerdp_peer_context_new(peer))
|
||||
return FALSE;
|
||||
|
||||
client = (rdpShadowClient*) peer->context;
|
||||
|
||||
client->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)
|
||||
shadow_client_thread, client, 0, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
int shadow_client_surface_update(rdpShadowClient* client, REGION16* region);
|
||||
void shadow_client_accepted(freerdp_listener* instance, freerdp_peer* client);
|
||||
BOOL shadow_client_accepted(freerdp_listener* instance, freerdp_peer* client);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -534,26 +534,29 @@ int shadow_server_init(rdpShadowServer* server)
|
||||
|
||||
WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi());
|
||||
|
||||
server->clients = ArrayList_New(TRUE);
|
||||
if (!(server->clients = ArrayList_New(TRUE)))
|
||||
goto fail_client_array;
|
||||
|
||||
server->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!(server->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
goto fail_stop_event;
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&(server->lock), 4000);
|
||||
if (!InitializeCriticalSectionAndSpinCount(&(server->lock), 4000))
|
||||
goto fail_server_lock;
|
||||
|
||||
status = shadow_server_init_config_path(server);
|
||||
|
||||
if (status < 0)
|
||||
return -1;
|
||||
goto fail_config_path;
|
||||
|
||||
status = shadow_server_init_certificate(server);
|
||||
|
||||
if (status < 0)
|
||||
return -1;
|
||||
goto fail_certificate;
|
||||
|
||||
server->listener = freerdp_listener_new();
|
||||
|
||||
if (!server->listener)
|
||||
return -1;
|
||||
goto fail_listener;
|
||||
|
||||
server->listener->info = (void*) server;
|
||||
server->listener->PeerAccepted = shadow_client_accepted;
|
||||
@ -561,11 +564,35 @@ int shadow_server_init(rdpShadowServer* server)
|
||||
server->subsystem = shadow_subsystem_new(NULL);
|
||||
|
||||
if (!server->subsystem)
|
||||
return -1;
|
||||
goto fail_subsystem_new;
|
||||
|
||||
status = shadow_subsystem_init(server->subsystem, server);
|
||||
|
||||
return status;
|
||||
if (status >= 0)
|
||||
return status;
|
||||
|
||||
fail_subsystem_new:
|
||||
freerdp_listener_free(server->listener);
|
||||
server->listener = NULL;
|
||||
fail_listener:
|
||||
free(server->CertificateFile);
|
||||
server->CertificateFile = NULL;
|
||||
free(server->PrivateKeyFile);
|
||||
server->PrivateKeyFile = NULL;
|
||||
fail_certificate:
|
||||
free(server->ConfigPath);
|
||||
server->ConfigPath = NULL;
|
||||
fail_config_path:
|
||||
DeleteCriticalSection(&(server->lock));
|
||||
fail_server_lock:
|
||||
CloseHandle(server->StopEvent);
|
||||
server->StopEvent = NULL;
|
||||
fail_stop_event:
|
||||
ArrayList_Free(server->clients);
|
||||
server->clients = NULL;
|
||||
fail_client_array:
|
||||
WLog_ERR(TAG, "Failed to initialize shadow server");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int shadow_server_uninit(rdpShadowServer* server)
|
||||
|
@ -126,32 +126,52 @@ rdpShadowSubsystem* shadow_subsystem_new(const char* name)
|
||||
|
||||
void shadow_subsystem_free(rdpShadowSubsystem* subsystem)
|
||||
{
|
||||
if (subsystem->ep.Free)
|
||||
if (subsystem && subsystem->ep.Free)
|
||||
subsystem->ep.Free(subsystem);
|
||||
}
|
||||
|
||||
int shadow_subsystem_init(rdpShadowSubsystem* subsystem, rdpShadowServer* server)
|
||||
{
|
||||
int status;
|
||||
int status = -1;
|
||||
|
||||
if (!subsystem || !subsystem->ep.Init)
|
||||
return -1;
|
||||
|
||||
subsystem->server = server;
|
||||
subsystem->selectedMonitor = server->selectedMonitor;
|
||||
|
||||
subsystem->MsgPipe = MessagePipe_New();
|
||||
subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!(subsystem->MsgPipe = MessagePipe_New()))
|
||||
goto fail;
|
||||
|
||||
if (!(subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
goto fail;
|
||||
|
||||
region16_init(&(subsystem->invalidRegion));
|
||||
|
||||
if (!subsystem->ep.Init)
|
||||
return -1;
|
||||
if ((status = subsystem->ep.Init(subsystem)) >= 0)
|
||||
return status;
|
||||
|
||||
status = subsystem->ep.Init(subsystem);
|
||||
fail:
|
||||
if (subsystem->MsgPipe)
|
||||
{
|
||||
MessagePipe_Free(subsystem->MsgPipe);
|
||||
subsystem->MsgPipe = NULL;
|
||||
}
|
||||
|
||||
if (subsystem->updateEvent)
|
||||
{
|
||||
CloseHandle(subsystem->updateEvent);
|
||||
subsystem->updateEvent = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void shadow_subsystem_uninit(rdpShadowSubsystem* subsystem)
|
||||
{
|
||||
if (!subsystem)
|
||||
return;
|
||||
|
||||
if (subsystem->ep.Uninit)
|
||||
subsystem->ep.Uninit(subsystem);
|
||||
|
||||
@ -175,7 +195,7 @@ int shadow_subsystem_start(rdpShadowSubsystem* subsystem)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!subsystem->ep.Start)
|
||||
if (!subsystem || !subsystem->ep.Start)
|
||||
return -1;
|
||||
|
||||
status = subsystem->ep.Start(subsystem);
|
||||
@ -187,7 +207,7 @@ int shadow_subsystem_stop(rdpShadowSubsystem* subsystem)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!subsystem->ep.Stop)
|
||||
if (!subsystem || !subsystem->ep.Stop)
|
||||
return -1;
|
||||
|
||||
status = subsystem->ep.Stop(subsystem);
|
||||
|
@ -21,7 +21,7 @@ int TestCommMonitor(int argc, char* argv[])
|
||||
if (!hComm || (hComm == INVALID_HANDLE_VALUE))
|
||||
{
|
||||
printf("CreateFileA failure: %s\n", lpFileName);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fSuccess = SetCommMask(hComm, EV_CTS | EV_DSR);
|
||||
@ -29,11 +29,15 @@ int TestCommMonitor(int argc, char* argv[])
|
||||
if (!fSuccess)
|
||||
{
|
||||
printf("SetCommMask failure: GetLastError() = %d\n", (int) GetLastError());
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
|
||||
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!(overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
printf("CreateEvent failed: GetLastError() = %d\n", (int) GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WaitCommEvent(hComm, &dwEvtMask, &overlapped))
|
||||
{
|
||||
@ -58,7 +62,7 @@ int TestCommMonitor(int argc, char* argv[])
|
||||
else
|
||||
{
|
||||
printf("WaitCommEvent failure: GetLastError() = %d\n", (int) dwError);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,10 +439,26 @@ int TestPipeCreateNamedPipe(int argc, char* argv[])
|
||||
#ifndef _WIN32
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
SingleThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_single_thread, NULL, 0, NULL);
|
||||
ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL);
|
||||
ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL);
|
||||
if (!(ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
printf("CreateEvent failure: (%d)\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
if (!(SingleThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_single_thread, NULL, 0, NULL)))
|
||||
{
|
||||
printf("CreateThread (SingleThread) failure: (%d)\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
if (!(ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL)))
|
||||
{
|
||||
printf("CreateThread (ClientThread) failure: (%d)\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
if (!(ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL)))
|
||||
{
|
||||
printf("CreateThread (ServerThread) failure: (%d)\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
WaitForSingleObject(SingleThread, INFINITE);
|
||||
WaitForSingleObject(ClientThread, INFINITE);
|
||||
WaitForSingleObject(ServerThread, INFINITE);
|
||||
|
@ -53,7 +53,13 @@ static void* named_pipe_client_thread(void* arg)
|
||||
return NULL;
|
||||
}
|
||||
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
|
||||
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
printf("CreateEvent failure: (%d)\n", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
overlapped.hEvent = hEvent;
|
||||
nNumberOfBytesToWrite = PIPE_BUFFER_SIZE;
|
||||
FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x59);
|
||||
@ -137,7 +143,13 @@ static void* named_pipe_server_thread(void* arg)
|
||||
|
||||
SetEvent(ReadyEvent);
|
||||
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
|
||||
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
printf("CreateEvent failure: (%d)\n", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
overlapped.hEvent = hEvent;
|
||||
fConnected = ConnectNamedPipe(hNamedPipe, &overlapped);
|
||||
printf("ConnectNamedPipe status: %d\n", GetLastError());
|
||||
@ -222,11 +234,26 @@ int TestPipeCreateNamedPipeOverlapped(int argc, char* argv[])
|
||||
{
|
||||
HANDLE ClientThread;
|
||||
HANDLE ServerThread;
|
||||
ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL);
|
||||
ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL);
|
||||
|
||||
if (!(ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
printf("CreateEvent failed: %d\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
if (!(ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL)))
|
||||
{
|
||||
printf("CreateThread (client) failed: %d\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
if (!(ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL)))
|
||||
{
|
||||
printf("CreateThread (server) failed: %d\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
WaitForSingleObject(ClientThread, INFINITE);
|
||||
WaitForSingleObject(ServerThread, INFINITE);
|
||||
|
||||
/* FIXME: Since this function always returns 0 this test is very much useless */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -60,10 +60,12 @@ static void module_init()
|
||||
|
||||
static TP_POOL DEFAULT_POOL =
|
||||
{
|
||||
0, /* Minimum */
|
||||
500, /* Maximum */
|
||||
NULL, /* Threads */
|
||||
0, /* ThreadCount */
|
||||
0, /* DWORD Minimum */
|
||||
500, /* DWORD Maximum */
|
||||
NULL, /* wArrayList* Threads */
|
||||
NULL, /* wQueue* PendingQueue */
|
||||
NULL, /* HANDLE TerminateEvent */
|
||||
NULL, /* wCountdownEvent* WorkComplete */
|
||||
};
|
||||
|
||||
static void* thread_pool_work_func(void* arg)
|
||||
@ -110,33 +112,62 @@ static void threads_close(void *thread)
|
||||
CloseHandle(thread);
|
||||
}
|
||||
|
||||
void InitializeThreadpool(PTP_POOL pool)
|
||||
static BOOL InitializeThreadpool(PTP_POOL pool)
|
||||
{
|
||||
int index;
|
||||
HANDLE thread;
|
||||
|
||||
if (!pool->Threads)
|
||||
if (pool->Threads)
|
||||
return TRUE;
|
||||
|
||||
pool->Minimum = 0;
|
||||
pool->Maximum = 500;
|
||||
|
||||
if (!(pool->PendingQueue = Queue_New(TRUE, -1, -1)))
|
||||
goto fail_queue_new;
|
||||
|
||||
if (!(pool->WorkComplete = CountdownEvent_New(0)))
|
||||
goto fail_countdown_event;
|
||||
|
||||
if (!(pool->TerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
goto fail_terminate_event;
|
||||
|
||||
if (!(pool->Threads = ArrayList_New(TRUE)))
|
||||
goto fail_thread_array;
|
||||
|
||||
pool->Threads->object.fnObjectFree = threads_close;
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
pool->Minimum = 0;
|
||||
pool->Maximum = 500;
|
||||
|
||||
pool->Threads = ArrayList_New(TRUE);
|
||||
pool->Threads->object.fnObjectFree = threads_close;
|
||||
|
||||
pool->PendingQueue = Queue_New(TRUE, -1, -1);
|
||||
pool->WorkComplete = CountdownEvent_New(0);
|
||||
|
||||
pool->TerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
thread = CreateThread(NULL, 0,
|
||||
if (!(thread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) thread_pool_work_func,
|
||||
(void*) pool, 0, NULL);
|
||||
|
||||
ArrayList_Add(pool->Threads, thread);
|
||||
(void*) pool, 0, NULL)))
|
||||
{
|
||||
goto fail_create_threads;
|
||||
}
|
||||
|
||||
ArrayList_Add(pool->Threads, thread);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail_create_threads:
|
||||
SetEvent(pool->TerminateEvent);
|
||||
ArrayList_Free(pool->Threads);
|
||||
pool->Threads = NULL;
|
||||
fail_thread_array:
|
||||
CloseHandle(pool->TerminateEvent);
|
||||
pool->TerminateEvent = NULL;
|
||||
fail_terminate_event:
|
||||
CountdownEvent_Free(pool->WorkComplete);
|
||||
pool->WorkComplete = NULL;
|
||||
fail_countdown_event:
|
||||
Queue_Free(pool->PendingQueue);
|
||||
pool->WorkComplete = NULL;
|
||||
fail_queue_new:
|
||||
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
PTP_POOL GetDefaultThreadpool()
|
||||
@ -145,7 +176,8 @@ PTP_POOL GetDefaultThreadpool()
|
||||
|
||||
pool = &DEFAULT_POOL;
|
||||
|
||||
InitializeThreadpool(pool);
|
||||
if (!InitializeThreadpool(pool))
|
||||
return NULL;
|
||||
|
||||
return pool;
|
||||
}
|
||||
@ -164,13 +196,17 @@ PTP_POOL CreateThreadpool(PVOID reserved)
|
||||
if (pCreateThreadpool)
|
||||
return pCreateThreadpool(reserved);
|
||||
#else
|
||||
pool = (PTP_POOL) calloc(1, sizeof(TP_POOL));
|
||||
if (!(pool = (PTP_POOL) calloc(1, sizeof(TP_POOL))))
|
||||
return NULL;
|
||||
|
||||
if (pool)
|
||||
InitializeThreadpool(pool);
|
||||
#endif
|
||||
if (!InitializeThreadpool(pool))
|
||||
{
|
||||
free(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pool;
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID CloseThreadpool(PTP_POOL ptpp)
|
||||
@ -188,7 +224,17 @@ VOID CloseThreadpool(PTP_POOL ptpp)
|
||||
CountdownEvent_Free(ptpp->WorkComplete);
|
||||
CloseHandle(ptpp->TerminateEvent);
|
||||
|
||||
free(ptpp);
|
||||
if (ptpp == &DEFAULT_POOL)
|
||||
{
|
||||
ptpp->Threads = NULL;
|
||||
ptpp->PendingQueue = NULL;
|
||||
ptpp->WorkComplete = NULL;
|
||||
ptpp->TerminateEvent = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(ptpp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,11 @@ int TestPoolThread(int argc, char* argv[])
|
||||
{
|
||||
TP_POOL* pool;
|
||||
|
||||
pool = CreateThreadpool(NULL);
|
||||
if (!(pool = CreateThreadpool(NULL)))
|
||||
{
|
||||
printf("CreateThreadpool failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
SetThreadpoolThreadMinimum(pool, 8); /* default is 0 */
|
||||
SetThreadpoolThreadMaximum(pool, 64); /* default is 500 */
|
||||
|
@ -58,7 +58,11 @@ int TestPoolWork(int argc, char* argv[])
|
||||
|
||||
printf("Private Thread Pool\n");
|
||||
|
||||
pool = CreateThreadpool(NULL);
|
||||
if (!(pool = CreateThreadpool(NULL)))
|
||||
{
|
||||
printf("CreateThreadpool failure\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
SetThreadpoolThreadMinimum(pool, 4);
|
||||
SetThreadpoolThreadMaximum(pool, 8);
|
||||
|
@ -1398,8 +1398,14 @@ WINSCARDAPI HANDLE WINAPI PCSC_SCardAccessStartedEvent(void)
|
||||
|
||||
if (!g_StartedEvent)
|
||||
{
|
||||
g_StartedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
SetEvent(g_StartedEvent);
|
||||
if (!(g_StartedEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
return NULL;
|
||||
|
||||
if (!SetEvent(g_StartedEvent))
|
||||
{
|
||||
CloseHandle(g_StartedEvent);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_StartedEventRefCount++;
|
||||
|
@ -36,12 +36,26 @@ int TestSynchBarrier(int argc, char* argv[])
|
||||
|
||||
g_Count = 0;
|
||||
|
||||
g_Event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!(g_Event = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
printf("%s: CreateEvent failed. GetLastError() = 0x%08x", __FUNCTION__, GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
InitializeCriticalSectionAndSpinCount(&g_Lock, 4000);
|
||||
if (!InitializeCriticalSectionAndSpinCount(&g_Lock, 4000))
|
||||
{
|
||||
printf("%s: InitializeCriticalSectionAndSpinCount failed. GetLastError() = 0x%08x", __FUNCTION__, GetLastError());
|
||||
CloseHandle(g_Event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!InitializeSynchronizationBarrier(&g_Barrier, 5, -1))
|
||||
{
|
||||
printf("%s: InitializeSynchronizationBarrier failed. GetLastError() = 0x%08x", __FUNCTION__, GetLastError());
|
||||
DeleteCriticalSection(&g_Lock);
|
||||
CloseHandle(g_Event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (index = 0; index < 5; index++)
|
||||
{
|
||||
|
@ -57,6 +57,11 @@ int TestSynchTimerQueue(int argc, char* argv[])
|
||||
APC_DATA apcData[TIMER_COUNT];
|
||||
|
||||
g_Event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!g_Event)
|
||||
{
|
||||
printf("CreateEvent failed (%d)\n", (int) GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
hTimerQueue = CreateTimerQueue();
|
||||
|
||||
|
@ -44,9 +44,16 @@ int TestSynchWaitableTimerAPC(int argc, char* argv[])
|
||||
if (!apcData)
|
||||
{
|
||||
printf("Memory allocation failed\n");
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
g_Event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!g_Event)
|
||||
{
|
||||
printf("Failed to create event\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
|
||||
|
||||
if (!hTimer)
|
||||
|
@ -152,20 +152,32 @@ wCountdownEvent* CountdownEvent_New(DWORD initialCount)
|
||||
{
|
||||
wCountdownEvent* countdown = NULL;
|
||||
|
||||
countdown = (wCountdownEvent*) malloc(sizeof(wCountdownEvent));
|
||||
if (!(countdown = (wCountdownEvent*) calloc(1, sizeof(wCountdownEvent))))
|
||||
return NULL;
|
||||
|
||||
if (countdown)
|
||||
{
|
||||
countdown->count = initialCount;
|
||||
countdown->initialCount = initialCount;
|
||||
InitializeCriticalSectionAndSpinCount(&countdown->lock, 4000);
|
||||
countdown->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
countdown->count = initialCount;
|
||||
countdown->initialCount = initialCount;
|
||||
|
||||
if (countdown->count == 0)
|
||||
SetEvent(countdown->event);
|
||||
}
|
||||
if (!InitializeCriticalSectionAndSpinCount(&countdown->lock, 4000))
|
||||
goto fail_critical_section;
|
||||
|
||||
if (!(countdown->event = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
goto fail_create_event;
|
||||
|
||||
if (countdown->count == 0)
|
||||
if (!SetEvent(countdown->event))
|
||||
goto fail_set_event;
|
||||
|
||||
return countdown;
|
||||
|
||||
fail_set_event:
|
||||
CloseHandle(countdown->event);
|
||||
fail_create_event:
|
||||
DeleteCriticalSection(&countdown->lock);
|
||||
fail_critical_section:
|
||||
free(countdown);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CountdownEvent_Free(wCountdownEvent* countdown)
|
||||
|
Loading…
Reference in New Issue
Block a user