Beispiel #1
0
void wf_cliprdr_uninit(wfContext* wfc, CliprdrClientContext* cliprdr)
{
	wfClipboard* clipboard = wfc->clipboard;

	cliprdr->custom = NULL;

	if (!clipboard)
		return;

	if (clipboard->hwnd)
		PostMessage(clipboard->hwnd, WM_QUIT, 0, 0);

	if (clipboard->thread)
	{
		WaitForSingleObject(clipboard->thread, INFINITE);
		CloseHandle(clipboard->thread);
		clipboard->thread = NULL;
	}

	if (clipboard->response_data_event)
	{
		CloseHandle(clipboard->response_data_event);
		clipboard->response_data_event = NULL;
	}

	clear_file_array(clipboard);
	clear_format_map(clipboard);

	free(clipboard->file_names);
	free(clipboard->fileDescriptor);
	free(clipboard->format_mappings);

	free(clipboard);
}
Beispiel #2
0
void wf_cliprdr_uninit(wfContext* wfc)
{
	cliprdrContext *cliprdr = (cliprdrContext *) wfc->cliprdr_context;

	if (!cliprdr)
		return;

	if (cliprdr->hwndClipboard)
		PostMessage(cliprdr->hwndClipboard, WM_QUIT, 0, 0);

	if (cliprdr->cliprdr_thread)
	{
		WaitForSingleObject(cliprdr->cliprdr_thread, INFINITE);
		CloseHandle(cliprdr->cliprdr_thread);
	}

	if (cliprdr->response_data_event)
		CloseHandle(cliprdr->response_data_event);

	clear_file_array(cliprdr);
	clear_format_map(cliprdr);

	if (cliprdr->file_names)
		free(cliprdr->file_names);
	if (cliprdr->fileDescriptor)
		free(cliprdr->fileDescriptor);
	if (cliprdr->format_mappings)
		free(cliprdr->format_mappings);

	free(cliprdr);
}
Beispiel #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;
}
Beispiel #4
0
static void wf_cliprdr_process_cb_data_request_event(wfContext* wfc, RDP_CB_DATA_REQUEST_EVENT* event)
{
	HANDLE hClipdata;
	int size = 0;
	char* buff = NULL;
	char* globlemem = NULL;
	UINT32 local_format;
	cliprdrContext* cliprdr = (cliprdrContext*) wfc->cliprdr_context;
	RDP_CB_DATA_RESPONSE_EVENT* response_event;

	local_format = event->format;

	if (local_format == FORMAT_ID_PALETTE)
	{
		/* TODO: implement this */
		DEBUG_CLIPRDR("FORMAT_ID_PALETTE is not supported yet.");
	}
	else if (local_format == FORMAT_ID_METAFILE)
	{
		/* TODO: implement this */
		DEBUG_CLIPRDR("FORMAT_ID_MATEFILE is not supported yet.");
	}
	else if (local_format == RegisterClipboardFormatW(L"FileGroupDescriptorW"))
	{
		HRESULT result;
		LPDATAOBJECT dataObj;
		FORMATETC format_etc;
		STGMEDIUM stg_medium;
		DROPFILES *dropFiles;

		int len;
		int i;
		wchar_t *wFileName;
		unsigned int uSize;

		DEBUG_CLIPRDR("file descriptors request.");
		result = OleGetClipboard(&dataObj);
		if (!SUCCEEDED(result))
		{
			DEBUG_CLIPRDR("OleGetClipboard failed.");
		}

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

		/* try to get FileGroupDescriptorW struct from OLE */
		format_etc.cfFormat = local_format;
		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 = malloc(uSize);
			memcpy(buff, globlemem, uSize);
			GlobalUnlock(stg_medium.hGlobal);

			ReleaseStgMedium(&stg_medium);

			clear_file_array(cliprdr);
		}
		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 (!SUCCEEDED(result)) {
				DEBUG_CLIPRDR("dataObj->GetData failed.");
			}

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

			if (globlemem == NULL)
			{
				GlobalUnlock(stg_medium.hGlobal);

				ReleaseStgMedium(&stg_medium);
				cliprdr->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(cliprdr);

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

				/* dropFiles contains file names */
				for (wFileName = (wchar_t *)((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(cliprdr, wFileName, pathLen);

					if ((cliprdr->fileDescriptor[cliprdr->nFiles - 1]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
					{
						/* this is a directory */
						wf_cliprdr_traverse_directory(cliprdr, wFileName, pathLen);
					}
				}
			}
			else
			{
				char *p;
				for (p = (char *)((char *)dropFiles + dropFiles->pFiles); (len = strlen(p)) > 0; p += len + 1, cliprdr->nFiles++)
				{
					int cchWideChar;

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

					if (cliprdr->nFiles == cliprdr->file_array_size)
					{
						cliprdr->file_array_size *= 2;
						cliprdr->fileDescriptor = (FILEDESCRIPTORW **)realloc(cliprdr->fileDescriptor, cliprdr->file_array_size * sizeof(FILEDESCRIPTORW *));
						cliprdr->file_names = (wchar_t **)realloc(cliprdr->file_names, cliprdr->file_array_size * sizeof(wchar_t *));
					}
				}
			}

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

			Write_UINT32(buff, cliprdr->nFiles);

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

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

		hClipdata = GetClipboardData(event->format);

		if (!hClipdata)
		{
			DEBUG_CLIPRDR("GetClipboardData failed.");
			CloseClipboard();
			return;
		}

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

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

		GlobalUnlock(hClipdata);

		CloseClipboard();
	}

	response_event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class,
			CliprdrChannel_DataResponse, NULL, NULL);

	response_event->data = (BYTE *)buff;
	response_event->size = size;

	freerdp_channels_send_event(cliprdr->channels, (wMessage*) response_event);

	/* Note: don't free buffer here. */
}