FreeRDP
synthetic.c
1 
20 #include <winpr/config.h>
21 
22 #include <errno.h>
23 #include <winpr/crt.h>
24 #include <winpr/user.h>
25 #include <winpr/image.h>
26 
27 #include "../utils/image.h"
28 #include "clipboard.h"
29 
30 static const char* mime_bitmap[] = { "image/bmp", "image/x-bmp", "image/x-MS-bmp",
31  "image/x-win-bitmap" };
32 
33 #if defined(WINPR_UTILS_IMAGE_WEBP)
34 static const char mime_webp[] = "image/webp";
35 #endif
36 #if defined(WINPR_UTILS_IMAGE_PNG)
37 static const char mime_png[] = "image/png";
38 #endif
39 #if defined(WINPR_UTILS_IMAGE_JPEG)
40 static const char mime_jpeg[] = "image/jpeg";
41 #endif
53 static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId, const void* data,
54  UINT32* pSize)
55 {
56  size_t size = 0;
57  char* pDstData = NULL;
58 
59  if (formatId == CF_UNICODETEXT)
60  {
61  char* str = ConvertWCharNToUtf8Alloc(data, *pSize / sizeof(WCHAR), &size);
62 
63  if (!str || (size > UINT32_MAX))
64  {
65  free(str);
66  return NULL;
67  }
68 
69  pDstData = ConvertLineEndingToCRLF(str, &size);
70  free(str);
71  *pSize = (UINT32)size;
72  return pDstData;
73  }
74  else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
75  (formatId == ClipboardGetFormatId(clipboard, mime_text_plain)))
76  {
77  size = *pSize;
78  pDstData = ConvertLineEndingToCRLF(data, &size);
79 
80  if (!pDstData || (size > *pSize))
81  {
82  free(pDstData);
83  return NULL;
84  }
85 
86  *pSize = (UINT32)size;
87  return pDstData;
88  }
89 
90  return NULL;
91 }
92 
99 static void* clipboard_synthesize_cf_oemtext(wClipboard* clipboard, UINT32 formatId,
100  const void* data, UINT32* pSize)
101 {
102  return clipboard_synthesize_cf_text(clipboard, formatId, data, pSize);
103 }
104 
111 static void* clipboard_synthesize_cf_locale(wClipboard* clipboard, UINT32 formatId,
112  const void* data, UINT32* pSize)
113 {
114  UINT32* pDstData = NULL;
115  pDstData = (UINT32*)malloc(sizeof(UINT32));
116 
117  if (!pDstData)
118  return NULL;
119 
120  *pDstData = 0x0409; /* English - United States */
121  return (void*)pDstData;
122 }
123 
130 static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 formatId,
131  const void* data, UINT32* pSize)
132 {
133  size_t size = 0;
134  char* crlfStr = NULL;
135  WCHAR* pDstData = NULL;
136 
137  if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
138  (formatId == ClipboardGetFormatId(clipboard, mime_text_plain)))
139  {
140  size_t len = 0;
141  if (!pSize || (*pSize > INT32_MAX))
142  return NULL;
143 
144  size = *pSize;
145  crlfStr = ConvertLineEndingToCRLF((const char*)data, &size);
146 
147  if (!crlfStr)
148  return NULL;
149 
150  pDstData = ConvertUtf8NToWCharAlloc(crlfStr, size, &len);
151  free(crlfStr);
152 
153  if ((len < 1) || ((len + 1) > UINT32_MAX / sizeof(WCHAR)))
154  {
155  free(pDstData);
156  return NULL;
157  }
158 
159  const size_t slen = (len + 1) * sizeof(WCHAR);
160  *pSize = (UINT32)slen;
161  }
162 
163  return (void*)pDstData;
164 }
165 
172 static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 formatId,
173  const void* data, UINT32* pSize)
174 {
175  if (formatId == CF_UNICODETEXT)
176  {
177  size_t size = 0;
178  char* pDstData = ConvertWCharNToUtf8Alloc(data, *pSize / sizeof(WCHAR), &size);
179 
180  if (!pDstData)
181  return NULL;
182 
183  const size_t rc = ConvertLineEndingToLF(pDstData, size);
184  WINPR_ASSERT(rc <= UINT32_MAX);
185  *pSize = (UINT32)rc;
186  return pDstData;
187  }
188  else if ((formatId == CF_TEXT) || (formatId == CF_OEMTEXT) ||
189  (formatId == ClipboardGetFormatId(clipboard, mime_text_plain)))
190  {
191  const size_t size = *pSize;
192  char* pDstData = calloc(size + 1, sizeof(char));
193 
194  if (!pDstData)
195  return NULL;
196 
197  CopyMemory(pDstData, data, size);
198  const size_t rc = ConvertLineEndingToLF(pDstData, size);
199  WINPR_ASSERT(rc <= UINT32_MAX);
200  *pSize = (UINT32)rc;
201  return pDstData;
202  }
203 
204  return NULL;
205 }
206 
207 static BOOL is_format_bitmap(wClipboard* clipboard, UINT32 formatId)
208 {
209  for (size_t x = 0; x < ARRAYSIZE(mime_bitmap); x++)
210  {
211  const char* mime = mime_bitmap[x];
212  const UINT32 altFormatId = ClipboardGetFormatId(clipboard, mime);
213  if (altFormatId == formatId)
214  return TRUE;
215  }
216 
217  return FALSE;
218 }
219 
226 static void* clipboard_synthesize_cf_dib(wClipboard* clipboard, UINT32 formatId, const void* data,
227  UINT32* pSize)
228 {
229  UINT32 SrcSize = 0;
230  UINT32 DstSize = 0;
231  BYTE* pDstData = NULL;
232  SrcSize = *pSize;
233 
234  if (formatId == CF_DIBV5)
235  {
236  }
237  else if (is_format_bitmap(clipboard, formatId))
238  {
239  WINPR_BITMAP_FILE_HEADER pFileHeader = { 0 };
240  wStream sbuffer = { 0 };
241  wStream* s = Stream_StaticConstInit(&sbuffer, data, SrcSize);
242  if (!readBitmapFileHeader(s, &pFileHeader))
243  return NULL;
244 
245  DstSize = SrcSize - sizeof(BITMAPFILEHEADER);
246  pDstData = (BYTE*)malloc(DstSize);
247 
248  if (!pDstData)
249  return NULL;
250 
251  data = (const void*)&((const BYTE*)data)[sizeof(BITMAPFILEHEADER)];
252  CopyMemory(pDstData, data, DstSize);
253  *pSize = DstSize;
254  return pDstData;
255  }
256 
257  return NULL;
258 }
259 
266 static void* clipboard_synthesize_cf_dibv5(wClipboard* clipboard, UINT32 formatId, const void* data,
267  UINT32* pSize)
268 {
269  if (formatId == CF_DIB)
270  {
271  }
272  else if (is_format_bitmap(clipboard, formatId))
273  {
274  }
275 
276  return NULL;
277 }
278 
279 static void* clipboard_prepend_bmp_header(const WINPR_BITMAP_INFO_HEADER* pInfoHeader,
280  const void* data, size_t size, UINT32* pSize)
281 {
282  WINPR_ASSERT(pInfoHeader);
283  WINPR_ASSERT(pSize);
284 
285  *pSize = 0;
286  if ((pInfoHeader->biBitCount < 1) || (pInfoHeader->biBitCount > 32))
287  return NULL;
288 
289  const size_t DstSize = sizeof(WINPR_BITMAP_FILE_HEADER) + size;
290  if (DstSize > UINT32_MAX)
291  return NULL;
292 
293  wStream* s = Stream_New(NULL, DstSize);
294  if (!s)
295  return NULL;
296 
297  WINPR_BITMAP_FILE_HEADER fileHeader = { 0 };
298  fileHeader.bfType[0] = 'B';
299  fileHeader.bfType[1] = 'M';
300  fileHeader.bfSize = (UINT32)DstSize;
301  fileHeader.bfOffBits = sizeof(WINPR_BITMAP_FILE_HEADER) + sizeof(WINPR_BITMAP_INFO_HEADER);
302  if (!writeBitmapFileHeader(s, &fileHeader))
303  goto fail;
304 
305  if (!Stream_EnsureRemainingCapacity(s, size))
306  goto fail;
307  Stream_Write(s, data, size);
308  const size_t len = Stream_GetPosition(s);
309  if (len != DstSize)
310  goto fail;
311  *pSize = (UINT32)DstSize;
312 
313  BYTE* dst = Stream_Buffer(s);
314  Stream_Free(s, FALSE);
315  return dst;
316 
317 fail:
318  Stream_Free(s, TRUE);
319  return NULL;
320 }
321 
328 static void* clipboard_synthesize_image_bmp(wClipboard* clipboard, UINT32 formatId,
329  const void* data, UINT32* pSize)
330 {
331  UINT32 SrcSize = *pSize;
332 
333  if (formatId == CF_DIB)
334  {
335  if (SrcSize < sizeof(BITMAPINFOHEADER))
336  return NULL;
337 
338  wStream sbuffer = { 0 };
339  size_t offset = 0;
340  WINPR_BITMAP_INFO_HEADER header = { 0 };
341  wStream* s = Stream_StaticConstInit(&sbuffer, data, SrcSize);
342  if (!readBitmapInfoHeader(s, &header, &offset))
343  return NULL;
344 
345  return clipboard_prepend_bmp_header(&header, data, SrcSize, pSize);
346  }
347  else if (formatId == CF_DIBV5)
348  {
349  }
350 
351  return NULL;
352 }
353 
354 #if defined(WINPR_UTILS_IMAGE_PNG) || defined(WINPR_UTILS_IMAGE_WEBP) || \
355  defined(WINPR_UTILS_IMAGE_JPEG)
356 static void* clipboard_synthesize_image_bmp_to_format(wClipboard* clipboard, UINT32 formatId,
357  UINT32 bmpFormat, const void* data,
358  UINT32* pSize)
359 {
360  WINPR_ASSERT(clipboard);
361  WINPR_ASSERT(data);
362  WINPR_ASSERT(pSize);
363 
364  size_t dsize = 0;
365  void* result = NULL;
366 
367  wImage* img = winpr_image_new();
368  void* bmp = clipboard_synthesize_image_bmp(clipboard, formatId, data, pSize);
369  const UINT32 SrcSize = *pSize;
370  *pSize = 0;
371 
372  if (!bmp || !img)
373  goto fail;
374 
375  if (winpr_image_read_buffer(img, bmp, SrcSize) <= 0)
376  goto fail;
377 
378  result = winpr_image_write_buffer(img, bmpFormat, &dsize);
379  if (result)
380  {
381  if (dsize <= UINT32_MAX)
382  *pSize = (UINT32)dsize;
383  else
384  {
385  free(result);
386  result = NULL;
387  }
388  }
389 
390 fail:
391  free(bmp);
392  winpr_image_free(img, TRUE);
393  return result;
394 }
395 #endif
396 
397 #if defined(WINPR_UTILS_IMAGE_PNG)
398 static void* clipboard_synthesize_image_bmp_to_png(wClipboard* clipboard, UINT32 formatId,
399  const void* data, UINT32* pSize)
400 {
401  return clipboard_synthesize_image_bmp_to_format(clipboard, formatId, WINPR_IMAGE_PNG, data,
402  pSize);
403 }
404 
405 static void* clipboard_synthesize_image_format_to_bmp(wClipboard* clipboard, UINT32 srcFormatId,
406  const void* data, UINT32* pSize)
407 {
408  WINPR_ASSERT(clipboard);
409  WINPR_ASSERT(data);
410  WINPR_ASSERT(pSize);
411 
412  BYTE* dst = NULL;
413  const UINT32 SrcSize = *pSize;
414  size_t size = 0;
415  wImage* image = winpr_image_new();
416  if (!image)
417  goto fail;
418 
419  const int res = winpr_image_read_buffer(image, data, SrcSize);
420  if (res <= 0)
421  goto fail;
422 
423  dst = winpr_image_write_buffer(image, WINPR_IMAGE_BITMAP, &size);
424  if ((size < sizeof(WINPR_BITMAP_FILE_HEADER)) || (size > UINT32_MAX))
425  {
426  free(dst);
427  dst = NULL;
428  goto fail;
429  }
430  *pSize = (UINT32)size;
431 
432 fail:
433  winpr_image_free(image, TRUE);
434 
435  if (dst)
436  memmove(dst, &dst[sizeof(WINPR_BITMAP_FILE_HEADER)],
437  size - sizeof(WINPR_BITMAP_FILE_HEADER));
438  return dst;
439 }
440 
441 static void* clipboard_synthesize_image_png_to_bmp(wClipboard* clipboard, UINT32 formatId,
442  const void* data, UINT32* pSize)
443 {
444  return clipboard_synthesize_image_format_to_bmp(clipboard, formatId, data, pSize);
445 }
446 #endif
447 
448 #if defined(WINPR_UTILS_IMAGE_WEBP)
449 static void* clipboard_synthesize_image_bmp_to_webp(wClipboard* clipboard, UINT32 formatId,
450  const void* data, UINT32* pSize)
451 {
452  return clipboard_synthesize_image_bmp_to_format(clipboard, formatId, WINPR_IMAGE_WEBP, data,
453  pSize);
454 }
455 
456 static void* clipboard_synthesize_image_webp_to_bmp(wClipboard* clipboard, UINT32 formatId,
457  const void* data, UINT32* pSize)
458 {
459  return clipboard_synthesize_image_format_to_bmp(clipboard, formatId, data, pSize);
460 }
461 #endif
462 
463 #if defined(WINPR_UTILS_IMAGE_JPEG)
464 static void* clipboard_synthesize_image_bmp_to_jpeg(wClipboard* clipboard, UINT32 formatId,
465  const void* data, UINT32* pSize)
466 {
467  return clipboard_synthesize_image_bmp_to_format(clipboard, formatId, WINPR_IMAGE_JPEG, data,
468  pSize);
469 }
470 
471 static void* clipboard_synthesize_image_jpeg_to_bmp(wClipboard* clipboard, UINT32 formatId,
472  const void* data, UINT32* pSize)
473 {
474  return clipboard_synthesize_image_format_to_bmp(clipboard, formatId, data, pSize);
475 }
476 #endif
477 
484 static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 formatId,
485  const void* pData, UINT32* pSize)
486 {
487  union
488  {
489  const void* cpv;
490  const char* cpc;
491  const BYTE* cpb;
492  WCHAR* pv;
493  } pSrcData;
494  char* pDstData = NULL;
495 
496  pSrcData.cpv = NULL;
497 
498  WINPR_ASSERT(clipboard);
499  WINPR_ASSERT(pSize);
500 
501  if (formatId == ClipboardGetFormatId(clipboard, "text/html"))
502  {
503  const size_t SrcSize = (size_t)*pSize;
504  const size_t DstSize = SrcSize + 200;
505  char* body = NULL;
506  char num[20] = { 0 };
507 
508  /* Create a copy, we modify the input data */
509  pSrcData.pv = calloc(1, SrcSize + 1);
510  if (!pSrcData.pv)
511  goto fail;
512  memcpy(pSrcData.pv, pData, SrcSize);
513 
514  if (SrcSize > 2)
515  {
516  if (SrcSize > INT_MAX)
517  goto fail;
518 
519  /* Check the BOM (Byte Order Mark) */
520  if ((pSrcData.cpb[0] == 0xFE) && (pSrcData.cpb[1] == 0xFF))
521  ByteSwapUnicode(pSrcData.pv, (SrcSize / 2));
522 
523  /* Check if we have WCHAR, convert to UTF-8 */
524  if ((pSrcData.cpb[0] == 0xFF) && (pSrcData.cpb[1] == 0xFE))
525  {
526  char* utfString =
527  ConvertWCharNToUtf8Alloc(&pSrcData.pv[1], SrcSize / sizeof(WCHAR), NULL);
528  free(pSrcData.pv);
529  pSrcData.cpc = utfString;
530  if (!utfString)
531  goto fail;
532  }
533  }
534 
535  pDstData = (char*)calloc(1, DstSize);
536 
537  if (!pDstData)
538  goto fail;
539 
540  (void)sprintf_s(pDstData, DstSize,
541  "Version:0.9\r\n"
542  "StartHTML:0000000000\r\n"
543  "EndHTML:0000000000\r\n"
544  "StartFragment:0000000000\r\n"
545  "EndFragment:0000000000\r\n");
546  body = strstr(pSrcData.cpc, "<body");
547 
548  if (!body)
549  body = strstr(pSrcData.cpc, "<BODY");
550 
551  /* StartHTML */
552  (void)sprintf_s(num, sizeof(num), "%010" PRIuz "", strnlen(pDstData, DstSize));
553  CopyMemory(&pDstData[23], num, 10);
554 
555  if (!body)
556  {
557  if (!winpr_str_append("<HTML><BODY>", pDstData, DstSize, NULL))
558  goto fail;
559  }
560 
561  if (!winpr_str_append("<!--StartFragment-->", pDstData, DstSize, NULL))
562  goto fail;
563 
564  /* StartFragment */
565  (void)sprintf_s(num, sizeof(num), "%010" PRIuz "", strnlen(pDstData, SrcSize + 200));
566  CopyMemory(&pDstData[69], num, 10);
567 
568  if (!winpr_str_append(pSrcData.cpc, pDstData, DstSize, NULL))
569  goto fail;
570 
571  /* EndFragment */
572  (void)sprintf_s(num, sizeof(num), "%010" PRIuz "", strnlen(pDstData, SrcSize + 200));
573  CopyMemory(&pDstData[93], num, 10);
574 
575  if (!winpr_str_append("<!--EndFragment-->", pDstData, DstSize, NULL))
576  goto fail;
577 
578  if (!body)
579  {
580  if (!winpr_str_append("</BODY></HTML>", pDstData, DstSize, NULL))
581  goto fail;
582  }
583 
584  /* EndHTML */
585  (void)sprintf_s(num, sizeof(num), "%010" PRIuz "", strnlen(pDstData, DstSize));
586  CopyMemory(&pDstData[43], num, 10);
587  *pSize = (UINT32)strnlen(pDstData, DstSize) + 1;
588  }
589 fail:
590  free(pSrcData.pv);
591  return pDstData;
592 }
593 
600 static void* clipboard_synthesize_text_html(wClipboard* clipboard, UINT32 formatId,
601  const void* data, UINT32* pSize)
602 {
603  char* pDstData = NULL;
604 
605  if (formatId == ClipboardGetFormatId(clipboard, "HTML Format"))
606  {
607  const char* str = (const char*)data;
608  const size_t SrcSize = *pSize;
609  const char* begStr = strstr(str, "StartHTML:");
610  const char* endStr = strstr(str, "EndHTML:");
611 
612  if (!begStr || !endStr)
613  return NULL;
614 
615  errno = 0;
616  const long beg = strtol(&begStr[10], NULL, 10);
617 
618  if (errno != 0)
619  return NULL;
620 
621  const long end = strtol(&endStr[8], NULL, 10);
622 
623  if ((beg < 0) || (end < 0) || ((size_t)beg > SrcSize) || ((size_t)end > SrcSize) ||
624  (beg >= end) || (errno != 0))
625  return NULL;
626 
627  const size_t DstSize = (size_t)(end - beg);
628  pDstData = calloc(DstSize + 1, sizeof(char));
629 
630  if (!pDstData)
631  return NULL;
632 
633  CopyMemory(pDstData, &str[beg], DstSize);
634  const size_t rc = ConvertLineEndingToLF(pDstData, DstSize);
635  WINPR_ASSERT(rc <= UINT32_MAX);
636  *pSize = (UINT32)rc;
637  }
638 
639  return pDstData;
640 }
641 
642 BOOL ClipboardInitSynthesizers(wClipboard* clipboard)
643 {
647  {
648  ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_OEMTEXT,
649  clipboard_synthesize_cf_oemtext);
650  ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_UNICODETEXT,
651  clipboard_synthesize_cf_unicodetext);
652  ClipboardRegisterSynthesizer(clipboard, CF_TEXT, CF_LOCALE, clipboard_synthesize_cf_locale);
653 
654  UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
655  ClipboardRegisterSynthesizer(clipboard, CF_TEXT, altFormatId,
656  clipboard_synthesize_utf8_string);
657  }
661  {
662  ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_TEXT, clipboard_synthesize_cf_text);
663  ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_UNICODETEXT,
664  clipboard_synthesize_cf_unicodetext);
665  ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, CF_LOCALE,
666  clipboard_synthesize_cf_locale);
667  UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
668  ClipboardRegisterSynthesizer(clipboard, CF_OEMTEXT, altFormatId,
669  clipboard_synthesize_utf8_string);
670  }
674  {
675  ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_TEXT,
676  clipboard_synthesize_cf_text);
677  ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_OEMTEXT,
678  clipboard_synthesize_cf_oemtext);
679  ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, CF_LOCALE,
680  clipboard_synthesize_cf_locale);
681  UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
682  ClipboardRegisterSynthesizer(clipboard, CF_UNICODETEXT, altFormatId,
683  clipboard_synthesize_utf8_string);
684  }
688  {
689  UINT32 formatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
690 
691  if (formatId)
692  {
693  ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT,
694  clipboard_synthesize_cf_text);
695  ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
696  clipboard_synthesize_cf_oemtext);
697  ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
698  clipboard_synthesize_cf_unicodetext);
699  ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
700  clipboard_synthesize_cf_locale);
701  }
702  }
706  {
707  UINT32 formatId = ClipboardRegisterFormat(clipboard, mime_text_plain);
708 
709  if (formatId)
710  {
711  ClipboardRegisterSynthesizer(clipboard, formatId, CF_TEXT,
712  clipboard_synthesize_cf_text);
713  ClipboardRegisterSynthesizer(clipboard, formatId, CF_OEMTEXT,
714  clipboard_synthesize_cf_oemtext);
715  ClipboardRegisterSynthesizer(clipboard, formatId, CF_UNICODETEXT,
716  clipboard_synthesize_cf_unicodetext);
717  ClipboardRegisterSynthesizer(clipboard, formatId, CF_LOCALE,
718  clipboard_synthesize_cf_locale);
719  }
720  }
724  {
725  ClipboardRegisterSynthesizer(clipboard, CF_DIB, CF_DIBV5, clipboard_synthesize_cf_dibv5);
726  for (size_t x = 0; x < ARRAYSIZE(mime_bitmap); x++)
727  {
728  const char* mime = mime_bitmap[x];
729  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime);
730  if (altFormatId == 0)
731  continue;
732  ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId,
733  clipboard_synthesize_image_bmp);
734  }
735  }
736 
741  if (0)
742  {
743  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, CF_DIB, clipboard_synthesize_cf_dib);
744 
745  for (size_t x = 0; x < ARRAYSIZE(mime_bitmap); x++)
746  {
747  const char* mime = mime_bitmap[x];
748  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime);
749  if (altFormatId == 0)
750  continue;
751  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId,
752  clipboard_synthesize_image_bmp);
753  }
754  }
755 
759  for (size_t x = 0; x < ARRAYSIZE(mime_bitmap); x++)
760  {
761  const char* mime = mime_bitmap[x];
762  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime);
763  if (altFormatId == 0)
764  continue;
765  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIB, clipboard_synthesize_cf_dib);
766  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIBV5,
767  clipboard_synthesize_cf_dibv5);
768  }
769 
773 #if defined(WINPR_UTILS_IMAGE_PNG)
774  {
775  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_png);
776  ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId,
777  clipboard_synthesize_image_bmp_to_png);
778  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId,
779  clipboard_synthesize_image_bmp_to_png);
780  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIB,
781  clipboard_synthesize_image_png_to_bmp);
782  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIBV5,
783  clipboard_synthesize_image_png_to_bmp);
784  }
785 #endif
786 
790 #if defined(WINPR_UTILS_IMAGE_WEBP)
791  {
792  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_webp);
793  ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId,
794  clipboard_synthesize_image_bmp_to_webp);
795  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId,
796  clipboard_synthesize_image_webp_to_bmp);
797  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIB,
798  clipboard_synthesize_image_bmp_to_webp);
799  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIBV5,
800  clipboard_synthesize_image_webp_to_bmp);
801  }
802 #endif
803 
807 #if defined(WINPR_UTILS_IMAGE_JPEG)
808  {
809  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, mime_jpeg);
810  ClipboardRegisterSynthesizer(clipboard, CF_DIB, altFormatId,
811  clipboard_synthesize_image_bmp_to_jpeg);
812  ClipboardRegisterSynthesizer(clipboard, CF_DIBV5, altFormatId,
813  clipboard_synthesize_image_jpeg_to_bmp);
814  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIB,
815  clipboard_synthesize_image_bmp_to_jpeg);
816  ClipboardRegisterSynthesizer(clipboard, altFormatId, CF_DIBV5,
817  clipboard_synthesize_image_jpeg_to_bmp);
818  }
819 #endif
820 
824  {
825  UINT32 formatId = ClipboardRegisterFormat(clipboard, "HTML Format");
826 
827  if (formatId)
828  {
829  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, "text/html");
830  ClipboardRegisterSynthesizer(clipboard, formatId, altFormatId,
831  clipboard_synthesize_text_html);
832  }
833  }
834 
838  {
839  UINT32 formatId = ClipboardRegisterFormat(clipboard, "text/html");
840 
841  if (formatId)
842  {
843  const UINT32 altFormatId = ClipboardRegisterFormat(clipboard, "HTML Format");
844  ClipboardRegisterSynthesizer(clipboard, formatId, altFormatId,
845  clipboard_synthesize_html_format);
846  }
847  }
848 
849  return TRUE;
850 }