예제 #1
0
파일: client.c 프로젝트: kdienes/FreeRDP
static UINT VCAPITYPE FreeRDP_VirtualChannelCloseEx(LPVOID pInitHandle, DWORD openHandle)
{
	rdpChannels* channels = NULL;
	CHANNEL_INIT_DATA* pChannelInitData = NULL;
	CHANNEL_OPEN_DATA* pChannelOpenData = NULL;

	if (!pInitHandle)
		return CHANNEL_RC_BAD_INIT_HANDLE;

	pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
	channels = pChannelInitData->channels;

	if (!channels)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	pChannelOpenData = HashTable_GetItemValue(channels->openHandles, (void*)(UINT_PTR) openHandle);

	if (!pChannelOpenData)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	if (pChannelOpenData->flags != 2)
		return CHANNEL_RC_NOT_OPEN;

	pChannelOpenData->flags = 0;
	return CHANNEL_RC_OK;
}
예제 #2
0
파일: client.c 프로젝트: JozLes77/FreeRDP
UINT FreeRDP_VirtualChannelEventPush(DWORD openHandle, wMessage* event)
{
    rdpChannels* channels;
    CHANNEL_OPEN_DATA* pChannelOpenData;

    pChannelOpenData = HashTable_GetItemValue(g_OpenHandles, (void*) (UINT_PTR) openHandle);

    if (!pChannelOpenData)
        return CHANNEL_RC_BAD_CHANNEL_HANDLE;

    channels = pChannelOpenData->channels;

    if (!channels)
        return CHANNEL_RC_BAD_CHANNEL_HANDLE;

    if (!channels->is_connected)
        return CHANNEL_RC_NOT_CONNECTED;

    if (!event)
        return CHANNEL_RC_NULL_DATA;

    if (pChannelOpenData->flags != 2)
        return CHANNEL_RC_NOT_OPEN;

    /**
     * We really intend to use the In queue for events, but we're pushing on both
     * to wake up threads waiting on the out queue. Doing this cleanly would require
     * breaking freerdp_pop_event() a bit too early in this refactoring.
     */

    MessageQueue_Post(channels->MsgPipe->In, (void*) channels, 1, (void*) event, NULL);
    MessageQueue_Post(channels->MsgPipe->Out, (void*) channels, 1, (void*) event, NULL);

    return CHANNEL_RC_OK;
}
예제 #3
0
static UINT VCAPITYPE FreeRDP_VirtualChannelWriteEx(LPVOID pInitHandle, DWORD openHandle,
        LPVOID pData, ULONG dataLength, LPVOID pUserData)
{
	rdpChannels* channels = NULL;
	CHANNEL_INIT_DATA* pChannelInitData = NULL;
	CHANNEL_OPEN_DATA* pChannelOpenData = NULL;
	CHANNEL_OPEN_EVENT* pChannelOpenEvent = NULL;
	wMessage message;

	if (!pInitHandle)
		return CHANNEL_RC_BAD_INIT_HANDLE;

	pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
	channels = pChannelInitData->channels;

	if (!channels)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	pChannelOpenData = HashTable_GetItemValue(channels->openHandles, (void*)(UINT_PTR) openHandle);

	if (!pChannelOpenData)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	if (!channels->connected)
		return CHANNEL_RC_NOT_CONNECTED;

	if (!pData)
		return CHANNEL_RC_NULL_DATA;

	if (!dataLength)
		return CHANNEL_RC_ZERO_LENGTH;

	if (pChannelOpenData->flags != 2)
		return CHANNEL_RC_NOT_OPEN;

	pChannelOpenEvent = (CHANNEL_OPEN_EVENT*) malloc(sizeof(CHANNEL_OPEN_EVENT));

	if (!pChannelOpenEvent)
		return CHANNEL_RC_NO_MEMORY;

	pChannelOpenEvent->Data = pData;
	pChannelOpenEvent->DataLength = dataLength;
	pChannelOpenEvent->UserData = pUserData;
	pChannelOpenEvent->pChannelOpenData = pChannelOpenData;
	message.context = channels;
	message.id = 0;
	message.wParam = pChannelOpenEvent;
	message.lParam = NULL;
	message.Free = channel_queue_message_free;

	if (!MessageQueue_Dispatch(channels->queue, &message))
	{
		channel_queue_message_free(&message);
		return CHANNEL_RC_NO_MEMORY;
	}

	return CHANNEL_RC_OK;
}
예제 #4
0
static void* rdpgfx_get_surface_data(RdpgfxClientContext* context,
                                     UINT16 surfaceId)
{
	ULONG_PTR key;
	void* pData = NULL;
	RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle;
	key = ((ULONG_PTR) surfaceId) + 1;
	pData = HashTable_GetItemValue(gfx->SurfaceTable, (void*) key);
	return pData;
}
예제 #5
0
파일: xf_rail.c 프로젝트: 99455125/FreeRDP
static BOOL xf_rail_window_icon(rdpContext* context,
                                WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
{
	xfContext* xfc = (xfContext*) context;
	xfAppWindow* railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
	                          (void*)(UINT_PTR) orderInfo->windowId);

	if (!railWindow)
		return FALSE;

	return TRUE;
}
예제 #6
0
파일: xf_rail.c 프로젝트: bceverly/FreeRDP
void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
{
	int index;
	int count;
	RECTANGLE_16 updateRect;
	RECTANGLE_16 windowRect;
	ULONG_PTR* pKeys = NULL;
	xfAppWindow* appWindow;
	const RECTANGLE_16* extents;
	REGION16 windowInvalidRegion;

	region16_init(&windowInvalidRegion);

	count = HashTable_GetKeys(xfc->railWindows, &pKeys);

	for (index = 0; index < count; index++)
	{
		appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]);

		if (appWindow)
		{
			windowRect.left = MAX(appWindow->x, 0);
			windowRect.top = MAX(appWindow->y, 0);
			windowRect.right = MAX(appWindow->x + appWindow->width, 0);
			windowRect.bottom = MAX(appWindow->y + appWindow->height, 0);

			region16_clear(&windowInvalidRegion);
			region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect);

			if (!region16_is_empty(&windowInvalidRegion))
			{
				extents = region16_extents(&windowInvalidRegion);

				updateRect.left = extents->left - appWindow->x;
				updateRect.top = extents->top - appWindow->y;
				updateRect.right = extents->right - appWindow->x;
				updateRect.bottom = extents->bottom - appWindow->y;

				if (appWindow)
				{
					xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top,
							updateRect.right - updateRect.left,
							updateRect.bottom - updateRect.top);
				}
			}
		}
	}

	region16_uninit(&windowInvalidRegion);
}
예제 #7
0
static BOOL xf_rail_window_delete(rdpContext* context,
                                  WINDOW_ORDER_INFO* orderInfo)
{
	xfAppWindow* appWindow = NULL;
	xfContext* xfc = (xfContext*) context;
	appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
	            (void*)(UINT_PTR) orderInfo->windowId);

	if (!appWindow)
		return TRUE;

	HashTable_Remove(xfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId);
	xf_DestroyWindow(xfc, appWindow);
	return TRUE;
}
예제 #8
0
static BOOL xf_rail_window_icon(rdpContext* context,
                                WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
{
	BOOL bigIcon;
	xfAppWindow* railWindow;
	xfContext* xfc = (xfContext*) context;
	railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
	             (void*)(UINT_PTR) orderInfo->windowId);

	if (!railWindow)
		return FALSE;

	bigIcon = (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? TRUE : FALSE;
	return TRUE;
}
예제 #9
0
UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle)
{
	CHANNEL_OPEN_DATA* pChannelOpenData;

	pChannelOpenData = HashTable_GetItemValue(g_OpenHandles, (void*) (UINT_PTR) openHandle);

	if (!pChannelOpenData)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	if (pChannelOpenData->flags != 2)
		return CHANNEL_RC_NOT_OPEN;

	pChannelOpenData->flags = 0;

	return CHANNEL_RC_OK;
}
예제 #10
0
UINT VCAPITYPE FreeRDP_VirtualChannelWrite(DWORD openHandle, LPVOID pData, ULONG dataLength, LPVOID pUserData)
{
	rdpChannels* channels;
	CHANNEL_OPEN_DATA* pChannelOpenData;
	CHANNEL_OPEN_EVENT* pChannelOpenEvent;

	pChannelOpenData = HashTable_GetItemValue(g_OpenHandles, (void*) (UINT_PTR) openHandle);

	if (!pChannelOpenData)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	channels = pChannelOpenData->channels;

	if (!channels)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	if (!channels->connected)
		return CHANNEL_RC_NOT_CONNECTED;

	if (!pData)
		return CHANNEL_RC_NULL_DATA;

	if (!dataLength)
		return CHANNEL_RC_ZERO_LENGTH;

	if (pChannelOpenData->flags != 2)
		return CHANNEL_RC_NOT_OPEN;

	pChannelOpenEvent = (CHANNEL_OPEN_EVENT*) malloc(sizeof(CHANNEL_OPEN_EVENT));

	if (!pChannelOpenEvent)
		return CHANNEL_RC_NO_MEMORY;

	pChannelOpenEvent->Data = pData;
	pChannelOpenEvent->DataLength = dataLength;
	pChannelOpenEvent->UserData = pUserData;
	pChannelOpenEvent->pChannelOpenData = pChannelOpenData;

	if (!MessageQueue_Post(channels->queue, (void*) channels, 0, (void*) pChannelOpenEvent, NULL))
	{
		free(pChannelOpenEvent);
		return CHANNEL_RC_NO_MEMORY;
	}

	return CHANNEL_RC_OK;
}
예제 #11
0
파일: wf_rail.c 프로젝트: AMV007/FreeRDP
void wf_rail_invalidate_region(wfContext* wfc, REGION16* invalidRegion)
{
	int index;
	int count;
	RECT updateRect;
	RECTANGLE_16 windowRect;
	ULONG_PTR* pKeys = NULL;
	wfRailWindow* railWindow;
	const RECTANGLE_16* extents;
	REGION16 windowInvalidRegion;

	region16_init(&windowInvalidRegion);

	count = HashTable_GetKeys(wfc->railWindows, &pKeys);

	for (index = 0; index < count; index++)
	{
		railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows, (void*) pKeys[index]);

		if (railWindow)
		{
			windowRect.left = railWindow->x;
			windowRect.top = railWindow->y;
			windowRect.right = railWindow->x + railWindow->width;
			windowRect.bottom = railWindow->y + railWindow->height;

			region16_clear(&windowInvalidRegion);
			region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect);

			if (!region16_is_empty(&windowInvalidRegion))
			{
				extents = region16_extents(&windowInvalidRegion);

				updateRect.left = extents->left - railWindow->x;
				updateRect.top = extents->top - railWindow->y;
				updateRect.right = extents->right - railWindow->x;
				updateRect.bottom = extents->bottom - railWindow->y;

				InvalidateRect(railWindow->hWnd, &updateRect, FALSE);
			}
		}
	}

	region16_uninit(&windowInvalidRegion);
}
예제 #12
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT xf_rail_server_min_max_info(RailClientContext* context,
                                        RAIL_MINMAXINFO_ORDER* minMaxInfo)
{
	xfAppWindow* appWindow = NULL;
	xfContext* xfc = (xfContext*) context->custom;
	appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
	            (void*)(UINT_PTR) minMaxInfo->windowId);

	if (!appWindow)
		return ERROR_INTERNAL_ERROR;

	xf_SetWindowMinMaxInfo(xfc, appWindow,
	                       minMaxInfo->maxWidth, minMaxInfo->maxHeight,
	                       minMaxInfo->maxPosX, minMaxInfo->maxPosY,
	                       minMaxInfo->minTrackWidth, minMaxInfo->minTrackHeight,
	                       minMaxInfo->maxTrackWidth, minMaxInfo->maxTrackHeight);
	return CHANNEL_RC_OK;
}
예제 #13
0
파일: wf_rail.c 프로젝트: AMV007/FreeRDP
static void wf_rail_window_delete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
{
	wfRailWindow* railWindow = NULL;
	wfContext* wfc = (wfContext*) context;
	RailClientContext* rail = wfc->rail;

	WLog_DBG(TAG, "RailWindowDelete");

	railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows,
			(void*) (UINT_PTR) orderInfo->windowId);

	if (!railWindow)
		return;

	HashTable_Remove(wfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId);

	DestroyWindow(railWindow->hWnd);

	free(railWindow);
}
예제 #14
0
파일: client.c 프로젝트: kdienes/FreeRDP
static UINT VCAPITYPE FreeRDP_VirtualChannelClose(DWORD openHandle)
{
	rdpChannels* channels;
	CHANNEL_OPEN_DATA* pChannelOpenData;
	channels = (rdpChannels*) freerdp_channel_get_open_handle_data(&g_ChannelHandles, openHandle);

	if (!channels)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	pChannelOpenData = HashTable_GetItemValue(channels->openHandles, (void*)(UINT_PTR) openHandle);

	if (!pChannelOpenData)
		return CHANNEL_RC_BAD_CHANNEL_HANDLE;

	if (pChannelOpenData->flags != 2)
		return CHANNEL_RC_NOT_OPEN;

	pChannelOpenData->flags = 0;
	return CHANNEL_RC_OK;
}
예제 #15
0
xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
{
	int index;
	int count;
	ULONG_PTR* pKeys = NULL;
	xfAppWindow* appWindow;
	count = HashTable_GetKeys(xfc->railWindows, &pKeys);

	for (index = 0; index < count; index++)
	{
		appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]);

		if (appWindow->handle == wnd)
		{
			free(pKeys);
			return appWindow;
		}
	}

	free(pKeys);
	return NULL;
}
예제 #16
0
static UINT video_PresentationRequest(VideoClientContext* video, TSMM_PRESENTATION_REQUEST *req)
{
	VideoClientContextPriv *priv = video->priv;
	PresentationContext *presentation;
	UINT ret = CHANNEL_RC_OK;

	presentation = priv->currentPresentation;

	if (req->Command == TSMM_START_PRESENTATION)
	{
		MAPPED_GEOMETRY *geom;
		TSMM_PRESENTATION_RESPONSE resp;

		if (memcmp(req->VideoSubtypeId, MFVideoFormat_H264, 16) != 0)
		{
			WLog_ERR(TAG, "not a H264 video, ignoring request");
			return CHANNEL_RC_OK;
		}

		if (presentation)
		{
			if (presentation->PresentationId == req->PresentationId)
			{
				WLog_ERR(TAG, "ignoring start request for existing presentation %d", req->PresentationId);
				return CHANNEL_RC_OK;
			}

			WLog_ERR(TAG, "releasing current presentation %d", req->PresentationId);
			PresentationContext_unref(presentation);
			presentation = priv->currentPresentation = NULL;
		}

		if (!priv->geometry)
		{
			WLog_ERR(TAG, "geometry channel not ready, ignoring request");
			return CHANNEL_RC_OK;
		}

		geom = HashTable_GetItemValue(priv->geometry->geometries, &(req->GeometryMappingId));
		if (!geom)
		{
			WLog_ERR(TAG, "geometry mapping 0x%"PRIx64" not registered", req->GeometryMappingId);
			return CHANNEL_RC_OK;
		}

		WLog_DBG(TAG, "creating presentation 0x%x", req->PresentationId);
		presentation = PresentationContext_new(video, req->PresentationId,
				geom->topLevelLeft + geom->left,
				geom->topLevelTop + geom->top,
				req->SourceWidth, req->SourceHeight);
		if (!presentation)
		{
			WLog_ERR(TAG, "unable to create presentation video");
			return CHANNEL_RC_NO_MEMORY;
		}

		mappedGeometryRef(geom);
		presentation->geometry = geom;

		priv->currentPresentation = presentation;
		presentation->video = video;
		presentation->SourceWidth = req->SourceWidth;
		presentation->SourceHeight = req->SourceHeight;
		presentation->ScaledWidth = req->ScaledWidth;
		presentation->ScaledHeight = req->ScaledHeight;

		geom->custom = presentation;
		geom->MappedGeometryUpdate = video_onMappedGeometryUpdate;
		geom->MappedGeometryClear = video_onMappedGeometryClear;

		/* send back response */
		resp.PresentationId = req->PresentationId;
		ret = video_control_send_presentation_response(video, &resp);
	}
	else if (req->Command == TSMM_STOP_PRESENTATION)
	{
		WLog_DBG(TAG, "stopping presentation 0x%x", req->PresentationId);
		if (!presentation)
		{
			WLog_ERR(TAG, "unknown presentation to stop %d", req->PresentationId);
			return CHANNEL_RC_OK;
		}

		priv->currentPresentation = NULL;
		priv->droppedFrames = 0;
		priv->publishedFrames = 0;
		PresentationContext_unref(presentation);
	}

	return CHANNEL_RC_OK;
}
예제 #17
0
파일: wf_rail.c 프로젝트: AMV007/FreeRDP
static void wf_rail_window_icon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
{
	HDC hDC;
	int bpp;
	int width;
	int height;
	HICON hIcon;
	BOOL bigIcon;
	ICONINFO iconInfo;
	BITMAPINFO bitmapInfo;
	wfRailWindow* railWindow;
	BITMAPINFOHEADER* bitmapInfoHeader;
	wfContext* wfc = (wfContext*) context;
	RailClientContext* rail = wfc->rail;

	WLog_DBG(TAG, "RailWindowIcon");

	PrintRailIconInfo(orderInfo, windowIcon->iconInfo);

	railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows,
			(void*) (UINT_PTR) orderInfo->windowId);

	if (!railWindow)
		return;

	bigIcon = (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? TRUE : FALSE;

	hDC = GetDC(railWindow->hWnd);

	iconInfo.fIcon = TRUE;
	iconInfo.xHotspot = 0;
	iconInfo.yHotspot = 0;

	ZeroMemory(&bitmapInfo, sizeof(BITMAPINFO));
	bitmapInfoHeader = &(bitmapInfo.bmiHeader);

	bpp = windowIcon->iconInfo->bpp;
	width = windowIcon->iconInfo->width;
	height = windowIcon->iconInfo->height;

	bitmapInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
	bitmapInfoHeader->biWidth = width;
	bitmapInfoHeader->biHeight = height;
	bitmapInfoHeader->biPlanes = 1;
	bitmapInfoHeader->biBitCount = bpp;
	bitmapInfoHeader->biCompression = 0;
	bitmapInfoHeader->biSizeImage = height * width * ((bpp + 7) / 8);
	bitmapInfoHeader->biXPelsPerMeter = width;
	bitmapInfoHeader->biYPelsPerMeter = height;
	bitmapInfoHeader->biClrUsed = 0;
	bitmapInfoHeader->biClrImportant = 0;

	iconInfo.hbmMask = CreateDIBitmap(hDC,
		bitmapInfoHeader, CBM_INIT,
		windowIcon->iconInfo->bitsMask,
		&bitmapInfo, DIB_RGB_COLORS);

	iconInfo.hbmColor = CreateDIBitmap(hDC,
		bitmapInfoHeader, CBM_INIT,
		windowIcon->iconInfo->bitsColor,
		&bitmapInfo, DIB_RGB_COLORS);

	hIcon = CreateIconIndirect(&iconInfo);

	if (hIcon)
	{
		WPARAM wParam;
		LPARAM lParam;

		wParam = (WPARAM) bigIcon ? ICON_BIG : ICON_SMALL;
		lParam = (LPARAM) hIcon;

		SendMessage(railWindow->hWnd, WM_SETICON, wParam, lParam);
	}

	ReleaseDC(NULL, hDC);

	if (windowIcon->iconInfo->cacheEntry != 0xFFFF)
	{
		/* icon should be cached */
	}
}
예제 #18
0
파일: wf_rail.c 프로젝트: AMV007/FreeRDP
static void wf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
	wfRailWindow* railWindow = NULL;
	wfContext* wfc = (wfContext*) context;
	RailClientContext* rail = wfc->rail;
	UINT32 fieldFlags = orderInfo->fieldFlags;

	PrintRailWindowState(orderInfo, windowState);

	if (fieldFlags & WINDOW_ORDER_STATE_NEW)
	{
		HANDLE hInstance;
		WCHAR* titleW = NULL;
		WNDCLASSEX wndClassEx;

		railWindow = (wfRailWindow*) calloc(1, sizeof(wfRailWindow));

		if (!railWindow)
			return;

		railWindow->wfc = wfc;

		railWindow->dwStyle = windowState->style;
		railWindow->dwStyle &= ~RAIL_DISABLED_WINDOW_STYLES;
		railWindow->dwExStyle = windowState->extendedStyle;
		railWindow->dwExStyle &= ~RAIL_DISABLED_EXTENDED_WINDOW_STYLES;

		railWindow->x = windowState->windowOffsetX;
		railWindow->y = windowState->windowOffsetY;
		railWindow->width = windowState->windowWidth;
		railWindow->height = windowState->windowHeight;

		if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
		{
			char* title = NULL;

			ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
				   windowState->titleInfo.length / 2, &title, 0, NULL, NULL);

			railWindow->title = title;
		}
		else
		{
			railWindow->title = _strdup("RdpRailWindow");
		}

		ConvertToUnicode(CP_UTF8, 0, railWindow->title, -1, &titleW, 0);

		hInstance = GetModuleHandle(NULL);

		ZeroMemory(&wndClassEx, sizeof(WNDCLASSEX));
		wndClassEx.cbSize = sizeof(WNDCLASSEX);
		wndClassEx.style = 0;
		wndClassEx.lpfnWndProc = wf_RailWndProc;
		wndClassEx.cbClsExtra = 0;
		wndClassEx.cbWndExtra = 0;
		wndClassEx.hIcon = NULL;
		wndClassEx.hCursor = NULL;
		wndClassEx.hbrBackground = NULL;
		wndClassEx.lpszMenuName = NULL;
		wndClassEx.lpszClassName = _T("RdpRailWindow");
		wndClassEx.hInstance = hInstance;
		wndClassEx.hIconSm = NULL;

		RegisterClassEx(&wndClassEx);

		railWindow->hWnd = CreateWindowExW(
				railWindow->dwExStyle, /* dwExStyle */
				_T("RdpRailWindow"), /* lpClassName */
				titleW, /* lpWindowName */
				railWindow->dwStyle, /* dwStyle */
				railWindow->x, /* x */
				railWindow->y, /* y */
				railWindow->width, /* nWidth */
				railWindow->height, /* nHeight */
				NULL, /* hWndParent */
				NULL, /* hMenu */
				hInstance, /* hInstance */
				NULL /* lpParam */
				);

		SetWindowLongPtr(railWindow->hWnd, GWLP_USERDATA, (LONG_PTR) railWindow);

		HashTable_Add(wfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) railWindow);

		free(titleW);

		UpdateWindow(railWindow->hWnd);

		return;
	}
	else
	{
		railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows,
			(void*) (UINT_PTR) orderInfo->windowId);
	}

	if (!railWindow)
		return;

	if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
		(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
	{
		if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
		{
			railWindow->x = windowState->windowOffsetX;
			railWindow->y = windowState->windowOffsetY;
		}

		if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
		{
			railWindow->width = windowState->windowWidth;
			railWindow->height = windowState->windowHeight;
		}

		SetWindowPos(railWindow->hWnd, NULL,
			railWindow->x,
			railWindow->y,
			railWindow->width,
			railWindow->height,
			0);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_OWNER)
	{
		
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{
		railWindow->dwStyle = windowState->style;
		railWindow->dwStyle &= ~RAIL_DISABLED_WINDOW_STYLES;
		railWindow->dwExStyle = windowState->extendedStyle;
		railWindow->dwExStyle &= ~RAIL_DISABLED_EXTENDED_WINDOW_STYLES;

		SetWindowLongPtr(railWindow->hWnd, GWL_STYLE, (LONG) railWindow->dwStyle);
		SetWindowLongPtr(railWindow->hWnd, GWL_EXSTYLE, (LONG) railWindow->dwExStyle);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		ShowWindow(railWindow->hWnd, windowState->showState);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		char* title = NULL;
		WCHAR* titleW = NULL;

		ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
			   windowState->titleInfo.length / 2, &title, 0, NULL, NULL);

		free(railWindow->title);
		railWindow->title = title;

		ConvertToUnicode(CP_UTF8, 0, railWindow->title, -1, &titleW, 0);

		SetWindowTextW(railWindow->hWnd, titleW);

		free(titleW);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
	{

	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
	{

	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
	{

	}

	if (fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
	{

	}

	if (fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
	{

	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
	{
		UINT32 index;
		HRGN hWndRect;
		HRGN hWndRects;
		RECTANGLE_16* rect;

		if (windowState->numWindowRects > 0)
		{
			rect = &(windowState->windowRects[0]);
			hWndRects = CreateRectRgn(rect->left, rect->top, rect->right, rect->bottom);

			for (index = 1; index < windowState->numWindowRects; index++)
			{
				rect = &(windowState->windowRects[index]);
				hWndRect = CreateRectRgn(rect->left, rect->top, rect->right, rect->bottom);
				CombineRgn(hWndRects, hWndRects, hWndRect, RGN_OR);
				DeleteObject(hWndRect);
			}

			SetWindowRgn(railWindow->hWnd, hWndRects, TRUE);
			DeleteObject(hWndRects);
		}
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
	{

	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
	{

	}

	UpdateWindow(railWindow->hWnd);
}
예제 #19
0
파일: xf_rail.c 프로젝트: bceverly/FreeRDP
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT xf_rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
{
	int x = 0, y = 0;
	int direction = 0;
	Window child_window;
	xfAppWindow* appWindow = NULL;
	xfContext* xfc = (xfContext*) context->custom;

	appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
			(void*) (UINT_PTR) localMoveSize->windowId);

	if (!appWindow)
		return ERROR_INTERNAL_ERROR;

	switch (localMoveSize->moveSizeType)
	{
		case RAIL_WMSZ_LEFT:
			direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			break;

		case RAIL_WMSZ_RIGHT:
			direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			break;

		case RAIL_WMSZ_TOP:
			direction = _NET_WM_MOVERESIZE_SIZE_TOP;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			break;

		case RAIL_WMSZ_TOPLEFT:
			direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			break;

		case RAIL_WMSZ_TOPRIGHT:
			direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			break;

		case RAIL_WMSZ_BOTTOM:
			direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			break;

		case RAIL_WMSZ_BOTTOMLEFT:
			direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			break;

		case RAIL_WMSZ_BOTTOMRIGHT:
			direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			break;

		case RAIL_WMSZ_MOVE:
			direction = _NET_WM_MOVERESIZE_MOVE;
			XTranslateCoordinates(xfc->display, appWindow->handle,
					RootWindowOfScreen(xfc->screen),
					localMoveSize->posX, localMoveSize->posY, &x, &y, &child_window);
			break;

		case RAIL_WMSZ_KEYMOVE:
			direction = _NET_WM_MOVERESIZE_MOVE_KEYBOARD;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			/* FIXME: local keyboard moves not working */
			return CHANNEL_RC_OK;
			break;

		case RAIL_WMSZ_KEYSIZE:
			direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD;
			x = localMoveSize->posX;
			y = localMoveSize->posY;
			/* FIXME: local keyboard moves not working */
			return CHANNEL_RC_OK;
			break;
	}

	if (localMoveSize->isMoveSizeStart)
	{
		xf_StartLocalMoveSize(xfc, appWindow, direction, x, y);
	}
	else
	{
		xf_EndLocalMoveSize(xfc, appWindow);
	}

	return CHANNEL_RC_OK;
}
예제 #20
0
파일: xf_rail.c 프로젝트: bceverly/FreeRDP
static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
	xfAppWindow* appWindow = NULL;
	xfContext* xfc = (xfContext*) context;
	UINT32 fieldFlags = orderInfo->fieldFlags;

	if (fieldFlags & WINDOW_ORDER_STATE_NEW)
	{
		appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));

		if (!appWindow)
			return FALSE;

		appWindow->xfc = xfc;

		appWindow->windowId = orderInfo->windowId;
		appWindow->dwStyle = windowState->style;
		appWindow->dwExStyle = windowState->extendedStyle;

		appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX;
		appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY;
		appWindow->width = appWindow->windowWidth = windowState->windowWidth;
		appWindow->height = appWindow->windowHeight = windowState->windowHeight;

		appWindow->localWindowOffsetCorrX = 0;
		appWindow->localWindowOffsetCorrY = 0;

		if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
		{
			char* title = NULL;

			ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
				   windowState->titleInfo.length / 2, &title, 0, NULL, NULL);

			appWindow->title = title;
		}
		else
		{
			appWindow->title = _strdup("RdpRailWindow");
		}
		if (!appWindow->title)
		{
			free(appWindow);
			return FALSE;
		}

		HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow);

		xf_AppWindowInit(xfc, appWindow);

		return TRUE;
	}
	else
	{
		appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
			(void*) (UINT_PTR) orderInfo->windowId);
	}

	if (!appWindow)
		return FALSE;

	/* Update Parameters */

	if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
		(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
	{
		if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
		{
			appWindow->windowOffsetX = windowState->windowOffsetX;
			appWindow->windowOffsetY = windowState->windowOffsetY;

			/*
			 * The rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
			 * but we can only send unsigned integers to the rail server. Therefore, we maintain a local offset.
			 */

			if (appWindow->windowOffsetX < 0)
				appWindow->localWindowOffsetCorrX = 0 - appWindow->windowOffsetX;
			else
				appWindow->localWindowOffsetCorrX = 0;

			if (appWindow->windowOffsetY < 0)
				appWindow->localWindowOffsetCorrY = 0 - appWindow->windowOffsetY;
			else
				appWindow->localWindowOffsetCorrY = 0;
		}

		if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
		{
			appWindow->windowWidth = windowState->windowWidth;
			appWindow->windowHeight = windowState->windowHeight;
		}
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_OWNER)
	{
		appWindow->ownerWindowId = windowState->ownerWindowId;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{
		appWindow->dwStyle = windowState->style;
		appWindow->dwExStyle = windowState->extendedStyle;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		appWindow->showState = windowState->showState;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		char* title = NULL;

		ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
			   windowState->titleInfo.length / 2, &title, 0, NULL, NULL);

		free(appWindow->title);
		appWindow->title = title;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
	{
		appWindow->clientOffsetX = windowState->clientOffsetX;
		appWindow->clientOffsetY = windowState->clientOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
	{
		appWindow->clientAreaWidth = windowState->clientAreaWidth;
		appWindow->clientAreaHeight = windowState->clientAreaHeight;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
	{
		appWindow->windowClientDeltaX = windowState->windowClientDeltaX;
		appWindow->windowClientDeltaY = windowState->windowClientDeltaY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
	{
		if (appWindow->windowRects)
		{
			free(appWindow->windowRects);
			appWindow->windowRects = NULL;
		}

		appWindow->numWindowRects = windowState->numWindowRects;

		if (appWindow->numWindowRects)
		{
			appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects, sizeof(RECTANGLE_16));

			if (!appWindow->windowRects)
				return FALSE;

			CopyMemory(appWindow->windowRects, windowState->windowRects,
					appWindow->numWindowRects * sizeof(RECTANGLE_16));
		}
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
	{
		appWindow->visibleOffsetX = windowState->visibleOffsetX;
		appWindow->visibleOffsetY = windowState->visibleOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
	{
		if (appWindow->visibilityRects)
		{
			free(appWindow->visibilityRects);
			appWindow->visibilityRects = NULL;
		}

		appWindow->numVisibilityRects = windowState->numVisibilityRects;

		if (appWindow->numVisibilityRects)
		{
			appWindow->visibilityRects = (RECTANGLE_16*) calloc(appWindow->numVisibilityRects, sizeof(RECTANGLE_16));

			if (!appWindow->visibilityRects)
				return FALSE;

			CopyMemory(appWindow->visibilityRects, windowState->visibilityRects,
					appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
		}
	}

	/* Update Window */

	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{

	}

	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		xf_ShowWindow(xfc, appWindow, appWindow->showState);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		if (appWindow->title)
			xf_SetWindowText(xfc, appWindow, appWindow->title);
	}

	if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
			(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
	{
		/*
		 * The rail server like to set the window to a small size when it is minimized even though it is hidden
		 * in some cases this can cause the window not to restore back to its original size. Therefore we don't
		 * update our local window when that rail window state is minimized
		 */
		if (appWindow->rail_state == WINDOW_SHOW_MINIMIZED)
			return TRUE;

		/* Do nothing if window is already in the correct position */
		if (appWindow->x == (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) &&
				appWindow->y == (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) &&
				appWindow->width == appWindow->windowWidth &&
				appWindow->height == appWindow->windowHeight)
		{
			xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
			return TRUE;
		}

		xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX, appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY,
				appWindow->windowWidth, appWindow->windowHeight);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
	{
		xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
	{
		xf_SetWindowVisibilityRects(xfc, appWindow, appWindow->visibilityRects, appWindow->numVisibilityRects);
	}
	return TRUE;
}
예제 #21
0
파일: server.c 프로젝트: Auto-Droid/FreeRDP
HANDLE WINAPI FreeRDP_WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags)
{
	UINT32 index;
	wStream* s;
	rdpMcs* mcs;
	BOOL joined = FALSE;
	freerdp_peer* client;
	rdpPeerChannel* channel;
	ULONG written;
	WTSVirtualChannelManager* vcm;

	if (SessionId == WTS_CURRENT_SESSION)
		return NULL;

	vcm = (WTSVirtualChannelManager*) HashTable_GetItemValue(g_ServerHandles, (void*) (UINT_PTR) SessionId);

	if (!vcm)
		return NULL;

	if (!(flags & WTS_CHANNEL_OPTION_DYNAMIC))
	{
		return FreeRDP_WTSVirtualChannelOpen((HANDLE) vcm, SessionId, pVirtualName);
	}

	client = vcm->client;
	mcs = client->context->rdp->mcs;

	for (index = 0; index < mcs->channelCount; index++)
	{
		if (mcs->channels[index].joined && (strncmp(mcs->channels[index].Name, "drdynvc", 7) == 0))
		{
			joined = TRUE;
			break;
		}
	}

	if (!joined)
	{
		SetLastError(ERROR_NOT_FOUND);
		return NULL;
	}

	if (!vcm->drdynvc_channel || (vcm->drdynvc_state != DRDYNVC_STATE_READY))
	{
		SetLastError(ERROR_NOT_READY);
		return NULL;
	}

	channel = (rdpPeerChannel*) calloc(1, sizeof(rdpPeerChannel));

	channel->vcm = vcm;
	channel->client = client;
	channel->channelType = RDP_PEER_CHANNEL_TYPE_DVC;
	channel->receiveData = Stream_New(NULL, client->settings->VirtualChannelChunkSize);
	channel->queue = MessageQueue_New(NULL);

	channel->channelId = vcm->dvc_channel_id_seq++;
	ArrayList_Add(vcm->dynamicVirtualChannels, channel);

	s = Stream_New(NULL, 64);
	wts_write_drdynvc_create_request(s, channel->channelId, pVirtualName);
	WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
	Stream_Free(s, TRUE);

	return channel;
}
예제 #22
0
int test_hash_table_string()
{
	int count;
	char* value;
	wHashTable* table;

	table = HashTable_New(TRUE);
	if (!table)
		return -1;

	table->hash = HashTable_StringHash;
	table->keyCompare = HashTable_StringCompare;
	table->valueCompare = HashTable_StringCompare;
	table->keyClone = HashTable_StringClone;
	table->valueClone = HashTable_StringClone;
	table->keyFree = HashTable_StringFree;
	table->valueFree = HashTable_StringFree;

	HashTable_Add(table, key1, val1);
	HashTable_Add(table, key2, val2);
	HashTable_Add(table, key3, val3);

	count = HashTable_Count(table);

	if (count != 3)
	{
		printf("HashTable_Count: Expected : %d, Actual: %d\n", 3, count);
		return -1;
	}

	HashTable_Remove(table, key2);

	count = HashTable_Count(table);

	if (count != 2)
	{
		printf("HashTable_Count: Expected : %d, Actual: %d\n", 2, count);
		return -1;
	}

	HashTable_Remove(table, key3);

	count = HashTable_Count(table);

	if (count != 1)
	{
		printf("HashTable_Count: Expected : %d, Actual: %d\n", 1, count);
		return -1;
	}

	HashTable_Remove(table, key1);

	count = HashTable_Count(table);

	if (count != 0)
	{
		printf("HashTable_Count: Expected : %d, Actual: %d\n", 0, count);
		return -1;
	}

	HashTable_Add(table, key1, val1);
	HashTable_Add(table, key2, val2);
	HashTable_Add(table, key3, val3);

	count = HashTable_Count(table);

	if (count != 3)
	{
		printf("HashTable_Count: Expected : %d, Actual: %d\n", 3, count);
		return -1;
	}

	value = (char*) HashTable_GetItemValue(table, key1);

	if (strcmp(value, val1) != 0)
	{
		printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val1, value);
		return -1;
	}

	value = (char*) HashTable_GetItemValue(table, key2);

	if (strcmp(value, val2) != 0)
	{
		printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val2, value);
		return -1;
	}

	value = (char*) HashTable_GetItemValue(table, key3);

	if (strcmp(value, val3) != 0)
	{
		printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", val3, value);
		return -1;
	}

	HashTable_SetItemValue(table, key2, "apple");

	value = (char*) HashTable_GetItemValue(table, key2);

	if (strcmp(value, "apple") != 0)
	{
		printf("HashTable_GetItemValue: Expected : %s, Actual: %s\n", "apple", value);
		return -1;
	}

	if (!HashTable_Contains(table, key2))
	{
		printf("HashTable_Contains: Expected : %d, Actual: %d\n", TRUE, FALSE);
		return -1;
	}

	if (!HashTable_Remove(table, key2))
	{
		printf("HashTable_Remove: Expected : %d, Actual: %d\n", TRUE, FALSE);
		return -1;
	}

	if (HashTable_Remove(table, key2))
	{
		printf("HashTable_Remove: Expected : %d, Actual: %d\n", FALSE, TRUE);
		return -1;
	}

	HashTable_Clear(table);

	count = HashTable_Count(table);

	if (count != 0)
	{
		printf("HashTable_Count: Expected : %d, Actual: %d\n", 0, count);
		return -1;
	}

	HashTable_Free(table);

	return 1;
}
예제 #23
0
static BOOL xf_rail_window_common(rdpContext* context,
                                  WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
	xfAppWindow* appWindow = NULL;
	xfContext* xfc = (xfContext*) context;
	UINT32 fieldFlags = orderInfo->fieldFlags;
	BOOL position_or_size_updated = FALSE;

	if (fieldFlags & WINDOW_ORDER_STATE_NEW)
	{
		appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));

		if (!appWindow)
			return FALSE;

		appWindow->xfc = xfc;
		appWindow->windowId = orderInfo->windowId;
		appWindow->dwStyle = windowState->style;
		appWindow->dwExStyle = windowState->extendedStyle;
		appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX;
		appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY;
		appWindow->width = appWindow->windowWidth = windowState->windowWidth;
		appWindow->height = appWindow->windowHeight = windowState->windowHeight;

		/* Ensure window always gets a window title */
		if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
		{
			char* title = NULL;

			if (windowState->titleInfo.length == 0)
			{
				if (!(title = _strdup("")))
				{
					WLog_ERR(TAG, "failed to duplicate empty window title string");
					/* error handled below */
				}
			}
			else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
			                            windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
			{
				WLog_ERR(TAG, "failed to convert window title");
				/* error handled below */
			}

			appWindow->title = title;
		}
		else
		{
			if (!(appWindow->title = _strdup("RdpRailWindow")))
				WLog_ERR(TAG, "failed to duplicate default window title string");
		}

		if (!appWindow->title)
		{
			free(appWindow);
			return FALSE;
		}

		HashTable_Add(xfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId,
		              (void*) appWindow);
		xf_AppWindowInit(xfc, appWindow);
	}
	else
	{
		appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
		            (void*)(UINT_PTR) orderInfo->windowId);
	}

	if (!appWindow)
		return FALSE;

	/* Keep track of any position/size update so that we can force a refresh of the window */
	if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
	    (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)   ||
	    (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) ||
	    (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) ||
	    (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) ||
	    (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) ||
	    (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY))
	{
		position_or_size_updated = TRUE;
	}

	/* Update Parameters */

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
	{
		appWindow->windowOffsetX = windowState->windowOffsetX;
		appWindow->windowOffsetY = windowState->windowOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
	{
		appWindow->windowWidth = windowState->windowWidth;
		appWindow->windowHeight = windowState->windowHeight;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_OWNER)
	{
		appWindow->ownerWindowId = windowState->ownerWindowId;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{
		appWindow->dwStyle = windowState->style;
		appWindow->dwExStyle = windowState->extendedStyle;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		appWindow->showState = windowState->showState;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		char* title = NULL;

		if (windowState->titleInfo.length == 0)
		{
			if (!(title = _strdup("")))
			{
				WLog_ERR(TAG, "failed to duplicate empty window title string");
				return FALSE;
			}
		}
		else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
		                            windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
		{
			WLog_ERR(TAG, "failed to convert window title");
			return FALSE;
		}

		free(appWindow->title);
		appWindow->title = title;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
	{
		appWindow->clientOffsetX = windowState->clientOffsetX;
		appWindow->clientOffsetY = windowState->clientOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
	{
		appWindow->clientAreaWidth = windowState->clientAreaWidth;
		appWindow->clientAreaHeight = windowState->clientAreaHeight;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
	{
		appWindow->windowClientDeltaX = windowState->windowClientDeltaX;
		appWindow->windowClientDeltaY = windowState->windowClientDeltaY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
	{
		if (appWindow->windowRects)
		{
			free(appWindow->windowRects);
			appWindow->windowRects = NULL;
		}

		appWindow->numWindowRects = windowState->numWindowRects;

		if (appWindow->numWindowRects)
		{
			appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects,
			                         sizeof(RECTANGLE_16));

			if (!appWindow->windowRects)
				return FALSE;

			CopyMemory(appWindow->windowRects, windowState->windowRects,
			           appWindow->numWindowRects * sizeof(RECTANGLE_16));
		}
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
	{
		appWindow->visibleOffsetX = windowState->visibleOffsetX;
		appWindow->visibleOffsetY = windowState->visibleOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
	{
		if (appWindow->visibilityRects)
		{
			free(appWindow->visibilityRects);
			appWindow->visibilityRects = NULL;
		}

		appWindow->numVisibilityRects = windowState->numVisibilityRects;

		if (appWindow->numVisibilityRects)
		{
			appWindow->visibilityRects = (RECTANGLE_16*) calloc(
			                                 appWindow->numVisibilityRects, sizeof(RECTANGLE_16));

			if (!appWindow->visibilityRects)
				return FALSE;

			CopyMemory(appWindow->visibilityRects, windowState->visibilityRects,
			           appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
		}
	}

	/* Update Window */

	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		xf_ShowWindow(xfc, appWindow, appWindow->showState);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		if (appWindow->title)
			xf_SetWindowText(xfc, appWindow, appWindow->title);
	}

	if (position_or_size_updated)
	{
		UINT32 visibilityRectsOffsetX = (appWindow->visibleOffsetX -
		                                 (appWindow->clientOffsetX - appWindow->windowClientDeltaX));
		UINT32 visibilityRectsOffsetY = (appWindow->visibleOffsetY -
		                                 (appWindow->clientOffsetY - appWindow->windowClientDeltaY));

		/*
		 * The rail server like to set the window to a small size when it is minimized even though it is hidden
		 * in some cases this can cause the window not to restore back to its original size. Therefore we don't
		 * update our local window when that rail window state is minimized
		 */
		if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)
		{
			/* Redraw window area if already in the correct position */
			if (appWindow->x == appWindow->windowOffsetX &&
			    appWindow->y == appWindow->windowOffsetY &&
			    appWindow->width == appWindow->windowWidth &&
			    appWindow->height == appWindow->windowHeight)
			{
				xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth,
				                    appWindow->windowHeight);
			}
			else
			{
				xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX,
				              appWindow->windowOffsetY,
				              appWindow->windowWidth, appWindow->windowHeight);
			}

			xf_SetWindowVisibilityRects(xfc, appWindow, visibilityRectsOffsetX,
			                            visibilityRectsOffsetY, appWindow->visibilityRects,
			                            appWindow->numVisibilityRects);
		}
	}

	/* We should only be using the visibility rects for shaping the window */
	/*if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
	{
		xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects);
	}*/
	return TRUE;
}