/************************************************************************** * IDataObject_Constructor */ LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidl, UINT cidl) { IDataObjectImpl* dto; dto = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDataObjectImpl)); if (dto) { dto->ref = 1; dto->lpVtbl = &dtovt; dto->pidl = ILClone(pMyPidl); dto->apidl = _ILCopyaPidl(apidl, cidl); dto->cidl = cidl; dto->cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); dto->cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA); dto->cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW); InitFormatEtc(dto->pFormatEtc[0], dto->cfShellIDList, TYMED_HGLOBAL); InitFormatEtc(dto->pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL); InitFormatEtc(dto->pFormatEtc[2], dto->cfFileNameA, TYMED_HGLOBAL); InitFormatEtc(dto->pFormatEtc[3], dto->cfFileNameW, TYMED_HGLOBAL); } TRACE("(%p)->(apidl=%p cidl=%u)\n",dto, apidl, cidl); return (LPDATAOBJECT)dto; }
/****************************************************************************** * CLIPFORMAT_UserUnmarshal [OLE32.@] * * Unmarshals a clip format from a buffer. * * PARAMS * pFlags [I] Flags. See notes. * pBuffer [I] Buffer to marshal the clip format from. * pCF [O] Address that receive the unmarshaled clip format. * * RETURNS * The end of the marshaled data in the buffer. * * NOTES * Even though the function is documented to take a pointer to an unsigned * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which * the first parameter is an unsigned long. * This function is only intended to be called by the RPC runtime. */ unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF) { wireCLIPFORMAT wirecf = (wireCLIPFORMAT)pBuffer; TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", pBuffer, pCF); pBuffer += sizeof(*wirecf); if (wirecf->fContext == WDT_INPROC_CALL) *pCF = (CLIPFORMAT)wirecf->u.dwValue; else if (wirecf->fContext == WDT_REMOTE_CALL) { CLIPFORMAT cf; INT len = *(INT *)pBuffer; pBuffer += sizeof(INT); if (*(INT *)pBuffer != 0) RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL); pBuffer += sizeof(INT); if (*(INT *)pBuffer != len) RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL); pBuffer += sizeof(INT); if (((WCHAR *)pBuffer)[len] != '\0') RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL); TRACE("unmarshaling clip format %s\n", debugstr_w((LPCWSTR)pBuffer)); cf = RegisterClipboardFormatW((LPCWSTR)pBuffer); pBuffer += (len + 1) * sizeof(WCHAR); if (!cf) RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL); *pCF = cf; } else /* code not really appropriate, but nearest I can find */ RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL); return pBuffer; }
static BOOL ClipboardReadMemory(HANDLE hFile, DWORD dwFormat, DWORD dwOffset, DWORD dwLength, WORD FileIdentifier, PVOID lpFormatName) { HGLOBAL hData; DWORD dwTemp = 0; hData = ClipboardReadMemoryBlock(hFile, dwOffset, dwLength); if (!hData) return FALSE; if ((dwFormat >= 0xC000) && (dwFormat <= 0xFFFF)) { if (FileIdentifier == CLIP_FMT_31) dwTemp = RegisterClipboardFormatA((LPCSTR)lpFormatName); else if ((FileIdentifier == CLIP_FMT_NT) || (FileIdentifier == CLIP_FMT_BK)) dwTemp = RegisterClipboardFormatW((LPCWSTR)lpFormatName); if (!dwTemp) { GlobalFree(hData); return FALSE; } } else { dwTemp = dwFormat; } if (!SetClipboardData(dwTemp, hData)) { GlobalFree(hData); return FALSE; } return TRUE; }
HRESULT WINAPI IDataObjectImpl::Initialize(HWND hwndOwner, LPCITEMIDLIST pMyPidl, LPCITEMIDLIST * apidlx, UINT cidlx) { pidl = ILClone(pMyPidl); apidl = _ILCopyaPidl(apidlx, cidlx); if (pidl == NULL || apidl == NULL) return E_OUTOFMEMORY; cidl = cidlx; cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST); cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA); cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW); InitFormatEtc(pFormatEtc[0], cfShellIDList, TYMED_HGLOBAL); InitFormatEtc(pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL); InitFormatEtc(pFormatEtc[2], cfFileNameA, TYMED_HGLOBAL); InitFormatEtc(pFormatEtc[3], cfFileNameW, TYMED_HGLOBAL); return S_OK; }
static HRESULT InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker, IN HWND hwndParent OPTIONAL, OUT LPWSTR lpBuffer, IN UINT uSize) { IDataObject *pdo = NULL; HRESULT hRet; hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker, hwndParent, &pdo); if (hRet == S_OK) { STGMEDIUM stm; FORMATETC fe; fe.cfFormat = (CLIPFORMAT) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST); fe.ptd = NULL; fe.dwAspect = DVASPECT_CONTENT; fe.lindex = -1; fe.tymed = TYMED_HGLOBAL; hRet = pdo->lpVtbl->GetData(pdo, &fe, &stm); if (SUCCEEDED(hRet)) { PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal); if (SelectionList != NULL) { if (SelectionList->cItems == 1) { size_t nlen = wcslen(SelectionList->aDsSelection[0].pwzName); if (nlen >= uSize) { nlen = uSize - 1; } memcpy(lpBuffer, SelectionList->aDsSelection[0].pwzName, nlen * sizeof(WCHAR)); lpBuffer[nlen] = L'\0'; } GlobalUnlock(stm.hGlobal); } ReleaseStgMedium(&stm); } pdo->lpVtbl->Release(pdo); } return hRet; }
static BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { WCHAR empty = 0; WNDCLASSEXW wndclass = {0}; /* Frame class */ wndclass.cbSize = sizeof(WNDCLASSEXW); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = FrameWndProc; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_REGEDIT)); wndclass.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW); wndclass.lpszClassName = szFrameClass; wndclass.hIconSm = LoadImageW(hInstance, MAKEINTRESOURCEW(IDI_REGEDIT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); RegisterClassExW(&wndclass); /* Child class */ wndclass.lpfnWndProc = ChildWndProc; wndclass.cbWndExtra = sizeof(HANDLE); wndclass.lpszClassName = szChildClass; RegisterClassExW(&wndclass); hMenuFrame = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_REGEDIT_MENU)); hPopupMenus = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_POPUP_MENUS)); /* Initialize the Windows Common Controls DLL */ InitCommonControls(); /* register our hex editor control */ HexEdit_Register(); nClipboardFormat = RegisterClipboardFormatW(strClipboardFormat); hFrameWnd = CreateWindowExW(0, szFrameClass, szTitle, WS_OVERLAPPEDWINDOW | WS_EX_CLIENTEDGE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, hMenuFrame, hInstance, NULL/*lpParam*/); if (!hFrameWnd) { return FALSE; } /* Create the status bar */ hStatusBar = CreateStatusWindowW(WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|SBT_NOBORDERS, &empty, hFrameWnd, STATUS_WINDOW); if (hStatusBar) { /* Create the status bar panes */ SetupStatusBar(hFrameWnd, FALSE); CheckMenuItem(GetSubMenu(hMenuFrame, ID_VIEW_MENU), ID_VIEW_STATUSBAR, MF_BYCOMMAND|MF_CHECKED); } ShowWindow(hFrameWnd, nCmdShow); UpdateWindow(hFrameWnd); return TRUE; }
BOOL wf_create_file_obj(wfClipboard* clipboard, IDataObject** ppDataObject) { FORMATETC fmtetc[3]; STGMEDIUM stgmeds[3]; if (!ppDataObject) return FALSE; fmtetc[0].cfFormat = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW); fmtetc[0].dwAspect = DVASPECT_CONTENT; fmtetc[0].lindex = 0; fmtetc[0].ptd = NULL; fmtetc[0].tymed = TYMED_HGLOBAL; stgmeds[0].tymed = TYMED_HGLOBAL; stgmeds[0].hGlobal = NULL; stgmeds[0].pUnkForRelease = NULL; fmtetc[1].cfFormat = RegisterClipboardFormatW(CFSTR_FILECONTENTS); fmtetc[1].dwAspect = DVASPECT_CONTENT; fmtetc[1].lindex = 0; fmtetc[1].ptd = NULL; fmtetc[1].tymed = TYMED_ISTREAM; stgmeds[1].tymed = TYMED_ISTREAM; stgmeds[1].pstm = NULL; stgmeds[1].pUnkForRelease = NULL; fmtetc[2].cfFormat = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT); fmtetc[2].dwAspect = DVASPECT_CONTENT; fmtetc[2].lindex = 0; fmtetc[2].ptd = NULL; fmtetc[2].tymed = TYMED_HGLOBAL; stgmeds[2].tymed = TYMED_HGLOBAL; stgmeds[2].hGlobal = NULL; stgmeds[2].pUnkForRelease = NULL; *ppDataObject = (IDataObject*) CliprdrDataObject_New(fmtetc, stgmeds, 3, clipboard); return (*ppDataObject) ? TRUE : FALSE; }
HRESULT WINAPI CIDLDataObj::Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx) { pidl = ILClone(pMyPidl); apidl = _ILCopyaPidl(apidlx, cidlx); if (pidl == NULL || apidl == NULL) return E_OUTOFMEMORY; cidl = cidlx; dropeffect = DROPEFFECT_COPY; cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST); cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA); cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW); cfPreferredDropEffect = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW); InitFormatEtc(pFormatEtc[0], cfShellIDList, TYMED_HGLOBAL); InitFormatEtc(pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL); InitFormatEtc(pFormatEtc[2], cfFileNameA, TYMED_HGLOBAL); InitFormatEtc(pFormatEtc[3], cfFileNameW, TYMED_HGLOBAL); InitFormatEtc(pFormatEtc[4], cfPreferredDropEffect, TYMED_HGLOBAL); return S_OK; }
void GnuUnitTests() { int nRegW = RegisterClipboardFormatW(CFSTR_FILENAMEW/*L"FileNameW"*/); int nRegA = RegisterClipboardFormatA("FileNameW"); Assert(nRegW && nRegA && nRegW==nRegA); wchar_t szHex[] = L"\x2018"/*�*/ L"\x2019"/*�*/; wchar_t szNum[] = {0x2018, 0x2019, 0}; int iDbg = lstrcmp(szHex, szNum); Assert(iDbg==0); }
static void mime_available(Binding *This, LPCWSTR mime) { heap_free(This->mime); This->mime = heap_strdupW(mime); if(!This->mime || !This->report_mime) return; IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_MIMETYPEAVAILABLE, This->mime); This->clipboard_format = RegisterClipboardFormatW(This->mime); }
void wf_cliprdr_init(wfContext* wfc, rdpChannels* channels) { cliprdrContext *cliprdr; if (!wfc->instance->settings->RedirectClipboard) { wfc->cliprdr_context = NULL; fprintf(stderr, "clipboard is not redirected.\n"); return; } wfc->cliprdr_context = (cliprdrContext *) calloc(1, sizeof(cliprdrContext)); cliprdr = (cliprdrContext *) wfc->cliprdr_context; assert(cliprdr != NULL); cliprdr->channels = channels; cliprdr->channel_initialized = FALSE; cliprdr->map_capacity = 32; cliprdr->map_size = 0; cliprdr->format_mappings = (formatMapping *)calloc(1, sizeof(formatMapping) * cliprdr->map_capacity); assert(cliprdr->format_mappings != NULL); cliprdr->file_array_size = 32; cliprdr->file_names = (wchar_t **)calloc(1, cliprdr->file_array_size * sizeof(wchar_t *)); cliprdr->fileDescriptor = (FILEDESCRIPTORW **)calloc(1, cliprdr->file_array_size * sizeof(FILEDESCRIPTORW *)); cliprdr->response_data_event = CreateEvent(NULL, TRUE, FALSE, L"response_data_event"); assert(cliprdr->response_data_event != NULL); cliprdr->req_fevent = CreateEvent(NULL, TRUE, FALSE, L"request_filecontents_event"); cliprdr->ID_FILEDESCRIPTORW = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW); cliprdr->ID_FILECONTENTS = RegisterClipboardFormatW(CFSTR_FILECONTENTS); cliprdr->ID_PREFERREDDROPEFFECT = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT); cliprdr->cliprdr_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)cliprdr_thread_func, cliprdr, 0, NULL); assert(cliprdr->cliprdr_thread != NULL); }
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; }
/************************************************************************** * RegisterClipboardFormatA (USER32.@) */ UINT WINAPI RegisterClipboardFormatA(LPCSTR formatName) { int len; LPWSTR wFormat; UINT ret; len = MultiByteToWideChar(CP_ACP, 0, formatName, -1, NULL, 0); wFormat = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, formatName, -1, wFormat, len); ret = RegisterClipboardFormatW(wFormat); HeapFree(GetProcessHeap(), 0, wFormat); return ret; }
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE* ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl) { UINT cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST); if (!cfShellIDList) return E_FAIL; FORMATETC fmt; InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL); HRESULT hr = pDataObject->QueryGetData(&fmt); if (FAILED_UNEXPECTEDLY(hr)) return hr; STGMEDIUM medium; hr = pDataObject->GetData(&fmt, &medium); if (FAILED_UNEXPECTEDLY(hr)) return hr; /* lock the handle */ LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal); if (!lpcida) { ReleaseStgMedium(&medium); return E_FAIL; } /* convert the data into pidl */ LPITEMIDLIST pidl; LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida); if (!apidl) { ReleaseStgMedium(&medium); return E_OUTOFMEMORY; } *ppidlfolder = pidl; *apidlItems = apidl; *pcidl = lpcida->cidl; ReleaseStgMedium(&medium); return S_OK; }
static void register_clipboard_formats(void) { /* These used to be declared in olestd.h, but that seems to have been removed from the api */ static const WCHAR CF_EMBEDSOURCEW[] = { 'E','m','b','e','d',' ','S','o','u','r','c','e',0 }; static const WCHAR CF_EMBEDDEDOBJECTW[] = { 'E','m','b','e','d','d','e','d',' ','O','b','j','e','c','t',0 }; static const WCHAR CF_LINKSOURCEW[] = { 'L','i','n','k',' ','S','o','u','r','c','e',0 }; static const WCHAR CF_OBJECTDESCRIPTORW[] = { 'O','b','j','e','c','t',' ','D','e','s','c','r','i','p','t','o','r',0 }; static const WCHAR CF_LINKSRCDESCRIPTORW[] = { 'L','i','n','k',' ','S','o','u','r','c','e',' ','D','e','s','c','r','i','p','t','o','r',0 }; static const WCHAR CF_OWNERLINKW[] = { 'O','w','n','e','r','L','i','n','k',0 }; static const WCHAR CF_FILENAMEW[] = { 'F','i','l','e','N','a','m','e',0 }; static const WCHAR CF_FILENAMEWW[] = { 'F','i','l','e','N','a','m','e','W',0 }; /* Load in the same order as native to make debugging easier */ cf_object_descriptor = RegisterClipboardFormatW(CF_OBJECTDESCRIPTORW); cf_link_src_descriptor = RegisterClipboardFormatW(CF_LINKSRCDESCRIPTORW); cf_embed_source = RegisterClipboardFormatW(CF_EMBEDSOURCEW); cf_embedded_object = RegisterClipboardFormatW(CF_EMBEDDEDOBJECTW); cf_link_source = RegisterClipboardFormatW(CF_LINKSOURCEW); cf_ownerlink = RegisterClipboardFormatW(CF_OWNERLINKW); cf_filename = RegisterClipboardFormatW(CF_FILENAMEW); cf_filenamew = RegisterClipboardFormatW(CF_FILENAMEWW); }
void InitGDI() { ClipboardFormat = RegisterClipboardFormatW(L"Altona Clipboard Object"); if(ClipboardFormat==0) sFatal(L"failed to register clipboard format"); // if(sGetSystemFlags() & sISF_2D) { sU32 color = GDICOL(0); for(sInt i=0;i<MAX_BRUSHES;i++) { BrushColor[i] = color; BrushHandle[i] = CreateSolidBrush(color); BrushPen[i] = CreatePen(PS_SOLID,0,color); } for(sInt i=0;i<MAX_CLIPS;i++) { ClipStack[i] = CreateRectRgn(0,0,0,0); } static const LPCWSTR cursormap[] = { 0, IDC_ARROW, IDC_WAIT, IDC_CROSS, IDC_HAND, IDC_IBEAM, IDC_NO, IDC_SIZEALL, IDC_SIZENS, IDC_SIZEWE, IDC_SIZENWSE, IDC_SIZENESW, }; Cursors[0] = 0; for(sInt i=1;i<sMP_MAX;i++) Cursors[i] = LoadCursorW(0,cursormap[i]); } }
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; }
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { BOOL AclUiAvailable; HMENU hEditMenu; WNDCLASSEXW wcFrame; WNDCLASSEXW wcChild; ATOM hFrameWndClass; ZeroMemory(&wcFrame, sizeof(WNDCLASSEXW)); wcFrame.cbSize = sizeof(WNDCLASSEXW); wcFrame.lpfnWndProc = FrameWndProc; wcFrame.hInstance = hInstance; wcFrame.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_REGEDIT)); wcFrame.hIconSm = (HICON)LoadImageW(hInstance, MAKEINTRESOURCEW(IDI_REGEDIT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); wcFrame.hCursor = LoadCursorW(NULL, IDC_ARROW); wcFrame.lpszClassName = szFrameClass; hFrameWndClass = RegisterClassExW(&wcFrame); /* register frame window class */ ZeroMemory(&wcChild, sizeof(WNDCLASSEXW)); wcChild.cbSize = sizeof(WNDCLASSEXW); wcChild.lpfnWndProc = ChildWndProc; wcChild.cbWndExtra = sizeof(HANDLE); wcChild.hInstance = hInstance; wcChild.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_REGEDIT)); wcChild.hCursor = LoadCursorW(NULL, IDC_ARROW); wcChild.lpszClassName = szChildClass; wcChild.hIconSm = (HICON)LoadImageW(hInstance, MAKEINTRESOURCEW(IDI_REGEDIT), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); RegisterClassExW(&wcChild); /* register child windows class */ RegisterHexEditorClass(hInstance); hMenuFrame = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_REGEDIT_MENU)); hPopupMenus = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_POPUP_MENUS)); /* Initialize the Windows Common Controls DLL */ // TODO: Replace this call by InitCommonControlsEx(_something_) InitCommonControls(); hEditMenu = GetSubMenu(hMenuFrame, 1); AclUiAvailable = InitializeAclUiDll(); if(!AclUiAvailable) { /* hide the Edit/Permissions... menu entry */ if(hEditMenu != NULL) { RemoveMenu(hEditMenu, ID_EDIT_PERMISSIONS, MF_BYCOMMAND); /* remove the separator after the menu item */ RemoveMenu(hEditMenu, 4, MF_BYPOSITION); } } if(hEditMenu != NULL) SetMenuDefaultItem(hEditMenu, ID_EDIT_MODIFY, MF_BYCOMMAND); nClipboardFormat = RegisterClipboardFormatW(strClipboardFormat); /* if (nClipboardFormat == 0) { DWORD dwError = GetLastError(); } */ hFrameWnd = CreateWindowExW(WS_EX_WINDOWEDGE, (LPCWSTR)(UlongToPtr(hFrameWndClass)), szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, hMenuFrame, hInstance, NULL/*lpParam*/); if (!hFrameWnd) { return FALSE; } /* Create the status bar */ hStatusBar = CreateStatusWindowW(WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | SBT_NOBORDERS, L"", hFrameWnd, STATUS_WINDOW); if (hStatusBar) { /* Create the status bar panes */ SetupStatusBar(hFrameWnd, FALSE); CheckMenuItem(GetSubMenu(hMenuFrame, ID_VIEW_MENU), ID_VIEW_STATUSBAR, MF_BYCOMMAND | MF_CHECKED); } LoadSettings(); UpdateWindow(hFrameWnd); return TRUE; }
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 void wf_cliprdr_process_cb_data_request_event(wfContext *wfc, RDP_CB_DATA_REQUEST_EVENT *event) { cliprdrContext *cliprdr = (cliprdrContext *)wfc->cliprdr_context; RDP_CB_DATA_RESPONSE_EVENT *responce_event; HANDLE hClipdata; int size = 0; char *buff = NULL; char *globlemem = NULL; UINT32 local_format; local_format = event->format; if (local_format == 0x9) /* FORMAT_ID_PALETTE */ { /* TODO: implement this */ DEBUG_CLIPRDR("FORMAT_ID_PALETTE is not supported yet."); } else if (local_format == 0x3) /* FORMAT_ID_MATEFILE */ { /* TODO: implement this */ DEBUG_CLIPRDR("FORMAT_ID_MATEFILE is not supported yet."); } else if (local_format == RegisterClipboardFormatW(L"FileGroupDescriptorW")) { /* TODO: implement this */ DEBUG_CLIPRDR("FileGroupDescriptorW is not supported yet."); } 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 = GlobalSize(hClipdata); buff = (char *)malloc(size); memcpy(buff, globlemem, size); GlobalUnlock(hClipdata); CloseClipboard(); } responce_event = (RDP_CB_DATA_RESPONSE_EVENT *)freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_DataResponse, NULL, NULL); responce_event->data = (BYTE *)buff; responce_event->size = size; freerdp_channels_send_event(cliprdr->channels, (wMessage *) responce_event); /* Note: don't free buff here. */ }
static void cliprdr_send_format_list(cliprdrContext *cliprdr) { RDP_CB_FORMAT_LIST_EVENT *cliprdr_event; BYTE *format_data; int format = 0; int data_size; int format_count; int len = 0; int namelen; int stream_file_transferring = FALSE; if (!OpenClipboard(cliprdr->hwndClipboard)) { DEBUG_CLIPRDR("OpenClipboard failed with 0x%x", GetLastError()); return; } format_count = CountClipboardFormats(); data_size = format_count * (4 + MAX_PATH * 2); format_data = (BYTE *)calloc(1, data_size); assert(format_data != NULL); while (format = EnumClipboardFormats(format)) { Write_UINT32(format_data + len, format); len += 4; if ((cliprdr->capabilities & CB_USE_LONG_FORMAT_NAMES) != 0) { if (format >= CF_MAX) { namelen = GetClipboardFormatNameW(format, (LPWSTR)(format_data + len), MAX_PATH); if ((wcscmp((LPWSTR)(format_data + len), L"FileNameW") == 0) || (wcscmp((LPWSTR)(format_data + len), L"FileName") == 0) || (wcscmp((LPWSTR)(format_data + len), CFSTR_FILEDESCRIPTORW) == 0)) { stream_file_transferring = TRUE; } len += namelen * sizeof(WCHAR); } len += 2; /* end of Unicode string */ } else { if (format >= CF_MAX) { static wchar_t wName[MAX_PATH] = {0}; int wLen; ZeroMemory(wName, MAX_PATH*2); wLen = GetClipboardFormatNameW(format, wName, MAX_PATH); if (wLen < 16) { memcpy(format_data + len, wName, wLen * sizeof(WCHAR)); } else { memcpy(format_data + len, wName, 32); /* truncate the long name to 32 bytes */ } } len += 32; } } CloseClipboard(); cliprdr_event = (RDP_CB_FORMAT_LIST_EVENT *) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL, NULL); if (stream_file_transferring) { cliprdr_event->raw_format_data = (BYTE *)calloc(1, (4 + 42)); format = RegisterClipboardFormatW(L"FileGroupDescriptorW"); Write_UINT32(cliprdr_event->raw_format_data, format); wcscpy((wchar_t *)(cliprdr_event->raw_format_data + 4), L"FileGroupDescriptorW"); cliprdr_event->raw_format_data_size = 4 + 42; } else { cliprdr_event->raw_format_data = (BYTE *)calloc(1, len); assert(cliprdr_event->raw_format_data != NULL); CopyMemory(cliprdr_event->raw_format_data, format_data, len); cliprdr_event->raw_format_data_size = len; } free(format_data); freerdp_channels_send_event(cliprdr->channels, (wMessage *) cliprdr_event); }
void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr) { wfClipboard* clipboard; rdpContext* context = (rdpContext*) wfc; wfc->clipboard = (wfClipboard*) calloc(1, sizeof(wfClipboard)); if (!wfc->clipboard) return; clipboard = wfc->clipboard; clipboard->wfc = wfc; clipboard->context = cliprdr; clipboard->channels = context->channels; clipboard->sync = FALSE; clipboard->map_capacity = 32; clipboard->map_size = 0; if (!(clipboard->format_mappings = (formatMapping*) calloc(1, sizeof(formatMapping) * clipboard->map_capacity))) goto fail_format_mappings; clipboard->file_array_size = 32; if (!(clipboard->file_names = (WCHAR**) calloc(1, clipboard->file_array_size * sizeof(WCHAR*)))) goto fail_file_names; if (!(clipboard->fileDescriptor = (FILEDESCRIPTORW**) calloc(1, clipboard->file_array_size * sizeof(FILEDESCRIPTORW*)))) goto fail_file_descriptor; if (!(clipboard->response_data_event = CreateEvent(NULL, TRUE, FALSE, _T("response_data_event")))) goto fail_data_event; if (!(clipboard->req_fevent = CreateEvent(NULL, TRUE, FALSE, _T("request_filecontents_event")))) goto fail_filecontents_event; clipboard->ID_FILEDESCRIPTORW = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW); clipboard->ID_FILECONTENTS = RegisterClipboardFormatW(CFSTR_FILECONTENTS); clipboard->ID_PREFERREDDROPEFFECT = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT); if (!(clipboard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) cliprdr_thread_func, clipboard, 0, NULL))) goto fail_clipboard_thread; cliprdr->MonitorReady = wf_cliprdr_monitor_ready; cliprdr->ServerCapabilities = wf_cliprdr_server_capabilities; cliprdr->ServerFormatList = wf_cliprdr_server_format_list; cliprdr->ServerFormatListResponse = wf_cliprdr_server_format_list_response; cliprdr->ServerLockClipboardData = wf_cliprdr_server_lock_clipboard_data; cliprdr->ServerUnlockClipboardData = wf_cliprdr_server_unlock_clipboard_data; cliprdr->ServerFormatDataRequest = wf_cliprdr_server_format_data_request; cliprdr->ServerFormatDataResponse = wf_cliprdr_server_format_data_response; cliprdr->ServerFileContentsRequest = wf_cliprdr_server_file_contents_request; cliprdr->ServerFileContentsResponse = wf_cliprdr_server_file_contents_response; cliprdr->custom = (void*) wfc->clipboard; return; fail_clipboard_thread: CloseHandle(clipboard->req_fevent); clipboard->req_fevent = NULL; fail_filecontents_event: CloseHandle(clipboard->response_data_event); clipboard->response_data_event = NULL; fail_data_event: free(clipboard->fileDescriptor); clipboard->fileDescriptor = NULL; fail_file_descriptor: free(clipboard->file_names); clipboard->file_names = NULL; fail_file_names: free(clipboard->format_mappings); clipboard->format_mappings = NULL; fail_format_mappings: free(wfc->clipboard); wfc->clipboard = NULL; return; }
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. */ }