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; }
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 & CB_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 { UINT32 k; for (k = 0; k < event->raw_format_data_size / 36; k++) { int name_len; formatMapping* map; 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 (file_transferring(cliprdr)) { PostMessage(cliprdr->hwndClipboard, WM_CLIPRDR_MESSAGE, OLE_SETCLIPBOARD, 0); } else { if (!OpenClipboard(cliprdr->hwndClipboard)) return; if (EmptyClipboard()) for (i = 0; i < cliprdr->map_size; i++) SetClipboardData(cliprdr->format_mappings[i].local_format_id, NULL); CloseClipboard(); } }