wfreerdp-server: merge with latest updates

This commit is contained in:
Marc-André Moreau 2012-09-02 14:39:27 -04:00
commit 12859c7eac
6 changed files with 492 additions and 434 deletions

View File

@ -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);
}
}

View File

@ -17,70 +17,104 @@
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <winpr/tchar.h>
#include <winpr/windows.h>
#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);
}

View File

@ -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
#endif

View File

@ -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;
}
return TRUE;
}

View File

@ -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;
}
}

View File

@ -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 */