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