mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
xfreerdp: replace cliprdr to wire format conversion
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/image.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/clipboard.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/client/cliprdr.h>
|
||||
@@ -55,6 +56,8 @@ struct xf_clipboard
|
||||
rdpChannels* channels;
|
||||
CliprdrClientContext* context;
|
||||
|
||||
wClipboard* system;
|
||||
|
||||
Window root_window;
|
||||
Atom clipboard_atom;
|
||||
Atom property_atom;
|
||||
@@ -186,14 +189,6 @@ static xfCliprdrFormat* xf_cliprdr_get_format_by_atom(xfClipboard* clipboard, At
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BYTE* xf_cliprdr_format_raw_to_wire(BYTE* data, int* size)
|
||||
{
|
||||
BYTE* outbuf;
|
||||
outbuf = (BYTE*) malloc(*size);
|
||||
CopyMemory(outbuf, data, *size);
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
static int xf_cliprdr_format_text_from_wire(BYTE* pSrcData, int SrcSize, BYTE** ppDstData)
|
||||
{
|
||||
int DstSize = -1;
|
||||
@@ -208,15 +203,6 @@ static int xf_cliprdr_format_text_from_wire(BYTE* pSrcData, int SrcSize, BYTE**
|
||||
return DstSize;
|
||||
}
|
||||
|
||||
static BYTE* xf_cliprdr_format_text_to_wire(BYTE* data, int* size)
|
||||
{
|
||||
char* outbuf;
|
||||
|
||||
outbuf = ConvertLineEndingToCRLF((char*) data, size);
|
||||
|
||||
return (BYTE*) outbuf;
|
||||
}
|
||||
|
||||
static int xf_cliprdr_format_unicode_text_from_wire(BYTE* pSrcData, int SrcSize, BYTE** ppDstData)
|
||||
{
|
||||
int DstSize = -1;
|
||||
@@ -232,21 +218,6 @@ static int xf_cliprdr_format_unicode_text_from_wire(BYTE* pSrcData, int SrcSize,
|
||||
return DstSize;
|
||||
}
|
||||
|
||||
static BYTE* xf_cliprdr_format_unicode_text_to_wire(BYTE* data, int* size)
|
||||
{
|
||||
char* inbuf;
|
||||
WCHAR* outbuf = NULL;
|
||||
int out_size;
|
||||
|
||||
inbuf = ConvertLineEndingToCRLF((char*) data, size);
|
||||
out_size = ConvertToUnicode(CP_UTF8, 0, inbuf, -1, &outbuf, 0);
|
||||
free(inbuf);
|
||||
|
||||
*size = (int) ((out_size + 1) * 2);
|
||||
|
||||
return (BYTE*) outbuf;
|
||||
}
|
||||
|
||||
static int xf_cliprdr_format_dib_from_wire(BYTE* pSrcData, int SrcSize, BYTE** ppDstData)
|
||||
{
|
||||
wStream* s;
|
||||
@@ -289,22 +260,6 @@ static int xf_cliprdr_format_dib_from_wire(BYTE* pSrcData, int SrcSize, BYTE** p
|
||||
return DstSize;
|
||||
}
|
||||
|
||||
static BYTE* xf_cliprdr_format_dib_to_wire(BYTE* data, int* size)
|
||||
{
|
||||
BYTE* outbuf;
|
||||
|
||||
/* length should be at least BMP header (14) + sizeof(BITMAPINFOHEADER) */
|
||||
|
||||
if (*size < 54)
|
||||
return NULL;
|
||||
|
||||
*size -= 14;
|
||||
outbuf = (BYTE*) calloc(1, *size);
|
||||
CopyMemory(outbuf, data + 14, *size);
|
||||
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
static int xf_cliprdr_format_html_from_wire(BYTE* pSrcData, int SrcSize, BYTE** ppDstData)
|
||||
{
|
||||
int start;
|
||||
@@ -336,83 +291,6 @@ static int xf_cliprdr_format_html_from_wire(BYTE* pSrcData, int SrcSize, BYTE**
|
||||
return DstSize;
|
||||
}
|
||||
|
||||
static BYTE* xf_cliprdr_format_html_to_wire(BYTE* data, int* size)
|
||||
{
|
||||
char* inbuf;
|
||||
BYTE* in;
|
||||
BYTE* outbuf;
|
||||
char num[11];
|
||||
|
||||
inbuf = NULL;
|
||||
|
||||
if (*size > 2)
|
||||
{
|
||||
BYTE bom[2];
|
||||
|
||||
CopyMemory(bom, data, 2);
|
||||
|
||||
if ((bom[0] == 0xFE) && (bom[1] == 0xFF))
|
||||
{
|
||||
ByteSwapUnicode((WCHAR*) data, *size / 2);
|
||||
}
|
||||
|
||||
if ((bom[0] == 0xFF) && (bom[1] == 0xFE))
|
||||
{
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) (data + 2),
|
||||
(*size - 2) / 2, &inbuf, 0, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!inbuf)
|
||||
{
|
||||
inbuf = calloc(1, *size + 1);
|
||||
CopyMemory(inbuf, data, *size);
|
||||
}
|
||||
|
||||
outbuf = (BYTE*) calloc(1, *size + 200);
|
||||
|
||||
strcpy((char*) outbuf,
|
||||
"Version:0.9\r\n"
|
||||
"StartHTML:0000000000\r\n"
|
||||
"EndHTML:0000000000\r\n"
|
||||
"StartFragment:0000000000\r\n"
|
||||
"EndFragment:0000000000\r\n");
|
||||
|
||||
in = (BYTE*) strstr((char*) inbuf, "<body");
|
||||
|
||||
if (!in)
|
||||
in = (BYTE*) strstr((char*) inbuf, "<BODY");
|
||||
|
||||
/* StartHTML */
|
||||
snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf));
|
||||
CopyMemory(outbuf + 23, num, 10);
|
||||
|
||||
if (!in)
|
||||
strcat((char*) outbuf, "<HTML><BODY>");
|
||||
|
||||
strcat((char*) outbuf, "<!--StartFragment-->");
|
||||
/* StartFragment */
|
||||
snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf));
|
||||
CopyMemory(outbuf + 69, num, 10);
|
||||
strcat((char*) outbuf, (char*) inbuf);
|
||||
/* EndFragment */
|
||||
snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf));
|
||||
CopyMemory(outbuf + 93, num, 10);
|
||||
strcat((char*) outbuf, "<!--EndFragment-->");
|
||||
|
||||
if (!in)
|
||||
strcat((char*) outbuf, "</BODY></HTML>");
|
||||
|
||||
/* EndHTML */
|
||||
snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf));
|
||||
CopyMemory(outbuf + 43, num, 10);
|
||||
|
||||
*size = strlen((char*) outbuf) + 1;
|
||||
free(inbuf);
|
||||
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
static void xf_cliprdr_send_data_request(xfClipboard* clipboard, UINT32 formatId)
|
||||
{
|
||||
CLIPRDR_FORMAT_DATA_REQUEST request;
|
||||
@@ -487,62 +365,108 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||
free(formats);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL has_data, BYTE* data, int size)
|
||||
static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasData, BYTE* data, int size)
|
||||
{
|
||||
BYTE* outbuf;
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
BOOL bSuccess;
|
||||
UINT32 SrcSize;
|
||||
UINT32 DstSize;
|
||||
UINT32 formatId;
|
||||
UINT32 altFormatId;
|
||||
UINT32* pFormatIds;
|
||||
const char* formatName;
|
||||
BYTE* pSrcData = NULL;
|
||||
BYTE* pDstData = NULL;
|
||||
xfCliprdrFormat* format;
|
||||
|
||||
if (clipboard->incr_starts && has_data)
|
||||
if (clipboard->incr_starts && hasData)
|
||||
return;
|
||||
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (!has_data || !data || !format)
|
||||
if (!hasData || !data || !format)
|
||||
{
|
||||
xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
formatId = 0;
|
||||
altFormatId = 0;
|
||||
|
||||
switch (format->formatId)
|
||||
{
|
||||
case 0:
|
||||
case CB_FORMAT_PNG:
|
||||
case CB_FORMAT_JPEG:
|
||||
case CB_FORMAT_GIF:
|
||||
outbuf = xf_cliprdr_format_raw_to_wire(data, &size);
|
||||
break;
|
||||
|
||||
case CF_TEXT:
|
||||
outbuf = xf_cliprdr_format_text_to_wire(data, &size);
|
||||
break;
|
||||
|
||||
case CF_UNICODETEXT:
|
||||
outbuf = xf_cliprdr_format_unicode_text_to_wire(data, &size);
|
||||
formatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
|
||||
break;
|
||||
|
||||
case CF_DIB:
|
||||
outbuf = xf_cliprdr_format_dib_to_wire(data, &size);
|
||||
formatId = ClipboardGetFormatId(clipboard->system, "image/bmp");
|
||||
break;
|
||||
|
||||
case CB_FORMAT_HTML:
|
||||
outbuf = xf_cliprdr_format_html_to_wire(data, &size);
|
||||
break;
|
||||
|
||||
default:
|
||||
outbuf = NULL;
|
||||
formatId = ClipboardGetFormatId(clipboard->system, "text/html");
|
||||
break;
|
||||
}
|
||||
|
||||
if (outbuf)
|
||||
xf_cliprdr_send_data_response(clipboard, outbuf, size);
|
||||
else
|
||||
xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
SrcSize = (UINT32) size;
|
||||
pSrcData = (BYTE*) malloc(SrcSize);
|
||||
|
||||
if (!clipboard->xfixes_supported)
|
||||
if (!pSrcData)
|
||||
return;
|
||||
|
||||
CopyMemory(pSrcData, data, SrcSize);
|
||||
|
||||
bSuccess = ClipboardSetData(clipboard->system, formatId, (void*) pSrcData, SrcSize);
|
||||
|
||||
pFormatIds = NULL;
|
||||
count = ClipboardGetFormatIds(clipboard->system, &pFormatIds);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
/* Resend the format list, otherwise the server won't request again for the next paste */
|
||||
xf_cliprdr_send_client_format_list(clipboard);
|
||||
formatId = pFormatIds[index];
|
||||
formatName = ClipboardGetFormatName(clipboard->system, formatId);
|
||||
|
||||
if (formatId < CF_MAX)
|
||||
{
|
||||
switch (formatId)
|
||||
{
|
||||
case CF_TEXT:
|
||||
altFormatId = CF_TEXT;
|
||||
break;
|
||||
|
||||
case CF_UNICODETEXT:
|
||||
altFormatId = CF_UNICODETEXT;
|
||||
break;
|
||||
|
||||
case CF_DIB:
|
||||
altFormatId = CF_DIB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (strcmp(formatName, "HTML Format") == 0)
|
||||
{
|
||||
altFormatId = formatId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(pFormatIds);
|
||||
|
||||
if (bSuccess && altFormatId)
|
||||
{
|
||||
DstSize = 0;
|
||||
pDstData = (BYTE*) ClipboardGetData(clipboard->system, altFormatId, &DstSize);
|
||||
}
|
||||
|
||||
if (!pDstData)
|
||||
{
|
||||
xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
xf_cliprdr_send_data_response(clipboard, pDstData, (int) DstSize);
|
||||
}
|
||||
|
||||
static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
||||
@@ -1207,6 +1131,8 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||
channels = ((rdpContext*) xfc)->channels;
|
||||
clipboard->channels = channels;
|
||||
|
||||
clipboard->system = ClipboardCreate();
|
||||
|
||||
clipboard->requestedFormatId = -1;
|
||||
|
||||
clipboard->root_window = DefaultRootWindow(xfc->display);
|
||||
@@ -1314,6 +1240,8 @@ void xf_clipboard_free(xfClipboard* clipboard)
|
||||
clipboard->serverFormats = NULL;
|
||||
}
|
||||
|
||||
ClipboardDestroy(clipboard->system);
|
||||
|
||||
free(clipboard->data);
|
||||
free(clipboard->respond);
|
||||
free(clipboard->incr_data);
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
|
||||
#include <freerdp/codec/mppc.h>
|
||||
|
||||
#define WINPR_PACK_PUSH
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct _XCRUSH_MATCH_INFO
|
||||
{
|
||||
@@ -68,8 +67,7 @@ struct _RDP61_COMPRESSED_DATA
|
||||
};
|
||||
typedef struct _RDP61_COMPRESSED_DATA RDP61_COMPRESSED_DATA;
|
||||
|
||||
#define WINPR_PACK_POP
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(pop)
|
||||
|
||||
struct _XCRUSH_CONTEXT
|
||||
{
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#define WINPR_PACK_PUSH
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct _WINPR_BITMAP_FILE_HEADER
|
||||
{
|
||||
@@ -62,8 +61,7 @@ struct _WINPR_BITMAP_CORE_HEADER
|
||||
};
|
||||
typedef struct _WINPR_BITMAP_CORE_HEADER WINPR_BITMAP_CORE_HEADER;
|
||||
|
||||
#define WINPR_PACK_POP
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(pop)
|
||||
|
||||
#define WINPR_IMAGE_BITMAP 0
|
||||
#define WINPR_IMAGE_PNG 1
|
||||
|
||||
@@ -227,8 +227,7 @@
|
||||
#define SCARD_NEGOTIABLE 5
|
||||
#define SCARD_SPECIFIC 6
|
||||
|
||||
#define WINPR_PACK_PUSH
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct _SCARD_IO_REQUEST
|
||||
{
|
||||
@@ -554,8 +553,7 @@ typedef struct
|
||||
SCARDHANDLE hCardHandle;
|
||||
} OPENCARDNAMEW, *POPENCARDNAMEW, *LPOPENCARDNAMEW;
|
||||
|
||||
#define WINPR_PACK_POP
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef UNICODE
|
||||
#define LPOCNCONNPROC LPOCNCONNPROCW
|
||||
|
||||
@@ -68,8 +68,7 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#define WINPR_PACK_PUSH
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef LONG FXPT16DOT16, FAR *LPFXPT16DOT16;
|
||||
typedef LONG FXPT2DOT30, FAR *LPFXPT2DOT30;
|
||||
@@ -227,8 +226,7 @@ typedef struct tagBITMAPFILEHEADER
|
||||
DWORD bfOffBits;
|
||||
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
|
||||
|
||||
#define WINPR_PACK_POP
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -402,8 +402,9 @@ void* ClipboardGetData(wClipboard* clipboard, UINT32 formatId, UINT32* pSize)
|
||||
return NULL;
|
||||
|
||||
DstSize = SrcSize;
|
||||
|
||||
pDstData = synthesizer->pfnSynthesize(clipboard, format->formatId, pSrcData, &DstSize);
|
||||
|
||||
*pSize = DstSize;
|
||||
}
|
||||
|
||||
return pDstData;
|
||||
|
||||
@@ -30,29 +30,6 @@
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/ff729168/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Synthesized Clipboard Formats
|
||||
*
|
||||
* Clipboard Format Conversion Format
|
||||
*
|
||||
* CF_BITMAP CF_DIB
|
||||
* CF_BITMAP CF_DIBV5
|
||||
* CF_DIB CF_BITMAP
|
||||
* CF_DIB CF_PALETTE
|
||||
* CF_DIB CF_DIBV5
|
||||
* CF_DIBV5 CF_BITMAP
|
||||
* CF_DIBV5 CF_DIB
|
||||
* CF_DIBV5 CF_PALETTE
|
||||
* CF_ENHMETAFILE CF_METAFILEPICT
|
||||
* CF_METAFILEPICT CF_ENHMETAFILE
|
||||
* CF_OEMTEXT CF_TEXT
|
||||
* CF_OEMTEXT CF_UNICODETEXT
|
||||
* CF_TEXT CF_OEMTEXT
|
||||
* CF_TEXT CF_UNICODETEXT
|
||||
* CF_UNICODETEXT CF_OEMTEXT
|
||||
* CF_UNICODETEXT CF_TEXT
|
||||
*/
|
||||
|
||||
/**
|
||||
* "CF_TEXT":
|
||||
*
|
||||
@@ -302,6 +279,9 @@ static void* clipboard_synthesize_image_bmp(wClipboard* clipboard, UINT32 format
|
||||
BITMAPINFOHEADER* pInfoHeader;
|
||||
BITMAPFILEHEADER* pFileHeader;
|
||||
|
||||
if (SrcSize < sizeof(BITMAPINFOHEADER))
|
||||
return NULL;
|
||||
|
||||
pInfoHeader = (BITMAPINFOHEADER*) data;
|
||||
|
||||
if ((pInfoHeader->biBitCount < 1) || (pInfoHeader->biBitCount > 32))
|
||||
|
||||
@@ -78,8 +78,7 @@ typedef long PCSC_LONG;
|
||||
#define PCSC_SCARD_CTL_CODE(code) (0x42000000 + (code))
|
||||
#define PCSC_CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
|
||||
|
||||
#define WINPR_PACK_PUSH
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -105,8 +104,7 @@ typedef struct
|
||||
UINT32 value;
|
||||
} PCSC_TLV_STRUCTURE;
|
||||
|
||||
#define WINPR_PACK_POP
|
||||
#include <winpr/pack.h>
|
||||
#pragma pack(pop)
|
||||
|
||||
struct _PCSCFunctionTable
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user