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 & CAPS_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 { int k; for (k = 0; k < event->raw_format_data_size / 36; k++) { formatMapping *map; int name_len; 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 (!OpenClipboard(cliprdr->hwndClipboard)) { DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError()); return; } if (!EmptyClipboard()) { DEBUG_CLIPRDR("EmptyClipboard failed with 0x%x", GetLastError()); CloseClipboard(); return; } for (i = 0; i < cliprdr->map_size; i++) { SetClipboardData(cliprdr->format_mappings[i].local_format_id, NULL); } CloseClipboard(); }
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; }