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 #define WIN32_NO_STATUS 39 #define _INC_WINDOWS 40 41 #include <windef.h> 42 #include <winbase.h> 43 #include <shlobj.h> 44 #include <wine/debug.h> 45 #include <wine/unicode.h> 46 47 #include "shell32_main.h" 48 49 WINE_DEFAULT_DEBUG_CHANNEL(shell); 50 51 /************************************************************************** 52 * RenderHDROP 53 * 54 * creates a CF_HDROP structure 55 */ 56 HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) 57 { 58 UINT i; 59 #ifdef __REACTOS__ 60 int size = 0; 61 #else 62 int rootlen = 0,size = 0; 63 WCHAR wszRootPath[MAX_PATH]; 64 #endif 65 WCHAR wszFileName[MAX_PATH]; 66 HGLOBAL hGlobal = NULL; 67 DROPFILES *pDropFiles; 68 int offset; 69 #ifdef __REACTOS__ 70 LPITEMIDLIST *pidls; 71 #endif 72 73 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); 74 75 #ifdef __REACTOS__ 76 pidls = (LPITEMIDLIST *)HeapAlloc(GetProcessHeap(), 0, cidl * sizeof(*pidls)); 77 if (!pidls) 78 goto cleanup; 79 #endif 80 81 /* get the size needed */ 82 size = sizeof(DROPFILES); 83 84 #ifndef __REACTOS__ 85 SHGetPathFromIDListW(pidlRoot, wszRootPath); 86 PathAddBackslashW(wszRootPath); 87 rootlen = strlenW(wszRootPath); 88 #endif 89 90 for (i=0; i<cidl;i++) 91 { 92 #ifdef __REACTOS__ 93 pidls[i] = ILCombine(pidlRoot, apidl[i]); 94 SHGetPathFromIDListW(pidls[i], wszFileName); 95 size += (wcslen(wszFileName) + 1) * sizeof(WCHAR); 96 #else 97 _ILSimpleGetTextW(apidl[i], wszFileName, MAX_PATH); 98 size += (rootlen + strlenW(wszFileName) + 1) * sizeof(WCHAR); 99 #endif 100 } 101 102 size += sizeof(WCHAR); 103 104 /* Fill the structure */ 105 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); 106 #ifdef __REACTOS__ 107 if(!hGlobal) goto cleanup; 108 #else 109 if(!hGlobal) return hGlobal; 110 #endif 111 112 pDropFiles = GlobalLock(hGlobal); 113 offset = (sizeof(DROPFILES) + sizeof(WCHAR) - 1) / sizeof(WCHAR); 114 pDropFiles->pFiles = offset * sizeof(WCHAR); 115 pDropFiles->fWide = TRUE; 116 117 #ifndef __REACTOS__ 118 strcpyW(wszFileName, wszRootPath); 119 #endif 120 121 for (i=0; i<cidl;i++) 122 { 123 124 #ifdef __REACTOS__ 125 SHGetPathFromIDListW(pidls[i], wszFileName); 126 wcscpy(((WCHAR*)pDropFiles)+offset, wszFileName); 127 offset += wcslen(wszFileName) + 1; 128 ILFree(pidls[i]); 129 #else 130 _ILSimpleGetTextW(apidl[i], wszFileName + rootlen, MAX_PATH - rootlen); 131 strcpyW(((WCHAR*)pDropFiles)+offset, wszFileName); 132 offset += strlenW(wszFileName) + 1; 133 #endif 134 } 135 136 ((WCHAR*)pDropFiles)[offset] = 0; 137 GlobalUnlock(hGlobal); 138 139 #ifdef __REACTOS__ 140 cleanup: 141 if(pidls) 142 HeapFree(GetProcessHeap(), 0, pidls); 143 #endif 144 145 return hGlobal; 146 } 147 148 HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) 149 { 150 UINT i; 151 int offset = 0, sizePidl, size; 152 HGLOBAL hGlobal; 153 LPIDA pcida; 154 155 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); 156 157 /* get the size needed */ 158 size = sizeof(CIDA) + sizeof (UINT)*(cidl); /* header */ 159 size += ILGetSize (pidlRoot); /* root pidl */ 160 for(i=0; i<cidl; i++) 161 { 162 size += ILGetSize(apidl[i]); /* child pidls */ 163 } 164 165 /* fill the structure */ 166 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); 167 if(!hGlobal) return hGlobal; 168 pcida = GlobalLock (hGlobal); 169 pcida->cidl = cidl; 170 171 /* root pidl */ 172 offset = sizeof(CIDA) + sizeof (UINT)*(cidl); 173 pcida->aoffset[0] = offset; /* first element */ 174 sizePidl = ILGetSize (pidlRoot); 175 memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl); 176 offset += sizePidl; 177 178 for(i=0; i<cidl; i++) /* child pidls */ 179 { 180 pcida->aoffset[i+1] = offset; 181 sizePidl = ILGetSize(apidl[i]); 182 memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl); 183 offset += sizePidl; 184 } 185 186 GlobalUnlock(hGlobal); 187 return hGlobal; 188 } 189 190 HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) 191 { 192 int size = 0; 193 char szTemp[MAX_PATH], *szFileName; 194 LPITEMIDLIST pidl; 195 HGLOBAL hGlobal; 196 BOOL bSuccess; 197 198 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); 199 200 /* get path of combined pidl */ 201 pidl = ILCombine(pidlRoot, apidl[0]); 202 if (!pidl) 203 return 0; 204 205 bSuccess = SHGetPathFromIDListA(pidl, szTemp); 206 SHFree(pidl); 207 if (!bSuccess) 208 return 0; 209 210 size = strlen(szTemp) + 1; 211 212 /* fill the structure */ 213 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); 214 if(!hGlobal) return hGlobal; 215 szFileName = GlobalLock(hGlobal); 216 memcpy(szFileName, szTemp, size); 217 GlobalUnlock(hGlobal); 218 219 return hGlobal; 220 } 221 222 HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) 223 { 224 int size = 0; 225 WCHAR szTemp[MAX_PATH], *szFileName; 226 LPITEMIDLIST pidl; 227 HGLOBAL hGlobal; 228 BOOL bSuccess; 229 230 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); 231 232 /* get path of combined pidl */ 233 pidl = ILCombine(pidlRoot, apidl[0]); 234 if (!pidl) 235 return 0; 236 237 bSuccess = SHGetPathFromIDListW(pidl, szTemp); 238 SHFree(pidl); 239 if (!bSuccess) 240 return 0; 241 242 size = (strlenW(szTemp)+1) * sizeof(WCHAR); 243 244 /* fill the structure */ 245 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); 246 if(!hGlobal) return hGlobal; 247 szFileName = GlobalLock(hGlobal); 248 memcpy(szFileName, szTemp, size); 249 GlobalUnlock(hGlobal); 250 251 return hGlobal; 252 } 253