Example #1
0
static int wf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList)
{
	UINT32 i, j;
	formatMapping* mapping;
	CLIPRDR_FORMAT* format;
	wfClipboard* clipboard = (wfClipboard*) context->custom;

	clear_format_map(clipboard);

	for (i = j = 0; i < formatList->numFormats; i++)
	{
		format = &(formatList->formats[i]);
		mapping = &(clipboard->format_mappings[j++]);

		mapping->remote_format_id = format->formatId;

		if (format->formatName)
		{
			mapping->name = _strdup(format->formatName);
			mapping->local_format_id = RegisterClipboardFormatA((LPCSTR) mapping->name);
		}
		else
		{
			mapping->name = NULL;
			mapping->local_format_id = mapping->remote_format_id;
		}

		clipboard->map_size++;
		map_ensure_capacity(clipboard);
	}

	if (file_transferring(clipboard))
	{
		PostMessage(clipboard->hwnd, WM_CLIPRDR_MESSAGE, OLE_SETCLIPBOARD, 0);
	}
	else
	{
		if (!OpenClipboard(clipboard->hwnd))
			return -1;

		if (EmptyClipboard())
		{
			for (i = 0; i < (UINT32) clipboard->map_size; i++)
			{
				SetClipboardData(clipboard->format_mappings[i].local_format_id, NULL);
			}
		}

		CloseClipboard();
	}

	return 1;
}
Example #2
0
static void wf_cliprdr_process_cb_format_list_event(wfContext *wfc, RDP_CB_FORMAT_LIST_EVENT *event)
{
	cliprdrContext *cliprdr = (cliprdrContext *)wfc->cliprdr_context;
	UINT32 left_size = event->raw_format_data_size;
	int i = 0;
	BYTE *p;
	BYTE* end_mark;
	BOOL format_forbidden = FALSE;

	/* ignore the formats member in event struct, only parsing raw_format_data */

	p = event->raw_format_data;
	end_mark = p + event->raw_format_data_size;

	clear_format_map(cliprdr);

	if ((cliprdr->capabilities & CAPS_USE_LONG_FORMAT_NAMES) != 0)
	{
		while (left_size >= 6)
		{
			formatMapping *map;
			BYTE* tmp;
			int name_len;

			map = &cliprdr->format_mappings[i++];

			Read_UINT32(p, map->remote_format_id);
			map->name = NULL;

			/* get name_len */
			for (tmp = p, name_len = 0; tmp + 1 < end_mark; tmp += 2, name_len += 2)
			{
				if (*((unsigned short*) tmp) == 0)
					break;
			}

			if (name_len > 0)
			{
				map->name = malloc(name_len + 2);
				memcpy(map->name, p, name_len + 2);

				map->local_format_id = RegisterClipboardFormatW((LPCWSTR)map->name);
			}
			else
			{
				map->local_format_id = map->remote_format_id;
			}

			left_size -= name_len + 4 + 2;
			p += name_len + 2;          /* p's already +4 when Read_UINT32() is called. */

			cliprdr->map_size++;

			map_ensure_capacity(cliprdr);
		}
	}
	else
	{
		int k;

		for (k = 0; k < event->raw_format_data_size / 36; k++)
		{
			formatMapping *map;
			int name_len;

			map = &cliprdr->format_mappings[i++];

			Read_UINT32(p, map->remote_format_id);
			map->name = NULL;

			if (event->raw_format_unicode)
			{
				/* get name_len, in bytes, if the file name is truncated, no terminated null will be included. */
				for (name_len = 0; name_len < 32; name_len += 2)
				{
					if (*((unsigned short*) (p + name_len)) == 0)
						break;
				}

				if (name_len > 0)
				{
					map->name = calloc(1, name_len + 2);
					memcpy(map->name, p, name_len);
					map->local_format_id = RegisterClipboardFormatW((LPCWSTR)map->name);
				}
				else
				{
					map->local_format_id = map->remote_format_id;
				}
			}
			else
			{
				/* get name_len, in bytes, if the file name is truncated, no terminated null will be included. */
				for (name_len = 0; name_len < 32; name_len += 1)
				{
					if (*((unsigned char*) (p + name_len)) == 0)
						break;
				}

				if (name_len > 0)
				{
					map->name = calloc(1, name_len + 1);
					memcpy(map->name, p, name_len);
					map->local_format_id = RegisterClipboardFormatA((LPCSTR)map->name);
				}
				else
				{
					map->local_format_id = map->remote_format_id;
				}
			}

			p += 32;          /* p's already +4 when Read_UINT32() is called. */
			cliprdr->map_size++;
			map_ensure_capacity(cliprdr);
		}
	}

	if (!OpenClipboard(cliprdr->hwndClipboard))
	{
		DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError());
		return;
	}

	if (!EmptyClipboard())
	{
		DEBUG_CLIPRDR("EmptyClipboard failed with 0x%x", GetLastError());
		CloseClipboard();
		return;
	}

	for (i = 0; i < cliprdr->map_size; i++)
	{
		SetClipboardData(cliprdr->format_mappings[i].local_format_id, NULL);
	}

	CloseClipboard();
}
Example #3
0
static int wf_cliprdr_server_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
{
	int size = 0;
	char* buff = NULL;
	char* globlemem = NULL;
	HANDLE hClipdata = NULL;
	UINT32 requestedFormatId;
	CLIPRDR_FORMAT_DATA_RESPONSE response;
	wfClipboard* clipboard = (wfClipboard*) context->custom;

	requestedFormatId = formatDataRequest->requestedFormatId;

	if (requestedFormatId == RegisterClipboardFormatW(_T("FileGroupDescriptorW")))
	{
		int len;
		int i;
		WCHAR* wFileName;
		unsigned int uSize;
		HRESULT result;
		LPDATAOBJECT dataObj;
		FORMATETC format_etc;
		STGMEDIUM stg_medium;
		DROPFILES* dropFiles;

		result = OleGetClipboard(&dataObj);

		if (FAILED(result))
			return -1;

		ZeroMemory(&format_etc, sizeof(FORMATETC));
		ZeroMemory(&stg_medium, sizeof(STGMEDIUM));

		/* try to get FileGroupDescriptorW struct from OLE */
		format_etc.cfFormat = requestedFormatId;
		format_etc.tymed = TYMED_HGLOBAL;
		format_etc.dwAspect = 1;
		format_etc.lindex = -1;
		format_etc.ptd = 0;

		result = IDataObject_GetData(dataObj, &format_etc, &stg_medium);

		if (SUCCEEDED(result))
		{
			DEBUG_CLIPRDR("Got FileGroupDescriptorW.");
			globlemem = (char*) GlobalLock(stg_medium.hGlobal);
			uSize = GlobalSize(stg_medium.hGlobal);
			size = uSize;
			buff = (char*) malloc(uSize);
			CopyMemory(buff, globlemem, uSize);
			GlobalUnlock(stg_medium.hGlobal);

			ReleaseStgMedium(&stg_medium);

			clear_file_array(clipboard);
		}
		else
		{
			/* get DROPFILES struct from OLE */
			format_etc.cfFormat = CF_HDROP;
			format_etc.tymed = TYMED_HGLOBAL;
			format_etc.dwAspect = 1;
			format_etc.lindex = -1;

			result = IDataObject_GetData(dataObj, &format_etc, &stg_medium);

			if (FAILED(result)) {
				DEBUG_CLIPRDR("dataObj->GetData failed.");
			}

			globlemem = (char*) GlobalLock(stg_medium.hGlobal);

			if (!globlemem)
			{
				GlobalUnlock(stg_medium.hGlobal);

				ReleaseStgMedium(&stg_medium);
				clipboard->nFiles = 0;

				goto exit;
			}
			uSize = GlobalSize(stg_medium.hGlobal);

			dropFiles = (DROPFILES*) malloc(uSize);
			memcpy(dropFiles, globlemem, uSize);

			GlobalUnlock(stg_medium.hGlobal);

			ReleaseStgMedium(&stg_medium);

			clear_file_array(clipboard);

			if (dropFiles->fWide)
			{
				WCHAR* p;
				int str_len;
				int offset;
				int pathLen;

				/* dropFiles contains file names */
				for (wFileName = (WCHAR*)((char*)dropFiles + dropFiles->pFiles); (len = wcslen(wFileName)) > 0; wFileName += len + 1)
				{
					/* get path name */
					str_len = wcslen(wFileName);
					offset = str_len;
					/* find the last '\' in full file name */
					for (p = wFileName + offset; *p != L'\\'; p--)
					{
						;
					}
					p += 1;
					pathLen = wcslen(wFileName) - wcslen(p);

					wf_cliprdr_add_to_file_arrays(clipboard, wFileName, pathLen);

					if ((clipboard->fileDescriptor[clipboard->nFiles - 1]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
					{
						/* this is a directory */
						wf_cliprdr_traverse_directory(clipboard, wFileName, pathLen);
					}
				}
			}
			else
			{
				char* p;

				for (p = (char*)((char*)dropFiles + dropFiles->pFiles); (len = strlen(p)) > 0; p += len + 1, clipboard->nFiles++)
				{
					int cchWideChar;

					cchWideChar = MultiByteToWideChar(CP_ACP, MB_COMPOSITE, p, len, NULL, 0);
					clipboard->file_names[clipboard->nFiles] = (LPWSTR) malloc(cchWideChar * 2);
					MultiByteToWideChar(CP_ACP, MB_COMPOSITE, p, len, clipboard->file_names[clipboard->nFiles], cchWideChar);

					map_ensure_capacity(clipboard);
				}
			}

exit:
			size = 4 + clipboard->nFiles * sizeof(FILEDESCRIPTORW);
			buff = (char*) malloc(size);

			*((UINT32*) buff) = clipboard->nFiles;

			for (i = 0; i < clipboard->nFiles; i++)
			{
				if (clipboard->fileDescriptor[i])
				{
					memcpy(buff + 4 + i * sizeof(FILEDESCRIPTORW), clipboard->fileDescriptor[i], sizeof(FILEDESCRIPTORW));
				}
			}
		}

		IDataObject_Release(dataObj);
	}
	else
	{
		if (!OpenClipboard(clipboard->hwnd))
			return -1;

		hClipdata = GetClipboardData(requestedFormatId);

		if (!hClipdata)
		{
			CloseClipboard();
			return -1;
		}

		globlemem = (char*) GlobalLock(hClipdata);
		size = (int) GlobalSize(hClipdata);

		buff = (char*) malloc(size);
		CopyMemory(buff, globlemem, size);

		GlobalUnlock(hClipdata);

		CloseClipboard();
	}

	ZeroMemory(&response, sizeof(CLIPRDR_FORMAT_DATA_RESPONSE));

	response.msgFlags = CB_RESPONSE_OK;
	response.dataLen = size;
	response.requestedFormatData = (BYTE*) buff;

	clipboard->context->ClientFormatDataResponse(clipboard->context, &response);

	free(buff);

	return 1;
}