4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998 Juergen Schmied
7 * IShellFolder with IDropTarget, IPersistFolder
14 #include "debugtools.h"
21 #include "wine/obj_base.h"
22 #include "wine/obj_dragdrop.h"
23 #include "wine/obj_shellfolder.h"
24 #include "wine/undocshell.h"
25 #include "shell32_main.h"
27 DEFAULT_DEBUG_CHANNEL(shell)
29 /***************************************************************************
30 * IDropTarget interface definition for the ShellFolder
34 { ICOM_VTABLE(IDropTarget)* lpvtbl;
38 static struct ICOM_VTABLE(IDropTarget) dtvt;
41 /****************************************************************************
42 * ISFDropTarget implementation
45 static IDropTarget * WINAPI ISFDropTarget_Constructor(void)
49 sf = HeapAlloc(GetProcessHeap(), 0, sizeof(ISFDropTarget));
56 return (IDropTarget *)sf;
59 static HRESULT WINAPI ISFDropTarget_QueryInterface(
64 ICOM_THIS(ISFDropTarget,iface);
67 WINE_StringFromCLSID((LPCLSID)riid,xriid);
69 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
71 if ( !This || !ppvObj)
76 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
79 else if(IsEqualIID(riid, &IID_IDropTarget)) /*IShellFolder*/
80 { *ppvObj = (ISFDropTarget*)This;
84 { IDropTarget_AddRef((IDropTarget*)*ppvObj);
85 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
89 TRACE("-- Interface: E_NOINTERFACE\n");
94 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
96 ICOM_THIS(ISFDropTarget,iface);
98 TRACE("(%p)->(count=%lu)\n",This,This->ref);
102 return ++(This->ref);
105 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
107 ICOM_THIS(ISFDropTarget,iface);
112 { TRACE("-- destroying ISFDropTarget (%p)\n",This);
113 HeapFree(GetProcessHeap(),0,This);
119 static HRESULT WINAPI ISFDropTarget_DragEnter(
121 IDataObject *pDataObject,
127 ICOM_THIS(ISFDropTarget,iface);
129 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
134 static HRESULT WINAPI ISFDropTarget_DragOver(
140 ICOM_THIS(ISFDropTarget,iface);
142 FIXME("Stub: This=%p\n",This);
147 static HRESULT WINAPI ISFDropTarget_DragLeave(
150 ICOM_THIS(ISFDropTarget,iface);
152 FIXME("Stub: This=%p\n",This);
157 static HRESULT WINAPI ISFDropTarget_Drop(
159 IDataObject* pDataObject,
164 ICOM_THIS(ISFDropTarget,iface);
166 FIXME("Stub: This=%p\n",This);
171 static struct ICOM_VTABLE(IDropTarget) dtvt =
173 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
174 ISFDropTarget_QueryInterface,
175 ISFDropTarget_AddRef,
176 ISFDropTarget_Release,
177 ISFDropTarget_DragEnter,
178 ISFDropTarget_DragOver,
179 ISFDropTarget_DragLeave,
183 /***************************************************************************
184 * GetNextElement (internal function)
186 * gets a part of a string till the first backslash
189 * pszNext [IN] string to get the element from
190 * pszOut [IN] pointer to buffer whitch receives string
191 * dwOut [IN] length of pszOut
194 * LPSTR pointer to first, not yet parsed char
197 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
198 { LPCWSTR pszTail = pszNext;
200 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
204 if(!pszNext || !*pszNext)
207 while(*pszTail && (*pszTail != (WCHAR)'\\'))
210 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
211 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
218 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
222 static HRESULT SHELL32_ParseNextElement(
225 LPITEMIDLIST * pidlInOut,
228 DWORD *pdwAttributes)
230 HRESULT hr = E_OUTOFMEMORY;
231 LPITEMIDLIST pidlOut, pidlTemp = NULL;
232 IShellFolder *psfChild;
234 TRACE("(%p %p %s)\n",psf, pidlInOut? *pidlInOut: NULL, debugstr_w(szNext));
237 /* get the shellfolder for the child pidl and let it analyse further */
238 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
242 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
243 IShellFolder_Release(psfChild);
245 pidlTemp = ILCombine(*pidlInOut, pidlOut);
252 *pidlInOut = pidlTemp;
254 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
258 /***********************************************************************
259 * SHELL32_CoCreateInitSF
261 * creates a initialized shell folder
263 static HRESULT SHELL32_CoCreateInitSF (
264 LPITEMIDLIST pidlRoot,
265 LPITEMIDLIST pidlChild,
271 LPITEMIDLIST absPidl;
272 IShellFolder *pShellFolder;
273 IPersistFolder *pPersistFolder;
275 TRACE("%p %p\n", pidlRoot, pidlChild);
279 hr = SHCoCreateInstance(NULL, clsid, NULL, iid, (LPVOID*)&pShellFolder);
282 hr = IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
285 absPidl = ILCombine (pidlRoot, pidlChild);
286 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
287 IPersistFolder_Release(pPersistFolder);
289 *ppvOut = pShellFolder;
293 TRACE("-- ret=0x%08lx\n", hr);
297 static HRESULT SHELL32_GetDisplayNameOfChild(
304 LPITEMIDLIST pidlFirst, pidlNext;
305 IShellFolder * psfChild;
306 HRESULT hr = E_OUTOFMEMORY;
309 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
312 if ((pidlFirst = ILCloneFirst(pidl)))
314 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
317 pidlNext = ILGetNext(pidl);
319 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
322 if (strTemp.uType == STRRET_CSTRA)
324 lstrcpynA(szOut , strTemp.u.cStr, dwOutLen);
328 FIXME("wrong return type");
332 IShellFolder_Release(psfChild);
337 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
342 /***********************************************************************
343 * IShellFolder implementation
348 ICOM_VTABLE(IShellFolder)* lpvtbl;
351 ICOM_VTABLE(IPersistFolder)* lpvtblPersistFolder;
355 LPITEMIDLIST absPidl; /* complete pidl */
358 static struct ICOM_VTABLE(IShellFolder) sfvt;
360 static struct ICOM_VTABLE(IPersistFolder) psfvt;
362 static IShellFolder * ISF_MyComputer_Constructor(void);
364 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder)))
365 #define _ICOM_THIS_From_IPersistFolder(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
367 /**************************************************************************
368 * IShellFolder_Constructor
372 static IShellFolder * IShellFolder_Constructor(
377 IGenericSFImpl * sfParent = (IGenericSFImpl*) psf;
380 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
384 sf->lpvtblPersistFolder=&psfvt;
385 sf->pclsid = (CLSID*)&CLSID_SFFile;
387 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,sfParent, pidl);
390 if(pidl) /* do we have a pidl? */
394 sf->absPidl = ILCombine(sfParent->absPidl, pidl); /* build a absolute pidl */
396 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
398 if(sfParent->sMyPath) /* get the size of the parents path */
400 dwSize += strlen(sfParent->sMyPath) ;
401 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(sfParent->sMyPath));
404 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
405 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
407 if(!sf->sMyPath) return NULL;
410 if(sfParent->sMyPath) /* if the parent has a path, get it*/
412 strcpy(sf->sMyPath, sfParent->sMyPath);
413 PathAddBackslashA (sf->sMyPath);
416 len = strlen(sf->sMyPath);
417 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize - len + 1);
420 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
426 return (IShellFolder *)sf;
428 /**************************************************************************
429 * IShellFolder_fnQueryInterface
432 * REFIID riid [in ] Requested InterfaceID
433 * LPVOID* ppvObject [out] Interface* to hold the result
435 static HRESULT WINAPI IShellFolder_fnQueryInterface(
436 IShellFolder * iface,
440 ICOM_THIS(IGenericSFImpl, iface);
443 WINE_StringFromCLSID((LPCLSID)riid,xriid);
444 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
448 if(IsEqualIID(riid, &IID_IUnknown))
451 else if(IsEqualIID(riid, &IID_IShellFolder))
452 { *ppvObj = (IShellFolder*)This;
454 else if(IsEqualIID(riid, &IID_IPersist))
455 { *ppvObj = (IPersistFolder*)&(This->lpvtblPersistFolder);
457 else if(IsEqualIID(riid, &IID_IPersistFolder))
458 { *ppvObj = (IPersistFolder*)&(This->lpvtblPersistFolder);
463 IUnknown_AddRef((IUnknown*)(*ppvObj));
464 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
467 TRACE("-- Interface: E_NOINTERFACE\n");
468 return E_NOINTERFACE;
471 /**************************************************************************
472 * IShellFolder_AddRef
475 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder * iface)
477 ICOM_THIS(IGenericSFImpl, iface);
479 TRACE("(%p)->(count=%lu)\n",This,This->ref);
482 return ++(This->ref);
485 /**************************************************************************
486 * IShellFolder_fnRelease
488 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder * iface)
490 ICOM_THIS(IGenericSFImpl, iface);
492 TRACE("(%p)->(count=%lu)\n",This,This->ref);
496 { TRACE("-- destroying IShellFolder(%p)\n",This);
498 if (pdesktopfolder == iface)
499 { pdesktopfolder=NULL;
500 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
503 { SHFree(This->absPidl);
506 { SHFree(This->sMyPath);
509 HeapFree(GetProcessHeap(),0,This);
515 /**************************************************************************
516 * IShellFolder_fnParseDisplayName
518 * HWND hwndOwner, //[in ] Parent window for any message's
519 * LPBC pbc, //[in ] reserved
520 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
521 * ULONG* pchEaten, //[out] (unicode) characters processed
522 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
523 * ULONG* pdwAttributes //[out] items attributes
526 * every folder trys to parse only it's own (the leftmost) pidl and creates a
527 * subfolder to evaluate the remaining parts
528 * now we can parse into namespaces implemented by shell extensions
530 * behaviour on win98: lpszDisplayName=NULL -> chrash
531 * lpszDisplayName="" -> returns mycoputer-pidl
534 * pdwAttributes: not set
535 * pchEaten: not set like in windows
537 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
538 IShellFolder * iface,
541 LPOLESTR lpszDisplayName,
544 DWORD *pdwAttributes)
546 ICOM_THIS(IGenericSFImpl, iface);
548 HRESULT hr = E_OUTOFMEMORY;
550 WCHAR szElement[MAX_PATH];
551 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
552 LPITEMIDLIST pidlTemp=NULL;
554 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
555 This,hwndOwner,pbcReserved,lpszDisplayName,
556 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
558 if (pchEaten) *pchEaten = 0; /* strange but like the original */
560 if (*lpszDisplayName)
562 /* get the next element */
563 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
565 /* build the full pathname to the element */
566 WideCharToLocal(szTempA, szElement, lstrlenW(szElement) + 1);
567 strcpy(szPath, This->sMyPath);
568 PathAddBackslashA(szPath);
569 strcat(szPath, szTempA);
572 pidlTemp = SHSimpleIDListFromPathA(szPath);
576 /* try to analyse the next element */
577 if (szNext && *szNext)
579 hr = SHELL32_ParseNextElement(hwndOwner, (IShellFolder*)This, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
590 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
595 /**************************************************************************
596 * IShellFolder_fnEnumObjects
598 * HWND hwndOwner, //[in ] Parent Window
599 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
600 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
602 static HRESULT WINAPI IShellFolder_fnEnumObjects(
603 IShellFolder * iface,
606 LPENUMIDLIST* ppEnumIDList)
608 ICOM_THIS(IGenericSFImpl, iface);
610 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
612 *ppEnumIDList = NULL;
613 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
615 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
617 if(!*ppEnumIDList) return E_OUTOFMEMORY;
622 /**************************************************************************
623 * IShellFolder_fnBindToObject
625 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
626 * LPBC pbc, //[in ] reserved
627 * REFIID riid, //[in ] Initial Interface
628 * LPVOID* ppvObject //[out] Interface*
630 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder * iface, LPCITEMIDLIST pidl,
631 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
633 ICOM_THIS(IGenericSFImpl, iface);
636 IShellFolder *pShellFolder, *pSubFolder;
637 IPersistFolder *pPersistFolder;
638 LPITEMIDLIST absPidl;
640 WINE_StringFromCLSID(riid,xriid);
642 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
646 if ((iid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(iid, &IID_MyComputer))
648 /* we have to create a alien folder */
649 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
650 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
652 absPidl = ILCombine (This->absPidl, pidl);
653 IPersistFolder_Initialize(pPersistFolder, absPidl);
654 IPersistFolder_Release(pPersistFolder);
664 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
665 pShellFolder = IShellFolder_Constructor((IShellFolder*)This, pidltemp);
669 if (_ILIsPidlSimple(pidl))
671 *ppvOut = pShellFolder;
675 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
676 IShellFolder_Release(pShellFolder);
677 *ppvOut = pSubFolder;
680 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
685 /**************************************************************************
686 * IShellFolder_fnBindToStorage
688 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
689 * LPBC pbc, //[in ] reserved
690 * REFIID riid, //[in ] Initial storage interface
691 * LPVOID* ppvObject //[out] Interface* returned
693 static HRESULT WINAPI IShellFolder_fnBindToStorage(
694 IShellFolder * iface,
700 ICOM_THIS(IGenericSFImpl, iface);
703 WINE_StringFromCLSID(riid,xriid);
705 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",This,pidl,pbcReserved,xriid,ppvOut);
711 /**************************************************************************
712 * IShellFolder_fnCompareIDs
715 * LPARAM lParam, //[in ] Column?
716 * LPCITEMIDLIST pidl1, //[in ] simple pidl
717 * LPCITEMIDLIST pidl2) //[in ] simple pidl
720 * Special case - If one of the items is a Path and the other is a File,
721 * always make the Path come before the File.
724 * use SCODE_CODE() on the return value to get the result
727 static HRESULT WINAPI IShellFolder_fnCompareIDs(
728 IShellFolder * iface,
733 ICOM_THIS(IGenericSFImpl, iface);
735 CHAR szTemp1[MAX_PATH];
736 CHAR szTemp2[MAX_PATH];
739 HRESULT hr = E_OUTOFMEMORY;
740 LPCITEMIDLIST pidlTemp;
743 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
747 if (!pidl1 && !pidl2)
749 hr = ResultFromShort(0);
753 hr = ResultFromShort(-1);
757 hr = ResultFromShort(1);
762 pd1 = _ILGetDataPointer(pidl1);
763 pd2 = _ILGetDataPointer(pidl2);
765 /* compate the types. sort order is the PT_* constant */
766 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
767 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
771 hr = ResultFromShort(pt1-pt2);
773 else /* same type of pidl */
775 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
776 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
777 nReturn = strcasecmp(szTemp1, szTemp2);
779 if (nReturn == 0) /* first pidl different ? */
781 pidl1 = ILGetNext(pidl1);
783 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
785 pidlTemp = ILCloneFirst(pidl1);
786 pidl2 = ILGetNext(pidl2);
788 hr = IShellFolder_BindToObject((IShellFolder*)This, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
791 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
792 IShellFolder_Release(psf);
793 hr = ResultFromShort(nReturn);
799 hr = ResultFromShort(nReturn); /* two equal simple pidls */
804 hr = ResultFromShort(nReturn); /* two different simple pidls */
809 TRACE("-- res=0x%08lx\n", hr);
813 /**************************************************************************
814 * IShellFolder_fnCreateViewObject
815 * Creates an View Object representing the ShellFolder
816 * IShellView / IShellBrowser / IContextMenu
819 * HWND hwndOwner, // Handle of owner window
820 * REFIID riid, // Requested initial interface
821 * LPVOID* ppvObject) // Resultant interface*
824 * the same as SHCreateShellFolderViewEx ???
826 static HRESULT WINAPI IShellFolder_fnCreateViewObject( IShellFolder * iface,
827 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
829 ICOM_THIS(IGenericSFImpl, iface);
831 LPSHELLVIEW pShellView;
835 WINE_StringFromCLSID(riid,xriid);
836 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
840 pShellView = IShellView_Constructor((IShellFolder *) This);
843 return E_OUTOFMEMORY;
845 hr = pShellView->lpvtbl->fnQueryInterface(pShellView, riid, ppvOut);
846 pShellView->lpvtbl->fnRelease(pShellView);
847 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
851 /**************************************************************************
852 * IShellFolder_fnGetAttributesOf
855 * UINT cidl, //[in ] num elements in pidl array
856 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
857 * ULONG* rgfInOut) //[out] result array
860 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(IShellFolder * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
862 ICOM_THIS(IGenericSFImpl, iface);
866 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
868 if ( (!cidl) || (!apidl) || (!rgfInOut))
871 while (cidl > 0 && *apidl)
874 if (_ILIsFolder( *apidl))
876 *rgfInOut &= 0xe0000177;
879 else if (_ILIsValue( *apidl))
881 *rgfInOut &= 0x40000177;
890 TRACE("-- result=0x%08lx\n",*rgfInOut);
894 /**************************************************************************
895 * IShellFolder_fnGetUIObjectOf
898 * HWND hwndOwner, //[in ] Parent window for any output
899 * UINT cidl, //[in ] array size
900 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
901 * REFIID riid, //[in ] Requested Interface
902 * UINT* prgfInOut, //[ ] reserved
903 * LPVOID* ppvObject) //[out] Resulting Interface
906 * This function gets asked to return "view objects" for one or more (multiple select)
908 * The viewobject typically is an COM object with one of the following interfaces:
909 * IExtractIcon,IDataObject,IContextMenu
910 * In order to support icon positions in the default Listview your DataObject
911 * must implement the SetData method (in addition to GetData :) - the shell passes
912 * a barely documented "Icon positions" structure to SetData when the drag starts,
913 * and GetData's it if the drop is in another explorer window that needs the positions.
915 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
916 IShellFolder * iface,
919 LPCITEMIDLIST * apidl,
924 ICOM_THIS(IGenericSFImpl, iface);
928 LPUNKNOWN pObj = NULL;
930 WINE_StringFromCLSID(riid,xclsid);
932 TRACE("(%p)->(%u,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
933 This,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut);
940 if(IsEqualIID(riid, &IID_IContextMenu))
945 pObj = (LPUNKNOWN)IContextMenu_Constructor((IShellFolder *)This, This->absPidl, apidl, cidl);
947 else if (IsEqualIID(riid, &IID_IDataObject))
952 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
954 else if(IsEqualIID(riid, &IID_IExtractIconA))
959 pidl = ILCombine(This->absPidl,apidl[0]);
960 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
963 else if (IsEqualIID(riid, &IID_IDropTarget))
968 pObj = (LPUNKNOWN)ISFDropTarget_Constructor();
972 ERR("(%p)->E_NOINTERFACE\n",This);
973 return E_NOINTERFACE;
977 return E_OUTOFMEMORY;
983 /**************************************************************************
984 * IShellFolder_fnGetDisplayNameOf
985 * Retrieves the display name for the specified file object or subfolder
988 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
989 * DWORD dwFlags, //[in ] SHGNO formatting flags
990 * LPSTRRET lpName) //[out] Returned display name
993 * if the name is in the pidl the ret value should be a STRRET_OFFSET
995 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
996 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
998 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
999 IShellFolder * iface,
1004 ICOM_THIS(IGenericSFImpl, iface);
1006 CHAR szPath[MAX_PATH]= "";
1010 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1013 if(!pidl || !strRet) return E_INVALIDARG;
1015 bSimplePidl = _ILIsPidlSimple(pidl);
1017 /* take names of special folders only if its only this folder */
1018 if (_ILIsSpecialFolder(pidl))
1022 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1027 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1029 strcpy (szPath, This->sMyPath); /* get path to root*/
1030 PathAddBackslashA(szPath);
1031 len = strlen(szPath);
1033 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1036 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1038 PathAddBackslashA(szPath);
1039 len = strlen(szPath);
1041 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild((IShellFolder*)This, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1042 return E_OUTOFMEMORY;
1044 strRet->uType = STRRET_CSTRA;
1045 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1047 TRACE("-- (%p)->(%s)\n", This, szPath);
1051 /**************************************************************************
1052 * IShellFolder_fnSetNameOf
1053 * Changes the name of a file object or subfolder, possibly changing its item
1054 * identifier in the process.
1057 * HWND hwndOwner, //[in ] Owner window for output
1058 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1059 * LPCOLESTR lpszName, //[in ] the items new display name
1060 * DWORD dwFlags, //[in ] SHGNO formatting flags
1061 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1063 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1064 IShellFolder * iface,
1066 LPCITEMIDLIST pidl, /*simple pidl*/
1069 LPITEMIDLIST *pPidlOut)
1071 ICOM_THIS(IGenericSFImpl, iface);
1073 FIXME("(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
1074 This,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut);
1079 /**************************************************************************
1080 * IShellFolder_fnGetFolderPath
1082 static HRESULT WINAPI IShellFolder_fnGetFolderPath(IShellFolder * iface, LPSTR lpszOut, DWORD dwOutSize)
1084 ICOM_THIS(IGenericSFImpl, iface);
1086 TRACE("(%p)->(%p %lu)\n",This, lpszOut, dwOutSize);
1088 if (!lpszOut) return FALSE;
1092 if (! This->sMyPath) return FALSE;
1094 lstrcpynA(lpszOut, This->sMyPath, dwOutSize);
1096 TRACE("-- (%p)->(return=%s)\n",This, lpszOut);
1100 static ICOM_VTABLE(IShellFolder) sfvt =
1102 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1103 IShellFolder_fnQueryInterface,
1104 IShellFolder_fnAddRef,
1105 IShellFolder_fnRelease,
1106 IShellFolder_fnParseDisplayName,
1107 IShellFolder_fnEnumObjects,
1108 IShellFolder_fnBindToObject,
1109 IShellFolder_fnBindToStorage,
1110 IShellFolder_fnCompareIDs,
1111 IShellFolder_fnCreateViewObject,
1112 IShellFolder_fnGetAttributesOf,
1113 IShellFolder_fnGetUIObjectOf,
1114 IShellFolder_fnGetDisplayNameOf,
1115 IShellFolder_fnSetNameOf,
1116 IShellFolder_fnGetFolderPath
1119 /***********************************************************************
1120 * [Desktopfolder] IShellFolder implementation
1122 static struct ICOM_VTABLE(IShellFolder) sfdvt;
1124 /**************************************************************************
1125 * ISF_Desktop_Constructor
1128 IShellFolder * ISF_Desktop_Constructor()
1130 IGenericSFImpl * sf;
1132 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1135 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1140 return (IShellFolder *)sf;
1143 /**************************************************************************
1144 * ISF_Desktop_fnQueryInterface
1146 * NOTES supports not IPersist/IPersistFolder
1148 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1149 IShellFolder * iface,
1153 ICOM_THIS(IGenericSFImpl, iface);
1156 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1157 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
1161 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1164 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1165 { *ppvObj = (IShellFolder*)This;
1170 IUnknown_AddRef((IUnknown*)(*ppvObj));
1171 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1174 TRACE("-- Interface: E_NOINTERFACE\n");
1175 return E_NOINTERFACE;
1178 /**************************************************************************
1179 * ISF_Desktop_fnParseDisplayName
1182 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1185 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1186 IShellFolder * iface,
1189 LPOLESTR lpszDisplayName,
1191 LPITEMIDLIST *ppidl,
1192 DWORD *pdwAttributes)
1194 ICOM_THIS(IGenericSFImpl, iface);
1196 LPCWSTR szNext=NULL;
1197 LPITEMIDLIST pidlTemp=NULL;
1198 HRESULT hr=E_OUTOFMEMORY;
1200 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1201 This,hwndOwner,pbcReserved,lpszDisplayName,
1202 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1205 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1207 /* fixme no real parsing implemented */
1208 pidlTemp = _ILCreateMyComputer();
1209 szNext = lpszDisplayName;
1211 if (szNext && *szNext)
1213 hr = SHELL32_ParseNextElement(hwndOwner, (IShellFolder*)This, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1222 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1227 /**************************************************************************
1228 * ISF_Desktop_fnEnumObjects
1230 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1231 IShellFolder * iface,
1234 LPENUMIDLIST* ppEnumIDList)
1236 ICOM_THIS(IGenericSFImpl, iface);
1238 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1240 *ppEnumIDList = NULL;
1241 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1243 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1245 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1250 /**************************************************************************
1251 * ISF_Desktop_fnBindToObject
1253 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder * iface, LPCITEMIDLIST pidl,
1254 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1256 ICOM_THIS(IGenericSFImpl, iface);
1259 IShellFolder *pShellFolder, *pSubFolder;
1261 WINE_StringFromCLSID(riid,xriid);
1263 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
1267 if (!(clsid=_ILGetGUIDPointer(pidl))) return E_INVALIDARG;
1269 if ( IsEqualIID(clsid, &IID_MyComputer))
1271 pShellFolder = ISF_MyComputer_Constructor();
1275 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1277 return E_INVALIDARG;
1281 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1283 *ppvOut = pShellFolder;
1285 else /* go deeper */
1287 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1288 IShellFolder_Release(pShellFolder);
1289 *ppvOut = pSubFolder;
1292 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1297 /**************************************************************************
1298 * ISF_Desktop_fnGetAttributesOf
1300 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(IShellFolder * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
1302 ICOM_THIS(IGenericSFImpl, iface);
1308 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1310 if ( (!cidl) || (!apidl) || (!rgfInOut))
1311 return E_INVALIDARG;
1313 while (cidl > 0 && *apidl)
1317 if ((clsid=_ILGetGUIDPointer(*apidl)))
1319 if (IsEqualIID(clsid, &IID_MyComputer))
1321 *rgfInOut &= 0xb0000154;
1324 else if (HCR_GetFolderAttributes(clsid, &attributes))
1326 *rgfInOut &= attributes;
1330 else if (_ILIsFolder( *apidl))
1332 *rgfInOut &= 0xe0000177;
1335 else if (_ILIsValue( *apidl))
1337 *rgfInOut &= 0x40000177;
1346 TRACE("-- result=0x%08lx\n",*rgfInOut);
1351 /**************************************************************************
1352 * ISF_Desktop_fnGetDisplayNameOf
1355 * special case: pidl = null gives desktop-name back
1357 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1358 IShellFolder * iface,
1363 ICOM_THIS(IGenericSFImpl, iface);
1365 CHAR szPath[MAX_PATH]= "";
1367 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1370 if(!strRet) return E_INVALIDARG;
1374 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1376 else if ( _ILIsPidlSimple(pidl) )
1378 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1382 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild((IShellFolder*)This, pidl, dwFlags, szPath, MAX_PATH)))
1383 return E_OUTOFMEMORY;
1385 strRet->uType = STRRET_CSTRA;
1386 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1389 TRACE("-- (%p)->(%s)\n", This, szPath);
1393 static ICOM_VTABLE(IShellFolder) sfdvt =
1395 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1396 ISF_Desktop_fnQueryInterface,
1397 IShellFolder_fnAddRef,
1398 IShellFolder_fnRelease,
1399 ISF_Desktop_fnParseDisplayName,
1400 ISF_Desktop_fnEnumObjects,
1401 ISF_Desktop_fnBindToObject,
1402 IShellFolder_fnBindToStorage,
1403 IShellFolder_fnCompareIDs,
1404 IShellFolder_fnCreateViewObject,
1405 ISF_Desktop_fnGetAttributesOf,
1406 IShellFolder_fnGetUIObjectOf,
1407 ISF_Desktop_fnGetDisplayNameOf,
1408 IShellFolder_fnSetNameOf,
1409 IShellFolder_fnGetFolderPath
1413 /***********************************************************************
1414 * IShellFolder [MyComputer] implementation
1417 static struct ICOM_VTABLE(IShellFolder) sfmcvt;
1419 /**************************************************************************
1420 * ISF_MyComputer_Constructor
1422 static IShellFolder * ISF_MyComputer_Constructor(void)
1424 IGenericSFImpl * sf;
1426 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1429 sf->lpvtbl = &sfmcvt;
1430 sf->lpvtblPersistFolder = &psfvt;
1431 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
1432 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
1437 return (IShellFolder *)sf;
1440 /**************************************************************************
1441 * ISF_MyComputer_fnParseDisplayName
1443 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
1444 IShellFolder * iface,
1447 LPOLESTR lpszDisplayName,
1449 LPITEMIDLIST *ppidl,
1450 DWORD *pdwAttributes)
1452 ICOM_THIS(IGenericSFImpl, iface);
1454 HRESULT hr = E_OUTOFMEMORY;
1455 LPCWSTR szNext=NULL;
1456 WCHAR szElement[MAX_PATH];
1457 CHAR szTempA[MAX_PATH];
1458 LPITEMIDLIST pidlTemp;
1460 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1461 This,hwndOwner,pbcReserved,lpszDisplayName,
1462 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1465 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1467 if (PathIsRootW(lpszDisplayName))
1469 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
1470 WideCharToLocal(szTempA, szElement, lstrlenW(szElement) + 1);
1471 pidlTemp = _ILCreateDrive(szTempA);
1473 if (szNext && *szNext)
1475 hr = SHELL32_ParseNextElement(hwndOwner, (IShellFolder*)This, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1484 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1489 /**************************************************************************
1490 * ISF_MyComputer_fnEnumObjects
1492 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
1493 IShellFolder * iface,
1496 LPENUMIDLIST* ppEnumIDList)
1498 ICOM_THIS(IGenericSFImpl, iface);
1500 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1502 *ppEnumIDList = NULL;
1503 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
1505 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1507 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1512 /**************************************************************************
1513 * ISF_MyComputer_fnBindToObject
1515 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder * iface, LPCITEMIDLIST pidl,
1516 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1518 ICOM_THIS(IGenericSFImpl, iface);
1521 IShellFolder *pShellFolder, *pSubFolder;
1522 LPITEMIDLIST pidltemp;
1524 WINE_StringFromCLSID(riid,xriid);
1526 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
1530 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &IID_MyComputer))
1532 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1539 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
1541 pidltemp = ILCloneFirst(pidl);
1542 pShellFolder = IShellFolder_Constructor((IShellFolder*)This, pidltemp);
1546 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1548 *ppvOut = pShellFolder;
1550 else /* go deeper */
1552 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
1553 IShellFolder_Release(pShellFolder);
1554 *ppvOut = pSubFolder;
1557 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1562 /**************************************************************************
1563 * ISF_MyComputer_fnGetAttributesOf
1565 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(IShellFolder * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
1567 ICOM_THIS(IGenericSFImpl, iface);
1573 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
1575 if ( (!cidl) || (!apidl) || (!rgfInOut))
1576 return E_INVALIDARG;
1578 *rgfInOut = 0xffffffff;
1580 while (cidl > 0 && *apidl)
1584 if (_ILIsDrive(*apidl))
1586 *rgfInOut &= 0xf0000144;
1589 else if ((clsid=_ILGetGUIDPointer(*apidl)))
1591 if (HCR_GetFolderAttributes(clsid, &attributes))
1593 *rgfInOut &= attributes;
1603 TRACE("-- result=0x%08lx\n",*rgfInOut);
1607 /**************************************************************************
1608 * ISF_MyComputer_fnGetDisplayNameOf
1611 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
1612 * SHGDN_INFOLDER makes no sense.
1614 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
1615 IShellFolder * iface,
1620 ICOM_THIS(IGenericSFImpl, iface);
1622 char szPath[MAX_PATH], szDrive[18];
1626 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1629 if(!strRet) return E_INVALIDARG;
1631 szPath[0]=0x00; szDrive[0]=0x00;
1634 bSimplePidl = _ILIsPidlSimple(pidl);
1636 if (_ILIsSpecialFolder(pidl))
1638 /* take names of special folders only if its only this folder */
1641 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1646 if (!_ILIsDrive(pidl))
1648 ERR("Wrong pidl type\n");
1649 return E_INVALIDARG;
1652 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1654 /* long view "lw_name (C:)" */
1655 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
1657 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
1659 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
1660 strcat (szDrive," (");
1661 strncat (szDrive, szPath, 2);
1662 strcat (szDrive,")");
1663 strcpy (szPath, szDrive);
1667 if (!bSimplePidl) /* go deeper if needed */
1669 PathAddBackslashA(szPath);
1670 len = strlen(szPath);
1672 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild((IShellFolder*)This, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
1673 return E_OUTOFMEMORY;
1675 strRet->uType = STRRET_CSTRA;
1676 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1679 TRACE("-- (%p)->(%s)\n", This, szPath);
1683 static ICOM_VTABLE(IShellFolder) sfmcvt =
1685 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1686 IShellFolder_fnQueryInterface,
1687 IShellFolder_fnAddRef,
1688 IShellFolder_fnRelease,
1689 ISF_MyComputer_fnParseDisplayName,
1690 ISF_MyComputer_fnEnumObjects,
1691 ISF_MyComputer_fnBindToObject,
1692 IShellFolder_fnBindToStorage,
1693 IShellFolder_fnCompareIDs,
1694 IShellFolder_fnCreateViewObject,
1695 ISF_MyComputer_fnGetAttributesOf,
1696 IShellFolder_fnGetUIObjectOf,
1697 ISF_MyComputer_fnGetDisplayNameOf,
1698 IShellFolder_fnSetNameOf,
1699 IShellFolder_fnGetFolderPath
1703 /************************************************************************
1704 * ISFPersistFolder_QueryInterface (IUnknown)
1707 static HRESULT WINAPI ISFPersistFolder_QueryInterface(
1708 IPersistFolder * iface,
1712 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
1714 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1717 /************************************************************************
1718 * ISFPersistFolder_AddRef (IUnknown)
1721 static ULONG WINAPI ISFPersistFolder_AddRef(
1722 IPersistFolder * iface)
1724 _ICOM_THIS_From_IPersistFolder(IShellFolder, iface);
1726 return IShellFolder_AddRef((IShellFolder*)This);
1729 /************************************************************************
1730 * ISFPersistFolder_Release (IUnknown)
1733 static ULONG WINAPI ISFPersistFolder_Release(
1734 IPersistFolder * iface)
1736 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
1738 return IShellFolder_Release((IShellFolder*)This);
1741 /************************************************************************
1742 * ISFPersistFolder_GetClassID (IPersist)
1744 static HRESULT WINAPI ISFPersistFolder_GetClassID(
1745 IPersistFolder * iface,
1748 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
1750 if (!lpClassId) return E_POINTER;
1751 *lpClassId = *This->pclsid;
1756 /************************************************************************
1757 * ISFPersistFolder_Initialize (IPersistFolder)
1760 * sMyPath is not set. Don't know how to handle in a non rooted environment.
1762 static HRESULT WINAPI ISFPersistFolder_Initialize(
1763 IPersistFolder * iface,
1766 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
1770 SHFree(This->absPidl);
1771 This->absPidl = NULL;
1773 This->absPidl = ILClone(pidl);
1777 static ICOM_VTABLE(IPersistFolder) psfvt =
1779 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1780 ISFPersistFolder_QueryInterface,
1781 ISFPersistFolder_AddRef,
1782 ISFPersistFolder_Release,
1783 ISFPersistFolder_GetClassID,
1784 ISFPersistFolder_Initialize