diff --git a/libfreerdp/crypto/nla.c b/libfreerdp/crypto/nla.c index 169f5ac11..db53765ef 100644 --- a/libfreerdp/crypto/nla.c +++ b/libfreerdp/crypto/nla.c @@ -381,7 +381,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; @@ -452,6 +451,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)); /* @@ -495,9 +496,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) { @@ -517,15 +517,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)) { @@ -554,7 +547,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; @@ -575,7 +568,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; @@ -1307,6 +1300,6 @@ void credssp_free(rdpCredssp* credssp) free(credssp->identity.User); free(credssp->identity.Domain); free(credssp->identity.Password); - free(credssp); + //free(credssp); } } diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 1289f82d9..c4bf73b9f 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -17,70 +17,104 @@ * limitations under the License. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include + #include #include #include "wf_info.h" #include "wf_mirage.h" -wfInfo * wf_info_init(wfInfo * info) +extern wfInfo * wfInfoSingleton; + +int wf_info_lock(DWORD ms) { - if(!info) + DWORD dRes; + + dRes = WaitForSingleObject(wfInfoSingleton->mutex, ms); + + switch(dRes) { - info = (wfInfo*)malloc(sizeof(wfInfo)); //free this on shutdown - memset(info, 0, sizeof(wfInfo)); + case WAIT_ABANDONED: + //complain and proceed as normal + printf("Got ownership of abandoned mutex... resuming...\n"); - info->mutex = CreateMutex( - NULL, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex + case WAIT_OBJECT_0: + break; - if (info->mutex == NULL) + 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) + { + wfi = (wfInfo*) malloc(sizeof(wfInfo)); + ZeroMemory(wfi, sizeof(wfInfo)); + + wfi->mutex = CreateMutex(NULL, FALSE, NULL); + + if (wfi->mutex == NULL) { _tprintf(_T("CreateMutex error: %d\n"), GetLastError()); } - info->encodeMutex = CreateMutex( - NULL, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex + 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, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex + 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, // handle to mutex - INFINITE); // no time-out interval + 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; + /* only the first peer needs to call this. */ + + context->wfInfo = wfi; wf_check_disp_devices(context->wfInfo); wf_disp_device_set_attatch(context->wfInfo, 1); wf_update_mirror_drv(context->wfInfo, 0); @@ -94,42 +128,49 @@ void wf_info_mirror_init(wfInfo * info, wfPeerContext* context) rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); context->s = stream_new(65536); - printf("Start Encoder\n"); - ReleaseMutex(info->encodeMutex); - } - ++info->subscribers; + context->wfInfo->roflbuffer = (BYTE*)malloc( (context->wfInfo->width) * (context->wfInfo->height) * 4); - if (! ReleaseMutex(info->mutex)) - { - _tprintf(_T("Error releasing mutex\n")); - } + printf("Start Encoder\n"); + ReleaseMutex(wfi->encodeMutex); + } + ++wfi->subscribers; + + if (!ReleaseMutex(wfi->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 -void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context) +/** + * 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* 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); - switch (dRes) - { - // The thread got ownership of the mutex - case WAIT_OBJECT_0: - --info->subscribers; - //only the last peer needs to call this + dRes = WaitForSingleObject(wfi->encodeMutex, INFINITE); + + switch (dRes) + { + /* The thread got ownership of the mutex */ + + case WAIT_OBJECT_0: + --wfi->subscribers; + /* 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); @@ -137,166 +178,137 @@ void wf_info_subscriber_release(wfInfo* info, wfPeerContext* context) stream_free(context->s); rfx_context_free(context->rfx_context); - printf("Stop encoder\n"); - break; + free(context->wfInfo->roflbuffer); + 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; + --wfi->subscribers; } - ReleaseMutex(info->mutex); + ReleaseMutex(wfi->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* wfi) +{ + if (wfi->subscribers > 0) + return TRUE; + + return FALSE; +} + + +BOOL wf_info_have_updates(wfInfo* wfi) +{ + if (wfi->nextUpdate == wfi->lastUpdate) + return FALSE; + + return TRUE; +} + +void wf_info_updated(wfInfo* wfi) +{ + + wfi->lastUpdate = wfi->nextUpdate; } - -BOOL wf_info_has_subscribers(wfInfo* info) -{ - int subs; - - WaitForSingleObject(info->mutex, INFINITE); - subs = info->subscribers; - ReleaseMutex(info->mutex); - - if(info->subscribers > 0) - return true; - return false; -} - - -BOOL wf_info_have_updates(wfInfo* info) -{ - BOOL ret; - ret = true; - WaitForSingleObject(info->mutex, INFINITE); - if(info->nextUpdate == info->lastUpdate) - ret = false; - ReleaseMutex(info->mutex); - - return ret; -} - - -void wf_info_updated(wfInfo* info) -{ - - WaitForSingleObject(info->mutex, INFINITE); - info->lastUpdate = info->nextUpdate; - ReleaseMutex(info->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); + buf = (GETCHANGESBUF*) wfi->changeBuffer; + wfi->nextUpdate = buf->buffer->counter; + } - -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; + buf = (GETCHANGESBUF*) wfi->changeBuffer; - if(info->enc_data == false) + if (wfi->enc_data == FALSE) { - info->invalid_x1 = 1920;//info->width; - info->invalid_x2 = 0; - info->invalid_y1 = 1200;// info->height; - info->invalid_y2 = 0; + wfi->invalid_x1 = wfi->width - 1; + wfi->invalid_x2 = 0; + wfi->invalid_y1 = wfi->height - 1; + wfi->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 = wfi->lastUpdate; i != wfi->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); + 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; + } - -void wf_info_clear_invalid_region(wfInfo* info) +void wf_info_clear_invalid_region(wfInfo* wfi) { + WaitForSingleObject(wfi->mutex, INFINITE); + + wfi->lastUpdate = wfi->nextUpdate; - 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); + 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)) - return false; - return true; + 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_thread_count(wfInfo* wfi) { - int ret; - - WaitForSingleObject(info->mutex, INFINITE); - ret = info->height; - ReleaseMutex(info->mutex); - - return ret; + int count; + + WaitForSingleObject(wfi->mutex, INFINITE); + count = wfi->threadCnt; + ReleaseMutex(wfi->mutex); + + return count; } -int wf_info_get_width(wfInfo* info) +void wf_info_set_thread_count(wfInfo* wfi, int count) { - int ret; - - WaitForSingleObject(info->mutex, INFINITE); - ret = info->width; - ReleaseMutex(info->mutex); - - return ret; -} - -int wf_info_get_thread_count(wfInfo* info) -{ - int ret; - WaitForSingleObject(info->mutex, INFINITE); - ret = info->threadCnt; - ReleaseMutex(info->mutex); - return ret; -} - - -void wf_info_set_thread_count(wfInfo* info, 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..92201e75c 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; @@ -50,27 +48,27 @@ struct wf_info long invalid_y2; BOOL enc_data; + + BYTE* roflbuffer; }; 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); +int wf_info_lock(DWORD ms); +int wf_info_unlock(); -int wf_info_get_thread_count(wfInfo* info); -void wf_info_set_thread_count(wfInfo* info, int count); +wfInfo* wf_info_init(wfInfo* wfi); +void wf_info_mirror_init(wfInfo* wfi, wfPeerContext* context); +void wf_info_subscriber_release(wfInfo* wfi, wfPeerContext* context); -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); +int wf_info_get_thread_count(wfInfo* wfi); +void wf_info_set_thread_count(wfInfo* wfi, int count); -int wf_info_get_height(wfInfo* info); -int wf_info_get_width(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); - - -#endif \ No newline at end of file +#endif diff --git a/server/Windows/wf_mirage.c b/server/Windows/wf_mirage.c index 6076231c2..8c0c6f4d6 100644 --- a/server/Windows/wf_mirage.c +++ b/server/Windows/wf_mirage.c @@ -31,27 +31,22 @@ the function returns false. */ BOOL wf_check_disp_devices(wfInfo* context) { - BOOL result, devFound; + BOOL result; + BOOL devFound; DWORD deviceNumber; DISPLAY_DEVICE deviceInfo; - devFound = false; + devFound = FALSE; deviceNumber = 0; deviceInfo.cb = sizeof(deviceInfo); - printf("Detecting display devices:\n"); - while (result = EnumDisplayDevices(NULL, deviceNumber, &deviceInfo, 0)) { - _tprintf(_T("\t%s\n"), deviceInfo.DeviceString); - if (_tcscmp(deviceInfo.DeviceString, _T("Mirage Driver")) == 0) { int deviceKeyLength; int deviceKeyPrefixLength; - _tprintf(_T("\n\nFound our target of interest!\n")); - deviceKeyPrefixLength = _tcslen(DEVICE_KEY_PREFIX); if (_tcsncmp(deviceInfo.DeviceKey, DEVICE_KEY_PREFIX, deviceKeyPrefixLength) == 0) @@ -61,28 +56,26 @@ BOOL wf_check_disp_devices(wfInfo* context) _tcsncpy_s(context->deviceKey, deviceKeyLength + 1, &deviceInfo.DeviceKey[deviceKeyPrefixLength], deviceKeyLength); - - _tprintf(_T("DeviceKey: %s\n"), context->deviceKey); } _tcsncpy_s(context->deviceName, 32, deviceInfo.DeviceName, _tcslen(deviceInfo.DeviceName)); - return true; + return TRUE; } deviceNumber++; } - return false; + 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) @@ -121,31 +114,80 @@ 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. +void wf_disp_change_print_status(LONG status) +{ + TCHAR disp_change[64]; + + switch (status) + { + case DISP_CHANGE_SUCCESSFUL: + _tcscpy(disp_change, _T("DISP_CHANGE_SUCCESSFUL")); + break; + + case DISP_CHANGE_BADDUALVIEW: + _tcscpy(disp_change, _T("DISP_CHANGE_BADDUALVIEW")); + break; + + case DISP_CHANGE_BADFLAGS: + _tcscpy(disp_change, _T("DISP_CHANGE_BADFLAGS")); + break; + + case DISP_CHANGE_BADMODE: + _tcscpy(disp_change, _T("DISP_CHANGE_BADMODE")); + break; + + case DISP_CHANGE_BADPARAM: + _tcscpy(disp_change, _T("DISP_CHANGE_BADPARAM")); + break; + + case DISP_CHANGE_FAILED: + _tcscpy(disp_change, _T("DISP_CHANGE_FAILED")); + break; + + case DISP_CHANGE_NOTUPDATED: + _tcscpy(disp_change, _T("DISP_CHANGE_NOTUPDATED")); + break; + + case DISP_CHANGE_RESTART: + _tcscpy(disp_change, _T("DISP_CHANGE_RESTART")); + break; + + default: + _tcscpy(disp_change, _T("DISP_CHANGE_UNKNOWN")); + break; + } + + if (status != DISP_CHANGE_SUCCESSFUL) + _tprintf(_T("ChangeDisplaySettingsEx() failed with %s (%d)\n"), disp_change, status); + else + _tprintf(_T("ChangeDisplaySettingsEx() succeeded with %s (%d)\n"), disp_change, status); +} + +/** + * 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) { - int currentScreenPixHeight, currentScreenPixWidth, currentScreenBPP; HDC dc; - LONG status; + BOOL status; DWORD* extHdr; 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); @@ -187,52 +229,16 @@ 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) - { - case DISP_CHANGE_SUCCESSFUL: - _tprintf(_T("ChangeDisplaySettingsEx() was successfull\n")); - rturn = true; - break; + status = (disp_change_status == DISP_CHANGE_SUCCESSFUL) ? TRUE : FALSE; - case DISP_CHANGE_BADDUALVIEW: - _tcscpy(rMsg, _T("DISP_CHANGE_BADDUALVIEW")); - break; - - case DISP_CHANGE_BADFLAGS: - _tcscpy(rMsg, _T("DISP_CHANGE_BADFLAGS")); - break; - - case DISP_CHANGE_BADMODE: - _tcscpy(rMsg, _T("DISP_CHANGE_BADMODE")); - break; - - case DISP_CHANGE_BADPARAM: - _tcscpy(rMsg, _T("DISP_CHANGE_BADPARAM")); - break; - - case DISP_CHANGE_FAILED: - _tcscpy(rMsg, _T("DISP_CHANGE_FAILED")); - break; - - case DISP_CHANGE_NOTUPDATED: - _tcscpy(rMsg, _T("DISP_CHANGE_NOTUPDATED")); - break; - - case DISP_CHANGE_RESTART: - _tcscpy(rMsg, _T("DISP_CHANGE_RESTART")); - break; - } - - if(!rturn) - _tprintf(_T("ChangeDisplaySettingsEx() failed with %s, code %d\n"), rMsg, status); + if (!status) + wf_disp_change_print_status(disp_change_status); - return rturn; + return status; } - BOOL wf_map_mirror_mem(wfInfo* context) { int status; @@ -244,46 +250,42 @@ 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)); - 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); if (status <= 0) { - _tprintf(_T("Failed to map shared memory from the driver! Code %d\n"), status); + _tprintf(_T("Failed to map shared memory from the driver! code %d\n"), status); } - b = (GETCHANGESBUF*)context->changeBuffer; - _tprintf(_T("ExtEscape() returned code %d\n"), status); + b = (GETCHANGESBUF*) context->changeBuffer; - return true; + 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; + int status; - _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) + status = ExtEscape(context->driverDC, dmf_esc_usm_pipe_unmap, sizeof(GETCHANGESBUF), (LPSTR) context->changeBuffer, 0, 0); + + if (status <= 0) { - _tprintf(_T("Failed to unmap shared memory from the driver! Code %d\n"), iResult); + _tprintf(_T("Failed to unmap shared memory from the driver! code %d\n"), status); } - _tprintf(_T("Releasing DC\n")); - if(context->driverDC != NULL) + if (context->driverDC != NULL) { - iResult = DeleteDC(context->driverDC); - if(iResult == 0) + status = DeleteDC(context->driverDC); + + if (status == 0) { _tprintf(_T("Failed to release DC!\n")); } @@ -291,5 +293,5 @@ BOOL wf_mirror_cleanup(wfInfo* context) free(context->changeBuffer); - return true; -} \ No newline at end of file + return TRUE; +} diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 7df93f057..52c314e84 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -50,133 +50,183 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam) { - DWORD start, end, diff; - DWORD rate; - + DWORD fps; + DWORD beg, end; + DWORD diff, rate; freerdp_peer* client; - rate = 42; - client = (freerdp_peer*)lpParam; + fps = 24; + rate = 1000 / fps; + client = (freerdp_peer*) lpParam; - //todo: make sure we dont encode after no clients - while(1) + while (1) { + beg = GetTickCount(); - start = GetTickCount(); + wf_info_lock(INFINITE); - - 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); - } + } } + else + { + wf_info_unlock(); + } + + wf_info_unlock(); end = GetTickCount(); - diff = end - start; - if(diff < rate) + diff = end - beg; + + if (diff < rate) { - //printf("sleeping for %d ms...\n", rate - diff); Sleep(rate - diff); } - } + _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; } 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; + +#ifdef ROFLBUFFER + uint16 i; + int delta; + int scanline; + BYTE* srcp; + BYTE* dstp; +#endif + + if(client->activated == FALSE) + return; wfp = (wfPeerContext*) client->context; dRes = WaitForSingleObject(wfInfoSingleton->encodeMutex, INFINITE); - switch(dRes) + + switch (dRes) { - case WAIT_OBJECT_0: - wf_info_find_invalid_region(wfInfoSingleton); + case WAIT_ABANDONED: - if( (wfp->activated == false) || - (wf_info_has_subscribers(wfInfoSingleton) == false) || - !wf_info_have_invalid_region(wfInfoSingleton) || - (wfInfoSingleton->enc_data == true) ) - { + printf("\n\nwf_rfx_encode: Got ownership of abandoned mutex... resuming...\n"); + //no break + + case WAIT_OBJECT_0: + + 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) ) + { + 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) + 1; + height = (wfi->invalid_y2 - wfi->invalid_y1) + 1; + + 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("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; + 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; - - 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); - - //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; } } @@ -191,12 +241,14 @@ void wf_peer_init(freerdp_peer* client) #ifndef WITH_WIN8 if (!wf_info_get_thread_count(wfInfoSingleton)) { - _tprintf(_T("Trying to create a monitor thread...\n")); - if (CreateThread(NULL, 0, wf_peer_mirror_monitor, client, 0, NULL) != 0) - _tprintf(_T("Created!\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); + } + else + { + _tprintf(_T("failed to create monitor thread\n")); + } } #endif } @@ -228,13 +280,10 @@ boolean wf_peer_post_connect(freerdp_peer* client) printf("Client requested desktop: %dx%dx%d\n", client->settings->width, client->settings->height, client->settings->color_depth); - printf("But we will try resizing to %dx%d\n", - wf_info_get_width(wfInfoSingleton), - wf_info_get_height(wfInfoSingleton) - ); + printf("But we will try resizing to %dx%d\n", wfInfoSingleton->width, wfInfoSingleton->height); - client->settings->width = wf_info_get_width(wfInfoSingleton); - client->settings->height = wf_info_get_height(wfInfoSingleton); + client->settings->width = wfInfoSingleton->width; + client->settings->height = wfInfoSingleton->height; client->update->DesktopResize(client->update->context); @@ -259,40 +308,45 @@ 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_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? */ + + 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; + } + + wf_info_updated(wfInfoSingleton); + + update->SurfaceBits(update->context, &update->surface_bits_command); + + wfInfoSingleton->enc_data = FALSE; + wf_info_unlock(); 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; } - - } 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 */