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