HRESULT WINAPI OleQueryCreateFromData(IDataObject *data) { IEnumFORMATETC *enum_fmt; FORMATETC fmt; BOOL found_static = FALSE; HRESULT hr; hr = IDataObject_EnumFormatEtc(data, DATADIR_GET, &enum_fmt); if(FAILED(hr)) return hr; do { hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL); if(hr == S_OK) { if(fmt.cfFormat == embedded_object_clipboard_format || fmt.cfFormat == embed_source_clipboard_format || fmt.cfFormat == filename_clipboard_format) { IEnumFORMATETC_Release(enum_fmt); return S_OK; } if(fmt.cfFormat == CF_METAFILEPICT || fmt.cfFormat == CF_BITMAP || fmt.cfFormat == CF_DIB) found_static = TRUE; } } while (hr == S_OK); IEnumFORMATETC_Release(enum_fmt); return found_static ? OLE_S_STATIC : S_FALSE; }
static DWORD init_pastelist(HWND hdlg, OLEUIPASTESPECIALW *ps) { IEnumFORMATETC *penum; HRESULT hr; FORMATETC fmts[20]; DWORD fetched, items_added = 0; hr = IDataObject_EnumFormatEtc(ps->lpSrcDataObj, DATADIR_GET, &penum); if(FAILED(hr)) { WARN("Unable to create IEnumFORMATETC\n"); return 0; } /* The native version grabs only the first 20 fmts and we do the same */ hr = IEnumFORMATETC_Next(penum, sizeof(fmts)/sizeof(fmts[0]), fmts, &fetched); TRACE("got %d formats hr %08x\n", fetched, hr); if(SUCCEEDED(hr)) { DWORD src_fmt, req_fmt; for(req_fmt = 0; req_fmt < ps->cPasteEntries; req_fmt++) { /* This is used by update_structure() to set nSelectedIndex on exit */ ps->arrPasteEntries[req_fmt].dwScratchSpace = req_fmt; TRACE("req_fmt %x\n", ps->arrPasteEntries[req_fmt].fmtetc.cfFormat); for(src_fmt = 0; src_fmt < fetched; src_fmt++) { TRACE("\tenum'ed fmt %x\n", fmts[src_fmt].cfFormat); if(ps->arrPasteEntries[req_fmt].fmtetc.cfFormat == fmts[src_fmt].cfFormat) { add_entry_to_lb(hdlg, IDC_PS_PASTELIST, ps->arrPasteEntries + req_fmt); items_added++; break; } } } } IEnumFORMATETC_Release(penum); EnableWindow(GetDlgItem(hdlg, IDC_PS_PASTE), items_added ? TRUE : FALSE); return items_added; }
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; }
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; }