From d211adceaed92277508a946575c3a54741fe5fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 23 Aug 2012 16:09:46 -0400 Subject: [PATCH 1/7] libfreerdp-crypto: temporarily disable free() operations causing crash in Windows FreeRDP server --- libfreerdp/crypto/nla.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/libfreerdp/crypto/nla.c b/libfreerdp/crypto/nla.c index e98663b37..1592740ba 100644 --- a/libfreerdp/crypto/nla.c +++ b/libfreerdp/crypto/nla.c @@ -383,7 +383,6 @@ int credssp_server_authenticate(rdpCredssp* credssp) CredHandle credentials; TimeStamp expiration; PSecPkgInfo pPackageInfo; - PSecBuffer p_buffer; SecBuffer input_buffer; SecBuffer output_buffer; SecBufferDesc input_buffer_desc; @@ -463,6 +462,8 @@ int credssp_server_authenticate(rdpCredssp* credssp) have_pub_key_auth = false; ZeroMemory(&input_buffer, sizeof(SecBuffer)); ZeroMemory(&output_buffer, sizeof(SecBuffer)); + ZeroMemory(&input_buffer_desc, sizeof(SecBufferDesc)); + ZeroMemory(&output_buffer_desc, sizeof(SecBufferDesc)); ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes)); /* @@ -506,9 +507,8 @@ int credssp_server_authenticate(rdpCredssp* credssp) credssp_buffer_print(credssp); #endif - p_buffer = &input_buffer_desc.pBuffers[0]; - p_buffer->pvBuffer = credssp->negoToken.pvBuffer; - p_buffer->cbBuffer = credssp->negoToken.cbBuffer; + input_buffer.pvBuffer = credssp->negoToken.pvBuffer; + input_buffer.cbBuffer = credssp->negoToken.cbBuffer; if (credssp->negoToken.cbBuffer < 1) { @@ -528,15 +528,8 @@ int credssp_server_authenticate(rdpCredssp* credssp) &input_buffer_desc, fContextReq, SECURITY_NATIVE_DREP, &credssp->context, &output_buffer_desc, &pfContextAttr, &expiration); - if (input_buffer.pvBuffer != NULL) - { - free(input_buffer.pvBuffer); - input_buffer.pvBuffer = NULL; - } - - p_buffer = &output_buffer_desc.pBuffers[0]; - credssp->negoToken.pvBuffer = p_buffer->pvBuffer; - credssp->negoToken.cbBuffer = p_buffer->cbBuffer; + credssp->negoToken.pvBuffer = output_buffer.pvBuffer; + credssp->negoToken.cbBuffer = output_buffer.cbBuffer; if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED)) { @@ -565,7 +558,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) return -1; } - sspi_SecBufferFree(&credssp->negoToken); + //sspi_SecBufferFree(&credssp->negoToken); credssp->negoToken.pvBuffer = NULL; credssp->negoToken.cbBuffer = 0; @@ -586,7 +579,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) #endif credssp_send(credssp); - credssp_buffer_free(credssp); + //credssp_buffer_free(credssp); if (status != SEC_I_CONTINUE_NEEDED) break; @@ -1316,6 +1309,6 @@ void credssp_free(rdpCredssp* credssp) free(credssp->identity.User); free(credssp->identity.Domain); free(credssp->identity.Password); - free(credssp); + //free(credssp); } } From 9c507b179a5f2d14297ed44a3a5d6af9fae3d300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 23 Aug 2012 16:35:54 -0400 Subject: [PATCH 2/7] wfreerdp-server: cleanup code style --- server/Windows/wf_info.c | 164 ++++++++++++++++---------------- server/Windows/wf_mirage.c | 43 +++++---- server/Windows/wf_peer.c | 190 ++++++++++++++++++------------------- 3 files changed, 194 insertions(+), 203 deletions(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 1289f82d9..872959790 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -17,7 +17,12 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include + #include #include @@ -26,35 +31,26 @@ wfInfo * wf_info_init(wfInfo * info) { - if(!info) + if (!info) { - info = (wfInfo*)malloc(sizeof(wfInfo)); //free this on shutdown - memset(info, 0, sizeof(wfInfo)); + info = (wfInfo*) malloc(sizeof(wfInfo)); + ZeroMemory(info, sizeof(wfInfo)); - info->mutex = CreateMutex( - NULL, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex + info->mutex = CreateMutex(NULL, FALSE, NULL); if (info->mutex == NULL) { _tprintf(_T("CreateMutex error: %d\n"), GetLastError()); } - info->encodeMutex = CreateMutex( - NULL, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex + info->encodeMutex = CreateMutex(NULL, FALSE, NULL); if (info->encodeMutex == NULL) { _tprintf(_T("CreateMutex error: %d\n"), GetLastError()); } - info->can_send_mutex = CreateMutex( - NULL, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex + info->can_send_mutex = CreateMutex(NULL, FALSE, NULL); if (info->can_send_mutex == NULL) { @@ -69,17 +65,16 @@ void wf_info_mirror_init(wfInfo * info, wfPeerContext* context) { DWORD dRes; - - dRes = WaitForSingleObject( - info->mutex, // handle to mutex - INFINITE); // no time-out interval + dRes = WaitForSingleObject(info->mutex, INFINITE); switch(dRes) { case WAIT_OBJECT_0: - if(info->subscribers == 0) + + if (info->subscribers == 0) { - //only the first peer needs to call this. + /* only the first peer needs to call this. */ + context->wfInfo = info; wf_check_disp_devices(context->wfInfo); wf_disp_device_set_attatch(context->wfInfo, 1); @@ -99,22 +94,25 @@ void wf_info_mirror_init(wfInfo * info, wfPeerContext* context) } ++info->subscribers; - if (! ReleaseMutex(info->mutex)) - { - _tprintf(_T("Error releasing mutex\n")); - } + if (!ReleaseMutex(info->mutex)) + { + _tprintf(_T("Error releasing mutex\n")); + } break; default: _tprintf(_T("Error waiting for mutex: %d\n"), dRes); + break; } - } -//todo: i think i can replace all the context->info here with info -//in fact it may not even care about subscribers +/** + * TODO: i think i can replace all the context->info here with info + * in fact it may not even care about subscribers + */ + void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context) { DWORD dRes; @@ -124,12 +122,14 @@ void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context) { dRes = WaitForSingleObject(info->encodeMutex, INFINITE); - switch (dRes) - { - // The thread got ownership of the mutex - case WAIT_OBJECT_0: + + switch (dRes) + { + /* The thread got ownership of the mutex */ + + case WAIT_OBJECT_0: --info->subscribers; - //only the last peer needs to call this + /* only the last peer needs to call this */ wf_mirror_cleanup(context->wfInfo); wf_disp_device_set_attatch(context->wfInfo, 0); wf_update_mirror_drv(context->wfInfo, 1); @@ -138,14 +138,17 @@ void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context) rfx_context_free(context->rfx_context); printf("Stop encoder\n"); - break; + break; - // The thread got ownership of an abandoned mutex - // The database is in an indeterminate state - default: - printf("wf_info_subscriber_release: Something else happened!!! dRes = %d\n", dRes); - } - } + /** + * The thread got ownership of an abandoned mutex + * The database is in an indeterminate state + */ + default: + printf("wf_info_subscriber_release: Something else happened!!! dRes = %d\n", dRes); + break; + } + } else { --info->subscribers; @@ -153,44 +156,44 @@ void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context) ReleaseMutex(info->mutex); - /*************** - Note: if we released the last subscriber, - block the encoder until next subscriber - ***************/ - + /** + * Note: if we released the last subscriber, + * block the encoder until next subscriber + */ } - BOOL wf_info_has_subscribers(wfInfo* info) { int subs; - WaitForSingleObject(info->mutex, INFINITE); + WaitForSingleObject(info->mutex, INFINITE); + subs = info->subscribers; ReleaseMutex(info->mutex); - if(info->subscribers > 0) - return true; - return false; + if (info->subscribers > 0) + return TRUE; + + return FALSE; } BOOL wf_info_have_updates(wfInfo* info) { - BOOL ret; - ret = true; + BOOL status = TRUE; + WaitForSingleObject(info->mutex, INFINITE); - if(info->nextUpdate == info->lastUpdate) - ret = false; + + if (info->nextUpdate == info->lastUpdate) + status = FALSE; + ReleaseMutex(info->mutex); - return ret; + return status; } - void wf_info_updated(wfInfo* info) { - WaitForSingleObject(info->mutex, INFINITE); info->lastUpdate = info->nextUpdate; ReleaseMutex(info->mutex); @@ -216,35 +219,27 @@ void wf_info_find_invalid_region(wfInfo* info) WaitForSingleObject(info->mutex, INFINITE); buf = (GETCHANGESBUF*)info->changeBuffer; - if(info->enc_data == false) + if (info->enc_data == FALSE) { - info->invalid_x1 = 1920;//info->width; + info->invalid_x1 = 1920; info->invalid_x2 = 0; - info->invalid_y1 = 1200;// info->height; + info->invalid_y1 = 1200; info->invalid_y2 = 0; } - //printf("\tFIND = (%d, %d), (%d, %d)\n", info->invalid_x1, info->invalid_y1, info->invalid_x2, info->invalid_y2); - for(i = info->lastUpdate; i != info->nextUpdate; i = (i+1) % MAXCHANGES_BUF ) + for (i = info->lastUpdate; i != info->nextUpdate; i = (i+1) % MAXCHANGES_BUF ) { - /*printf("\t(%d, %d), (%d, %d)\n", - buf->buffer->pointrect[i].rect.left, - buf->buffer->pointrect[i].rect.top, - buf->buffer->pointrect[i].rect.right, - buf->buffer->pointrect[i].rect.bottom); - */ info->invalid_x1 = min(info->invalid_x1, buf->buffer->pointrect[i].rect.left); info->invalid_x2 = max(info->invalid_x2, buf->buffer->pointrect[i].rect.right); info->invalid_y1 = min(info->invalid_y1, buf->buffer->pointrect[i].rect.top); info->invalid_y2 = max(info->invalid_y2, buf->buffer->pointrect[i].rect.bottom); } + ReleaseMutex(info->mutex); } - void wf_info_clear_invalid_region(wfInfo* info) { - WaitForSingleObject(info->mutex, INFINITE); info->lastUpdate = info->nextUpdate; info->invalid_x1 = info->width; @@ -256,46 +251,47 @@ void wf_info_clear_invalid_region(wfInfo* info) BOOL wf_info_have_invalid_region(wfInfo* info) { - if((info->invalid_x1 >= info->invalid_x2) || (info->invalid_y1 >= info->invalid_y2)) - return false; - return true; + if ((info->invalid_x1 >= info->invalid_x2) || (info->invalid_y1 >= info->invalid_y2)) + return FALSE; + + return TRUE; } int wf_info_get_height(wfInfo* info) { - int ret; + int height; WaitForSingleObject(info->mutex, INFINITE); - ret = info->height; + height = info->height; ReleaseMutex(info->mutex); - return ret; + return height; } int wf_info_get_width(wfInfo* info) { - int ret; + int width; WaitForSingleObject(info->mutex, INFINITE); - ret = info->width; + width = info->width; ReleaseMutex(info->mutex); - return ret; + return width; } int wf_info_get_thread_count(wfInfo* info) { - int ret; + int count; + WaitForSingleObject(info->mutex, INFINITE); - ret = info->threadCnt; + count = info->threadCnt; ReleaseMutex(info->mutex); - return ret; + + return count; } - void wf_info_set_thread_count(wfInfo* info, int count) { - WaitForSingleObject(info->mutex, INFINITE); info->threadCnt = count; ReleaseMutex(info->mutex); diff --git a/server/Windows/wf_mirage.c b/server/Windows/wf_mirage.c index 514288fd0..4ca8e42c8 100644 --- a/server/Windows/wf_mirage.c +++ b/server/Windows/wf_mirage.c @@ -145,22 +145,23 @@ If unload is nonzero then the the driver will be asked to remove it self. */ BOOL wf_update_mirror_drv(wfInfo* context, int unload) { - int currentScreenPixHeight, currentScreenPixWidth, currentScreenBPP; HDC dc; - LONG status; + BOOL status; DWORD* extHdr; + TCHAR rMsg[64]; WORD drvExtraSaved; DEVMODE* deviceMode; + int currentScreenBPP; + int currentScreenPixHeight; + int currentScreenPixWidth; + LONG disp_change_status; DWORD dmf_devmodewext_magic_sig = 0xDF20C0DE; - TCHAR rMsg[64]; - BOOL rturn; - if(!unload) + if (!unload) { /* - Will have to come back to this for supporting non primary displays and - multimonitor setups - */ + * Will have to come back to this for supporting non primary displays and multimonitor setups + */ dc = GetDC(NULL); currentScreenPixHeight = GetDeviceCaps(dc, VERTRES); currentScreenPixWidth = GetDeviceCaps(dc, HORZRES); @@ -202,14 +203,15 @@ BOOL wf_update_mirror_drv(wfInfo* context, int unload) _tcsncpy_s(deviceMode->dmDeviceName, 32, context->deviceName, _tcslen(context->deviceName)); - status = ChangeDisplaySettingsEx(context->deviceName, deviceMode, NULL, CDS_UPDATEREGISTRY, NULL); + disp_change_status = ChangeDisplaySettingsEx(context->deviceName, deviceMode, NULL, CDS_UPDATEREGISTRY, NULL); - rturn = false; - switch (status) + status = FALSE; + + switch (disp_change_status) { case DISP_CHANGE_SUCCESSFUL: _tprintf(_T("ChangeDisplaySettingsEx() was successfull\n")); - rturn = true; + status = true; break; case DISP_CHANGE_BADDUALVIEW: @@ -241,10 +243,10 @@ BOOL wf_update_mirror_drv(wfInfo* context, int unload) break; } - if(!rturn) - _tprintf(_T("ChangeDisplaySettingsEx() failed with %s, code %d\n"), rMsg, status); + if (!status) + _tprintf(_T("ChangeDisplaySettingsEx() failed with %s, code %d\n"), rMsg, disp_change_status); - return rturn; + return status; } @@ -259,7 +261,7 @@ BOOL wf_map_mirror_mem(wfInfo* context) if (context->driverDC == NULL) { _tprintf(_T("Could not create device driver context!\n")); - return false; + return FALSE; } context->changeBuffer = malloc(sizeof(GETCHANGESBUF)); @@ -276,7 +278,7 @@ BOOL wf_map_mirror_mem(wfInfo* context) b = (GETCHANGESBUF*)context->changeBuffer; _tprintf(_T("ExtEscape() returned code %d\n"), status); - return true; + return TRUE; } /* @@ -289,13 +291,14 @@ BOOL wf_mirror_cleanup(wfInfo* context) _tprintf(_T("\n\nCleaning up...\nDisconnecting driver...\n")); iResult = ExtEscape(context->driverDC, dmf_esc_usm_pipe_unmap, sizeof(context->changeBuffer), (LPSTR) context->changeBuffer, 0, 0); - if(iResult <= 0) + if (iResult <= 0) { _tprintf(_T("Failed to unmap shared memory from the driver! Code %d\n"), iResult); } _tprintf(_T("Releasing DC\n")); - if(context->driverDC != NULL) + + if (context->driverDC != NULL) { iResult = DeleteDC(context->driverDC); if(iResult == 0) @@ -307,4 +310,4 @@ BOOL wf_mirror_cleanup(wfInfo* context) free(context->changeBuffer); return true; -} \ No newline at end of file +} diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index cc0a5d94c..958f3563e 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -46,37 +46,37 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) { - DWORD start, end, diff; + DWORD start; + DWORD end; + DWORD diff; DWORD rate; - freerdp_peer* client; rate = 42; client = (freerdp_peer*)lpParam; - //todo: make sure we dont encode after no clients + /* TODO: do not encode when no clients are connected */ + while(1) { start = GetTickCount(); - - if(wf_info_has_subscribers(wfInfoSingleton)) + if (wf_info_has_subscribers(wfInfoSingleton)) { wf_info_update_changes(wfInfoSingleton); - if(wf_info_have_updates(wfInfoSingleton)) + + if (wf_info_have_updates(wfInfoSingleton)) { - //wf_info_find_invalid_region(wfInfoSingleton); - //printf("Fake Encode!\n"); wf_rfx_encode(client); } } end = GetTickCount(); diff = end - start; - if(diff < rate) + + if (diff < rate) { - //printf("sleeping for %d ms...\n", rate - diff); Sleep(rate - diff); } @@ -84,6 +84,7 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) _tprintf(_T("monitor thread terminating...\n")); wf_info_set_thread_count(wfInfoSingleton, wf_info_get_thread_count(wfInfoSingleton) - 1 ); + return 0; } @@ -105,74 +106,71 @@ void wf_rfx_encode(freerdp_peer* client) dRes = WaitForSingleObject(wfInfoSingleton->encodeMutex, INFINITE); switch(dRes) { - case WAIT_OBJECT_0: + case WAIT_OBJECT_0: - wf_info_find_invalid_region(wfInfoSingleton); + wf_info_find_invalid_region(wfInfoSingleton); - if( (wfp->activated == false) || - (wf_info_has_subscribers(wfInfoSingleton) == false) || - !wf_info_have_invalid_region(wfInfoSingleton) || - (wfInfoSingleton->enc_data == true) ) - { + if( (wfp->activated == false) || + (wf_info_has_subscribers(wfInfoSingleton) == false) || + !wf_info_have_invalid_region(wfInfoSingleton) || + (wfInfoSingleton->enc_data == true) ) + { + ReleaseMutex(wfInfoSingleton->encodeMutex); + break; + } + + update = client->update; + cmd = &update->surface_bits_command; + wfi = wfp->wfInfo; + buf = (GETCHANGESBUF*)wfi->changeBuffer; + + width = wfi->invalid_x2 - wfi->invalid_x1; + height = wfi->invalid_y2 - wfi->invalid_y1; + + stream_clear(wfp->s); + stream_set_pos(wfp->s, 0); + s = wfp->s; + + rect.x = 0; + rect.y = 0; + rect.width = (uint16) width; + rect.height = (uint16) height; + + offset = (4 * wfi->invalid_x1) + (wfi->invalid_y1 * wfi->width * 4); + + rfx_compose_message(wfp->rfx_context, s, &rect, 1, + ((uint8*) (buf->Userbuffer)) + offset, width, height, wfi->width * 4); + + cmd->destLeft = wfi->invalid_x1; + cmd->destTop = wfi->invalid_y1; + cmd->destRight = wfi->invalid_x1 + width; + cmd->destBottom = wfi->invalid_y1 + height; + + cmd->bpp = 32; + cmd->codecID = client->settings->rfx_codec_id; + cmd->width = width; + cmd->height = height; + cmd->bitmapDataLength = stream_get_length(s); + cmd->bitmapData = stream_get_head(s); + + wfi->enc_data = true; ReleaseMutex(wfInfoSingleton->encodeMutex); break; - } - update = client->update; - cmd = &update->surface_bits_command; - wfi = wfp->wfInfo; - buf = (GETCHANGESBUF*)wfi->changeBuffer; + case WAIT_TIMEOUT: - //printf("encode %d\n", wfi->nextUpdate - wfi->lastUpdate); - //printf("\tinvlaid region = (%d, %d), (%d, %d)\n", wfi->invalid_x1, wfi->invalid_y1, wfi->invalid_x2, wfi->invalid_y2); + ReleaseMutex(wfInfoSingleton->encodeMutex); + break; - width = wfi->invalid_x2 - wfi->invalid_x1; - height = wfi->invalid_y2 - wfi->invalid_y1; + case WAIT_ABANDONED: - stream_clear(wfp->s); - stream_set_pos(wfp->s, 0); - s = wfp->s; - - rect.x = 0; - rect.y = 0; - rect.width = (uint16) width; - rect.height = (uint16) height; + printf("\n\nwf_rfx_encode: Got ownership of abandoned mutex... releasing...\n", dRes); + ReleaseMutex(wfInfoSingleton->encodeMutex); + break; - offset = (4 * wfi->invalid_x1) + (wfi->invalid_y1 * wfi->width * 4); - - //printf("width = %d, height = %d\n", width, height); - rfx_compose_message(wfp->rfx_context, s, &rect, 1, - ((uint8*) (buf->Userbuffer)) + offset, width, height, wfi->width * 4); - - cmd->destLeft = wfi->invalid_x1; - cmd->destTop = wfi->invalid_y1; - cmd->destRight = wfi->invalid_x1 + width; - cmd->destBottom = wfi->invalid_y1 + height; - - - cmd->bpp = 32; - cmd->codecID = client->settings->rfx_codec_id; - cmd->width = width; - cmd->height = height; - cmd->bitmapDataLength = stream_get_length(s); - cmd->bitmapData = stream_get_head(s); - - wfi->enc_data = true; - ReleaseMutex(wfInfoSingleton->encodeMutex); - break; - - case WAIT_TIMEOUT: - - ReleaseMutex(wfInfoSingleton->encodeMutex); - break; - - case WAIT_ABANDONED: - - printf("\n\nwf_rfx_encode: Got ownership of abandoned mutex... releasing...\n", dRes); - ReleaseMutex(wfInfoSingleton->encodeMutex); - break; - default: - printf("\n\nwf_rfx_encode: Something else happened!!! dRes = %d\n", dRes); + default: + printf("\n\nwf_rfx_encode: Something else happened!!! dRes = %d\n", dRes); + break; } } @@ -224,8 +222,7 @@ boolean wf_peer_post_connect(freerdp_peer* client) printf("But we will try resizing to %dx%d\n", wf_info_get_width(wfInfoSingleton), - wf_info_get_height(wfInfoSingleton) - ); + wf_info_get_height(wfInfoSingleton)); client->settings->width = wf_info_get_width(wfInfoSingleton); client->settings->height = wf_info_get_height(wfInfoSingleton); @@ -253,40 +250,35 @@ void wf_peer_send_changes(rdpUpdate* update) { int dRes; - //are we currently encoding? + /* are we currently encoding? */ dRes = WaitForSingleObject(wfInfoSingleton->encodeMutex, 0); + switch(dRes) { - case WAIT_OBJECT_0: - //are there changes to send? - if( !wf_info_have_updates(wfInfoSingleton) || !wf_info_have_invalid_region(wfInfoSingleton) || (wfInfoSingleton->enc_data == false) ) - { + case WAIT_OBJECT_0: + + /* are there changes to send? */ + if (!wf_info_have_updates(wfInfoSingleton) || + !wf_info_have_invalid_region(wfInfoSingleton) || + (wfInfoSingleton->enc_data == FALSE)) + { + ReleaseMutex(wfInfoSingleton->encodeMutex); + break; + } + + wf_info_updated(wfInfoSingleton); + + update->SurfaceBits(update->context, &update->surface_bits_command); + + wfInfoSingleton->enc_data = FALSE; ReleaseMutex(wfInfoSingleton->encodeMutex); break; - } - - wf_info_updated(wfInfoSingleton); - /* - printf("\tSend..."); - printf("\t(%d, %d), (%d, %d) [%dx%d]\n", - update->surface_bits_command.destLeft, update->surface_bits_command.destTop, - update->surface_bits_command.destRight, update->surface_bits_command.destBottom, - update->surface_bits_command.width, update->surface_bits_command.height); - */ - update->SurfaceBits(update->context, &update->surface_bits_command); - //wf_info_clear_invalid_region(wfInfoSingleton); - wfInfoSingleton->enc_data = false; - ReleaseMutex(wfInfoSingleton->encodeMutex); - break; + case WAIT_TIMEOUT: + break; - case WAIT_TIMEOUT: - break; - - - default: - printf("wf_peer_send_changes: Something else happened!!! dRes = %d\n", dRes); + default: + printf("wf_peer_send_changes: Something else happened!!! dRes = %d\n", dRes); + break; } - - } From c60c013d5e1bad92f6326a48d2a7732b051130b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 23 Aug 2012 17:10:22 -0400 Subject: [PATCH 3/7] wfreerdp-server: fix crash with out of bound coordinates --- server/Windows/wf_info.c | 189 ++++++++++++++++++++----------------- server/Windows/wf_info.h | 34 +++---- server/Windows/wf_mirage.c | 46 ++++----- server/Windows/wf_peer.c | 27 +++--- server/Windows/wf_peer.h | 3 +- 5 files changed, 154 insertions(+), 145 deletions(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 872959790..7fe6f10f8 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -29,53 +29,53 @@ #include "wf_info.h" #include "wf_mirage.h" -wfInfo * wf_info_init(wfInfo * info) +wfInfo* wf_info_init(wfInfo * wfi) { - if (!info) + if (!wfi) { - info = (wfInfo*) malloc(sizeof(wfInfo)); - ZeroMemory(info, sizeof(wfInfo)); + wfi = (wfInfo*) malloc(sizeof(wfInfo)); + ZeroMemory(wfi, sizeof(wfInfo)); - info->mutex = CreateMutex(NULL, FALSE, NULL); + wfi->mutex = CreateMutex(NULL, FALSE, NULL); - if (info->mutex == NULL) + if (wfi->mutex == NULL) { _tprintf(_T("CreateMutex error: %d\n"), GetLastError()); } - info->encodeMutex = CreateMutex(NULL, FALSE, NULL); + wfi->encodeMutex = CreateMutex(NULL, FALSE, NULL); - if (info->encodeMutex == NULL) + if (wfi->encodeMutex == NULL) { _tprintf(_T("CreateMutex error: %d\n"), GetLastError()); } - info->can_send_mutex = CreateMutex(NULL, FALSE, NULL); + wfi->can_send_mutex = CreateMutex(NULL, FALSE, NULL); - if (info->can_send_mutex == NULL) + if (wfi->can_send_mutex == NULL) { _tprintf(_T("CreateMutex error: %d\n"), GetLastError()); } } - return info; + return wfi; } -void wf_info_mirror_init(wfInfo * info, wfPeerContext* context) +void wf_info_mirror_init(wfInfo* wfi, wfPeerContext* context) { DWORD dRes; - dRes = WaitForSingleObject(info->mutex, INFINITE); + dRes = WaitForSingleObject(wfi->mutex, INFINITE); switch(dRes) { case WAIT_OBJECT_0: - if (info->subscribers == 0) + if (wfi->subscribers == 0) { /* only the first peer needs to call this. */ - context->wfInfo = info; + context->wfInfo = wfi; wf_check_disp_devices(context->wfInfo); wf_disp_device_set_attatch(context->wfInfo, 1); wf_update_mirror_drv(context->wfInfo, 0); @@ -90,11 +90,11 @@ void wf_info_mirror_init(wfInfo * info, wfPeerContext* context) context->s = stream_new(65536); printf("Start Encoder\n"); - ReleaseMutex(info->encodeMutex); + ReleaseMutex(wfi->encodeMutex); } - ++info->subscribers; + ++wfi->subscribers; - if (!ReleaseMutex(info->mutex)) + if (!ReleaseMutex(wfi->mutex)) { _tprintf(_T("Error releasing mutex\n")); } @@ -113,22 +113,22 @@ void wf_info_mirror_init(wfInfo * info, wfPeerContext* context) * in fact it may not even care about subscribers */ -void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context) +void wf_info_subscriber_release(wfInfo* wfi, wfPeerContext* context) { DWORD dRes; - WaitForSingleObject(info->mutex, INFINITE); - if (context && (info->subscribers == 1)) + WaitForSingleObject(wfi->mutex, INFINITE); + + if (context && (wfi->subscribers == 1)) { - - dRes = WaitForSingleObject(info->encodeMutex, INFINITE); + dRes = WaitForSingleObject(wfi->encodeMutex, INFINITE); switch (dRes) { /* The thread got ownership of the mutex */ case WAIT_OBJECT_0: - --info->subscribers; + --wfi->subscribers; /* only the last peer needs to call this */ wf_mirror_cleanup(context->wfInfo); wf_disp_device_set_attatch(context->wfInfo, 0); @@ -151,10 +151,10 @@ void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context) } else { - --info->subscribers; + --wfi->subscribers; } - ReleaseMutex(info->mutex); + ReleaseMutex(wfi->mutex); /** * Note: if we released the last subscriber, @@ -162,137 +162,154 @@ void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context) */ } -BOOL wf_info_has_subscribers(wfInfo* info) +BOOL wf_info_has_subscribers(wfInfo* wfi) { int subs; - WaitForSingleObject(info->mutex, INFINITE); + WaitForSingleObject(wfi->mutex, INFINITE); - subs = info->subscribers; - ReleaseMutex(info->mutex); + subs = wfi->subscribers; + ReleaseMutex(wfi->mutex); - if (info->subscribers > 0) + if (wfi->subscribers > 0) return TRUE; return FALSE; } -BOOL wf_info_have_updates(wfInfo* info) +BOOL wf_info_have_updates(wfInfo* wfi) { BOOL status = TRUE; - WaitForSingleObject(info->mutex, INFINITE); + WaitForSingleObject(wfi->mutex, INFINITE); - if (info->nextUpdate == info->lastUpdate) + if (wfi->nextUpdate == wfi->lastUpdate) status = FALSE; - ReleaseMutex(info->mutex); + ReleaseMutex(wfi->mutex); return status; } -void wf_info_updated(wfInfo* info) +void wf_info_updated(wfInfo* wfi) { - WaitForSingleObject(info->mutex, INFINITE); - info->lastUpdate = info->nextUpdate; - ReleaseMutex(info->mutex); + WaitForSingleObject(wfi->mutex, INFINITE); + + wfi->lastUpdate = wfi->nextUpdate; + + ReleaseMutex(wfi->mutex); } - -void wf_info_update_changes(wfInfo* info) +void wf_info_update_changes(wfInfo* wfi) { GETCHANGESBUF* buf; - WaitForSingleObject(info->mutex, INFINITE); - buf = (GETCHANGESBUF*)info->changeBuffer; - info->nextUpdate = buf->buffer->counter; - ReleaseMutex(info->mutex); + WaitForSingleObject(wfi->mutex, INFINITE); + + buf = (GETCHANGESBUF*) wfi->changeBuffer; + wfi->nextUpdate = buf->buffer->counter; + + ReleaseMutex(wfi->mutex); } - -void wf_info_find_invalid_region(wfInfo* info) +void wf_info_find_invalid_region(wfInfo* wfi) { int i; GETCHANGESBUF* buf; - WaitForSingleObject(info->mutex, INFINITE); - buf = (GETCHANGESBUF*)info->changeBuffer; + WaitForSingleObject(wfi->mutex, INFINITE); + buf = (GETCHANGESBUF*) wfi->changeBuffer; - if (info->enc_data == FALSE) + if (wfi->enc_data == FALSE) { - info->invalid_x1 = 1920; - info->invalid_x2 = 0; - info->invalid_y1 = 1200; - info->invalid_y2 = 0; + wfi->invalid_x1 = wfi->width - 1; + wfi->invalid_x2 = 0; + wfi->invalid_y1 = wfi->height - 1; + wfi->invalid_y2 = 0; } - for (i = info->lastUpdate; i != info->nextUpdate; i = (i+1) % MAXCHANGES_BUF ) + for (i = wfi->lastUpdate; i != wfi->nextUpdate; i = (i + 1) % MAXCHANGES_BUF) { - info->invalid_x1 = min(info->invalid_x1, buf->buffer->pointrect[i].rect.left); - info->invalid_x2 = max(info->invalid_x2, buf->buffer->pointrect[i].rect.right); - info->invalid_y1 = min(info->invalid_y1, buf->buffer->pointrect[i].rect.top); - info->invalid_y2 = max(info->invalid_y2, buf->buffer->pointrect[i].rect.bottom); + wfi->invalid_x1 = min(wfi->invalid_x1, buf->buffer->pointrect[i].rect.left); + wfi->invalid_x2 = max(wfi->invalid_x2, buf->buffer->pointrect[i].rect.right); + wfi->invalid_y1 = min(wfi->invalid_y1, buf->buffer->pointrect[i].rect.top); + wfi->invalid_y2 = max(wfi->invalid_y2, buf->buffer->pointrect[i].rect.bottom); } - ReleaseMutex(info->mutex); + if (wfi->invalid_x1 < 0) + wfi->invalid_x1 = 0; + + if (wfi->invalid_y1 < 0) + wfi->invalid_y1 = 0; + + if (wfi->invalid_x2 >= wfi->width) + wfi->invalid_x2 = wfi->width - 1; + + if (wfi->invalid_y2 >= wfi->height) + wfi->invalid_y2 = wfi->height - 1; + + ReleaseMutex(wfi->mutex); } -void wf_info_clear_invalid_region(wfInfo* info) +void wf_info_clear_invalid_region(wfInfo* wfi) { - WaitForSingleObject(info->mutex, INFINITE); - info->lastUpdate = info->nextUpdate; - info->invalid_x1 = info->width; - info->invalid_x2 = 0; - info->invalid_y1 = info->height; - info->invalid_y2 = 0; - ReleaseMutex(info->mutex); + WaitForSingleObject(wfi->mutex, INFINITE); + + wfi->lastUpdate = wfi->nextUpdate; + + wfi->invalid_x1 = wfi->width - 1; + wfi->invalid_x2 = 0; + wfi->invalid_y1 = wfi->height - 1; + wfi->invalid_y2 = 0; + + ReleaseMutex(wfi->mutex); } -BOOL wf_info_have_invalid_region(wfInfo* info) +BOOL wf_info_have_invalid_region(wfInfo* wfi) { - if ((info->invalid_x1 >= info->invalid_x2) || (info->invalid_y1 >= info->invalid_y2)) + if ((wfi->invalid_x1 >= wfi->invalid_x2) || (wfi->invalid_y1 >= wfi->invalid_y2)) return FALSE; return TRUE; } -int wf_info_get_height(wfInfo* info) +int wf_info_get_height(wfInfo* wfi) { int height; - WaitForSingleObject(info->mutex, INFINITE); - height = info->height; - ReleaseMutex(info->mutex); + WaitForSingleObject(wfi->mutex, INFINITE); + height = wfi->height; + ReleaseMutex(wfi->mutex); return height; } -int wf_info_get_width(wfInfo* info) +int wf_info_get_width(wfInfo* wfi) { int width; - WaitForSingleObject(info->mutex, INFINITE); - width = info->width; - ReleaseMutex(info->mutex); + WaitForSingleObject(wfi->mutex, INFINITE); + width = wfi->width; + ReleaseMutex(wfi->mutex); return width; } -int wf_info_get_thread_count(wfInfo* info) +int wf_info_get_thread_count(wfInfo* wfi) { int count; - WaitForSingleObject(info->mutex, INFINITE); - count = info->threadCnt; - ReleaseMutex(info->mutex); + WaitForSingleObject(wfi->mutex, INFINITE); + count = wfi->threadCnt; + ReleaseMutex(wfi->mutex); return count; } -void wf_info_set_thread_count(wfInfo* info, int count) +void wf_info_set_thread_count(wfInfo* wfi, int count) { - WaitForSingleObject(info->mutex, INFINITE); - info->threadCnt = count; - ReleaseMutex(info->mutex); + WaitForSingleObject(wfi->mutex, INFINITE); + wfi->threadCnt = count; + ReleaseMutex(wfi->mutex); } diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index 58edf7da0..8b8c83ce5 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -20,8 +20,6 @@ #ifndef WF_INFO_H #define WF_INFO_H -//#include "wfreerdp.h" - struct wf_peer_context; typedef struct wf_peer_context wfPeerContext; @@ -53,24 +51,22 @@ struct wf_info }; typedef struct wf_info wfInfo; -wfInfo* wf_info_init(wfInfo* info); -void wf_info_mirror_init(wfInfo* info, wfPeerContext* context); -void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context); +wfInfo* wf_info_init(wfInfo* wfi); +void wf_info_mirror_init(wfInfo* wfi, wfPeerContext* context); +void wf_info_subscriber_release(wfInfo* wfi, wfPeerContext* context); -int wf_info_get_thread_count(wfInfo* info); -void wf_info_set_thread_count(wfInfo* info, int count); +int wf_info_get_thread_count(wfInfo* wfi); +void wf_info_set_thread_count(wfInfo* wfi, int count); -BOOL wf_info_has_subscribers(wfInfo* info); -BOOL wf_info_have_updates(wfInfo* info); -void wf_info_updated(wfInfo* info); -void wf_info_update_changes(wfInfo* info); -void wf_info_find_invalid_region(wfInfo* info); -void wf_info_clear_invalid_region(wfInfo* info); -BOOL wf_info_have_invalid_region(wfInfo* info); +BOOL wf_info_has_subscribers(wfInfo* wfi); +BOOL wf_info_have_updates(wfInfo* wfi); +void wf_info_updated(wfInfo* wfi); +void wf_info_update_changes(wfInfo* wfi); +void wf_info_find_invalid_region(wfInfo* wfi); +void wf_info_clear_invalid_region(wfInfo* wfi); +BOOL wf_info_have_invalid_region(wfInfo* wfi); -int wf_info_get_height(wfInfo* info); -int wf_info_get_width(wfInfo* info); +int wf_info_get_height(wfInfo* wfi); +int wf_info_get_width(wfInfo* wfi); - - -#endif \ No newline at end of file +#endif diff --git a/server/Windows/wf_mirage.c b/server/Windows/wf_mirage.c index 4ca8e42c8..a77a68382 100644 --- a/server/Windows/wf_mirage.c +++ b/server/Windows/wf_mirage.c @@ -75,15 +75,16 @@ BOOL wf_check_disp_devices(wfInfo* context) return false; } -/* -This function will attempt to access the the windows registry using the device - key stored in the current context. It will attempt to read the value of the - "Attach.ToDesktop" subkey and will return true if the value is already set to - val. If unable to read the subkey, this function will return false. If the - subkey is not set to val it will then attempt to set it to val and return true. If - unsuccessful or an unexpected value is encountered, the function returns - false. +/** + * This function will attempt to access the the windows registry using the device + * key stored in the current context. It will attempt to read the value of the + * "Attach.ToDesktop" subkey and will return true if the value is already set to + * val. If unable to read the subkey, this function will return false. If the + * subkey is not set to val it will then attempt to set it to val and return true. If + * unsuccessful or an unexpected value is encountered, the function returns + * false. */ + BOOL wf_disp_device_set_attatch(wfInfo* context, DWORD val) { LONG status; @@ -136,13 +137,13 @@ BOOL wf_disp_device_set_attatch(wfInfo* context, DWORD val) return true; } -/* -This function will attempt to apply the currently configured display settings -in the registry to the display driver. It will return true if successful -otherwise it returns false. +/** + * This function will attempt to apply the currently configured display settings + * in the registry to the display driver. It will return true if successful + * otherwise it returns false. + * If unload is nonzero then the the driver will be asked to remove itself. + */ -If unload is nonzero then the the driver will be asked to remove it self. -*/ BOOL wf_update_mirror_drv(wfInfo* context, int unload) { HDC dc; @@ -249,7 +250,6 @@ BOOL wf_update_mirror_drv(wfInfo* context, int unload) return status; } - BOOL wf_map_mirror_mem(wfInfo* context) { int status; @@ -265,7 +265,7 @@ BOOL wf_map_mirror_mem(wfInfo* context) } context->changeBuffer = malloc(sizeof(GETCHANGESBUF)); - memset(context->changeBuffer, 0, sizeof(GETCHANGESBUF)); + ZeroMemory(context->changeBuffer, sizeof(GETCHANGESBUF)); _tprintf(_T("\n\nConnecting to driver...\n")); status = ExtEscape(context->driverDC, dmf_esc_usm_pipe_map, 0, 0, sizeof(GETCHANGESBUF), (LPSTR) context->changeBuffer); @@ -275,22 +275,21 @@ BOOL wf_map_mirror_mem(wfInfo* context) _tprintf(_T("Failed to map shared memory from the driver! Code %d\n"), status); } - b = (GETCHANGESBUF*)context->changeBuffer; + b = (GETCHANGESBUF*) context->changeBuffer; _tprintf(_T("ExtEscape() returned code %d\n"), status); return TRUE; } -/* -Unmap the shared memory and release the DC -*/ +/* Unmap the shared memory and release the DC */ + BOOL wf_mirror_cleanup(wfInfo* context) { int iResult; _tprintf(_T("\n\nCleaning up...\nDisconnecting driver...\n")); - iResult = ExtEscape(context->driverDC, dmf_esc_usm_pipe_unmap, sizeof(context->changeBuffer), (LPSTR) context->changeBuffer, 0, 0); - + iResult = ExtEscape(context->driverDC, dmf_esc_usm_pipe_unmap, sizeof(GETCHANGESBUF), (LPSTR) context->changeBuffer, 0, 0); + if (iResult <= 0) { _tprintf(_T("Failed to unmap shared memory from the driver! Code %d\n"), iResult); @@ -301,7 +300,8 @@ BOOL wf_mirror_cleanup(wfInfo* context) if (context->driverDC != NULL) { iResult = DeleteDC(context->driverDC); - if(iResult == 0) + + if (iResult == 0) { _tprintf(_T("Failed to release DC!\n")); } diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 958f3563e..9756e0b23 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -46,21 +46,18 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) { - DWORD start; - DWORD end; - DWORD diff; - DWORD rate; + DWORD beg, end; + DWORD diff, rate; freerdp_peer* client; rate = 42; - client = (freerdp_peer*)lpParam; + client = (freerdp_peer*) lpParam; /* TODO: do not encode when no clients are connected */ - while(1) + while (1) { - - start = GetTickCount(); + beg = GetTickCount(); if (wf_info_has_subscribers(wfInfoSingleton)) { @@ -69,17 +66,16 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) if (wf_info_have_updates(wfInfoSingleton)) { wf_rfx_encode(client); - } + } } end = GetTickCount(); - diff = end - start; + diff = end - beg; if (diff < rate) { Sleep(rate - diff); } - } _tprintf(_T("monitor thread terminating...\n")); @@ -90,20 +86,21 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) void wf_rfx_encode(freerdp_peer* client) { + int dRes; STREAM* s; wfInfo* wfi; + long offset; RFX_RECT rect; + long height, width; rdpUpdate* update; wfPeerContext* wfp; - SURFACE_BITS_COMMAND* cmd; GETCHANGESBUF* buf; - long height, width; - long offset; - int dRes; + SURFACE_BITS_COMMAND* cmd; wfp = (wfPeerContext*) client->context; dRes = WaitForSingleObject(wfInfoSingleton->encodeMutex, INFINITE); + switch(dRes) { case WAIT_OBJECT_0: diff --git a/server/Windows/wf_peer.h b/server/Windows/wf_peer.h index a9590038e..833126f65 100644 --- a/server/Windows/wf_peer.h +++ b/server/Windows/wf_peer.h @@ -29,7 +29,6 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context); void wf_peer_init(freerdp_peer* client); void wf_rfx_encode(freerdp_peer* client); -//void wf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int height); boolean wf_peer_post_connect(freerdp_peer* client); boolean wf_peer_activate(freerdp_peer* client); @@ -38,6 +37,6 @@ void wf_peer_synchronize_event(rdpInput* input, uint32 flags); void wf_peer_send_changes(rdpUpdate* update); -wfInfo * wfInfoSingleton; +wfInfo* wfInfoSingleton; #endif /* WF_PEER_H */ From c6d2d4d6eca37c607df43a58125ec393fd28ebf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 23 Aug 2012 17:37:28 -0400 Subject: [PATCH 4/7] wfreerdp-server: fix off-by-one width and height errors --- server/Windows/wf_peer.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 9756e0b23..281b4c6a4 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -46,11 +46,13 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) { + DWORD fps; DWORD beg, end; DWORD diff, rate; freerdp_peer* client; - rate = 42; + fps = 30; + rate = 1000 / fps; client = (freerdp_peer*) lpParam; /* TODO: do not encode when no clients are connected */ @@ -79,7 +81,7 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) } _tprintf(_T("monitor thread terminating...\n")); - wf_info_set_thread_count(wfInfoSingleton, wf_info_get_thread_count(wfInfoSingleton) - 1 ); + wf_info_set_thread_count(wfInfoSingleton, wf_info_get_thread_count(wfInfoSingleton) - 1); return 0; } @@ -101,7 +103,7 @@ void wf_rfx_encode(freerdp_peer* client) dRes = WaitForSingleObject(wfInfoSingleton->encodeMutex, INFINITE); - switch(dRes) + switch (dRes) { case WAIT_OBJECT_0: @@ -119,10 +121,10 @@ void wf_rfx_encode(freerdp_peer* client) update = client->update; cmd = &update->surface_bits_command; wfi = wfp->wfInfo; - buf = (GETCHANGESBUF*)wfi->changeBuffer; + buf = (GETCHANGESBUF*) wfi->changeBuffer; - width = wfi->invalid_x2 - wfi->invalid_x1; - height = wfi->invalid_y2 - wfi->invalid_y1; + width = (wfi->invalid_x2 - wfi->invalid_x1) + 1; + height = (wfi->invalid_y2 - wfi->invalid_y1) + 1; stream_clear(wfp->s); stream_set_pos(wfp->s, 0); @@ -133,6 +135,9 @@ void wf_rfx_encode(freerdp_peer* client) rect.width = (uint16) width; rect.height = (uint16) height; + //printf("Encoding: left:%d top:%d right:%d bottom:%d width:%d height:%d\n", + // wfi->invalid_x1, wfi->invalid_y1, wfi->invalid_x2, wfi->invalid_y2, width, height); + offset = (4 * wfi->invalid_x1) + (wfi->invalid_y1 * wfi->width * 4); rfx_compose_message(wfp->rfx_context, s, &rect, 1, From 49e97852b4ed570eafbdec1b0b63844bacbcb26e Mon Sep 17 00:00:00 2001 From: C-o-r-E Date: Fri, 24 Aug 2012 19:39:30 -0400 Subject: [PATCH 5/7] wfreerdp-server: fixed subsequent connection issue --- server/Windows/wf_peer.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 281b4c6a4..911b31301 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -56,8 +56,8 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) client = (freerdp_peer*) lpParam; /* TODO: do not encode when no clients are connected */ - - while (1) + /* TODO: refactor this */ + while (wf_info_has_subscribers(wfInfoSingleton)) { beg = GetTickCount(); @@ -79,6 +79,7 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) Sleep(rate - diff); } } + _tprintf(_T("monitor thread terminating...\n")); wf_info_set_thread_count(wfInfoSingleton, wf_info_get_thread_count(wfInfoSingleton) - 1); @@ -98,13 +99,19 @@ void wf_rfx_encode(freerdp_peer* client) wfPeerContext* wfp; GETCHANGESBUF* buf; SURFACE_BITS_COMMAND* cmd; - + wfp = (wfPeerContext*) client->context; dRes = WaitForSingleObject(wfInfoSingleton->encodeMutex, INFINITE); switch (dRes) { + + case WAIT_ABANDONED: + + printf("\n\nwf_rfx_encode: Got ownership of abandoned mutex... resuming...\n"); + //no break + case WAIT_OBJECT_0: wf_info_find_invalid_region(wfInfoSingleton); @@ -164,12 +171,6 @@ void wf_rfx_encode(freerdp_peer* client) ReleaseMutex(wfInfoSingleton->encodeMutex); break; - case WAIT_ABANDONED: - - printf("\n\nwf_rfx_encode: Got ownership of abandoned mutex... releasing...\n", dRes); - ReleaseMutex(wfInfoSingleton->encodeMutex); - break; - default: printf("\n\nwf_rfx_encode: Something else happened!!! dRes = %d\n", dRes); break; @@ -257,6 +258,11 @@ void wf_peer_send_changes(rdpUpdate* update) switch(dRes) { + case WAIT_ABANDONED: + + printf("\n\nwf_peer_send_changes: Got ownership of abandoned mutex... resuming...\n"); + //no break; + case WAIT_OBJECT_0: /* are there changes to send? */ From fdfc5f8f1cad5e24750869e3988256ea790e591c Mon Sep 17 00:00:00 2001 From: C-o-r-E Date: Tue, 28 Aug 2012 19:28:04 -0400 Subject: [PATCH 6/7] wfreerdp-server: added optional back buffer --- server/Windows/wf_info.c | 43 ++++++++++++++++++++++++++++++++++++++++ server/Windows/wf_info.h | 5 +++++ server/Windows/wf_peer.c | 42 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 7fe6f10f8..ac45b6f54 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -29,6 +29,45 @@ #include "wf_info.h" #include "wf_mirage.h" +extern wfInfo * wfInfoSingleton; + +int wf_info_lock() +{ + DWORD dRes; + + dRes = WaitForSingleObject(wfInfoSingleton->mutex, INFINITE); + + switch(dRes) + { + case WAIT_ABANDONED: + //complain and proceed as normal + printf("Got ownership of abandoned mutex... resuming...\n"); + + case WAIT_OBJECT_0: + break; + + case WAIT_TIMEOUT: + return 1; + break; + case WAIT_FAILED: + printf("WAIT FAILED code %#X\n", GetLastError()); + return -1; + break; + } + + return 0; +} + + + +int wf_info_unlock() +{ + if(ReleaseMutex(wfInfoSingleton->mutex) == 0) + return 0; + return 1; +} + + wfInfo* wf_info_init(wfInfo * wfi) { if (!wfi) @@ -89,6 +128,8 @@ void wf_info_mirror_init(wfInfo* wfi, wfPeerContext* context) rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); context->s = stream_new(65536); + context->wfInfo->roflbuffer = (BYTE*)malloc( (context->wfInfo->width) * (context->wfInfo->height) * 4); + printf("Start Encoder\n"); ReleaseMutex(wfi->encodeMutex); } @@ -137,6 +178,8 @@ void wf_info_subscriber_release(wfInfo* wfi, wfPeerContext* context) stream_free(context->s); rfx_context_free(context->rfx_context); + free(context->wfInfo->roflbuffer); + printf("Stop encoder\n"); break; diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index 8b8c83ce5..abc21c9d2 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -48,9 +48,14 @@ struct wf_info long invalid_y2; BOOL enc_data; + + BYTE* roflbuffer; }; typedef struct wf_info wfInfo; +int wf_info_lock(); +int wf_info_unlock(); + wfInfo* wf_info_init(wfInfo* wfi); void wf_info_mirror_init(wfInfo* wfi, wfPeerContext* context); void wf_info_subscriber_release(wfInfo* wfi, wfPeerContext* context); diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 911b31301..39b6fde1a 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -51,7 +51,7 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) DWORD diff, rate; freerdp_peer* client; - fps = 30; + fps = 24; rate = 1000 / fps; client = (freerdp_peer*) lpParam; @@ -100,6 +100,13 @@ void wf_rfx_encode(freerdp_peer* client) GETCHANGESBUF* buf; SURFACE_BITS_COMMAND* cmd; +#ifdef ROFLBUFFER + uint16 i; + int delta; + int scanline; + BYTE* srcp; + BYTE* dstp; +#endif wfp = (wfPeerContext*) client->context; dRes = WaitForSingleObject(wfInfoSingleton->encodeMutex, INFINITE); @@ -145,10 +152,43 @@ void wf_rfx_encode(freerdp_peer* client) //printf("Encoding: left:%d top:%d right:%d bottom:%d width:%d height:%d\n", // wfi->invalid_x1, wfi->invalid_y1, wfi->invalid_x2, wfi->invalid_y2, width, height); + +#ifndef ROFLBUFFER offset = (4 * wfi->invalid_x1) + (wfi->invalid_y1 * wfi->width * 4); + rfx_compose_message(wfp->rfx_context, s, &rect, 1, ((uint8*) (buf->Userbuffer)) + offset, width, height, wfi->width * 4); +#else + + //memcpy(wfi->roflbuffer, ((uint8*) (buf->Userbuffer)) + offset, 4 * width * height); + + //to copy the region we must copy HxWxB bytes per line and skip 4*(screen_w - x2) + + + /*delta = 0; + for(i = 0; i < height; ++i) + { + memcpy(wfi->roflbuffer + offset + delta, ((uint8*) (buf->Userbuffer)) + offset + delta, 4 * width); + delta += (4 * width) + (4 * (wfi->width - wfi->invalid_x2) + (4 * wfi->invalid_x1)); + }*/ + + scanline = (wfi->width * 4); + offset = (wfi->invalid_y1 * scanline) + (wfi->invalid_x1 * 4); + srcp = (BYTE*) buf->Userbuffer + offset; + dstp = (BYTE*) wfi->roflbuffer + offset; + Sleep(100); + for (i = 0; i < height; i++) + { + memcpy(dstp, srcp, width * 4); + dstp += scanline; + srcp += scanline; + } + + rfx_compose_message(wfp->rfx_context, s, &rect, 1, + wfi->roflbuffer + offset, width, height, wfi->width * 4); + +#endif cmd->destLeft = wfi->invalid_x1; cmd->destTop = wfi->invalid_y1; From 88ad2661bd2e0322c405f033065b7931cb8d441f Mon Sep 17 00:00:00 2001 From: C-o-r-E Date: Thu, 30 Aug 2012 15:50:46 -0400 Subject: [PATCH 7/7] wfreerdp-server: cleaned up synchronization code --- server/Windows/wf_info.c | 28 ++++------------------------ server/Windows/wf_info.h | 2 +- server/Windows/wf_peer.c | 25 ++++++++++++++++++++----- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index ac45b6f54..9e783962d 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -31,11 +31,11 @@ extern wfInfo * wfInfoSingleton; -int wf_info_lock() +int wf_info_lock(DWORD ms) { DWORD dRes; - dRes = WaitForSingleObject(wfInfoSingleton->mutex, INFINITE); + dRes = WaitForSingleObject(wfInfoSingleton->mutex, ms); switch(dRes) { @@ -207,13 +207,6 @@ void wf_info_subscriber_release(wfInfo* wfi, wfPeerContext* context) BOOL wf_info_has_subscribers(wfInfo* wfi) { - int subs; - - WaitForSingleObject(wfi->mutex, INFINITE); - - subs = wfi->subscribers; - ReleaseMutex(wfi->mutex); - if (wfi->subscribers > 0) return TRUE; @@ -223,37 +216,26 @@ BOOL wf_info_has_subscribers(wfInfo* wfi) BOOL wf_info_have_updates(wfInfo* wfi) { - BOOL status = TRUE; - - WaitForSingleObject(wfi->mutex, INFINITE); - if (wfi->nextUpdate == wfi->lastUpdate) - status = FALSE; - - ReleaseMutex(wfi->mutex); + return FALSE; - return status; + return TRUE; } void wf_info_updated(wfInfo* wfi) { - WaitForSingleObject(wfi->mutex, INFINITE); wfi->lastUpdate = wfi->nextUpdate; - ReleaseMutex(wfi->mutex); } void wf_info_update_changes(wfInfo* wfi) { GETCHANGESBUF* buf; - WaitForSingleObject(wfi->mutex, INFINITE); - buf = (GETCHANGESBUF*) wfi->changeBuffer; wfi->nextUpdate = buf->buffer->counter; - ReleaseMutex(wfi->mutex); } void wf_info_find_invalid_region(wfInfo* wfi) @@ -261,7 +243,6 @@ void wf_info_find_invalid_region(wfInfo* wfi) int i; GETCHANGESBUF* buf; - WaitForSingleObject(wfi->mutex, INFINITE); buf = (GETCHANGESBUF*) wfi->changeBuffer; if (wfi->enc_data == FALSE) @@ -292,7 +273,6 @@ void wf_info_find_invalid_region(wfInfo* wfi) if (wfi->invalid_y2 >= wfi->height) wfi->invalid_y2 = wfi->height - 1; - ReleaseMutex(wfi->mutex); } void wf_info_clear_invalid_region(wfInfo* wfi) diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index abc21c9d2..2116ce29d 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -53,7 +53,7 @@ struct wf_info }; typedef struct wf_info wfInfo; -int wf_info_lock(); +int wf_info_lock(DWORD ms); int wf_info_unlock(); wfInfo* wf_info_init(wfInfo* wfi); diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 39b6fde1a..0595e727a 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -35,6 +35,7 @@ void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context) { + wfInfoSingleton = wf_info_init(wfInfoSingleton); wf_info_mirror_init(wfInfoSingleton, context); } @@ -55,21 +56,27 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) rate = 1000 / fps; client = (freerdp_peer*) lpParam; - /* TODO: do not encode when no clients are connected */ - /* TODO: refactor this */ - while (wf_info_has_subscribers(wfInfoSingleton)) + while (1) { beg = GetTickCount(); + wf_info_lock(INFINITE); + if (wf_info_has_subscribers(wfInfoSingleton)) { - wf_info_update_changes(wfInfoSingleton); + wf_info_update_changes(wfInfoSingleton); if (wf_info_have_updates(wfInfoSingleton)) { wf_rfx_encode(client); } } + else + { + wf_info_unlock(); + } + + wf_info_unlock(); end = GetTickCount(); diff = end - beg; @@ -107,6 +114,9 @@ void wf_rfx_encode(freerdp_peer* client) BYTE* srcp; BYTE* dstp; #endif + + if(client->activated == FALSE) + return; wfp = (wfPeerContext*) client->context; dRes = WaitForSingleObject(wfInfoSingleton->encodeMutex, INFINITE); @@ -306,10 +316,14 @@ void wf_peer_send_changes(rdpUpdate* update) case WAIT_OBJECT_0: /* are there changes to send? */ - if (!wf_info_have_updates(wfInfoSingleton) || + + if ( ((wf_info_lock(0) != 0)) || + !wf_info_have_updates(wfInfoSingleton) || !wf_info_have_invalid_region(wfInfoSingleton) || (wfInfoSingleton->enc_data == FALSE)) { + //we dont send + wf_info_unlock(); ReleaseMutex(wfInfoSingleton->encodeMutex); break; } @@ -319,6 +333,7 @@ void wf_peer_send_changes(rdpUpdate* update) update->SurfaceBits(update->context, &update->surface_bits_command); wfInfoSingleton->enc_data = FALSE; + wf_info_unlock(); ReleaseMutex(wfInfoSingleton->encodeMutex); break;