示例#1
0
文件: wf_cliprdr.c 项目: C4rt/FreeRDP
int wf_cliprdr_server_file_contents_request(CliprdrClientContext* context, CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{
	UINT32 uSize = 0;
	BYTE* pData = NULL;
	HRESULT	hRet = S_OK;
	FORMATETC vFormatEtc;
	LPDATAOBJECT pDataObj = NULL;
	STGMEDIUM vStgMedium;
	LPSTREAM pStream = NULL;
	BOOL bIsStreamFile = TRUE;
	static LPSTREAM	pStreamStc = NULL;
	static UINT32 uStreamIdStc = 0;
	wfClipboard* clipboard = (wfClipboard*) context->custom;

	if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE)
		fileContentsRequest->cbRequested = sizeof(UINT64);

	pData = (BYTE*) calloc(1, fileContentsRequest->cbRequested);
	
	if (!pData)
		goto error;

	hRet = OleGetClipboard(&pDataObj);

	if (FAILED(hRet))
	{
		WLog_ERR(TAG,  "filecontents: get ole clipboard failed.");
		goto error;
	}
	
	ZeroMemory(&vFormatEtc, sizeof(FORMATETC));
	ZeroMemory(&vStgMedium, sizeof(STGMEDIUM));

	vFormatEtc.cfFormat = clipboard->ID_FILECONTENTS;
	vFormatEtc.tymed = TYMED_ISTREAM;
	vFormatEtc.dwAspect = 1;
	vFormatEtc.lindex = fileContentsRequest->listIndex;
	vFormatEtc.ptd = NULL;

	if ((uStreamIdStc != fileContentsRequest->streamId) || !pStreamStc)
	{
		LPENUMFORMATETC pEnumFormatEtc;
		ULONG CeltFetched;

		FORMATETC vFormatEtc2;

		if (pStreamStc)
		{
			IStream_Release(pStreamStc);
			pStreamStc = NULL;
		}

		bIsStreamFile = FALSE;

		hRet = IDataObject_EnumFormatEtc(pDataObj, DATADIR_GET, &pEnumFormatEtc);

		if (hRet == S_OK)
		{
			do
			{
				hRet = IEnumFORMATETC_Next(pEnumFormatEtc, 1, &vFormatEtc2, &CeltFetched);

				if (hRet == S_OK)
				{
					if (vFormatEtc2.cfFormat == clipboard->ID_FILECONTENTS)
					{
						hRet = IDataObject_GetData(pDataObj, &vFormatEtc, &vStgMedium);

						if (hRet == S_OK)
						{
							pStreamStc = vStgMedium.pstm;
							uStreamIdStc = fileContentsRequest->streamId;
							bIsStreamFile = TRUE;
						}
						break;
					}
				}
			}
			while (hRet == S_OK);
		}
	}

	if (bIsStreamFile == TRUE)
	{
		if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE)
		{
			STATSTG vStatStg;

			ZeroMemory(&vStatStg, sizeof(STATSTG));

			hRet = IStream_Stat(pStreamStc, &vStatStg, STATFLAG_NONAME);

			if (hRet == S_OK)
			{
				*((UINT32*) &pData[0]) = vStatStg.cbSize.LowPart;
				*((UINT32*) &pData[4]) = vStatStg.cbSize.HighPart;
				uSize = fileContentsRequest->cbRequested;
			}
		}
		else if (fileContentsRequest->dwFlags == FILECONTENTS_RANGE)
		{
			LARGE_INTEGER dlibMove;
			ULARGE_INTEGER dlibNewPosition;

			dlibMove.HighPart = fileContentsRequest->nPositionHigh;
			dlibMove.LowPart = fileContentsRequest->nPositionLow;

			hRet = IStream_Seek(pStreamStc, dlibMove, STREAM_SEEK_SET, &dlibNewPosition);

			if (SUCCEEDED(hRet))
			{
				hRet = IStream_Read(pStreamStc, pData, fileContentsRequest->cbRequested, (PULONG) &uSize);
			}

		}
	}
	else
	{
		if (fileContentsRequest->dwFlags == FILECONTENTS_SIZE)
		{
			*((UINT32*) &pData[0]) = clipboard->fileDescriptor[fileContentsRequest->listIndex]->nFileSizeLow;
			*((UINT32*) &pData[4]) = clipboard->fileDescriptor[fileContentsRequest->listIndex]->nFileSizeHigh;
			uSize = fileContentsRequest->cbRequested;
		}
		else if (fileContentsRequest->dwFlags == FILECONTENTS_RANGE)
		{
			BOOL bRet;

			bRet = wf_cliprdr_get_file_contents(clipboard->file_names[fileContentsRequest->listIndex], pData,
				fileContentsRequest->nPositionLow, fileContentsRequest->nPositionHigh,
				fileContentsRequest->cbRequested, &uSize);

			if (bRet == FALSE)
			{
				WLog_ERR(TAG, "get file contents failed.");
				uSize = 0;
				goto error;
			}
		}
	}

	IDataObject_Release(pDataObj);

	if (uSize == 0)
	{
		free(pData);
		pData = NULL;
	}

	cliprdr_send_response_filecontents(clipboard, fileContentsRequest->streamId, uSize, pData);

	free(pData);

	return 1;

error:
	if (pData)
	{
		free(pData);
		pData = NULL;
	}

	if (pDataObj)
	{
		IDataObject_Release(pDataObj);
		pDataObj = NULL;
	}

	WLog_ERR(TAG,  "filecontents: send failed response.");
	cliprdr_send_response_filecontents(clipboard, fileContentsRequest->streamId, 0, NULL);

	return -1;
}
示例#2
0
static void wf_cliprdr_process_cb_filecontents_request_event(wfContext *wfc, RDP_CB_FILECONTENTS_REQUEST_EVENT *event)
{
	cliprdrContext		*cliprdr = (cliprdrContext *)wfc->cliprdr_context;
	UINT32				uSize = 0;
	BYTE				*pData = NULL;
	HRESULT				hRet = S_OK;
	FORMATETC			vFormatEtc;
	LPDATAOBJECT		pDataObj = NULL;
	STGMEDIUM			vStgMedium;
	LPSTREAM			pStream = NULL;
	BOOL				bIsStreamFile = TRUE;
	static LPSTREAM		pStreamStc = NULL;
	static UINT32		uStreamIdStc = 0;

	pData = (BYTE *)calloc(1, event->cbRequested);
	if (!pData)
		goto error;

	hRet = OleGetClipboard(&pDataObj);
	if (!SUCCEEDED(hRet))
	{
		fprintf(stderr, "filecontents: get ole clipboard failed.\n");
		goto error;
	}
	
	ZeroMemory(&vFormatEtc, sizeof(FORMATETC));
	ZeroMemory(&vStgMedium, sizeof(STGMEDIUM));

	vFormatEtc.cfFormat = cliprdr->ID_FILECONTENTS;
	vFormatEtc.tymed = TYMED_ISTREAM;
	vFormatEtc.dwAspect = 1;
	vFormatEtc.lindex = event->lindex;
	vFormatEtc.ptd = NULL;

	if (uStreamIdStc != event->streamId || pStreamStc == NULL)
	{
		LPENUMFORMATETC pEnumFormatEtc;
		ULONG CeltFetched;

		FORMATETC vFormatEtc2;
		if (pStreamStc != NULL)
		{
			IStream_Release(pStreamStc);
			pStreamStc = NULL;
		}

		bIsStreamFile = FALSE;

		hRet = IDataObject_EnumFormatEtc(pDataObj, DATADIR_GET, &pEnumFormatEtc);
		if (hRet == S_OK)
		{
			do {
				hRet = IEnumFORMATETC_Next(pEnumFormatEtc, 1, &vFormatEtc2, &CeltFetched);
				if (hRet == S_OK)
				{
					if (vFormatEtc2.cfFormat == cliprdr->ID_FILECONTENTS)
					{
						hRet = IDataObject_GetData(pDataObj, &vFormatEtc, &vStgMedium);
						if (hRet == S_OK)
						{
							pStreamStc = vStgMedium.pstm;
							uStreamIdStc = event->streamId;
							bIsStreamFile = TRUE;
						}
						break;
					}
				}
			} while (hRet == S_OK);
		}
	}

	if (bIsStreamFile == TRUE)
	{
		if (event->dwFlags == 0x00000001)            /* FILECONTENTS_SIZE */
		{
			STATSTG vStatStg;

			ZeroMemory(&vStatStg, sizeof(STATSTG));

			hRet = IStream_Stat(pStreamStc, &vStatStg, STATFLAG_NONAME);
			if (hRet == S_OK)
			{
				Write_UINT32(pData, vStatStg.cbSize.LowPart);
				Write_UINT32(pData + 4, vStatStg.cbSize.HighPart);
				uSize = event->cbRequested;
			}
		}
		else if (event->dwFlags == 0x00000002)     /* FILECONTENTS_RANGE */
		{
			LARGE_INTEGER dlibMove;
			ULARGE_INTEGER dlibNewPosition;

			dlibMove.HighPart = event->nPositionHigh;
			dlibMove.LowPart = event->nPositionLow;

			hRet = IStream_Seek(pStreamStc, dlibMove, STREAM_SEEK_SET, &dlibNewPosition);
			if (SUCCEEDED(hRet))
			{
				hRet = IStream_Read(pStreamStc, pData, event->cbRequested, (PULONG)&uSize);
			}

		}
	}
	else // is local file
	{
		if (event->dwFlags == 0x00000001)            /* FILECONTENTS_SIZE */
		{
			Write_UINT32(pData, cliprdr->fileDescriptor[event->lindex]->nFileSizeLow);
			Write_UINT32(pData + 4, cliprdr->fileDescriptor[event->lindex]->nFileSizeHigh);
			uSize = event->cbRequested;
		}
		else if (event->dwFlags == 0x00000002)     /* FILECONTENTS_RANGE */
		{
			BOOL bRet;

			bRet = wf_cliprdr_get_file_contents(cliprdr->file_names[event->lindex], pData,
				event->nPositionLow, event->nPositionHigh, event->cbRequested, &uSize);
			if (bRet == FALSE)
			{
				fprintf(stderr, "get file contents failed.\n");
				uSize = 0;
				goto error;
			}
		}
	}

	IDataObject_Release(pDataObj);

	if (uSize == 0)
	{
		free(pData);
		pData = NULL;
	}

	cliprdr_send_response_filecontents(cliprdr, event->streamId, uSize, pData);

	return;

error:
	if (pData)
	{
		free(pData);
		pData = NULL;
	}

	if (pDataObj)
	{
		IDataObject_Release(pDataObj);
		pDataObj = NULL;
	}
	fprintf(stderr, "filecontents: send failed response.\n");
	cliprdr_send_response_filecontents(cliprdr, event->streamId, 0, NULL);
	return;
}