xref: /reactos/dll/win32/shell32/wine/clipboard.c (revision 52dd07fe)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  *	clipboard helper functions
3c2c66affSColin Finck  *
4c2c66affSColin Finck  *	Copyright 2000	Juergen Schmied <juergen.schmied@debitel.de>
5c2c66affSColin Finck  *
6c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck  * License as published by the Free Software Foundation; either
9c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck  *
11c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14c2c66affSColin Finck  * Lesser General Public License for more details.
15c2c66affSColin Finck  *
16c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck  *
20c2c66affSColin Finck  * NOTES:
21c2c66affSColin Finck  *
22c2c66affSColin Finck  * For copy & paste functions within contextmenus does the shell use
23c2c66affSColin Finck  * the OLE clipboard functions in combination with dataobjects.
24c2c66affSColin Finck  * The OLE32.DLL gets loaded with LoadLibrary
25c2c66affSColin Finck  *
26c2c66affSColin Finck  * - a right mousebutton-copy sets the following formats:
27c2c66affSColin Finck  *  classic:
28c2c66affSColin Finck  *	Shell IDList Array
29c2c66affSColin Finck  *	Preferred Drop Effect
30c2c66affSColin Finck  *	Shell Object Offsets
31c2c66affSColin Finck  *	HDROP
32c2c66affSColin Finck  *	FileName
33c2c66affSColin Finck  *  ole:
34c2c66affSColin Finck  *	OlePrivateData (ClipboardDataObjectInterface)
35c2c66affSColin Finck  *
36c2c66affSColin Finck  */
37c2c66affSColin Finck 
38c2c66affSColin Finck #define WIN32_NO_STATUS
39c2c66affSColin Finck #define _INC_WINDOWS
40c2c66affSColin Finck 
41c2c66affSColin Finck #include <windef.h>
42c2c66affSColin Finck #include <winbase.h>
43c2c66affSColin Finck #include <shlobj.h>
44c2c66affSColin Finck #include <wine/debug.h>
45c2c66affSColin Finck #include <wine/unicode.h>
46c2c66affSColin Finck 
47*52dd07feSHermès Bélusca-Maïto #include "shell32_main.h"
48*52dd07feSHermès Bélusca-Maïto 
49c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(shell);
50c2c66affSColin Finck 
51c2c66affSColin Finck /**************************************************************************
52c2c66affSColin Finck  * RenderHDROP
53c2c66affSColin Finck  *
54c2c66affSColin Finck  * creates a CF_HDROP structure
55c2c66affSColin Finck  */
RenderHDROP(LPITEMIDLIST pidlRoot,LPITEMIDLIST * apidl,UINT cidl)56c2c66affSColin Finck HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
57c2c66affSColin Finck {
58c2c66affSColin Finck 	UINT i;
59c2c66affSColin Finck #ifdef __REACTOS__
60c2c66affSColin Finck         int size = 0;
61c2c66affSColin Finck #else
62c2c66affSColin Finck 	int rootlen = 0,size = 0;
63c2c66affSColin Finck 	WCHAR wszRootPath[MAX_PATH];
64c2c66affSColin Finck #endif
65c2c66affSColin Finck 	WCHAR wszFileName[MAX_PATH];
66c2c66affSColin Finck 	HGLOBAL hGlobal = NULL;
67c2c66affSColin Finck 	DROPFILES *pDropFiles;
68c2c66affSColin Finck 	int offset;
69c2c66affSColin Finck #ifdef __REACTOS__
70c2c66affSColin Finck         LPITEMIDLIST *pidls;
71c2c66affSColin Finck #endif
72c2c66affSColin Finck 
73c2c66affSColin Finck 	TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
74c2c66affSColin Finck 
75c2c66affSColin Finck #ifdef __REACTOS__
76c2c66affSColin Finck         pidls = (LPITEMIDLIST *)HeapAlloc(GetProcessHeap(), 0, cidl * sizeof(*pidls));
77c2c66affSColin Finck         if (!pidls)
78c2c66affSColin Finck             goto cleanup;
79c2c66affSColin Finck #endif
80c2c66affSColin Finck 
81c2c66affSColin Finck 	/* get the size needed */
82c2c66affSColin Finck 	size = sizeof(DROPFILES);
83c2c66affSColin Finck 
84c2c66affSColin Finck #ifndef __REACTOS__
85c2c66affSColin Finck 	SHGetPathFromIDListW(pidlRoot, wszRootPath);
86c2c66affSColin Finck 	PathAddBackslashW(wszRootPath);
87c2c66affSColin Finck 	rootlen = strlenW(wszRootPath);
88c2c66affSColin Finck #endif
89c2c66affSColin Finck 
90c2c66affSColin Finck 	for (i=0; i<cidl;i++)
91c2c66affSColin Finck 	{
92c2c66affSColin Finck #ifdef __REACTOS__
93c2c66affSColin Finck           pidls[i] = ILCombine(pidlRoot, apidl[i]);
94c2c66affSColin Finck           SHGetPathFromIDListW(pidls[i], wszFileName);
95c2c66affSColin Finck           size += (wcslen(wszFileName) + 1) * sizeof(WCHAR);
96c2c66affSColin Finck #else
97c2c66affSColin Finck 	  _ILSimpleGetTextW(apidl[i], wszFileName, MAX_PATH);
98c2c66affSColin Finck 	  size += (rootlen + strlenW(wszFileName) + 1) * sizeof(WCHAR);
99c2c66affSColin Finck #endif
100c2c66affSColin Finck 	}
101c2c66affSColin Finck 
102c2c66affSColin Finck 	size += sizeof(WCHAR);
103c2c66affSColin Finck 
104c2c66affSColin Finck 	/* Fill the structure */
105c2c66affSColin Finck 	hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
106c2c66affSColin Finck #ifdef __REACTOS__
107c2c66affSColin Finck         if(!hGlobal) goto cleanup;
108c2c66affSColin Finck #else
109c2c66affSColin Finck 	if(!hGlobal) return hGlobal;
110c2c66affSColin Finck #endif
111c2c66affSColin Finck 
112c2c66affSColin Finck         pDropFiles = GlobalLock(hGlobal);
113c2c66affSColin Finck 	offset = (sizeof(DROPFILES) + sizeof(WCHAR) - 1) / sizeof(WCHAR);
114c2c66affSColin Finck         pDropFiles->pFiles = offset * sizeof(WCHAR);
115c2c66affSColin Finck         pDropFiles->fWide = TRUE;
116c2c66affSColin Finck 
117c2c66affSColin Finck #ifndef __REACTOS__
118c2c66affSColin Finck 	strcpyW(wszFileName, wszRootPath);
119c2c66affSColin Finck #endif
120c2c66affSColin Finck 
121c2c66affSColin Finck 	for (i=0; i<cidl;i++)
122c2c66affSColin Finck 	{
123c2c66affSColin Finck 
124c2c66affSColin Finck #ifdef __REACTOS__
125c2c66affSColin Finck           SHGetPathFromIDListW(pidls[i], wszFileName);
126c2c66affSColin Finck           wcscpy(((WCHAR*)pDropFiles)+offset, wszFileName);
127c2c66affSColin Finck           offset += wcslen(wszFileName) + 1;
128c2c66affSColin Finck           ILFree(pidls[i]);
129c2c66affSColin Finck #else
130c2c66affSColin Finck 	  _ILSimpleGetTextW(apidl[i], wszFileName + rootlen, MAX_PATH - rootlen);
131c2c66affSColin Finck 	  strcpyW(((WCHAR*)pDropFiles)+offset, wszFileName);
132c2c66affSColin Finck 	  offset += strlenW(wszFileName) + 1;
133c2c66affSColin Finck #endif
134c2c66affSColin Finck 	}
135c2c66affSColin Finck 
136c2c66affSColin Finck 	((WCHAR*)pDropFiles)[offset] = 0;
137c2c66affSColin Finck 	GlobalUnlock(hGlobal);
138c2c66affSColin Finck 
139c2c66affSColin Finck #ifdef __REACTOS__
140c2c66affSColin Finck cleanup:
141c2c66affSColin Finck     if(pidls)
142c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, pidls);
143c2c66affSColin Finck #endif
144c2c66affSColin Finck 
145c2c66affSColin Finck 	return hGlobal;
146c2c66affSColin Finck }
147c2c66affSColin Finck 
RenderSHELLIDLIST(LPITEMIDLIST pidlRoot,LPITEMIDLIST * apidl,UINT cidl)148c2c66affSColin Finck HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
149c2c66affSColin Finck {
150c2c66affSColin Finck 	UINT i;
151c2c66affSColin Finck 	int offset = 0, sizePidl, size;
152c2c66affSColin Finck 	HGLOBAL hGlobal;
153c2c66affSColin Finck 	LPIDA	pcida;
154c2c66affSColin Finck 
155c2c66affSColin Finck 	TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
156c2c66affSColin Finck 
157c2c66affSColin Finck 	/* get the size needed */
158c2c66affSColin Finck 	size = sizeof(CIDA) + sizeof (UINT)*(cidl);	/* header */
159c2c66affSColin Finck 	size += ILGetSize (pidlRoot);			/* root pidl */
160c2c66affSColin Finck 	for(i=0; i<cidl; i++)
161c2c66affSColin Finck 	{
162c2c66affSColin Finck 	  size += ILGetSize(apidl[i]);			/* child pidls */
163c2c66affSColin Finck 	}
164c2c66affSColin Finck 
165c2c66affSColin Finck 	/* fill the structure */
166c2c66affSColin Finck 	hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
167c2c66affSColin Finck 	if(!hGlobal) return hGlobal;
168c2c66affSColin Finck 	pcida = GlobalLock (hGlobal);
169c2c66affSColin Finck 	pcida->cidl = cidl;
170c2c66affSColin Finck 
171c2c66affSColin Finck 	/* root pidl */
172c2c66affSColin Finck 	offset = sizeof(CIDA) + sizeof (UINT)*(cidl);
173c2c66affSColin Finck 	pcida->aoffset[0] = offset;			/* first element */
174c2c66affSColin Finck 	sizePidl = ILGetSize (pidlRoot);
175c2c66affSColin Finck 	memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl);
176c2c66affSColin Finck 	offset += sizePidl;
177c2c66affSColin Finck 
178c2c66affSColin Finck 	for(i=0; i<cidl; i++)				/* child pidls */
179c2c66affSColin Finck 	{
180c2c66affSColin Finck 	  pcida->aoffset[i+1] = offset;
181c2c66affSColin Finck 	  sizePidl = ILGetSize(apidl[i]);
182c2c66affSColin Finck 	  memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl);
183c2c66affSColin Finck 	  offset += sizePidl;
184c2c66affSColin Finck 	}
185c2c66affSColin Finck 
186c2c66affSColin Finck 	GlobalUnlock(hGlobal);
187c2c66affSColin Finck 	return hGlobal;
188c2c66affSColin Finck }
189c2c66affSColin Finck 
RenderFILENAMEA(LPITEMIDLIST pidlRoot,LPITEMIDLIST * apidl,UINT cidl)190c2c66affSColin Finck HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
191c2c66affSColin Finck {
192c2c66affSColin Finck 	int size = 0;
193c2c66affSColin Finck 	char szTemp[MAX_PATH], *szFileName;
194c2c66affSColin Finck 	LPITEMIDLIST pidl;
195c2c66affSColin Finck 	HGLOBAL hGlobal;
196c2c66affSColin Finck 	BOOL bSuccess;
197c2c66affSColin Finck 
198c2c66affSColin Finck 	TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
199c2c66affSColin Finck 
200c2c66affSColin Finck 	/* get path of combined pidl */
201c2c66affSColin Finck 	pidl = ILCombine(pidlRoot, apidl[0]);
202c2c66affSColin Finck 	if (!pidl)
203c2c66affSColin Finck 		return 0;
204c2c66affSColin Finck 
205c2c66affSColin Finck 	bSuccess = SHGetPathFromIDListA(pidl, szTemp);
206c2c66affSColin Finck 	SHFree(pidl);
207c2c66affSColin Finck 	if (!bSuccess)
208c2c66affSColin Finck 		return 0;
209c2c66affSColin Finck 
210c2c66affSColin Finck 	size = strlen(szTemp) + 1;
211c2c66affSColin Finck 
212c2c66affSColin Finck 	/* fill the structure */
213c2c66affSColin Finck 	hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
214c2c66affSColin Finck 	if(!hGlobal) return hGlobal;
215c2c66affSColin Finck 	szFileName = GlobalLock(hGlobal);
216c2c66affSColin Finck 	memcpy(szFileName, szTemp, size);
217c2c66affSColin Finck 	GlobalUnlock(hGlobal);
218c2c66affSColin Finck 
219c2c66affSColin Finck 	return hGlobal;
220c2c66affSColin Finck }
221c2c66affSColin Finck 
RenderFILENAMEW(LPITEMIDLIST pidlRoot,LPITEMIDLIST * apidl,UINT cidl)222c2c66affSColin Finck HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
223c2c66affSColin Finck {
224c2c66affSColin Finck 	int size = 0;
225c2c66affSColin Finck 	WCHAR szTemp[MAX_PATH], *szFileName;
226c2c66affSColin Finck 	LPITEMIDLIST pidl;
227c2c66affSColin Finck 	HGLOBAL hGlobal;
228c2c66affSColin Finck 	BOOL bSuccess;
229c2c66affSColin Finck 
230c2c66affSColin Finck 	TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
231c2c66affSColin Finck 
232c2c66affSColin Finck 	/* get path of combined pidl */
233c2c66affSColin Finck 	pidl = ILCombine(pidlRoot, apidl[0]);
234c2c66affSColin Finck 	if (!pidl)
235c2c66affSColin Finck 		return 0;
236c2c66affSColin Finck 
237c2c66affSColin Finck 	bSuccess = SHGetPathFromIDListW(pidl, szTemp);
238c2c66affSColin Finck 	SHFree(pidl);
239c2c66affSColin Finck 	if (!bSuccess)
240c2c66affSColin Finck 		return 0;
241c2c66affSColin Finck 
242c2c66affSColin Finck 	size = (strlenW(szTemp)+1) * sizeof(WCHAR);
243c2c66affSColin Finck 
244c2c66affSColin Finck 	/* fill the structure */
245c2c66affSColin Finck 	hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
246c2c66affSColin Finck 	if(!hGlobal) return hGlobal;
247c2c66affSColin Finck 	szFileName = GlobalLock(hGlobal);
248c2c66affSColin Finck 	memcpy(szFileName, szTemp, size);
249c2c66affSColin Finck 	GlobalUnlock(hGlobal);
250c2c66affSColin Finck 
251c2c66affSColin Finck 	return hGlobal;
252c2c66affSColin Finck }
253