4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
7 * IShellFolder with IDropTarget, IPersistFolder
14 #include "debugtools.h"
21 #include "wine/obj_base.h"
22 #include "wine/obj_dragdrop.h"
23 #include "wine/obj_shellfolder.h"
24 #include "wine/undocshell.h"
25 #include "shell32_main.h"
27 DEFAULT_DEBUG_CHANNEL(shell)
31 /***************************************************************************
32 * GetNextElement (internal function)
34 * gets a part of a string till the first backslash
37 * pszNext [IN] string to get the element from
38 * pszOut [IN] pointer to buffer whitch receives string
39 * dwOut [IN] length of pszOut
42 * LPSTR pointer to first, not yet parsed char
45 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
46 { LPCWSTR pszTail = pszNext;
48 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
52 if(!pszNext || !*pszNext)
55 while(*pszTail && (*pszTail != (WCHAR)'\\'))
58 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
59 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
66 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
70 static HRESULT SHELL32_ParseNextElement(
73 LPITEMIDLIST * pidlInOut,
78 HRESULT hr = E_OUTOFMEMORY;
79 LPITEMIDLIST pidlOut, pidlTemp = NULL;
80 IShellFolder *psfChild;
82 TRACE("(%p %p %s)\n",psf, pidlInOut? *pidlInOut: NULL, debugstr_w(szNext));
85 /* get the shellfolder for the child pidl and let it analyse further */
86 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
90 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
91 IShellFolder_Release(psfChild);
93 pidlTemp = ILCombine(*pidlInOut, pidlOut);
100 *pidlInOut = pidlTemp;
102 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
106 /***********************************************************************
107 * SHELL32_CoCreateInitSF
109 * creates a initialized shell folder
111 static HRESULT SHELL32_CoCreateInitSF (
112 LPITEMIDLIST pidlRoot,
113 LPITEMIDLIST pidlChild,
119 LPITEMIDLIST absPidl;
120 IShellFolder2 *pShellFolder;
121 IPersistFolder *pPersistFolder;
123 TRACE("%p %p\n", pidlRoot, pidlChild);
127 /* we have to ask first for IPersistFolder, some special folders are expecting this */
128 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
131 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
134 absPidl = ILCombine (pidlRoot, pidlChild);
135 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
136 IPersistFolder_Release(pPersistFolder);
138 *ppvOut = pShellFolder;
142 TRACE("-- ret=0x%08lx\n", hr);
146 static HRESULT SHELL32_GetDisplayNameOfChild(
153 LPITEMIDLIST pidlFirst, pidlNext;
154 IShellFolder2 * psfChild;
155 HRESULT hr = E_OUTOFMEMORY;
158 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
161 if ((pidlFirst = ILCloneFirst(pidl)))
163 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
166 pidlNext = ILGetNext(pidl);
168 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
171 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
174 IShellFolder_Release(psfChild);
179 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
184 /***********************************************************************
185 * IShellFolder implementation
190 ICOM_VFIELD(IShellFolder2);
193 ICOM_VTABLE(IPersistFolder)* lpvtblPersistFolder;
194 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
199 LPITEMIDLIST absPidl; /* complete pidl */
201 UINT cfShellIDList; /* clipboardformat for IDropTarget */
202 BOOL fAcceptFmt; /* flag for pending Drop */
205 static struct ICOM_VTABLE(IShellFolder2) sfvt;
206 static struct ICOM_VTABLE(IPersistFolder) psfvt;
207 static struct ICOM_VTABLE(IDropTarget) dtvt;
209 static IShellFolder * ISF_MyComputer_Constructor(void);
211 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder)))
212 #define _ICOM_THIS_From_IPersistFolder(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
214 static struct ICOM_VTABLE(IDropTarget) dtvt;
215 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
216 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
218 /**************************************************************************
219 * registers clipboardformat once
221 static void SF_RegisterClipFmt (IShellFolder2 * iface)
223 ICOM_THIS(IGenericSFImpl, iface);
225 TRACE("(%p)\n", This);
227 if (!This->cfShellIDList)
229 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
233 /**************************************************************************
234 * IShellFolder_Constructor
238 static IShellFolder * IShellFolder_Constructor(
243 IGenericSFImpl * sfParent = (IGenericSFImpl*) psf;
246 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
250 sf->lpvtblPersistFolder=&psfvt;
251 sf->lpvtblDropTarget=&dtvt;
252 sf->pclsid = (CLSID*)&CLSID_SFFile;
254 sf->fAcceptFmt=FALSE;
256 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,sfParent, pidl);
259 if(pidl) /* do we have a pidl? */
263 sf->absPidl = ILCombine(sfParent->absPidl, pidl); /* build a absolute pidl */
265 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
267 if(sfParent->sMyPath) /* get the size of the parents path */
269 dwSize += strlen(sfParent->sMyPath) ;
270 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(sfParent->sMyPath));
273 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
274 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
276 if(!sf->sMyPath) return NULL;
279 if(sfParent->sMyPath) /* if the parent has a path, get it*/
281 strcpy(sf->sMyPath, sfParent->sMyPath);
282 PathAddBackslashA (sf->sMyPath);
285 len = strlen(sf->sMyPath);
286 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize - len + 1);
289 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
295 return (IShellFolder *)sf;
297 /**************************************************************************
298 * IShellFolder_fnQueryInterface
301 * REFIID riid [in ] Requested InterfaceID
302 * LPVOID* ppvObject [out] Interface* to hold the result
304 static HRESULT WINAPI IShellFolder_fnQueryInterface(
305 IShellFolder2 * iface,
309 ICOM_THIS(IGenericSFImpl, iface);
312 WINE_StringFromCLSID((LPCLSID)riid,xriid);
313 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
317 if(IsEqualIID(riid, &IID_IUnknown))
320 else if(IsEqualIID(riid, &IID_IShellFolder))
322 *ppvObj = (IShellFolder*)This;
324 else if(IsEqualIID(riid, &IID_IShellFolder2))
326 *ppvObj = (IShellFolder2*)This;
328 else if(IsEqualIID(riid, &IID_IPersist))
330 *ppvObj = (IPersistFolder*)&(This->lpvtblPersistFolder);
332 else if(IsEqualIID(riid, &IID_IPersistFolder))
334 *ppvObj = (IPersistFolder*)&(This->lpvtblPersistFolder);
336 else if(IsEqualIID(riid, &IID_IDropTarget))
338 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
339 SF_RegisterClipFmt((IShellFolder2*)This);
344 IUnknown_AddRef((IUnknown*)(*ppvObj));
345 TRACE("-- Interface = %p\n", *ppvObj);
348 TRACE("-- Interface: E_NOINTERFACE\n");
349 return E_NOINTERFACE;
352 /**************************************************************************
353 * IShellFolder_AddRef
356 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
358 ICOM_THIS(IGenericSFImpl, iface);
361 TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
363 TRACE("(%p)->(count=%lu)\n",This,This->ref);
366 return ++(This->ref);
369 /**************************************************************************
370 * IShellFolder_fnRelease
372 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
374 ICOM_THIS(IGenericSFImpl, iface);
377 TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
379 TRACE("(%p)->(count=%lu)\n",This,This->ref);
383 { TRACE("-- destroying IShellFolder(%p)\n",This);
385 if (pdesktopfolder == (IShellFolder*) iface)
386 { pdesktopfolder=NULL;
387 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
390 { SHFree(This->absPidl);
393 { SHFree(This->sMyPath);
396 HeapFree(GetProcessHeap(),0,This);
402 /**************************************************************************
403 * IShellFolder_fnParseDisplayName
405 * HWND hwndOwner, //[in ] Parent window for any message's
406 * LPBC pbc, //[in ] reserved
407 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
408 * ULONG* pchEaten, //[out] (unicode) characters processed
409 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
410 * ULONG* pdwAttributes //[out] items attributes
413 * every folder trys to parse only it's own (the leftmost) pidl and creates a
414 * subfolder to evaluate the remaining parts
415 * now we can parse into namespaces implemented by shell extensions
417 * behaviour on win98: lpszDisplayName=NULL -> chrash
418 * lpszDisplayName="" -> returns mycoputer-pidl
421 * pdwAttributes: not set
422 * pchEaten: not set like in windows
424 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
425 IShellFolder2 * iface,
428 LPOLESTR lpszDisplayName,
431 DWORD *pdwAttributes)
433 ICOM_THIS(IGenericSFImpl, iface);
435 HRESULT hr = E_OUTOFMEMORY;
437 WCHAR szElement[MAX_PATH];
438 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
439 LPITEMIDLIST pidlTemp=NULL;
441 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
442 This,hwndOwner,pbcReserved,lpszDisplayName,
443 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
445 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
447 if (pchEaten) *pchEaten = 0; /* strange but like the original */
449 if (*lpszDisplayName)
451 /* get the next element */
452 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
454 /* build the full pathname to the element */
455 WideCharToLocal(szTempA, szElement, lstrlenW(szElement) + 1);
456 strcpy(szPath, This->sMyPath);
457 PathAddBackslashA(szPath);
458 strcat(szPath, szTempA);
461 pidlTemp = SHSimpleIDListFromPathA(szPath);
465 /* try to analyse the next element */
466 if (szNext && *szNext)
468 hr = SHELL32_ParseNextElement(hwndOwner, (IShellFolder2*)This, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
479 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
484 /**************************************************************************
485 * IShellFolder_fnEnumObjects
487 * HWND hwndOwner, //[in ] Parent Window
488 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
489 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
491 static HRESULT WINAPI IShellFolder_fnEnumObjects(
492 IShellFolder2 * iface,
495 LPENUMIDLIST* ppEnumIDList)
497 ICOM_THIS(IGenericSFImpl, iface);
499 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
501 *ppEnumIDList = NULL;
502 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
504 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
506 if(!*ppEnumIDList) return E_OUTOFMEMORY;
511 /**************************************************************************
512 * IShellFolder_fnBindToObject
514 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
515 * LPBC pbc, //[in ] reserved
516 * REFIID riid, //[in ] Initial Interface
517 * LPVOID* ppvObject //[out] Interface*
519 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
520 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
522 ICOM_THIS(IGenericSFImpl, iface);
525 IShellFolder *pShellFolder, *pSubFolder;
526 IPersistFolder *pPersistFolder;
527 LPITEMIDLIST absPidl;
529 WINE_StringFromCLSID(riid,xriid);
531 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
533 if(!pidl || !ppvOut) return E_INVALIDARG;
537 if ((iid=_ILGetGUIDPointer(pidl)))
539 /* we have to create a alien folder */
540 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
541 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
543 absPidl = ILCombine (This->absPidl, pidl);
544 IPersistFolder_Initialize(pPersistFolder, absPidl);
545 IPersistFolder_Release(pPersistFolder);
555 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
556 pShellFolder = IShellFolder_Constructor((IShellFolder*)This, pidltemp);
560 if (_ILIsPidlSimple(pidl))
562 *ppvOut = pShellFolder;
566 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
567 IShellFolder_Release(pShellFolder);
568 *ppvOut = pSubFolder;
571 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
576 /**************************************************************************
577 * IShellFolder_fnBindToStorage
579 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
580 * LPBC pbc, //[in ] reserved
581 * REFIID riid, //[in ] Initial storage interface
582 * LPVOID* ppvObject //[out] Interface* returned
584 static HRESULT WINAPI IShellFolder_fnBindToStorage(
585 IShellFolder2 * iface,
591 ICOM_THIS(IGenericSFImpl, iface);
594 WINE_StringFromCLSID(riid,xriid);
596 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",This,pidl,pbcReserved,xriid,ppvOut);
602 /**************************************************************************
603 * IShellFolder_fnCompareIDs
606 * LPARAM lParam, //[in ] Column?
607 * LPCITEMIDLIST pidl1, //[in ] simple pidl
608 * LPCITEMIDLIST pidl2) //[in ] simple pidl
611 * Special case - If one of the items is a Path and the other is a File,
612 * always make the Path come before the File.
615 * use SCODE_CODE() on the return value to get the result
618 static HRESULT WINAPI IShellFolder_fnCompareIDs(
619 IShellFolder2 * iface,
624 ICOM_THIS(IGenericSFImpl, iface);
626 CHAR szTemp1[MAX_PATH];
627 CHAR szTemp2[MAX_PATH];
630 HRESULT hr = E_OUTOFMEMORY;
631 LPCITEMIDLIST pidlTemp;
634 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
638 if (!pidl1 && !pidl2)
640 hr = ResultFromShort(0);
644 hr = ResultFromShort(-1);
648 hr = ResultFromShort(1);
653 pd1 = _ILGetDataPointer(pidl1);
654 pd2 = _ILGetDataPointer(pidl2);
656 /* compate the types. sort order is the PT_* constant */
657 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
658 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
662 hr = ResultFromShort(pt1-pt2);
664 else /* same type of pidl */
666 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
667 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
668 nReturn = strcasecmp(szTemp1, szTemp2);
670 if (nReturn == 0) /* first pidl different ? */
672 pidl1 = ILGetNext(pidl1);
674 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
676 pidlTemp = ILCloneFirst(pidl1);
677 pidl2 = ILGetNext(pidl2);
679 hr = IShellFolder_BindToObject((IShellFolder*)This, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
682 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
683 IShellFolder_Release(psf);
684 hr = ResultFromShort(nReturn);
690 hr = ResultFromShort(nReturn); /* two equal simple pidls */
695 hr = ResultFromShort(nReturn); /* two different simple pidls */
700 TRACE("-- res=0x%08lx\n", hr);
704 /**************************************************************************
705 * IShellFolder_fnCreateViewObject
707 static HRESULT WINAPI IShellFolder_fnCreateViewObject( IShellFolder2 * iface,
708 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
710 ICOM_THIS(IGenericSFImpl, iface);
712 LPSHELLVIEW pShellView;
714 HRESULT hr = E_INVALIDARG;
716 WINE_StringFromCLSID(riid,xriid);
717 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
723 if(IsEqualIID(riid, &IID_IDropTarget))
725 hr = IShellFolder_QueryInterface((IShellFolder*)This, &IID_IDropTarget, ppvOut);
727 else if(IsEqualIID(riid, &IID_IContextMenu))
729 FIXME("IContextMenu not implemented\n");
732 else if(IsEqualIID(riid, &IID_IShellView))
734 pShellView = IShellView_Constructor((IShellFolder *) This);
737 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
738 IShellView_Release(pShellView);
742 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
746 /**************************************************************************
747 * IShellFolder_fnGetAttributesOf
750 * UINT cidl, //[in ] num elements in pidl array
751 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
752 * ULONG* rgfInOut) //[out] result array
755 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
757 ICOM_THIS(IGenericSFImpl, iface);
761 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
763 if ( (!cidl) || (!apidl) || (!rgfInOut))
766 while (cidl > 0 && *apidl)
769 if (_ILIsFolder( *apidl))
771 *rgfInOut &= 0xe0000177;
774 else if (_ILIsValue( *apidl))
776 *rgfInOut &= 0x40000177;
785 TRACE("-- result=0x%08lx\n",*rgfInOut);
789 /**************************************************************************
790 * IShellFolder_fnGetUIObjectOf
793 * HWND hwndOwner, //[in ] Parent window for any output
794 * UINT cidl, //[in ] array size
795 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
796 * REFIID riid, //[in ] Requested Interface
797 * UINT* prgfInOut, //[ ] reserved
798 * LPVOID* ppvObject) //[out] Resulting Interface
801 * This function gets asked to return "view objects" for one or more (multiple select)
803 * The viewobject typically is an COM object with one of the following interfaces:
804 * IExtractIcon,IDataObject,IContextMenu
805 * In order to support icon positions in the default Listview your DataObject
806 * must implement the SetData method (in addition to GetData :) - the shell passes
807 * a barely documented "Icon positions" structure to SetData when the drag starts,
808 * and GetData's it if the drop is in another explorer window that needs the positions.
810 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
811 IShellFolder2 * iface,
814 LPCITEMIDLIST * apidl,
819 ICOM_THIS(IGenericSFImpl, iface);
823 IUnknown* pObj = NULL;
824 HRESULT hr = E_INVALIDARG;
826 WINE_StringFromCLSID(riid,xclsid);
828 TRACE("(%p)->(%u,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
829 This,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut);
835 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
837 pObj = (LPUNKNOWN)IContextMenu_Constructor((IShellFolder *)This, This->absPidl, apidl, cidl);
840 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
842 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
845 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
847 pidl = ILCombine(This->absPidl,apidl[0]);
848 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
852 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
854 hr = IShellFolder_QueryInterface((IShellFolder*)This, &IID_IDropTarget, (LPVOID*)&pObj);
866 TRACE("(%p)->hr=0x%08lx\n",This, hr);
870 /**************************************************************************
871 * IShellFolder_fnGetDisplayNameOf
872 * Retrieves the display name for the specified file object or subfolder
875 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
876 * DWORD dwFlags, //[in ] SHGNO formatting flags
877 * LPSTRRET lpName) //[out] Returned display name
880 * if the name is in the pidl the ret value should be a STRRET_OFFSET
882 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
883 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
885 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
886 IShellFolder2 * iface,
891 ICOM_THIS(IGenericSFImpl, iface);
893 CHAR szPath[MAX_PATH]= "";
897 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
900 if(!pidl || !strRet) return E_INVALIDARG;
902 bSimplePidl = _ILIsPidlSimple(pidl);
904 /* take names of special folders only if its only this folder */
905 if (_ILIsSpecialFolder(pidl))
909 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
914 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
916 strcpy (szPath, This->sMyPath); /* get path to root*/
917 PathAddBackslashA(szPath);
918 len = strlen(szPath);
920 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
923 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
925 PathAddBackslashA(szPath);
926 len = strlen(szPath);
928 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild((IShellFolder2*)This, pidl, dwFlags, szPath + len, MAX_PATH - len)))
929 return E_OUTOFMEMORY;
931 strRet->uType = STRRET_CSTRA;
932 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
934 TRACE("-- (%p)->(%s)\n", This, szPath);
938 /**************************************************************************
939 * IShellFolder_fnSetNameOf
940 * Changes the name of a file object or subfolder, possibly changing its item
941 * identifier in the process.
944 * HWND hwndOwner, //[in ] Owner window for output
945 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
946 * LPCOLESTR lpszName, //[in ] the items new display name
947 * DWORD dwFlags, //[in ] SHGNO formatting flags
948 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
950 static HRESULT WINAPI IShellFolder_fnSetNameOf(
951 IShellFolder2 * iface,
953 LPCITEMIDLIST pidl, /*simple pidl*/
956 LPITEMIDLIST *pPidlOut)
958 ICOM_THIS(IGenericSFImpl, iface);
960 FIXME("(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
961 This,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut);
966 /**************************************************************************
967 * IShellFolder_fnGetFolderPath
969 static HRESULT WINAPI IShellFolder_fnGetFolderPath(IShellFolder2 * iface, LPSTR lpszOut, DWORD dwOutSize)
971 ICOM_THIS(IGenericSFImpl, iface);
973 TRACE("(%p)->(%p %lu)\n",This, lpszOut, dwOutSize);
975 if (!lpszOut) return FALSE;
979 if (! This->sMyPath) return FALSE;
981 lstrcpynA(lpszOut, This->sMyPath, dwOutSize);
983 TRACE("-- (%p)->(return=%s)\n",This, lpszOut);
987 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
988 IShellFolder2 * iface,
991 ICOM_THIS(IGenericSFImpl, iface);
992 TRACE("(%p)\n",This);
995 static HRESULT WINAPI IShellFolder_fnEnumSearches(
996 IShellFolder2 * iface,
997 IEnumExtraSearch **ppenum)
999 ICOM_THIS(IGenericSFImpl, iface);
1000 TRACE("(%p)\n",This);
1003 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1004 IShellFolder2 * iface,
1009 ICOM_THIS(IGenericSFImpl, iface);
1010 TRACE("(%p)\n",This);
1013 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1014 IShellFolder2 * iface,
1018 ICOM_THIS(IGenericSFImpl, iface);
1019 TRACE("(%p)\n",This);
1022 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1023 IShellFolder2 * iface,
1025 const SHCOLUMNID *pscid,
1028 ICOM_THIS(IGenericSFImpl, iface);
1029 TRACE("(%p)\n",This);
1032 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1033 IShellFolder2 * iface,
1038 ICOM_THIS(IGenericSFImpl, iface);
1039 TRACE("(%p)\n",This);
1042 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1043 IShellFolder2 * iface,
1047 ICOM_THIS(IGenericSFImpl, iface);
1048 TRACE("(%p)\n",This);
1052 static ICOM_VTABLE(IShellFolder2) sfvt =
1054 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1055 IShellFolder_fnQueryInterface,
1056 IShellFolder_fnAddRef,
1057 IShellFolder_fnRelease,
1058 IShellFolder_fnParseDisplayName,
1059 IShellFolder_fnEnumObjects,
1060 IShellFolder_fnBindToObject,
1061 IShellFolder_fnBindToStorage,
1062 IShellFolder_fnCompareIDs,
1063 IShellFolder_fnCreateViewObject,
1064 IShellFolder_fnGetAttributesOf,
1065 IShellFolder_fnGetUIObjectOf,
1066 IShellFolder_fnGetDisplayNameOf,
1067 IShellFolder_fnSetNameOf,
1070 IShellFolder_fnGetDefaultSearchGUID,
1071 IShellFolder_fnEnumSearches,
1072 IShellFolder_fnGetDefaultColumn,
1073 IShellFolder_fnGetDefaultColumnState,
1074 IShellFolder_fnGetDetailsEx,
1075 IShellFolder_fnGetDetailsOf,
1076 IShellFolder_fnMapNameToSCID
1079 /***********************************************************************
1080 * [Desktopfolder] IShellFolder implementation
1082 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1084 /**************************************************************************
1085 * ISF_Desktop_Constructor
1088 IShellFolder * ISF_Desktop_Constructor()
1090 IGenericSFImpl * sf;
1092 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1094 ICOM_VTBL(sf)=&sfdvt;
1095 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1100 return (IShellFolder *)sf;
1103 /**************************************************************************
1104 * ISF_Desktop_fnQueryInterface
1106 * NOTES supports not IPersist/IPersistFolder
1108 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1109 IShellFolder2 * iface,
1113 ICOM_THIS(IGenericSFImpl, iface);
1116 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1117 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
1121 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1124 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1125 { *ppvObj = (IShellFolder*)This;
1127 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1128 { *ppvObj = (IShellFolder2*)This;
1133 IUnknown_AddRef((IUnknown*)(*ppvObj));
1134 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1137 TRACE("-- Interface: E_NOINTERFACE\n");
1138 return E_NOINTERFACE;
1141 /**************************************************************************
1142 * ISF_Desktop_fnParseDisplayName
1145 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1148 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1149 IShellFolder2 * iface,
1152 LPOLESTR lpszDisplayName,
1154 LPITEMIDLIST *ppidl,
1155 DWORD *pdwAttributes)
1157 ICOM_THIS(IGenericSFImpl, iface);
1159 LPCWSTR szNext=NULL;
1160 LPITEMIDLIST pidlTemp=NULL;
1161 HRESULT hr=E_OUTOFMEMORY;
1163 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1164 This,hwndOwner,pbcReserved,lpszDisplayName,
1165 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1168 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1170 /* fixme no real parsing implemented */
1171 pidlTemp = _ILCreateMyComputer();
1172 szNext = lpszDisplayName;
1174 if (szNext && *szNext)
1176 hr = SHELL32_ParseNextElement(hwndOwner, (IShellFolder2*)This, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1185 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1190 /**************************************************************************
1191 * ISF_Desktop_fnEnumObjects
1193 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1194 IShellFolder2 * iface,
1197 LPENUMIDLIST* ppEnumIDList)
1199 ICOM_THIS(IGenericSFImpl, iface);
1201 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1203 *ppEnumIDList = NULL;
1204 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1206 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1208 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1213 /**************************************************************************
1214 * ISF_Desktop_fnBindToObject
1216 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1217 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1219 ICOM_THIS(IGenericSFImpl, iface);
1222 IShellFolder *pShellFolder, *pSubFolder;
1224 WINE_StringFromCLSID(riid,xriid);
1226 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
1230 if ((clsid=_ILGetGUIDPointer(pidl)))
1232 if ( IsEqualIID(clsid, &IID_MyComputer))
1234 pShellFolder = ISF_MyComputer_Constructor();
1238 /* shell extension */
1239 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1241 return E_INVALIDARG;
1247 /* file system folder on the desktop */
1248 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
1249 pShellFolder = IShellFolder_Constructor((IShellFolder*)This, pidltemp);
1253 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1255 *ppvOut = pShellFolder;
1257 else /* go deeper */
1259 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1260 IShellFolder_Release(pShellFolder);
1261 *ppvOut = pSubFolder;
1264 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1269 /**************************************************************************
1270 * ISF_Desktop_fnCreateViewObject
1272 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1273 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1275 ICOM_THIS(IGenericSFImpl, iface);
1277 LPSHELLVIEW pShellView;
1279 HRESULT hr = E_INVALIDARG;
1281 WINE_StringFromCLSID(riid,xriid);
1282 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
1288 if(IsEqualIID(riid, &IID_IDropTarget))
1290 FIXME("IDropTarget not implemented\n");
1293 else if(IsEqualIID(riid, &IID_IContextMenu))
1295 FIXME("IContextMenu not implemented\n");
1298 else if(IsEqualIID(riid, &IID_IShellView))
1300 pShellView = IShellView_Constructor((IShellFolder *) This);
1303 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1304 IShellView_Release(pShellView);
1308 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1312 /**************************************************************************
1313 * ISF_Desktop_fnGetAttributesOf
1315 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
1317 ICOM_THIS(IGenericSFImpl, iface);
1323 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1325 if ( (!cidl) || (!apidl) || (!rgfInOut))
1326 return E_INVALIDARG;
1328 while (cidl > 0 && *apidl)
1332 if ((clsid=_ILGetGUIDPointer(*apidl)))
1334 if (IsEqualIID(clsid, &IID_MyComputer))
1336 *rgfInOut &= 0xb0000154;
1339 else if (HCR_GetFolderAttributes(clsid, &attributes))
1341 *rgfInOut &= attributes;
1345 { /* some shell-extension */
1346 *rgfInOut &= 0xb0000154;
1349 else if (_ILIsFolder( *apidl))
1351 *rgfInOut &= 0xe0000177;
1354 else if (_ILIsValue( *apidl))
1356 *rgfInOut &= 0x40000177;
1365 TRACE("-- result=0x%08lx\n",*rgfInOut);
1370 /**************************************************************************
1371 * ISF_Desktop_fnGetDisplayNameOf
1374 * special case: pidl = null gives desktop-name back
1376 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1377 IShellFolder2 * iface,
1382 ICOM_THIS(IGenericSFImpl, iface);
1384 CHAR szPath[MAX_PATH]= "";
1386 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1389 if(!strRet) return E_INVALIDARG;
1393 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1395 else if ( _ILIsPidlSimple(pidl) )
1397 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1401 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild((IShellFolder2*)This, pidl, dwFlags, szPath, MAX_PATH)))
1402 return E_OUTOFMEMORY;
1404 strRet->uType = STRRET_CSTRA;
1405 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1408 TRACE("-- (%p)->(%s)\n", This, szPath);
1412 static ICOM_VTABLE(IShellFolder2) sfdvt =
1414 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1415 ISF_Desktop_fnQueryInterface,
1416 IShellFolder_fnAddRef,
1417 IShellFolder_fnRelease,
1418 ISF_Desktop_fnParseDisplayName,
1419 ISF_Desktop_fnEnumObjects,
1420 ISF_Desktop_fnBindToObject,
1421 IShellFolder_fnBindToStorage,
1422 IShellFolder_fnCompareIDs,
1423 ISF_Desktop_fnCreateViewObject,
1424 ISF_Desktop_fnGetAttributesOf,
1425 IShellFolder_fnGetUIObjectOf,
1426 ISF_Desktop_fnGetDisplayNameOf,
1427 IShellFolder_fnSetNameOf,
1430 IShellFolder_fnGetDefaultSearchGUID,
1431 IShellFolder_fnEnumSearches,
1432 IShellFolder_fnGetDefaultColumn,
1433 IShellFolder_fnGetDefaultColumnState,
1434 IShellFolder_fnGetDetailsEx,
1435 IShellFolder_fnGetDetailsOf,
1436 IShellFolder_fnMapNameToSCID
1440 /***********************************************************************
1441 * IShellFolder [MyComputer] implementation
1444 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
1446 /**************************************************************************
1447 * ISF_MyComputer_Constructor
1449 static IShellFolder * ISF_MyComputer_Constructor(void)
1451 IGenericSFImpl * sf;
1453 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1456 ICOM_VTBL(sf) = &sfmcvt;
1457 sf->lpvtblPersistFolder = &psfvt;
1458 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
1459 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
1464 return (IShellFolder *)sf;
1467 /**************************************************************************
1468 * ISF_MyComputer_fnParseDisplayName
1470 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
1471 IShellFolder2 * iface,
1474 LPOLESTR lpszDisplayName,
1476 LPITEMIDLIST *ppidl,
1477 DWORD *pdwAttributes)
1479 ICOM_THIS(IGenericSFImpl, iface);
1481 HRESULT hr = E_OUTOFMEMORY;
1482 LPCWSTR szNext=NULL;
1483 WCHAR szElement[MAX_PATH];
1484 CHAR szTempA[MAX_PATH];
1485 LPITEMIDLIST pidlTemp;
1487 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1488 This,hwndOwner,pbcReserved,lpszDisplayName,
1489 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1492 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1494 if (PathIsRootW(lpszDisplayName))
1496 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
1497 WideCharToLocal(szTempA, szElement, lstrlenW(szElement) + 1);
1498 pidlTemp = _ILCreateDrive(szTempA);
1500 if (szNext && *szNext)
1502 hr = SHELL32_ParseNextElement(hwndOwner, (IShellFolder2*)This, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1511 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1516 /**************************************************************************
1517 * ISF_MyComputer_fnEnumObjects
1519 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
1520 IShellFolder2 * iface,
1523 LPENUMIDLIST* ppEnumIDList)
1525 ICOM_THIS(IGenericSFImpl, iface);
1527 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1529 *ppEnumIDList = NULL;
1530 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
1532 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1534 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1539 /**************************************************************************
1540 * ISF_MyComputer_fnBindToObject
1542 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1543 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1545 ICOM_THIS(IGenericSFImpl, iface);
1548 IShellFolder *pShellFolder, *pSubFolder;
1549 LPITEMIDLIST pidltemp;
1551 WINE_StringFromCLSID(riid,xriid);
1553 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
1555 if(!pidl || !ppvOut) return E_INVALIDARG;
1559 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &IID_MyComputer))
1561 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1568 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
1570 pidltemp = ILCloneFirst(pidl);
1571 pShellFolder = IShellFolder_Constructor((IShellFolder*)This, pidltemp);
1575 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1577 *ppvOut = pShellFolder;
1579 else /* go deeper */
1581 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
1582 IShellFolder_Release(pShellFolder);
1583 *ppvOut = pSubFolder;
1586 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1591 /**************************************************************************
1592 * ISF_MyComputer_fnCreateViewObject
1594 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
1595 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1597 ICOM_THIS(IGenericSFImpl, iface);
1599 LPSHELLVIEW pShellView;
1601 HRESULT hr = E_INVALIDARG;
1603 WINE_StringFromCLSID(riid,xriid);
1604 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
1610 if(IsEqualIID(riid, &IID_IDropTarget))
1612 FIXME("IDropTarget not implemented\n");
1615 else if(IsEqualIID(riid, &IID_IContextMenu))
1617 FIXME("IContextMenu not implemented\n");
1620 else if(IsEqualIID(riid, &IID_IShellView))
1622 pShellView = IShellView_Constructor((IShellFolder *) This);
1625 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1626 IShellView_Release(pShellView);
1630 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1634 /**************************************************************************
1635 * ISF_MyComputer_fnGetAttributesOf
1637 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
1639 ICOM_THIS(IGenericSFImpl, iface);
1645 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
1647 if ( (!cidl) || (!apidl) || (!rgfInOut))
1648 return E_INVALIDARG;
1650 *rgfInOut = 0xffffffff;
1652 while (cidl > 0 && *apidl)
1656 if (_ILIsDrive(*apidl))
1658 *rgfInOut &= 0xf0000144;
1661 else if ((clsid=_ILGetGUIDPointer(*apidl)))
1663 if (HCR_GetFolderAttributes(clsid, &attributes))
1665 *rgfInOut &= attributes;
1675 TRACE("-- result=0x%08lx\n",*rgfInOut);
1679 /**************************************************************************
1680 * ISF_MyComputer_fnGetDisplayNameOf
1683 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
1684 * SHGDN_INFOLDER makes no sense.
1686 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
1687 IShellFolder2 * iface,
1692 ICOM_THIS(IGenericSFImpl, iface);
1694 char szPath[MAX_PATH], szDrive[18];
1698 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1701 if(!strRet) return E_INVALIDARG;
1703 szPath[0]=0x00; szDrive[0]=0x00;
1706 bSimplePidl = _ILIsPidlSimple(pidl);
1708 if (_ILIsSpecialFolder(pidl))
1710 /* take names of special folders only if its only this folder */
1713 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1718 if (!_ILIsDrive(pidl))
1720 ERR("Wrong pidl type\n");
1721 return E_INVALIDARG;
1724 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1726 /* long view "lw_name (C:)" */
1727 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
1729 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
1731 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
1732 strcat (szDrive," (");
1733 strncat (szDrive, szPath, 2);
1734 strcat (szDrive,")");
1735 strcpy (szPath, szDrive);
1739 if (!bSimplePidl) /* go deeper if needed */
1741 PathAddBackslashA(szPath);
1742 len = strlen(szPath);
1744 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild((IShellFolder2*)This, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
1745 return E_OUTOFMEMORY;
1747 strRet->uType = STRRET_CSTRA;
1748 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1751 TRACE("-- (%p)->(%s)\n", This, szPath);
1755 static ICOM_VTABLE(IShellFolder2) sfmcvt =
1757 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1758 IShellFolder_fnQueryInterface,
1759 IShellFolder_fnAddRef,
1760 IShellFolder_fnRelease,
1761 ISF_MyComputer_fnParseDisplayName,
1762 ISF_MyComputer_fnEnumObjects,
1763 ISF_MyComputer_fnBindToObject,
1764 IShellFolder_fnBindToStorage,
1765 IShellFolder_fnCompareIDs,
1766 ISF_MyComputer_fnCreateViewObject,
1767 ISF_MyComputer_fnGetAttributesOf,
1768 IShellFolder_fnGetUIObjectOf,
1769 ISF_MyComputer_fnGetDisplayNameOf,
1770 IShellFolder_fnSetNameOf,
1773 IShellFolder_fnGetDefaultSearchGUID,
1774 IShellFolder_fnEnumSearches,
1775 IShellFolder_fnGetDefaultColumn,
1776 IShellFolder_fnGetDefaultColumnState,
1777 IShellFolder_fnGetDetailsEx,
1778 IShellFolder_fnGetDetailsOf,
1779 IShellFolder_fnMapNameToSCID
1783 /************************************************************************
1784 * ISFPersistFolder_QueryInterface (IUnknown)
1787 static HRESULT WINAPI ISFPersistFolder_QueryInterface(
1788 IPersistFolder * iface,
1792 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
1794 TRACE("(%p)\n", This);
1796 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1799 /************************************************************************
1800 * ISFPersistFolder_AddRef (IUnknown)
1803 static ULONG WINAPI ISFPersistFolder_AddRef(
1804 IPersistFolder * iface)
1806 _ICOM_THIS_From_IPersistFolder(IShellFolder, iface);
1808 TRACE("(%p)\n", This);
1810 return IShellFolder_AddRef((IShellFolder*)This);
1813 /************************************************************************
1814 * ISFPersistFolder_Release (IUnknown)
1817 static ULONG WINAPI ISFPersistFolder_Release(
1818 IPersistFolder * iface)
1820 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
1822 TRACE("(%p)\n", This);
1824 return IShellFolder_Release((IShellFolder*)This);
1827 /************************************************************************
1828 * ISFPersistFolder_GetClassID (IPersist)
1830 static HRESULT WINAPI ISFPersistFolder_GetClassID(
1831 IPersistFolder * iface,
1834 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
1836 TRACE("(%p)\n", This);
1838 if (!lpClassId) return E_POINTER;
1839 *lpClassId = *This->pclsid;
1844 /************************************************************************
1845 * ISFPersistFolder_Initialize (IPersistFolder)
1848 * sMyPath is not set. Don't know how to handle in a non rooted environment.
1850 static HRESULT WINAPI ISFPersistFolder_Initialize(
1851 IPersistFolder * iface,
1854 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
1856 TRACE("(%p)\n", This);
1860 SHFree(This->absPidl);
1861 This->absPidl = NULL;
1863 This->absPidl = ILClone(pidl);
1867 static ICOM_VTABLE(IPersistFolder) psfvt =
1869 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1870 ISFPersistFolder_QueryInterface,
1871 ISFPersistFolder_AddRef,
1872 ISFPersistFolder_Release,
1873 ISFPersistFolder_GetClassID,
1874 ISFPersistFolder_Initialize
1877 /****************************************************************************
1878 * ISFDropTarget implementation
1880 static BOOL ISFDropTarget_QueryDrop(
1885 DWORD dwEffect = *pdwEffect;
1887 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
1889 *pdwEffect = DROPEFFECT_NONE;
1891 if (This->fAcceptFmt)
1892 { /* Does our interpretation of the keystate ... */
1893 *pdwEffect = KeyStateToDropEffect(dwKeyState);
1895 /* ... matches the desired effect ? */
1896 if (dwEffect & *pdwEffect)
1904 static HRESULT WINAPI ISFDropTarget_QueryInterface(
1909 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
1911 TRACE("(%p)\n", This);
1913 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1916 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
1918 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
1920 TRACE("(%p)\n", This);
1922 return IShellFolder_AddRef((IShellFolder*)This);
1925 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
1927 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
1929 TRACE("(%p)\n", This);
1931 return IShellFolder_Release((IShellFolder*)This);
1934 static HRESULT WINAPI ISFDropTarget_DragEnter(
1936 IDataObject *pDataObject,
1943 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
1945 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
1947 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
1949 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
1951 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
1956 static HRESULT WINAPI ISFDropTarget_DragOver(
1962 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
1964 TRACE("(%p)\n",This);
1966 if(!pdwEffect) return E_INVALIDARG;
1968 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
1973 static HRESULT WINAPI ISFDropTarget_DragLeave(
1976 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
1978 TRACE("(%p)\n",This);
1980 This->fAcceptFmt = FALSE;
1985 static HRESULT WINAPI ISFDropTarget_Drop(
1987 IDataObject* pDataObject,
1992 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
1994 FIXME("(%p) object dropped\n",This);
1999 static struct ICOM_VTABLE(IDropTarget) dtvt =
2001 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2002 ISFDropTarget_QueryInterface,
2003 ISFDropTarget_AddRef,
2004 ISFDropTarget_Release,
2005 ISFDropTarget_DragEnter,
2006 ISFDropTarget_DragOver,
2007 ISFDropTarget_DragLeave,