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
25 #include "wine/port.h"
39 #include "wine/obj_base.h"
40 #include "wine/obj_dragdrop.h"
41 #include "wine/obj_shellfolder.h"
42 #include "undocshell.h"
43 #include "shell32_main.h"
46 #include "shellfolder.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
52 /***************************************************************************
53 * debughelper: print out the return adress
54 * helps especially to track down unbalanced AddRef/Release
59 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
73 /***************************************************************************
74 * GetNextElement (internal function)
76 * gets a part of a string till the first backslash
79 * pszNext [IN] string to get the element from
80 * pszOut [IN] pointer to buffer whitch receives string
81 * dwOut [IN] length of pszOut
84 * LPSTR pointer to first, not yet parsed char
87 static LPCWSTR
GetNextElementW(LPCWSTR pszNext
,LPWSTR pszOut
,DWORD dwOut
)
88 { LPCWSTR pszTail
= pszNext
;
90 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext
),pszOut
,dwOut
);
94 if(!pszNext
|| !*pszNext
)
97 while(*pszTail
&& (*pszTail
!= (WCHAR
)'\\'))
100 dwCopy
= (WCHAR
*)pszTail
- (WCHAR
*)pszNext
+ 1;
101 lstrcpynW(pszOut
, pszNext
, (dwOut
<dwCopy
)? dwOut
: dwCopy
);
108 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext
),debugstr_w(pszOut
),dwOut
,pszTail
);
112 static HRESULT
SHELL32_ParseNextElement(
115 LPITEMIDLIST
* pidlInOut
,
118 DWORD
*pdwAttributes
)
120 HRESULT hr
= E_OUTOFMEMORY
;
121 LPITEMIDLIST pidlOut
, pidlTemp
= NULL
;
122 IShellFolder
*psfChild
;
124 TRACE("(%p, %p, %s)\n",psf
, pidlInOut
? *pidlInOut
: NULL
, debugstr_w(szNext
));
127 /* get the shellfolder for the child pidl and let it analyse further */
128 hr
= IShellFolder_BindToObject(psf
, *pidlInOut
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
132 hr
= IShellFolder_ParseDisplayName(psfChild
, hwndOwner
, NULL
, szNext
, pEaten
, &pidlOut
, pdwAttributes
);
133 IShellFolder_Release(psfChild
);
135 pidlTemp
= ILCombine(*pidlInOut
, pidlOut
);
142 *pidlInOut
= pidlTemp
;
144 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut
? *pidlInOut
: NULL
, hr
);
148 /***********************************************************************
149 * SHELL32_CoCreateInitSF
151 * creates a initialized shell folder
153 static HRESULT
SHELL32_CoCreateInitSF (
154 LPITEMIDLIST pidlRoot
,
155 LPITEMIDLIST pidlChild
,
161 LPITEMIDLIST absPidl
;
162 IShellFolder2
*pShellFolder
;
163 IPersistFolder
*pPersistFolder
;
165 TRACE("%p %p\n", pidlRoot
, pidlChild
);
169 /* we have to ask first for IPersistFolder, some special folders are expecting this */
170 hr
= SHCoCreateInstance(NULL
, clsid
, NULL
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
);
173 hr
= IPersistFolder_QueryInterface(pPersistFolder
, iid
, (LPVOID
*)&pShellFolder
);
176 absPidl
= ILCombine (pidlRoot
, pidlChild
);
177 hr
= IPersistFolder_Initialize(pPersistFolder
, absPidl
);
178 IPersistFolder_Release(pPersistFolder
);
180 *ppvOut
= pShellFolder
;
184 TRACE("-- ret=0x%08lx\n", hr
);
188 static HRESULT
SHELL32_GetDisplayNameOfChild(
195 LPITEMIDLIST pidlFirst
, pidlNext
;
196 IShellFolder2
* psfChild
;
197 HRESULT hr
= E_OUTOFMEMORY
;
200 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf
,pidl
,dwFlags
,szOut
, dwOutLen
);
203 if ((pidlFirst
= ILCloneFirst(pidl
)))
205 hr
= IShellFolder_BindToObject(psf
, pidlFirst
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
208 pidlNext
= ILGetNext(pidl
);
210 hr
= IShellFolder_GetDisplayNameOf(psfChild
, pidlNext
, dwFlags
| SHGDN_INFOLDER
, &strTemp
);
213 hr
= StrRetToStrNA(szOut
, dwOutLen
, &strTemp
, pidlNext
);
216 IShellFolder_Release(psfChild
);
221 TRACE("-- ret=0x%08lx %s\n", hr
, szOut
);
226 /***********************************************************************
227 * SHELL32_GetItemAttributes
231 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
232 * file: 0x40000177 FILESYSTEM
233 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
234 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
235 * (seems to be default for shell extensions if no registry entry exists)
237 * This functions does not set flags!! It only resets flags when nessesary.
239 static HRESULT
SHELL32_GetItemAttributes(
242 LPDWORD pdwAttributes
)
247 TRACE("0x%08lx\n", *pdwAttributes
);
249 if (*pdwAttributes
& (0xcff3fe88))
250 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes
);
251 *pdwAttributes
&= ~SFGAO_LINK
; /* FIXME: for native filedialogs */
253 if (_ILIsDrive(pidl
))
255 *pdwAttributes
&= 0xf0000144;
257 else if ((clsid
=_ILGetGUIDPointer(pidl
)))
259 if (HCR_GetFolderAttributes(clsid
, &dwAttributes
))
261 *pdwAttributes
&= dwAttributes
;
265 *pdwAttributes
&= 0xb0000154;
268 else if (_ILGetDataPointer(pidl
))
270 dwAttributes
= _ILGetFileAttributes(pidl
, NULL
, 0);
271 *pdwAttributes
&= ~SFGAO_FILESYSANCESTOR
;
273 if(( SFGAO_FOLDER
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
274 *pdwAttributes
&= ~(SFGAO_FOLDER
|SFGAO_HASSUBFOLDER
);
276 if(( SFGAO_HIDDEN
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_HIDDEN
))
277 *pdwAttributes
&= ~SFGAO_HIDDEN
;
279 if(( SFGAO_READONLY
& *pdwAttributes
) && !(dwAttributes
& FILE_ATTRIBUTE_READONLY
))
280 *pdwAttributes
&= ~SFGAO_READONLY
;
284 *pdwAttributes
&= 0xb0000154;
286 TRACE("-- 0x%08lx\n", *pdwAttributes
);
290 /***********************************************************************
291 * IShellFolder implementation
296 ICOM_VFIELD(IUnknown
);
298 ICOM_VTABLE(IShellFolder2
)* lpvtblShellFolder
;
299 ICOM_VTABLE(IPersistFolder2
)* lpvtblPersistFolder2
;
300 ICOM_VTABLE(IDropTarget
)* lpvtblDropTarget
;
301 ICOM_VTABLE(ISFHelper
)* lpvtblSFHelper
;
303 IUnknown
*pUnkOuter
; /* used for aggregation */
308 LPITEMIDLIST absPidl
; /* complete pidl */
310 UINT cfShellIDList
; /* clipboardformat for IDropTarget */
311 BOOL fAcceptFmt
; /* flag for pending Drop */
314 static struct ICOM_VTABLE(IUnknown
) unkvt
;
315 static struct ICOM_VTABLE(IShellFolder2
) sfvt
;
316 static struct ICOM_VTABLE(IPersistFolder2
) psfvt
;
317 static struct ICOM_VTABLE(IDropTarget
) dtvt
;
318 static struct ICOM_VTABLE(ISFHelper
) shvt
;
320 static IShellFolder
* ISF_MyComputer_Constructor(void);
322 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
323 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
325 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
326 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
328 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
329 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
331 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
332 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
334 converts This to a interface pointer
336 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
337 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
338 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
339 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
340 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
341 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
342 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
343 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
344 /**************************************************************************
345 * registers clipboardformat once
347 static void SF_RegisterClipFmt (IGenericSFImpl
* This
)
349 TRACE("(%p)\n", This
);
351 if (!This
->cfShellIDList
)
353 This
->cfShellIDList
= RegisterClipboardFormatA(CFSTR_SHELLIDLIST
);
357 /**************************************************************************
358 * we need a separate IUnknown to handle aggregation
361 static HRESULT WINAPI
IUnknown_fnQueryInterface(
366 ICOM_THIS(IGenericSFImpl
, iface
);
369 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
373 if(IsEqualIID(riid
, &IID_IUnknown
)) *ppvObj
= _IUnknown_(This
);
374 else if(IsEqualIID(riid
, &IID_IShellFolder
)) *ppvObj
= _IShellFolder_(This
);
375 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) *ppvObj
= _IShellFolder_(This
);
376 else if(IsEqualIID(riid
, &IID_IPersist
)) *ppvObj
= _IPersist_(This
);
377 else if(IsEqualIID(riid
, &IID_IPersistFolder
)) *ppvObj
= _IPersistFolder_(This
);
378 else if(IsEqualIID(riid
, &IID_IPersistFolder2
)) *ppvObj
= _IPersistFolder2_(This
);
379 else if(IsEqualIID(riid
, &IID_ISFHelper
)) *ppvObj
= _ISFHelper_(This
);
380 else if(IsEqualIID(riid
, &IID_IDropTarget
))
382 *ppvObj
= _IDropTarget_(This
);
383 SF_RegisterClipFmt(This
);
388 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
389 TRACE("-- Interface = %p\n", *ppvObj
);
392 TRACE("-- Interface: E_NOINTERFACE\n");
393 return E_NOINTERFACE
;
396 static ULONG WINAPI
IUnknown_fnAddRef(IUnknown
* iface
)
398 ICOM_THIS(IGenericSFImpl
, iface
);
401 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
404 return ++(This
->ref
);
407 static ULONG WINAPI
IUnknown_fnRelease(IUnknown
* iface
)
409 ICOM_THIS(IGenericSFImpl
, iface
);
412 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
417 TRACE("-- destroying IShellFolder(%p)\n",This
);
419 if (pdesktopfolder
== _IShellFolder_(This
))
422 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This
);
424 if(This
->absPidl
) SHFree(This
->absPidl
);
425 if(This
->sMyPath
) SHFree(This
->sMyPath
);
426 HeapFree(GetProcessHeap(),0,This
);
432 static ICOM_VTABLE(IUnknown
) unkvt
=
434 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
435 IUnknown_fnQueryInterface
,
440 static shvheader GenericSFHeader
[] =
442 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
443 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
444 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
445 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
446 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
448 #define GENERICSHELLVIEWCOLUMNS 5
450 /**************************************************************************
451 * IShellFolder_Constructor
454 * creating undocumented ShellFS_Folder as part of an aggregation
455 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
458 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
460 HRESULT
IFSFolder_Constructor(
461 IUnknown
* pUnkOuter
,
468 TRACE("unkOut=%p riid=%s\n",pUnkOuter
, debugstr_guid(riid
));
470 if(pUnkOuter
&& ! IsEqualIID(riid
, &IID_IUnknown
))
472 hr
= CLASS_E_NOAGGREGATION
; /* forbidden by definition */
476 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
480 ICOM_VTBL(sf
)=&unkvt
;
481 sf
->lpvtblShellFolder
=&sfvt
;
482 sf
->lpvtblPersistFolder2
=&psfvt
;
483 sf
->lpvtblDropTarget
=&dtvt
;
484 sf
->lpvtblSFHelper
=&shvt
;
486 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
487 sf
->pUnkOuter
= pUnkOuter
? pUnkOuter
: _IUnknown_(sf
);
488 *ppv
= _IUnknown_(sf
);
499 /**************************************************************************
500 * IShellFolder_Constructor
503 * THIS points to the parent folder
506 IShellFolder
* IShellFolder_Constructor(
507 IShellFolder2
* iface
,
513 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
515 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
518 ICOM_VTBL(sf
)=&unkvt
;
519 sf
->lpvtblShellFolder
=&sfvt
;
520 sf
->lpvtblPersistFolder2
=&psfvt
;
521 sf
->lpvtblDropTarget
=&dtvt
;
522 sf
->lpvtblSFHelper
=&shvt
;
524 sf
->pclsid
= (CLSID
*)&CLSID_SFFile
;
525 sf
->pUnkOuter
= _IUnknown_(sf
);
527 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf
,This
, pidl
);
530 if(pidl
&& iface
) /* do we have a pidl? */
534 sf
->absPidl
= ILCombine(This
->absPidl
, pidl
); /* build a absolute pidl */
536 if (!_ILIsSpecialFolder(pidl
)) /* only file system paths */
538 if(This
->sMyPath
) /* get the size of the parents path */
540 dwSize
+= strlen(This
->sMyPath
) ;
541 TRACE("-- (%p)->(parent's path=%s)\n",sf
, debugstr_a(This
->sMyPath
));
544 dwSize
+= _ILSimpleGetText(pidl
,NULL
,0); /* add the size of our name*/
545 sf
->sMyPath
= SHAlloc(dwSize
+ 2); /* '\0' and backslash */
547 if(!sf
->sMyPath
) return NULL
;
550 if(This
->sMyPath
) /* if the parent has a path, get it*/
552 strcpy(sf
->sMyPath
, This
->sMyPath
);
553 PathAddBackslashA (sf
->sMyPath
);
556 len
= strlen(sf
->sMyPath
);
557 _ILSimpleGetText(pidl
, sf
->sMyPath
+ len
, dwSize
+2 - len
);
560 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf
, sf
->absPidl
,debugstr_a(sf
->sMyPath
));
566 return _IShellFolder_(sf
);
569 /**************************************************************************
570 * IShellFolder_fnQueryInterface
573 * REFIID riid [in ] Requested InterfaceID
574 * LPVOID* ppvObject [out] Interface* to hold the result
576 static HRESULT WINAPI
IShellFolder_fnQueryInterface(
577 IShellFolder2
* iface
,
581 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
584 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
586 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
589 /**************************************************************************
590 * IShellFolder_AddRef
593 static ULONG WINAPI
IShellFolder_fnAddRef(IShellFolder2
* iface
)
595 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
598 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
600 return IUnknown_AddRef(This
->pUnkOuter
);
603 /**************************************************************************
604 * IShellFolder_fnRelease
606 static ULONG WINAPI
IShellFolder_fnRelease(IShellFolder2
* iface
)
608 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
611 TRACE("(%p)->(count=%lu)\n",This
,This
->ref
);
613 return IUnknown_Release(This
->pUnkOuter
);
616 /**************************************************************************
617 * IShellFolder_fnParseDisplayName
619 * HWND hwndOwner, //[in ] Parent window for any message's
620 * LPBC pbc, //[in ] reserved
621 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
622 * ULONG* pchEaten, //[out] (unicode) characters processed
623 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
624 * ULONG* pdwAttributes //[out] items attributes
627 * every folder tries to parse only its own (the leftmost) pidl and creates a
628 * subfolder to evaluate the remaining parts
629 * now we can parse into namespaces implemented by shell extensions
631 * behaviour on win98: lpszDisplayName=NULL -> chrash
632 * lpszDisplayName="" -> returns mycoputer-pidl
635 * pdwAttributes: not set
636 * pchEaten: not set like in windows
638 static HRESULT WINAPI
IShellFolder_fnParseDisplayName(
639 IShellFolder2
* iface
,
642 LPOLESTR lpszDisplayName
,
645 DWORD
*pdwAttributes
)
647 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
649 HRESULT hr
= E_OUTOFMEMORY
;
651 WCHAR szElement
[MAX_PATH
];
652 CHAR szTempA
[MAX_PATH
], szPath
[MAX_PATH
];
653 LPITEMIDLIST pidlTemp
=NULL
;
655 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
656 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
657 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
659 if (!lpszDisplayName
|| !ppidl
) return E_INVALIDARG
;
661 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
663 if (*lpszDisplayName
)
665 /* get the next element */
666 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
668 /* build the full pathname to the element */
669 WideCharToMultiByte( CP_ACP
, 0, szElement
, -1, szTempA
, MAX_PATH
, NULL
, NULL
);
670 strcpy(szPath
, This
->sMyPath
);
671 PathAddBackslashA(szPath
);
672 strcat(szPath
, szTempA
);
675 pidlTemp
= SHSimpleIDListFromPathA(szPath
);
679 /* try to analyse the next element */
680 if (szNext
&& *szNext
)
682 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
686 if (pdwAttributes
&& *pdwAttributes
)
688 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
689 /* WIN32_FIND_DATAA fd;
690 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
691 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
692 *pdwAttributes &= ~SFGAO_FOLDER;
693 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
694 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
707 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This
, ppidl
? *ppidl
:0, hr
);
712 /**************************************************************************
713 * IShellFolder_fnEnumObjects
715 * HWND hwndOwner, //[in ] Parent Window
716 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
717 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
719 static HRESULT WINAPI
IShellFolder_fnEnumObjects(
720 IShellFolder2
* iface
,
723 LPENUMIDLIST
* ppEnumIDList
)
725 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
727 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
729 *ppEnumIDList
= NULL
;
730 *ppEnumIDList
= IEnumIDList_Constructor (This
->sMyPath
, dwFlags
, EIDL_FILE
);
732 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
734 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
739 /**************************************************************************
740 * IShellFolder_fnBindToObject
742 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
743 * LPBC pbc, //[in ] reserved
744 * REFIID riid, //[in ] Initial Interface
745 * LPVOID* ppvObject //[out] Interface*
747 static HRESULT WINAPI
IShellFolder_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
748 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
750 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
752 IShellFolder
*pShellFolder
, *pSubFolder
;
753 IPersistFolder
*pPersistFolder
;
754 LPITEMIDLIST absPidl
;
757 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
759 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
763 if ((iid
=_ILGetGUIDPointer(pidl
)))
765 /* we have to create a alien folder */
766 if ( SUCCEEDED(SHCoCreateInstance(NULL
, iid
, NULL
, riid
, (LPVOID
*)&pShellFolder
))
767 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&pPersistFolder
)))
769 absPidl
= ILCombine (This
->absPidl
, pidl
);
770 IPersistFolder_Initialize(pPersistFolder
, absPidl
);
771 IPersistFolder_Release(pPersistFolder
);
781 LPITEMIDLIST pidltemp
= ILCloneFirst(pidl
);
782 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
786 if (_ILIsPidlSimple(pidl
))
788 if(IsEqualIID(riid
, &IID_IShellFolder
))
790 *ppvOut
= pShellFolder
;
795 hr
= IShellFolder_QueryInterface(pShellFolder
, riid
, ppvOut
);
796 IShellFolder_Release(pShellFolder
);
801 hr
= IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
,
802 riid
, (LPVOID
)&pSubFolder
);
803 IShellFolder_Release(pShellFolder
);
804 *ppvOut
= pSubFolder
;
807 TRACE("-- (%p) returning (%p) %08lx\n",This
, *ppvOut
, hr
);
812 /**************************************************************************
813 * IShellFolder_fnBindToStorage
815 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
816 * LPBC pbc, //[in ] reserved
817 * REFIID riid, //[in ] Initial storage interface
818 * LPVOID* ppvObject //[out] Interface* returned
820 static HRESULT WINAPI
IShellFolder_fnBindToStorage(
821 IShellFolder2
* iface
,
827 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
829 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
830 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
836 /**************************************************************************
837 * IShellFolder_fnCompareIDs
840 * LPARAM lParam, //[in ] Column?
841 * LPCITEMIDLIST pidl1, //[in ] simple pidl
842 * LPCITEMIDLIST pidl2) //[in ] simple pidl
845 * Special case - If one of the items is a Path and the other is a File,
846 * always make the Path come before the File.
849 * use SCODE_CODE() on the return value to get the result
852 static HRESULT WINAPI
IShellFolder_fnCompareIDs(
853 IShellFolder2
* iface
,
858 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
860 CHAR szTemp1
[MAX_PATH
];
861 CHAR szTemp2
[MAX_PATH
];
864 HRESULT hr
= E_OUTOFMEMORY
;
865 LPCITEMIDLIST pidlTemp
;
868 if (TRACE_ON(shell
)) {
869 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This
,lParam
,pidl1
,pidl2
);
874 if (!pidl1
&& !pidl2
)
876 hr
= ResultFromShort(0);
880 hr
= ResultFromShort(-1);
884 hr
= ResultFromShort(1);
889 pd1
= _ILGetDataPointer(pidl1
);
890 pd2
= _ILGetDataPointer(pidl2
);
892 /* compate the types. sort order is the PT_* constant */
893 pt1
= ( pd1
? pd1
->type
: PT_DESKTOP
);
894 pt2
= ( pd2
? pd2
->type
: PT_DESKTOP
);
898 hr
= ResultFromShort(pt1
-pt2
);
900 else /* same type of pidl */
902 _ILSimpleGetText(pidl1
, szTemp1
, MAX_PATH
);
903 _ILSimpleGetText(pidl2
, szTemp2
, MAX_PATH
);
904 nReturn
= strcasecmp(szTemp1
, szTemp2
);
906 if (nReturn
== 0) /* first pidl different ? */
908 pidl1
= ILGetNext(pidl1
);
910 if (pidl1
&& pidl1
->mkid
.cb
) /* go deeper? */
912 pidlTemp
= ILCloneFirst(pidl1
);
913 pidl2
= ILGetNext(pidl2
);
915 hr
= IShellFolder_BindToObject(iface
, pidlTemp
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psf
);
918 nReturn
= IShellFolder_CompareIDs(psf
, 0, pidl1
, pidl2
);
919 IShellFolder_Release(psf
);
920 hr
= ResultFromShort(nReturn
);
924 else /* no deeper on #1 */
926 pidl2
= ILGetNext(pidl2
);
927 if (pidl2
&& pidl2
->mkid
.cb
) /* go deeper on #2 ? */
928 hr
= ResultFromShort(-1); /* two different */
930 hr
= ResultFromShort(nReturn
); /* two equal simple pidls */
935 hr
= ResultFromShort(nReturn
); /* two different simple pidls */
940 TRACE("-- res=0x%08lx\n", hr
);
944 /**************************************************************************
945 * IShellFolder_fnCreateViewObject
947 static HRESULT WINAPI
IShellFolder_fnCreateViewObject(
948 IShellFolder2
* iface
,
953 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
955 LPSHELLVIEW pShellView
;
956 HRESULT hr
= E_INVALIDARG
;
958 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
964 if(IsEqualIID(riid
, &IID_IDropTarget
))
966 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, ppvOut
);
968 else if(IsEqualIID(riid
, &IID_IContextMenu
))
970 FIXME("IContextMenu not implemented\n");
973 else if(IsEqualIID(riid
, &IID_IShellView
))
975 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
978 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
979 IShellView_Release(pShellView
);
983 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
987 /**************************************************************************
988 * IShellFolder_fnGetAttributesOf
991 * UINT cidl, //[in ] num elements in pidl array
992 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
993 * ULONG* rgfInOut) //[out] result array
996 static HRESULT WINAPI
IShellFolder_fnGetAttributesOf(
997 IShellFolder2
* iface
,
999 LPCITEMIDLIST
*apidl
,
1002 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1006 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
1008 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
1009 return E_INVALIDARG
;
1011 while (cidl
> 0 && *apidl
)
1014 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
1019 TRACE("-- result=0x%08lx\n",*rgfInOut
);
1023 /**************************************************************************
1024 * IShellFolder_fnGetUIObjectOf
1027 * HWND hwndOwner, //[in ] Parent window for any output
1028 * UINT cidl, //[in ] array size
1029 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1030 * REFIID riid, //[in ] Requested Interface
1031 * UINT* prgfInOut, //[ ] reserved
1032 * LPVOID* ppvObject) //[out] Resulting Interface
1035 * This function gets asked to return "view objects" for one or more (multiple select)
1037 * The viewobject typically is an COM object with one of the following interfaces:
1038 * IExtractIcon,IDataObject,IContextMenu
1039 * In order to support icon positions in the default Listview your DataObject
1040 * must implement the SetData method (in addition to GetData :) - the shell passes
1041 * a barely documented "Icon positions" structure to SetData when the drag starts,
1042 * and GetData's it if the drop is in another explorer window that needs the positions.
1044 static HRESULT WINAPI
IShellFolder_fnGetUIObjectOf(
1045 IShellFolder2
* iface
,
1048 LPCITEMIDLIST
* apidl
,
1053 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1056 IUnknown
* pObj
= NULL
;
1057 HRESULT hr
= E_INVALIDARG
;
1059 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1060 This
,hwndOwner
,cidl
,apidl
,debugstr_guid(riid
),prgfInOut
,ppvOut
);
1066 if(IsEqualIID(riid
, &IID_IContextMenu
) && (cidl
>= 1))
1068 pObj
= (LPUNKNOWN
)ISvItemCm_Constructor((IShellFolder
*)iface
, This
->absPidl
, apidl
, cidl
);
1071 else if (IsEqualIID(riid
, &IID_IDataObject
) &&(cidl
>= 1))
1073 pObj
= (LPUNKNOWN
)IDataObject_Constructor (hwndOwner
, This
->absPidl
, apidl
, cidl
);
1076 else if (IsEqualIID(riid
, &IID_IExtractIconA
) && (cidl
== 1))
1078 pidl
= ILCombine(This
->absPidl
,apidl
[0]);
1079 pObj
= (LPUNKNOWN
)IExtractIconA_Constructor( pidl
);
1083 else if (IsEqualIID(riid
, &IID_IDropTarget
) && (cidl
>= 1))
1085 hr
= IShellFolder_QueryInterface(iface
, &IID_IDropTarget
, (LPVOID
*)&pObj
);
1097 TRACE("(%p)->hr=0x%08lx\n",This
, hr
);
1101 /**************************************************************************
1102 * IShellFolder_fnGetDisplayNameOf
1103 * Retrieves the display name for the specified file object or subfolder
1106 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1107 * DWORD dwFlags, //[in ] SHGNO formatting flags
1108 * LPSTRRET lpName) //[out] Returned display name
1111 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1113 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1114 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1116 static HRESULT WINAPI
IShellFolder_fnGetDisplayNameOf(
1117 IShellFolder2
* iface
,
1122 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1124 CHAR szPath
[MAX_PATH
]= "";
1128 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1131 if(!pidl
|| !strRet
) return E_INVALIDARG
;
1133 bSimplePidl
= _ILIsPidlSimple(pidl
);
1135 /* take names of special folders only if its only this folder */
1136 if (_ILIsSpecialFolder(pidl
))
1140 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
1145 if (!(dwFlags
& SHGDN_INFOLDER
) && (dwFlags
& SHGDN_FORPARSING
) && This
->sMyPath
)
1147 strcpy (szPath
, This
->sMyPath
); /* get path to root*/
1148 PathAddBackslashA(szPath
);
1149 len
= strlen(szPath
);
1151 _ILSimpleGetText(pidl
, szPath
+ len
, MAX_PATH
- len
); /* append my own path */
1153 /* MSDN also mentions SHGDN_FOREDITING, which isn't defined in wine */
1154 if(!_ILIsFolder(pidl
) && !(dwFlags
& SHGDN_FORPARSING
) &&
1155 ((dwFlags
& SHGDN_INFOLDER
) || (dwFlags
== SHGDN_NORMAL
)))
1159 DWORD dwDataSize
= sizeof(DWORD
);
1160 BOOL doHide
= 0; /* The default value is FALSE (win98 at least) */
1162 /* XXX should it do this only for known file types? -- that would make it even slower! */
1163 /* XXX That's what the prompt says!! */
1164 if(!RegCreateKeyExA(HKEY_CURRENT_USER
,
1165 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
1166 0, 0, 0, KEY_ALL_ACCESS
, 0, &hKey
, 0))
1168 if(!RegQueryValueExA(hKey
, "HideFileExt", 0, 0, (LPBYTE
)&dwData
, &dwDataSize
))
1172 if(doHide
&& szPath
[0]!='.') PathRemoveExtensionA(szPath
);
1176 if ( (dwFlags
& SHGDN_FORPARSING
) && !bSimplePidl
) /* go deeper if needed */
1178 PathAddBackslashA(szPath
);
1179 len
= strlen(szPath
);
1181 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
+ len
, MAX_PATH
- len
)))
1182 return E_OUTOFMEMORY
;
1184 strRet
->uType
= STRRET_CSTRA
;
1185 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1187 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1191 /**************************************************************************
1192 * IShellFolder_fnSetNameOf
1193 * Changes the name of a file object or subfolder, possibly changing its item
1194 * identifier in the process.
1197 * HWND hwndOwner, //[in ] Owner window for output
1198 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1199 * LPCOLESTR lpszName, //[in ] the items new display name
1200 * DWORD dwFlags, //[in ] SHGNO formatting flags
1201 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1203 static HRESULT WINAPI
IShellFolder_fnSetNameOf(
1204 IShellFolder2
* iface
,
1206 LPCITEMIDLIST pidl
, /*simple pidl*/
1209 LPITEMIDLIST
*pPidlOut
)
1211 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1212 char szSrc
[MAX_PATH
], szDest
[MAX_PATH
];
1214 BOOL bIsFolder
= _ILIsFolder(ILFindLastID(pidl
));
1216 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1217 This
,hwndOwner
,pidl
,debugstr_w(lpName
),dwFlags
,pPidlOut
);
1219 /* build source path */
1220 if (dwFlags
& SHGDN_INFOLDER
)
1222 strcpy(szSrc
, This
->sMyPath
);
1223 PathAddBackslashA(szSrc
);
1224 len
= strlen (szSrc
);
1225 _ILSimpleGetText(pidl
, szSrc
+len
, MAX_PATH
-len
);
1229 SHGetPathFromIDListA(pidl
, szSrc
);
1232 /* build destination path */
1233 strcpy(szDest
, This
->sMyPath
);
1234 PathAddBackslashA(szDest
);
1235 len
= strlen (szDest
);
1236 WideCharToMultiByte( CP_ACP
, 0, lpName
, -1, szDest
+len
, MAX_PATH
-len
, NULL
, NULL
);
1237 szDest
[MAX_PATH
-1] = 0;
1238 TRACE("src=%s dest=%s\n", szSrc
, szDest
);
1239 if ( MoveFileA(szSrc
, szDest
) )
1241 if (pPidlOut
) *pPidlOut
= SHSimpleIDListFromPathA(szDest
);
1242 SHChangeNotifyA( bIsFolder
?SHCNE_RENAMEFOLDER
:SHCNE_RENAMEITEM
, SHCNF_PATHA
, szSrc
, szDest
);
1248 static HRESULT WINAPI
IShellFolder_fnGetDefaultSearchGUID(
1249 IShellFolder2
* iface
,
1252 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1253 FIXME("(%p)\n",This
);
1256 static HRESULT WINAPI
IShellFolder_fnEnumSearches(
1257 IShellFolder2
* iface
,
1258 IEnumExtraSearch
**ppenum
)
1260 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1261 FIXME("(%p)\n",This
);
1264 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumn(
1265 IShellFolder2
* iface
,
1270 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1272 TRACE("(%p)\n",This
);
1274 if (pSort
) *pSort
= 0;
1275 if (pDisplay
) *pDisplay
= 0;
1279 static HRESULT WINAPI
IShellFolder_fnGetDefaultColumnState(
1280 IShellFolder2
* iface
,
1284 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1286 TRACE("(%p)\n",This
);
1288 if (!pcsFlags
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1290 *pcsFlags
= GenericSFHeader
[iColumn
].pcsFlags
;
1294 static HRESULT WINAPI
IShellFolder_fnGetDetailsEx(
1295 IShellFolder2
* iface
,
1297 const SHCOLUMNID
*pscid
,
1300 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1301 FIXME("(%p)\n",This
);
1305 static HRESULT WINAPI
IShellFolder_fnGetDetailsOf(
1306 IShellFolder2
* iface
,
1311 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1312 HRESULT hr
= E_FAIL
;
1314 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
1316 if (!psd
|| iColumn
>= GENERICSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
1320 /* the header titles */
1321 psd
->fmt
= GenericSFHeader
[iColumn
].fmt
;
1322 psd
->cxChar
= GenericSFHeader
[iColumn
].cxChar
;
1323 psd
->str
.uType
= STRRET_CSTRA
;
1324 LoadStringA(shell32_hInstance
, GenericSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
1329 /* the data from the pidl */
1333 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
1336 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1339 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1342 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1344 case 4: /* attributes */
1345 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
1349 psd
->str
.uType
= STRRET_CSTRA
;
1354 static HRESULT WINAPI
IShellFolder_fnMapNameToSCID(
1355 IShellFolder2
* iface
,
1359 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1360 FIXME("(%p)\n",This
);
1364 static ICOM_VTABLE(IShellFolder2
) sfvt
=
1366 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1367 IShellFolder_fnQueryInterface
,
1368 IShellFolder_fnAddRef
,
1369 IShellFolder_fnRelease
,
1370 IShellFolder_fnParseDisplayName
,
1371 IShellFolder_fnEnumObjects
,
1372 IShellFolder_fnBindToObject
,
1373 IShellFolder_fnBindToStorage
,
1374 IShellFolder_fnCompareIDs
,
1375 IShellFolder_fnCreateViewObject
,
1376 IShellFolder_fnGetAttributesOf
,
1377 IShellFolder_fnGetUIObjectOf
,
1378 IShellFolder_fnGetDisplayNameOf
,
1379 IShellFolder_fnSetNameOf
,
1382 IShellFolder_fnGetDefaultSearchGUID
,
1383 IShellFolder_fnEnumSearches
,
1384 IShellFolder_fnGetDefaultColumn
,
1385 IShellFolder_fnGetDefaultColumnState
,
1386 IShellFolder_fnGetDetailsEx
,
1387 IShellFolder_fnGetDetailsOf
,
1388 IShellFolder_fnMapNameToSCID
1391 /****************************************************************************
1392 * ISFHelper for IShellFolder implementation
1395 static HRESULT WINAPI
ISFHelper_fnQueryInterface(
1400 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1402 TRACE("(%p)\n", This
);
1404 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
1407 static ULONG WINAPI
ISFHelper_fnAddRef(
1410 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1412 TRACE("(%p)\n", This
);
1414 return IUnknown_AddRef(This
->pUnkOuter
);
1417 static ULONG WINAPI
ISFHelper_fnRelease(
1420 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1422 TRACE("(%p)\n", This
);
1424 return IUnknown_Release(This
->pUnkOuter
);
1428 /****************************************************************************
1429 * ISFHelper_fnAddFolder
1431 * creates a unique folder name
1434 static HRESULT WINAPI
ISFHelper_fnGetUniqueName(
1439 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1440 IEnumIDList
* penum
;
1442 char szText
[MAX_PATH
];
1443 char * szNewFolder
= "New Folder";
1445 TRACE("(%p)(%s %u)\n", This
, lpName
, uLen
);
1447 if (uLen
< strlen(szNewFolder
) + 4) return E_POINTER
;
1449 strcpy(lpName
, szNewFolder
);
1451 hr
= IShellFolder_fnEnumObjects(_IShellFolder2_(This
), 0, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
| SHCONTF_INCLUDEHIDDEN
, &penum
);
1458 next
: IEnumIDList_Reset(penum
);
1459 while(S_OK
== IEnumIDList_Next(penum
, 1, &pidl
, &dwFetched
) && dwFetched
)
1461 _ILSimpleGetText(pidl
, szText
, MAX_PATH
);
1462 if (0 == strcasecmp(szText
, lpName
))
1464 sprintf(lpName
, "%s %d", szNewFolder
, i
++);
1474 IEnumIDList_Release(penum
);
1479 /****************************************************************************
1480 * ISFHelper_fnAddFolder
1482 * adds a new folder.
1485 static HRESULT WINAPI
ISFHelper_fnAddFolder(
1489 LPITEMIDLIST
* ppidlOut
)
1491 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1492 char lpstrNewDir
[MAX_PATH
];
1494 HRESULT hres
= E_FAIL
;
1496 TRACE("(%p)(%s %p)\n", This
, lpName
, ppidlOut
);
1498 strcpy(lpstrNewDir
, This
->sMyPath
);
1499 PathAddBackslashA(lpstrNewDir
);
1500 strcat(lpstrNewDir
, lpName
);
1502 bRes
= CreateDirectoryA(lpstrNewDir
, NULL
);
1506 LPITEMIDLIST pidl
, pidlitem
;
1508 pidlitem
= SHSimpleIDListFromPathA(lpstrNewDir
);
1510 pidl
= ILCombine(This
->absPidl
, pidlitem
);
1511 SHChangeNotifyA(SHCNE_MKDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1514 if (ppidlOut
) *ppidlOut
= pidlitem
;
1519 char lpstrText
[128+MAX_PATH
];
1520 char lpstrTempText
[128];
1521 char lpstrCaption
[256];
1523 /* Cannot Create folder because of permissions */
1524 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_DENIED
, lpstrTempText
, sizeof(lpstrTempText
));
1525 LoadStringA(shell32_hInstance
, IDS_CREATEFOLDER_CAPTION
, lpstrCaption
, sizeof(lpstrCaption
));
1526 sprintf(lpstrText
,lpstrTempText
, lpstrNewDir
);
1527 MessageBoxA(hwnd
,lpstrText
, lpstrCaption
, MB_OK
| MB_ICONEXCLAMATION
);
1533 /****************************************************************************
1534 * ISFHelper_fnDeleteItems
1536 * deletes items in folder
1538 static HRESULT WINAPI
ISFHelper_fnDeleteItems(
1541 LPCITEMIDLIST
* apidl
)
1543 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
)
1545 char szPath
[MAX_PATH
];
1546 BOOL bConfirm
= TRUE
;
1548 TRACE("(%p)(%u %p)\n", This
, cidl
, apidl
);
1550 /* deleting multiple items so give a slightly different warning */
1554 snprintf(tmp
, sizeof(tmp
), "%d", cidl
);
1555 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM
, tmp
))
1560 for(i
=0; i
< cidl
; i
++)
1562 strcpy(szPath
, This
->sMyPath
);
1563 PathAddBackslashA(szPath
);
1564 _ILSimpleGetText(apidl
[i
], szPath
+strlen(szPath
), MAX_PATH
);
1566 if (_ILIsFolder(apidl
[i
]))
1569 TRACE("delete %s\n", szPath
);
1570 if (! SHELL_DeleteDirectoryA(szPath
, bConfirm
))
1572 TRACE("delete %s failed, bConfirm=%d\n", szPath
, bConfirm
);
1575 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1576 SHChangeNotifyA(SHCNE_RMDIR
, SHCNF_IDLIST
, pidl
, NULL
);
1579 else if (_ILIsValue(apidl
[i
]))
1583 TRACE("delete %s\n", szPath
);
1584 if (! SHELL_DeleteFileA(szPath
, bConfirm
))
1586 TRACE("delete %s failed, bConfirm=%d\n", szPath
, bConfirm
);
1589 pidl
= ILCombine(This
->absPidl
, apidl
[i
]);
1590 SHChangeNotifyA(SHCNE_DELETE
, SHCNF_IDLIST
, pidl
, NULL
);
1598 /****************************************************************************
1599 * ISFHelper_fnCopyItems
1601 * copies items to this folder
1603 static HRESULT WINAPI
ISFHelper_fnCopyItems(
1605 IShellFolder
* pSFFrom
,
1607 LPCITEMIDLIST
*apidl
)
1610 IPersistFolder2
* ppf2
=NULL
;
1611 char szSrcPath
[MAX_PATH
], szDstPath
[MAX_PATH
];
1612 _ICOM_THIS_From_ISFHelper(IGenericSFImpl
,iface
);
1614 TRACE("(%p)->(%p,%u,%p)\n", This
, pSFFrom
, cidl
, apidl
);
1616 IShellFolder_QueryInterface(pSFFrom
, &IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
1620 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2
, &pidl
)))
1622 for (i
=0; i
<cidl
; i
++)
1624 SHGetPathFromIDListA(pidl
, szSrcPath
);
1625 PathAddBackslashA(szSrcPath
);
1626 _ILSimpleGetText(apidl
[i
], szSrcPath
+strlen(szSrcPath
), MAX_PATH
);
1628 strcpy(szDstPath
, This
->sMyPath
);
1629 PathAddBackslashA(szDstPath
);
1630 _ILSimpleGetText(apidl
[i
], szDstPath
+strlen(szDstPath
), MAX_PATH
);
1631 MESSAGE("would copy %s to %s\n", szSrcPath
, szDstPath
);
1635 IPersistFolder2_Release(ppf2
);
1640 static ICOM_VTABLE(ISFHelper
) shvt
=
1642 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1643 ISFHelper_fnQueryInterface
,
1645 ISFHelper_fnRelease
,
1646 ISFHelper_fnGetUniqueName
,
1647 ISFHelper_fnAddFolder
,
1648 ISFHelper_fnDeleteItems
,
1649 ISFHelper_fnCopyItems
,
1652 /***********************************************************************
1653 * [Desktopfolder] IShellFolder implementation
1655 static struct ICOM_VTABLE(IShellFolder2
) sfdvt
;
1657 static shvheader DesktopSFHeader
[] =
1659 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
1660 { IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1661 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
1662 { IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12 },
1663 { IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5 }
1665 #define DESKTOPSHELLVIEWCOLUMNS 5
1667 /**************************************************************************
1668 * ISF_Desktop_Constructor
1671 IShellFolder
* ISF_Desktop_Constructor()
1673 IGenericSFImpl
* sf
;
1675 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
1677 ICOM_VTBL(sf
)=&unkvt
;
1678 sf
->lpvtblShellFolder
=&sfdvt
;
1679 sf
->absPidl
=_ILCreateDesktop(); /* my qualified pidl */
1680 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
1685 return _IShellFolder_(sf
);
1688 /**************************************************************************
1689 * ISF_Desktop_fnQueryInterface
1691 * NOTES supports not IPersist/IPersistFolder
1693 static HRESULT WINAPI
ISF_Desktop_fnQueryInterface(
1694 IShellFolder2
* iface
,
1698 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1700 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
1704 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
1706 *ppvObj
= _IUnknown_(This
);
1708 else if(IsEqualIID(riid
, &IID_IShellFolder
)) /*IShellFolder*/
1710 *ppvObj
= _IShellFolder_(This
);
1712 else if(IsEqualIID(riid
, &IID_IShellFolder2
)) /*IShellFolder2*/
1714 *ppvObj
= _IShellFolder_(This
);
1719 IUnknown_AddRef((IUnknown
*)(*ppvObj
));
1720 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
1723 TRACE("-- Interface: E_NOINTERFACE\n");
1724 return E_NOINTERFACE
;
1727 /**************************************************************************
1728 * ISF_Desktop_fnParseDisplayName
1731 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1734 static HRESULT WINAPI
ISF_Desktop_fnParseDisplayName(
1735 IShellFolder2
* iface
,
1738 LPOLESTR lpszDisplayName
,
1740 LPITEMIDLIST
*ppidl
,
1741 DWORD
*pdwAttributes
)
1743 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1745 LPCWSTR szNext
=NULL
;
1746 LPITEMIDLIST pidlTemp
=NULL
;
1747 HRESULT hr
=E_OUTOFMEMORY
;
1749 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1750 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
1751 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
1754 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
1756 /* FIXME no real parsing implemented */
1757 pidlTemp
= _ILCreateMyComputer();
1758 szNext
= lpszDisplayName
;
1760 if (szNext
&& *szNext
)
1762 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
1768 if (pdwAttributes
&& *pdwAttributes
)
1770 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
1776 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
1781 /**************************************************************************
1782 * ISF_Desktop_fnEnumObjects
1784 static HRESULT WINAPI
ISF_Desktop_fnEnumObjects(
1785 IShellFolder2
* iface
,
1788 LPENUMIDLIST
* ppEnumIDList
)
1790 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1792 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
1794 *ppEnumIDList
= NULL
;
1795 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_DESK
);
1797 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
1799 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
1804 /**************************************************************************
1805 * ISF_Desktop_fnBindToObject
1807 static HRESULT WINAPI
ISF_Desktop_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
1808 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
1810 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1812 IShellFolder
*pShellFolder
, *pSubFolder
;
1815 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1816 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
1820 if ((clsid
=_ILGetGUIDPointer(pidl
)))
1822 if ( IsEqualIID(clsid
, &CLSID_MyComputer
))
1824 pShellFolder
= ISF_MyComputer_Constructor();
1828 /* shell extension */
1829 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
1831 return E_INVALIDARG
;
1837 /* file system folder on the desktop */
1838 LPITEMIDLIST deskpidl
, firstpidl
, completepidl
;
1839 IPersistFolder
* ppf
;
1842 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY
, &deskpidl
);
1843 firstpidl
= ILCloneFirst(pidl
);
1844 completepidl
= ILCombine(deskpidl
, firstpidl
);
1846 pShellFolder
= IShellFolder_Constructor(NULL
, NULL
);
1847 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder
, (LPVOID
*)&ppf
)))
1849 IPersistFolder_Initialize(ppf
, completepidl
);
1850 IPersistFolder_Release(ppf
);
1852 ILFree(completepidl
);
1857 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
1859 *ppvOut
= pShellFolder
;
1862 else /* go deeper */
1864 hr
= IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
, riid
, (LPVOID
)&pSubFolder
);
1865 IShellFolder_Release(pShellFolder
);
1866 *ppvOut
= pSubFolder
;
1869 TRACE("-- (%p) returning (%p) %08lx\n",This
, *ppvOut
, hr
);
1874 /**************************************************************************
1875 * ISF_Desktop_fnCreateViewObject
1877 static HRESULT WINAPI
ISF_Desktop_fnCreateViewObject( IShellFolder2
* iface
,
1878 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
1880 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1882 LPSHELLVIEW pShellView
;
1883 HRESULT hr
= E_INVALIDARG
;
1885 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
1891 if(IsEqualIID(riid
, &IID_IDropTarget
))
1893 WARN("IDropTarget not implemented\n");
1896 else if(IsEqualIID(riid
, &IID_IContextMenu
))
1898 WARN("IContextMenu not implemented\n");
1901 else if(IsEqualIID(riid
, &IID_IShellView
))
1903 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
1906 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
1907 IShellView_Release(pShellView
);
1911 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
1915 /**************************************************************************
1916 * ISF_Desktop_fnGetAttributesOf
1918 static HRESULT WINAPI
ISF_Desktop_fnGetAttributesOf(
1919 IShellFolder2
* iface
,
1921 LPCITEMIDLIST
*apidl
,
1924 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1928 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
, *rgfInOut
);
1930 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
1931 return E_INVALIDARG
;
1933 while (cidl
> 0 && *apidl
)
1936 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
1941 TRACE("-- result=0x%08lx\n",*rgfInOut
);
1946 /**************************************************************************
1947 * ISF_Desktop_fnGetDisplayNameOf
1950 * special case: pidl = null gives desktop-name back
1952 static HRESULT WINAPI
ISF_Desktop_fnGetDisplayNameOf(
1953 IShellFolder2
* iface
,
1958 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1960 CHAR szPath
[MAX_PATH
]= "";
1962 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
1965 if(!strRet
) return E_INVALIDARG
;
1969 HCR_GetClassName(&CLSID_ShellDesktop
, szPath
, MAX_PATH
);
1971 else if ( _ILIsPidlSimple(pidl
) )
1973 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
1977 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
, szPath
, MAX_PATH
)))
1978 return E_OUTOFMEMORY
;
1980 strRet
->uType
= STRRET_CSTRA
;
1981 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
1984 TRACE("-- (%p)->(%s)\n", This
, szPath
);
1988 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultSearchGUID(
1989 IShellFolder2
* iface
,
1992 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
1993 FIXME("(%p)\n",This
);
1996 static HRESULT WINAPI
ISF_Desktop_fnEnumSearches(
1997 IShellFolder2
* iface
,
1998 IEnumExtraSearch
**ppenum
)
2000 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2001 FIXME("(%p)\n",This
);
2004 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumn(
2005 IShellFolder2
* iface
,
2010 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2012 TRACE("(%p)\n",This
);
2014 if (pSort
) *pSort
= 0;
2015 if (pDisplay
) *pDisplay
= 0;
2019 static HRESULT WINAPI
ISF_Desktop_fnGetDefaultColumnState(
2020 IShellFolder2
* iface
,
2024 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2026 TRACE("(%p)\n",This
);
2028 if (!pcsFlags
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2030 *pcsFlags
= DesktopSFHeader
[iColumn
].pcsFlags
;
2034 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsEx(
2035 IShellFolder2
* iface
,
2037 const SHCOLUMNID
*pscid
,
2040 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2041 FIXME("(%p)\n",This
);
2045 static HRESULT WINAPI
ISF_Desktop_fnGetDetailsOf(
2046 IShellFolder2
* iface
,
2051 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2052 HRESULT hr
= E_FAIL
;
2054 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
2056 if (!psd
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2060 psd
->fmt
= DesktopSFHeader
[iColumn
].fmt
;
2061 psd
->cxChar
= DesktopSFHeader
[iColumn
].cxChar
;
2062 psd
->str
.uType
= STRRET_CSTRA
;
2063 LoadStringA(shell32_hInstance
, DesktopSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
2068 /* the data from the pidl */
2072 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
2075 _ILGetFileSize (pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2078 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2081 _ILGetFileDate(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2083 case 4: /* attributes */
2084 _ILGetFileAttributes(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2088 psd
->str
.uType
= STRRET_CSTRA
;
2093 static HRESULT WINAPI
ISF_Desktop_fnMapNameToSCID(
2094 IShellFolder2
* iface
,
2098 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2099 FIXME("(%p)\n",This
);
2103 static ICOM_VTABLE(IShellFolder2
) sfdvt
=
2105 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2106 ISF_Desktop_fnQueryInterface
,
2107 IShellFolder_fnAddRef
,
2108 IShellFolder_fnRelease
,
2109 ISF_Desktop_fnParseDisplayName
,
2110 ISF_Desktop_fnEnumObjects
,
2111 ISF_Desktop_fnBindToObject
,
2112 IShellFolder_fnBindToStorage
,
2113 IShellFolder_fnCompareIDs
,
2114 ISF_Desktop_fnCreateViewObject
,
2115 ISF_Desktop_fnGetAttributesOf
,
2116 IShellFolder_fnGetUIObjectOf
,
2117 ISF_Desktop_fnGetDisplayNameOf
,
2118 IShellFolder_fnSetNameOf
,
2121 ISF_Desktop_fnGetDefaultSearchGUID
,
2122 ISF_Desktop_fnEnumSearches
,
2123 ISF_Desktop_fnGetDefaultColumn
,
2124 ISF_Desktop_fnGetDefaultColumnState
,
2125 ISF_Desktop_fnGetDetailsEx
,
2126 ISF_Desktop_fnGetDetailsOf
,
2127 ISF_Desktop_fnMapNameToSCID
2131 /***********************************************************************
2132 * IShellFolder [MyComputer] implementation
2135 static struct ICOM_VTABLE(IShellFolder2
) sfmcvt
;
2137 static shvheader MyComputerSFHeader
[] =
2139 { IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15 },
2140 { IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2141 { IDS_SHV_COLUMN6
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2142 { IDS_SHV_COLUMN7
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10 },
2144 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2146 /**************************************************************************
2147 * ISF_MyComputer_Constructor
2149 static IShellFolder
* ISF_MyComputer_Constructor(void)
2151 IGenericSFImpl
* sf
;
2153 sf
=(IGenericSFImpl
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IGenericSFImpl
));
2156 ICOM_VTBL(sf
)=&unkvt
;
2157 sf
->lpvtblShellFolder
=&sfmcvt
;
2158 sf
->lpvtblPersistFolder2
= &psfvt
;
2159 sf
->pclsid
= (CLSID
*)&CLSID_SFMyComp
;
2160 sf
->absPidl
=_ILCreateMyComputer(); /* my qualified pidl */
2161 sf
->pUnkOuter
= (IUnknown
*) &sf
->lpVtbl
;
2166 return _IShellFolder_(sf
);
2169 /**************************************************************************
2170 * ISF_MyComputer_fnParseDisplayName
2172 static HRESULT WINAPI
ISF_MyComputer_fnParseDisplayName(
2173 IShellFolder2
* iface
,
2176 LPOLESTR lpszDisplayName
,
2178 LPITEMIDLIST
*ppidl
,
2179 DWORD
*pdwAttributes
)
2181 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2183 HRESULT hr
= E_OUTOFMEMORY
;
2184 LPCWSTR szNext
=NULL
;
2185 WCHAR szElement
[MAX_PATH
];
2186 CHAR szTempA
[MAX_PATH
];
2187 LPITEMIDLIST pidlTemp
;
2189 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2190 This
,hwndOwner
,pbcReserved
,lpszDisplayName
,
2191 debugstr_w(lpszDisplayName
),pchEaten
,ppidl
,pdwAttributes
);
2194 if (pchEaten
) *pchEaten
= 0; /* strange but like the original */
2196 /* do we have an absolute path name ? */
2197 if (PathGetDriveNumberW(lpszDisplayName
) >= 0 &&
2198 lpszDisplayName
[2] == (WCHAR
)'\\')
2200 szNext
= GetNextElementW(lpszDisplayName
, szElement
, MAX_PATH
);
2201 WideCharToMultiByte( CP_ACP
, 0, szElement
, -1, szTempA
, MAX_PATH
, NULL
, NULL
);
2202 pidlTemp
= _ILCreateDrive(szTempA
);
2204 if (szNext
&& *szNext
)
2206 hr
= SHELL32_ParseNextElement(hwndOwner
, iface
, &pidlTemp
, (LPOLESTR
)szNext
, pchEaten
, pdwAttributes
);
2210 if (pdwAttributes
&& *pdwAttributes
)
2212 SHELL32_GetItemAttributes(_IShellFolder_(This
), pidlTemp
, pdwAttributes
);
2219 TRACE("(%p)->(-- ret=0x%08lx)\n", This
, hr
);
2224 /**************************************************************************
2225 * ISF_MyComputer_fnEnumObjects
2227 static HRESULT WINAPI
ISF_MyComputer_fnEnumObjects(
2228 IShellFolder2
* iface
,
2231 LPENUMIDLIST
* ppEnumIDList
)
2233 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2235 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This
,hwndOwner
,dwFlags
,ppEnumIDList
);
2237 *ppEnumIDList
= NULL
;
2238 *ppEnumIDList
= IEnumIDList_Constructor (NULL
, dwFlags
, EIDL_MYCOMP
);
2240 TRACE("-- (%p)->(new ID List: %p)\n",This
,*ppEnumIDList
);
2242 if(!*ppEnumIDList
) return E_OUTOFMEMORY
;
2247 /**************************************************************************
2248 * ISF_MyComputer_fnBindToObject
2250 static HRESULT WINAPI
ISF_MyComputer_fnBindToObject( IShellFolder2
* iface
, LPCITEMIDLIST pidl
,
2251 LPBC pbcReserved
, REFIID riid
, LPVOID
* ppvOut
)
2253 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2255 IShellFolder
*pShellFolder
, *pSubFolder
;
2256 LPITEMIDLIST pidltemp
;
2259 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2260 This
,pidl
,pbcReserved
,debugstr_guid(riid
),ppvOut
);
2262 if(!pidl
|| !ppvOut
) return E_INVALIDARG
;
2266 if ((clsid
=_ILGetGUIDPointer(pidl
)) && !IsEqualIID(clsid
, &CLSID_MyComputer
))
2268 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This
->absPidl
, pidl
, clsid
, riid
, (LPVOID
*)&pShellFolder
)))
2275 if (!_ILIsDrive(pidl
)) return E_INVALIDARG
;
2277 pidltemp
= ILCloneFirst(pidl
);
2278 pShellFolder
= IShellFolder_Constructor(iface
, pidltemp
);
2282 if (_ILIsPidlSimple(pidl
)) /* no sub folders */
2284 *ppvOut
= pShellFolder
;
2287 else /* go deeper */
2289 hr
= IShellFolder_BindToObject(pShellFolder
, ILGetNext(pidl
), NULL
,
2290 riid
, (LPVOID
)&pSubFolder
);
2291 IShellFolder_Release(pShellFolder
);
2292 *ppvOut
= pSubFolder
;
2295 TRACE("-- (%p) returning (%p) %08lx\n",This
, *ppvOut
, hr
);
2300 /**************************************************************************
2301 * ISF_MyComputer_fnCreateViewObject
2303 static HRESULT WINAPI
ISF_MyComputer_fnCreateViewObject( IShellFolder2
* iface
,
2304 HWND hwndOwner
, REFIID riid
, LPVOID
*ppvOut
)
2306 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2308 LPSHELLVIEW pShellView
;
2309 HRESULT hr
= E_INVALIDARG
;
2311 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This
,hwndOwner
,debugstr_guid(riid
),ppvOut
);
2317 if(IsEqualIID(riid
, &IID_IDropTarget
))
2319 WARN("IDropTarget not implemented\n");
2322 else if(IsEqualIID(riid
, &IID_IContextMenu
))
2324 WARN("IContextMenu not implemented\n");
2327 else if(IsEqualIID(riid
, &IID_IShellView
))
2329 pShellView
= IShellView_Constructor((IShellFolder
*)iface
);
2332 hr
= IShellView_QueryInterface(pShellView
, riid
, ppvOut
);
2333 IShellView_Release(pShellView
);
2337 TRACE("-- (%p)->(interface=%p)\n",This
, ppvOut
);
2341 /**************************************************************************
2342 * ISF_MyComputer_fnGetAttributesOf
2344 static HRESULT WINAPI
ISF_MyComputer_fnGetAttributesOf(
2345 IShellFolder2
* iface
,
2347 LPCITEMIDLIST
*apidl
,
2350 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2354 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This
,cidl
,apidl
,*rgfInOut
);
2356 if ( (!cidl
) || (!apidl
) || (!rgfInOut
))
2357 return E_INVALIDARG
;
2359 while (cidl
> 0 && *apidl
)
2362 SHELL32_GetItemAttributes(_IShellFolder_(This
), *apidl
, rgfInOut
);
2367 TRACE("-- result=0x%08lx\n",*rgfInOut
);
2371 /**************************************************************************
2372 * ISF_MyComputer_fnGetDisplayNameOf
2375 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2376 * SHGDN_INFOLDER makes no sense.
2378 static HRESULT WINAPI
ISF_MyComputer_fnGetDisplayNameOf(
2379 IShellFolder2
* iface
,
2384 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2386 char szPath
[MAX_PATH
], szDrive
[18];
2390 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This
,pidl
,dwFlags
,strRet
);
2393 if(!strRet
) return E_INVALIDARG
;
2395 szPath
[0]=0x00; szDrive
[0]=0x00;
2398 bSimplePidl
= _ILIsPidlSimple(pidl
);
2400 if (_ILIsSpecialFolder(pidl
))
2402 /* take names of special folders only if its only this folder */
2405 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2410 if (!_ILIsDrive(pidl
))
2412 ERR("Wrong pidl type\n");
2413 return E_INVALIDARG
;
2416 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
); /* append my own path */
2418 /* long view "lw_name (C:)" */
2419 if ( bSimplePidl
&& !(dwFlags
& SHGDN_FORPARSING
))
2421 DWORD dwVolumeSerialNumber
,dwMaximumComponetLength
,dwFileSystemFlags
;
2423 GetVolumeInformationA(szPath
,szDrive
,sizeof(szDrive
)-6,&dwVolumeSerialNumber
,&dwMaximumComponetLength
,&dwFileSystemFlags
,NULL
,0);
2424 strcat (szDrive
," (");
2425 strncat (szDrive
, szPath
, 2);
2426 strcat (szDrive
,")");
2427 strcpy (szPath
, szDrive
);
2431 if (!bSimplePidl
) /* go deeper if needed */
2433 PathAddBackslashA(szPath
);
2434 len
= strlen(szPath
);
2436 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface
, pidl
, dwFlags
| SHGDN_FORPARSING
, szPath
+ len
, MAX_PATH
- len
)))
2437 return E_OUTOFMEMORY
;
2439 strRet
->uType
= STRRET_CSTRA
;
2440 lstrcpynA(strRet
->u
.cStr
, szPath
, MAX_PATH
);
2443 TRACE("-- (%p)->(%s)\n", This
, szPath
);
2447 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultSearchGUID(
2448 IShellFolder2
* iface
,
2451 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2452 FIXME("(%p)\n",This
);
2455 static HRESULT WINAPI
ISF_MyComputer_fnEnumSearches(
2456 IShellFolder2
* iface
,
2457 IEnumExtraSearch
**ppenum
)
2459 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2460 FIXME("(%p)\n",This
);
2463 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumn(
2464 IShellFolder2
* iface
,
2469 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2471 TRACE("(%p)\n",This
);
2473 if (pSort
) *pSort
= 0;
2474 if (pDisplay
) *pDisplay
= 0;
2478 static HRESULT WINAPI
ISF_MyComputer_fnGetDefaultColumnState(
2479 IShellFolder2
* iface
,
2483 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2485 TRACE("(%p)\n",This
);
2487 if (!pcsFlags
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2489 *pcsFlags
= MyComputerSFHeader
[iColumn
].pcsFlags
;
2493 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsEx(
2494 IShellFolder2
* iface
,
2496 const SHCOLUMNID
*pscid
,
2499 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2500 FIXME("(%p)\n",This
);
2505 /* FIXME: drive size >4GB is rolling over */
2506 static HRESULT WINAPI
ISF_MyComputer_fnGetDetailsOf(
2507 IShellFolder2
* iface
,
2512 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2515 TRACE("(%p)->(%p %i %p)\n",This
, pidl
, iColumn
, psd
);
2517 if (!psd
|| iColumn
>= MYCOMPUTERSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
2521 psd
->fmt
= MyComputerSFHeader
[iColumn
].fmt
;
2522 psd
->cxChar
= MyComputerSFHeader
[iColumn
].cxChar
;
2523 psd
->str
.uType
= STRRET_CSTRA
;
2524 LoadStringA(shell32_hInstance
, MyComputerSFHeader
[iColumn
].colnameid
, psd
->str
.u
.cStr
, MAX_PATH
);
2529 char szPath
[MAX_PATH
];
2530 ULARGE_INTEGER ulBytes
;
2532 psd
->str
.u
.cStr
[0] = 0x00;
2533 psd
->str
.uType
= STRRET_CSTRA
;
2537 hr
= IShellFolder_GetDisplayNameOf(iface
, pidl
, SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
2540 _ILGetFileType(pidl
, psd
->str
.u
.cStr
, MAX_PATH
);
2542 case 2: /* total size */
2543 if (_ILIsDrive(pidl
))
2545 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2546 GetDiskFreeSpaceExA(szPath
, NULL
, &ulBytes
, NULL
);
2547 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2550 case 3: /* free size */
2551 if (_ILIsDrive(pidl
))
2553 _ILSimpleGetText(pidl
, szPath
, MAX_PATH
);
2554 GetDiskFreeSpaceExA(szPath
, &ulBytes
, NULL
, NULL
);
2555 StrFormatByteSizeA(ulBytes
.s
.LowPart
, psd
->str
.u
.cStr
, MAX_PATH
);
2564 static HRESULT WINAPI
ISF_MyComputer_fnMapNameToSCID(
2565 IShellFolder2
* iface
,
2569 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl
, iface
)
2570 FIXME("(%p)\n",This
);
2574 static ICOM_VTABLE(IShellFolder2
) sfmcvt
=
2576 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2577 IShellFolder_fnQueryInterface
,
2578 IShellFolder_fnAddRef
,
2579 IShellFolder_fnRelease
,
2580 ISF_MyComputer_fnParseDisplayName
,
2581 ISF_MyComputer_fnEnumObjects
,
2582 ISF_MyComputer_fnBindToObject
,
2583 IShellFolder_fnBindToStorage
,
2584 IShellFolder_fnCompareIDs
,
2585 ISF_MyComputer_fnCreateViewObject
,
2586 ISF_MyComputer_fnGetAttributesOf
,
2587 IShellFolder_fnGetUIObjectOf
,
2588 ISF_MyComputer_fnGetDisplayNameOf
,
2589 IShellFolder_fnSetNameOf
,
2592 ISF_MyComputer_fnGetDefaultSearchGUID
,
2593 ISF_MyComputer_fnEnumSearches
,
2594 ISF_MyComputer_fnGetDefaultColumn
,
2595 ISF_MyComputer_fnGetDefaultColumnState
,
2596 ISF_MyComputer_fnGetDetailsEx
,
2597 ISF_MyComputer_fnGetDetailsOf
,
2598 ISF_MyComputer_fnMapNameToSCID
2602 /************************************************************************
2603 * ISFPersistFolder_QueryInterface (IUnknown)
2606 static HRESULT WINAPI
ISFPersistFolder2_QueryInterface(
2607 IPersistFolder2
* iface
,
2611 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2613 TRACE("(%p)\n", This
);
2615 return IUnknown_QueryInterface(This
->pUnkOuter
, iid
, ppvObj
);
2618 /************************************************************************
2619 * ISFPersistFolder_AddRef (IUnknown)
2622 static ULONG WINAPI
ISFPersistFolder2_AddRef(
2623 IPersistFolder2
* iface
)
2625 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2627 TRACE("(%p)\n", This
);
2629 return IUnknown_AddRef(This
->pUnkOuter
);
2632 /************************************************************************
2633 * ISFPersistFolder_Release (IUnknown)
2636 static ULONG WINAPI
ISFPersistFolder2_Release(
2637 IPersistFolder2
* iface
)
2639 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2641 TRACE("(%p)\n", This
);
2643 return IUnknown_Release(This
->pUnkOuter
);
2646 /************************************************************************
2647 * ISFPersistFolder_GetClassID (IPersist)
2649 static HRESULT WINAPI
ISFPersistFolder2_GetClassID(
2650 IPersistFolder2
* iface
,
2653 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2655 TRACE("(%p)\n", This
);
2657 if (!lpClassId
) return E_POINTER
;
2658 *lpClassId
= *This
->pclsid
;
2663 /************************************************************************
2664 * ISFPersistFolder_Initialize (IPersistFolder)
2667 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2669 static HRESULT WINAPI
ISFPersistFolder2_Initialize(
2670 IPersistFolder2
* iface
,
2673 char sTemp
[MAX_PATH
];
2674 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2676 TRACE("(%p)->(%p)\n", This
, pidl
);
2678 /* free the old stuff */
2681 SHFree(This
->absPidl
);
2682 This
->absPidl
= NULL
;
2686 SHFree(This
->sMyPath
);
2687 This
->sMyPath
= NULL
;
2691 This
->absPidl
= ILClone(pidl
);
2694 if (SHGetPathFromIDListA(pidl
, sTemp
))
2696 This
->sMyPath
= SHAlloc(strlen(sTemp
)+1);
2697 strcpy(This
->sMyPath
, sTemp
);
2700 TRACE("--(%p)->(%s)\n", This
, This
->sMyPath
);
2705 /**************************************************************************
2706 * IPersistFolder2_fnGetCurFolder
2708 static HRESULT WINAPI
ISFPersistFolder2_fnGetCurFolder(
2709 IPersistFolder2
* iface
,
2710 LPITEMIDLIST
* pidl
)
2712 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl
, iface
);
2714 TRACE("(%p)->(%p)\n",This
, pidl
);
2716 if (!pidl
) return E_POINTER
;
2718 *pidl
= ILClone(This
->absPidl
);
2723 static ICOM_VTABLE(IPersistFolder2
) psfvt
=
2725 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2726 ISFPersistFolder2_QueryInterface
,
2727 ISFPersistFolder2_AddRef
,
2728 ISFPersistFolder2_Release
,
2729 ISFPersistFolder2_GetClassID
,
2730 ISFPersistFolder2_Initialize
,
2731 ISFPersistFolder2_fnGetCurFolder
2734 /****************************************************************************
2735 * ISFDropTarget implementation
2737 static BOOL
ISFDropTarget_QueryDrop(
2742 DWORD dwEffect
= *pdwEffect
;
2744 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2746 *pdwEffect
= DROPEFFECT_NONE
;
2748 if (This
->fAcceptFmt
)
2749 { /* Does our interpretation of the keystate ... */
2750 *pdwEffect
= KeyStateToDropEffect(dwKeyState
);
2752 /* ... matches the desired effect ? */
2753 if (dwEffect
& *pdwEffect
)
2761 static HRESULT WINAPI
ISFDropTarget_QueryInterface(
2766 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2768 TRACE("(%p)\n", This
);
2770 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppvObj
);
2773 static ULONG WINAPI
ISFDropTarget_AddRef( IDropTarget
*iface
)
2775 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2777 TRACE("(%p)\n", This
);
2779 return IUnknown_AddRef(This
->pUnkOuter
);
2782 static ULONG WINAPI
ISFDropTarget_Release( IDropTarget
*iface
)
2784 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2786 TRACE("(%p)\n", This
);
2788 return IUnknown_Release(This
->pUnkOuter
);
2791 static HRESULT WINAPI
ISFDropTarget_DragEnter(
2793 IDataObject
*pDataObject
,
2800 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2802 TRACE("(%p)->(DataObject=%p)\n",This
,pDataObject
);
2804 InitFormatEtc(fmt
, This
->cfShellIDList
, TYMED_HGLOBAL
);
2806 This
->fAcceptFmt
= (S_OK
== IDataObject_QueryGetData(pDataObject
, &fmt
)) ? TRUE
: FALSE
;
2808 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2813 static HRESULT WINAPI
ISFDropTarget_DragOver(
2819 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2821 TRACE("(%p)\n",This
);
2823 if(!pdwEffect
) return E_INVALIDARG
;
2825 ISFDropTarget_QueryDrop(iface
, dwKeyState
, pdwEffect
);
2830 static HRESULT WINAPI
ISFDropTarget_DragLeave(
2833 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2835 TRACE("(%p)\n",This
);
2837 This
->fAcceptFmt
= FALSE
;
2842 static HRESULT WINAPI
ISFDropTarget_Drop(
2844 IDataObject
* pDataObject
,
2849 _ICOM_THIS_From_IDropTarget(IGenericSFImpl
,iface
);
2851 FIXME("(%p) object dropped\n",This
);
2856 static struct ICOM_VTABLE(IDropTarget
) dtvt
=
2858 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2859 ISFDropTarget_QueryInterface
,
2860 ISFDropTarget_AddRef
,
2861 ISFDropTarget_Release
,
2862 ISFDropTarget_DragEnter
,
2863 ISFDropTarget_DragOver
,
2864 ISFDropTarget_DragLeave
,