static void get_descriptors(HWND hdlg, ps_struct_t *ps_struct) { FORMATETC fmtetc; STGMEDIUM stg; fmtetc.tymed = TYMED_HGLOBAL; fmtetc.dwAspect = DVASPECT_CONTENT; fmtetc.ptd = NULL; fmtetc.lindex = -1; fmtetc.cfFormat = cf_object_descriptor; if(IDataObject_GetData(ps_struct->ps->lpSrcDataObj, &fmtetc, &stg) == S_OK) { OBJECTDESCRIPTOR *obj_desc = GlobalLock(stg.u.hGlobal); if(obj_desc->dwSrcOfCopy) ps_struct->source_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwSrcOfCopy)); if(obj_desc->dwFullUserTypeName) ps_struct->type_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwFullUserTypeName)); OleRegGetUserType(&obj_desc->clsid, USERCLASSTYPE_APPNAME, &ps_struct->app_name); /* Get the icon here. If dwDrawAspect & DVASCPECT_ICON call GetData(CF_METAFILEPICT), otherwise native calls OleGetIconFromClass(obj_desc->clsid) */ GlobalUnlock(stg.u.hGlobal); GlobalFree(stg.u.hGlobal); } else { /* Try to get some data using some of the other clipboard formats */ } fmtetc.cfFormat = cf_link_src_descriptor; if(IDataObject_GetData(ps_struct->ps->lpSrcDataObj, &fmtetc, &stg) == S_OK) { OBJECTDESCRIPTOR *obj_desc = GlobalLock(stg.u.hGlobal); if(obj_desc->dwSrcOfCopy) ps_struct->link_source_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwSrcOfCopy)); if(obj_desc->dwFullUserTypeName) ps_struct->link_type_name = strdupW((WCHAR*)((char*)obj_desc + obj_desc->dwFullUserTypeName)); GlobalUnlock(stg.u.hGlobal); GlobalFree(stg.u.hGlobal); } if(ps_struct->source_name == NULL && ps_struct->link_source_name == NULL) { WCHAR buf[200]; LoadStringW(OLEDLG_hInstance, IDS_PS_UNKNOWN_SRC, buf, sizeof(buf)/sizeof(WCHAR)); ps_struct->source_name = strdupW(buf); } if(ps_struct->type_name == NULL && ps_struct->link_type_name == NULL) { WCHAR buf[200]; LoadStringW(OLEDLG_hInstance, IDS_PS_UNKNOWN_TYPE, buf, sizeof(buf)/sizeof(WCHAR)); ps_struct->type_name = strdupW(buf); } }
HRESULT WINAPI SHCreateShellItemArrayFromDataObject(IDataObject *pdo, REFIID riid, void **ppv) { IShellItemArray *psia; FORMATETC fmt; STGMEDIUM medium; HRESULT ret; TRACE("%p, %s, %p\n", pdo, shdebugstr_guid(riid), ppv); if(!pdo) return E_INVALIDARG; *ppv = NULL; fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED_HGLOBAL; ret = IDataObject_GetData(pdo, &fmt, &medium); if(SUCCEEDED(ret)) { LPIDA pida = GlobalLock(medium.u.hGlobal); LPCITEMIDLIST parent_pidl; LPCITEMIDLIST *children; UINT i; TRACE("Converting %d objects.\n", pida->cidl); parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]); children = HeapAlloc(GetProcessHeap(), 0, sizeof(LPCITEMIDLIST)*pida->cidl); for(i = 0; i < pida->cidl; i++) children[i] = (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[i+1]); ret = SHCreateShellItemArray(parent_pidl, NULL, pida->cidl, children, &psia); HeapFree(GetProcessHeap(), 0, children); GlobalUnlock(medium.u.hGlobal); GlobalFree(medium.u.hGlobal); } if(SUCCEEDED(ret)) { ret = IShellItemArray_QueryInterface(psia, riid, ppv); IShellItemArray_Release(psia); } return ret; }
/****************************************************************************** * DataAdviseHolder_SendOnDataChange */ static HRESULT WINAPI DataAdviseHolder_SendOnDataChange( IDataAdviseHolder* iface, IDataObject* pDataObject, DWORD dwReserved, DWORD advf) { DataAdviseHolder *This = (DataAdviseHolder *)iface; DWORD index; STGMEDIUM stg; HRESULT res; TRACE("(%p)->(%p,%08x,%08x)\n", This, pDataObject, dwReserved, advf); for(index = 0; index < This->maxCons; index++) { if(This->Connections[index].sink != NULL) { memset(&stg, 0, sizeof(stg)); if(!(This->Connections[index].advf & ADVF_NODATA)) { TRACE("Calling IDataObject_GetData\n"); res = IDataObject_GetData(pDataObject, &(This->Connections[index].fmat), &stg); TRACE("returns %08x\n", res); } TRACE("Calling IAdviseSink_OnDataChange\n"); IAdviseSink_OnDataChange(This->Connections[index].sink, &(This->Connections[index].fmat), &stg); TRACE("Done IAdviseSink_OnDataChange\n"); if(This->Connections[index].advf & ADVF_ONLYONCE) { TRACE("Removing connection\n"); DataAdviseHolder_Unadvise(iface, index+1); } } } return S_OK; }
void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, ME_Paragraph *para, BOOL selected) { IDataObject* ido; FORMATETC fmt; STGMEDIUM stgm; DIBSECTION dibsect; ENHMETAHEADER emh; HDC hMemDC; SIZE sz; BOOL has_size; assert(run->nFlags & MERF_GRAPHICS); assert(run->ole_obj); if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK) { FIXME("Couldn't get interface\n"); return; } has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0; fmt.cfFormat = CF_BITMAP; fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED_GDI; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) { fmt.cfFormat = CF_ENHMETAFILE; fmt.tymed = TYMED_ENHMF; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) { FIXME("Couldn't get storage medium\n"); IDataObject_Release(ido); return; } } switch (stgm.tymed) { case TYMED_GDI: GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect); hMemDC = CreateCompatibleDC(c->hDC); SelectObject(hMemDC, stgm.u.hBitmap); if (has_size) { convert_sizel(c, &run->ole_obj->sizel, &sz); } else { sz.cx = MulDiv(dibsect.dsBm.bmWidth, c->dpi.cx, 96); sz.cy = MulDiv(dibsect.dsBm.bmHeight, c->dpi.cy, 96); } if (c->editor->nZoomNumerator != 0) { sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); } if (sz.cx == dibsect.dsBm.bmWidth && sz.cy == dibsect.dsBm.bmHeight) { BitBlt(c->hDC, x, y - sz.cy, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, hMemDC, 0, 0, SRCCOPY); } else { StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY); } DeleteDC(hMemDC); if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap); break; case TYMED_ENHMF: GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh); if (has_size) { convert_sizel(c, &run->ole_obj->sizel, &sz); } else { sz.cy = MulDiv(emh.rclBounds.bottom - emh.rclBounds.top, c->dpi.cx, 96); sz.cx = MulDiv(emh.rclBounds.right - emh.rclBounds.left, c->dpi.cy, 96); } if (c->editor->nZoomNumerator != 0) { sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); } { RECT rc; rc.left = x; rc.top = y - sz.cy; rc.right = x + sz.cx; rc.bottom = y; PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc); } if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile); break; default: FIXME("Unsupported tymed %d\n", stgm.tymed); selected = FALSE; break; } if (selected && !c->editor->bHideSelection) PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT); IDataObject_Release(ido); }
/****************************************************************************** * ME_GetOLEObjectSize * * Sets run extent for OLE objects. */ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) { IDataObject* ido; FORMATETC fmt; STGMEDIUM stgm; DIBSECTION dibsect; ENHMETAHEADER emh; assert(run->nFlags & MERF_GRAPHICS); assert(run->ole_obj); if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0) { convert_sizel(c, &run->ole_obj->sizel, pSize); if (c->editor->nZoomNumerator != 0) { pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); } return; } IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido); fmt.cfFormat = CF_BITMAP; fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED_GDI; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) { fmt.cfFormat = CF_ENHMETAFILE; fmt.tymed = TYMED_ENHMF; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) { FIXME("unsupported format\n"); pSize->cx = pSize->cy = 0; IDataObject_Release(ido); return; } } switch (stgm.tymed) { case TYMED_GDI: GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect); pSize->cx = dibsect.dsBm.bmWidth; pSize->cy = dibsect.dsBm.bmHeight; if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap); break; case TYMED_ENHMF: GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh); pSize->cx = emh.rclBounds.right - emh.rclBounds.left; pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top; if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile); break; default: FIXME("Unsupported tymed %d\n", stgm.tymed); break; } IDataObject_Release(ido); if (c->editor->nZoomNumerator != 0) { pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); } }
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 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; }
HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj, DATAOBJ_GET_ITEM_FLAGS dwFlags, REFIID riid, void **ppv) { FORMATETC fmt; STGMEDIUM medium; HRESULT ret; TRACE("%p, %x, %s, %p\n", pdtobj, dwFlags, debugstr_guid(riid), ppv); if(!pdtobj) return E_INVALIDARG; fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED_HGLOBAL; ret = IDataObject_GetData(pdtobj, &fmt, &medium); if(SUCCEEDED(ret)) { LPIDA pida = GlobalLock(medium.u.hGlobal); if((pida->cidl > 1 && !(dwFlags & DOGIF_ONLY_IF_ONE)) || pida->cidl == 1) { LPITEMIDLIST pidl; /* Get the first pidl (parent + child1) */ pidl = ILCombine((LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[0]), (LPCITEMIDLIST) ((LPBYTE)pida+pida->aoffset[1])); ret = SHCreateItemFromIDList(pidl, riid, ppv); ILFree(pidl); } else { ret = E_FAIL; } GlobalUnlock(medium.u.hGlobal); GlobalFree(medium.u.hGlobal); } if(FAILED(ret) && !(dwFlags & DOGIF_NO_HDROP)) { TRACE("Attempting to fall back on CF_HDROP.\n"); fmt.cfFormat = CF_HDROP; fmt.ptd = NULL; fmt.dwAspect = DVASPECT_CONTENT; fmt.lindex = -1; fmt.tymed = TYMED_HGLOBAL; ret = IDataObject_GetData(pdtobj, &fmt, &medium); if(SUCCEEDED(ret)) { DROPFILES *df = GlobalLock(medium.u.hGlobal); LPBYTE files = (LPBYTE)df + df->pFiles; BOOL multiple_files = FALSE; ret = E_FAIL; if(!df->fWide) { WCHAR filename[MAX_PATH]; PCSTR first_file = (PCSTR)files; if(*(files + lstrlenA(first_file) + 1) != 0) multiple_files = TRUE; if( !(multiple_files && (dwFlags & DOGIF_ONLY_IF_ONE)) ) { MultiByteToWideChar(CP_ACP, 0, first_file, -1, filename, MAX_PATH); ret = SHCreateItemFromParsingName(filename, NULL, riid, ppv); } } else { PCWSTR first_file = (PCWSTR)files; if(*((PCWSTR)files + lstrlenW(first_file) + 1) != 0) multiple_files = TRUE; if( !(multiple_files && (dwFlags & DOGIF_ONLY_IF_ONE)) ) ret = SHCreateItemFromParsingName(first_file, NULL, riid, ppv); } GlobalUnlock(medium.u.hGlobal); GlobalFree(medium.u.hGlobal); } } if(FAILED(ret) && !(dwFlags & DOGIF_NO_URL)) { FIXME("Failed to create item, should try CF_URL.\n"); } return ret; }
static void wf_cliprdr_process_cb_data_request_event(wfContext* wfc, RDP_CB_DATA_REQUEST_EVENT* event) { HANDLE hClipdata; int size = 0; char* buff = NULL; char* globlemem = NULL; UINT32 local_format; cliprdrContext* cliprdr = (cliprdrContext*) wfc->cliprdr_context; RDP_CB_DATA_RESPONSE_EVENT* response_event; local_format = event->format; if (local_format == FORMAT_ID_PALETTE) { /* TODO: implement this */ DEBUG_CLIPRDR("FORMAT_ID_PALETTE is not supported yet."); } else if (local_format == FORMAT_ID_METAFILE) { /* TODO: implement this */ DEBUG_CLIPRDR("FORMAT_ID_MATEFILE is not supported yet."); } else if (local_format == RegisterClipboardFormatW(L"FileGroupDescriptorW")) { HRESULT result; LPDATAOBJECT dataObj; FORMATETC format_etc; STGMEDIUM stg_medium; DROPFILES *dropFiles; int len; int i; wchar_t *wFileName; unsigned int uSize; DEBUG_CLIPRDR("file descriptors request."); result = OleGetClipboard(&dataObj); if (!SUCCEEDED(result)) { DEBUG_CLIPRDR("OleGetClipboard failed."); } ZeroMemory(&format_etc, sizeof(FORMATETC)); ZeroMemory(&stg_medium, sizeof(STGMEDIUM)); /* try to get FileGroupDescriptorW struct from OLE */ format_etc.cfFormat = local_format; 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 = malloc(uSize); memcpy(buff, globlemem, uSize); GlobalUnlock(stg_medium.hGlobal); ReleaseStgMedium(&stg_medium); clear_file_array(cliprdr); } 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 (!SUCCEEDED(result)) { DEBUG_CLIPRDR("dataObj->GetData failed."); } globlemem = (char *)GlobalLock(stg_medium.hGlobal); if (globlemem == NULL) { GlobalUnlock(stg_medium.hGlobal); ReleaseStgMedium(&stg_medium); cliprdr->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(cliprdr); if (dropFiles->fWide) { wchar_t *p; int str_len; int offset; int pathLen; /* dropFiles contains file names */ for (wFileName = (wchar_t *)((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(cliprdr, wFileName, pathLen); if ((cliprdr->fileDescriptor[cliprdr->nFiles - 1]->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { /* this is a directory */ wf_cliprdr_traverse_directory(cliprdr, wFileName, pathLen); } } } else { char *p; for (p = (char *)((char *)dropFiles + dropFiles->pFiles); (len = strlen(p)) > 0; p += len + 1, cliprdr->nFiles++) { int cchWideChar; cchWideChar = MultiByteToWideChar(CP_ACP, MB_COMPOSITE, p, len, NULL, 0); cliprdr->file_names[cliprdr->nFiles] = (LPWSTR)malloc(cchWideChar); MultiByteToWideChar(CP_ACP, MB_COMPOSITE, p, len, cliprdr->file_names[cliprdr->nFiles], cchWideChar); if (cliprdr->nFiles == cliprdr->file_array_size) { cliprdr->file_array_size *= 2; cliprdr->fileDescriptor = (FILEDESCRIPTORW **)realloc(cliprdr->fileDescriptor, cliprdr->file_array_size * sizeof(FILEDESCRIPTORW *)); cliprdr->file_names = (wchar_t **)realloc(cliprdr->file_names, cliprdr->file_array_size * sizeof(wchar_t *)); } } } exit: size = 4 + cliprdr->nFiles * sizeof(FILEDESCRIPTORW); buff = (char *)malloc(size); Write_UINT32(buff, cliprdr->nFiles); for (i = 0; i < cliprdr->nFiles; i++) { if (cliprdr->fileDescriptor[i]) { memcpy(buff + 4 + i * sizeof(FILEDESCRIPTORW), cliprdr->fileDescriptor[i], sizeof(FILEDESCRIPTORW)); } } } IDataObject_Release(dataObj); } else { if (!OpenClipboard(cliprdr->hwndClipboard)) { DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError()); return; } hClipdata = GetClipboardData(event->format); if (!hClipdata) { DEBUG_CLIPRDR("GetClipboardData failed."); CloseClipboard(); return; } globlemem = (char*) GlobalLock(hClipdata); size = (int) GlobalSize(hClipdata); buff = (char*) malloc(size); memcpy(buff, globlemem, size); GlobalUnlock(hClipdata); CloseClipboard(); } response_event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_DataResponse, NULL, NULL); response_event->data = (BYTE *)buff; response_event->size = size; freerdp_channels_send_event(cliprdr->channels, (wMessage*) response_event); /* Note: don't free buffer here. */ }
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; }
static BOOL DoPaste(ContextMenu *This) { BOOL bSuccess = FALSE; IDataObject * pda; TRACE("\n"); if(SUCCEEDED(OleGetClipboard(&pda))) { STGMEDIUM medium; FORMATETC formatetc; TRACE("pda=%p\n", pda); /* Set the FORMATETC structure*/ InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL); /* Get the pidls from IDataObject */ if(SUCCEEDED(IDataObject_GetData(pda,&formatetc,&medium))) { LPITEMIDLIST * apidl; LPITEMIDLIST pidl; IShellFolder *psfFrom = NULL, *psfDesktop; LPIDA lpcida = GlobalLock(medium.u.hGlobal); TRACE("cida=%p\n", lpcida); apidl = _ILCopyCidaToaPidl(&pidl, lpcida); /* bind to the source shellfolder */ SHGetDesktopFolder(&psfDesktop); if(psfDesktop) { IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom); IShellFolder_Release(psfDesktop); } if (psfFrom) { /* get source and destination shellfolder */ ISFHelper *psfhlpdst, *psfhlpsrc; IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst); IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (void**)&psfhlpsrc); /* do the copy/move */ if (psfhlpdst && psfhlpsrc) { ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl); /* FIXME handle move ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl); */ } if(psfhlpdst) ISFHelper_Release(psfhlpdst); if(psfhlpsrc) ISFHelper_Release(psfhlpsrc); IShellFolder_Release(psfFrom); } _ILFreeaPidl(apidl, lpcida->cidl); SHFree(pidl); /* release the medium*/ ReleaseStgMedium(&medium); } IDataObject_Release(pda); } #if 0 HGLOBAL hMem; OpenClipboard(NULL); hMem = GetClipboardData(CF_HDROP); if(hMem) { char * pDropFiles = GlobalLock(hMem); if(pDropFiles) { int len, offset = sizeof(DROPFILESTRUCT); while( pDropFiles[offset] != 0) { len = strlen(pDropFiles + offset); TRACE("%s\n", pDropFiles + offset); offset += len+1; } } GlobalUnlock(hMem); } CloseClipboard(); #endif return bSuccess; }