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