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"
32 #include "shellfolder.h"
35 DEFAULT_DEBUG_CHANNEL(shell
)
38 /***************************************************************************
39 * debughelper: print out the return adress
40 * helps especially to track down unbalanced AddRef/Release
45 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
59 /***************************************************************************
60 * GetNextElement (internal function)
62 * gets a part of a string till the first backslash
65 * pszNext [IN] string to get the element from
66 * pszOut [IN] pointer to buffer whitch receives string
67 * dwOut [IN] length of pszOut
70 * LPSTR pointer to first, not yet parsed char
73 static LPCWSTR
GetNextElementW(LPCWSTR pszNext
,LPWSTR pszOut
,DWORD dwOut
)
74 { LPCWSTR pszTail
= pszNext
;
76 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext
),pszOut
,dwOut
);
80 if(!pszNext
|| !*pszNext
)
83 while(*pszTail
&& (*pszTail
!= (WCHAR
)'\\'))
86 dwCopy
= (WCHAR
*)pszTail
- (WCHAR
*)pszNext
+ 1;
87 lstrcpynW(pszOut
, pszNext
, (dwOut
<dwCopy
)? dwOut
: dwCopy
);
94 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext
),debugstr_w(pszOut
),dwOut
,pszTail
);
98 static HRESULT
SHELL32_ParseNextElement(
101 LPITEMIDLIST
* pidlInOut
,
104 DWORD
*pdwAttributes
)
106 HRESULT hr
= E_OUTOFMEMORY
;
107 LPITEMIDLIST pidlOut
, pidlTemp
= NULL
;
108 IShellFolder
*psfChild
;
110 TRACE("(%p, %p, %s)\n",psf
, pidlInOut
? *pidlInOut
: NULL
, debugstr_w(szNext
));
113 /* get the shellfolder for the child pidl and let it analyse further */
114 hr
= IShellFolder_BindToObject(psf
, *pidlInOut
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
118 hr
= IShellFolder_ParseDisplayName(psfChild
, hwndOwner
, NULL
, szNext
, pEaten
, &pidlOut
, pdwAttributes
);
119 IShellFolder_Release(psfChild
);
121 pidlTemp
= ILCombine(*pidlInOut
, pidlOut
);
128 *pidlInOut
= pidlTemp
;
130 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut
? *pidlInOut
: NULL
, hr
);
134 /***********************************************************************
135 * SHELL32_CoCreateInitSF
137 * creates a initialized shell folder
139 static HRESULT
SHELL32_CoCreateInitSF (
140 LPITEMIDLIST pidlRoot
,
141 LPITEMIDLIST pidlChild
,
147 LPITEMIDLIST absPidl
;
148 IShellFolder2
*pShellFolder
;
149 IPersistFolder
*pPersistFolder
;
151 TRACE("%p %p\n", pidlRoot
, pidlChild
);
155 /* we have to ask first for IPersistFolder, some special folders are expecting this */
156 hr
= SHCoCreateInstance(NULL
, clsid
, NULL
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
);
159 hr
= IPersistFolder_QueryInterface(pPersistFolder
, iid
, (LPVOID
*)&pShellFolder
);
162 absPidl
= ILCombine (pidlRoot
, pidlChild
);
163 hr
= IPersistFolder_Initialize(pPersistFolder
, absPidl
);
164 IPersistFolder_Release(pPersistFolder
);
166 *ppvOut
= pShellFolder
;
170 TRACE("-- ret=0x%08lx\n", hr
);
174 static HRESULT
SHELL32_GetDisplayNameOfChild(
181 LPITEMIDLIST pidlFirst
, pidlNext
;
182 IShellFolder2
* psfChild
;
183 HRESULT hr
= E_OUTOFMEMORY
;
186 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf
,pidl
,dwFlags
,szOut
, dwOutLen
);
189 if ((pidlFirst
= ILCloneFirst(pidl
)))
191 hr
= IShellFolder_BindToObject(psf
, pidlFirst
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
194 pidlNext
= ILGetNext(pidl
);
196 hr
= IShellFolder_GetDisplayNameOf(psfChild
, pidlNext
, dwFlags
| SHGDN_INFOLDER
, &strTemp
);
199 hr
= StrRetToStrNA(szOut
, dwOutLen
, &strTemp
, pidlNext
);
202 IShellFolder_Release(psfChild
);
207 TRACE("-- ret=0x%08lx %s\n", hr
, szOut
);
212 /***********************************************************************
213 * SHELL32_GetItemAttributes
217 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
218 * file: 0x40000177 FILESYSTEM
219 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
220 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
221 * (seems to be default for shell extensions if no registry entry exists)
223 * This functions does not set flags!! It only resets flags when nessesary.
225 static HRESULT
SHELL32_GetItemAttributes(
228 LPDWORD pdwAttributes
)
233 TRACE("0x%08lx\n", *pdwAttributes
);
235 if (*pdwAttributes
& (0xcff3fe88))
236 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes
);
237 *pdwAttributes
&= ~SFGAO_LINK
; /* FIXME: for native filedialogs */
239 if (_ILIsDrive(pidl
))
241 *pdwAttributes
&= 0xf0000144;
243 else if ((clsid
=_ILGetGUIDPointer(pidl
)))
245 if (HCR_GetFolderAttributes(clsid
, &dwAttributes
))
247 *pdwAttributes
&= dwAttributes
;
251 *pdwAttributes
&= 0xb0000154;
254 else if (_ILGetDataPointer(pidl
))
256 dwAttributes
= _ILGetFileAttributes(pidl
, NULL
, 0);
257 *pdwAttributes
&= ~SFGAO_FILESYSANCESTOR
;
259 if(( SFGAO_FOLDER
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
260 *pdwAttributes
&= ~(SFGAO_FOLDER
|SFGAO_HASSUBFOLDER
);
262 if(( SFGAO_HIDDEN
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_HIDDEN
))
263 *pdwAttributes
&= ~SFGAO_HIDDEN
;
265 if(( SFGAO_READONLY
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_READONLY
))
266 *pdwAttributes
&= ~SFGAO_READONLY
;
270 *pdwAttributes
&= 0xb0000154;
272 TRACE("-- 0x%08lx\n", *pdwAttributes
);
276 /***********************************************************************
277 * IShellFolder implementation
282 ICOM_VFIELD(IUnknown
);
284 ICOM_VTABLE(IShellFolder2
)* lpvtblShellFolder
;
285 ICOM_VTABLE(IPersistFolder2
)* lpvtblPersistFolder2
;
286 ICOM_VTABLE(IDropTarget
)* lpvtblDropTarget
;
287 ICOM_VTABLE(ISFHelper
)* lpvtblSFHelper
;
289 IUnknown
*pUnkOuter
; /* used for aggregation */
294 LPITEMIDLIST absPidl
; /* complete pidl */
296 UINT cfShellIDList
; /* clipboardformat for IDropTarget */
297 BOOL fAcceptFmt
; /* flag for pending Drop */
300 static struct ICOM_VTABLE(IUnknown
) unkvt
;
301 static struct ICOM_VTABLE(IShellFolder2
) sfvt
;
302 static struct ICOM_VTABLE(IPersistFolder2
) psfvt
;
303 static struct ICOM_VTABLE(IDropTarget
) dtvt
;
304 static struct ICOM_VTABLE(ISFHelper
) shvt
;
306 static IShellFolder
* ISF_MyComputer_Constructor(void);
308 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
309 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
311 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
312 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
314 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
315 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
317 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
318 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
320 converts This to a interface pointer
322 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
323 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
324 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
325 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
326 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
327 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
328 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
329 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
330 /**************************************************************************
331 * registers clipboardformat once
333 static void SF_RegisterClipFmt (IGenericSFImpl
* This
)
335 TRACE("(%p)\n", This
);
337 if (!This
->cfShellIDList
)
339 This
->cfShellIDList
= RegisterClipboardFormatA(CFSTR_SHELLIDLIST
);
343 /**************************************************************************
344 * we need a seperate IUnknown to handle aggregation
347 static HRESULT WINAPI
IUnknown_fnQueryInterface(
352 ICOM_THIS(IGenericSFImpl
, iface
);
355 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
359 if(IsEqualIID(riid
, &IID_IUnknown
)) *ppvObj
= _IUnknown_(This
);
360 else if(IsEqualIID(riid
, &IID_IShellFolder
)) *ppvObj
= _IShellFolder_(This
);
361 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) *ppvObj
= _IShellFolder_(This
);
362 else if(IsEqualIID(riid
, &IID_IPersist
)) *ppvObj
= _IPersist_(This
);
363 else if(IsEqualIID(riid
, &IID_IPersistFolder
)) *ppvObj
= _IPersistFolder_(This
);
364 else if(IsEqualIID(riid
, &IID_IPersistFolder2
)) *ppvObj
= _IPersistFolder2_(This
);
365 else if(IsEqualIID(riid
, &IID_ISFHelper
)) *ppvObj
= _ISFHelper_(This
);
366 else if(IsEqualIID(riid
, &IID_IDropTarget
))
368 *ppvObj
= _IDropTarget_(This
);
369 SF_RegisterClipFmt(This
);
374 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
375 TRACE("-- Interface = %p\n", *ppvObj
);
378 TRACE("-- Interface: E_NOINTERFACE\n");
379 return E_NOINTERFACE
;
382 static ULONG WINAPI
IUnknown_fnAddRef(IUnknown
* iface
)
384 ICOM_THIS(IGenericSFImpl
, iface
);
387 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
390 return ++(This
->ref
);
393 static ULONG WINAPI
IUnknown_fnRelease(IUnknown
* iface
)
395 ICOM_THIS(IGenericSFImpl
, iface
);
398 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
403 TRACE("-- destroying IShellFolder(%p)\n",This
);
405 if (pdesktopfolder
== _IShellFolder_(This
))
408 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This
);
410 if(This
->absPidl
) SHFree(This
->absPidl
);
411 if(This
->sMyPath
) SHFree(This
->sMyPath
);
412 HeapFree(GetProcessHeap(),0,This
);
418 static ICOM_VTABLE(IUnknown
) unkvt
=
420 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
421 IUnknown_fnQueryInterface
,
426 static shvheader GenericSFHeader
[] =
428 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
429 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
430 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
431 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
432 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
434 #define GENERICSHELLVIEWCOLUMNS 5
436 /**************************************************************************
437 * IShellFolder_Constructor
440 * creating undocumented ShellFS_Folder as part of an aggregation
441 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
444 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
446 HRESULT
IFSFolder_Constructor(
447 IUnknown
* pUnkOuter
,
454 TRACE("unkOut=%p riid=%s\n",pUnkOuter
, debugstr_guid(riid
));
456 if(pUnkOuter
&& ! IsEqualIID(riid
, &IID_IUnknown
))
458 hr
= CLASS_E_NOAGGREGATION
; /* forbidden by definition */
462 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
466 ICOM_VTBL(sf
)=&unkvt
;
467 sf
->lpvtblShellFolder
=&sfvt
;
468 sf
->lpvtblPersistFolder2
=&psfvt
;
469 sf
->lpvtblDropTarget
=&dtvt
;
470 sf
->lpvtblSFHelper
=&shvt
;
472 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
473 sf
->pUnkOuter
= pUnkOuter
? pUnkOuter
: _IUnknown_(sf
);
474 *ppv
= _IUnknown_(sf
);
485 /**************************************************************************
486 * IShellFolder_Constructor
489 * THIS points to the parent folder
492 IShellFolder
* IShellFolder_Constructor(
493 IShellFolder2
* iface
,
499 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
501 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
504 ICOM_VTBL(sf
)=&unkvt
;
505 sf
->lpvtblShellFolder
=&sfvt
;
506 sf
->lpvtblPersistFolder2
=&psfvt
;
507 sf
->lpvtblDropTarget
=&dtvt
;
508 sf
->lpvtblSFHelper
=&shvt
;
510 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
511 sf
->pUnkOuter
= _IUnknown_(sf
);
513 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf
,This
, pidl
);
516 if(pidl
&& iface
) /* do we have a pidl? */
520 sf
->absPidl
= ILCombine(This
->absPidl
, pidl
); /* build a absolute pidl */
522 if (!_ILIsSpecialFolder(pidl
)) /* only file system paths */
524 if(This
->sMyPath
) /* get the size of the parents path */
526 dwSize
+= strlen(This
->sMyPath
) ;
527 TRACE("-- (%p)->(parent's path=%s)\n",sf
, debugstr_a(This
->sMyPath
));
530 dwSize
+= _ILSimpleGetText(pidl
,NULL
,0); /* add the size of our name*/
531 sf
->sMyPath
= SHAlloc(dwSize
+ 2); /* '\0' and backslash */
533 if(!sf
->sMyPath
) return NULL
;
536 if(This
->sMyPath
) /* if the parent has a path, get it*/
538 strcpy(sf
->sMyPath
, This
->sMyPath
);
539 PathAddBackslashA (sf
->sMyPath
);
542 len
= strlen(sf
->sMyPath
);
543 _ILSimpleGetText(pidl
, sf
->sMyPath
+ len
, dwSize
+2 - len
);
546 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf
, sf
->absPidl
,debugstr_a(sf
->sMyPath
));
552 return _IShellFolder_(sf
);
555 /**************************************************************************
556 * IShellFolder_fnQueryInterface
559 * REFIID riid [in ] Requested InterfaceID
560 * LPVOID* ppvObject [out] Interface* to hold the result
562 static HRESULT WINAPI
IShellFolder_fnQueryInterface(
563 IShellFolder2
* iface
,
567 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
570 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
572 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
575 /**************************************************************************
576 * IShellFolder_AddRef
579 static ULONG WINAPI
IShellFolder_fnAddRef(IShellFolder2
* iface
)
581 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
584 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
586 return IUnknown_AddRef(This
->pUnkOuter
);
589 /**************************************************************************
590 * IShellFolder_fnRelease
592 static ULONG WINAPI
IShellFolder_fnRelease(IShellFolder2
* iface
)
594 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
597 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
599 return IUnknown_Release(This
->pUnkOuter
);
602 /**************************************************************************
603 * IShellFolder_fnParseDisplayName
605 * HWND hwndOwner, //[in ] Parent window for any message's
606 * LPBC pbc, //[in ] reserved
607 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
608 * ULONG* pchEaten, //[out] (unicode) characters processed
609 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
610 * ULONG* pdwAttributes //[out] items attributes
613 * every folder trys to parse only it's own (the leftmost) pidl and creates a
614 * subfolder to evaluate the remaining parts
615 * now we can parse into namespaces implemented by shell extensions
617 * behaviour on win98: lpszDisplayName=NULL -> chrash
618 * lpszDisplayName="" -> returns mycoputer-pidl
621 * pdwAttributes: not set
622 * pchEaten: not set like in windows
624 static HRESULT WINAPI
IShellFolder_fnParseDisplayName(
625 IShellFolder2
* iface
,
628 LPOLESTR lpszDisplayName
,
631 DWORD
*pdwAttributes
)
633 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
635 HRESULT hr
= E_OUTOFMEMORY
;
637 WCHAR szElement
[MAX_PATH
];
638 CHAR szTempA
[MAX_PATH
], szPath
[MAX_PATH
];
639 LPITEMIDLIST pidlTemp
=NULL
;
641 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
642 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
643 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
645 if (!lpszDisplayName
|| !ppidl
) return E_INVALIDARG
;
647 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
649 if (*lpszDisplayName
)
651 /* get the next element */
652 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
654 /* build the full pathname to the element */
655 lstrcpynWtoA(szTempA
, szElement
, lstrlenW(szElement
) + 1);
656 strcpy(szPath
, This
->sMyPath
);
657 PathAddBackslashA(szPath
);
658 strcat(szPath
, szTempA
);
661 pidlTemp
= SHSimpleIDListFromPathA(szPath
);
665 /* try to analyse the next element */
666 if (szNext
&& *szNext
)
668 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
672 if (pdwAttributes
&& *pdwAttributes
)
674 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
675 /* WIN32_FIND_DATAA fd;
676 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
677 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
678 *pdwAttributes &= ~SFGAO_FOLDER;
679 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
680 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
690 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This
, ppidl
? *ppidl
:0, hr
);
695 /**************************************************************************
696 * IShellFolder_fnEnumObjects
698 * HWND hwndOwner, //[in ] Parent Window
699 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
700 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
702 static HRESULT WINAPI
IShellFolder_fnEnumObjects(
703 IShellFolder2
* iface
,
706 LPENUMIDLIST
* ppEnumIDList
)
708 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
710 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
712 *ppEnumIDList
= NULL
;
713 *ppEnumIDList
= IEnumIDList_Constructor (This
->sMyPath
, dwFlags
, EIDL_FILE
);
715 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
717 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
722 /**************************************************************************
723 * IShellFolder_fnBindToObject
725 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
726 * LPBC pbc, //[in ] reserved
727 * REFIID riid, //[in ] Initial Interface
728 * LPVOID* ppvObject //[out] Interface*
730 static HRESULT WINAPI
IShellFolder_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
731 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
733 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
735 IShellFolder
*pShellFolder
, *pSubFolder
;
736 IPersistFolder
*pPersistFolder
;
737 LPITEMIDLIST absPidl
;
739 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
741 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
745 if ((iid
=_ILGetGUIDPointer(pidl
)))
747 /* we have to create a alien folder */
748 if ( SUCCEEDED(SHCoCreateInstance(NULL
, iid
, NULL
, riid
, (LPVOID
*)&pShellFolder
))
749 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
)))
751 absPidl
= ILCombine (This
->absPidl
, pidl
);
752 IPersistFolder_Initialize(pPersistFolder
, absPidl
);
753 IPersistFolder_Release(pPersistFolder
);
761 else if(_ILIsFolder(pidl
))
763 LPITEMIDLIST pidltemp
= ILCloneFirst(pidl
);
764 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
769 ERR("can't bind to a file\n");
773 if (_ILIsPidlSimple(pidl
))
775 *ppvOut
= pShellFolder
;
779 IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, &IID_IShellFolder
, (LPVOID
)&pSubFolder
);
780 IShellFolder_Release(pShellFolder
);
781 *ppvOut
= pSubFolder
;
784 TRACE("-- (%p) returning (%p)\n",This
, *ppvOut
);
789 /**************************************************************************
790 * IShellFolder_fnBindToStorage
792 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
793 * LPBC pbc, //[in ] reserved
794 * REFIID riid, //[in ] Initial storage interface
795 * LPVOID* ppvObject //[out] Interface* returned
797 static HRESULT WINAPI
IShellFolder_fnBindToStorage(
798 IShellFolder2
* iface
,
804 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
806 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
807 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
813 /**************************************************************************
814 * IShellFolder_fnCompareIDs
817 * LPARAM lParam, //[in ] Column?
818 * LPCITEMIDLIST pidl1, //[in ] simple pidl
819 * LPCITEMIDLIST pidl2) //[in ] simple pidl
822 * Special case - If one of the items is a Path and the other is a File,
823 * always make the Path come before the File.
826 * use SCODE_CODE() on the return value to get the result
829 static HRESULT WINAPI
IShellFolder_fnCompareIDs(
830 IShellFolder2
* iface
,
835 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
837 CHAR szTemp1
[MAX_PATH
];
838 CHAR szTemp2
[MAX_PATH
];
841 HRESULT hr
= E_OUTOFMEMORY
;
842 LPCITEMIDLIST pidlTemp
;
845 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This
,lParam
,pidl1
,pidl2
);
849 if (!pidl1
&& !pidl2
)
851 hr
= ResultFromShort(0);
855 hr
= ResultFromShort(-1);
859 hr
= ResultFromShort(1);
864 pd1
= _ILGetDataPointer(pidl1
);
865 pd2
= _ILGetDataPointer(pidl2
);
867 /* compate the types. sort order is the PT_* constant */
868 pt1
= ( pd1
? pd1
->type
: PT_DESKTOP
);
869 pt2
= ( pd2
? pd2
->type
: PT_DESKTOP
);
873 hr
= ResultFromShort(pt1
-pt2
);
875 else /* same type of pidl */
877 _ILSimpleGetText(pidl1
, szTemp1
, MAX_PATH
);
878 _ILSimpleGetText(pidl2
, szTemp2
, MAX_PATH
);
879 nReturn
= strcasecmp(szTemp1
, szTemp2
);
881 if (nReturn
== 0) /* first pidl different ? */
883 pidl1
= ILGetNext(pidl1
);
885 if (pidl1
&& pidl1
->mkid
.cb
) /* go deeper? */
887 pidlTemp
= ILCloneFirst(pidl1
);
888 pidl2
= ILGetNext(pidl2
);
890 hr
= IShellFolder_BindToObject(iface
, pidlTemp
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psf
);
893 nReturn
= IShellFolder_CompareIDs(psf
, 0, pidl1
, pidl2
);
894 IShellFolder_Release(psf
);
895 hr
= ResultFromShort(nReturn
);
901 hr
= ResultFromShort(nReturn
); /* two equal simple pidls */
906 hr
= ResultFromShort(nReturn
); /* two different simple pidls */
911 TRACE("-- res=0x%08lx\n", hr
);
915 /**************************************************************************
916 * IShellFolder_fnCreateViewObject
918 static HRESULT WINAPI
IShellFolder_fnCreateViewObject(
919 IShellFolder2
* iface
,
924 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
926 LPSHELLVIEW pShellView
;
927 HRESULT hr
= E_INVALIDARG
;
929 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
935 if(IsEqualIID(riid
, &IID_IDropTarget
))
937 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, ppvOut
);
939 else if(IsEqualIID(riid
, &IID_IContextMenu
))
941 FIXME("IContextMenu not implemented\n");
944 else if(IsEqualIID(riid
, &IID_IShellView
))
946 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
949 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
950 IShellView_Release(pShellView
);
954 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
958 /**************************************************************************
959 * IShellFolder_fnGetAttributesOf
962 * UINT cidl, //[in ] num elements in pidl array
963 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
964 * ULONG* rgfInOut) //[out] result array
967 static HRESULT WINAPI
IShellFolder_fnGetAttributesOf(
968 IShellFolder2
* iface
,
970 LPCITEMIDLIST
*apidl
,
973 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
977 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
979 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
982 while (cidl
> 0 && *apidl
)
985 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
990 TRACE("-- result=0x%08lx\n",*rgfInOut
);
994 /**************************************************************************
995 * IShellFolder_fnGetUIObjectOf
998 * HWND hwndOwner, //[in ] Parent window for any output
999 * UINT cidl, //[in ] array size
1000 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1001 * REFIID riid, //[in ] Requested Interface
1002 * UINT* prgfInOut, //[ ] reserved
1003 * LPVOID* ppvObject) //[out] Resulting Interface
1006 * This function gets asked to return "view objects" for one or more (multiple select)
1008 * The viewobject typically is an COM object with one of the following interfaces:
1009 * IExtractIcon,IDataObject,IContextMenu
1010 * In order to support icon positions in the default Listview your DataObject
1011 * must implement the SetData method (in addition to GetData :) - the shell passes
1012 * a barely documented "Icon positions" structure to SetData when the drag starts,
1013 * and GetData's it if the drop is in another explorer window that needs the positions.
1015 static HRESULT WINAPI
IShellFolder_fnGetUIObjectOf(
1016 IShellFolder2
* iface
,
1019 LPCITEMIDLIST
* apidl
,
1024 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1027 IUnknown
* pObj
= NULL
;
1028 HRESULT hr
= E_INVALIDARG
;
1030 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1031 This
,hwndOwner
,cidl
,apidl
,debugstr_guid(riid
),prgfInOut
,ppvOut
);
1037 if(IsEqualIID(riid
, &IID_IContextMenu
) && (cidl
>= 1))
1039 pObj
= (LPUNKNOWN
)ISvItemCm_Constructor((IShellFolder
*)iface
, This
->absPidl
, apidl
, cidl
);
1042 else if (IsEqualIID(riid
, &IID_IDataObject
) &&(cidl
>= 1))
1044 pObj
= (LPUNKNOWN
)IDataObject_Constructor (hwndOwner
, This
->absPidl
, apidl
, cidl
);
1047 else if (IsEqualIID(riid
, &IID_IExtractIconA
) && (cidl
== 1))
1049 pidl
= ILCombine(This
->absPidl
,apidl
[0]);
1050 pObj
= (LPUNKNOWN
)IExtractIconA_Constructor( pidl
);
1054 else if (IsEqualIID(riid
, &IID_IDropTarget
) && (cidl
>= 1))
1056 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, (LPVOID
*)&pObj
);
1068 TRACE("(%p)->hr=0x%08lx\n",This
, hr
);
1072 /**************************************************************************
1073 * IShellFolder_fnGetDisplayNameOf
1074 * Retrieves the display name for the specified file object or subfolder
1077 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1078 * DWORD dwFlags, //[in ] SHGNO formatting flags
1079 * LPSTRRET lpName) //[out] Returned display name
1082 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1084 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1085 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1087 static HRESULT WINAPI
IShellFolder_fnGetDisplayNameOf(
1088 IShellFolder2
* iface
,
1093 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1095 CHAR szPath
[MAX_PATH
]= "";
1099 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1102 if(!pidl
|| !strRet
) return E_INVALIDARG
;
1104 bSimplePidl
= _ILIsPidlSimple(pidl
);
1106 /* take names of special folders only if its only this folder */
1107 if (_ILIsSpecialFolder(pidl
))
1111 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
1116 if (!(dwFlags
& SHGDN_INFOLDER
) && (dwFlags
& SHGDN_FORPARSING
) && This
->sMyPath
)
1118 strcpy (szPath
, This
->sMyPath
); /* get path to root*/
1119 PathAddBackslashA(szPath
);
1120 len
= strlen(szPath
);
1122 _ILSimpleGetText(pidl
, szPath
+ len
, MAX_PATH
- len
); /* append my own path */
1125 if ( (dwFlags
& SHGDN_FORPARSING
) && !bSimplePidl
) /* go deeper if needed */
1127 PathAddBackslashA(szPath
);
1128 len
= strlen(szPath
);
1130 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
+ len
, MAX_PATH
- len
)))
1131 return E_OUTOFMEMORY
;
1133 strRet
->uType
= STRRET_CSTRA
;
1134 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1136 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1140 /**************************************************************************
1141 * IShellFolder_fnSetNameOf
1142 * Changes the name of a file object or subfolder, possibly changing its item
1143 * identifier in the process.
1146 * HWND hwndOwner, //[in ] Owner window for output
1147 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1148 * LPCOLESTR lpszName, //[in ] the items new display name
1149 * DWORD dwFlags, //[in ] SHGNO formatting flags
1150 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1152 static HRESULT WINAPI
IShellFolder_fnSetNameOf(
1153 IShellFolder2
* iface
,
1155 LPCITEMIDLIST pidl
, /*simple pidl*/
1158 LPITEMIDLIST
*pPidlOut
)
1160 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1161 char szSrc
[MAX_PATH
], szDest
[MAX_PATH
];
1163 BOOL bIsFolder
= _ILIsFolder(ILFindLastID(pidl
));
1165 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1166 This
,hwndOwner
,pidl
,debugstr_w(lpName
),dwFlags
,pPidlOut
);
1168 /* build source path */
1169 if (dwFlags
& SHGDN_INFOLDER
)
1171 strcpy(szSrc
, This
->sMyPath
);
1172 PathAddBackslashA(szSrc
);
1173 len
= strlen (szSrc
);
1174 _ILSimpleGetText(pidl
, szSrc
+len
, MAX_PATH
-len
);
1178 SHGetPathFromIDListA(pidl
, szSrc
);
1181 /* build destination path */
1182 strcpy(szDest
, This
->sMyPath
);
1183 PathAddBackslashA(szDest
);
1184 len
= strlen (szDest
);
1185 lstrcpynWtoA(szDest
+len
, lpName
, MAX_PATH
-len
);
1187 TRACE("src=%s dest=%s\n", szSrc
, szDest
);
1188 if ( MoveFileA(szSrc
, szDest
) )
1190 if (pPidlOut
) *pPidlOut
= SHSimpleIDListFromPathA(szDest
);
1191 SHChangeNotifyA( bIsFolder
?SHCNE_RENAMEFOLDER
:SHCNE_RENAMEITEM
, SHCNF_PATHA
, szSrc
, szDest
);
1197 static HRESULT WINAPI
IShellFolder_fnGetDefaultSearchGUID(
1198 IShellFolder2
* iface
,
1201 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1202 FIXME("(%p)\n",This
);
1205 static HRESULT WINAPI
IShellFolder_fnEnumSearches(
1206 IShellFolder2
* iface
,
1207 IEnumExtraSearch
**ppenum
)
1209 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1210 FIXME("(%p)\n",This
);
1213 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumn(
1214 IShellFolder2
* iface
,
1219 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1221 TRACE("(%p)\n",This
);
1223 if (pSort
) *pSort
= 0;
1224 if (pDisplay
) *pDisplay
= 0;
1228 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumnState(
1229 IShellFolder2
* iface
,
1233 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1235 TRACE("(%p)\n",This
);
1237 if (!pcsFlags
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1239 *pcsFlags
= GenericSFHeader
[iColumn
].pcsFlags
;
1243 static HRESULT WINAPI
IShellFolder_fnGetDetailsEx(
1244 IShellFolder2
* iface
,
1246 const SHCOLUMNID
*pscid
,
1249 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1250 FIXME("(%p)\n",This
);
1254 static HRESULT WINAPI
IShellFolder_fnGetDetailsOf(
1255 IShellFolder2
* iface
,
1260 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1261 HRESULT hr
= E_FAIL
;
1263 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
1265 if (!psd
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1269 /* the header titles */
1270 psd
->fmt
= GenericSFHeader
[iColumn
].fmt
;
1271 psd
->cxChar
= GenericSFHeader
[iColumn
].cxChar
;
1272 psd
->str
.uType
= STRRET_CSTRA
;
1273 LoadStringA(shell32_hInstance
, GenericSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
1278 /* the data from the pidl */
1282 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
1285 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1288 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1291 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1293 case 4: /* attributes */
1294 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1298 psd
->str
.uType
= STRRET_CSTRA
;
1303 static HRESULT WINAPI
IShellFolder_fnMapNameToSCID(
1304 IShellFolder2
* iface
,
1308 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1309 FIXME("(%p)\n",This
);
1313 static ICOM_VTABLE(IShellFolder2
) sfvt
=
1315 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1316 IShellFolder_fnQueryInterface
,
1317 IShellFolder_fnAddRef
,
1318 IShellFolder_fnRelease
,
1319 IShellFolder_fnParseDisplayName
,
1320 IShellFolder_fnEnumObjects
,
1321 IShellFolder_fnBindToObject
,
1322 IShellFolder_fnBindToStorage
,
1323 IShellFolder_fnCompareIDs
,
1324 IShellFolder_fnCreateViewObject
,
1325 IShellFolder_fnGetAttributesOf
,
1326 IShellFolder_fnGetUIObjectOf
,
1327 IShellFolder_fnGetDisplayNameOf
,
1328 IShellFolder_fnSetNameOf
,
1331 IShellFolder_fnGetDefaultSearchGUID
,
1332 IShellFolder_fnEnumSearches
,
1333 IShellFolder_fnGetDefaultColumn
,
1334 IShellFolder_fnGetDefaultColumnState
,
1335 IShellFolder_fnGetDetailsEx
,
1336 IShellFolder_fnGetDetailsOf
,
1337 IShellFolder_fnMapNameToSCID
1340 /****************************************************************************
1341 * ISFHelper for IShellFolder implementation
1344 static HRESULT WINAPI
ISFHelper_fnQueryInterface(
1349 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1351 TRACE("(%p)\n", This
);
1353 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
1356 static ULONG WINAPI
ISFHelper_fnAddRef(
1359 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1361 TRACE("(%p)\n", This
);
1363 return IUnknown_AddRef(This
->pUnkOuter
);
1366 static ULONG WINAPI
ISFHelper_fnRelease(
1369 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1371 TRACE("(%p)\n", This
);
1373 return IUnknown_Release(This
->pUnkOuter
);
1377 /****************************************************************************
1378 * ISFHelper_fnAddFolder
1380 * creates a unique folder name
1383 static HRESULT WINAPI
ISFHelper_fnGetUniqueName(
1388 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1389 IEnumIDList
* penum
;
1391 char szText
[MAX_PATH
];
1392 char * szNewFolder
= "New Folder";
1394 TRACE("(%p)(%s %u)\n", This
, lpName
, uLen
);
1396 if (uLen
< strlen(szNewFolder
) + 4) return E_POINTER
;
1398 strcpy(lpName
, szNewFolder
);
1400 hr
= IShellFolder_fnEnumObjects(_IShellFolder2_(This
), 0, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
| SHCONTF_INCLUDEHIDDEN
, &penum
);
1407 next
: IEnumIDList_Reset(penum
);
1408 while(S_OK
== IEnumIDList_Next(penum
, 1, &pidl
, &dwFetched
) && dwFetched
)
1410 _ILSimpleGetText(pidl
, szText
, MAX_PATH
);
1411 if (0 == strcasecmp(szText
, lpName
))
1413 sprintf(lpName
, "%s %d", szNewFolder
, i
++);
1423 IEnumIDList_Release(penum
);
1428 /****************************************************************************
1429 * ISFHelper_fnAddFolder
1431 * adds a new folder.
1434 static HRESULT WINAPI
ISFHelper_fnAddFolder(
1438 LPITEMIDLIST
* ppidlOut
)
1440 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1441 char lpstrNewDir
[MAX_PATH
];
1443 HRESULT hres
= E_FAIL
;
1445 TRACE("(%p)(%s %p)\n", This
, lpName
, ppidlOut
);
1447 strcpy(lpstrNewDir
, This
->sMyPath
);
1448 PathAddBackslashA(lpstrNewDir
);
1449 strcat(lpstrNewDir
, lpName
);
1451 bRes
= CreateDirectoryA(lpstrNewDir
, NULL
);
1455 LPITEMIDLIST pidl
, pidlitem
;
1457 pidlitem
= SHSimpleIDListFromPathA(lpstrNewDir
);
1459 pidl
= ILCombine(This
->absPidl
, pidlitem
);
1460 SHChangeNotifyA(SHCNE_MKDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1463 if (ppidlOut
) *ppidlOut
= pidlitem
;
1468 char lpstrText
[128+MAX_PATH
];
1469 char lpstrTempText
[128];
1470 char lpstrCaption
[256];
1472 /* Cannot Create folder because of permissions */
1473 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_DENIED
, lpstrTempText
, sizeof(lpstrTempText
));
1474 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_CAPTION
, lpstrCaption
, sizeof(lpstrCaption
));
1475 sprintf(lpstrText
,lpstrTempText
, lpstrNewDir
);
1476 MessageBoxA(hwnd
,lpstrText
, lpstrCaption
, MB_OK
| MB_ICONEXCLAMATION
);
1482 /****************************************************************************
1483 * ISFHelper_fnDeleteItems
1485 * deletes items in folder
1487 static HRESULT WINAPI
ISFHelper_fnDeleteItems(
1490 LPCITEMIDLIST
* apidl
)
1492 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1494 char szPath
[MAX_PATH
];
1496 TRACE("(%p)(%u %p)\n", This
, cidl
, apidl
);
1498 for(i
=0; i
< cidl
; i
++)
1500 strcpy(szPath
, This
->sMyPath
);
1501 PathAddBackslashA(szPath
);
1502 _ILSimpleGetText(apidl
[i
], szPath
+strlen(szPath
), MAX_PATH
);
1504 if (_ILIsFolder(apidl
[i
]))
1508 MESSAGE("delete %s\n", szPath
);
1509 if (! SHELL_DeleteDirectoryA(szPath
, TRUE
)) return E_FAIL
;
1510 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1511 SHChangeNotifyA(SHCNE_RMDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1514 else if (_ILIsValue(apidl
[i
]))
1518 MESSAGE("delete %s\n", szPath
);
1519 if (! DeleteFileA(szPath
)) return E_FAIL
;
1520 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1521 SHChangeNotifyA(SHCNE_DELETE
, SHCNF_IDLIST
, pidl
, NULL
);
1529 /****************************************************************************
1530 * ISFHelper_fnCopyItems
1532 * copys items to this folder
1534 static HRESULT WINAPI
ISFHelper_fnCopyItems(
1536 IShellFolder
* pSFFrom
,
1538 LPCITEMIDLIST
*apidl
)
1541 IPersistFolder2
* ppf2
=NULL
;
1542 char szSrcPath
[MAX_PATH
], szDstPath
[MAX_PATH
];
1543 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1545 TRACE("(%p)->(%p,%u,%p)\n", This
, pSFFrom
, cidl
, apidl
);
1547 IShellFolder_QueryInterface(pSFFrom
, &IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
1551 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2
, &pidl
)))
1553 for (i
=0; i
<cidl
; i
++)
1555 SHGetPathFromIDListA(pidl
, szSrcPath
);
1556 PathAddBackslashA(szSrcPath
);
1557 _ILSimpleGetText(apidl
[i
], szSrcPath
+strlen(szSrcPath
), MAX_PATH
);
1559 strcpy(szDstPath
, This
->sMyPath
);
1560 PathAddBackslashA(szDstPath
);
1561 _ILSimpleGetText(apidl
[i
], szDstPath
+strlen(szDstPath
), MAX_PATH
);
1562 MESSAGE("would copy %s to %s\n", szSrcPath
, szDstPath
);
1566 IPersistFolder2_Release(ppf2
);
1571 static ICOM_VTABLE(ISFHelper
) shvt
=
1573 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1574 ISFHelper_fnQueryInterface
,
1576 ISFHelper_fnRelease
,
1577 ISFHelper_fnGetUniqueName
,
1578 ISFHelper_fnAddFolder
,
1579 ISFHelper_fnDeleteItems
,
1580 ISFHelper_fnCopyItems
,
1583 /***********************************************************************
1584 * [Desktopfolder] IShellFolder implementation
1586 static struct ICOM_VTABLE(IShellFolder2
) sfdvt
;
1588 static shvheader DesktopSFHeader
[] =
1590 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
1591 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1592 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1593 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
1594 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
1596 #define DESKTOPSHELLVIEWCOLUMNS 5
1598 /**************************************************************************
1599 * ISF_Desktop_Constructor
1602 IShellFolder
* ISF_Desktop_Constructor()
1604 IGenericSFImpl
* sf
;
1606 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
1608 ICOM_VTBL(sf
)=&unkvt
;
1609 sf
->lpvtblShellFolder
=&sfdvt
;
1610 sf
->absPidl
=_ILCreateDesktop(); /* my qualified pidl */
1611 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
1616 return _IShellFolder_(sf
);
1619 /**************************************************************************
1620 * ISF_Desktop_fnQueryInterface
1622 * NOTES supports not IPersist/IPersistFolder
1624 static HRESULT WINAPI
ISF_Desktop_fnQueryInterface(
1625 IShellFolder2
* iface
,
1629 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1631 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
1635 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
1637 *ppvObj
= _IUnknown_(This
);
1639 else if(IsEqualIID(riid
, &IID_IShellFolder
)) /*IShellFolder*/
1641 *ppvObj
= _IShellFolder_(This
);
1643 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) /*IShellFolder2*/
1645 *ppvObj
= _IShellFolder_(This
);
1650 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
1651 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
1654 TRACE("-- Interface: E_NOINTERFACE\n");
1655 return E_NOINTERFACE
;
1658 /**************************************************************************
1659 * ISF_Desktop_fnParseDisplayName
1662 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1665 static HRESULT WINAPI
ISF_Desktop_fnParseDisplayName(
1666 IShellFolder2
* iface
,
1669 LPOLESTR lpszDisplayName
,
1671 LPITEMIDLIST
*ppidl
,
1672 DWORD
*pdwAttributes
)
1674 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1676 LPCWSTR szNext
=NULL
;
1677 LPITEMIDLIST pidlTemp
=NULL
;
1678 HRESULT hr
=E_OUTOFMEMORY
;
1680 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1681 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
1682 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
1685 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
1687 /* fixme no real parsing implemented */
1688 pidlTemp
= _ILCreateMyComputer();
1689 szNext
= lpszDisplayName
;
1691 if (szNext
&& *szNext
)
1693 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
1699 if (pdwAttributes
&& *pdwAttributes
)
1701 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
1707 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
1712 /**************************************************************************
1713 * ISF_Desktop_fnEnumObjects
1715 static HRESULT WINAPI
ISF_Desktop_fnEnumObjects(
1716 IShellFolder2
* iface
,
1719 LPENUMIDLIST
* ppEnumIDList
)
1721 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1723 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
1725 *ppEnumIDList
= NULL
;
1726 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_DESK
);
1728 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
1730 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
1735 /**************************************************************************
1736 * ISF_Desktop_fnBindToObject
1738 static HRESULT WINAPI
ISF_Desktop_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
1739 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
1741 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1743 IShellFolder
*pShellFolder
, *pSubFolder
;
1745 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1746 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
1750 if ((clsid
=_ILGetGUIDPointer(pidl
)))
1752 if ( IsEqualIID(clsid
, &CLSID_MyComputer
))
1754 pShellFolder
= ISF_MyComputer_Constructor();
1758 /* shell extension */
1759 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
1761 return E_INVALIDARG
;
1767 /* file system folder on the desktop */
1768 LPITEMIDLIST deskpidl
, firstpidl
, completepidl
;
1769 IPersistFolder
* ppf
;
1772 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY
, &deskpidl
);
1773 firstpidl
= ILCloneFirst(pidl
);
1774 completepidl
= ILCombine(deskpidl
, firstpidl
);
1776 pShellFolder
= IShellFolder_Constructor(NULL
, NULL
);
1777 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&ppf
)))
1779 IPersistFolder_Initialize(ppf
, completepidl
);
1780 IPersistFolder_Release(ppf
);
1782 ILFree(completepidl
);
1787 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
1789 *ppvOut
= pShellFolder
;
1791 else /* go deeper */
1793 IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, riid
, (LPVOID
)&pSubFolder
);
1794 IShellFolder_Release(pShellFolder
);
1795 *ppvOut
= pSubFolder
;
1798 TRACE("-- (%p) returning (%p)\n",This
, *ppvOut
);
1803 /**************************************************************************
1804 * ISF_Desktop_fnCreateViewObject
1806 static HRESULT WINAPI
ISF_Desktop_fnCreateViewObject( IShellFolder2
* iface
,
1807 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
1809 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1811 LPSHELLVIEW pShellView
;
1812 HRESULT hr
= E_INVALIDARG
;
1814 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
1820 if(IsEqualIID(riid
, &IID_IDropTarget
))
1822 FIXME("IDropTarget not implemented\n");
1825 else if(IsEqualIID(riid
, &IID_IContextMenu
))
1827 FIXME("IContextMenu not implemented\n");
1830 else if(IsEqualIID(riid
, &IID_IShellView
))
1832 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
1835 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
1836 IShellView_Release(pShellView
);
1840 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
1844 /**************************************************************************
1845 * ISF_Desktop_fnGetAttributesOf
1847 static HRESULT WINAPI
ISF_Desktop_fnGetAttributesOf(
1848 IShellFolder2
* iface
,
1850 LPCITEMIDLIST
*apidl
,
1853 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1857 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
, *rgfInOut
);
1859 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
1860 return E_INVALIDARG
;
1862 while (cidl
> 0 && *apidl
)
1865 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
1870 TRACE("-- result=0x%08lx\n",*rgfInOut
);
1875 /**************************************************************************
1876 * ISF_Desktop_fnGetDisplayNameOf
1879 * special case: pidl = null gives desktop-name back
1881 static HRESULT WINAPI
ISF_Desktop_fnGetDisplayNameOf(
1882 IShellFolder2
* iface
,
1887 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1889 CHAR szPath
[MAX_PATH
]= "";
1891 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1894 if(!strRet
) return E_INVALIDARG
;
1898 HCR_GetClassName(&CLSID_ShellDesktop
, szPath
, MAX_PATH
);
1900 else if ( _ILIsPidlSimple(pidl
) )
1902 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
1906 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
, MAX_PATH
)))
1907 return E_OUTOFMEMORY
;
1909 strRet
->uType
= STRRET_CSTRA
;
1910 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1913 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1917 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultSearchGUID(
1918 IShellFolder2
* iface
,
1921 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1922 FIXME("(%p)\n",This
);
1925 static HRESULT WINAPI
ISF_Desktop_fnEnumSearches(
1926 IShellFolder2
* iface
,
1927 IEnumExtraSearch
**ppenum
)
1929 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1930 FIXME("(%p)\n",This
);
1933 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumn(
1934 IShellFolder2
* iface
,
1939 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1941 TRACE("(%p)\n",This
);
1943 if (pSort
) *pSort
= 0;
1944 if (pDisplay
) *pDisplay
= 0;
1948 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumnState(
1949 IShellFolder2
* iface
,
1953 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1955 TRACE("(%p)\n",This
);
1957 if (!pcsFlags
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1959 *pcsFlags
= DesktopSFHeader
[iColumn
].pcsFlags
;
1963 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsEx(
1964 IShellFolder2
* iface
,
1966 const SHCOLUMNID
*pscid
,
1969 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1970 FIXME("(%p)\n",This
);
1974 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsOf(
1975 IShellFolder2
* iface
,
1980 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1981 HRESULT hr
= E_FAIL
;;
1983 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
1985 if (!psd
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1989 psd
->fmt
= DesktopSFHeader
[iColumn
].fmt
;
1990 psd
->cxChar
= DesktopSFHeader
[iColumn
].cxChar
;
1991 psd
->str
.uType
= STRRET_CSTRA
;
1992 LoadStringA(shell32_hInstance
, DesktopSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
1997 /* the data from the pidl */
2001 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
2004 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2007 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2010 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2012 case 4: /* attributes */
2013 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2017 psd
->str
.uType
= STRRET_CSTRA
;
2022 static HRESULT WINAPI
ISF_Desktop_fnMapNameToSCID(
2023 IShellFolder2
* iface
,
2027 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2028 FIXME("(%p)\n",This
);
2032 static ICOM_VTABLE(IShellFolder2
) sfdvt
=
2034 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2035 ISF_Desktop_fnQueryInterface
,
2036 IShellFolder_fnAddRef
,
2037 IShellFolder_fnRelease
,
2038 ISF_Desktop_fnParseDisplayName
,
2039 ISF_Desktop_fnEnumObjects
,
2040 ISF_Desktop_fnBindToObject
,
2041 IShellFolder_fnBindToStorage
,
2042 IShellFolder_fnCompareIDs
,
2043 ISF_Desktop_fnCreateViewObject
,
2044 ISF_Desktop_fnGetAttributesOf
,
2045 IShellFolder_fnGetUIObjectOf
,
2046 ISF_Desktop_fnGetDisplayNameOf
,
2047 IShellFolder_fnSetNameOf
,
2050 ISF_Desktop_fnGetDefaultSearchGUID
,
2051 ISF_Desktop_fnEnumSearches
,
2052 ISF_Desktop_fnGetDefaultColumn
,
2053 ISF_Desktop_fnGetDefaultColumnState
,
2054 ISF_Desktop_fnGetDetailsEx
,
2055 ISF_Desktop_fnGetDetailsOf
,
2056 ISF_Desktop_fnMapNameToSCID
2060 /***********************************************************************
2061 * IShellFolder [MyComputer] implementation
2064 static struct ICOM_VTABLE(IShellFolder2
) sfmcvt
;
2066 static shvheader MyComputerSFHeader
[] =
2068 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
2069 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2070 { IDS_SHV_COLUMN6
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2071 { IDS_SHV_COLUMN7
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2073 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2075 /**************************************************************************
2076 * ISF_MyComputer_Constructor
2078 static IShellFolder
* ISF_MyComputer_Constructor(void)
2080 IGenericSFImpl
* sf
;
2082 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
2085 ICOM_VTBL(sf
)=&unkvt
;
2086 sf
->lpvtblShellFolder
=&sfmcvt
;
2087 sf
->lpvtblPersistFolder2
= &psfvt
;
2088 sf
->pclsid
= (CLSID
*)&CLSID_SFMyComp
;
2089 sf
->absPidl
=_ILCreateMyComputer(); /* my qualified pidl */
2090 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
2095 return _IShellFolder_(sf
);
2098 /**************************************************************************
2099 * ISF_MyComputer_fnParseDisplayName
2101 static HRESULT WINAPI
ISF_MyComputer_fnParseDisplayName(
2102 IShellFolder2
* iface
,
2105 LPOLESTR lpszDisplayName
,
2107 LPITEMIDLIST
*ppidl
,
2108 DWORD
*pdwAttributes
)
2110 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2112 HRESULT hr
= E_OUTOFMEMORY
;
2113 LPCWSTR szNext
=NULL
;
2114 WCHAR szElement
[MAX_PATH
];
2115 CHAR szTempA
[MAX_PATH
];
2116 LPITEMIDLIST pidlTemp
;
2118 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2119 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
2120 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
2123 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
2125 /* do we have an absolute path name ? */
2126 if (PathGetDriveNumberW(lpszDisplayName
) >= 0 &&
2127 lpszDisplayName
[2] == (WCHAR
)'\\')
2129 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
2130 lstrcpynWtoA(szTempA
, szElement
, lstrlenW(szElement
) + 1);
2131 pidlTemp
= _ILCreateDrive(szTempA
);
2133 if (szNext
&& *szNext
)
2135 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
2139 if (pdwAttributes
&& *pdwAttributes
)
2141 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
2148 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
2153 /**************************************************************************
2154 * ISF_MyComputer_fnEnumObjects
2156 static HRESULT WINAPI
ISF_MyComputer_fnEnumObjects(
2157 IShellFolder2
* iface
,
2160 LPENUMIDLIST
* ppEnumIDList
)
2162 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2164 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
2166 *ppEnumIDList
= NULL
;
2167 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_MYCOMP
);
2169 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
2171 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
2176 /**************************************************************************
2177 * ISF_MyComputer_fnBindToObject
2179 static HRESULT WINAPI
ISF_MyComputer_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
2180 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
2182 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2184 IShellFolder
*pShellFolder
, *pSubFolder
;
2185 LPITEMIDLIST pidltemp
;
2187 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2188 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
2190 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
2194 if ((clsid
=_ILGetGUIDPointer(pidl
)) && !IsEqualIID(clsid
, &CLSID_MyComputer
))
2196 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
2203 if (!_ILIsDrive(pidl
)) return E_INVALIDARG
;
2205 pidltemp
= ILCloneFirst(pidl
);
2206 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
2210 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
2212 *ppvOut
= pShellFolder
;
2214 else /* go deeper */
2216 IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, &IID_IShellFolder
, (LPVOID
)&pSubFolder
);
2217 IShellFolder_Release(pShellFolder
);
2218 *ppvOut
= pSubFolder
;
2221 TRACE("-- (%p) returning (%p)\n",This
, *ppvOut
);
2226 /**************************************************************************
2227 * ISF_MyComputer_fnCreateViewObject
2229 static HRESULT WINAPI
ISF_MyComputer_fnCreateViewObject( IShellFolder2
* iface
,
2230 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
2232 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2234 LPSHELLVIEW pShellView
;
2235 HRESULT hr
= E_INVALIDARG
;
2237 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
2243 if(IsEqualIID(riid
, &IID_IDropTarget
))
2245 FIXME("IDropTarget not implemented\n");
2248 else if(IsEqualIID(riid
, &IID_IContextMenu
))
2250 FIXME("IContextMenu not implemented\n");
2253 else if(IsEqualIID(riid
, &IID_IShellView
))
2255 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
2258 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
2259 IShellView_Release(pShellView
);
2263 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
2267 /**************************************************************************
2268 * ISF_MyComputer_fnGetAttributesOf
2270 static HRESULT WINAPI
ISF_MyComputer_fnGetAttributesOf(
2271 IShellFolder2
* iface
,
2273 LPCITEMIDLIST
*apidl
,
2276 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2280 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
2282 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
2283 return E_INVALIDARG
;
2285 while (cidl
> 0 && *apidl
)
2288 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
2293 TRACE("-- result=0x%08lx\n",*rgfInOut
);
2297 /**************************************************************************
2298 * ISF_MyComputer_fnGetDisplayNameOf
2301 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2302 * SHGDN_INFOLDER makes no sense.
2304 static HRESULT WINAPI
ISF_MyComputer_fnGetDisplayNameOf(
2305 IShellFolder2
* iface
,
2310 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2312 char szPath
[MAX_PATH
], szDrive
[18];
2316 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
2319 if(!strRet
) return E_INVALIDARG
;
2321 szPath
[0]=0x00; szDrive
[0]=0x00;
2324 bSimplePidl
= _ILIsPidlSimple(pidl
);
2326 if (_ILIsSpecialFolder(pidl
))
2328 /* take names of special folders only if its only this folder */
2331 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2336 if (!_ILIsDrive(pidl
))
2338 ERR("Wrong pidl type\n");
2339 return E_INVALIDARG
;
2342 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2344 /* long view "lw_name (C:)" */
2345 if ( bSimplePidl
&& !(dwFlags
& SHGDN_FORPARSING
))
2347 DWORD dwVolumeSerialNumber
,dwMaximumComponetLength
,dwFileSystemFlags
;
2349 GetVolumeInformationA(szPath
,szDrive
,12,&dwVolumeSerialNumber
,&dwMaximumComponetLength
,&dwFileSystemFlags
,NULL
,0);
2350 strcat (szDrive
," (");
2351 strncat (szDrive
, szPath
, 2);
2352 strcat (szDrive
,")");
2353 strcpy (szPath
, szDrive
);
2357 if (!bSimplePidl
) /* go deeper if needed */
2359 PathAddBackslashA(szPath
);
2360 len
= strlen(szPath
);
2362 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
| SHGDN_FORPARSING
, szPath
+ len
, MAX_PATH
- len
)))
2363 return E_OUTOFMEMORY
;
2365 strRet
->uType
= STRRET_CSTRA
;
2366 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
2369 TRACE("-- (%p)->(%s)\n", This
, szPath
);
2373 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultSearchGUID(
2374 IShellFolder2
* iface
,
2377 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2378 FIXME("(%p)\n",This
);
2381 static HRESULT WINAPI
ISF_MyComputer_fnEnumSearches(
2382 IShellFolder2
* iface
,
2383 IEnumExtraSearch
**ppenum
)
2385 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2386 FIXME("(%p)\n",This
);
2389 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumn(
2390 IShellFolder2
* iface
,
2395 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2397 TRACE("(%p)\n",This
);
2399 if (pSort
) *pSort
= 0;
2400 if (pDisplay
) *pDisplay
= 0;
2404 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumnState(
2405 IShellFolder2
* iface
,
2409 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2411 TRACE("(%p)\n",This
);
2413 if (!pcsFlags
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2415 *pcsFlags
= MyComputerSFHeader
[iColumn
].pcsFlags
;
2419 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsEx(
2420 IShellFolder2
* iface
,
2422 const SHCOLUMNID
*pscid
,
2425 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2426 FIXME("(%p)\n",This
);
2431 /* fixme: drive size >4GB is rolling over */
2432 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsOf(
2433 IShellFolder2
* iface
,
2438 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2441 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
2443 if (!psd
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2447 psd
->fmt
= MyComputerSFHeader
[iColumn
].fmt
;
2448 psd
->cxChar
= MyComputerSFHeader
[iColumn
].cxChar
;
2449 psd
->str
.uType
= STRRET_CSTRA
;
2450 LoadStringA(shell32_hInstance
, MyComputerSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
2455 char szPath
[MAX_PATH
];
2456 ULARGE_INTEGER ulBytes
;
2458 psd
->str
.u
.cStr
[0] = 0x00;
2459 psd
->str
.uType
= STRRET_CSTRA
;
2463 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
2466 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2468 case 2: /* total size */
2469 if (_ILIsDrive(pidl
))
2471 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2472 GetDiskFreeSpaceExA(szPath
, NULL
, &ulBytes
, NULL
);
2473 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2476 case 3: /* free size */
2477 if (_ILIsDrive(pidl
))
2479 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2480 GetDiskFreeSpaceExA(szPath
, &ulBytes
, NULL
, NULL
);
2481 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2490 static HRESULT WINAPI
ISF_MyComputer_fnMapNameToSCID(
2491 IShellFolder2
* iface
,
2495 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2496 FIXME("(%p)\n",This
);
2500 static ICOM_VTABLE(IShellFolder2
) sfmcvt
=
2502 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2503 IShellFolder_fnQueryInterface
,
2504 IShellFolder_fnAddRef
,
2505 IShellFolder_fnRelease
,
2506 ISF_MyComputer_fnParseDisplayName
,
2507 ISF_MyComputer_fnEnumObjects
,
2508 ISF_MyComputer_fnBindToObject
,
2509 IShellFolder_fnBindToStorage
,
2510 IShellFolder_fnCompareIDs
,
2511 ISF_MyComputer_fnCreateViewObject
,
2512 ISF_MyComputer_fnGetAttributesOf
,
2513 IShellFolder_fnGetUIObjectOf
,
2514 ISF_MyComputer_fnGetDisplayNameOf
,
2515 IShellFolder_fnSetNameOf
,
2518 ISF_MyComputer_fnGetDefaultSearchGUID
,
2519 ISF_MyComputer_fnEnumSearches
,
2520 ISF_MyComputer_fnGetDefaultColumn
,
2521 ISF_MyComputer_fnGetDefaultColumnState
,
2522 ISF_MyComputer_fnGetDetailsEx
,
2523 ISF_MyComputer_fnGetDetailsOf
,
2524 ISF_MyComputer_fnMapNameToSCID
2528 /************************************************************************
2529 * ISFPersistFolder_QueryInterface (IUnknown)
2532 static HRESULT WINAPI
ISFPersistFolder2_QueryInterface(
2533 IPersistFolder2
* iface
,
2537 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2539 TRACE("(%p)\n", This
);
2541 return IUnknown_QueryInterface(This
->pUnkOuter
, iid
, ppvObj
);
2544 /************************************************************************
2545 * ISFPersistFolder_AddRef (IUnknown)
2548 static ULONG WINAPI
ISFPersistFolder2_AddRef(
2549 IPersistFolder2
* iface
)
2551 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2553 TRACE("(%p)\n", This
);
2555 return IUnknown_AddRef(This
->pUnkOuter
);
2558 /************************************************************************
2559 * ISFPersistFolder_Release (IUnknown)
2562 static ULONG WINAPI
ISFPersistFolder2_Release(
2563 IPersistFolder2
* iface
)
2565 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2567 TRACE("(%p)\n", This
);
2569 return IUnknown_Release(This
->pUnkOuter
);
2572 /************************************************************************
2573 * ISFPersistFolder_GetClassID (IPersist)
2575 static HRESULT WINAPI
ISFPersistFolder2_GetClassID(
2576 IPersistFolder2
* iface
,
2579 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2581 TRACE("(%p)\n", This
);
2583 if (!lpClassId
) return E_POINTER
;
2584 *lpClassId
= *This
->pclsid
;
2589 /************************************************************************
2590 * ISFPersistFolder_Initialize (IPersistFolder)
2593 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2595 static HRESULT WINAPI
ISFPersistFolder2_Initialize(
2596 IPersistFolder2
* iface
,
2599 char sTemp
[MAX_PATH
];
2600 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2602 TRACE("(%p)->(%p)\n", This
, pidl
);
2604 /* free the old stuff */
2607 SHFree(This
->absPidl
);
2608 This
->absPidl
= NULL
;
2612 SHFree(This
->sMyPath
);
2613 This
->sMyPath
= NULL
;
2617 This
->absPidl
= ILClone(pidl
);
2620 if (SHGetPathFromIDListA(pidl
, sTemp
))
2622 This
->sMyPath
= SHAlloc(strlen(sTemp
)+1);
2623 strcpy(This
->sMyPath
, sTemp
);
2626 TRACE("--(%p)->(%s)\n", This
, This
->sMyPath
);
2631 /**************************************************************************
2632 * IPersistFolder2_fnGetCurFolder
2634 static HRESULT WINAPI
ISFPersistFolder2_fnGetCurFolder(
2635 IPersistFolder2
* iface
,
2636 LPITEMIDLIST
* pidl
)
2638 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2640 TRACE("(%p)->(%p)\n",This
, pidl
);
2642 if (!pidl
) return E_POINTER
;
2644 *pidl
= ILClone(This
->absPidl
);
2649 static ICOM_VTABLE(IPersistFolder2
) psfvt
=
2651 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2652 ISFPersistFolder2_QueryInterface
,
2653 ISFPersistFolder2_AddRef
,
2654 ISFPersistFolder2_Release
,
2655 ISFPersistFolder2_GetClassID
,
2656 ISFPersistFolder2_Initialize
,
2657 ISFPersistFolder2_fnGetCurFolder
2660 /****************************************************************************
2661 * ISFDropTarget implementation
2663 static BOOL
ISFDropTarget_QueryDrop(
2668 DWORD dwEffect
= *pdwEffect
;
2670 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2672 *pdwEffect
= DROPEFFECT_NONE
;
2674 if (This
->fAcceptFmt
)
2675 { /* Does our interpretation of the keystate ... */
2676 *pdwEffect
= KeyStateToDropEffect(dwKeyState
);
2678 /* ... matches the desired effect ? */
2679 if (dwEffect
& *pdwEffect
)
2687 static HRESULT WINAPI
ISFDropTarget_QueryInterface(
2692 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2694 TRACE("(%p)\n", This
);
2696 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
2699 static ULONG WINAPI
ISFDropTarget_AddRef( IDropTarget
*iface
)
2701 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2703 TRACE("(%p)\n", This
);
2705 return IUnknown_AddRef(This
->pUnkOuter
);
2708 static ULONG WINAPI
ISFDropTarget_Release( IDropTarget
*iface
)
2710 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2712 TRACE("(%p)\n", This
);
2714 return IUnknown_Release(This
->pUnkOuter
);
2717 static HRESULT WINAPI
ISFDropTarget_DragEnter(
2719 IDataObject
*pDataObject
,
2726 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2728 TRACE("(%p)->(DataObject=%p)\n",This
,pDataObject
);
2730 InitFormatEtc(fmt
, This
->cfShellIDList
, TYMED_HGLOBAL
);
2732 This
->fAcceptFmt
= (S_OK
== IDataObject_QueryGetData(pDataObject
, &fmt
)) ? TRUE
: FALSE
;
2734 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2739 static HRESULT WINAPI
ISFDropTarget_DragOver(
2745 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2747 TRACE("(%p)\n",This
);
2749 if(!pdwEffect
) return E_INVALIDARG
;
2751 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2756 static HRESULT WINAPI
ISFDropTarget_DragLeave(
2759 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2761 TRACE("(%p)\n",This
);
2763 This
->fAcceptFmt
= FALSE
;
2768 static HRESULT WINAPI
ISFDropTarget_Drop(
2770 IDataObject
* pDataObject
,
2775 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2777 FIXME("(%p) object dropped\n",This
);
2782 static struct ICOM_VTABLE(IDropTarget
) dtvt
=
2784 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2785 ISFDropTarget_QueryInterface
,
2786 ISFDropTarget_AddRef
,
2787 ISFDropTarget_Release
,
2788 ISFDropTarget_DragEnter
,
2789 ISFDropTarget_DragOver
,
2790 ISFDropTarget_DragLeave
,