4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
7 * IShellFolder2 and related interfaces
15 #include "debugtools.h"
23 #include "wine/obj_base.h"
24 #include "wine/obj_dragdrop.h"
25 #include "wine/obj_shellfolder.h"
26 #include "undocshell.h"
27 #include "shell32_main.h"
30 #include "shellfolder.h"
32 DEFAULT_DEBUG_CHANNEL(shell);
35 /***************************************************************************
36 * debughelper: print out the return adress
37 * helps especially to track down unbalanced AddRef/Release
42 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
56 /***************************************************************************
57 * GetNextElement (internal function)
59 * gets a part of a string till the first backslash
62 * pszNext [IN] string to get the element from
63 * pszOut [IN] pointer to buffer whitch receives string
64 * dwOut [IN] length of pszOut
67 * LPSTR pointer to first, not yet parsed char
70 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
71 { LPCWSTR pszTail = pszNext;
73 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
77 if(!pszNext || !*pszNext)
80 while(*pszTail && (*pszTail != (WCHAR)'\\'))
83 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
84 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
91 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
95 static HRESULT SHELL32_ParseNextElement(
98 LPITEMIDLIST * pidlInOut,
101 DWORD *pdwAttributes)
103 HRESULT hr = E_OUTOFMEMORY;
104 LPITEMIDLIST pidlOut, pidlTemp = NULL;
105 IShellFolder *psfChild;
107 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
110 /* get the shellfolder for the child pidl and let it analyse further */
111 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
115 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
116 IShellFolder_Release(psfChild);
118 pidlTemp = ILCombine(*pidlInOut, pidlOut);
125 *pidlInOut = pidlTemp;
127 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
131 /***********************************************************************
132 * SHELL32_CoCreateInitSF
134 * creates a initialized shell folder
136 static HRESULT SHELL32_CoCreateInitSF (
137 LPITEMIDLIST pidlRoot,
138 LPITEMIDLIST pidlChild,
144 LPITEMIDLIST absPidl;
145 IShellFolder2 *pShellFolder;
146 IPersistFolder *pPersistFolder;
148 TRACE("%p %p\n", pidlRoot, pidlChild);
152 /* we have to ask first for IPersistFolder, some special folders are expecting this */
153 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
156 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
159 absPidl = ILCombine (pidlRoot, pidlChild);
160 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
161 IPersistFolder_Release(pPersistFolder);
163 *ppvOut = pShellFolder;
167 TRACE("-- ret=0x%08lx\n", hr);
171 static HRESULT SHELL32_GetDisplayNameOfChild(
178 LPITEMIDLIST pidlFirst, pidlNext;
179 IShellFolder2 * psfChild;
180 HRESULT hr = E_OUTOFMEMORY;
183 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
186 if ((pidlFirst = ILCloneFirst(pidl)))
188 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
191 pidlNext = ILGetNext(pidl);
193 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
196 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
199 IShellFolder_Release(psfChild);
204 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
209 /***********************************************************************
210 * SHELL32_GetItemAttributes
214 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
215 * file: 0x40000177 FILESYSTEM
216 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
217 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
218 * (seems to be default for shell extensions if no registry entry exists)
220 * This functions does not set flags!! It only resets flags when nessesary.
222 static HRESULT SHELL32_GetItemAttributes(
225 LPDWORD pdwAttributes)
230 TRACE("0x%08lx\n", *pdwAttributes);
232 if (*pdwAttributes & (0xcff3fe88))
233 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
234 *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
236 if (_ILIsDrive(pidl))
238 *pdwAttributes &= 0xf0000144;
240 else if ((clsid=_ILGetGUIDPointer(pidl)))
242 if (HCR_GetFolderAttributes(clsid, &dwAttributes))
244 *pdwAttributes &= dwAttributes;
248 *pdwAttributes &= 0xb0000154;
251 else if (_ILGetDataPointer(pidl))
253 dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
254 *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
256 if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
257 *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
259 if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
260 *pdwAttributes &= ~SFGAO_HIDDEN;
262 if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
263 *pdwAttributes &= ~SFGAO_READONLY;
267 *pdwAttributes &= 0xb0000154;
269 TRACE("-- 0x%08lx\n", *pdwAttributes);
273 /***********************************************************************
274 * IShellFolder implementation
279 ICOM_VFIELD(IUnknown);
281 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
282 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
283 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
284 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
286 IUnknown *pUnkOuter; /* used for aggregation */
291 LPITEMIDLIST absPidl; /* complete pidl */
293 UINT cfShellIDList; /* clipboardformat for IDropTarget */
294 BOOL fAcceptFmt; /* flag for pending Drop */
297 static struct ICOM_VTABLE(IUnknown) unkvt;
298 static struct ICOM_VTABLE(IShellFolder2) sfvt;
299 static struct ICOM_VTABLE(IPersistFolder2) psfvt;
300 static struct ICOM_VTABLE(IDropTarget) dtvt;
301 static struct ICOM_VTABLE(ISFHelper) shvt;
303 static IShellFolder * ISF_MyComputer_Constructor(void);
305 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
306 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
308 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
309 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
311 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
312 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
314 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
315 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
317 converts This to a interface pointer
319 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
320 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
321 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
322 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
323 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
324 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
325 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
326 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
327 /**************************************************************************
328 * registers clipboardformat once
330 static void SF_RegisterClipFmt (IGenericSFImpl * This)
332 TRACE("(%p)\n", This);
334 if (!This->cfShellIDList)
336 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
340 /**************************************************************************
341 * we need a separate IUnknown to handle aggregation
344 static HRESULT WINAPI IUnknown_fnQueryInterface(
349 ICOM_THIS(IGenericSFImpl, iface);
352 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
356 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
357 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
358 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
359 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
360 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
361 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
362 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
363 else if(IsEqualIID(riid, &IID_IDropTarget))
365 *ppvObj = _IDropTarget_(This);
366 SF_RegisterClipFmt(This);
371 IUnknown_AddRef((IUnknown*)(*ppvObj));
372 TRACE("-- Interface = %p\n", *ppvObj);
375 TRACE("-- Interface: E_NOINTERFACE\n");
376 return E_NOINTERFACE;
379 static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
381 ICOM_THIS(IGenericSFImpl, iface);
384 TRACE("(%p)->(count=%lu)\n",This,This->ref);
387 return ++(This->ref);
390 static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
392 ICOM_THIS(IGenericSFImpl, iface);
395 TRACE("(%p)->(count=%lu)\n",This,This->ref);
400 TRACE("-- destroying IShellFolder(%p)\n",This);
402 if (pdesktopfolder == _IShellFolder_(This))
405 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
407 if(This->absPidl) SHFree(This->absPidl);
408 if(This->sMyPath) SHFree(This->sMyPath);
409 HeapFree(GetProcessHeap(),0,This);
415 static ICOM_VTABLE(IUnknown) unkvt =
417 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
418 IUnknown_fnQueryInterface,
423 static shvheader GenericSFHeader [] =
425 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
426 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
427 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
428 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
429 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
431 #define GENERICSHELLVIEWCOLUMNS 5
433 /**************************************************************************
434 * IShellFolder_Constructor
437 * creating undocumented ShellFS_Folder as part of an aggregation
438 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
441 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
443 HRESULT IFSFolder_Constructor(
444 IUnknown * pUnkOuter,
451 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
453 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
455 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
459 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
463 ICOM_VTBL(sf)=&unkvt;
464 sf->lpvtblShellFolder=&sfvt;
465 sf->lpvtblPersistFolder2=&psfvt;
466 sf->lpvtblDropTarget=&dtvt;
467 sf->lpvtblSFHelper=&shvt;
469 sf->pclsid = (CLSID*)&CLSID_SFFile;
470 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
471 *ppv = _IUnknown_(sf);
482 /**************************************************************************
483 * IShellFolder_Constructor
486 * THIS points to the parent folder
489 IShellFolder * IShellFolder_Constructor(
490 IShellFolder2 * iface,
496 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
498 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
501 ICOM_VTBL(sf)=&unkvt;
502 sf->lpvtblShellFolder=&sfvt;
503 sf->lpvtblPersistFolder2=&psfvt;
504 sf->lpvtblDropTarget=&dtvt;
505 sf->lpvtblSFHelper=&shvt;
507 sf->pclsid = (CLSID*)&CLSID_SFFile;
508 sf->pUnkOuter = _IUnknown_(sf);
510 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
513 if(pidl && iface) /* do we have a pidl? */
517 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
519 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
521 if(This->sMyPath) /* get the size of the parents path */
523 dwSize += strlen(This->sMyPath) ;
524 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
527 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
528 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
530 if(!sf->sMyPath) return NULL;
533 if(This->sMyPath) /* if the parent has a path, get it*/
535 strcpy(sf->sMyPath, This->sMyPath);
536 PathAddBackslashA (sf->sMyPath);
539 len = strlen(sf->sMyPath);
540 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
543 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
549 return _IShellFolder_(sf);
552 /**************************************************************************
553 * IShellFolder_fnQueryInterface
556 * REFIID riid [in ] Requested InterfaceID
557 * LPVOID* ppvObject [out] Interface* to hold the result
559 static HRESULT WINAPI IShellFolder_fnQueryInterface(
560 IShellFolder2 * iface,
564 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
567 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
569 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
572 /**************************************************************************
573 * IShellFolder_AddRef
576 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
578 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
581 TRACE("(%p)->(count=%lu)\n",This,This->ref);
583 return IUnknown_AddRef(This->pUnkOuter);
586 /**************************************************************************
587 * IShellFolder_fnRelease
589 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
591 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
594 TRACE("(%p)->(count=%lu)\n",This,This->ref);
596 return IUnknown_Release(This->pUnkOuter);
599 /**************************************************************************
600 * IShellFolder_fnParseDisplayName
602 * HWND hwndOwner, //[in ] Parent window for any message's
603 * LPBC pbc, //[in ] reserved
604 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
605 * ULONG* pchEaten, //[out] (unicode) characters processed
606 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
607 * ULONG* pdwAttributes //[out] items attributes
610 * every folder tries to parse only its own (the leftmost) pidl and creates a
611 * subfolder to evaluate the remaining parts
612 * now we can parse into namespaces implemented by shell extensions
614 * behaviour on win98: lpszDisplayName=NULL -> chrash
615 * lpszDisplayName="" -> returns mycoputer-pidl
618 * pdwAttributes: not set
619 * pchEaten: not set like in windows
621 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
622 IShellFolder2 * iface,
625 LPOLESTR lpszDisplayName,
628 DWORD *pdwAttributes)
630 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
632 HRESULT hr = E_OUTOFMEMORY;
634 WCHAR szElement[MAX_PATH];
635 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
636 LPITEMIDLIST pidlTemp=NULL;
638 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
639 This,hwndOwner,pbcReserved,lpszDisplayName,
640 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
642 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
644 if (pchEaten) *pchEaten = 0; /* strange but like the original */
646 if (*lpszDisplayName)
648 /* get the next element */
649 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
651 /* build the full pathname to the element */
652 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
653 strcpy(szPath, This->sMyPath);
654 PathAddBackslashA(szPath);
655 strcat(szPath, szTempA);
658 pidlTemp = SHSimpleIDListFromPathA(szPath);
662 /* try to analyse the next element */
663 if (szNext && *szNext)
665 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
669 if (pdwAttributes && *pdwAttributes)
671 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
672 /* WIN32_FIND_DATAA fd;
673 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
674 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
675 *pdwAttributes &= ~SFGAO_FOLDER;
676 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
677 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
690 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
695 /**************************************************************************
696 * IShellFolder_fnEnumObjects
698 * HWND hwndOwner, //[in ] Parent Window
699 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
700 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
702 static HRESULT WINAPI IShellFolder_fnEnumObjects(
703 IShellFolder2 * iface,
706 LPENUMIDLIST* ppEnumIDList)
708 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
710 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
712 *ppEnumIDList = NULL;
713 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
715 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
717 if(!*ppEnumIDList) return E_OUTOFMEMORY;
722 /**************************************************************************
723 * IShellFolder_fnBindToObject
725 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
726 * LPBC pbc, //[in ] reserved
727 * REFIID riid, //[in ] Initial Interface
728 * LPVOID* ppvObject //[out] Interface*
730 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
731 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
733 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
735 IShellFolder *pShellFolder, *pSubFolder;
736 IPersistFolder *pPersistFolder;
737 LPITEMIDLIST absPidl;
739 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
741 if(!pidl || !ppvOut) return E_INVALIDARG;
745 if ((iid=_ILGetGUIDPointer(pidl)))
747 /* we have to create a alien folder */
748 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
749 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
751 absPidl = ILCombine (This->absPidl, pidl);
752 IPersistFolder_Initialize(pPersistFolder, absPidl);
753 IPersistFolder_Release(pPersistFolder);
761 else if(_ILIsFolder(pidl))
763 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
764 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
769 ERR("can't bind to a file\n");
773 if (_ILIsPidlSimple(pidl))
775 *ppvOut = pShellFolder;
779 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
780 IShellFolder_Release(pShellFolder);
781 *ppvOut = pSubFolder;
784 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
789 /**************************************************************************
790 * IShellFolder_fnBindToStorage
792 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
793 * LPBC pbc, //[in ] reserved
794 * REFIID riid, //[in ] Initial storage interface
795 * LPVOID* ppvObject //[out] Interface* returned
797 static HRESULT WINAPI IShellFolder_fnBindToStorage(
798 IShellFolder2 * iface,
804 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
806 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
807 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
813 /**************************************************************************
814 * IShellFolder_fnCompareIDs
817 * LPARAM lParam, //[in ] Column?
818 * LPCITEMIDLIST pidl1, //[in ] simple pidl
819 * LPCITEMIDLIST pidl2) //[in ] simple pidl
822 * Special case - If one of the items is a Path and the other is a File,
823 * always make the Path come before the File.
826 * use SCODE_CODE() on the return value to get the result
829 static HRESULT WINAPI IShellFolder_fnCompareIDs(
830 IShellFolder2 * iface,
835 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
837 CHAR szTemp1[MAX_PATH];
838 CHAR szTemp2[MAX_PATH];
841 HRESULT hr = E_OUTOFMEMORY;
842 LPCITEMIDLIST pidlTemp;
845 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
849 if (!pidl1 && !pidl2)
851 hr = ResultFromShort(0);
855 hr = ResultFromShort(-1);
859 hr = ResultFromShort(1);
864 pd1 = _ILGetDataPointer(pidl1);
865 pd2 = _ILGetDataPointer(pidl2);
867 /* compate the types. sort order is the PT_* constant */
868 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
869 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
873 hr = ResultFromShort(pt1-pt2);
875 else /* same type of pidl */
877 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
878 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
879 nReturn = strcasecmp(szTemp1, szTemp2);
881 if (nReturn == 0) /* first pidl different ? */
883 pidl1 = ILGetNext(pidl1);
885 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
887 pidlTemp = ILCloneFirst(pidl1);
888 pidl2 = ILGetNext(pidl2);
890 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
893 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
894 IShellFolder_Release(psf);
895 hr = ResultFromShort(nReturn);
899 else /* no deeper on #1 */
901 pidl2 = ILGetNext(pidl2);
902 if (pidl2 && pidl2->mkid.cb) /* go deeper on #2 ? */
903 hr = ResultFromShort(-1); /* two different */
905 hr = ResultFromShort(nReturn); /* two equal simple pidls */
910 hr = ResultFromShort(nReturn); /* two different simple pidls */
915 TRACE("-- res=0x%08lx\n", hr);
919 /**************************************************************************
920 * IShellFolder_fnCreateViewObject
922 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
923 IShellFolder2 * iface,
928 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
930 LPSHELLVIEW pShellView;
931 HRESULT hr = E_INVALIDARG;
933 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
939 if(IsEqualIID(riid, &IID_IDropTarget))
941 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
943 else if(IsEqualIID(riid, &IID_IContextMenu))
945 FIXME("IContextMenu not implemented\n");
948 else if(IsEqualIID(riid, &IID_IShellView))
950 pShellView = IShellView_Constructor((IShellFolder*)iface);
953 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
954 IShellView_Release(pShellView);
958 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
962 /**************************************************************************
963 * IShellFolder_fnGetAttributesOf
966 * UINT cidl, //[in ] num elements in pidl array
967 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
968 * ULONG* rgfInOut) //[out] result array
971 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
972 IShellFolder2 * iface,
974 LPCITEMIDLIST *apidl,
977 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
981 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
983 if ( (!cidl) || (!apidl) || (!rgfInOut))
986 while (cidl > 0 && *apidl)
989 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
994 TRACE("-- result=0x%08lx\n",*rgfInOut);
998 /**************************************************************************
999 * IShellFolder_fnGetUIObjectOf
1002 * HWND hwndOwner, //[in ] Parent window for any output
1003 * UINT cidl, //[in ] array size
1004 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1005 * REFIID riid, //[in ] Requested Interface
1006 * UINT* prgfInOut, //[ ] reserved
1007 * LPVOID* ppvObject) //[out] Resulting Interface
1010 * This function gets asked to return "view objects" for one or more (multiple select)
1012 * The viewobject typically is an COM object with one of the following interfaces:
1013 * IExtractIcon,IDataObject,IContextMenu
1014 * In order to support icon positions in the default Listview your DataObject
1015 * must implement the SetData method (in addition to GetData :) - the shell passes
1016 * a barely documented "Icon positions" structure to SetData when the drag starts,
1017 * and GetData's it if the drop is in another explorer window that needs the positions.
1019 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1020 IShellFolder2 * iface,
1023 LPCITEMIDLIST * apidl,
1028 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1031 IUnknown* pObj = NULL;
1032 HRESULT hr = E_INVALIDARG;
1034 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1035 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1041 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1043 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1046 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1048 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1051 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1053 pidl = ILCombine(This->absPidl,apidl[0]);
1054 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1058 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1060 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1072 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1076 /**************************************************************************
1077 * IShellFolder_fnGetDisplayNameOf
1078 * Retrieves the display name for the specified file object or subfolder
1081 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1082 * DWORD dwFlags, //[in ] SHGNO formatting flags
1083 * LPSTRRET lpName) //[out] Returned display name
1086 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1088 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1089 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1091 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1092 IShellFolder2 * iface,
1097 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1099 CHAR szPath[MAX_PATH]= "";
1103 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1106 if(!pidl || !strRet) return E_INVALIDARG;
1108 bSimplePidl = _ILIsPidlSimple(pidl);
1110 /* take names of special folders only if its only this folder */
1111 if (_ILIsSpecialFolder(pidl))
1115 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1120 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1122 strcpy (szPath, This->sMyPath); /* get path to root*/
1123 PathAddBackslashA(szPath);
1124 len = strlen(szPath);
1126 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1129 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1131 PathAddBackslashA(szPath);
1132 len = strlen(szPath);
1134 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1135 return E_OUTOFMEMORY;
1137 strRet->uType = STRRET_CSTRA;
1138 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1140 TRACE("-- (%p)->(%s)\n", This, szPath);
1144 /**************************************************************************
1145 * IShellFolder_fnSetNameOf
1146 * Changes the name of a file object or subfolder, possibly changing its item
1147 * identifier in the process.
1150 * HWND hwndOwner, //[in ] Owner window for output
1151 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1152 * LPCOLESTR lpszName, //[in ] the items new display name
1153 * DWORD dwFlags, //[in ] SHGNO formatting flags
1154 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1156 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1157 IShellFolder2 * iface,
1159 LPCITEMIDLIST pidl, /*simple pidl*/
1162 LPITEMIDLIST *pPidlOut)
1164 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1165 char szSrc[MAX_PATH], szDest[MAX_PATH];
1167 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1169 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1170 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1172 /* build source path */
1173 if (dwFlags & SHGDN_INFOLDER)
1175 strcpy(szSrc, This->sMyPath);
1176 PathAddBackslashA(szSrc);
1177 len = strlen (szSrc);
1178 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1182 SHGetPathFromIDListA(pidl, szSrc);
1185 /* build destination path */
1186 strcpy(szDest, This->sMyPath);
1187 PathAddBackslashA(szDest);
1188 len = strlen (szDest);
1189 WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
1190 szDest[MAX_PATH-1] = 0;
1191 TRACE("src=%s dest=%s\n", szSrc, szDest);
1192 if ( MoveFileA(szSrc, szDest) )
1194 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1195 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1201 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1202 IShellFolder2 * iface,
1205 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1206 FIXME("(%p)\n",This);
1209 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1210 IShellFolder2 * iface,
1211 IEnumExtraSearch **ppenum)
1213 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1214 FIXME("(%p)\n",This);
1217 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1218 IShellFolder2 * iface,
1223 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1225 TRACE("(%p)\n",This);
1227 if (pSort) *pSort = 0;
1228 if (pDisplay) *pDisplay = 0;
1232 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1233 IShellFolder2 * iface,
1237 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1239 TRACE("(%p)\n",This);
1241 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1243 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1247 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1248 IShellFolder2 * iface,
1250 const SHCOLUMNID *pscid,
1253 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1254 FIXME("(%p)\n",This);
1258 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1259 IShellFolder2 * iface,
1264 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1265 HRESULT hr = E_FAIL;
1267 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1269 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1273 /* the header titles */
1274 psd->fmt = GenericSFHeader[iColumn].fmt;
1275 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1276 psd->str.uType = STRRET_CSTRA;
1277 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1282 /* the data from the pidl */
1286 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1289 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1292 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1295 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1297 case 4: /* attributes */
1298 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1302 psd->str.uType = STRRET_CSTRA;
1307 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1308 IShellFolder2 * iface,
1312 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1313 FIXME("(%p)\n",This);
1317 static ICOM_VTABLE(IShellFolder2) sfvt =
1319 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1320 IShellFolder_fnQueryInterface,
1321 IShellFolder_fnAddRef,
1322 IShellFolder_fnRelease,
1323 IShellFolder_fnParseDisplayName,
1324 IShellFolder_fnEnumObjects,
1325 IShellFolder_fnBindToObject,
1326 IShellFolder_fnBindToStorage,
1327 IShellFolder_fnCompareIDs,
1328 IShellFolder_fnCreateViewObject,
1329 IShellFolder_fnGetAttributesOf,
1330 IShellFolder_fnGetUIObjectOf,
1331 IShellFolder_fnGetDisplayNameOf,
1332 IShellFolder_fnSetNameOf,
1335 IShellFolder_fnGetDefaultSearchGUID,
1336 IShellFolder_fnEnumSearches,
1337 IShellFolder_fnGetDefaultColumn,
1338 IShellFolder_fnGetDefaultColumnState,
1339 IShellFolder_fnGetDetailsEx,
1340 IShellFolder_fnGetDetailsOf,
1341 IShellFolder_fnMapNameToSCID
1344 /****************************************************************************
1345 * ISFHelper for IShellFolder implementation
1348 static HRESULT WINAPI ISFHelper_fnQueryInterface(
1353 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1355 TRACE("(%p)\n", This);
1357 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1360 static ULONG WINAPI ISFHelper_fnAddRef(
1363 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1365 TRACE("(%p)\n", This);
1367 return IUnknown_AddRef(This->pUnkOuter);
1370 static ULONG WINAPI ISFHelper_fnRelease(
1373 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1375 TRACE("(%p)\n", This);
1377 return IUnknown_Release(This->pUnkOuter);
1381 /****************************************************************************
1382 * ISFHelper_fnAddFolder
1384 * creates a unique folder name
1387 static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1392 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1393 IEnumIDList * penum;
1395 char szText[MAX_PATH];
1396 char * szNewFolder = "New Folder";
1398 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1400 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1402 strcpy(lpName, szNewFolder);
1404 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1411 next: IEnumIDList_Reset(penum);
1412 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1414 _ILSimpleGetText(pidl, szText, MAX_PATH);
1415 if (0 == strcasecmp(szText, lpName))
1417 sprintf(lpName, "%s %d", szNewFolder, i++);
1427 IEnumIDList_Release(penum);
1432 /****************************************************************************
1433 * ISFHelper_fnAddFolder
1435 * adds a new folder.
1438 static HRESULT WINAPI ISFHelper_fnAddFolder(
1442 LPITEMIDLIST* ppidlOut)
1444 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1445 char lpstrNewDir[MAX_PATH];
1447 HRESULT hres = E_FAIL;
1449 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1451 strcpy(lpstrNewDir, This->sMyPath);
1452 PathAddBackslashA(lpstrNewDir);
1453 strcat(lpstrNewDir, lpName);
1455 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1459 LPITEMIDLIST pidl, pidlitem;
1461 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1463 pidl = ILCombine(This->absPidl, pidlitem);
1464 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1467 if (ppidlOut) *ppidlOut = pidlitem;
1472 char lpstrText[128+MAX_PATH];
1473 char lpstrTempText[128];
1474 char lpstrCaption[256];
1476 /* Cannot Create folder because of permissions */
1477 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1478 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1479 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1480 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1486 /****************************************************************************
1487 * ISFHelper_fnDeleteItems
1489 * deletes items in folder
1491 static HRESULT WINAPI ISFHelper_fnDeleteItems(
1494 LPCITEMIDLIST* apidl)
1496 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1498 char szPath[MAX_PATH];
1499 BOOL bConfirm = TRUE;
1501 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1503 /* deleting multiple items so give a slightly different warning */
1507 snprintf(tmp, sizeof(tmp), "%d", cidl);
1508 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM, tmp))
1513 for(i=0; i< cidl; i++)
1515 strcpy(szPath, This->sMyPath);
1516 PathAddBackslashA(szPath);
1517 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1519 if (_ILIsFolder(apidl[i]))
1522 TRACE("delete %s\n", szPath);
1523 if (! SHELL_DeleteDirectoryA(szPath, bConfirm))
1525 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1528 pidl = ILCombine(This->absPidl, apidl[i]);
1529 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1532 else if (_ILIsValue(apidl[i]))
1536 TRACE("delete %s\n", szPath);
1537 if (! SHELL_DeleteFileA(szPath, bConfirm))
1539 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1542 pidl = ILCombine(This->absPidl, apidl[i]);
1543 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1551 /****************************************************************************
1552 * ISFHelper_fnCopyItems
1554 * copys items to this folder
1556 static HRESULT WINAPI ISFHelper_fnCopyItems(
1558 IShellFolder* pSFFrom,
1560 LPCITEMIDLIST *apidl)
1563 IPersistFolder2 * ppf2=NULL;
1564 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1565 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1567 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1569 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1573 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1575 for (i=0; i<cidl; i++)
1577 SHGetPathFromIDListA(pidl, szSrcPath);
1578 PathAddBackslashA(szSrcPath);
1579 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1581 strcpy(szDstPath, This->sMyPath);
1582 PathAddBackslashA(szDstPath);
1583 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1584 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1588 IPersistFolder2_Release(ppf2);
1593 static ICOM_VTABLE(ISFHelper) shvt =
1595 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1596 ISFHelper_fnQueryInterface,
1598 ISFHelper_fnRelease,
1599 ISFHelper_fnGetUniqueName,
1600 ISFHelper_fnAddFolder,
1601 ISFHelper_fnDeleteItems,
1602 ISFHelper_fnCopyItems,
1605 /***********************************************************************
1606 * [Desktopfolder] IShellFolder implementation
1608 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1610 static shvheader DesktopSFHeader [] =
1612 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1613 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1614 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1615 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1616 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1618 #define DESKTOPSHELLVIEWCOLUMNS 5
1620 /**************************************************************************
1621 * ISF_Desktop_Constructor
1624 IShellFolder * ISF_Desktop_Constructor()
1626 IGenericSFImpl * sf;
1628 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1630 ICOM_VTBL(sf)=&unkvt;
1631 sf->lpvtblShellFolder=&sfdvt;
1632 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1633 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1638 return _IShellFolder_(sf);
1641 /**************************************************************************
1642 * ISF_Desktop_fnQueryInterface
1644 * NOTES supports not IPersist/IPersistFolder
1646 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1647 IShellFolder2 * iface,
1651 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1653 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1657 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1659 *ppvObj = _IUnknown_(This);
1661 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1663 *ppvObj = _IShellFolder_(This);
1665 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1667 *ppvObj = _IShellFolder_(This);
1672 IUnknown_AddRef((IUnknown*)(*ppvObj));
1673 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1676 TRACE("-- Interface: E_NOINTERFACE\n");
1677 return E_NOINTERFACE;
1680 /**************************************************************************
1681 * ISF_Desktop_fnParseDisplayName
1684 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1687 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1688 IShellFolder2 * iface,
1691 LPOLESTR lpszDisplayName,
1693 LPITEMIDLIST *ppidl,
1694 DWORD *pdwAttributes)
1696 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1698 LPCWSTR szNext=NULL;
1699 LPITEMIDLIST pidlTemp=NULL;
1700 HRESULT hr=E_OUTOFMEMORY;
1702 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1703 This,hwndOwner,pbcReserved,lpszDisplayName,
1704 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1707 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1709 /* fixme no real parsing implemented */
1710 pidlTemp = _ILCreateMyComputer();
1711 szNext = lpszDisplayName;
1713 if (szNext && *szNext)
1715 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1721 if (pdwAttributes && *pdwAttributes)
1723 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1729 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1734 /**************************************************************************
1735 * ISF_Desktop_fnEnumObjects
1737 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1738 IShellFolder2 * iface,
1741 LPENUMIDLIST* ppEnumIDList)
1743 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1745 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1747 *ppEnumIDList = NULL;
1748 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1750 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1752 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1757 /**************************************************************************
1758 * ISF_Desktop_fnBindToObject
1760 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1761 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1763 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1765 IShellFolder *pShellFolder, *pSubFolder;
1767 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1768 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1772 if ((clsid=_ILGetGUIDPointer(pidl)))
1774 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1776 pShellFolder = ISF_MyComputer_Constructor();
1780 /* shell extension */
1781 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1783 return E_INVALIDARG;
1789 /* file system folder on the desktop */
1790 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1791 IPersistFolder * ppf;
1794 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1795 firstpidl = ILCloneFirst(pidl);
1796 completepidl = ILCombine(deskpidl, firstpidl);
1798 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1799 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1801 IPersistFolder_Initialize(ppf, completepidl);
1802 IPersistFolder_Release(ppf);
1804 ILFree(completepidl);
1809 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1811 *ppvOut = pShellFolder;
1813 else /* go deeper */
1815 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1816 IShellFolder_Release(pShellFolder);
1817 *ppvOut = pSubFolder;
1820 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1825 /**************************************************************************
1826 * ISF_Desktop_fnCreateViewObject
1828 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1829 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1831 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1833 LPSHELLVIEW pShellView;
1834 HRESULT hr = E_INVALIDARG;
1836 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1842 if(IsEqualIID(riid, &IID_IDropTarget))
1844 WARN("IDropTarget not implemented\n");
1847 else if(IsEqualIID(riid, &IID_IContextMenu))
1849 WARN("IContextMenu not implemented\n");
1852 else if(IsEqualIID(riid, &IID_IShellView))
1854 pShellView = IShellView_Constructor((IShellFolder*)iface);
1857 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1858 IShellView_Release(pShellView);
1862 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1866 /**************************************************************************
1867 * ISF_Desktop_fnGetAttributesOf
1869 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1870 IShellFolder2 * iface,
1872 LPCITEMIDLIST *apidl,
1875 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1879 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1881 if ( (!cidl) || (!apidl) || (!rgfInOut))
1882 return E_INVALIDARG;
1884 while (cidl > 0 && *apidl)
1887 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1892 TRACE("-- result=0x%08lx\n",*rgfInOut);
1897 /**************************************************************************
1898 * ISF_Desktop_fnGetDisplayNameOf
1901 * special case: pidl = null gives desktop-name back
1903 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1904 IShellFolder2 * iface,
1909 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1911 CHAR szPath[MAX_PATH]= "";
1913 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1916 if(!strRet) return E_INVALIDARG;
1920 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1922 else if ( _ILIsPidlSimple(pidl) )
1924 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1928 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1929 return E_OUTOFMEMORY;
1931 strRet->uType = STRRET_CSTRA;
1932 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1935 TRACE("-- (%p)->(%s)\n", This, szPath);
1939 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1940 IShellFolder2 * iface,
1943 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1944 FIXME("(%p)\n",This);
1947 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1948 IShellFolder2 * iface,
1949 IEnumExtraSearch **ppenum)
1951 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1952 FIXME("(%p)\n",This);
1955 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1956 IShellFolder2 * iface,
1961 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1963 TRACE("(%p)\n",This);
1965 if (pSort) *pSort = 0;
1966 if (pDisplay) *pDisplay = 0;
1970 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1971 IShellFolder2 * iface,
1975 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1977 TRACE("(%p)\n",This);
1979 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1981 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1985 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1986 IShellFolder2 * iface,
1988 const SHCOLUMNID *pscid,
1991 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1992 FIXME("(%p)\n",This);
1996 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
1997 IShellFolder2 * iface,
2002 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2003 HRESULT hr = E_FAIL;;
2005 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2007 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2011 psd->fmt = DesktopSFHeader[iColumn].fmt;
2012 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
2013 psd->str.uType = STRRET_CSTRA;
2014 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2019 /* the data from the pidl */
2023 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2026 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2029 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2032 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2034 case 4: /* attributes */
2035 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2039 psd->str.uType = STRRET_CSTRA;
2044 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2045 IShellFolder2 * iface,
2049 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2050 FIXME("(%p)\n",This);
2054 static ICOM_VTABLE(IShellFolder2) sfdvt =
2056 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2057 ISF_Desktop_fnQueryInterface,
2058 IShellFolder_fnAddRef,
2059 IShellFolder_fnRelease,
2060 ISF_Desktop_fnParseDisplayName,
2061 ISF_Desktop_fnEnumObjects,
2062 ISF_Desktop_fnBindToObject,
2063 IShellFolder_fnBindToStorage,
2064 IShellFolder_fnCompareIDs,
2065 ISF_Desktop_fnCreateViewObject,
2066 ISF_Desktop_fnGetAttributesOf,
2067 IShellFolder_fnGetUIObjectOf,
2068 ISF_Desktop_fnGetDisplayNameOf,
2069 IShellFolder_fnSetNameOf,
2072 ISF_Desktop_fnGetDefaultSearchGUID,
2073 ISF_Desktop_fnEnumSearches,
2074 ISF_Desktop_fnGetDefaultColumn,
2075 ISF_Desktop_fnGetDefaultColumnState,
2076 ISF_Desktop_fnGetDetailsEx,
2077 ISF_Desktop_fnGetDetailsOf,
2078 ISF_Desktop_fnMapNameToSCID
2082 /***********************************************************************
2083 * IShellFolder [MyComputer] implementation
2086 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2088 static shvheader MyComputerSFHeader [] =
2090 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2091 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2092 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2093 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2095 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2097 /**************************************************************************
2098 * ISF_MyComputer_Constructor
2100 static IShellFolder * ISF_MyComputer_Constructor(void)
2102 IGenericSFImpl * sf;
2104 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2107 ICOM_VTBL(sf)=&unkvt;
2108 sf->lpvtblShellFolder=&sfmcvt;
2109 sf->lpvtblPersistFolder2 = &psfvt;
2110 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2111 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2112 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2117 return _IShellFolder_(sf);
2120 /**************************************************************************
2121 * ISF_MyComputer_fnParseDisplayName
2123 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2124 IShellFolder2 * iface,
2127 LPOLESTR lpszDisplayName,
2129 LPITEMIDLIST *ppidl,
2130 DWORD *pdwAttributes)
2132 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2134 HRESULT hr = E_OUTOFMEMORY;
2135 LPCWSTR szNext=NULL;
2136 WCHAR szElement[MAX_PATH];
2137 CHAR szTempA[MAX_PATH];
2138 LPITEMIDLIST pidlTemp;
2140 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2141 This,hwndOwner,pbcReserved,lpszDisplayName,
2142 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2145 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2147 /* do we have an absolute path name ? */
2148 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2149 lpszDisplayName[2] == (WCHAR)'\\')
2151 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2152 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
2153 pidlTemp = _ILCreateDrive(szTempA);
2155 if (szNext && *szNext)
2157 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2161 if (pdwAttributes && *pdwAttributes)
2163 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2170 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2175 /**************************************************************************
2176 * ISF_MyComputer_fnEnumObjects
2178 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2179 IShellFolder2 * iface,
2182 LPENUMIDLIST* ppEnumIDList)
2184 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2186 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2188 *ppEnumIDList = NULL;
2189 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2191 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2193 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2198 /**************************************************************************
2199 * ISF_MyComputer_fnBindToObject
2201 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2202 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2204 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2206 IShellFolder *pShellFolder, *pSubFolder;
2207 LPITEMIDLIST pidltemp;
2209 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2210 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2212 if(!pidl || !ppvOut) return E_INVALIDARG;
2216 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2218 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2225 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2227 pidltemp = ILCloneFirst(pidl);
2228 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2232 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2234 *ppvOut = pShellFolder;
2236 else /* go deeper */
2238 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
2239 IShellFolder_Release(pShellFolder);
2240 *ppvOut = pSubFolder;
2243 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
2248 /**************************************************************************
2249 * ISF_MyComputer_fnCreateViewObject
2251 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2252 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2254 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2256 LPSHELLVIEW pShellView;
2257 HRESULT hr = E_INVALIDARG;
2259 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2265 if(IsEqualIID(riid, &IID_IDropTarget))
2267 WARN("IDropTarget not implemented\n");
2270 else if(IsEqualIID(riid, &IID_IContextMenu))
2272 WARN("IContextMenu not implemented\n");
2275 else if(IsEqualIID(riid, &IID_IShellView))
2277 pShellView = IShellView_Constructor((IShellFolder*)iface);
2280 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2281 IShellView_Release(pShellView);
2285 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2289 /**************************************************************************
2290 * ISF_MyComputer_fnGetAttributesOf
2292 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2293 IShellFolder2 * iface,
2295 LPCITEMIDLIST *apidl,
2298 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2302 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2304 if ( (!cidl) || (!apidl) || (!rgfInOut))
2305 return E_INVALIDARG;
2307 while (cidl > 0 && *apidl)
2310 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2315 TRACE("-- result=0x%08lx\n",*rgfInOut);
2319 /**************************************************************************
2320 * ISF_MyComputer_fnGetDisplayNameOf
2323 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2324 * SHGDN_INFOLDER makes no sense.
2326 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2327 IShellFolder2 * iface,
2332 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2334 char szPath[MAX_PATH], szDrive[18];
2338 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2341 if(!strRet) return E_INVALIDARG;
2343 szPath[0]=0x00; szDrive[0]=0x00;
2346 bSimplePidl = _ILIsPidlSimple(pidl);
2348 if (_ILIsSpecialFolder(pidl))
2350 /* take names of special folders only if its only this folder */
2353 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2358 if (!_ILIsDrive(pidl))
2360 ERR("Wrong pidl type\n");
2361 return E_INVALIDARG;
2364 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2366 /* long view "lw_name (C:)" */
2367 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2369 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2371 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2372 strcat (szDrive," (");
2373 strncat (szDrive, szPath, 2);
2374 strcat (szDrive,")");
2375 strcpy (szPath, szDrive);
2379 if (!bSimplePidl) /* go deeper if needed */
2381 PathAddBackslashA(szPath);
2382 len = strlen(szPath);
2384 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2385 return E_OUTOFMEMORY;
2387 strRet->uType = STRRET_CSTRA;
2388 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2391 TRACE("-- (%p)->(%s)\n", This, szPath);
2395 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2396 IShellFolder2 * iface,
2399 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2400 FIXME("(%p)\n",This);
2403 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2404 IShellFolder2 * iface,
2405 IEnumExtraSearch **ppenum)
2407 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2408 FIXME("(%p)\n",This);
2411 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2412 IShellFolder2 * iface,
2417 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2419 TRACE("(%p)\n",This);
2421 if (pSort) *pSort = 0;
2422 if (pDisplay) *pDisplay = 0;
2426 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2427 IShellFolder2 * iface,
2431 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2433 TRACE("(%p)\n",This);
2435 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2437 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2441 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2442 IShellFolder2 * iface,
2444 const SHCOLUMNID *pscid,
2447 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2448 FIXME("(%p)\n",This);
2453 /* fixme: drive size >4GB is rolling over */
2454 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2455 IShellFolder2 * iface,
2460 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2463 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2465 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2469 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2470 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2471 psd->str.uType = STRRET_CSTRA;
2472 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2477 char szPath[MAX_PATH];
2478 ULARGE_INTEGER ulBytes;
2480 psd->str.u.cStr[0] = 0x00;
2481 psd->str.uType = STRRET_CSTRA;
2485 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2488 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2490 case 2: /* total size */
2491 if (_ILIsDrive(pidl))
2493 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2494 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2495 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2498 case 3: /* free size */
2499 if (_ILIsDrive(pidl))
2501 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2502 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2503 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2512 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2513 IShellFolder2 * iface,
2517 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2518 FIXME("(%p)\n",This);
2522 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2524 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2525 IShellFolder_fnQueryInterface,
2526 IShellFolder_fnAddRef,
2527 IShellFolder_fnRelease,
2528 ISF_MyComputer_fnParseDisplayName,
2529 ISF_MyComputer_fnEnumObjects,
2530 ISF_MyComputer_fnBindToObject,
2531 IShellFolder_fnBindToStorage,
2532 IShellFolder_fnCompareIDs,
2533 ISF_MyComputer_fnCreateViewObject,
2534 ISF_MyComputer_fnGetAttributesOf,
2535 IShellFolder_fnGetUIObjectOf,
2536 ISF_MyComputer_fnGetDisplayNameOf,
2537 IShellFolder_fnSetNameOf,
2540 ISF_MyComputer_fnGetDefaultSearchGUID,
2541 ISF_MyComputer_fnEnumSearches,
2542 ISF_MyComputer_fnGetDefaultColumn,
2543 ISF_MyComputer_fnGetDefaultColumnState,
2544 ISF_MyComputer_fnGetDetailsEx,
2545 ISF_MyComputer_fnGetDetailsOf,
2546 ISF_MyComputer_fnMapNameToSCID
2550 /************************************************************************
2551 * ISFPersistFolder_QueryInterface (IUnknown)
2554 static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2555 IPersistFolder2 * iface,
2559 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2561 TRACE("(%p)\n", This);
2563 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2566 /************************************************************************
2567 * ISFPersistFolder_AddRef (IUnknown)
2570 static ULONG WINAPI ISFPersistFolder2_AddRef(
2571 IPersistFolder2 * iface)
2573 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2575 TRACE("(%p)\n", This);
2577 return IUnknown_AddRef(This->pUnkOuter);
2580 /************************************************************************
2581 * ISFPersistFolder_Release (IUnknown)
2584 static ULONG WINAPI ISFPersistFolder2_Release(
2585 IPersistFolder2 * iface)
2587 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2589 TRACE("(%p)\n", This);
2591 return IUnknown_Release(This->pUnkOuter);
2594 /************************************************************************
2595 * ISFPersistFolder_GetClassID (IPersist)
2597 static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2598 IPersistFolder2 * iface,
2601 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2603 TRACE("(%p)\n", This);
2605 if (!lpClassId) return E_POINTER;
2606 *lpClassId = *This->pclsid;
2611 /************************************************************************
2612 * ISFPersistFolder_Initialize (IPersistFolder)
2615 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2617 static HRESULT WINAPI ISFPersistFolder2_Initialize(
2618 IPersistFolder2 * iface,
2621 char sTemp[MAX_PATH];
2622 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2624 TRACE("(%p)->(%p)\n", This, pidl);
2626 /* free the old stuff */
2629 SHFree(This->absPidl);
2630 This->absPidl = NULL;
2634 SHFree(This->sMyPath);
2635 This->sMyPath = NULL;
2639 This->absPidl = ILClone(pidl);
2642 if (SHGetPathFromIDListA(pidl, sTemp))
2644 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2645 strcpy(This->sMyPath, sTemp);
2648 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2653 /**************************************************************************
2654 * IPersistFolder2_fnGetCurFolder
2656 static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2657 IPersistFolder2 * iface,
2658 LPITEMIDLIST * pidl)
2660 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2662 TRACE("(%p)->(%p)\n",This, pidl);
2664 if (!pidl) return E_POINTER;
2666 *pidl = ILClone(This->absPidl);
2671 static ICOM_VTABLE(IPersistFolder2) psfvt =
2673 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2674 ISFPersistFolder2_QueryInterface,
2675 ISFPersistFolder2_AddRef,
2676 ISFPersistFolder2_Release,
2677 ISFPersistFolder2_GetClassID,
2678 ISFPersistFolder2_Initialize,
2679 ISFPersistFolder2_fnGetCurFolder
2682 /****************************************************************************
2683 * ISFDropTarget implementation
2685 static BOOL ISFDropTarget_QueryDrop(
2690 DWORD dwEffect = *pdwEffect;
2692 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2694 *pdwEffect = DROPEFFECT_NONE;
2696 if (This->fAcceptFmt)
2697 { /* Does our interpretation of the keystate ... */
2698 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2700 /* ... matches the desired effect ? */
2701 if (dwEffect & *pdwEffect)
2709 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2714 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2716 TRACE("(%p)\n", This);
2718 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2721 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2723 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2725 TRACE("(%p)\n", This);
2727 return IUnknown_AddRef(This->pUnkOuter);
2730 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2732 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2734 TRACE("(%p)\n", This);
2736 return IUnknown_Release(This->pUnkOuter);
2739 static HRESULT WINAPI ISFDropTarget_DragEnter(
2741 IDataObject *pDataObject,
2748 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2750 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2752 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2754 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2756 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2761 static HRESULT WINAPI ISFDropTarget_DragOver(
2767 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2769 TRACE("(%p)\n",This);
2771 if(!pdwEffect) return E_INVALIDARG;
2773 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2778 static HRESULT WINAPI ISFDropTarget_DragLeave(
2781 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2783 TRACE("(%p)\n",This);
2785 This->fAcceptFmt = FALSE;
2790 static HRESULT WINAPI ISFDropTarget_Drop(
2792 IDataObject* pDataObject,
2797 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2799 FIXME("(%p) object dropped\n",This);
2804 static struct ICOM_VTABLE(IDropTarget) dtvt =
2806 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2807 ISFDropTarget_QueryInterface,
2808 ISFDropTarget_AddRef,
2809 ISFDropTarget_Release,
2810 ISFDropTarget_DragEnter,
2811 ISFDropTarget_DragOver,
2812 ISFDropTarget_DragLeave,