4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
7 * IShellFolder2 and related interfaces
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #include "wine/obj_base.h"
37 #include "wine/obj_dragdrop.h"
38 #include "wine/obj_shellfolder.h"
39 #include "undocshell.h"
40 #include "shell32_main.h"
43 #include "shellfolder.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
49 /***************************************************************************
50 * debughelper: print out the return adress
51 * helps especially to track down unbalanced AddRef/Release
56 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
70 /***************************************************************************
71 * GetNextElement (internal function)
73 * gets a part of a string till the first backslash
76 * pszNext [IN] string to get the element from
77 * pszOut [IN] pointer to buffer whitch receives string
78 * dwOut [IN] length of pszOut
81 * LPSTR pointer to first, not yet parsed char
84 static LPCWSTR
GetNextElementW(LPCWSTR pszNext
,LPWSTR pszOut
,DWORD dwOut
)
85 { LPCWSTR pszTail
= pszNext
;
87 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext
),pszOut
,dwOut
);
91 if(!pszNext
|| !*pszNext
)
94 while(*pszTail
&& (*pszTail
!= (WCHAR
)'\\'))
97 dwCopy
= (WCHAR
*)pszTail
- (WCHAR
*)pszNext
+ 1;
98 lstrcpynW(pszOut
, pszNext
, (dwOut
<dwCopy
)? dwOut
: dwCopy
);
105 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext
),debugstr_w(pszOut
),dwOut
,pszTail
);
109 static HRESULT
SHELL32_ParseNextElement(
112 LPITEMIDLIST
* pidlInOut
,
115 DWORD
*pdwAttributes
)
117 HRESULT hr
= E_OUTOFMEMORY
;
118 LPITEMIDLIST pidlOut
, pidlTemp
= NULL
;
119 IShellFolder
*psfChild
;
121 TRACE("(%p, %p, %s)\n",psf
, pidlInOut
? *pidlInOut
: NULL
, debugstr_w(szNext
));
124 /* get the shellfolder for the child pidl and let it analyse further */
125 hr
= IShellFolder_BindToObject(psf
, *pidlInOut
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
129 hr
= IShellFolder_ParseDisplayName(psfChild
, hwndOwner
, NULL
, szNext
, pEaten
, &pidlOut
, pdwAttributes
);
130 IShellFolder_Release(psfChild
);
132 pidlTemp
= ILCombine(*pidlInOut
, pidlOut
);
139 *pidlInOut
= pidlTemp
;
141 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut
? *pidlInOut
: NULL
, hr
);
145 /***********************************************************************
146 * SHELL32_CoCreateInitSF
148 * creates a initialized shell folder
150 static HRESULT
SHELL32_CoCreateInitSF (
151 LPITEMIDLIST pidlRoot
,
152 LPITEMIDLIST pidlChild
,
158 LPITEMIDLIST absPidl
;
159 IShellFolder2
*pShellFolder
;
160 IPersistFolder
*pPersistFolder
;
162 TRACE("%p %p\n", pidlRoot
, pidlChild
);
166 /* we have to ask first for IPersistFolder, some special folders are expecting this */
167 hr
= SHCoCreateInstance(NULL
, clsid
, NULL
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
);
170 hr
= IPersistFolder_QueryInterface(pPersistFolder
, iid
, (LPVOID
*)&pShellFolder
);
173 absPidl
= ILCombine (pidlRoot
, pidlChild
);
174 hr
= IPersistFolder_Initialize(pPersistFolder
, absPidl
);
175 IPersistFolder_Release(pPersistFolder
);
177 *ppvOut
= pShellFolder
;
181 TRACE("-- ret=0x%08lx\n", hr
);
185 static HRESULT
SHELL32_GetDisplayNameOfChild(
192 LPITEMIDLIST pidlFirst
, pidlNext
;
193 IShellFolder2
* psfChild
;
194 HRESULT hr
= E_OUTOFMEMORY
;
197 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf
,pidl
,dwFlags
,szOut
, dwOutLen
);
200 if ((pidlFirst
= ILCloneFirst(pidl
)))
202 hr
= IShellFolder_BindToObject(psf
, pidlFirst
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
205 pidlNext
= ILGetNext(pidl
);
207 hr
= IShellFolder_GetDisplayNameOf(psfChild
, pidlNext
, dwFlags
| SHGDN_INFOLDER
, &strTemp
);
210 hr
= StrRetToStrNA(szOut
, dwOutLen
, &strTemp
, pidlNext
);
213 IShellFolder_Release(psfChild
);
218 TRACE("-- ret=0x%08lx %s\n", hr
, szOut
);
223 /***********************************************************************
224 * SHELL32_GetItemAttributes
228 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
229 * file: 0x40000177 FILESYSTEM
230 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
231 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
232 * (seems to be default for shell extensions if no registry entry exists)
234 * This functions does not set flags!! It only resets flags when nessesary.
236 static HRESULT
SHELL32_GetItemAttributes(
239 LPDWORD pdwAttributes
)
244 TRACE("0x%08lx\n", *pdwAttributes
);
246 if (*pdwAttributes
& (0xcff3fe88))
247 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes
);
248 *pdwAttributes
&= ~SFGAO_LINK
; /* FIXME: for native filedialogs */
250 if (_ILIsDrive(pidl
))
252 *pdwAttributes
&= 0xf0000144;
254 else if ((clsid
=_ILGetGUIDPointer(pidl
)))
256 if (HCR_GetFolderAttributes(clsid
, &dwAttributes
))
258 *pdwAttributes
&= dwAttributes
;
262 *pdwAttributes
&= 0xb0000154;
265 else if (_ILGetDataPointer(pidl
))
267 dwAttributes
= _ILGetFileAttributes(pidl
, NULL
, 0);
268 *pdwAttributes
&= ~SFGAO_FILESYSANCESTOR
;
270 if(( SFGAO_FOLDER
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
271 *pdwAttributes
&= ~(SFGAO_FOLDER
|SFGAO_HASSUBFOLDER
);
273 if(( SFGAO_HIDDEN
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_HIDDEN
))
274 *pdwAttributes
&= ~SFGAO_HIDDEN
;
276 if(( SFGAO_READONLY
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_READONLY
))
277 *pdwAttributes
&= ~SFGAO_READONLY
;
281 *pdwAttributes
&= 0xb0000154;
283 TRACE("-- 0x%08lx\n", *pdwAttributes
);
287 /***********************************************************************
288 * IShellFolder implementation
293 ICOM_VFIELD(IUnknown
);
295 ICOM_VTABLE(IShellFolder2
)* lpvtblShellFolder
;
296 ICOM_VTABLE(IPersistFolder2
)* lpvtblPersistFolder2
;
297 ICOM_VTABLE(IDropTarget
)* lpvtblDropTarget
;
298 ICOM_VTABLE(ISFHelper
)* lpvtblSFHelper
;
300 IUnknown
*pUnkOuter
; /* used for aggregation */
305 LPITEMIDLIST absPidl
; /* complete pidl */
307 UINT cfShellIDList
; /* clipboardformat for IDropTarget */
308 BOOL fAcceptFmt
; /* flag for pending Drop */
311 static struct ICOM_VTABLE(IUnknown
) unkvt
;
312 static struct ICOM_VTABLE(IShellFolder2
) sfvt
;
313 static struct ICOM_VTABLE(IPersistFolder2
) psfvt
;
314 static struct ICOM_VTABLE(IDropTarget
) dtvt
;
315 static struct ICOM_VTABLE(ISFHelper
) shvt
;
317 static IShellFolder
* ISF_MyComputer_Constructor(void);
319 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
320 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
322 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
323 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
325 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
326 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
328 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
329 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
331 converts This to a interface pointer
333 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
334 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
335 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
336 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
337 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
338 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
339 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
340 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
341 /**************************************************************************
342 * registers clipboardformat once
344 static void SF_RegisterClipFmt (IGenericSFImpl
* This
)
346 TRACE("(%p)\n", This
);
348 if (!This
->cfShellIDList
)
350 This
->cfShellIDList
= RegisterClipboardFormatA(CFSTR_SHELLIDLIST
);
354 /**************************************************************************
355 * we need a separate IUnknown to handle aggregation
358 static HRESULT WINAPI
IUnknown_fnQueryInterface(
363 ICOM_THIS(IGenericSFImpl
, iface
);
366 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
370 if(IsEqualIID(riid
, &IID_IUnknown
)) *ppvObj
= _IUnknown_(This
);
371 else if(IsEqualIID(riid
, &IID_IShellFolder
)) *ppvObj
= _IShellFolder_(This
);
372 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) *ppvObj
= _IShellFolder_(This
);
373 else if(IsEqualIID(riid
, &IID_IPersist
)) *ppvObj
= _IPersist_(This
);
374 else if(IsEqualIID(riid
, &IID_IPersistFolder
)) *ppvObj
= _IPersistFolder_(This
);
375 else if(IsEqualIID(riid
, &IID_IPersistFolder2
)) *ppvObj
= _IPersistFolder2_(This
);
376 else if(IsEqualIID(riid
, &IID_ISFHelper
)) *ppvObj
= _ISFHelper_(This
);
377 else if(IsEqualIID(riid
, &IID_IDropTarget
))
379 *ppvObj
= _IDropTarget_(This
);
380 SF_RegisterClipFmt(This
);
385 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
386 TRACE("-- Interface = %p\n", *ppvObj
);
389 TRACE("-- Interface: E_NOINTERFACE\n");
390 return E_NOINTERFACE
;
393 static ULONG WINAPI
IUnknown_fnAddRef(IUnknown
* iface
)
395 ICOM_THIS(IGenericSFImpl
, iface
);
398 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
401 return ++(This
->ref
);
404 static ULONG WINAPI
IUnknown_fnRelease(IUnknown
* iface
)
406 ICOM_THIS(IGenericSFImpl
, iface
);
409 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
414 TRACE("-- destroying IShellFolder(%p)\n",This
);
416 if (pdesktopfolder
== _IShellFolder_(This
))
419 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This
);
421 if(This
->absPidl
) SHFree(This
->absPidl
);
422 if(This
->sMyPath
) SHFree(This
->sMyPath
);
423 HeapFree(GetProcessHeap(),0,This
);
429 static ICOM_VTABLE(IUnknown
) unkvt
=
431 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
432 IUnknown_fnQueryInterface
,
437 static shvheader GenericSFHeader
[] =
439 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
440 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
441 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
442 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
443 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
445 #define GENERICSHELLVIEWCOLUMNS 5
447 /**************************************************************************
448 * IShellFolder_Constructor
451 * creating undocumented ShellFS_Folder as part of an aggregation
452 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
455 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
457 HRESULT
IFSFolder_Constructor(
458 IUnknown
* pUnkOuter
,
465 TRACE("unkOut=%p riid=%s\n",pUnkOuter
, debugstr_guid(riid
));
467 if(pUnkOuter
&& ! IsEqualIID(riid
, &IID_IUnknown
))
469 hr
= CLASS_E_NOAGGREGATION
; /* forbidden by definition */
473 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
477 ICOM_VTBL(sf
)=&unkvt
;
478 sf
->lpvtblShellFolder
=&sfvt
;
479 sf
->lpvtblPersistFolder2
=&psfvt
;
480 sf
->lpvtblDropTarget
=&dtvt
;
481 sf
->lpvtblSFHelper
=&shvt
;
483 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
484 sf
->pUnkOuter
= pUnkOuter
? pUnkOuter
: _IUnknown_(sf
);
485 *ppv
= _IUnknown_(sf
);
496 /**************************************************************************
497 * IShellFolder_Constructor
500 * THIS points to the parent folder
503 IShellFolder
* IShellFolder_Constructor(
504 IShellFolder2
* iface
,
510 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
512 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
515 ICOM_VTBL(sf
)=&unkvt
;
516 sf
->lpvtblShellFolder
=&sfvt
;
517 sf
->lpvtblPersistFolder2
=&psfvt
;
518 sf
->lpvtblDropTarget
=&dtvt
;
519 sf
->lpvtblSFHelper
=&shvt
;
521 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
522 sf
->pUnkOuter
= _IUnknown_(sf
);
524 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf
,This
, pidl
);
527 if(pidl
&& iface
) /* do we have a pidl? */
531 sf
->absPidl
= ILCombine(This
->absPidl
, pidl
); /* build a absolute pidl */
533 if (!_ILIsSpecialFolder(pidl
)) /* only file system paths */
535 if(This
->sMyPath
) /* get the size of the parents path */
537 dwSize
+= strlen(This
->sMyPath
) ;
538 TRACE("-- (%p)->(parent's path=%s)\n",sf
, debugstr_a(This
->sMyPath
));
541 dwSize
+= _ILSimpleGetText(pidl
,NULL
,0); /* add the size of our name*/
542 sf
->sMyPath
= SHAlloc(dwSize
+ 2); /* '\0' and backslash */
544 if(!sf
->sMyPath
) return NULL
;
547 if(This
->sMyPath
) /* if the parent has a path, get it*/
549 strcpy(sf
->sMyPath
, This
->sMyPath
);
550 PathAddBackslashA (sf
->sMyPath
);
553 len
= strlen(sf
->sMyPath
);
554 _ILSimpleGetText(pidl
, sf
->sMyPath
+ len
, dwSize
+2 - len
);
557 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf
, sf
->absPidl
,debugstr_a(sf
->sMyPath
));
563 return _IShellFolder_(sf
);
566 /**************************************************************************
567 * IShellFolder_fnQueryInterface
570 * REFIID riid [in ] Requested InterfaceID
571 * LPVOID* ppvObject [out] Interface* to hold the result
573 static HRESULT WINAPI
IShellFolder_fnQueryInterface(
574 IShellFolder2
* iface
,
578 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
581 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
583 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
586 /**************************************************************************
587 * IShellFolder_AddRef
590 static ULONG WINAPI
IShellFolder_fnAddRef(IShellFolder2
* iface
)
592 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
595 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
597 return IUnknown_AddRef(This
->pUnkOuter
);
600 /**************************************************************************
601 * IShellFolder_fnRelease
603 static ULONG WINAPI
IShellFolder_fnRelease(IShellFolder2
* iface
)
605 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
608 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
610 return IUnknown_Release(This
->pUnkOuter
);
613 /**************************************************************************
614 * IShellFolder_fnParseDisplayName
616 * HWND hwndOwner, //[in ] Parent window for any message's
617 * LPBC pbc, //[in ] reserved
618 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
619 * ULONG* pchEaten, //[out] (unicode) characters processed
620 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
621 * ULONG* pdwAttributes //[out] items attributes
624 * every folder tries to parse only its own (the leftmost) pidl and creates a
625 * subfolder to evaluate the remaining parts
626 * now we can parse into namespaces implemented by shell extensions
628 * behaviour on win98: lpszDisplayName=NULL -> chrash
629 * lpszDisplayName="" -> returns mycoputer-pidl
632 * pdwAttributes: not set
633 * pchEaten: not set like in windows
635 static HRESULT WINAPI
IShellFolder_fnParseDisplayName(
636 IShellFolder2
* iface
,
639 LPOLESTR lpszDisplayName
,
642 DWORD
*pdwAttributes
)
644 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
646 HRESULT hr
= E_OUTOFMEMORY
;
648 WCHAR szElement
[MAX_PATH
];
649 CHAR szTempA
[MAX_PATH
], szPath
[MAX_PATH
];
650 LPITEMIDLIST pidlTemp
=NULL
;
652 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
653 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
654 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
656 if (!lpszDisplayName
|| !ppidl
) return E_INVALIDARG
;
658 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
660 if (*lpszDisplayName
)
662 /* get the next element */
663 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
665 /* build the full pathname to the element */
666 WideCharToMultiByte( CP_ACP
, 0, szElement
, -1, szTempA
, MAX_PATH
, NULL
, NULL
);
667 strcpy(szPath
, This
->sMyPath
);
668 PathAddBackslashA(szPath
);
669 strcat(szPath
, szTempA
);
672 pidlTemp
= SHSimpleIDListFromPathA(szPath
);
676 /* try to analyse the next element */
677 if (szNext
&& *szNext
)
679 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
683 if (pdwAttributes
&& *pdwAttributes
)
685 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
686 /* WIN32_FIND_DATAA fd;
687 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
688 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
689 *pdwAttributes &= ~SFGAO_FOLDER;
690 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
691 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
704 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This
, ppidl
? *ppidl
:0, hr
);
709 /**************************************************************************
710 * IShellFolder_fnEnumObjects
712 * HWND hwndOwner, //[in ] Parent Window
713 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
714 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
716 static HRESULT WINAPI
IShellFolder_fnEnumObjects(
717 IShellFolder2
* iface
,
720 LPENUMIDLIST
* ppEnumIDList
)
722 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
724 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
726 *ppEnumIDList
= NULL
;
727 *ppEnumIDList
= IEnumIDList_Constructor (This
->sMyPath
, dwFlags
, EIDL_FILE
);
729 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
731 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
736 /**************************************************************************
737 * IShellFolder_fnBindToObject
739 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
740 * LPBC pbc, //[in ] reserved
741 * REFIID riid, //[in ] Initial Interface
742 * LPVOID* ppvObject //[out] Interface*
744 static HRESULT WINAPI
IShellFolder_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
745 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
747 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
749 IShellFolder
*pShellFolder
, *pSubFolder
;
750 IPersistFolder
*pPersistFolder
;
751 LPITEMIDLIST absPidl
;
754 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
756 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
760 if ((iid
=_ILGetGUIDPointer(pidl
)))
762 /* we have to create a alien folder */
763 if ( SUCCEEDED(SHCoCreateInstance(NULL
, iid
, NULL
, riid
, (LPVOID
*)&pShellFolder
))
764 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
)))
766 absPidl
= ILCombine (This
->absPidl
, pidl
);
767 IPersistFolder_Initialize(pPersistFolder
, absPidl
);
768 IPersistFolder_Release(pPersistFolder
);
778 LPITEMIDLIST pidltemp
= ILCloneFirst(pidl
);
779 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
783 if (_ILIsPidlSimple(pidl
))
785 if(IsEqualIID(riid
, &IID_IShellFolder
))
787 *ppvOut
= pShellFolder
;
792 hr
= IShellFolder_QueryInterface(pShellFolder
, riid
, ppvOut
);
793 IShellFolder_Release(pShellFolder
);
798 hr
= IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
,
799 riid
, (LPVOID
)&pSubFolder
);
800 IShellFolder_Release(pShellFolder
);
801 *ppvOut
= pSubFolder
;
804 TRACE("-- (%p) returning (%p) %08lx\n",This
, *ppvOut
, hr
);
809 /**************************************************************************
810 * IShellFolder_fnBindToStorage
812 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
813 * LPBC pbc, //[in ] reserved
814 * REFIID riid, //[in ] Initial storage interface
815 * LPVOID* ppvObject //[out] Interface* returned
817 static HRESULT WINAPI
IShellFolder_fnBindToStorage(
818 IShellFolder2
* iface
,
824 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
826 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
827 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
833 /**************************************************************************
834 * IShellFolder_fnCompareIDs
837 * LPARAM lParam, //[in ] Column?
838 * LPCITEMIDLIST pidl1, //[in ] simple pidl
839 * LPCITEMIDLIST pidl2) //[in ] simple pidl
842 * Special case - If one of the items is a Path and the other is a File,
843 * always make the Path come before the File.
846 * use SCODE_CODE() on the return value to get the result
849 static HRESULT WINAPI
IShellFolder_fnCompareIDs(
850 IShellFolder2
* iface
,
855 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
857 CHAR szTemp1
[MAX_PATH
];
858 CHAR szTemp2
[MAX_PATH
];
861 HRESULT hr
= E_OUTOFMEMORY
;
862 LPCITEMIDLIST pidlTemp
;
865 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This
,lParam
,pidl1
,pidl2
);
869 if (!pidl1
&& !pidl2
)
871 hr
= ResultFromShort(0);
875 hr
= ResultFromShort(-1);
879 hr
= ResultFromShort(1);
884 pd1
= _ILGetDataPointer(pidl1
);
885 pd2
= _ILGetDataPointer(pidl2
);
887 /* compate the types. sort order is the PT_* constant */
888 pt1
= ( pd1
? pd1
->type
: PT_DESKTOP
);
889 pt2
= ( pd2
? pd2
->type
: PT_DESKTOP
);
893 hr
= ResultFromShort(pt1
-pt2
);
895 else /* same type of pidl */
897 _ILSimpleGetText(pidl1
, szTemp1
, MAX_PATH
);
898 _ILSimpleGetText(pidl2
, szTemp2
, MAX_PATH
);
899 nReturn
= strcasecmp(szTemp1
, szTemp2
);
901 if (nReturn
== 0) /* first pidl different ? */
903 pidl1
= ILGetNext(pidl1
);
905 if (pidl1
&& pidl1
->mkid
.cb
) /* go deeper? */
907 pidlTemp
= ILCloneFirst(pidl1
);
908 pidl2
= ILGetNext(pidl2
);
910 hr
= IShellFolder_BindToObject(iface
, pidlTemp
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psf
);
913 nReturn
= IShellFolder_CompareIDs(psf
, 0, pidl1
, pidl2
);
914 IShellFolder_Release(psf
);
915 hr
= ResultFromShort(nReturn
);
919 else /* no deeper on #1 */
921 pidl2
= ILGetNext(pidl2
);
922 if (pidl2
&& pidl2
->mkid
.cb
) /* go deeper on #2 ? */
923 hr
= ResultFromShort(-1); /* two different */
925 hr
= ResultFromShort(nReturn
); /* two equal simple pidls */
930 hr
= ResultFromShort(nReturn
); /* two different simple pidls */
935 TRACE("-- res=0x%08lx\n", hr
);
939 /**************************************************************************
940 * IShellFolder_fnCreateViewObject
942 static HRESULT WINAPI
IShellFolder_fnCreateViewObject(
943 IShellFolder2
* iface
,
948 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
950 LPSHELLVIEW pShellView
;
951 HRESULT hr
= E_INVALIDARG
;
953 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
959 if(IsEqualIID(riid
, &IID_IDropTarget
))
961 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, ppvOut
);
963 else if(IsEqualIID(riid
, &IID_IContextMenu
))
965 FIXME("IContextMenu not implemented\n");
968 else if(IsEqualIID(riid
, &IID_IShellView
))
970 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
973 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
974 IShellView_Release(pShellView
);
978 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
982 /**************************************************************************
983 * IShellFolder_fnGetAttributesOf
986 * UINT cidl, //[in ] num elements in pidl array
987 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
988 * ULONG* rgfInOut) //[out] result array
991 static HRESULT WINAPI
IShellFolder_fnGetAttributesOf(
992 IShellFolder2
* iface
,
994 LPCITEMIDLIST
*apidl
,
997 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1001 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
1003 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
1004 return E_INVALIDARG
;
1006 while (cidl
> 0 && *apidl
)
1009 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
1014 TRACE("-- result=0x%08lx\n",*rgfInOut
);
1018 /**************************************************************************
1019 * IShellFolder_fnGetUIObjectOf
1022 * HWND hwndOwner, //[in ] Parent window for any output
1023 * UINT cidl, //[in ] array size
1024 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1025 * REFIID riid, //[in ] Requested Interface
1026 * UINT* prgfInOut, //[ ] reserved
1027 * LPVOID* ppvObject) //[out] Resulting Interface
1030 * This function gets asked to return "view objects" for one or more (multiple select)
1032 * The viewobject typically is an COM object with one of the following interfaces:
1033 * IExtractIcon,IDataObject,IContextMenu
1034 * In order to support icon positions in the default Listview your DataObject
1035 * must implement the SetData method (in addition to GetData :) - the shell passes
1036 * a barely documented "Icon positions" structure to SetData when the drag starts,
1037 * and GetData's it if the drop is in another explorer window that needs the positions.
1039 static HRESULT WINAPI
IShellFolder_fnGetUIObjectOf(
1040 IShellFolder2
* iface
,
1043 LPCITEMIDLIST
* apidl
,
1048 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1051 IUnknown
* pObj
= NULL
;
1052 HRESULT hr
= E_INVALIDARG
;
1054 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1055 This
,hwndOwner
,cidl
,apidl
,debugstr_guid(riid
),prgfInOut
,ppvOut
);
1061 if(IsEqualIID(riid
, &IID_IContextMenu
) && (cidl
>= 1))
1063 pObj
= (LPUNKNOWN
)ISvItemCm_Constructor((IShellFolder
*)iface
, This
->absPidl
, apidl
, cidl
);
1066 else if (IsEqualIID(riid
, &IID_IDataObject
) &&(cidl
>= 1))
1068 pObj
= (LPUNKNOWN
)IDataObject_Constructor (hwndOwner
, This
->absPidl
, apidl
, cidl
);
1071 else if (IsEqualIID(riid
, &IID_IExtractIconA
) && (cidl
== 1))
1073 pidl
= ILCombine(This
->absPidl
,apidl
[0]);
1074 pObj
= (LPUNKNOWN
)IExtractIconA_Constructor( pidl
);
1078 else if (IsEqualIID(riid
, &IID_IDropTarget
) && (cidl
>= 1))
1080 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, (LPVOID
*)&pObj
);
1092 TRACE("(%p)->hr=0x%08lx\n",This
, hr
);
1096 /**************************************************************************
1097 * IShellFolder_fnGetDisplayNameOf
1098 * Retrieves the display name for the specified file object or subfolder
1101 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1102 * DWORD dwFlags, //[in ] SHGNO formatting flags
1103 * LPSTRRET lpName) //[out] Returned display name
1106 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1108 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1109 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1111 static HRESULT WINAPI
IShellFolder_fnGetDisplayNameOf(
1112 IShellFolder2
* iface
,
1117 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1119 CHAR szPath
[MAX_PATH
]= "";
1123 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1126 if(!pidl
|| !strRet
) return E_INVALIDARG
;
1128 bSimplePidl
= _ILIsPidlSimple(pidl
);
1130 /* take names of special folders only if its only this folder */
1131 if (_ILIsSpecialFolder(pidl
))
1135 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
1140 if (!(dwFlags
& SHGDN_INFOLDER
) && (dwFlags
& SHGDN_FORPARSING
) && This
->sMyPath
)
1142 strcpy (szPath
, This
->sMyPath
); /* get path to root*/
1143 PathAddBackslashA(szPath
);
1144 len
= strlen(szPath
);
1146 _ILSimpleGetText(pidl
, szPath
+ len
, MAX_PATH
- len
); /* append my own path */
1149 if ( (dwFlags
& SHGDN_FORPARSING
) && !bSimplePidl
) /* go deeper if needed */
1151 PathAddBackslashA(szPath
);
1152 len
= strlen(szPath
);
1154 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
+ len
, MAX_PATH
- len
)))
1155 return E_OUTOFMEMORY
;
1157 strRet
->uType
= STRRET_CSTRA
;
1158 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1160 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1164 /**************************************************************************
1165 * IShellFolder_fnSetNameOf
1166 * Changes the name of a file object or subfolder, possibly changing its item
1167 * identifier in the process.
1170 * HWND hwndOwner, //[in ] Owner window for output
1171 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1172 * LPCOLESTR lpszName, //[in ] the items new display name
1173 * DWORD dwFlags, //[in ] SHGNO formatting flags
1174 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1176 static HRESULT WINAPI
IShellFolder_fnSetNameOf(
1177 IShellFolder2
* iface
,
1179 LPCITEMIDLIST pidl
, /*simple pidl*/
1182 LPITEMIDLIST
*pPidlOut
)
1184 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1185 char szSrc
[MAX_PATH
], szDest
[MAX_PATH
];
1187 BOOL bIsFolder
= _ILIsFolder(ILFindLastID(pidl
));
1189 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1190 This
,hwndOwner
,pidl
,debugstr_w(lpName
),dwFlags
,pPidlOut
);
1192 /* build source path */
1193 if (dwFlags
& SHGDN_INFOLDER
)
1195 strcpy(szSrc
, This
->sMyPath
);
1196 PathAddBackslashA(szSrc
);
1197 len
= strlen (szSrc
);
1198 _ILSimpleGetText(pidl
, szSrc
+len
, MAX_PATH
-len
);
1202 SHGetPathFromIDListA(pidl
, szSrc
);
1205 /* build destination path */
1206 strcpy(szDest
, This
->sMyPath
);
1207 PathAddBackslashA(szDest
);
1208 len
= strlen (szDest
);
1209 WideCharToMultiByte( CP_ACP
, 0, lpName
, -1, szDest
+len
, MAX_PATH
-len
, NULL
, NULL
);
1210 szDest
[MAX_PATH
-1] = 0;
1211 TRACE("src=%s dest=%s\n", szSrc
, szDest
);
1212 if ( MoveFileA(szSrc
, szDest
) )
1214 if (pPidlOut
) *pPidlOut
= SHSimpleIDListFromPathA(szDest
);
1215 SHChangeNotifyA( bIsFolder
?SHCNE_RENAMEFOLDER
:SHCNE_RENAMEITEM
, SHCNF_PATHA
, szSrc
, szDest
);
1221 static HRESULT WINAPI
IShellFolder_fnGetDefaultSearchGUID(
1222 IShellFolder2
* iface
,
1225 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1226 FIXME("(%p)\n",This
);
1229 static HRESULT WINAPI
IShellFolder_fnEnumSearches(
1230 IShellFolder2
* iface
,
1231 IEnumExtraSearch
**ppenum
)
1233 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1234 FIXME("(%p)\n",This
);
1237 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumn(
1238 IShellFolder2
* iface
,
1243 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1245 TRACE("(%p)\n",This
);
1247 if (pSort
) *pSort
= 0;
1248 if (pDisplay
) *pDisplay
= 0;
1252 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumnState(
1253 IShellFolder2
* iface
,
1257 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1259 TRACE("(%p)\n",This
);
1261 if (!pcsFlags
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1263 *pcsFlags
= GenericSFHeader
[iColumn
].pcsFlags
;
1267 static HRESULT WINAPI
IShellFolder_fnGetDetailsEx(
1268 IShellFolder2
* iface
,
1270 const SHCOLUMNID
*pscid
,
1273 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1274 FIXME("(%p)\n",This
);
1278 static HRESULT WINAPI
IShellFolder_fnGetDetailsOf(
1279 IShellFolder2
* iface
,
1284 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1285 HRESULT hr
= E_FAIL
;
1287 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
1289 if (!psd
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1293 /* the header titles */
1294 psd
->fmt
= GenericSFHeader
[iColumn
].fmt
;
1295 psd
->cxChar
= GenericSFHeader
[iColumn
].cxChar
;
1296 psd
->str
.uType
= STRRET_CSTRA
;
1297 LoadStringA(shell32_hInstance
, GenericSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
1302 /* the data from the pidl */
1306 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
1309 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1312 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1315 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1317 case 4: /* attributes */
1318 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1322 psd
->str
.uType
= STRRET_CSTRA
;
1327 static HRESULT WINAPI
IShellFolder_fnMapNameToSCID(
1328 IShellFolder2
* iface
,
1332 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1333 FIXME("(%p)\n",This
);
1337 static ICOM_VTABLE(IShellFolder2
) sfvt
=
1339 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1340 IShellFolder_fnQueryInterface
,
1341 IShellFolder_fnAddRef
,
1342 IShellFolder_fnRelease
,
1343 IShellFolder_fnParseDisplayName
,
1344 IShellFolder_fnEnumObjects
,
1345 IShellFolder_fnBindToObject
,
1346 IShellFolder_fnBindToStorage
,
1347 IShellFolder_fnCompareIDs
,
1348 IShellFolder_fnCreateViewObject
,
1349 IShellFolder_fnGetAttributesOf
,
1350 IShellFolder_fnGetUIObjectOf
,
1351 IShellFolder_fnGetDisplayNameOf
,
1352 IShellFolder_fnSetNameOf
,
1355 IShellFolder_fnGetDefaultSearchGUID
,
1356 IShellFolder_fnEnumSearches
,
1357 IShellFolder_fnGetDefaultColumn
,
1358 IShellFolder_fnGetDefaultColumnState
,
1359 IShellFolder_fnGetDetailsEx
,
1360 IShellFolder_fnGetDetailsOf
,
1361 IShellFolder_fnMapNameToSCID
1364 /****************************************************************************
1365 * ISFHelper for IShellFolder implementation
1368 static HRESULT WINAPI
ISFHelper_fnQueryInterface(
1373 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1375 TRACE("(%p)\n", This
);
1377 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
1380 static ULONG WINAPI
ISFHelper_fnAddRef(
1383 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1385 TRACE("(%p)\n", This
);
1387 return IUnknown_AddRef(This
->pUnkOuter
);
1390 static ULONG WINAPI
ISFHelper_fnRelease(
1393 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1395 TRACE("(%p)\n", This
);
1397 return IUnknown_Release(This
->pUnkOuter
);
1401 /****************************************************************************
1402 * ISFHelper_fnAddFolder
1404 * creates a unique folder name
1407 static HRESULT WINAPI
ISFHelper_fnGetUniqueName(
1412 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1413 IEnumIDList
* penum
;
1415 char szText
[MAX_PATH
];
1416 char * szNewFolder
= "New Folder";
1418 TRACE("(%p)(%s %u)\n", This
, lpName
, uLen
);
1420 if (uLen
< strlen(szNewFolder
) + 4) return E_POINTER
;
1422 strcpy(lpName
, szNewFolder
);
1424 hr
= IShellFolder_fnEnumObjects(_IShellFolder2_(This
), 0, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
| SHCONTF_INCLUDEHIDDEN
, &penum
);
1431 next
: IEnumIDList_Reset(penum
);
1432 while(S_OK
== IEnumIDList_Next(penum
, 1, &pidl
, &dwFetched
) && dwFetched
)
1434 _ILSimpleGetText(pidl
, szText
, MAX_PATH
);
1435 if (0 == strcasecmp(szText
, lpName
))
1437 sprintf(lpName
, "%s %d", szNewFolder
, i
++);
1447 IEnumIDList_Release(penum
);
1452 /****************************************************************************
1453 * ISFHelper_fnAddFolder
1455 * adds a new folder.
1458 static HRESULT WINAPI
ISFHelper_fnAddFolder(
1462 LPITEMIDLIST
* ppidlOut
)
1464 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1465 char lpstrNewDir
[MAX_PATH
];
1467 HRESULT hres
= E_FAIL
;
1469 TRACE("(%p)(%s %p)\n", This
, lpName
, ppidlOut
);
1471 strcpy(lpstrNewDir
, This
->sMyPath
);
1472 PathAddBackslashA(lpstrNewDir
);
1473 strcat(lpstrNewDir
, lpName
);
1475 bRes
= CreateDirectoryA(lpstrNewDir
, NULL
);
1479 LPITEMIDLIST pidl
, pidlitem
;
1481 pidlitem
= SHSimpleIDListFromPathA(lpstrNewDir
);
1483 pidl
= ILCombine(This
->absPidl
, pidlitem
);
1484 SHChangeNotifyA(SHCNE_MKDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1487 if (ppidlOut
) *ppidlOut
= pidlitem
;
1492 char lpstrText
[128+MAX_PATH
];
1493 char lpstrTempText
[128];
1494 char lpstrCaption
[256];
1496 /* Cannot Create folder because of permissions */
1497 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_DENIED
, lpstrTempText
, sizeof(lpstrTempText
));
1498 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_CAPTION
, lpstrCaption
, sizeof(lpstrCaption
));
1499 sprintf(lpstrText
,lpstrTempText
, lpstrNewDir
);
1500 MessageBoxA(hwnd
,lpstrText
, lpstrCaption
, MB_OK
| MB_ICONEXCLAMATION
);
1506 /****************************************************************************
1507 * ISFHelper_fnDeleteItems
1509 * deletes items in folder
1511 static HRESULT WINAPI
ISFHelper_fnDeleteItems(
1514 LPCITEMIDLIST
* apidl
)
1516 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1518 char szPath
[MAX_PATH
];
1519 BOOL bConfirm
= TRUE
;
1521 TRACE("(%p)(%u %p)\n", This
, cidl
, apidl
);
1523 /* deleting multiple items so give a slightly different warning */
1527 snprintf(tmp
, sizeof(tmp
), "%d", cidl
);
1528 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM
, tmp
))
1533 for(i
=0; i
< cidl
; i
++)
1535 strcpy(szPath
, This
->sMyPath
);
1536 PathAddBackslashA(szPath
);
1537 _ILSimpleGetText(apidl
[i
], szPath
+strlen(szPath
), MAX_PATH
);
1539 if (_ILIsFolder(apidl
[i
]))
1542 TRACE("delete %s\n", szPath
);
1543 if (! SHELL_DeleteDirectoryA(szPath
, bConfirm
))
1545 TRACE("delete %s failed, bConfirm=%d\n", szPath
, bConfirm
);
1548 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1549 SHChangeNotifyA(SHCNE_RMDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1552 else if (_ILIsValue(apidl
[i
]))
1556 TRACE("delete %s\n", szPath
);
1557 if (! SHELL_DeleteFileA(szPath
, bConfirm
))
1559 TRACE("delete %s failed, bConfirm=%d\n", szPath
, bConfirm
);
1562 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1563 SHChangeNotifyA(SHCNE_DELETE
, SHCNF_IDLIST
, pidl
, NULL
);
1571 /****************************************************************************
1572 * ISFHelper_fnCopyItems
1574 * copies items to this folder
1576 static HRESULT WINAPI
ISFHelper_fnCopyItems(
1578 IShellFolder
* pSFFrom
,
1580 LPCITEMIDLIST
*apidl
)
1583 IPersistFolder2
* ppf2
=NULL
;
1584 char szSrcPath
[MAX_PATH
], szDstPath
[MAX_PATH
];
1585 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1587 TRACE("(%p)->(%p,%u,%p)\n", This
, pSFFrom
, cidl
, apidl
);
1589 IShellFolder_QueryInterface(pSFFrom
, &IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
1593 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2
, &pidl
)))
1595 for (i
=0; i
<cidl
; i
++)
1597 SHGetPathFromIDListA(pidl
, szSrcPath
);
1598 PathAddBackslashA(szSrcPath
);
1599 _ILSimpleGetText(apidl
[i
], szSrcPath
+strlen(szSrcPath
), MAX_PATH
);
1601 strcpy(szDstPath
, This
->sMyPath
);
1602 PathAddBackslashA(szDstPath
);
1603 _ILSimpleGetText(apidl
[i
], szDstPath
+strlen(szDstPath
), MAX_PATH
);
1604 MESSAGE("would copy %s to %s\n", szSrcPath
, szDstPath
);
1608 IPersistFolder2_Release(ppf2
);
1613 static ICOM_VTABLE(ISFHelper
) shvt
=
1615 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1616 ISFHelper_fnQueryInterface
,
1618 ISFHelper_fnRelease
,
1619 ISFHelper_fnGetUniqueName
,
1620 ISFHelper_fnAddFolder
,
1621 ISFHelper_fnDeleteItems
,
1622 ISFHelper_fnCopyItems
,
1625 /***********************************************************************
1626 * [Desktopfolder] IShellFolder implementation
1628 static struct ICOM_VTABLE(IShellFolder2
) sfdvt
;
1630 static shvheader DesktopSFHeader
[] =
1632 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
1633 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1634 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1635 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
1636 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
1638 #define DESKTOPSHELLVIEWCOLUMNS 5
1640 /**************************************************************************
1641 * ISF_Desktop_Constructor
1644 IShellFolder
* ISF_Desktop_Constructor()
1646 IGenericSFImpl
* sf
;
1648 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
1650 ICOM_VTBL(sf
)=&unkvt
;
1651 sf
->lpvtblShellFolder
=&sfdvt
;
1652 sf
->absPidl
=_ILCreateDesktop(); /* my qualified pidl */
1653 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
1658 return _IShellFolder_(sf
);
1661 /**************************************************************************
1662 * ISF_Desktop_fnQueryInterface
1664 * NOTES supports not IPersist/IPersistFolder
1666 static HRESULT WINAPI
ISF_Desktop_fnQueryInterface(
1667 IShellFolder2
* iface
,
1671 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1673 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
1677 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
1679 *ppvObj
= _IUnknown_(This
);
1681 else if(IsEqualIID(riid
, &IID_IShellFolder
)) /*IShellFolder*/
1683 *ppvObj
= _IShellFolder_(This
);
1685 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) /*IShellFolder2*/
1687 *ppvObj
= _IShellFolder_(This
);
1692 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
1693 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
1696 TRACE("-- Interface: E_NOINTERFACE\n");
1697 return E_NOINTERFACE
;
1700 /**************************************************************************
1701 * ISF_Desktop_fnParseDisplayName
1704 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1707 static HRESULT WINAPI
ISF_Desktop_fnParseDisplayName(
1708 IShellFolder2
* iface
,
1711 LPOLESTR lpszDisplayName
,
1713 LPITEMIDLIST
*ppidl
,
1714 DWORD
*pdwAttributes
)
1716 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1718 LPCWSTR szNext
=NULL
;
1719 LPITEMIDLIST pidlTemp
=NULL
;
1720 HRESULT hr
=E_OUTOFMEMORY
;
1722 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1723 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
1724 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
1727 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
1729 /* FIXME no real parsing implemented */
1730 pidlTemp
= _ILCreateMyComputer();
1731 szNext
= lpszDisplayName
;
1733 if (szNext
&& *szNext
)
1735 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
1741 if (pdwAttributes
&& *pdwAttributes
)
1743 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
1749 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
1754 /**************************************************************************
1755 * ISF_Desktop_fnEnumObjects
1757 static HRESULT WINAPI
ISF_Desktop_fnEnumObjects(
1758 IShellFolder2
* iface
,
1761 LPENUMIDLIST
* ppEnumIDList
)
1763 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1765 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
1767 *ppEnumIDList
= NULL
;
1768 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_DESK
);
1770 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
1772 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
1777 /**************************************************************************
1778 * ISF_Desktop_fnBindToObject
1780 static HRESULT WINAPI
ISF_Desktop_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
1781 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
1783 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1785 IShellFolder
*pShellFolder
, *pSubFolder
;
1788 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1789 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
1793 if ((clsid
=_ILGetGUIDPointer(pidl
)))
1795 if ( IsEqualIID(clsid
, &CLSID_MyComputer
))
1797 pShellFolder
= ISF_MyComputer_Constructor();
1801 /* shell extension */
1802 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
1804 return E_INVALIDARG
;
1810 /* file system folder on the desktop */
1811 LPITEMIDLIST deskpidl
, firstpidl
, completepidl
;
1812 IPersistFolder
* ppf
;
1815 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY
, &deskpidl
);
1816 firstpidl
= ILCloneFirst(pidl
);
1817 completepidl
= ILCombine(deskpidl
, firstpidl
);
1819 pShellFolder
= IShellFolder_Constructor(NULL
, NULL
);
1820 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&ppf
)))
1822 IPersistFolder_Initialize(ppf
, completepidl
);
1823 IPersistFolder_Release(ppf
);
1825 ILFree(completepidl
);
1830 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
1832 *ppvOut
= pShellFolder
;
1835 else /* go deeper */
1837 hr
= IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, riid
, (LPVOID
)&pSubFolder
);
1838 IShellFolder_Release(pShellFolder
);
1839 *ppvOut
= pSubFolder
;
1842 TRACE("-- (%p) returning (%p) %08lx\n",This
, *ppvOut
, hr
);
1847 /**************************************************************************
1848 * ISF_Desktop_fnCreateViewObject
1850 static HRESULT WINAPI
ISF_Desktop_fnCreateViewObject( IShellFolder2
* iface
,
1851 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
1853 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1855 LPSHELLVIEW pShellView
;
1856 HRESULT hr
= E_INVALIDARG
;
1858 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
1864 if(IsEqualIID(riid
, &IID_IDropTarget
))
1866 WARN("IDropTarget not implemented\n");
1869 else if(IsEqualIID(riid
, &IID_IContextMenu
))
1871 WARN("IContextMenu not implemented\n");
1874 else if(IsEqualIID(riid
, &IID_IShellView
))
1876 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
1879 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
1880 IShellView_Release(pShellView
);
1884 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
1888 /**************************************************************************
1889 * ISF_Desktop_fnGetAttributesOf
1891 static HRESULT WINAPI
ISF_Desktop_fnGetAttributesOf(
1892 IShellFolder2
* iface
,
1894 LPCITEMIDLIST
*apidl
,
1897 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1901 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
, *rgfInOut
);
1903 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
1904 return E_INVALIDARG
;
1906 while (cidl
> 0 && *apidl
)
1909 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
1914 TRACE("-- result=0x%08lx\n",*rgfInOut
);
1919 /**************************************************************************
1920 * ISF_Desktop_fnGetDisplayNameOf
1923 * special case: pidl = null gives desktop-name back
1925 static HRESULT WINAPI
ISF_Desktop_fnGetDisplayNameOf(
1926 IShellFolder2
* iface
,
1931 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1933 CHAR szPath
[MAX_PATH
]= "";
1935 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1938 if(!strRet
) return E_INVALIDARG
;
1942 HCR_GetClassName(&CLSID_ShellDesktop
, szPath
, MAX_PATH
);
1944 else if ( _ILIsPidlSimple(pidl
) )
1946 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
1950 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
, MAX_PATH
)))
1951 return E_OUTOFMEMORY
;
1953 strRet
->uType
= STRRET_CSTRA
;
1954 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1957 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1961 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultSearchGUID(
1962 IShellFolder2
* iface
,
1965 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1966 FIXME("(%p)\n",This
);
1969 static HRESULT WINAPI
ISF_Desktop_fnEnumSearches(
1970 IShellFolder2
* iface
,
1971 IEnumExtraSearch
**ppenum
)
1973 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1974 FIXME("(%p)\n",This
);
1977 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumn(
1978 IShellFolder2
* iface
,
1983 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1985 TRACE("(%p)\n",This
);
1987 if (pSort
) *pSort
= 0;
1988 if (pDisplay
) *pDisplay
= 0;
1992 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumnState(
1993 IShellFolder2
* iface
,
1997 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1999 TRACE("(%p)\n",This
);
2001 if (!pcsFlags
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2003 *pcsFlags
= DesktopSFHeader
[iColumn
].pcsFlags
;
2007 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsEx(
2008 IShellFolder2
* iface
,
2010 const SHCOLUMNID
*pscid
,
2013 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2014 FIXME("(%p)\n",This
);
2018 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsOf(
2019 IShellFolder2
* iface
,
2024 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2025 HRESULT hr
= E_FAIL
;;
2027 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
2029 if (!psd
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2033 psd
->fmt
= DesktopSFHeader
[iColumn
].fmt
;
2034 psd
->cxChar
= DesktopSFHeader
[iColumn
].cxChar
;
2035 psd
->str
.uType
= STRRET_CSTRA
;
2036 LoadStringA(shell32_hInstance
, DesktopSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
2041 /* the data from the pidl */
2045 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
2048 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2051 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2054 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2056 case 4: /* attributes */
2057 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2061 psd
->str
.uType
= STRRET_CSTRA
;
2066 static HRESULT WINAPI
ISF_Desktop_fnMapNameToSCID(
2067 IShellFolder2
* iface
,
2071 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2072 FIXME("(%p)\n",This
);
2076 static ICOM_VTABLE(IShellFolder2
) sfdvt
=
2078 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2079 ISF_Desktop_fnQueryInterface
,
2080 IShellFolder_fnAddRef
,
2081 IShellFolder_fnRelease
,
2082 ISF_Desktop_fnParseDisplayName
,
2083 ISF_Desktop_fnEnumObjects
,
2084 ISF_Desktop_fnBindToObject
,
2085 IShellFolder_fnBindToStorage
,
2086 IShellFolder_fnCompareIDs
,
2087 ISF_Desktop_fnCreateViewObject
,
2088 ISF_Desktop_fnGetAttributesOf
,
2089 IShellFolder_fnGetUIObjectOf
,
2090 ISF_Desktop_fnGetDisplayNameOf
,
2091 IShellFolder_fnSetNameOf
,
2094 ISF_Desktop_fnGetDefaultSearchGUID
,
2095 ISF_Desktop_fnEnumSearches
,
2096 ISF_Desktop_fnGetDefaultColumn
,
2097 ISF_Desktop_fnGetDefaultColumnState
,
2098 ISF_Desktop_fnGetDetailsEx
,
2099 ISF_Desktop_fnGetDetailsOf
,
2100 ISF_Desktop_fnMapNameToSCID
2104 /***********************************************************************
2105 * IShellFolder [MyComputer] implementation
2108 static struct ICOM_VTABLE(IShellFolder2
) sfmcvt
;
2110 static shvheader MyComputerSFHeader
[] =
2112 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
2113 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2114 { IDS_SHV_COLUMN6
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2115 { IDS_SHV_COLUMN7
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2117 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2119 /**************************************************************************
2120 * ISF_MyComputer_Constructor
2122 static IShellFolder
* ISF_MyComputer_Constructor(void)
2124 IGenericSFImpl
* sf
;
2126 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
2129 ICOM_VTBL(sf
)=&unkvt
;
2130 sf
->lpvtblShellFolder
=&sfmcvt
;
2131 sf
->lpvtblPersistFolder2
= &psfvt
;
2132 sf
->pclsid
= (CLSID
*)&CLSID_SFMyComp
;
2133 sf
->absPidl
=_ILCreateMyComputer(); /* my qualified pidl */
2134 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
2139 return _IShellFolder_(sf
);
2142 /**************************************************************************
2143 * ISF_MyComputer_fnParseDisplayName
2145 static HRESULT WINAPI
ISF_MyComputer_fnParseDisplayName(
2146 IShellFolder2
* iface
,
2149 LPOLESTR lpszDisplayName
,
2151 LPITEMIDLIST
*ppidl
,
2152 DWORD
*pdwAttributes
)
2154 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2156 HRESULT hr
= E_OUTOFMEMORY
;
2157 LPCWSTR szNext
=NULL
;
2158 WCHAR szElement
[MAX_PATH
];
2159 CHAR szTempA
[MAX_PATH
];
2160 LPITEMIDLIST pidlTemp
;
2162 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2163 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
2164 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
2167 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
2169 /* do we have an absolute path name ? */
2170 if (PathGetDriveNumberW(lpszDisplayName
) >= 0 &&
2171 lpszDisplayName
[2] == (WCHAR
)'\\')
2173 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
2174 WideCharToMultiByte( CP_ACP
, 0, szElement
, -1, szTempA
, MAX_PATH
, NULL
, NULL
);
2175 pidlTemp
= _ILCreateDrive(szTempA
);
2177 if (szNext
&& *szNext
)
2179 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
2183 if (pdwAttributes
&& *pdwAttributes
)
2185 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
2192 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
2197 /**************************************************************************
2198 * ISF_MyComputer_fnEnumObjects
2200 static HRESULT WINAPI
ISF_MyComputer_fnEnumObjects(
2201 IShellFolder2
* iface
,
2204 LPENUMIDLIST
* ppEnumIDList
)
2206 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2208 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
2210 *ppEnumIDList
= NULL
;
2211 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_MYCOMP
);
2213 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
2215 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
2220 /**************************************************************************
2221 * ISF_MyComputer_fnBindToObject
2223 static HRESULT WINAPI
ISF_MyComputer_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
2224 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
2226 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2228 IShellFolder
*pShellFolder
, *pSubFolder
;
2229 LPITEMIDLIST pidltemp
;
2232 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2233 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
2235 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
2239 if ((clsid
=_ILGetGUIDPointer(pidl
)) && !IsEqualIID(clsid
, &CLSID_MyComputer
))
2241 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
2248 if (!_ILIsDrive(pidl
)) return E_INVALIDARG
;
2250 pidltemp
= ILCloneFirst(pidl
);
2251 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
2255 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
2257 *ppvOut
= pShellFolder
;
2260 else /* go deeper */
2262 hr
= IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
,
2263 riid
, (LPVOID
)&pSubFolder
);
2264 IShellFolder_Release(pShellFolder
);
2265 *ppvOut
= pSubFolder
;
2268 TRACE("-- (%p) returning (%p) %08lx\n",This
, *ppvOut
, hr
);
2273 /**************************************************************************
2274 * ISF_MyComputer_fnCreateViewObject
2276 static HRESULT WINAPI
ISF_MyComputer_fnCreateViewObject( IShellFolder2
* iface
,
2277 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
2279 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2281 LPSHELLVIEW pShellView
;
2282 HRESULT hr
= E_INVALIDARG
;
2284 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
2290 if(IsEqualIID(riid
, &IID_IDropTarget
))
2292 WARN("IDropTarget not implemented\n");
2295 else if(IsEqualIID(riid
, &IID_IContextMenu
))
2297 WARN("IContextMenu not implemented\n");
2300 else if(IsEqualIID(riid
, &IID_IShellView
))
2302 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
2305 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
2306 IShellView_Release(pShellView
);
2310 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
2314 /**************************************************************************
2315 * ISF_MyComputer_fnGetAttributesOf
2317 static HRESULT WINAPI
ISF_MyComputer_fnGetAttributesOf(
2318 IShellFolder2
* iface
,
2320 LPCITEMIDLIST
*apidl
,
2323 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2327 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
2329 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
2330 return E_INVALIDARG
;
2332 while (cidl
> 0 && *apidl
)
2335 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
2340 TRACE("-- result=0x%08lx\n",*rgfInOut
);
2344 /**************************************************************************
2345 * ISF_MyComputer_fnGetDisplayNameOf
2348 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2349 * SHGDN_INFOLDER makes no sense.
2351 static HRESULT WINAPI
ISF_MyComputer_fnGetDisplayNameOf(
2352 IShellFolder2
* iface
,
2357 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2359 char szPath
[MAX_PATH
], szDrive
[18];
2363 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
2366 if(!strRet
) return E_INVALIDARG
;
2368 szPath
[0]=0x00; szDrive
[0]=0x00;
2371 bSimplePidl
= _ILIsPidlSimple(pidl
);
2373 if (_ILIsSpecialFolder(pidl
))
2375 /* take names of special folders only if its only this folder */
2378 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2383 if (!_ILIsDrive(pidl
))
2385 ERR("Wrong pidl type\n");
2386 return E_INVALIDARG
;
2389 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2391 /* long view "lw_name (C:)" */
2392 if ( bSimplePidl
&& !(dwFlags
& SHGDN_FORPARSING
))
2394 DWORD dwVolumeSerialNumber
,dwMaximumComponetLength
,dwFileSystemFlags
;
2396 GetVolumeInformationA(szPath
,szDrive
,12,&dwVolumeSerialNumber
,&dwMaximumComponetLength
,&dwFileSystemFlags
,NULL
,0);
2397 strcat (szDrive
," (");
2398 strncat (szDrive
, szPath
, 2);
2399 strcat (szDrive
,")");
2400 strcpy (szPath
, szDrive
);
2404 if (!bSimplePidl
) /* go deeper if needed */
2406 PathAddBackslashA(szPath
);
2407 len
= strlen(szPath
);
2409 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
| SHGDN_FORPARSING
, szPath
+ len
, MAX_PATH
- len
)))
2410 return E_OUTOFMEMORY
;
2412 strRet
->uType
= STRRET_CSTRA
;
2413 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
2416 TRACE("-- (%p)->(%s)\n", This
, szPath
);
2420 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultSearchGUID(
2421 IShellFolder2
* iface
,
2424 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2425 FIXME("(%p)\n",This
);
2428 static HRESULT WINAPI
ISF_MyComputer_fnEnumSearches(
2429 IShellFolder2
* iface
,
2430 IEnumExtraSearch
**ppenum
)
2432 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2433 FIXME("(%p)\n",This
);
2436 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumn(
2437 IShellFolder2
* iface
,
2442 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2444 TRACE("(%p)\n",This
);
2446 if (pSort
) *pSort
= 0;
2447 if (pDisplay
) *pDisplay
= 0;
2451 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumnState(
2452 IShellFolder2
* iface
,
2456 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2458 TRACE("(%p)\n",This
);
2460 if (!pcsFlags
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2462 *pcsFlags
= MyComputerSFHeader
[iColumn
].pcsFlags
;
2466 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsEx(
2467 IShellFolder2
* iface
,
2469 const SHCOLUMNID
*pscid
,
2472 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2473 FIXME("(%p)\n",This
);
2478 /* FIXME: drive size >4GB is rolling over */
2479 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsOf(
2480 IShellFolder2
* iface
,
2485 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2488 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
2490 if (!psd
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2494 psd
->fmt
= MyComputerSFHeader
[iColumn
].fmt
;
2495 psd
->cxChar
= MyComputerSFHeader
[iColumn
].cxChar
;
2496 psd
->str
.uType
= STRRET_CSTRA
;
2497 LoadStringA(shell32_hInstance
, MyComputerSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
2502 char szPath
[MAX_PATH
];
2503 ULARGE_INTEGER ulBytes
;
2505 psd
->str
.u
.cStr
[0] = 0x00;
2506 psd
->str
.uType
= STRRET_CSTRA
;
2510 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
2513 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2515 case 2: /* total size */
2516 if (_ILIsDrive(pidl
))
2518 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2519 GetDiskFreeSpaceExA(szPath
, NULL
, &ulBytes
, NULL
);
2520 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2523 case 3: /* free size */
2524 if (_ILIsDrive(pidl
))
2526 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2527 GetDiskFreeSpaceExA(szPath
, &ulBytes
, NULL
, NULL
);
2528 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2537 static HRESULT WINAPI
ISF_MyComputer_fnMapNameToSCID(
2538 IShellFolder2
* iface
,
2542 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2543 FIXME("(%p)\n",This
);
2547 static ICOM_VTABLE(IShellFolder2
) sfmcvt
=
2549 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2550 IShellFolder_fnQueryInterface
,
2551 IShellFolder_fnAddRef
,
2552 IShellFolder_fnRelease
,
2553 ISF_MyComputer_fnParseDisplayName
,
2554 ISF_MyComputer_fnEnumObjects
,
2555 ISF_MyComputer_fnBindToObject
,
2556 IShellFolder_fnBindToStorage
,
2557 IShellFolder_fnCompareIDs
,
2558 ISF_MyComputer_fnCreateViewObject
,
2559 ISF_MyComputer_fnGetAttributesOf
,
2560 IShellFolder_fnGetUIObjectOf
,
2561 ISF_MyComputer_fnGetDisplayNameOf
,
2562 IShellFolder_fnSetNameOf
,
2565 ISF_MyComputer_fnGetDefaultSearchGUID
,
2566 ISF_MyComputer_fnEnumSearches
,
2567 ISF_MyComputer_fnGetDefaultColumn
,
2568 ISF_MyComputer_fnGetDefaultColumnState
,
2569 ISF_MyComputer_fnGetDetailsEx
,
2570 ISF_MyComputer_fnGetDetailsOf
,
2571 ISF_MyComputer_fnMapNameToSCID
2575 /************************************************************************
2576 * ISFPersistFolder_QueryInterface (IUnknown)
2579 static HRESULT WINAPI
ISFPersistFolder2_QueryInterface(
2580 IPersistFolder2
* iface
,
2584 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2586 TRACE("(%p)\n", This
);
2588 return IUnknown_QueryInterface(This
->pUnkOuter
, iid
, ppvObj
);
2591 /************************************************************************
2592 * ISFPersistFolder_AddRef (IUnknown)
2595 static ULONG WINAPI
ISFPersistFolder2_AddRef(
2596 IPersistFolder2
* iface
)
2598 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2600 TRACE("(%p)\n", This
);
2602 return IUnknown_AddRef(This
->pUnkOuter
);
2605 /************************************************************************
2606 * ISFPersistFolder_Release (IUnknown)
2609 static ULONG WINAPI
ISFPersistFolder2_Release(
2610 IPersistFolder2
* iface
)
2612 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2614 TRACE("(%p)\n", This
);
2616 return IUnknown_Release(This
->pUnkOuter
);
2619 /************************************************************************
2620 * ISFPersistFolder_GetClassID (IPersist)
2622 static HRESULT WINAPI
ISFPersistFolder2_GetClassID(
2623 IPersistFolder2
* iface
,
2626 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2628 TRACE("(%p)\n", This
);
2630 if (!lpClassId
) return E_POINTER
;
2631 *lpClassId
= *This
->pclsid
;
2636 /************************************************************************
2637 * ISFPersistFolder_Initialize (IPersistFolder)
2640 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2642 static HRESULT WINAPI
ISFPersistFolder2_Initialize(
2643 IPersistFolder2
* iface
,
2646 char sTemp
[MAX_PATH
];
2647 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2649 TRACE("(%p)->(%p)\n", This
, pidl
);
2651 /* free the old stuff */
2654 SHFree(This
->absPidl
);
2655 This
->absPidl
= NULL
;
2659 SHFree(This
->sMyPath
);
2660 This
->sMyPath
= NULL
;
2664 This
->absPidl
= ILClone(pidl
);
2667 if (SHGetPathFromIDListA(pidl
, sTemp
))
2669 This
->sMyPath
= SHAlloc(strlen(sTemp
)+1);
2670 strcpy(This
->sMyPath
, sTemp
);
2673 TRACE("--(%p)->(%s)\n", This
, This
->sMyPath
);
2678 /**************************************************************************
2679 * IPersistFolder2_fnGetCurFolder
2681 static HRESULT WINAPI
ISFPersistFolder2_fnGetCurFolder(
2682 IPersistFolder2
* iface
,
2683 LPITEMIDLIST
* pidl
)
2685 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2687 TRACE("(%p)->(%p)\n",This
, pidl
);
2689 if (!pidl
) return E_POINTER
;
2691 *pidl
= ILClone(This
->absPidl
);
2696 static ICOM_VTABLE(IPersistFolder2
) psfvt
=
2698 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2699 ISFPersistFolder2_QueryInterface
,
2700 ISFPersistFolder2_AddRef
,
2701 ISFPersistFolder2_Release
,
2702 ISFPersistFolder2_GetClassID
,
2703 ISFPersistFolder2_Initialize
,
2704 ISFPersistFolder2_fnGetCurFolder
2707 /****************************************************************************
2708 * ISFDropTarget implementation
2710 static BOOL
ISFDropTarget_QueryDrop(
2715 DWORD dwEffect
= *pdwEffect
;
2717 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2719 *pdwEffect
= DROPEFFECT_NONE
;
2721 if (This
->fAcceptFmt
)
2722 { /* Does our interpretation of the keystate ... */
2723 *pdwEffect
= KeyStateToDropEffect(dwKeyState
);
2725 /* ... matches the desired effect ? */
2726 if (dwEffect
& *pdwEffect
)
2734 static HRESULT WINAPI
ISFDropTarget_QueryInterface(
2739 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2741 TRACE("(%p)\n", This
);
2743 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
2746 static ULONG WINAPI
ISFDropTarget_AddRef( IDropTarget
*iface
)
2748 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2750 TRACE("(%p)\n", This
);
2752 return IUnknown_AddRef(This
->pUnkOuter
);
2755 static ULONG WINAPI
ISFDropTarget_Release( IDropTarget
*iface
)
2757 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2759 TRACE("(%p)\n", This
);
2761 return IUnknown_Release(This
->pUnkOuter
);
2764 static HRESULT WINAPI
ISFDropTarget_DragEnter(
2766 IDataObject
*pDataObject
,
2773 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2775 TRACE("(%p)->(DataObject=%p)\n",This
,pDataObject
);
2777 InitFormatEtc(fmt
, This
->cfShellIDList
, TYMED_HGLOBAL
);
2779 This
->fAcceptFmt
= (S_OK
== IDataObject_QueryGetData(pDataObject
, &fmt
)) ? TRUE
: FALSE
;
2781 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2786 static HRESULT WINAPI
ISFDropTarget_DragOver(
2792 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2794 TRACE("(%p)\n",This
);
2796 if(!pdwEffect
) return E_INVALIDARG
;
2798 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2803 static HRESULT WINAPI
ISFDropTarget_DragLeave(
2806 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2808 TRACE("(%p)\n",This
);
2810 This
->fAcceptFmt
= FALSE
;
2815 static HRESULT WINAPI
ISFDropTarget_Drop(
2817 IDataObject
* pDataObject
,
2822 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2824 FIXME("(%p) object dropped\n",This
);
2829 static struct ICOM_VTABLE(IDropTarget
) dtvt
=
2831 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2832 ISFDropTarget_QueryInterface
,
2833 ISFDropTarget_AddRef
,
2834 ISFDropTarget_Release
,
2835 ISFDropTarget_DragEnter
,
2836 ISFDropTarget_DragOver
,
2837 ISFDropTarget_DragLeave
,