4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
7 * IShellFolder2 and related interfaces
15 #include "debugtools.h"
22 #include "wine/obj_base.h"
23 #include "wine/obj_dragdrop.h"
24 #include "wine/obj_shellfolder.h"
25 #include "wine/undocshell.h"
26 #include "shell32_main.h"
31 #include "shellfolder.h"
34 DEFAULT_DEBUG_CHANNEL(shell
)
37 /***************************************************************************
38 * debughelper: print out the return adress
39 * helps especially to track down unbalanced AddRef/Release
44 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
58 /***************************************************************************
59 * GetNextElement (internal function)
61 * gets a part of a string till the first backslash
64 * pszNext [IN] string to get the element from
65 * pszOut [IN] pointer to buffer whitch receives string
66 * dwOut [IN] length of pszOut
69 * LPSTR pointer to first, not yet parsed char
72 static LPCWSTR
GetNextElementW(LPCWSTR pszNext
,LPWSTR pszOut
,DWORD dwOut
)
73 { LPCWSTR pszTail
= pszNext
;
75 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext
),pszOut
,dwOut
);
79 if(!pszNext
|| !*pszNext
)
82 while(*pszTail
&& (*pszTail
!= (WCHAR
)'\\'))
85 dwCopy
= (WCHAR
*)pszTail
- (WCHAR
*)pszNext
+ 1;
86 lstrcpynW(pszOut
, pszNext
, (dwOut
<dwCopy
)? dwOut
: dwCopy
);
93 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext
),debugstr_w(pszOut
),dwOut
,pszTail
);
97 static HRESULT
SHELL32_ParseNextElement(
100 LPITEMIDLIST
* pidlInOut
,
103 DWORD
*pdwAttributes
)
105 HRESULT hr
= E_OUTOFMEMORY
;
106 LPITEMIDLIST pidlOut
, pidlTemp
= NULL
;
107 IShellFolder
*psfChild
;
109 TRACE("(%p, %p, %s)\n",psf
, pidlInOut
? *pidlInOut
: NULL
, debugstr_w(szNext
));
112 /* get the shellfolder for the child pidl and let it analyse further */
113 hr
= IShellFolder_BindToObject(psf
, *pidlInOut
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
117 hr
= IShellFolder_ParseDisplayName(psfChild
, hwndOwner
, NULL
, szNext
, pEaten
, &pidlOut
, pdwAttributes
);
118 IShellFolder_Release(psfChild
);
120 pidlTemp
= ILCombine(*pidlInOut
, pidlOut
);
127 *pidlInOut
= pidlTemp
;
129 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut
? *pidlInOut
: NULL
, hr
);
133 /***********************************************************************
134 * SHELL32_CoCreateInitSF
136 * creates a initialized shell folder
138 static HRESULT
SHELL32_CoCreateInitSF (
139 LPITEMIDLIST pidlRoot
,
140 LPITEMIDLIST pidlChild
,
146 LPITEMIDLIST absPidl
;
147 IShellFolder2
*pShellFolder
;
148 IPersistFolder
*pPersistFolder
;
150 TRACE("%p %p\n", pidlRoot
, pidlChild
);
154 /* we have to ask first for IPersistFolder, some special folders are expecting this */
155 hr
= SHCoCreateInstance(NULL
, clsid
, NULL
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
);
158 hr
= IPersistFolder_QueryInterface(pPersistFolder
, iid
, (LPVOID
*)&pShellFolder
);
161 absPidl
= ILCombine (pidlRoot
, pidlChild
);
162 hr
= IPersistFolder_Initialize(pPersistFolder
, absPidl
);
163 IPersistFolder_Release(pPersistFolder
);
165 *ppvOut
= pShellFolder
;
169 TRACE("-- ret=0x%08lx\n", hr
);
173 static HRESULT
SHELL32_GetDisplayNameOfChild(
180 LPITEMIDLIST pidlFirst
, pidlNext
;
181 IShellFolder2
* psfChild
;
182 HRESULT hr
= E_OUTOFMEMORY
;
185 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf
,pidl
,dwFlags
,szOut
, dwOutLen
);
188 if ((pidlFirst
= ILCloneFirst(pidl
)))
190 hr
= IShellFolder_BindToObject(psf
, pidlFirst
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
193 pidlNext
= ILGetNext(pidl
);
195 hr
= IShellFolder_GetDisplayNameOf(psfChild
, pidlNext
, dwFlags
| SHGDN_INFOLDER
, &strTemp
);
198 hr
= StrRetToStrNA(szOut
, dwOutLen
, &strTemp
, pidlNext
);
201 IShellFolder_Release(psfChild
);
206 TRACE("-- ret=0x%08lx %s\n", hr
, szOut
);
211 /***********************************************************************
212 * IShellFolder implementation
217 ICOM_VFIELD(IUnknown
);
219 ICOM_VTABLE(IShellFolder2
)* lpvtblShellFolder
;
220 ICOM_VTABLE(IPersistFolder2
)* lpvtblPersistFolder2
;
221 ICOM_VTABLE(IDropTarget
)* lpvtblDropTarget
;
222 ICOM_VTABLE(ISFHelper
)* lpvtblSFHelper
;
224 IUnknown
*pUnkOuter
; /* used for aggregation */
229 LPITEMIDLIST absPidl
; /* complete pidl */
231 UINT cfShellIDList
; /* clipboardformat for IDropTarget */
232 BOOL fAcceptFmt
; /* flag for pending Drop */
235 static struct ICOM_VTABLE(IUnknown
) unkvt
;
236 static struct ICOM_VTABLE(IShellFolder2
) sfvt
;
237 static struct ICOM_VTABLE(IPersistFolder2
) psfvt
;
238 static struct ICOM_VTABLE(IDropTarget
) dtvt
;
239 static struct ICOM_VTABLE(ISFHelper
) shvt
;
241 static IShellFolder
* ISF_MyComputer_Constructor(void);
243 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
244 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
246 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
247 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
249 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
250 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
252 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
253 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
255 converts This to a interface pointer
257 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
258 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
259 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
260 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
261 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
262 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
263 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
264 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
265 /**************************************************************************
266 * registers clipboardformat once
268 static void SF_RegisterClipFmt (IGenericSFImpl
* This
)
270 TRACE("(%p)\n", This
);
272 if (!This
->cfShellIDList
)
274 This
->cfShellIDList
= RegisterClipboardFormatA(CFSTR_SHELLIDLIST
);
278 /**************************************************************************
279 * we need a seperate IUnknown to handle aggregation
282 static HRESULT WINAPI
IUnknown_fnQueryInterface(
287 ICOM_THIS(IGenericSFImpl
, iface
);
290 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
294 if(IsEqualIID(riid
, &IID_IUnknown
)) *ppvObj
= _IUnknown_(This
);
295 else if(IsEqualIID(riid
, &IID_IShellFolder
)) *ppvObj
= _IShellFolder_(This
);
296 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) *ppvObj
= _IShellFolder_(This
);
297 else if(IsEqualIID(riid
, &IID_IPersist
)) *ppvObj
= _IPersist_(This
);
298 else if(IsEqualIID(riid
, &IID_IPersistFolder
)) *ppvObj
= _IPersistFolder_(This
);
299 else if(IsEqualIID(riid
, &IID_IPersistFolder2
)) *ppvObj
= _IPersistFolder2_(This
);
300 else if(IsEqualIID(riid
, &IID_ISFHelper
)) *ppvObj
= _ISFHelper_(This
);
301 else if(IsEqualIID(riid
, &IID_IDropTarget
))
303 *ppvObj
= _IDropTarget_(This
);
304 SF_RegisterClipFmt(This
);
309 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
310 TRACE("-- Interface = %p\n", *ppvObj
);
313 TRACE("-- Interface: E_NOINTERFACE\n");
314 return E_NOINTERFACE
;
317 static ULONG WINAPI
IUnknown_fnAddRef(IUnknown
* iface
)
319 ICOM_THIS(IGenericSFImpl
, iface
);
322 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
325 return ++(This
->ref
);
328 static ULONG WINAPI
IUnknown_fnRelease(IUnknown
* iface
)
330 ICOM_THIS(IGenericSFImpl
, iface
);
333 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
338 TRACE("-- destroying IShellFolder(%p)\n",This
);
340 if (pdesktopfolder
== _IShellFolder_(This
))
343 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This
);
345 if(This
->absPidl
) SHFree(This
->absPidl
);
346 if(This
->sMyPath
) SHFree(This
->sMyPath
);
347 HeapFree(GetProcessHeap(),0,This
);
353 static ICOM_VTABLE(IUnknown
) unkvt
=
355 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
356 IUnknown_fnQueryInterface
,
361 static shvheader GenericSFHeader
[] =
363 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
364 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
365 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
366 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
367 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
369 #define GENERICSHELLVIEWCOLUMNS 5
371 /**************************************************************************
372 * IShellFolder_Constructor
375 * creating undocumented ShellFS_Folder as part of an aggregation
376 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
379 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
381 HRESULT
IFSFolder_Constructor(
382 IUnknown
* pUnkOuter
,
389 TRACE("unkOut=%p riid=%s\n",pUnkOuter
, debugstr_guid(riid
));
391 if(pUnkOuter
&& ! IsEqualIID(riid
, &IID_IUnknown
))
393 hr
= CLASS_E_NOAGGREGATION
; /* forbidden by definition */
397 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
401 ICOM_VTBL(sf
)=&unkvt
;
402 sf
->lpvtblShellFolder
=&sfvt
;
403 sf
->lpvtblPersistFolder2
=&psfvt
;
404 sf
->lpvtblDropTarget
=&dtvt
;
405 sf
->lpvtblSFHelper
=&shvt
;
407 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
408 sf
->pUnkOuter
= pUnkOuter
? pUnkOuter
: _IUnknown_(sf
);
409 *ppv
= _IUnknown_(sf
);
420 /**************************************************************************
421 * IShellFolder_Constructor
424 * THIS points to the parent folder
427 IShellFolder
* IShellFolder_Constructor(
428 IShellFolder2
* iface
,
434 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
436 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
439 ICOM_VTBL(sf
)=&unkvt
;
440 sf
->lpvtblShellFolder
=&sfvt
;
441 sf
->lpvtblPersistFolder2
=&psfvt
;
442 sf
->lpvtblDropTarget
=&dtvt
;
443 sf
->lpvtblSFHelper
=&shvt
;
445 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
446 sf
->pUnkOuter
= _IUnknown_(sf
);
448 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf
,This
, pidl
);
451 if(pidl
&& iface
) /* do we have a pidl? */
455 sf
->absPidl
= ILCombine(This
->absPidl
, pidl
); /* build a absolute pidl */
457 if (!_ILIsSpecialFolder(pidl
)) /* only file system paths */
459 if(This
->sMyPath
) /* get the size of the parents path */
461 dwSize
+= strlen(This
->sMyPath
) ;
462 TRACE("-- (%p)->(parent's path=%s)\n",sf
, debugstr_a(This
->sMyPath
));
465 dwSize
+= _ILSimpleGetText(pidl
,NULL
,0); /* add the size of our name*/
466 sf
->sMyPath
= SHAlloc(dwSize
+ 2); /* '\0' and backslash */
468 if(!sf
->sMyPath
) return NULL
;
471 if(This
->sMyPath
) /* if the parent has a path, get it*/
473 strcpy(sf
->sMyPath
, This
->sMyPath
);
474 PathAddBackslashA (sf
->sMyPath
);
477 len
= strlen(sf
->sMyPath
);
478 _ILSimpleGetText(pidl
, sf
->sMyPath
+ len
, dwSize
+2 - len
);
481 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf
, sf
->absPidl
,debugstr_a(sf
->sMyPath
));
487 return _IShellFolder_(sf
);
490 /**************************************************************************
491 * IShellFolder_fnQueryInterface
494 * REFIID riid [in ] Requested InterfaceID
495 * LPVOID* ppvObject [out] Interface* to hold the result
497 static HRESULT WINAPI
IShellFolder_fnQueryInterface(
498 IShellFolder2
* iface
,
502 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
505 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
507 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
510 /**************************************************************************
511 * IShellFolder_AddRef
514 static ULONG WINAPI
IShellFolder_fnAddRef(IShellFolder2
* iface
)
516 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
519 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
521 return IUnknown_AddRef(This
->pUnkOuter
);
524 /**************************************************************************
525 * IShellFolder_fnRelease
527 static ULONG WINAPI
IShellFolder_fnRelease(IShellFolder2
* iface
)
529 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
532 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
534 return IUnknown_Release(This
->pUnkOuter
);
537 /**************************************************************************
538 * IShellFolder_fnParseDisplayName
540 * HWND hwndOwner, //[in ] Parent window for any message's
541 * LPBC pbc, //[in ] reserved
542 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
543 * ULONG* pchEaten, //[out] (unicode) characters processed
544 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
545 * ULONG* pdwAttributes //[out] items attributes
548 * every folder trys to parse only it's own (the leftmost) pidl and creates a
549 * subfolder to evaluate the remaining parts
550 * now we can parse into namespaces implemented by shell extensions
552 * behaviour on win98: lpszDisplayName=NULL -> chrash
553 * lpszDisplayName="" -> returns mycoputer-pidl
556 * pdwAttributes: not set
557 * pchEaten: not set like in windows
559 static HRESULT WINAPI
IShellFolder_fnParseDisplayName(
560 IShellFolder2
* iface
,
563 LPOLESTR lpszDisplayName
,
566 DWORD
*pdwAttributes
)
568 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
570 HRESULT hr
= E_OUTOFMEMORY
;
572 WCHAR szElement
[MAX_PATH
];
573 CHAR szTempA
[MAX_PATH
], szPath
[MAX_PATH
];
574 LPITEMIDLIST pidlTemp
=NULL
;
576 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
577 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
578 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
580 if (!lpszDisplayName
|| !ppidl
) return E_INVALIDARG
;
582 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
584 if (*lpszDisplayName
)
586 /* get the next element */
587 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
589 /* build the full pathname to the element */
590 lstrcpynWtoA(szTempA
, szElement
, lstrlenW(szElement
) + 1);
591 strcpy(szPath
, This
->sMyPath
);
592 PathAddBackslashA(szPath
);
593 strcat(szPath
, szTempA
);
596 pidlTemp
= SHSimpleIDListFromPathA(szPath
);
600 /* try to analyse the next element */
601 if (szNext
&& *szNext
)
603 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
614 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This
, ppidl
? *ppidl
:0, hr
);
619 /**************************************************************************
620 * IShellFolder_fnEnumObjects
622 * HWND hwndOwner, //[in ] Parent Window
623 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
624 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
626 static HRESULT WINAPI
IShellFolder_fnEnumObjects(
627 IShellFolder2
* iface
,
630 LPENUMIDLIST
* ppEnumIDList
)
632 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
634 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
636 *ppEnumIDList
= NULL
;
637 *ppEnumIDList
= IEnumIDList_Constructor (This
->sMyPath
, dwFlags
, EIDL_FILE
);
639 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
641 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
646 /**************************************************************************
647 * IShellFolder_fnBindToObject
649 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
650 * LPBC pbc, //[in ] reserved
651 * REFIID riid, //[in ] Initial Interface
652 * LPVOID* ppvObject //[out] Interface*
654 static HRESULT WINAPI
IShellFolder_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
655 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
657 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
659 IShellFolder
*pShellFolder
, *pSubFolder
;
660 IPersistFolder
*pPersistFolder
;
661 LPITEMIDLIST absPidl
;
663 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
665 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
669 if ((iid
=_ILGetGUIDPointer(pidl
)))
671 /* we have to create a alien folder */
672 if ( SUCCEEDED(SHCoCreateInstance(NULL
, iid
, NULL
, riid
, (LPVOID
*)&pShellFolder
))
673 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
)))
675 absPidl
= ILCombine (This
->absPidl
, pidl
);
676 IPersistFolder_Initialize(pPersistFolder
, absPidl
);
677 IPersistFolder_Release(pPersistFolder
);
687 LPITEMIDLIST pidltemp
= ILCloneFirst(pidl
);
688 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
692 if (_ILIsPidlSimple(pidl
))
694 *ppvOut
= pShellFolder
;
698 IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, &IID_IShellFolder
, (LPVOID
)&pSubFolder
);
699 IShellFolder_Release(pShellFolder
);
700 *ppvOut
= pSubFolder
;
703 TRACE("-- (%p) returning (%p)\n",This
, *ppvOut
);
708 /**************************************************************************
709 * IShellFolder_fnBindToStorage
711 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
712 * LPBC pbc, //[in ] reserved
713 * REFIID riid, //[in ] Initial storage interface
714 * LPVOID* ppvObject //[out] Interface* returned
716 static HRESULT WINAPI
IShellFolder_fnBindToStorage(
717 IShellFolder2
* iface
,
723 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
725 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
726 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
732 /**************************************************************************
733 * IShellFolder_fnCompareIDs
736 * LPARAM lParam, //[in ] Column?
737 * LPCITEMIDLIST pidl1, //[in ] simple pidl
738 * LPCITEMIDLIST pidl2) //[in ] simple pidl
741 * Special case - If one of the items is a Path and the other is a File,
742 * always make the Path come before the File.
745 * use SCODE_CODE() on the return value to get the result
748 static HRESULT WINAPI
IShellFolder_fnCompareIDs(
749 IShellFolder2
* iface
,
754 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
756 CHAR szTemp1
[MAX_PATH
];
757 CHAR szTemp2
[MAX_PATH
];
760 HRESULT hr
= E_OUTOFMEMORY
;
761 LPCITEMIDLIST pidlTemp
;
764 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This
,lParam
,pidl1
,pidl2
);
768 if (!pidl1
&& !pidl2
)
770 hr
= ResultFromShort(0);
774 hr
= ResultFromShort(-1);
778 hr
= ResultFromShort(1);
783 pd1
= _ILGetDataPointer(pidl1
);
784 pd2
= _ILGetDataPointer(pidl2
);
786 /* compate the types. sort order is the PT_* constant */
787 pt1
= ( pd1
? pd1
->type
: PT_DESKTOP
);
788 pt2
= ( pd2
? pd2
->type
: PT_DESKTOP
);
792 hr
= ResultFromShort(pt1
-pt2
);
794 else /* same type of pidl */
796 _ILSimpleGetText(pidl1
, szTemp1
, MAX_PATH
);
797 _ILSimpleGetText(pidl2
, szTemp2
, MAX_PATH
);
798 nReturn
= strcasecmp(szTemp1
, szTemp2
);
800 if (nReturn
== 0) /* first pidl different ? */
802 pidl1
= ILGetNext(pidl1
);
804 if (pidl1
&& pidl1
->mkid
.cb
) /* go deeper? */
806 pidlTemp
= ILCloneFirst(pidl1
);
807 pidl2
= ILGetNext(pidl2
);
809 hr
= IShellFolder_BindToObject(iface
, pidlTemp
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psf
);
812 nReturn
= IShellFolder_CompareIDs(psf
, 0, pidl1
, pidl2
);
813 IShellFolder_Release(psf
);
814 hr
= ResultFromShort(nReturn
);
820 hr
= ResultFromShort(nReturn
); /* two equal simple pidls */
825 hr
= ResultFromShort(nReturn
); /* two different simple pidls */
830 TRACE("-- res=0x%08lx\n", hr
);
834 /**************************************************************************
835 * IShellFolder_fnCreateViewObject
837 static HRESULT WINAPI
IShellFolder_fnCreateViewObject(
838 IShellFolder2
* iface
,
843 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
845 LPSHELLVIEW pShellView
;
846 HRESULT hr
= E_INVALIDARG
;
848 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
854 if(IsEqualIID(riid
, &IID_IDropTarget
))
856 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, ppvOut
);
858 else if(IsEqualIID(riid
, &IID_IContextMenu
))
860 FIXME("IContextMenu not implemented\n");
863 else if(IsEqualIID(riid
, &IID_IShellView
))
865 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
868 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
869 IShellView_Release(pShellView
);
873 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
877 /**************************************************************************
878 * IShellFolder_fnGetAttributesOf
881 * UINT cidl, //[in ] num elements in pidl array
882 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
883 * ULONG* rgfInOut) //[out] result array
886 static HRESULT WINAPI
IShellFolder_fnGetAttributesOf(
887 IShellFolder2
* iface
,
889 LPCITEMIDLIST
*apidl
,
892 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
896 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
898 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
901 while (cidl
> 0 && *apidl
)
904 if (_ILIsFolder( *apidl
))
906 *rgfInOut
&= 0xe0000177;
909 else if (_ILIsValue( *apidl
))
911 *rgfInOut
&= 0x40000177;
920 TRACE("-- result=0x%08lx\n",*rgfInOut
);
924 /**************************************************************************
925 * IShellFolder_fnGetUIObjectOf
928 * HWND hwndOwner, //[in ] Parent window for any output
929 * UINT cidl, //[in ] array size
930 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
931 * REFIID riid, //[in ] Requested Interface
932 * UINT* prgfInOut, //[ ] reserved
933 * LPVOID* ppvObject) //[out] Resulting Interface
936 * This function gets asked to return "view objects" for one or more (multiple select)
938 * The viewobject typically is an COM object with one of the following interfaces:
939 * IExtractIcon,IDataObject,IContextMenu
940 * In order to support icon positions in the default Listview your DataObject
941 * must implement the SetData method (in addition to GetData :) - the shell passes
942 * a barely documented "Icon positions" structure to SetData when the drag starts,
943 * and GetData's it if the drop is in another explorer window that needs the positions.
945 static HRESULT WINAPI
IShellFolder_fnGetUIObjectOf(
946 IShellFolder2
* iface
,
949 LPCITEMIDLIST
* apidl
,
954 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
957 IUnknown
* pObj
= NULL
;
958 HRESULT hr
= E_INVALIDARG
;
960 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
961 This
,hwndOwner
,cidl
,apidl
,debugstr_guid(riid
),prgfInOut
,ppvOut
);
967 if(IsEqualIID(riid
, &IID_IContextMenu
) && (cidl
>= 1))
969 pObj
= (LPUNKNOWN
)ISvItemCm_Constructor((IShellFolder
*)iface
, This
->absPidl
, apidl
, cidl
);
972 else if (IsEqualIID(riid
, &IID_IDataObject
) &&(cidl
>= 1))
974 pObj
= (LPUNKNOWN
)IDataObject_Constructor (hwndOwner
, This
->absPidl
, apidl
, cidl
);
977 else if (IsEqualIID(riid
, &IID_IExtractIconA
) && (cidl
== 1))
979 pidl
= ILCombine(This
->absPidl
,apidl
[0]);
980 pObj
= (LPUNKNOWN
)IExtractIconA_Constructor( pidl
);
984 else if (IsEqualIID(riid
, &IID_IDropTarget
) && (cidl
>= 1))
986 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, (LPVOID
*)&pObj
);
998 TRACE("(%p)->hr=0x%08lx\n",This
, hr
);
1002 /**************************************************************************
1003 * IShellFolder_fnGetDisplayNameOf
1004 * Retrieves the display name for the specified file object or subfolder
1007 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1008 * DWORD dwFlags, //[in ] SHGNO formatting flags
1009 * LPSTRRET lpName) //[out] Returned display name
1012 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1014 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1015 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1017 static HRESULT WINAPI
IShellFolder_fnGetDisplayNameOf(
1018 IShellFolder2
* iface
,
1023 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1025 CHAR szPath
[MAX_PATH
]= "";
1029 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1032 if(!pidl
|| !strRet
) return E_INVALIDARG
;
1034 bSimplePidl
= _ILIsPidlSimple(pidl
);
1036 /* take names of special folders only if its only this folder */
1037 if (_ILIsSpecialFolder(pidl
))
1041 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
1046 if (!(dwFlags
& SHGDN_INFOLDER
) && (dwFlags
& SHGDN_FORPARSING
) && This
->sMyPath
)
1048 strcpy (szPath
, This
->sMyPath
); /* get path to root*/
1049 PathAddBackslashA(szPath
);
1050 len
= strlen(szPath
);
1052 _ILSimpleGetText(pidl
, szPath
+ len
, MAX_PATH
- len
); /* append my own path */
1055 if ( (dwFlags
& SHGDN_FORPARSING
) && !bSimplePidl
) /* go deeper if needed */
1057 PathAddBackslashA(szPath
);
1058 len
= strlen(szPath
);
1060 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
+ len
, MAX_PATH
- len
)))
1061 return E_OUTOFMEMORY
;
1063 strRet
->uType
= STRRET_CSTRA
;
1064 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1066 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1070 /**************************************************************************
1071 * IShellFolder_fnSetNameOf
1072 * Changes the name of a file object or subfolder, possibly changing its item
1073 * identifier in the process.
1076 * HWND hwndOwner, //[in ] Owner window for output
1077 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1078 * LPCOLESTR lpszName, //[in ] the items new display name
1079 * DWORD dwFlags, //[in ] SHGNO formatting flags
1080 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1082 static HRESULT WINAPI
IShellFolder_fnSetNameOf(
1083 IShellFolder2
* iface
,
1085 LPCITEMIDLIST pidl
, /*simple pidl*/
1088 LPITEMIDLIST
*pPidlOut
)
1090 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1091 char szSrc
[MAX_PATH
], szDest
[MAX_PATH
];
1093 BOOL bIsFolder
= _ILIsFolder(ILFindLastID(pidl
));
1095 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1096 This
,hwndOwner
,pidl
,debugstr_w(lpName
),dwFlags
,pPidlOut
);
1098 /* build source path */
1099 if (dwFlags
& SHGDN_INFOLDER
)
1101 strcpy(szSrc
, This
->sMyPath
);
1102 PathAddBackslashA(szSrc
);
1103 len
= strlen (szSrc
);
1104 _ILSimpleGetText(pidl
, szSrc
+len
, MAX_PATH
-len
);
1108 SHGetPathFromIDListA(pidl
, szSrc
);
1111 /* build destination path */
1112 strcpy(szDest
, This
->sMyPath
);
1113 PathAddBackslashA(szDest
);
1114 len
= strlen (szDest
);
1115 lstrcpynWtoA(szDest
+len
, lpName
, MAX_PATH
-len
);
1117 TRACE("src=%s dest=%s\n", szSrc
, szDest
);
1118 if ( MoveFileA(szSrc
, szDest
) )
1120 if (pPidlOut
) *pPidlOut
= SHSimpleIDListFromPathA(szDest
);
1121 SHChangeNotifyA( bIsFolder
?SHCNE_RENAMEFOLDER
:SHCNE_RENAMEITEM
, SHCNF_PATHA
, szSrc
, szDest
);
1127 static HRESULT WINAPI
IShellFolder_fnGetDefaultSearchGUID(
1128 IShellFolder2
* iface
,
1131 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1132 FIXME("(%p)\n",This
);
1135 static HRESULT WINAPI
IShellFolder_fnEnumSearches(
1136 IShellFolder2
* iface
,
1137 IEnumExtraSearch
**ppenum
)
1139 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1140 FIXME("(%p)\n",This
);
1143 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumn(
1144 IShellFolder2
* iface
,
1149 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1151 TRACE("(%p)\n",This
);
1153 if (pSort
) *pSort
= 0;
1154 if (pDisplay
) *pDisplay
= 0;
1158 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumnState(
1159 IShellFolder2
* iface
,
1163 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1165 TRACE("(%p)\n",This
);
1167 if (!pcsFlags
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1169 *pcsFlags
= GenericSFHeader
[iColumn
].pcsFlags
;
1173 static HRESULT WINAPI
IShellFolder_fnGetDetailsEx(
1174 IShellFolder2
* iface
,
1176 const SHCOLUMNID
*pscid
,
1179 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1180 FIXME("(%p)\n",This
);
1184 static HRESULT WINAPI
IShellFolder_fnGetDetailsOf(
1185 IShellFolder2
* iface
,
1190 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1191 HRESULT hr
= E_FAIL
;
1193 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
1195 if (!psd
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1199 /* the header titles */
1200 psd
->fmt
= GenericSFHeader
[iColumn
].fmt
;
1201 psd
->cxChar
= GenericSFHeader
[iColumn
].cxChar
;
1202 psd
->str
.uType
= STRRET_CSTRA
;
1203 LoadStringA(shell32_hInstance
, GenericSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
1208 /* the data from the pidl */
1212 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
1215 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1218 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1221 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1223 case 4: /* attributes */
1224 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1228 psd
->str
.uType
= STRRET_CSTRA
;
1233 static HRESULT WINAPI
IShellFolder_fnMapNameToSCID(
1234 IShellFolder2
* iface
,
1238 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1239 FIXME("(%p)\n",This
);
1243 static ICOM_VTABLE(IShellFolder2
) sfvt
=
1245 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1246 IShellFolder_fnQueryInterface
,
1247 IShellFolder_fnAddRef
,
1248 IShellFolder_fnRelease
,
1249 IShellFolder_fnParseDisplayName
,
1250 IShellFolder_fnEnumObjects
,
1251 IShellFolder_fnBindToObject
,
1252 IShellFolder_fnBindToStorage
,
1253 IShellFolder_fnCompareIDs
,
1254 IShellFolder_fnCreateViewObject
,
1255 IShellFolder_fnGetAttributesOf
,
1256 IShellFolder_fnGetUIObjectOf
,
1257 IShellFolder_fnGetDisplayNameOf
,
1258 IShellFolder_fnSetNameOf
,
1261 IShellFolder_fnGetDefaultSearchGUID
,
1262 IShellFolder_fnEnumSearches
,
1263 IShellFolder_fnGetDefaultColumn
,
1264 IShellFolder_fnGetDefaultColumnState
,
1265 IShellFolder_fnGetDetailsEx
,
1266 IShellFolder_fnGetDetailsOf
,
1267 IShellFolder_fnMapNameToSCID
1270 /****************************************************************************
1271 * ISFHelper for IShellFolder implementation
1274 static HRESULT WINAPI
ISFHelper_fnQueryInterface(
1279 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1281 TRACE("(%p)\n", This
);
1283 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
1286 static ULONG WINAPI
ISFHelper_fnAddRef(
1289 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1291 TRACE("(%p)\n", This
);
1293 return IUnknown_AddRef(This
->pUnkOuter
);
1296 static ULONG WINAPI
ISFHelper_fnRelease(
1299 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1301 TRACE("(%p)\n", This
);
1303 return IUnknown_Release(This
->pUnkOuter
);
1307 /****************************************************************************
1308 * ISFHelper_fnAddFolder
1310 * creates a unique folder name
1313 static HRESULT WINAPI
ISFHelper_fnGetUniqueName(
1318 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1319 IEnumIDList
* penum
;
1321 char szText
[MAX_PATH
];
1322 char * szNewFolder
= "New Folder";
1324 TRACE("(%p)(%s %u)\n", This
, lpName
, uLen
);
1326 if (uLen
< strlen(szNewFolder
) + 4) return E_POINTER
;
1328 strcpy(lpName
, szNewFolder
);
1330 hr
= IShellFolder_fnEnumObjects(_IShellFolder2_(This
), 0, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
| SHCONTF_INCLUDEHIDDEN
, &penum
);
1337 next
: IEnumIDList_Reset(penum
);
1338 while(S_OK
== IEnumIDList_Next(penum
, 1, &pidl
, &dwFetched
) && dwFetched
)
1340 _ILSimpleGetText(pidl
, szText
, MAX_PATH
);
1341 if (0 == strcasecmp(szText
, lpName
))
1343 sprintf(lpName
, "%s %d", szNewFolder
, i
++);
1353 IEnumIDList_Release(penum
);
1358 /****************************************************************************
1359 * ISFHelper_fnAddFolder
1361 * adds a new folder.
1364 static HRESULT WINAPI
ISFHelper_fnAddFolder(
1368 LPITEMIDLIST
* ppidlOut
)
1370 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1371 char lpstrNewDir
[MAX_PATH
];
1373 HRESULT hres
= E_FAIL
;
1375 TRACE("(%p)(%s %p)\n", This
, lpName
, ppidlOut
);
1377 strcpy(lpstrNewDir
, This
->sMyPath
);
1378 PathAddBackslashA(lpstrNewDir
);
1379 strcat(lpstrNewDir
, lpName
);
1381 bRes
= CreateDirectoryA(lpstrNewDir
, NULL
);
1385 LPITEMIDLIST pidl
, pidlitem
;
1387 pidlitem
= SHSimpleIDListFromPathA(lpstrNewDir
);
1389 pidl
= ILCombine(This
->absPidl
, pidlitem
);
1390 SHChangeNotifyA(SHCNE_MKDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1393 if (ppidlOut
) *ppidlOut
= pidlitem
;
1398 char lpstrText
[128+MAX_PATH
];
1399 char lpstrTempText
[128];
1400 char lpstrCaption
[256];
1402 /* Cannot Create folder because of permissions */
1403 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_DENIED
, lpstrTempText
, sizeof(lpstrTempText
));
1404 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_CAPTION
, lpstrCaption
, sizeof(lpstrCaption
));
1405 sprintf(lpstrText
,lpstrTempText
, lpstrNewDir
);
1406 MessageBoxA(hwnd
,lpstrText
, lpstrCaption
, MB_OK
| MB_ICONEXCLAMATION
);
1412 /****************************************************************************
1413 * ISFHelper_fnDeleteItems
1415 * deletes items in folder
1417 static HRESULT WINAPI
ISFHelper_fnDeleteItems(
1420 LPCITEMIDLIST
* apidl
)
1422 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1424 char szPath
[MAX_PATH
];
1426 TRACE("(%p)(%u %p)\n", This
, cidl
, apidl
);
1428 for(i
=0; i
< cidl
; i
++)
1430 strcpy(szPath
, This
->sMyPath
);
1431 PathAddBackslashA(szPath
);
1432 _ILSimpleGetText(apidl
[i
], szPath
+strlen(szPath
), MAX_PATH
);
1434 if (_ILIsFolder(apidl
[i
]))
1438 MESSAGE("delete %s\n", szPath
);
1439 if (! RemoveDirectoryA(szPath
)) return E_FAIL
;
1440 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1441 SHChangeNotifyA(SHCNE_RMDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1444 else if (_ILIsValue(apidl
[i
]))
1448 MESSAGE("delete %s\n", szPath
);
1449 if (! DeleteFileA(szPath
)) return E_FAIL
;
1450 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1451 SHChangeNotifyA(SHCNE_DELETE
, SHCNF_IDLIST
, pidl
, NULL
);
1459 /****************************************************************************
1460 * ISFHelper_fnCopyItems
1462 * copys items to this folder
1464 static HRESULT WINAPI
ISFHelper_fnCopyItems(
1466 IShellFolder
* pSFFrom
,
1468 LPCITEMIDLIST
*apidl
)
1471 IPersistFolder2
* ppf2
=NULL
;
1472 char szSrcPath
[MAX_PATH
], szDstPath
[MAX_PATH
];
1473 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1475 TRACE("(%p)->(%p,%u,%p)\n", This
, pSFFrom
, cidl
, apidl
);
1477 IShellFolder_QueryInterface(pSFFrom
, &IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
1481 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2
, &pidl
)))
1483 for (i
=0; i
<cidl
; i
++)
1485 SHGetPathFromIDListA(pidl
, szSrcPath
);
1486 PathAddBackslashA(szSrcPath
);
1487 _ILSimpleGetText(apidl
[i
], szSrcPath
+strlen(szSrcPath
), MAX_PATH
);
1489 strcpy(szDstPath
, This
->sMyPath
);
1490 PathAddBackslashA(szDstPath
);
1491 _ILSimpleGetText(apidl
[i
], szDstPath
+strlen(szDstPath
), MAX_PATH
);
1492 MESSAGE("would copy %s to %s\n", szSrcPath
, szDstPath
);
1496 IPersistFolder2_Release(ppf2
);
1501 static ICOM_VTABLE(ISFHelper
) shvt
=
1503 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1504 ISFHelper_fnQueryInterface
,
1506 ISFHelper_fnRelease
,
1507 ISFHelper_fnGetUniqueName
,
1508 ISFHelper_fnAddFolder
,
1509 ISFHelper_fnDeleteItems
,
1510 ISFHelper_fnCopyItems
,
1513 /***********************************************************************
1514 * [Desktopfolder] IShellFolder implementation
1516 static struct ICOM_VTABLE(IShellFolder2
) sfdvt
;
1518 static shvheader DesktopSFHeader
[] =
1520 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
1521 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1522 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1523 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
1524 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
1526 #define DESKTOPSHELLVIEWCOLUMNS 5
1528 /**************************************************************************
1529 * ISF_Desktop_Constructor
1532 IShellFolder
* ISF_Desktop_Constructor()
1534 IGenericSFImpl
* sf
;
1536 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
1538 ICOM_VTBL(sf
)=&unkvt
;
1539 sf
->lpvtblShellFolder
=&sfdvt
;
1540 sf
->absPidl
=_ILCreateDesktop(); /* my qualified pidl */
1541 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
1546 return _IShellFolder_(sf
);
1549 /**************************************************************************
1550 * ISF_Desktop_fnQueryInterface
1552 * NOTES supports not IPersist/IPersistFolder
1554 static HRESULT WINAPI
ISF_Desktop_fnQueryInterface(
1555 IShellFolder2
* iface
,
1559 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1561 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
1565 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
1567 *ppvObj
= _IUnknown_(This
);
1569 else if(IsEqualIID(riid
, &IID_IShellFolder
)) /*IShellFolder*/
1571 *ppvObj
= _IShellFolder_(This
);
1573 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) /*IShellFolder2*/
1575 *ppvObj
= _IShellFolder_(This
);
1580 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
1581 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
1584 TRACE("-- Interface: E_NOINTERFACE\n");
1585 return E_NOINTERFACE
;
1588 /**************************************************************************
1589 * ISF_Desktop_fnParseDisplayName
1592 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1595 static HRESULT WINAPI
ISF_Desktop_fnParseDisplayName(
1596 IShellFolder2
* iface
,
1599 LPOLESTR lpszDisplayName
,
1601 LPITEMIDLIST
*ppidl
,
1602 DWORD
*pdwAttributes
)
1604 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1606 LPCWSTR szNext
=NULL
;
1607 LPITEMIDLIST pidlTemp
=NULL
;
1608 HRESULT hr
=E_OUTOFMEMORY
;
1610 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1611 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
1612 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
1615 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
1617 /* fixme no real parsing implemented */
1618 pidlTemp
= _ILCreateMyComputer();
1619 szNext
= lpszDisplayName
;
1621 if (szNext
&& *szNext
)
1623 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
1632 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
1637 /**************************************************************************
1638 * ISF_Desktop_fnEnumObjects
1640 static HRESULT WINAPI
ISF_Desktop_fnEnumObjects(
1641 IShellFolder2
* iface
,
1644 LPENUMIDLIST
* ppEnumIDList
)
1646 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1648 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
1650 *ppEnumIDList
= NULL
;
1651 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_DESK
);
1653 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
1655 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
1660 /**************************************************************************
1661 * ISF_Desktop_fnBindToObject
1663 static HRESULT WINAPI
ISF_Desktop_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
1664 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
1666 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1668 IShellFolder
*pShellFolder
, *pSubFolder
;
1670 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1671 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
1675 if ((clsid
=_ILGetGUIDPointer(pidl
)))
1677 if ( IsEqualIID(clsid
, &CLSID_MyComputer
))
1679 pShellFolder
= ISF_MyComputer_Constructor();
1683 /* shell extension */
1684 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
1686 return E_INVALIDARG
;
1692 /* file system folder on the desktop */
1693 LPITEMIDLIST deskpidl
, firstpidl
, completepidl
;
1694 IPersistFolder
* ppf
;
1697 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY
, &deskpidl
);
1698 firstpidl
= ILCloneFirst(pidl
);
1699 completepidl
= ILCombine(deskpidl
, firstpidl
);
1701 pShellFolder
= IShellFolder_Constructor(NULL
, NULL
);
1702 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&ppf
)))
1704 IPersistFolder_Initialize(ppf
, completepidl
);
1705 IPersistFolder_Release(ppf
);
1707 ILFree(completepidl
);
1712 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
1714 *ppvOut
= pShellFolder
;
1716 else /* go deeper */
1718 IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, riid
, (LPVOID
)&pSubFolder
);
1719 IShellFolder_Release(pShellFolder
);
1720 *ppvOut
= pSubFolder
;
1723 TRACE("-- (%p) returning (%p)\n",This
, *ppvOut
);
1728 /**************************************************************************
1729 * ISF_Desktop_fnCreateViewObject
1731 static HRESULT WINAPI
ISF_Desktop_fnCreateViewObject( IShellFolder2
* iface
,
1732 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
1734 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1736 LPSHELLVIEW pShellView
;
1737 HRESULT hr
= E_INVALIDARG
;
1739 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
1745 if(IsEqualIID(riid
, &IID_IDropTarget
))
1747 FIXME("IDropTarget not implemented\n");
1750 else if(IsEqualIID(riid
, &IID_IContextMenu
))
1752 FIXME("IContextMenu not implemented\n");
1755 else if(IsEqualIID(riid
, &IID_IShellView
))
1757 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
1760 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
1761 IShellView_Release(pShellView
);
1765 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
1769 /**************************************************************************
1770 * ISF_Desktop_fnGetAttributesOf
1772 static HRESULT WINAPI
ISF_Desktop_fnGetAttributesOf(IShellFolder2
* iface
,UINT cidl
,LPCITEMIDLIST
*apidl
,DWORD
*rgfInOut
)
1774 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1780 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
, *rgfInOut
);
1782 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
1783 return E_INVALIDARG
;
1785 while (cidl
> 0 && *apidl
)
1789 if ((clsid
=_ILGetGUIDPointer(*apidl
)))
1791 if (IsEqualIID(clsid
, &CLSID_MyComputer
))
1793 *rgfInOut
&= 0xb0000154;
1796 else if (HCR_GetFolderAttributes(clsid
, &attributes
))
1798 *rgfInOut
&= attributes
;
1802 { /* some shell-extension */
1803 *rgfInOut
&= 0xb0000154;
1806 else if (_ILIsFolder( *apidl
))
1808 *rgfInOut
&= 0xe0000177;
1811 else if (_ILIsValue( *apidl
))
1813 *rgfInOut
&= 0x40000177;
1822 TRACE("-- result=0x%08lx\n",*rgfInOut
);
1827 /**************************************************************************
1828 * ISF_Desktop_fnGetDisplayNameOf
1831 * special case: pidl = null gives desktop-name back
1833 static HRESULT WINAPI
ISF_Desktop_fnGetDisplayNameOf(
1834 IShellFolder2
* iface
,
1839 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1841 CHAR szPath
[MAX_PATH
]= "";
1843 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1846 if(!strRet
) return E_INVALIDARG
;
1850 HCR_GetClassName(&CLSID_ShellDesktop
, szPath
, MAX_PATH
);
1852 else if ( _ILIsPidlSimple(pidl
) )
1854 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
1858 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
, MAX_PATH
)))
1859 return E_OUTOFMEMORY
;
1861 strRet
->uType
= STRRET_CSTRA
;
1862 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1865 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1869 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultSearchGUID(
1870 IShellFolder2
* iface
,
1873 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1874 FIXME("(%p)\n",This
);
1877 static HRESULT WINAPI
ISF_Desktop_fnEnumSearches(
1878 IShellFolder2
* iface
,
1879 IEnumExtraSearch
**ppenum
)
1881 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1882 FIXME("(%p)\n",This
);
1885 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumn(
1886 IShellFolder2
* iface
,
1891 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1893 TRACE("(%p)\n",This
);
1895 if (pSort
) *pSort
= 0;
1896 if (pDisplay
) *pDisplay
= 0;
1900 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumnState(
1901 IShellFolder2
* iface
,
1905 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1907 TRACE("(%p)\n",This
);
1909 if (!pcsFlags
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1911 *pcsFlags
= DesktopSFHeader
[iColumn
].pcsFlags
;
1915 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsEx(
1916 IShellFolder2
* iface
,
1918 const SHCOLUMNID
*pscid
,
1921 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1922 FIXME("(%p)\n",This
);
1926 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsOf(
1927 IShellFolder2
* iface
,
1932 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1933 HRESULT hr
= E_FAIL
;;
1935 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
1937 if (!psd
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1941 psd
->fmt
= DesktopSFHeader
[iColumn
].fmt
;
1942 psd
->cxChar
= DesktopSFHeader
[iColumn
].cxChar
;
1943 psd
->str
.uType
= STRRET_CSTRA
;
1944 LoadStringA(shell32_hInstance
, DesktopSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
1949 /* the data from the pidl */
1953 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
1956 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1959 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1962 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1964 case 4: /* attributes */
1965 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1969 psd
->str
.uType
= STRRET_CSTRA
;
1974 static HRESULT WINAPI
ISF_Desktop_fnMapNameToSCID(
1975 IShellFolder2
* iface
,
1979 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1980 FIXME("(%p)\n",This
);
1984 static ICOM_VTABLE(IShellFolder2
) sfdvt
=
1986 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1987 ISF_Desktop_fnQueryInterface
,
1988 IShellFolder_fnAddRef
,
1989 IShellFolder_fnRelease
,
1990 ISF_Desktop_fnParseDisplayName
,
1991 ISF_Desktop_fnEnumObjects
,
1992 ISF_Desktop_fnBindToObject
,
1993 IShellFolder_fnBindToStorage
,
1994 IShellFolder_fnCompareIDs
,
1995 ISF_Desktop_fnCreateViewObject
,
1996 ISF_Desktop_fnGetAttributesOf
,
1997 IShellFolder_fnGetUIObjectOf
,
1998 ISF_Desktop_fnGetDisplayNameOf
,
1999 IShellFolder_fnSetNameOf
,
2002 ISF_Desktop_fnGetDefaultSearchGUID
,
2003 ISF_Desktop_fnEnumSearches
,
2004 ISF_Desktop_fnGetDefaultColumn
,
2005 ISF_Desktop_fnGetDefaultColumnState
,
2006 ISF_Desktop_fnGetDetailsEx
,
2007 ISF_Desktop_fnGetDetailsOf
,
2008 ISF_Desktop_fnMapNameToSCID
2012 /***********************************************************************
2013 * IShellFolder [MyComputer] implementation
2016 static struct ICOM_VTABLE(IShellFolder2
) sfmcvt
;
2018 static shvheader MyComputerSFHeader
[] =
2020 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
2021 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2022 { IDS_SHV_COLUMN6
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2023 { IDS_SHV_COLUMN7
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2025 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2027 /**************************************************************************
2028 * ISF_MyComputer_Constructor
2030 static IShellFolder
* ISF_MyComputer_Constructor(void)
2032 IGenericSFImpl
* sf
;
2034 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
2037 ICOM_VTBL(sf
)=&unkvt
;
2038 sf
->lpvtblShellFolder
=&sfmcvt
;
2039 sf
->lpvtblPersistFolder2
= &psfvt
;
2040 sf
->pclsid
= (CLSID
*)&CLSID_SFMyComp
;
2041 sf
->absPidl
=_ILCreateMyComputer(); /* my qualified pidl */
2042 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
2047 return _IShellFolder_(sf
);
2050 /**************************************************************************
2051 * ISF_MyComputer_fnParseDisplayName
2053 static HRESULT WINAPI
ISF_MyComputer_fnParseDisplayName(
2054 IShellFolder2
* iface
,
2057 LPOLESTR lpszDisplayName
,
2059 LPITEMIDLIST
*ppidl
,
2060 DWORD
*pdwAttributes
)
2062 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2064 HRESULT hr
= E_OUTOFMEMORY
;
2065 LPCWSTR szNext
=NULL
;
2066 WCHAR szElement
[MAX_PATH
];
2067 CHAR szTempA
[MAX_PATH
];
2068 LPITEMIDLIST pidlTemp
;
2070 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2071 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
2072 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
2075 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
2077 if (PathIsRootW(lpszDisplayName
))
2079 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
2080 lstrcpynWtoA(szTempA
, szElement
, lstrlenW(szElement
) + 1);
2081 pidlTemp
= _ILCreateDrive(szTempA
);
2083 if (szNext
&& *szNext
)
2085 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
2094 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
2099 /**************************************************************************
2100 * ISF_MyComputer_fnEnumObjects
2102 static HRESULT WINAPI
ISF_MyComputer_fnEnumObjects(
2103 IShellFolder2
* iface
,
2106 LPENUMIDLIST
* ppEnumIDList
)
2108 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2110 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
2112 *ppEnumIDList
= NULL
;
2113 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_MYCOMP
);
2115 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
2117 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
2122 /**************************************************************************
2123 * ISF_MyComputer_fnBindToObject
2125 static HRESULT WINAPI
ISF_MyComputer_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
2126 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
2128 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2130 IShellFolder
*pShellFolder
, *pSubFolder
;
2131 LPITEMIDLIST pidltemp
;
2133 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2134 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
2136 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
2140 if ((clsid
=_ILGetGUIDPointer(pidl
)) && !IsEqualIID(clsid
, &CLSID_MyComputer
))
2142 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
2149 if (!_ILIsDrive(pidl
)) return E_INVALIDARG
;
2151 pidltemp
= ILCloneFirst(pidl
);
2152 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
2156 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
2158 *ppvOut
= pShellFolder
;
2160 else /* go deeper */
2162 IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, &IID_IShellFolder
, (LPVOID
)&pSubFolder
);
2163 IShellFolder_Release(pShellFolder
);
2164 *ppvOut
= pSubFolder
;
2167 TRACE("-- (%p) returning (%p)\n",This
, *ppvOut
);
2172 /**************************************************************************
2173 * ISF_MyComputer_fnCreateViewObject
2175 static HRESULT WINAPI
ISF_MyComputer_fnCreateViewObject( IShellFolder2
* iface
,
2176 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
2178 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2180 LPSHELLVIEW pShellView
;
2181 HRESULT hr
= E_INVALIDARG
;
2183 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
2189 if(IsEqualIID(riid
, &IID_IDropTarget
))
2191 FIXME("IDropTarget not implemented\n");
2194 else if(IsEqualIID(riid
, &IID_IContextMenu
))
2196 FIXME("IContextMenu not implemented\n");
2199 else if(IsEqualIID(riid
, &IID_IShellView
))
2201 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
2204 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
2205 IShellView_Release(pShellView
);
2209 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
2213 /**************************************************************************
2214 * ISF_MyComputer_fnGetAttributesOf
2216 static HRESULT WINAPI
ISF_MyComputer_fnGetAttributesOf(IShellFolder2
* iface
,UINT cidl
,LPCITEMIDLIST
*apidl
,DWORD
*rgfInOut
)
2218 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2224 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
2226 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
2227 return E_INVALIDARG
;
2229 *rgfInOut
= 0xffffffff;
2231 while (cidl
> 0 && *apidl
)
2235 if (_ILIsDrive(*apidl
))
2237 *rgfInOut
&= 0xf0000144;
2240 else if ((clsid
=_ILGetGUIDPointer(*apidl
)))
2242 if (HCR_GetFolderAttributes(clsid
, &attributes
))
2244 *rgfInOut
&= attributes
;
2254 TRACE("-- result=0x%08lx\n",*rgfInOut
);
2258 /**************************************************************************
2259 * ISF_MyComputer_fnGetDisplayNameOf
2262 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2263 * SHGDN_INFOLDER makes no sense.
2265 static HRESULT WINAPI
ISF_MyComputer_fnGetDisplayNameOf(
2266 IShellFolder2
* iface
,
2271 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2273 char szPath
[MAX_PATH
], szDrive
[18];
2277 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
2280 if(!strRet
) return E_INVALIDARG
;
2282 szPath
[0]=0x00; szDrive
[0]=0x00;
2285 bSimplePidl
= _ILIsPidlSimple(pidl
);
2287 if (_ILIsSpecialFolder(pidl
))
2289 /* take names of special folders only if its only this folder */
2292 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2297 if (!_ILIsDrive(pidl
))
2299 ERR("Wrong pidl type\n");
2300 return E_INVALIDARG
;
2303 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2305 /* long view "lw_name (C:)" */
2306 if ( bSimplePidl
&& !(dwFlags
& SHGDN_FORPARSING
))
2308 DWORD dwVolumeSerialNumber
,dwMaximumComponetLength
,dwFileSystemFlags
;
2310 GetVolumeInformationA(szPath
,szDrive
,12,&dwVolumeSerialNumber
,&dwMaximumComponetLength
,&dwFileSystemFlags
,NULL
,0);
2311 strcat (szDrive
," (");
2312 strncat (szDrive
, szPath
, 2);
2313 strcat (szDrive
,")");
2314 strcpy (szPath
, szDrive
);
2318 if (!bSimplePidl
) /* go deeper if needed */
2320 PathAddBackslashA(szPath
);
2321 len
= strlen(szPath
);
2323 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
| SHGDN_FORPARSING
, szPath
+ len
, MAX_PATH
- len
)))
2324 return E_OUTOFMEMORY
;
2326 strRet
->uType
= STRRET_CSTRA
;
2327 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
2330 TRACE("-- (%p)->(%s)\n", This
, szPath
);
2334 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultSearchGUID(
2335 IShellFolder2
* iface
,
2338 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2339 FIXME("(%p)\n",This
);
2342 static HRESULT WINAPI
ISF_MyComputer_fnEnumSearches(
2343 IShellFolder2
* iface
,
2344 IEnumExtraSearch
**ppenum
)
2346 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2347 FIXME("(%p)\n",This
);
2350 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumn(
2351 IShellFolder2
* iface
,
2356 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2358 TRACE("(%p)\n",This
);
2360 if (pSort
) *pSort
= 0;
2361 if (pDisplay
) *pDisplay
= 0;
2365 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumnState(
2366 IShellFolder2
* iface
,
2370 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2372 TRACE("(%p)\n",This
);
2374 if (!pcsFlags
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2376 *pcsFlags
= MyComputerSFHeader
[iColumn
].pcsFlags
;
2380 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsEx(
2381 IShellFolder2
* iface
,
2383 const SHCOLUMNID
*pscid
,
2386 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2387 FIXME("(%p)\n",This
);
2392 /* fixme: drive size >4GB is rolling over */
2393 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsOf(
2394 IShellFolder2
* iface
,
2399 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2402 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
2404 if (!psd
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2408 psd
->fmt
= MyComputerSFHeader
[iColumn
].fmt
;
2409 psd
->cxChar
= MyComputerSFHeader
[iColumn
].cxChar
;
2410 psd
->str
.uType
= STRRET_CSTRA
;
2411 LoadStringA(shell32_hInstance
, MyComputerSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
2416 char szPath
[MAX_PATH
];
2417 ULARGE_INTEGER ulBytes
;
2419 psd
->str
.u
.cStr
[0] = 0x00;
2420 psd
->str
.uType
= STRRET_CSTRA
;
2424 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
2427 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2429 case 2: /* total size */
2430 if (_ILIsDrive(pidl
))
2432 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2433 GetDiskFreeSpaceExA(szPath
, NULL
, &ulBytes
, NULL
);
2434 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2437 case 3: /* free size */
2438 if (_ILIsDrive(pidl
))
2440 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2441 GetDiskFreeSpaceExA(szPath
, &ulBytes
, NULL
, NULL
);
2442 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2451 static HRESULT WINAPI
ISF_MyComputer_fnMapNameToSCID(
2452 IShellFolder2
* iface
,
2456 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2457 FIXME("(%p)\n",This
);
2461 static ICOM_VTABLE(IShellFolder2
) sfmcvt
=
2463 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2464 IShellFolder_fnQueryInterface
,
2465 IShellFolder_fnAddRef
,
2466 IShellFolder_fnRelease
,
2467 ISF_MyComputer_fnParseDisplayName
,
2468 ISF_MyComputer_fnEnumObjects
,
2469 ISF_MyComputer_fnBindToObject
,
2470 IShellFolder_fnBindToStorage
,
2471 IShellFolder_fnCompareIDs
,
2472 ISF_MyComputer_fnCreateViewObject
,
2473 ISF_MyComputer_fnGetAttributesOf
,
2474 IShellFolder_fnGetUIObjectOf
,
2475 ISF_MyComputer_fnGetDisplayNameOf
,
2476 IShellFolder_fnSetNameOf
,
2479 ISF_MyComputer_fnGetDefaultSearchGUID
,
2480 ISF_MyComputer_fnEnumSearches
,
2481 ISF_MyComputer_fnGetDefaultColumn
,
2482 ISF_MyComputer_fnGetDefaultColumnState
,
2483 ISF_MyComputer_fnGetDetailsEx
,
2484 ISF_MyComputer_fnGetDetailsOf
,
2485 ISF_MyComputer_fnMapNameToSCID
2489 /************************************************************************
2490 * ISFPersistFolder_QueryInterface (IUnknown)
2493 static HRESULT WINAPI
ISFPersistFolder2_QueryInterface(
2494 IPersistFolder2
* iface
,
2498 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2500 TRACE("(%p)\n", This
);
2502 return IUnknown_QueryInterface(This
->pUnkOuter
, iid
, ppvObj
);
2505 /************************************************************************
2506 * ISFPersistFolder_AddRef (IUnknown)
2509 static ULONG WINAPI
ISFPersistFolder2_AddRef(
2510 IPersistFolder2
* iface
)
2512 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2514 TRACE("(%p)\n", This
);
2516 return IUnknown_AddRef(This
->pUnkOuter
);
2519 /************************************************************************
2520 * ISFPersistFolder_Release (IUnknown)
2523 static ULONG WINAPI
ISFPersistFolder2_Release(
2524 IPersistFolder2
* iface
)
2526 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2528 TRACE("(%p)\n", This
);
2530 return IUnknown_Release(This
->pUnkOuter
);
2533 /************************************************************************
2534 * ISFPersistFolder_GetClassID (IPersist)
2536 static HRESULT WINAPI
ISFPersistFolder2_GetClassID(
2537 IPersistFolder2
* iface
,
2540 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2542 TRACE("(%p)\n", This
);
2544 if (!lpClassId
) return E_POINTER
;
2545 *lpClassId
= *This
->pclsid
;
2550 /************************************************************************
2551 * ISFPersistFolder_Initialize (IPersistFolder)
2554 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2556 static HRESULT WINAPI
ISFPersistFolder2_Initialize(
2557 IPersistFolder2
* iface
,
2560 char sTemp
[MAX_PATH
];
2561 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2563 TRACE("(%p)->(%p)\n", This
, pidl
);
2565 /* free the old stuff */
2568 SHFree(This
->absPidl
);
2569 This
->absPidl
= NULL
;
2573 SHFree(This
->sMyPath
);
2574 This
->sMyPath
= NULL
;
2578 This
->absPidl
= ILClone(pidl
);
2581 if (SHGetPathFromIDListA(pidl
, sTemp
))
2583 This
->sMyPath
= SHAlloc(strlen(sTemp
+1));
2584 strcpy(This
->sMyPath
, sTemp
);
2587 TRACE("--(%p)->(%s)\n", This
, This
->sMyPath
);
2592 /**************************************************************************
2593 * IPersistFolder2_fnGetCurFolder
2595 static HRESULT WINAPI
ISFPersistFolder2_fnGetCurFolder(
2596 IPersistFolder2
* iface
,
2597 LPITEMIDLIST
* pidl
)
2599 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2601 TRACE("(%p)->(%p)\n",This
, pidl
);
2603 if (!pidl
) return E_POINTER
;
2605 *pidl
= ILClone(This
->absPidl
);
2610 static ICOM_VTABLE(IPersistFolder2
) psfvt
=
2612 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2613 ISFPersistFolder2_QueryInterface
,
2614 ISFPersistFolder2_AddRef
,
2615 ISFPersistFolder2_Release
,
2616 ISFPersistFolder2_GetClassID
,
2617 ISFPersistFolder2_Initialize
,
2618 ISFPersistFolder2_fnGetCurFolder
2621 /****************************************************************************
2622 * ISFDropTarget implementation
2624 static BOOL
ISFDropTarget_QueryDrop(
2629 DWORD dwEffect
= *pdwEffect
;
2631 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2633 *pdwEffect
= DROPEFFECT_NONE
;
2635 if (This
->fAcceptFmt
)
2636 { /* Does our interpretation of the keystate ... */
2637 *pdwEffect
= KeyStateToDropEffect(dwKeyState
);
2639 /* ... matches the desired effect ? */
2640 if (dwEffect
& *pdwEffect
)
2648 static HRESULT WINAPI
ISFDropTarget_QueryInterface(
2653 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2655 TRACE("(%p)\n", This
);
2657 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
2660 static ULONG WINAPI
ISFDropTarget_AddRef( IDropTarget
*iface
)
2662 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2664 TRACE("(%p)\n", This
);
2666 return IUnknown_AddRef(This
->pUnkOuter
);
2669 static ULONG WINAPI
ISFDropTarget_Release( IDropTarget
*iface
)
2671 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2673 TRACE("(%p)\n", This
);
2675 return IUnknown_Release(This
->pUnkOuter
);
2678 static HRESULT WINAPI
ISFDropTarget_DragEnter(
2680 IDataObject
*pDataObject
,
2687 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2689 TRACE("(%p)->(DataObject=%p)\n",This
,pDataObject
);
2691 InitFormatEtc(fmt
, This
->cfShellIDList
, TYMED_HGLOBAL
);
2693 This
->fAcceptFmt
= (S_OK
== IDataObject_QueryGetData(pDataObject
, &fmt
)) ? TRUE
: FALSE
;
2695 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2700 static HRESULT WINAPI
ISFDropTarget_DragOver(
2706 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2708 TRACE("(%p)\n",This
);
2710 if(!pdwEffect
) return E_INVALIDARG
;
2712 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2717 static HRESULT WINAPI
ISFDropTarget_DragLeave(
2720 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2722 TRACE("(%p)\n",This
);
2724 This
->fAcceptFmt
= FALSE
;
2729 static HRESULT WINAPI
ISFDropTarget_Drop(
2731 IDataObject
* pDataObject
,
2736 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2738 FIXME("(%p) object dropped\n",This
);
2743 static struct ICOM_VTABLE(IDropTarget
) dtvt
=
2745 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2746 ISFDropTarget_QueryInterface
,
2747 ISFDropTarget_AddRef
,
2748 ISFDropTarget_Release
,
2749 ISFDropTarget_DragEnter
,
2750 ISFDropTarget_DragOver
,
2751 ISFDropTarget_DragLeave
,