4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
7 * IShellFolder2 and related interfaces
15 #include "debugtools.h"
23 #include "wine/obj_base.h"
24 #include "wine/obj_dragdrop.h"
25 #include "wine/obj_shellfolder.h"
26 #include "wine/undocshell.h"
27 #include "shell32_main.h"
30 #include "shellfolder.h"
32 DEFAULT_DEBUG_CHANNEL(shell
);
35 /***************************************************************************
36 * debughelper: print out the return adress
37 * helps especially to track down unbalanced AddRef/Release
42 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
56 /***************************************************************************
57 * GetNextElement (internal function)
59 * gets a part of a string till the first backslash
62 * pszNext [IN] string to get the element from
63 * pszOut [IN] pointer to buffer whitch receives string
64 * dwOut [IN] length of pszOut
67 * LPSTR pointer to first, not yet parsed char
70 static LPCWSTR
GetNextElementW(LPCWSTR pszNext
,LPWSTR pszOut
,DWORD dwOut
)
71 { LPCWSTR pszTail
= pszNext
;
73 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext
),pszOut
,dwOut
);
77 if(!pszNext
|| !*pszNext
)
80 while(*pszTail
&& (*pszTail
!= (WCHAR
)'\\'))
83 dwCopy
= (WCHAR
*)pszTail
- (WCHAR
*)pszNext
+ 1;
84 lstrcpynW(pszOut
, pszNext
, (dwOut
<dwCopy
)? dwOut
: dwCopy
);
91 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext
),debugstr_w(pszOut
),dwOut
,pszTail
);
95 static HRESULT
SHELL32_ParseNextElement(
98 LPITEMIDLIST
* pidlInOut
,
101 DWORD
*pdwAttributes
)
103 HRESULT hr
= E_OUTOFMEMORY
;
104 LPITEMIDLIST pidlOut
, pidlTemp
= NULL
;
105 IShellFolder
*psfChild
;
107 TRACE("(%p, %p, %s)\n",psf
, pidlInOut
? *pidlInOut
: NULL
, debugstr_w(szNext
));
110 /* get the shellfolder for the child pidl and let it analyse further */
111 hr
= IShellFolder_BindToObject(psf
, *pidlInOut
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
115 hr
= IShellFolder_ParseDisplayName(psfChild
, hwndOwner
, NULL
, szNext
, pEaten
, &pidlOut
, pdwAttributes
);
116 IShellFolder_Release(psfChild
);
118 pidlTemp
= ILCombine(*pidlInOut
, pidlOut
);
125 *pidlInOut
= pidlTemp
;
127 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut
? *pidlInOut
: NULL
, hr
);
131 /***********************************************************************
132 * SHELL32_CoCreateInitSF
134 * creates a initialized shell folder
136 static HRESULT
SHELL32_CoCreateInitSF (
137 LPITEMIDLIST pidlRoot
,
138 LPITEMIDLIST pidlChild
,
144 LPITEMIDLIST absPidl
;
145 IShellFolder2
*pShellFolder
;
146 IPersistFolder
*pPersistFolder
;
148 TRACE("%p %p\n", pidlRoot
, pidlChild
);
152 /* we have to ask first for IPersistFolder, some special folders are expecting this */
153 hr
= SHCoCreateInstance(NULL
, clsid
, NULL
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
);
156 hr
= IPersistFolder_QueryInterface(pPersistFolder
, iid
, (LPVOID
*)&pShellFolder
);
159 absPidl
= ILCombine (pidlRoot
, pidlChild
);
160 hr
= IPersistFolder_Initialize(pPersistFolder
, absPidl
);
161 IPersistFolder_Release(pPersistFolder
);
163 *ppvOut
= pShellFolder
;
167 TRACE("-- ret=0x%08lx\n", hr
);
171 static HRESULT
SHELL32_GetDisplayNameOfChild(
178 LPITEMIDLIST pidlFirst
, pidlNext
;
179 IShellFolder2
* psfChild
;
180 HRESULT hr
= E_OUTOFMEMORY
;
183 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf
,pidl
,dwFlags
,szOut
, dwOutLen
);
186 if ((pidlFirst
= ILCloneFirst(pidl
)))
188 hr
= IShellFolder_BindToObject(psf
, pidlFirst
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
191 pidlNext
= ILGetNext(pidl
);
193 hr
= IShellFolder_GetDisplayNameOf(psfChild
, pidlNext
, dwFlags
| SHGDN_INFOLDER
, &strTemp
);
196 hr
= StrRetToStrNA(szOut
, dwOutLen
, &strTemp
, pidlNext
);
199 IShellFolder_Release(psfChild
);
204 TRACE("-- ret=0x%08lx %s\n", hr
, szOut
);
209 /***********************************************************************
210 * SHELL32_GetItemAttributes
214 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
215 * file: 0x40000177 FILESYSTEM
216 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
217 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
218 * (seems to be default for shell extensions if no registry entry exists)
220 * This functions does not set flags!! It only resets flags when nessesary.
222 static HRESULT
SHELL32_GetItemAttributes(
225 LPDWORD pdwAttributes
)
230 TRACE("0x%08lx\n", *pdwAttributes
);
232 if (*pdwAttributes
& (0xcff3fe88))
233 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes
);
234 *pdwAttributes
&= ~SFGAO_LINK
; /* FIXME: for native filedialogs */
236 if (_ILIsDrive(pidl
))
238 *pdwAttributes
&= 0xf0000144;
240 else if ((clsid
=_ILGetGUIDPointer(pidl
)))
242 if (HCR_GetFolderAttributes(clsid
, &dwAttributes
))
244 *pdwAttributes
&= dwAttributes
;
248 *pdwAttributes
&= 0xb0000154;
251 else if (_ILGetDataPointer(pidl
))
253 dwAttributes
= _ILGetFileAttributes(pidl
, NULL
, 0);
254 *pdwAttributes
&= ~SFGAO_FILESYSANCESTOR
;
256 if(( SFGAO_FOLDER
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
257 *pdwAttributes
&= ~(SFGAO_FOLDER
|SFGAO_HASSUBFOLDER
);
259 if(( SFGAO_HIDDEN
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_HIDDEN
))
260 *pdwAttributes
&= ~SFGAO_HIDDEN
;
262 if(( SFGAO_READONLY
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_READONLY
))
263 *pdwAttributes
&= ~SFGAO_READONLY
;
267 *pdwAttributes
&= 0xb0000154;
269 TRACE("-- 0x%08lx\n", *pdwAttributes
);
273 /***********************************************************************
274 * IShellFolder implementation
279 ICOM_VFIELD(IUnknown
);
281 ICOM_VTABLE(IShellFolder2
)* lpvtblShellFolder
;
282 ICOM_VTABLE(IPersistFolder2
)* lpvtblPersistFolder2
;
283 ICOM_VTABLE(IDropTarget
)* lpvtblDropTarget
;
284 ICOM_VTABLE(ISFHelper
)* lpvtblSFHelper
;
286 IUnknown
*pUnkOuter
; /* used for aggregation */
291 LPITEMIDLIST absPidl
; /* complete pidl */
293 UINT cfShellIDList
; /* clipboardformat for IDropTarget */
294 BOOL fAcceptFmt
; /* flag for pending Drop */
297 static struct ICOM_VTABLE(IUnknown
) unkvt
;
298 static struct ICOM_VTABLE(IShellFolder2
) sfvt
;
299 static struct ICOM_VTABLE(IPersistFolder2
) psfvt
;
300 static struct ICOM_VTABLE(IDropTarget
) dtvt
;
301 static struct ICOM_VTABLE(ISFHelper
) shvt
;
303 static IShellFolder
* ISF_MyComputer_Constructor(void);
305 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
306 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
308 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
309 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
311 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
312 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
314 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
315 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
317 converts This to a interface pointer
319 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
320 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
321 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
322 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
323 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
324 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
325 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
326 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
327 /**************************************************************************
328 * registers clipboardformat once
330 static void SF_RegisterClipFmt (IGenericSFImpl
* This
)
332 TRACE("(%p)\n", This
);
334 if (!This
->cfShellIDList
)
336 This
->cfShellIDList
= RegisterClipboardFormatA(CFSTR_SHELLIDLIST
);
340 /**************************************************************************
341 * we need a seperate IUnknown to handle aggregation
344 static HRESULT WINAPI
IUnknown_fnQueryInterface(
349 ICOM_THIS(IGenericSFImpl
, iface
);
352 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
356 if(IsEqualIID(riid
, &IID_IUnknown
)) *ppvObj
= _IUnknown_(This
);
357 else if(IsEqualIID(riid
, &IID_IShellFolder
)) *ppvObj
= _IShellFolder_(This
);
358 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) *ppvObj
= _IShellFolder_(This
);
359 else if(IsEqualIID(riid
, &IID_IPersist
)) *ppvObj
= _IPersist_(This
);
360 else if(IsEqualIID(riid
, &IID_IPersistFolder
)) *ppvObj
= _IPersistFolder_(This
);
361 else if(IsEqualIID(riid
, &IID_IPersistFolder2
)) *ppvObj
= _IPersistFolder2_(This
);
362 else if(IsEqualIID(riid
, &IID_ISFHelper
)) *ppvObj
= _ISFHelper_(This
);
363 else if(IsEqualIID(riid
, &IID_IDropTarget
))
365 *ppvObj
= _IDropTarget_(This
);
366 SF_RegisterClipFmt(This
);
371 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
372 TRACE("-- Interface = %p\n", *ppvObj
);
375 TRACE("-- Interface: E_NOINTERFACE\n");
376 return E_NOINTERFACE
;
379 static ULONG WINAPI
IUnknown_fnAddRef(IUnknown
* iface
)
381 ICOM_THIS(IGenericSFImpl
, iface
);
384 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
387 return ++(This
->ref
);
390 static ULONG WINAPI
IUnknown_fnRelease(IUnknown
* iface
)
392 ICOM_THIS(IGenericSFImpl
, iface
);
395 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
400 TRACE("-- destroying IShellFolder(%p)\n",This
);
402 if (pdesktopfolder
== _IShellFolder_(This
))
405 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This
);
407 if(This
->absPidl
) SHFree(This
->absPidl
);
408 if(This
->sMyPath
) SHFree(This
->sMyPath
);
409 HeapFree(GetProcessHeap(),0,This
);
415 static ICOM_VTABLE(IUnknown
) unkvt
=
417 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
418 IUnknown_fnQueryInterface
,
423 static shvheader GenericSFHeader
[] =
425 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
426 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
427 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
428 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
429 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
431 #define GENERICSHELLVIEWCOLUMNS 5
433 /**************************************************************************
434 * IShellFolder_Constructor
437 * creating undocumented ShellFS_Folder as part of an aggregation
438 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
441 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
443 HRESULT
IFSFolder_Constructor(
444 IUnknown
* pUnkOuter
,
451 TRACE("unkOut=%p riid=%s\n",pUnkOuter
, debugstr_guid(riid
));
453 if(pUnkOuter
&& ! IsEqualIID(riid
, &IID_IUnknown
))
455 hr
= CLASS_E_NOAGGREGATION
; /* forbidden by definition */
459 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
463 ICOM_VTBL(sf
)=&unkvt
;
464 sf
->lpvtblShellFolder
=&sfvt
;
465 sf
->lpvtblPersistFolder2
=&psfvt
;
466 sf
->lpvtblDropTarget
=&dtvt
;
467 sf
->lpvtblSFHelper
=&shvt
;
469 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
470 sf
->pUnkOuter
= pUnkOuter
? pUnkOuter
: _IUnknown_(sf
);
471 *ppv
= _IUnknown_(sf
);
482 /**************************************************************************
483 * IShellFolder_Constructor
486 * THIS points to the parent folder
489 IShellFolder
* IShellFolder_Constructor(
490 IShellFolder2
* iface
,
496 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
498 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
501 ICOM_VTBL(sf
)=&unkvt
;
502 sf
->lpvtblShellFolder
=&sfvt
;
503 sf
->lpvtblPersistFolder2
=&psfvt
;
504 sf
->lpvtblDropTarget
=&dtvt
;
505 sf
->lpvtblSFHelper
=&shvt
;
507 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
508 sf
->pUnkOuter
= _IUnknown_(sf
);
510 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf
,This
, pidl
);
513 if(pidl
&& iface
) /* do we have a pidl? */
517 sf
->absPidl
= ILCombine(This
->absPidl
, pidl
); /* build a absolute pidl */
519 if (!_ILIsSpecialFolder(pidl
)) /* only file system paths */
521 if(This
->sMyPath
) /* get the size of the parents path */
523 dwSize
+= strlen(This
->sMyPath
) ;
524 TRACE("-- (%p)->(parent's path=%s)\n",sf
, debugstr_a(This
->sMyPath
));
527 dwSize
+= _ILSimpleGetText(pidl
,NULL
,0); /* add the size of our name*/
528 sf
->sMyPath
= SHAlloc(dwSize
+ 2); /* '\0' and backslash */
530 if(!sf
->sMyPath
) return NULL
;
533 if(This
->sMyPath
) /* if the parent has a path, get it*/
535 strcpy(sf
->sMyPath
, This
->sMyPath
);
536 PathAddBackslashA (sf
->sMyPath
);
539 len
= strlen(sf
->sMyPath
);
540 _ILSimpleGetText(pidl
, sf
->sMyPath
+ len
, dwSize
+2 - len
);
543 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf
, sf
->absPidl
,debugstr_a(sf
->sMyPath
));
549 return _IShellFolder_(sf
);
552 /**************************************************************************
553 * IShellFolder_fnQueryInterface
556 * REFIID riid [in ] Requested InterfaceID
557 * LPVOID* ppvObject [out] Interface* to hold the result
559 static HRESULT WINAPI
IShellFolder_fnQueryInterface(
560 IShellFolder2
* iface
,
564 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
567 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
569 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
572 /**************************************************************************
573 * IShellFolder_AddRef
576 static ULONG WINAPI
IShellFolder_fnAddRef(IShellFolder2
* iface
)
578 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
581 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
583 return IUnknown_AddRef(This
->pUnkOuter
);
586 /**************************************************************************
587 * IShellFolder_fnRelease
589 static ULONG WINAPI
IShellFolder_fnRelease(IShellFolder2
* iface
)
591 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
594 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
596 return IUnknown_Release(This
->pUnkOuter
);
599 /**************************************************************************
600 * IShellFolder_fnParseDisplayName
602 * HWND hwndOwner, //[in ] Parent window for any message's
603 * LPBC pbc, //[in ] reserved
604 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
605 * ULONG* pchEaten, //[out] (unicode) characters processed
606 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
607 * ULONG* pdwAttributes //[out] items attributes
610 * every folder tries to parse only its own (the leftmost) pidl and creates a
611 * subfolder to evaluate the remaining parts
612 * now we can parse into namespaces implemented by shell extensions
614 * behaviour on win98: lpszDisplayName=NULL -> chrash
615 * lpszDisplayName="" -> returns mycoputer-pidl
618 * pdwAttributes: not set
619 * pchEaten: not set like in windows
621 static HRESULT WINAPI
IShellFolder_fnParseDisplayName(
622 IShellFolder2
* iface
,
625 LPOLESTR lpszDisplayName
,
628 DWORD
*pdwAttributes
)
630 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
632 HRESULT hr
= E_OUTOFMEMORY
;
634 WCHAR szElement
[MAX_PATH
];
635 CHAR szTempA
[MAX_PATH
], szPath
[MAX_PATH
];
636 LPITEMIDLIST pidlTemp
=NULL
;
638 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
639 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
640 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
642 if (!lpszDisplayName
|| !ppidl
) return E_INVALIDARG
;
644 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
646 if (*lpszDisplayName
)
648 /* get the next element */
649 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
651 /* build the full pathname to the element */
652 WideCharToMultiByte( CP_ACP
, 0, szElement
, -1, szTempA
, MAX_PATH
, NULL
, NULL
);
653 strcpy(szPath
, This
->sMyPath
);
654 PathAddBackslashA(szPath
);
655 strcat(szPath
, szTempA
);
658 pidlTemp
= SHSimpleIDListFromPathA(szPath
);
662 /* try to analyse the next element */
663 if (szNext
&& *szNext
)
665 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
669 if (pdwAttributes
&& *pdwAttributes
)
671 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
672 /* WIN32_FIND_DATAA fd;
673 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
674 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
675 *pdwAttributes &= ~SFGAO_FOLDER;
676 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
677 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
687 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This
, ppidl
? *ppidl
:0, hr
);
692 /**************************************************************************
693 * IShellFolder_fnEnumObjects
695 * HWND hwndOwner, //[in ] Parent Window
696 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
697 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
699 static HRESULT WINAPI
IShellFolder_fnEnumObjects(
700 IShellFolder2
* iface
,
703 LPENUMIDLIST
* ppEnumIDList
)
705 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
707 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
709 *ppEnumIDList
= NULL
;
710 *ppEnumIDList
= IEnumIDList_Constructor (This
->sMyPath
, dwFlags
, EIDL_FILE
);
712 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
714 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
719 /**************************************************************************
720 * IShellFolder_fnBindToObject
722 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
723 * LPBC pbc, //[in ] reserved
724 * REFIID riid, //[in ] Initial Interface
725 * LPVOID* ppvObject //[out] Interface*
727 static HRESULT WINAPI
IShellFolder_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
728 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
730 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
732 IShellFolder
*pShellFolder
, *pSubFolder
;
733 IPersistFolder
*pPersistFolder
;
734 LPITEMIDLIST absPidl
;
736 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
738 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
742 if ((iid
=_ILGetGUIDPointer(pidl
)))
744 /* we have to create a alien folder */
745 if ( SUCCEEDED(SHCoCreateInstance(NULL
, iid
, NULL
, riid
, (LPVOID
*)&pShellFolder
))
746 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
)))
748 absPidl
= ILCombine (This
->absPidl
, pidl
);
749 IPersistFolder_Initialize(pPersistFolder
, absPidl
);
750 IPersistFolder_Release(pPersistFolder
);
758 else if(_ILIsFolder(pidl
))
760 LPITEMIDLIST pidltemp
= ILCloneFirst(pidl
);
761 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
766 ERR("can't bind to a file\n");
770 if (_ILIsPidlSimple(pidl
))
772 *ppvOut
= pShellFolder
;
776 IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, &IID_IShellFolder
, (LPVOID
)&pSubFolder
);
777 IShellFolder_Release(pShellFolder
);
778 *ppvOut
= pSubFolder
;
781 TRACE("-- (%p) returning (%p)\n",This
, *ppvOut
);
786 /**************************************************************************
787 * IShellFolder_fnBindToStorage
789 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
790 * LPBC pbc, //[in ] reserved
791 * REFIID riid, //[in ] Initial storage interface
792 * LPVOID* ppvObject //[out] Interface* returned
794 static HRESULT WINAPI
IShellFolder_fnBindToStorage(
795 IShellFolder2
* iface
,
801 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
803 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
804 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
810 /**************************************************************************
811 * IShellFolder_fnCompareIDs
814 * LPARAM lParam, //[in ] Column?
815 * LPCITEMIDLIST pidl1, //[in ] simple pidl
816 * LPCITEMIDLIST pidl2) //[in ] simple pidl
819 * Special case - If one of the items is a Path and the other is a File,
820 * always make the Path come before the File.
823 * use SCODE_CODE() on the return value to get the result
826 static HRESULT WINAPI
IShellFolder_fnCompareIDs(
827 IShellFolder2
* iface
,
832 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
834 CHAR szTemp1
[MAX_PATH
];
835 CHAR szTemp2
[MAX_PATH
];
838 HRESULT hr
= E_OUTOFMEMORY
;
839 LPCITEMIDLIST pidlTemp
;
842 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This
,lParam
,pidl1
,pidl2
);
846 if (!pidl1
&& !pidl2
)
848 hr
= ResultFromShort(0);
852 hr
= ResultFromShort(-1);
856 hr
= ResultFromShort(1);
861 pd1
= _ILGetDataPointer(pidl1
);
862 pd2
= _ILGetDataPointer(pidl2
);
864 /* compate the types. sort order is the PT_* constant */
865 pt1
= ( pd1
? pd1
->type
: PT_DESKTOP
);
866 pt2
= ( pd2
? pd2
->type
: PT_DESKTOP
);
870 hr
= ResultFromShort(pt1
-pt2
);
872 else /* same type of pidl */
874 _ILSimpleGetText(pidl1
, szTemp1
, MAX_PATH
);
875 _ILSimpleGetText(pidl2
, szTemp2
, MAX_PATH
);
876 nReturn
= strcasecmp(szTemp1
, szTemp2
);
878 if (nReturn
== 0) /* first pidl different ? */
880 pidl1
= ILGetNext(pidl1
);
882 if (pidl1
&& pidl1
->mkid
.cb
) /* go deeper? */
884 pidlTemp
= ILCloneFirst(pidl1
);
885 pidl2
= ILGetNext(pidl2
);
887 hr
= IShellFolder_BindToObject(iface
, pidlTemp
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psf
);
890 nReturn
= IShellFolder_CompareIDs(psf
, 0, pidl1
, pidl2
);
891 IShellFolder_Release(psf
);
892 hr
= ResultFromShort(nReturn
);
898 hr
= ResultFromShort(nReturn
); /* two equal simple pidls */
903 hr
= ResultFromShort(nReturn
); /* two different simple pidls */
908 TRACE("-- res=0x%08lx\n", hr
);
912 /**************************************************************************
913 * IShellFolder_fnCreateViewObject
915 static HRESULT WINAPI
IShellFolder_fnCreateViewObject(
916 IShellFolder2
* iface
,
921 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
923 LPSHELLVIEW pShellView
;
924 HRESULT hr
= E_INVALIDARG
;
926 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
932 if(IsEqualIID(riid
, &IID_IDropTarget
))
934 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, ppvOut
);
936 else if(IsEqualIID(riid
, &IID_IContextMenu
))
938 FIXME("IContextMenu not implemented\n");
941 else if(IsEqualIID(riid
, &IID_IShellView
))
943 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
946 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
947 IShellView_Release(pShellView
);
951 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
955 /**************************************************************************
956 * IShellFolder_fnGetAttributesOf
959 * UINT cidl, //[in ] num elements in pidl array
960 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
961 * ULONG* rgfInOut) //[out] result array
964 static HRESULT WINAPI
IShellFolder_fnGetAttributesOf(
965 IShellFolder2
* iface
,
967 LPCITEMIDLIST
*apidl
,
970 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
974 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
976 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
979 while (cidl
> 0 && *apidl
)
982 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
987 TRACE("-- result=0x%08lx\n",*rgfInOut
);
991 /**************************************************************************
992 * IShellFolder_fnGetUIObjectOf
995 * HWND hwndOwner, //[in ] Parent window for any output
996 * UINT cidl, //[in ] array size
997 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
998 * REFIID riid, //[in ] Requested Interface
999 * UINT* prgfInOut, //[ ] reserved
1000 * LPVOID* ppvObject) //[out] Resulting Interface
1003 * This function gets asked to return "view objects" for one or more (multiple select)
1005 * The viewobject typically is an COM object with one of the following interfaces:
1006 * IExtractIcon,IDataObject,IContextMenu
1007 * In order to support icon positions in the default Listview your DataObject
1008 * must implement the SetData method (in addition to GetData :) - the shell passes
1009 * a barely documented "Icon positions" structure to SetData when the drag starts,
1010 * and GetData's it if the drop is in another explorer window that needs the positions.
1012 static HRESULT WINAPI
IShellFolder_fnGetUIObjectOf(
1013 IShellFolder2
* iface
,
1016 LPCITEMIDLIST
* apidl
,
1021 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1024 IUnknown
* pObj
= NULL
;
1025 HRESULT hr
= E_INVALIDARG
;
1027 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1028 This
,hwndOwner
,cidl
,apidl
,debugstr_guid(riid
),prgfInOut
,ppvOut
);
1034 if(IsEqualIID(riid
, &IID_IContextMenu
) && (cidl
>= 1))
1036 pObj
= (LPUNKNOWN
)ISvItemCm_Constructor((IShellFolder
*)iface
, This
->absPidl
, apidl
, cidl
);
1039 else if (IsEqualIID(riid
, &IID_IDataObject
) &&(cidl
>= 1))
1041 pObj
= (LPUNKNOWN
)IDataObject_Constructor (hwndOwner
, This
->absPidl
, apidl
, cidl
);
1044 else if (IsEqualIID(riid
, &IID_IExtractIconA
) && (cidl
== 1))
1046 pidl
= ILCombine(This
->absPidl
,apidl
[0]);
1047 pObj
= (LPUNKNOWN
)IExtractIconA_Constructor( pidl
);
1051 else if (IsEqualIID(riid
, &IID_IDropTarget
) && (cidl
>= 1))
1053 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, (LPVOID
*)&pObj
);
1065 TRACE("(%p)->hr=0x%08lx\n",This
, hr
);
1069 /**************************************************************************
1070 * IShellFolder_fnGetDisplayNameOf
1071 * Retrieves the display name for the specified file object or subfolder
1074 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1075 * DWORD dwFlags, //[in ] SHGNO formatting flags
1076 * LPSTRRET lpName) //[out] Returned display name
1079 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1081 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1082 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1084 static HRESULT WINAPI
IShellFolder_fnGetDisplayNameOf(
1085 IShellFolder2
* iface
,
1090 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1092 CHAR szPath
[MAX_PATH
]= "";
1096 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1099 if(!pidl
|| !strRet
) return E_INVALIDARG
;
1101 bSimplePidl
= _ILIsPidlSimple(pidl
);
1103 /* take names of special folders only if its only this folder */
1104 if (_ILIsSpecialFolder(pidl
))
1108 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
1113 if (!(dwFlags
& SHGDN_INFOLDER
) && (dwFlags
& SHGDN_FORPARSING
) && This
->sMyPath
)
1115 strcpy (szPath
, This
->sMyPath
); /* get path to root*/
1116 PathAddBackslashA(szPath
);
1117 len
= strlen(szPath
);
1119 _ILSimpleGetText(pidl
, szPath
+ len
, MAX_PATH
- len
); /* append my own path */
1122 if ( (dwFlags
& SHGDN_FORPARSING
) && !bSimplePidl
) /* go deeper if needed */
1124 PathAddBackslashA(szPath
);
1125 len
= strlen(szPath
);
1127 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
+ len
, MAX_PATH
- len
)))
1128 return E_OUTOFMEMORY
;
1130 strRet
->uType
= STRRET_CSTRA
;
1131 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1133 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1137 /**************************************************************************
1138 * IShellFolder_fnSetNameOf
1139 * Changes the name of a file object or subfolder, possibly changing its item
1140 * identifier in the process.
1143 * HWND hwndOwner, //[in ] Owner window for output
1144 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1145 * LPCOLESTR lpszName, //[in ] the items new display name
1146 * DWORD dwFlags, //[in ] SHGNO formatting flags
1147 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1149 static HRESULT WINAPI
IShellFolder_fnSetNameOf(
1150 IShellFolder2
* iface
,
1152 LPCITEMIDLIST pidl
, /*simple pidl*/
1155 LPITEMIDLIST
*pPidlOut
)
1157 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1158 char szSrc
[MAX_PATH
], szDest
[MAX_PATH
];
1160 BOOL bIsFolder
= _ILIsFolder(ILFindLastID(pidl
));
1162 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1163 This
,hwndOwner
,pidl
,debugstr_w(lpName
),dwFlags
,pPidlOut
);
1165 /* build source path */
1166 if (dwFlags
& SHGDN_INFOLDER
)
1168 strcpy(szSrc
, This
->sMyPath
);
1169 PathAddBackslashA(szSrc
);
1170 len
= strlen (szSrc
);
1171 _ILSimpleGetText(pidl
, szSrc
+len
, MAX_PATH
-len
);
1175 SHGetPathFromIDListA(pidl
, szSrc
);
1178 /* build destination path */
1179 strcpy(szDest
, This
->sMyPath
);
1180 PathAddBackslashA(szDest
);
1181 len
= strlen (szDest
);
1182 WideCharToMultiByte( CP_ACP
, 0, lpName
, -1, szDest
+len
, MAX_PATH
-len
, NULL
, NULL
);
1183 szDest
[MAX_PATH
-1] = 0;
1184 TRACE("src=%s dest=%s\n", szSrc
, szDest
);
1185 if ( MoveFileA(szSrc
, szDest
) )
1187 if (pPidlOut
) *pPidlOut
= SHSimpleIDListFromPathA(szDest
);
1188 SHChangeNotifyA( bIsFolder
?SHCNE_RENAMEFOLDER
:SHCNE_RENAMEITEM
, SHCNF_PATHA
, szSrc
, szDest
);
1194 static HRESULT WINAPI
IShellFolder_fnGetDefaultSearchGUID(
1195 IShellFolder2
* iface
,
1198 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1199 FIXME("(%p)\n",This
);
1202 static HRESULT WINAPI
IShellFolder_fnEnumSearches(
1203 IShellFolder2
* iface
,
1204 IEnumExtraSearch
**ppenum
)
1206 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1207 FIXME("(%p)\n",This
);
1210 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumn(
1211 IShellFolder2
* iface
,
1216 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1218 TRACE("(%p)\n",This
);
1220 if (pSort
) *pSort
= 0;
1221 if (pDisplay
) *pDisplay
= 0;
1225 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumnState(
1226 IShellFolder2
* iface
,
1230 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1232 TRACE("(%p)\n",This
);
1234 if (!pcsFlags
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1236 *pcsFlags
= GenericSFHeader
[iColumn
].pcsFlags
;
1240 static HRESULT WINAPI
IShellFolder_fnGetDetailsEx(
1241 IShellFolder2
* iface
,
1243 const SHCOLUMNID
*pscid
,
1246 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1247 FIXME("(%p)\n",This
);
1251 static HRESULT WINAPI
IShellFolder_fnGetDetailsOf(
1252 IShellFolder2
* iface
,
1257 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1258 HRESULT hr
= E_FAIL
;
1260 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
1262 if (!psd
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1266 /* the header titles */
1267 psd
->fmt
= GenericSFHeader
[iColumn
].fmt
;
1268 psd
->cxChar
= GenericSFHeader
[iColumn
].cxChar
;
1269 psd
->str
.uType
= STRRET_CSTRA
;
1270 LoadStringA(shell32_hInstance
, GenericSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
1275 /* the data from the pidl */
1279 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
1282 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1285 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1288 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1290 case 4: /* attributes */
1291 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1295 psd
->str
.uType
= STRRET_CSTRA
;
1300 static HRESULT WINAPI
IShellFolder_fnMapNameToSCID(
1301 IShellFolder2
* iface
,
1305 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1306 FIXME("(%p)\n",This
);
1310 static ICOM_VTABLE(IShellFolder2
) sfvt
=
1312 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1313 IShellFolder_fnQueryInterface
,
1314 IShellFolder_fnAddRef
,
1315 IShellFolder_fnRelease
,
1316 IShellFolder_fnParseDisplayName
,
1317 IShellFolder_fnEnumObjects
,
1318 IShellFolder_fnBindToObject
,
1319 IShellFolder_fnBindToStorage
,
1320 IShellFolder_fnCompareIDs
,
1321 IShellFolder_fnCreateViewObject
,
1322 IShellFolder_fnGetAttributesOf
,
1323 IShellFolder_fnGetUIObjectOf
,
1324 IShellFolder_fnGetDisplayNameOf
,
1325 IShellFolder_fnSetNameOf
,
1328 IShellFolder_fnGetDefaultSearchGUID
,
1329 IShellFolder_fnEnumSearches
,
1330 IShellFolder_fnGetDefaultColumn
,
1331 IShellFolder_fnGetDefaultColumnState
,
1332 IShellFolder_fnGetDetailsEx
,
1333 IShellFolder_fnGetDetailsOf
,
1334 IShellFolder_fnMapNameToSCID
1337 /****************************************************************************
1338 * ISFHelper for IShellFolder implementation
1341 static HRESULT WINAPI
ISFHelper_fnQueryInterface(
1346 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1348 TRACE("(%p)\n", This
);
1350 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
1353 static ULONG WINAPI
ISFHelper_fnAddRef(
1356 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1358 TRACE("(%p)\n", This
);
1360 return IUnknown_AddRef(This
->pUnkOuter
);
1363 static ULONG WINAPI
ISFHelper_fnRelease(
1366 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1368 TRACE("(%p)\n", This
);
1370 return IUnknown_Release(This
->pUnkOuter
);
1374 /****************************************************************************
1375 * ISFHelper_fnAddFolder
1377 * creates a unique folder name
1380 static HRESULT WINAPI
ISFHelper_fnGetUniqueName(
1385 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1386 IEnumIDList
* penum
;
1388 char szText
[MAX_PATH
];
1389 char * szNewFolder
= "New Folder";
1391 TRACE("(%p)(%s %u)\n", This
, lpName
, uLen
);
1393 if (uLen
< strlen(szNewFolder
) + 4) return E_POINTER
;
1395 strcpy(lpName
, szNewFolder
);
1397 hr
= IShellFolder_fnEnumObjects(_IShellFolder2_(This
), 0, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
| SHCONTF_INCLUDEHIDDEN
, &penum
);
1404 next
: IEnumIDList_Reset(penum
);
1405 while(S_OK
== IEnumIDList_Next(penum
, 1, &pidl
, &dwFetched
) && dwFetched
)
1407 _ILSimpleGetText(pidl
, szText
, MAX_PATH
);
1408 if (0 == strcasecmp(szText
, lpName
))
1410 sprintf(lpName
, "%s %d", szNewFolder
, i
++);
1420 IEnumIDList_Release(penum
);
1425 /****************************************************************************
1426 * ISFHelper_fnAddFolder
1428 * adds a new folder.
1431 static HRESULT WINAPI
ISFHelper_fnAddFolder(
1435 LPITEMIDLIST
* ppidlOut
)
1437 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1438 char lpstrNewDir
[MAX_PATH
];
1440 HRESULT hres
= E_FAIL
;
1442 TRACE("(%p)(%s %p)\n", This
, lpName
, ppidlOut
);
1444 strcpy(lpstrNewDir
, This
->sMyPath
);
1445 PathAddBackslashA(lpstrNewDir
);
1446 strcat(lpstrNewDir
, lpName
);
1448 bRes
= CreateDirectoryA(lpstrNewDir
, NULL
);
1452 LPITEMIDLIST pidl
, pidlitem
;
1454 pidlitem
= SHSimpleIDListFromPathA(lpstrNewDir
);
1456 pidl
= ILCombine(This
->absPidl
, pidlitem
);
1457 SHChangeNotifyA(SHCNE_MKDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1460 if (ppidlOut
) *ppidlOut
= pidlitem
;
1465 char lpstrText
[128+MAX_PATH
];
1466 char lpstrTempText
[128];
1467 char lpstrCaption
[256];
1469 /* Cannot Create folder because of permissions */
1470 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_DENIED
, lpstrTempText
, sizeof(lpstrTempText
));
1471 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_CAPTION
, lpstrCaption
, sizeof(lpstrCaption
));
1472 sprintf(lpstrText
,lpstrTempText
, lpstrNewDir
);
1473 MessageBoxA(hwnd
,lpstrText
, lpstrCaption
, MB_OK
| MB_ICONEXCLAMATION
);
1479 /****************************************************************************
1480 * ISFHelper_fnDeleteItems
1482 * deletes items in folder
1484 static HRESULT WINAPI
ISFHelper_fnDeleteItems(
1487 LPCITEMIDLIST
* apidl
)
1489 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1491 char szPath
[MAX_PATH
];
1493 TRACE("(%p)(%u %p)\n", This
, cidl
, apidl
);
1495 for(i
=0; i
< cidl
; i
++)
1497 strcpy(szPath
, This
->sMyPath
);
1498 PathAddBackslashA(szPath
);
1499 _ILSimpleGetText(apidl
[i
], szPath
+strlen(szPath
), MAX_PATH
);
1501 if (_ILIsFolder(apidl
[i
]))
1505 MESSAGE("delete %s\n", szPath
);
1506 if (! SHELL_DeleteDirectoryA(szPath
, TRUE
)) return E_FAIL
;
1507 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1508 SHChangeNotifyA(SHCNE_RMDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1511 else if (_ILIsValue(apidl
[i
]))
1515 MESSAGE("delete %s\n", szPath
);
1516 if (! DeleteFileA(szPath
)) return E_FAIL
;
1517 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1518 SHChangeNotifyA(SHCNE_DELETE
, SHCNF_IDLIST
, pidl
, NULL
);
1526 /****************************************************************************
1527 * ISFHelper_fnCopyItems
1529 * copys items to this folder
1531 static HRESULT WINAPI
ISFHelper_fnCopyItems(
1533 IShellFolder
* pSFFrom
,
1535 LPCITEMIDLIST
*apidl
)
1538 IPersistFolder2
* ppf2
=NULL
;
1539 char szSrcPath
[MAX_PATH
], szDstPath
[MAX_PATH
];
1540 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1542 TRACE("(%p)->(%p,%u,%p)\n", This
, pSFFrom
, cidl
, apidl
);
1544 IShellFolder_QueryInterface(pSFFrom
, &IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
1548 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2
, &pidl
)))
1550 for (i
=0; i
<cidl
; i
++)
1552 SHGetPathFromIDListA(pidl
, szSrcPath
);
1553 PathAddBackslashA(szSrcPath
);
1554 _ILSimpleGetText(apidl
[i
], szSrcPath
+strlen(szSrcPath
), MAX_PATH
);
1556 strcpy(szDstPath
, This
->sMyPath
);
1557 PathAddBackslashA(szDstPath
);
1558 _ILSimpleGetText(apidl
[i
], szDstPath
+strlen(szDstPath
), MAX_PATH
);
1559 MESSAGE("would copy %s to %s\n", szSrcPath
, szDstPath
);
1563 IPersistFolder2_Release(ppf2
);
1568 static ICOM_VTABLE(ISFHelper
) shvt
=
1570 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1571 ISFHelper_fnQueryInterface
,
1573 ISFHelper_fnRelease
,
1574 ISFHelper_fnGetUniqueName
,
1575 ISFHelper_fnAddFolder
,
1576 ISFHelper_fnDeleteItems
,
1577 ISFHelper_fnCopyItems
,
1580 /***********************************************************************
1581 * [Desktopfolder] IShellFolder implementation
1583 static struct ICOM_VTABLE(IShellFolder2
) sfdvt
;
1585 static shvheader DesktopSFHeader
[] =
1587 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
1588 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1589 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1590 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
1591 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
1593 #define DESKTOPSHELLVIEWCOLUMNS 5
1595 /**************************************************************************
1596 * ISF_Desktop_Constructor
1599 IShellFolder
* ISF_Desktop_Constructor()
1601 IGenericSFImpl
* sf
;
1603 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
1605 ICOM_VTBL(sf
)=&unkvt
;
1606 sf
->lpvtblShellFolder
=&sfdvt
;
1607 sf
->absPidl
=_ILCreateDesktop(); /* my qualified pidl */
1608 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
1613 return _IShellFolder_(sf
);
1616 /**************************************************************************
1617 * ISF_Desktop_fnQueryInterface
1619 * NOTES supports not IPersist/IPersistFolder
1621 static HRESULT WINAPI
ISF_Desktop_fnQueryInterface(
1622 IShellFolder2
* iface
,
1626 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1628 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
1632 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
1634 *ppvObj
= _IUnknown_(This
);
1636 else if(IsEqualIID(riid
, &IID_IShellFolder
)) /*IShellFolder*/
1638 *ppvObj
= _IShellFolder_(This
);
1640 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) /*IShellFolder2*/
1642 *ppvObj
= _IShellFolder_(This
);
1647 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
1648 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
1651 TRACE("-- Interface: E_NOINTERFACE\n");
1652 return E_NOINTERFACE
;
1655 /**************************************************************************
1656 * ISF_Desktop_fnParseDisplayName
1659 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1662 static HRESULT WINAPI
ISF_Desktop_fnParseDisplayName(
1663 IShellFolder2
* iface
,
1666 LPOLESTR lpszDisplayName
,
1668 LPITEMIDLIST
*ppidl
,
1669 DWORD
*pdwAttributes
)
1671 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1673 LPCWSTR szNext
=NULL
;
1674 LPITEMIDLIST pidlTemp
=NULL
;
1675 HRESULT hr
=E_OUTOFMEMORY
;
1677 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1678 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
1679 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
1682 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
1684 /* fixme no real parsing implemented */
1685 pidlTemp
= _ILCreateMyComputer();
1686 szNext
= lpszDisplayName
;
1688 if (szNext
&& *szNext
)
1690 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
1696 if (pdwAttributes
&& *pdwAttributes
)
1698 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
1704 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
1709 /**************************************************************************
1710 * ISF_Desktop_fnEnumObjects
1712 static HRESULT WINAPI
ISF_Desktop_fnEnumObjects(
1713 IShellFolder2
* iface
,
1716 LPENUMIDLIST
* ppEnumIDList
)
1718 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1720 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
1722 *ppEnumIDList
= NULL
;
1723 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_DESK
);
1725 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
1727 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
1732 /**************************************************************************
1733 * ISF_Desktop_fnBindToObject
1735 static HRESULT WINAPI
ISF_Desktop_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
1736 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
1738 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1740 IShellFolder
*pShellFolder
, *pSubFolder
;
1742 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1743 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
1747 if ((clsid
=_ILGetGUIDPointer(pidl
)))
1749 if ( IsEqualIID(clsid
, &CLSID_MyComputer
))
1751 pShellFolder
= ISF_MyComputer_Constructor();
1755 /* shell extension */
1756 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
1758 return E_INVALIDARG
;
1764 /* file system folder on the desktop */
1765 LPITEMIDLIST deskpidl
, firstpidl
, completepidl
;
1766 IPersistFolder
* ppf
;
1769 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY
, &deskpidl
);
1770 firstpidl
= ILCloneFirst(pidl
);
1771 completepidl
= ILCombine(deskpidl
, firstpidl
);
1773 pShellFolder
= IShellFolder_Constructor(NULL
, NULL
);
1774 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&ppf
)))
1776 IPersistFolder_Initialize(ppf
, completepidl
);
1777 IPersistFolder_Release(ppf
);
1779 ILFree(completepidl
);
1784 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
1786 *ppvOut
= pShellFolder
;
1788 else /* go deeper */
1790 IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, riid
, (LPVOID
)&pSubFolder
);
1791 IShellFolder_Release(pShellFolder
);
1792 *ppvOut
= pSubFolder
;
1795 TRACE("-- (%p) returning (%p)\n",This
, *ppvOut
);
1800 /**************************************************************************
1801 * ISF_Desktop_fnCreateViewObject
1803 static HRESULT WINAPI
ISF_Desktop_fnCreateViewObject( IShellFolder2
* iface
,
1804 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
1806 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1808 LPSHELLVIEW pShellView
;
1809 HRESULT hr
= E_INVALIDARG
;
1811 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
1817 if(IsEqualIID(riid
, &IID_IDropTarget
))
1819 WARN("IDropTarget not implemented\n");
1822 else if(IsEqualIID(riid
, &IID_IContextMenu
))
1824 WARN("IContextMenu not implemented\n");
1827 else if(IsEqualIID(riid
, &IID_IShellView
))
1829 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
1832 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
1833 IShellView_Release(pShellView
);
1837 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
1841 /**************************************************************************
1842 * ISF_Desktop_fnGetAttributesOf
1844 static HRESULT WINAPI
ISF_Desktop_fnGetAttributesOf(
1845 IShellFolder2
* iface
,
1847 LPCITEMIDLIST
*apidl
,
1850 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1854 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
, *rgfInOut
);
1856 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
1857 return E_INVALIDARG
;
1859 while (cidl
> 0 && *apidl
)
1862 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
1867 TRACE("-- result=0x%08lx\n",*rgfInOut
);
1872 /**************************************************************************
1873 * ISF_Desktop_fnGetDisplayNameOf
1876 * special case: pidl = null gives desktop-name back
1878 static HRESULT WINAPI
ISF_Desktop_fnGetDisplayNameOf(
1879 IShellFolder2
* iface
,
1884 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1886 CHAR szPath
[MAX_PATH
]= "";
1888 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1891 if(!strRet
) return E_INVALIDARG
;
1895 HCR_GetClassName(&CLSID_ShellDesktop
, szPath
, MAX_PATH
);
1897 else if ( _ILIsPidlSimple(pidl
) )
1899 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
1903 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
, MAX_PATH
)))
1904 return E_OUTOFMEMORY
;
1906 strRet
->uType
= STRRET_CSTRA
;
1907 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1910 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1914 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultSearchGUID(
1915 IShellFolder2
* iface
,
1918 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1919 FIXME("(%p)\n",This
);
1922 static HRESULT WINAPI
ISF_Desktop_fnEnumSearches(
1923 IShellFolder2
* iface
,
1924 IEnumExtraSearch
**ppenum
)
1926 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1927 FIXME("(%p)\n",This
);
1930 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumn(
1931 IShellFolder2
* iface
,
1936 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1938 TRACE("(%p)\n",This
);
1940 if (pSort
) *pSort
= 0;
1941 if (pDisplay
) *pDisplay
= 0;
1945 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumnState(
1946 IShellFolder2
* iface
,
1950 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1952 TRACE("(%p)\n",This
);
1954 if (!pcsFlags
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1956 *pcsFlags
= DesktopSFHeader
[iColumn
].pcsFlags
;
1960 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsEx(
1961 IShellFolder2
* iface
,
1963 const SHCOLUMNID
*pscid
,
1966 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1967 FIXME("(%p)\n",This
);
1971 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsOf(
1972 IShellFolder2
* iface
,
1977 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1978 HRESULT hr
= E_FAIL
;;
1980 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
1982 if (!psd
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1986 psd
->fmt
= DesktopSFHeader
[iColumn
].fmt
;
1987 psd
->cxChar
= DesktopSFHeader
[iColumn
].cxChar
;
1988 psd
->str
.uType
= STRRET_CSTRA
;
1989 LoadStringA(shell32_hInstance
, DesktopSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
1994 /* the data from the pidl */
1998 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
2001 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2004 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2007 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2009 case 4: /* attributes */
2010 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2014 psd
->str
.uType
= STRRET_CSTRA
;
2019 static HRESULT WINAPI
ISF_Desktop_fnMapNameToSCID(
2020 IShellFolder2
* iface
,
2024 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2025 FIXME("(%p)\n",This
);
2029 static ICOM_VTABLE(IShellFolder2
) sfdvt
=
2031 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2032 ISF_Desktop_fnQueryInterface
,
2033 IShellFolder_fnAddRef
,
2034 IShellFolder_fnRelease
,
2035 ISF_Desktop_fnParseDisplayName
,
2036 ISF_Desktop_fnEnumObjects
,
2037 ISF_Desktop_fnBindToObject
,
2038 IShellFolder_fnBindToStorage
,
2039 IShellFolder_fnCompareIDs
,
2040 ISF_Desktop_fnCreateViewObject
,
2041 ISF_Desktop_fnGetAttributesOf
,
2042 IShellFolder_fnGetUIObjectOf
,
2043 ISF_Desktop_fnGetDisplayNameOf
,
2044 IShellFolder_fnSetNameOf
,
2047 ISF_Desktop_fnGetDefaultSearchGUID
,
2048 ISF_Desktop_fnEnumSearches
,
2049 ISF_Desktop_fnGetDefaultColumn
,
2050 ISF_Desktop_fnGetDefaultColumnState
,
2051 ISF_Desktop_fnGetDetailsEx
,
2052 ISF_Desktop_fnGetDetailsOf
,
2053 ISF_Desktop_fnMapNameToSCID
2057 /***********************************************************************
2058 * IShellFolder [MyComputer] implementation
2061 static struct ICOM_VTABLE(IShellFolder2
) sfmcvt
;
2063 static shvheader MyComputerSFHeader
[] =
2065 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
2066 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2067 { IDS_SHV_COLUMN6
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2068 { IDS_SHV_COLUMN7
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2070 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2072 /**************************************************************************
2073 * ISF_MyComputer_Constructor
2075 static IShellFolder
* ISF_MyComputer_Constructor(void)
2077 IGenericSFImpl
* sf
;
2079 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
2082 ICOM_VTBL(sf
)=&unkvt
;
2083 sf
->lpvtblShellFolder
=&sfmcvt
;
2084 sf
->lpvtblPersistFolder2
= &psfvt
;
2085 sf
->pclsid
= (CLSID
*)&CLSID_SFMyComp
;
2086 sf
->absPidl
=_ILCreateMyComputer(); /* my qualified pidl */
2087 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
2092 return _IShellFolder_(sf
);
2095 /**************************************************************************
2096 * ISF_MyComputer_fnParseDisplayName
2098 static HRESULT WINAPI
ISF_MyComputer_fnParseDisplayName(
2099 IShellFolder2
* iface
,
2102 LPOLESTR lpszDisplayName
,
2104 LPITEMIDLIST
*ppidl
,
2105 DWORD
*pdwAttributes
)
2107 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2109 HRESULT hr
= E_OUTOFMEMORY
;
2110 LPCWSTR szNext
=NULL
;
2111 WCHAR szElement
[MAX_PATH
];
2112 CHAR szTempA
[MAX_PATH
];
2113 LPITEMIDLIST pidlTemp
;
2115 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2116 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
2117 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
2120 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
2122 /* do we have an absolute path name ? */
2123 if (PathGetDriveNumberW(lpszDisplayName
) >= 0 &&
2124 lpszDisplayName
[2] == (WCHAR
)'\\')
2126 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
2127 WideCharToMultiByte( CP_ACP
, 0, szElement
, -1, szTempA
, MAX_PATH
, NULL
, NULL
);
2128 pidlTemp
= _ILCreateDrive(szTempA
);
2130 if (szNext
&& *szNext
)
2132 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
2136 if (pdwAttributes
&& *pdwAttributes
)
2138 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
2145 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
2150 /**************************************************************************
2151 * ISF_MyComputer_fnEnumObjects
2153 static HRESULT WINAPI
ISF_MyComputer_fnEnumObjects(
2154 IShellFolder2
* iface
,
2157 LPENUMIDLIST
* ppEnumIDList
)
2159 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2161 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
2163 *ppEnumIDList
= NULL
;
2164 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_MYCOMP
);
2166 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
2168 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
2173 /**************************************************************************
2174 * ISF_MyComputer_fnBindToObject
2176 static HRESULT WINAPI
ISF_MyComputer_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
2177 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
2179 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2181 IShellFolder
*pShellFolder
, *pSubFolder
;
2182 LPITEMIDLIST pidltemp
;
2184 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2185 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
2187 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
2191 if ((clsid
=_ILGetGUIDPointer(pidl
)) && !IsEqualIID(clsid
, &CLSID_MyComputer
))
2193 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
2200 if (!_ILIsDrive(pidl
)) return E_INVALIDARG
;
2202 pidltemp
= ILCloneFirst(pidl
);
2203 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
2207 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
2209 *ppvOut
= pShellFolder
;
2211 else /* go deeper */
2213 IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, &IID_IShellFolder
, (LPVOID
)&pSubFolder
);
2214 IShellFolder_Release(pShellFolder
);
2215 *ppvOut
= pSubFolder
;
2218 TRACE("-- (%p) returning (%p)\n",This
, *ppvOut
);
2223 /**************************************************************************
2224 * ISF_MyComputer_fnCreateViewObject
2226 static HRESULT WINAPI
ISF_MyComputer_fnCreateViewObject( IShellFolder2
* iface
,
2227 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
2229 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2231 LPSHELLVIEW pShellView
;
2232 HRESULT hr
= E_INVALIDARG
;
2234 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
2240 if(IsEqualIID(riid
, &IID_IDropTarget
))
2242 WARN("IDropTarget not implemented\n");
2245 else if(IsEqualIID(riid
, &IID_IContextMenu
))
2247 WARN("IContextMenu not implemented\n");
2250 else if(IsEqualIID(riid
, &IID_IShellView
))
2252 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
2255 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
2256 IShellView_Release(pShellView
);
2260 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
2264 /**************************************************************************
2265 * ISF_MyComputer_fnGetAttributesOf
2267 static HRESULT WINAPI
ISF_MyComputer_fnGetAttributesOf(
2268 IShellFolder2
* iface
,
2270 LPCITEMIDLIST
*apidl
,
2273 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2277 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
2279 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
2280 return E_INVALIDARG
;
2282 while (cidl
> 0 && *apidl
)
2285 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
2290 TRACE("-- result=0x%08lx\n",*rgfInOut
);
2294 /**************************************************************************
2295 * ISF_MyComputer_fnGetDisplayNameOf
2298 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2299 * SHGDN_INFOLDER makes no sense.
2301 static HRESULT WINAPI
ISF_MyComputer_fnGetDisplayNameOf(
2302 IShellFolder2
* iface
,
2307 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2309 char szPath
[MAX_PATH
], szDrive
[18];
2313 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
2316 if(!strRet
) return E_INVALIDARG
;
2318 szPath
[0]=0x00; szDrive
[0]=0x00;
2321 bSimplePidl
= _ILIsPidlSimple(pidl
);
2323 if (_ILIsSpecialFolder(pidl
))
2325 /* take names of special folders only if its only this folder */
2328 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2333 if (!_ILIsDrive(pidl
))
2335 ERR("Wrong pidl type\n");
2336 return E_INVALIDARG
;
2339 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2341 /* long view "lw_name (C:)" */
2342 if ( bSimplePidl
&& !(dwFlags
& SHGDN_FORPARSING
))
2344 DWORD dwVolumeSerialNumber
,dwMaximumComponetLength
,dwFileSystemFlags
;
2346 GetVolumeInformationA(szPath
,szDrive
,12,&dwVolumeSerialNumber
,&dwMaximumComponetLength
,&dwFileSystemFlags
,NULL
,0);
2347 strcat (szDrive
," (");
2348 strncat (szDrive
, szPath
, 2);
2349 strcat (szDrive
,")");
2350 strcpy (szPath
, szDrive
);
2354 if (!bSimplePidl
) /* go deeper if needed */
2356 PathAddBackslashA(szPath
);
2357 len
= strlen(szPath
);
2359 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
| SHGDN_FORPARSING
, szPath
+ len
, MAX_PATH
- len
)))
2360 return E_OUTOFMEMORY
;
2362 strRet
->uType
= STRRET_CSTRA
;
2363 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
2366 TRACE("-- (%p)->(%s)\n", This
, szPath
);
2370 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultSearchGUID(
2371 IShellFolder2
* iface
,
2374 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2375 FIXME("(%p)\n",This
);
2378 static HRESULT WINAPI
ISF_MyComputer_fnEnumSearches(
2379 IShellFolder2
* iface
,
2380 IEnumExtraSearch
**ppenum
)
2382 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2383 FIXME("(%p)\n",This
);
2386 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumn(
2387 IShellFolder2
* iface
,
2392 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2394 TRACE("(%p)\n",This
);
2396 if (pSort
) *pSort
= 0;
2397 if (pDisplay
) *pDisplay
= 0;
2401 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumnState(
2402 IShellFolder2
* iface
,
2406 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2408 TRACE("(%p)\n",This
);
2410 if (!pcsFlags
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2412 *pcsFlags
= MyComputerSFHeader
[iColumn
].pcsFlags
;
2416 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsEx(
2417 IShellFolder2
* iface
,
2419 const SHCOLUMNID
*pscid
,
2422 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2423 FIXME("(%p)\n",This
);
2428 /* fixme: drive size >4GB is rolling over */
2429 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsOf(
2430 IShellFolder2
* iface
,
2435 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2438 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
2440 if (!psd
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2444 psd
->fmt
= MyComputerSFHeader
[iColumn
].fmt
;
2445 psd
->cxChar
= MyComputerSFHeader
[iColumn
].cxChar
;
2446 psd
->str
.uType
= STRRET_CSTRA
;
2447 LoadStringA(shell32_hInstance
, MyComputerSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
2452 char szPath
[MAX_PATH
];
2453 ULARGE_INTEGER ulBytes
;
2455 psd
->str
.u
.cStr
[0] = 0x00;
2456 psd
->str
.uType
= STRRET_CSTRA
;
2460 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
2463 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2465 case 2: /* total size */
2466 if (_ILIsDrive(pidl
))
2468 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2469 GetDiskFreeSpaceExA(szPath
, NULL
, &ulBytes
, NULL
);
2470 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2473 case 3: /* free size */
2474 if (_ILIsDrive(pidl
))
2476 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2477 GetDiskFreeSpaceExA(szPath
, &ulBytes
, NULL
, NULL
);
2478 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2487 static HRESULT WINAPI
ISF_MyComputer_fnMapNameToSCID(
2488 IShellFolder2
* iface
,
2492 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2493 FIXME("(%p)\n",This
);
2497 static ICOM_VTABLE(IShellFolder2
) sfmcvt
=
2499 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2500 IShellFolder_fnQueryInterface
,
2501 IShellFolder_fnAddRef
,
2502 IShellFolder_fnRelease
,
2503 ISF_MyComputer_fnParseDisplayName
,
2504 ISF_MyComputer_fnEnumObjects
,
2505 ISF_MyComputer_fnBindToObject
,
2506 IShellFolder_fnBindToStorage
,
2507 IShellFolder_fnCompareIDs
,
2508 ISF_MyComputer_fnCreateViewObject
,
2509 ISF_MyComputer_fnGetAttributesOf
,
2510 IShellFolder_fnGetUIObjectOf
,
2511 ISF_MyComputer_fnGetDisplayNameOf
,
2512 IShellFolder_fnSetNameOf
,
2515 ISF_MyComputer_fnGetDefaultSearchGUID
,
2516 ISF_MyComputer_fnEnumSearches
,
2517 ISF_MyComputer_fnGetDefaultColumn
,
2518 ISF_MyComputer_fnGetDefaultColumnState
,
2519 ISF_MyComputer_fnGetDetailsEx
,
2520 ISF_MyComputer_fnGetDetailsOf
,
2521 ISF_MyComputer_fnMapNameToSCID
2525 /************************************************************************
2526 * ISFPersistFolder_QueryInterface (IUnknown)
2529 static HRESULT WINAPI
ISFPersistFolder2_QueryInterface(
2530 IPersistFolder2
* iface
,
2534 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2536 TRACE("(%p)\n", This
);
2538 return IUnknown_QueryInterface(This
->pUnkOuter
, iid
, ppvObj
);
2541 /************************************************************************
2542 * ISFPersistFolder_AddRef (IUnknown)
2545 static ULONG WINAPI
ISFPersistFolder2_AddRef(
2546 IPersistFolder2
* iface
)
2548 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2550 TRACE("(%p)\n", This
);
2552 return IUnknown_AddRef(This
->pUnkOuter
);
2555 /************************************************************************
2556 * ISFPersistFolder_Release (IUnknown)
2559 static ULONG WINAPI
ISFPersistFolder2_Release(
2560 IPersistFolder2
* iface
)
2562 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2564 TRACE("(%p)\n", This
);
2566 return IUnknown_Release(This
->pUnkOuter
);
2569 /************************************************************************
2570 * ISFPersistFolder_GetClassID (IPersist)
2572 static HRESULT WINAPI
ISFPersistFolder2_GetClassID(
2573 IPersistFolder2
* iface
,
2576 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2578 TRACE("(%p)\n", This
);
2580 if (!lpClassId
) return E_POINTER
;
2581 *lpClassId
= *This
->pclsid
;
2586 /************************************************************************
2587 * ISFPersistFolder_Initialize (IPersistFolder)
2590 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2592 static HRESULT WINAPI
ISFPersistFolder2_Initialize(
2593 IPersistFolder2
* iface
,
2596 char sTemp
[MAX_PATH
];
2597 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2599 TRACE("(%p)->(%p)\n", This
, pidl
);
2601 /* free the old stuff */
2604 SHFree(This
->absPidl
);
2605 This
->absPidl
= NULL
;
2609 SHFree(This
->sMyPath
);
2610 This
->sMyPath
= NULL
;
2614 This
->absPidl
= ILClone(pidl
);
2617 if (SHGetPathFromIDListA(pidl
, sTemp
))
2619 This
->sMyPath
= SHAlloc(strlen(sTemp
)+1);
2620 strcpy(This
->sMyPath
, sTemp
);
2623 TRACE("--(%p)->(%s)\n", This
, This
->sMyPath
);
2628 /**************************************************************************
2629 * IPersistFolder2_fnGetCurFolder
2631 static HRESULT WINAPI
ISFPersistFolder2_fnGetCurFolder(
2632 IPersistFolder2
* iface
,
2633 LPITEMIDLIST
* pidl
)
2635 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2637 TRACE("(%p)->(%p)\n",This
, pidl
);
2639 if (!pidl
) return E_POINTER
;
2641 *pidl
= ILClone(This
->absPidl
);
2646 static ICOM_VTABLE(IPersistFolder2
) psfvt
=
2648 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2649 ISFPersistFolder2_QueryInterface
,
2650 ISFPersistFolder2_AddRef
,
2651 ISFPersistFolder2_Release
,
2652 ISFPersistFolder2_GetClassID
,
2653 ISFPersistFolder2_Initialize
,
2654 ISFPersistFolder2_fnGetCurFolder
2657 /****************************************************************************
2658 * ISFDropTarget implementation
2660 static BOOL
ISFDropTarget_QueryDrop(
2665 DWORD dwEffect
= *pdwEffect
;
2667 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2669 *pdwEffect
= DROPEFFECT_NONE
;
2671 if (This
->fAcceptFmt
)
2672 { /* Does our interpretation of the keystate ... */
2673 *pdwEffect
= KeyStateToDropEffect(dwKeyState
);
2675 /* ... matches the desired effect ? */
2676 if (dwEffect
& *pdwEffect
)
2684 static HRESULT WINAPI
ISFDropTarget_QueryInterface(
2689 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2691 TRACE("(%p)\n", This
);
2693 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
2696 static ULONG WINAPI
ISFDropTarget_AddRef( IDropTarget
*iface
)
2698 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2700 TRACE("(%p)\n", This
);
2702 return IUnknown_AddRef(This
->pUnkOuter
);
2705 static ULONG WINAPI
ISFDropTarget_Release( IDropTarget
*iface
)
2707 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2709 TRACE("(%p)\n", This
);
2711 return IUnknown_Release(This
->pUnkOuter
);
2714 static HRESULT WINAPI
ISFDropTarget_DragEnter(
2716 IDataObject
*pDataObject
,
2723 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2725 TRACE("(%p)->(DataObject=%p)\n",This
,pDataObject
);
2727 InitFormatEtc(fmt
, This
->cfShellIDList
, TYMED_HGLOBAL
);
2729 This
->fAcceptFmt
= (S_OK
== IDataObject_QueryGetData(pDataObject
, &fmt
)) ? TRUE
: FALSE
;
2731 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2736 static HRESULT WINAPI
ISFDropTarget_DragOver(
2742 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2744 TRACE("(%p)\n",This
);
2746 if(!pdwEffect
) return E_INVALIDARG
;
2748 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2753 static HRESULT WINAPI
ISFDropTarget_DragLeave(
2756 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2758 TRACE("(%p)\n",This
);
2760 This
->fAcceptFmt
= FALSE
;
2765 static HRESULT WINAPI
ISFDropTarget_Drop(
2767 IDataObject
* pDataObject
,
2772 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2774 FIXME("(%p) object dropped\n",This
);
2779 static struct ICOM_VTABLE(IDropTarget
) dtvt
=
2781 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2782 ISFDropTarget_QueryInterface
,
2783 ISFDropTarget_AddRef
,
2784 ISFDropTarget_Release
,
2785 ISFDropTarget_DragEnter
,
2786 ISFDropTarget_DragOver
,
2787 ISFDropTarget_DragLeave
,