4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
7 * IShellFolder2 and related interfaces
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"
28 DEFAULT_DEBUG_CHANNEL(shell)
31 /***************************************************************************
32 * debughelper: print out the return adress
33 * helps especially to track down unbalanced AddRef/Release
38 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
52 /***************************************************************************
53 * GetNextElement (internal function)
55 * gets a part of a string till the first backslash
58 * pszNext [IN] string to get the element from
59 * pszOut [IN] pointer to buffer whitch receives string
60 * dwOut [IN] length of pszOut
63 * LPSTR pointer to first, not yet parsed char
66 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
67 { LPCWSTR pszTail = pszNext;
69 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
73 if(!pszNext || !*pszNext)
76 while(*pszTail && (*pszTail != (WCHAR)'\\'))
79 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
80 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
87 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
91 static HRESULT SHELL32_ParseNextElement(
94 LPITEMIDLIST * pidlInOut,
99 HRESULT hr = E_OUTOFMEMORY;
100 LPITEMIDLIST pidlOut, pidlTemp = NULL;
101 IShellFolder *psfChild;
103 TRACE("(%p, %p, %s)\n",psf, pidlInOut? *pidlInOut: "(null)", debugstr_w(szNext));
106 /* get the shellfolder for the child pidl and let it analyse further */
107 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
111 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
112 IShellFolder_Release(psfChild);
114 pidlTemp = ILCombine(*pidlInOut, pidlOut);
121 *pidlInOut = pidlTemp;
123 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
127 /***********************************************************************
128 * SHELL32_CoCreateInitSF
130 * creates a initialized shell folder
132 static HRESULT SHELL32_CoCreateInitSF (
133 LPITEMIDLIST pidlRoot,
134 LPITEMIDLIST pidlChild,
140 LPITEMIDLIST absPidl;
141 IShellFolder2 *pShellFolder;
142 IPersistFolder *pPersistFolder;
144 TRACE("%p %p\n", pidlRoot, pidlChild);
148 /* we have to ask first for IPersistFolder, some special folders are expecting this */
149 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
152 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
155 absPidl = ILCombine (pidlRoot, pidlChild);
156 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
157 IPersistFolder_Release(pPersistFolder);
159 *ppvOut = pShellFolder;
163 TRACE("-- ret=0x%08lx\n", hr);
167 static HRESULT SHELL32_GetDisplayNameOfChild(
174 LPITEMIDLIST pidlFirst, pidlNext;
175 IShellFolder2 * psfChild;
176 HRESULT hr = E_OUTOFMEMORY;
179 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
182 if ((pidlFirst = ILCloneFirst(pidl)))
184 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
187 pidlNext = ILGetNext(pidl);
189 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
192 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
195 IShellFolder_Release(psfChild);
200 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
205 /***********************************************************************
206 * IShellFolder implementation
211 ICOM_VFIELD(IUnknown);
213 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;;
214 ICOM_VTABLE(IPersistFolder)* lpvtblPersistFolder;
215 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
217 IUnknown *pUnkOuter; /* used for aggregation */
222 LPITEMIDLIST absPidl; /* complete pidl */
224 UINT cfShellIDList; /* clipboardformat for IDropTarget */
225 BOOL fAcceptFmt; /* flag for pending Drop */
228 static struct ICOM_VTABLE(IUnknown) unkvt;
229 static struct ICOM_VTABLE(IShellFolder2) sfvt;
230 static struct ICOM_VTABLE(IPersistFolder) psfvt;
231 static struct ICOM_VTABLE(IDropTarget) dtvt;
233 static IShellFolder * ISF_MyComputer_Constructor(void);
235 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
236 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
238 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder)))
239 #define _ICOM_THIS_From_IPersistFolder(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
241 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
242 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
245 converts This to a interface pointer
247 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
248 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
249 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
250 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder)
251 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder)
252 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
253 /**************************************************************************
254 * registers clipboardformat once
256 static void SF_RegisterClipFmt (IGenericSFImpl * This)
258 TRACE("(%p)\n", This);
260 if (!This->cfShellIDList)
262 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
266 /**************************************************************************
267 * we need a seperate IUnknown to handle aggregation
270 static HRESULT WINAPI IUnknown_fnQueryInterface(
275 ICOM_THIS(IGenericSFImpl, iface);
278 WINE_StringFromCLSID((LPCLSID)riid,xriid);
281 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
285 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
286 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
287 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
288 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
289 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
290 else if(IsEqualIID(riid, &IID_IDropTarget))
292 *ppvObj = _IDropTarget_(This);
293 SF_RegisterClipFmt(This);
298 IUnknown_AddRef((IUnknown*)(*ppvObj));
299 TRACE("-- Interface = %p\n", *ppvObj);
302 TRACE("-- Interface: E_NOINTERFACE\n");
303 return E_NOINTERFACE;
306 static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
308 ICOM_THIS(IGenericSFImpl, iface);
311 TRACE("(%p)->(count=%lu)\n",This,This->ref);
314 return ++(This->ref);
317 static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
319 ICOM_THIS(IGenericSFImpl, iface);
322 TRACE("(%p)->(count=%lu)\n",This,This->ref);
327 TRACE("-- destroying IShellFolder(%p)\n",This);
329 if (pdesktopfolder == _IShellFolder_(This))
332 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
334 if(This->absPidl) SHFree(This->absPidl);
335 if(This->sMyPath) SHFree(This->sMyPath);
336 HeapFree(GetProcessHeap(),0,This);
342 static ICOM_VTABLE(IUnknown) unkvt =
344 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
345 IUnknown_fnQueryInterface,
350 static shvheader GenericSFHeader [] =
352 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
353 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
354 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
355 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
356 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
358 #define GENERICSHELLVIEWCOLUMNS 5
360 /**************************************************************************
361 * IShellFolder_Constructor
364 * creating undocumented ShellFS_Folder as part of an aggregation
365 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
368 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
370 HRESULT IFSFolder_Constructor(
371 IUnknown * pUnkOuter,
378 WINE_StringFromCLSID((LPCLSID)riid,xriid);
380 TRACE("unkOut=%p riid=%s\n",pUnkOuter, xriid);
382 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
384 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
388 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
392 ICOM_VTBL(sf)=&unkvt;
393 sf->lpvtblShellFolder=&sfvt;
394 sf->lpvtblPersistFolder=&psfvt;
395 sf->lpvtblDropTarget=&dtvt;
396 sf->pclsid = (CLSID*)&CLSID_SFFile;
397 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
398 *ppv = _IUnknown_(sf);
409 /**************************************************************************
410 * IShellFolder_Constructor
413 * THIS points to the parent folder
416 IShellFolder * IShellFolder_Constructor(
417 IShellFolder2 * iface,
423 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
425 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
428 ICOM_VTBL(sf)=&unkvt;
429 sf->lpvtblShellFolder=&sfvt;
430 sf->lpvtblPersistFolder=&psfvt;
431 sf->lpvtblDropTarget=&dtvt;
432 sf->pclsid = (CLSID*)&CLSID_SFFile;
433 sf->pUnkOuter = _IUnknown_(sf);
435 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
438 if(pidl && iface) /* do we have a pidl? */
442 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
444 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
446 if(This->sMyPath) /* get the size of the parents path */
448 dwSize += strlen(This->sMyPath) ;
449 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
452 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
453 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
455 if(!sf->sMyPath) return NULL;
458 if(This->sMyPath) /* if the parent has a path, get it*/
460 strcpy(sf->sMyPath, This->sMyPath);
461 PathAddBackslashA (sf->sMyPath);
464 len = strlen(sf->sMyPath);
465 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
468 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
474 return _IShellFolder_(sf);
477 /**************************************************************************
478 * IShellFolder_fnQueryInterface
481 * REFIID riid [in ] Requested InterfaceID
482 * LPVOID* ppvObject [out] Interface* to hold the result
484 static HRESULT WINAPI IShellFolder_fnQueryInterface(
485 IShellFolder2 * iface,
489 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
492 WINE_StringFromCLSID((LPCLSID)riid,xriid);
494 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
496 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
499 /**************************************************************************
500 * IShellFolder_AddRef
503 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
505 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
508 TRACE("(%p)->(count=%lu)\n",This,This->ref);
510 return IUnknown_AddRef(This->pUnkOuter);
513 /**************************************************************************
514 * IShellFolder_fnRelease
516 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
518 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
521 TRACE("(%p)->(count=%lu)\n",This,This->ref);
523 return IUnknown_Release(This->pUnkOuter);
526 /**************************************************************************
527 * IShellFolder_fnParseDisplayName
529 * HWND hwndOwner, //[in ] Parent window for any message's
530 * LPBC pbc, //[in ] reserved
531 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
532 * ULONG* pchEaten, //[out] (unicode) characters processed
533 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
534 * ULONG* pdwAttributes //[out] items attributes
537 * every folder trys to parse only it's own (the leftmost) pidl and creates a
538 * subfolder to evaluate the remaining parts
539 * now we can parse into namespaces implemented by shell extensions
541 * behaviour on win98: lpszDisplayName=NULL -> chrash
542 * lpszDisplayName="" -> returns mycoputer-pidl
545 * pdwAttributes: not set
546 * pchEaten: not set like in windows
548 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
549 IShellFolder2 * iface,
552 LPOLESTR lpszDisplayName,
555 DWORD *pdwAttributes)
557 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
559 HRESULT hr = E_OUTOFMEMORY;
561 WCHAR szElement[MAX_PATH];
562 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
563 LPITEMIDLIST pidlTemp=NULL;
565 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
566 This,hwndOwner,pbcReserved,lpszDisplayName,
567 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
569 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
571 if (pchEaten) *pchEaten = 0; /* strange but like the original */
573 if (*lpszDisplayName)
575 /* get the next element */
576 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
578 /* build the full pathname to the element */
579 WideCharToLocal(szTempA, szElement, lstrlenW(szElement) + 1);
580 strcpy(szPath, This->sMyPath);
581 PathAddBackslashA(szPath);
582 strcat(szPath, szTempA);
585 pidlTemp = SHSimpleIDListFromPathA(szPath);
589 /* try to analyse the next element */
590 if (szNext && *szNext)
592 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
603 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
608 /**************************************************************************
609 * IShellFolder_fnEnumObjects
611 * HWND hwndOwner, //[in ] Parent Window
612 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
613 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
615 static HRESULT WINAPI IShellFolder_fnEnumObjects(
616 IShellFolder2 * iface,
619 LPENUMIDLIST* ppEnumIDList)
621 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
623 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
625 *ppEnumIDList = NULL;
626 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
628 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
630 if(!*ppEnumIDList) return E_OUTOFMEMORY;
635 /**************************************************************************
636 * IShellFolder_fnBindToObject
638 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
639 * LPBC pbc, //[in ] reserved
640 * REFIID riid, //[in ] Initial Interface
641 * LPVOID* ppvObject //[out] Interface*
643 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
644 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
646 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
649 IShellFolder *pShellFolder, *pSubFolder;
650 IPersistFolder *pPersistFolder;
651 LPITEMIDLIST absPidl;
653 WINE_StringFromCLSID(riid,xriid);
655 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
657 if(!pidl || !ppvOut) return E_INVALIDARG;
661 if ((iid=_ILGetGUIDPointer(pidl)))
663 /* we have to create a alien folder */
664 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
665 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
667 absPidl = ILCombine (This->absPidl, pidl);
668 IPersistFolder_Initialize(pPersistFolder, absPidl);
669 IPersistFolder_Release(pPersistFolder);
679 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
680 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
684 if (_ILIsPidlSimple(pidl))
686 *ppvOut = pShellFolder;
690 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
691 IShellFolder_Release(pShellFolder);
692 *ppvOut = pSubFolder;
695 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
700 /**************************************************************************
701 * IShellFolder_fnBindToStorage
703 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
704 * LPBC pbc, //[in ] reserved
705 * REFIID riid, //[in ] Initial storage interface
706 * LPVOID* ppvObject //[out] Interface* returned
708 static HRESULT WINAPI IShellFolder_fnBindToStorage(
709 IShellFolder2 * iface,
715 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
718 WINE_StringFromCLSID(riid,xriid);
720 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",This,pidl,pbcReserved,xriid,ppvOut);
726 /**************************************************************************
727 * IShellFolder_fnCompareIDs
730 * LPARAM lParam, //[in ] Column?
731 * LPCITEMIDLIST pidl1, //[in ] simple pidl
732 * LPCITEMIDLIST pidl2) //[in ] simple pidl
735 * Special case - If one of the items is a Path and the other is a File,
736 * always make the Path come before the File.
739 * use SCODE_CODE() on the return value to get the result
742 static HRESULT WINAPI IShellFolder_fnCompareIDs(
743 IShellFolder2 * iface,
748 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
750 CHAR szTemp1[MAX_PATH];
751 CHAR szTemp2[MAX_PATH];
754 HRESULT hr = E_OUTOFMEMORY;
755 LPCITEMIDLIST pidlTemp;
758 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
762 if (!pidl1 && !pidl2)
764 hr = ResultFromShort(0);
768 hr = ResultFromShort(-1);
772 hr = ResultFromShort(1);
777 pd1 = _ILGetDataPointer(pidl1);
778 pd2 = _ILGetDataPointer(pidl2);
780 /* compate the types. sort order is the PT_* constant */
781 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
782 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
786 hr = ResultFromShort(pt1-pt2);
788 else /* same type of pidl */
790 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
791 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
792 nReturn = strcasecmp(szTemp1, szTemp2);
794 if (nReturn == 0) /* first pidl different ? */
796 pidl1 = ILGetNext(pidl1);
798 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
800 pidlTemp = ILCloneFirst(pidl1);
801 pidl2 = ILGetNext(pidl2);
803 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
806 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
807 IShellFolder_Release(psf);
808 hr = ResultFromShort(nReturn);
814 hr = ResultFromShort(nReturn); /* two equal simple pidls */
819 hr = ResultFromShort(nReturn); /* two different simple pidls */
824 TRACE("-- res=0x%08lx\n", hr);
828 /**************************************************************************
829 * IShellFolder_fnCreateViewObject
831 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
832 IShellFolder2 * iface,
837 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
839 LPSHELLVIEW pShellView;
841 HRESULT hr = E_INVALIDARG;
843 WINE_StringFromCLSID(riid,xriid);
844 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
850 if(IsEqualIID(riid, &IID_IDropTarget))
852 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
854 else if(IsEqualIID(riid, &IID_IContextMenu))
856 FIXME("IContextMenu not implemented\n");
859 else if(IsEqualIID(riid, &IID_IShellView))
861 pShellView = IShellView_Constructor((IShellFolder*)iface);
864 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
865 IShellView_Release(pShellView);
869 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
873 /**************************************************************************
874 * IShellFolder_fnGetAttributesOf
877 * UINT cidl, //[in ] num elements in pidl array
878 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
879 * ULONG* rgfInOut) //[out] result array
882 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
883 IShellFolder2 * iface,
885 LPCITEMIDLIST *apidl,
888 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
892 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
894 if ( (!cidl) || (!apidl) || (!rgfInOut))
897 while (cidl > 0 && *apidl)
900 if (_ILIsFolder( *apidl))
902 *rgfInOut &= 0xe0000177;
905 else if (_ILIsValue( *apidl))
907 *rgfInOut &= 0x40000177;
916 TRACE("-- result=0x%08lx\n",*rgfInOut);
920 /**************************************************************************
921 * IShellFolder_fnGetUIObjectOf
924 * HWND hwndOwner, //[in ] Parent window for any output
925 * UINT cidl, //[in ] array size
926 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
927 * REFIID riid, //[in ] Requested Interface
928 * UINT* prgfInOut, //[ ] reserved
929 * LPVOID* ppvObject) //[out] Resulting Interface
932 * This function gets asked to return "view objects" for one or more (multiple select)
934 * The viewobject typically is an COM object with one of the following interfaces:
935 * IExtractIcon,IDataObject,IContextMenu
936 * In order to support icon positions in the default Listview your DataObject
937 * must implement the SetData method (in addition to GetData :) - the shell passes
938 * a barely documented "Icon positions" structure to SetData when the drag starts,
939 * and GetData's it if the drop is in another explorer window that needs the positions.
941 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
942 IShellFolder2 * iface,
945 LPCITEMIDLIST * apidl,
950 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
954 IUnknown* pObj = NULL;
955 HRESULT hr = E_INVALIDARG;
957 WINE_StringFromCLSID(riid,xclsid);
959 TRACE("(%p)->(%u,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
960 This,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut);
966 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
968 pObj = (LPUNKNOWN)IContextMenu_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
971 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
973 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
976 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
978 pidl = ILCombine(This->absPidl,apidl[0]);
979 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
983 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
985 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
997 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1001 /**************************************************************************
1002 * IShellFolder_fnGetDisplayNameOf
1003 * Retrieves the display name for the specified file object or subfolder
1006 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1007 * DWORD dwFlags, //[in ] SHGNO formatting flags
1008 * LPSTRRET lpName) //[out] Returned display name
1011 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1013 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1014 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1016 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1017 IShellFolder2 * iface,
1022 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1024 CHAR szPath[MAX_PATH]= "";
1028 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1031 if(!pidl || !strRet) return E_INVALIDARG;
1033 bSimplePidl = _ILIsPidlSimple(pidl);
1035 /* take names of special folders only if its only this folder */
1036 if (_ILIsSpecialFolder(pidl))
1040 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1045 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1047 strcpy (szPath, This->sMyPath); /* get path to root*/
1048 PathAddBackslashA(szPath);
1049 len = strlen(szPath);
1051 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1054 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1056 PathAddBackslashA(szPath);
1057 len = strlen(szPath);
1059 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1060 return E_OUTOFMEMORY;
1062 strRet->uType = STRRET_CSTRA;
1063 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1065 TRACE("-- (%p)->(%s)\n", This, szPath);
1069 /**************************************************************************
1070 * IShellFolder_fnSetNameOf
1071 * Changes the name of a file object or subfolder, possibly changing its item
1072 * identifier in the process.
1075 * HWND hwndOwner, //[in ] Owner window for output
1076 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1077 * LPCOLESTR lpszName, //[in ] the items new display name
1078 * DWORD dwFlags, //[in ] SHGNO formatting flags
1079 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1081 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1082 IShellFolder2 * iface,
1084 LPCITEMIDLIST pidl, /*simple pidl*/
1087 LPITEMIDLIST *pPidlOut)
1089 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1091 FIXME("(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
1092 This,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut);
1097 /**************************************************************************
1098 * IShellFolder_fnGetFolderPath
1100 static HRESULT WINAPI IShellFolder_fnGetFolderPath(IShellFolder2 * iface, LPSTR lpszOut, DWORD dwOutSize)
1102 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1104 TRACE("(%p)->(%p %lu)\n",This, lpszOut, dwOutSize);
1106 if (!lpszOut) return FALSE;
1110 if (! This->sMyPath) return FALSE;
1112 lstrcpynA(lpszOut, This->sMyPath, dwOutSize);
1114 TRACE("-- (%p)->(return=%s)\n",This, lpszOut);
1118 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1119 IShellFolder2 * iface,
1122 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1123 FIXME("(%p)\n",This);
1126 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1127 IShellFolder2 * iface,
1128 IEnumExtraSearch **ppenum)
1130 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1131 FIXME("(%p)\n",This);
1134 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1135 IShellFolder2 * iface,
1140 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1142 TRACE("(%p)\n",This);
1144 if (pSort) *pSort = 0;
1145 if (pDisplay) *pDisplay = 0;
1149 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1150 IShellFolder2 * iface,
1154 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1156 TRACE("(%p)\n",This);
1158 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1160 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1164 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1165 IShellFolder2 * iface,
1167 const SHCOLUMNID *pscid,
1170 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1171 FIXME("(%p)\n",This);
1175 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1176 IShellFolder2 * iface,
1181 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1182 HRESULT hr = E_FAIL;
1184 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1186 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1190 /* the header titles */
1191 psd->fmt = GenericSFHeader[iColumn].fmt;
1192 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1193 psd->str.uType = STRRET_CSTRA;
1194 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1199 /* the data from the pidl */
1203 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1206 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1209 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1212 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1214 case 4: /* attributes */
1215 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1219 psd->str.uType = STRRET_CSTRA;
1224 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1225 IShellFolder2 * iface,
1229 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1230 FIXME("(%p)\n",This);
1234 static ICOM_VTABLE(IShellFolder2) sfvt =
1236 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1237 IShellFolder_fnQueryInterface,
1238 IShellFolder_fnAddRef,
1239 IShellFolder_fnRelease,
1240 IShellFolder_fnParseDisplayName,
1241 IShellFolder_fnEnumObjects,
1242 IShellFolder_fnBindToObject,
1243 IShellFolder_fnBindToStorage,
1244 IShellFolder_fnCompareIDs,
1245 IShellFolder_fnCreateViewObject,
1246 IShellFolder_fnGetAttributesOf,
1247 IShellFolder_fnGetUIObjectOf,
1248 IShellFolder_fnGetDisplayNameOf,
1249 IShellFolder_fnSetNameOf,
1252 IShellFolder_fnGetDefaultSearchGUID,
1253 IShellFolder_fnEnumSearches,
1254 IShellFolder_fnGetDefaultColumn,
1255 IShellFolder_fnGetDefaultColumnState,
1256 IShellFolder_fnGetDetailsEx,
1257 IShellFolder_fnGetDetailsOf,
1258 IShellFolder_fnMapNameToSCID
1260 /***********************************************************************
1261 * [Desktopfolder] IShellFolder implementation
1263 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1265 static shvheader DesktopSFHeader [] =
1267 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1268 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1269 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1270 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1271 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1273 #define DESKTOPSHELLVIEWCOLUMNS 5
1275 /**************************************************************************
1276 * ISF_Desktop_Constructor
1279 IShellFolder * ISF_Desktop_Constructor()
1281 IGenericSFImpl * sf;
1283 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1285 ICOM_VTBL(sf)=&unkvt;
1286 sf->lpvtblShellFolder=&sfdvt;
1287 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1288 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1293 return _IShellFolder_(sf);
1296 /**************************************************************************
1297 * ISF_Desktop_fnQueryInterface
1299 * NOTES supports not IPersist/IPersistFolder
1301 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1302 IShellFolder2 * iface,
1306 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1309 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1310 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
1314 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1316 *ppvObj = _IUnknown_(This);
1318 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1320 *ppvObj = _IShellFolder_(This);
1322 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1324 *ppvObj = _IShellFolder_(This);
1329 IUnknown_AddRef((IUnknown*)(*ppvObj));
1330 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1333 TRACE("-- Interface: E_NOINTERFACE\n");
1334 return E_NOINTERFACE;
1337 /**************************************************************************
1338 * ISF_Desktop_fnParseDisplayName
1341 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1344 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1345 IShellFolder2 * iface,
1348 LPOLESTR lpszDisplayName,
1350 LPITEMIDLIST *ppidl,
1351 DWORD *pdwAttributes)
1353 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1355 LPCWSTR szNext=NULL;
1356 LPITEMIDLIST pidlTemp=NULL;
1357 HRESULT hr=E_OUTOFMEMORY;
1359 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1360 This,hwndOwner,pbcReserved,lpszDisplayName,
1361 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1364 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1366 /* fixme no real parsing implemented */
1367 pidlTemp = _ILCreateMyComputer();
1368 szNext = lpszDisplayName;
1370 if (szNext && *szNext)
1372 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1381 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1386 /**************************************************************************
1387 * ISF_Desktop_fnEnumObjects
1389 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1390 IShellFolder2 * iface,
1393 LPENUMIDLIST* ppEnumIDList)
1395 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1397 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1399 *ppEnumIDList = NULL;
1400 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1402 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1404 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1409 /**************************************************************************
1410 * ISF_Desktop_fnBindToObject
1412 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1413 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1415 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1418 IShellFolder *pShellFolder, *pSubFolder;
1420 WINE_StringFromCLSID(riid,xriid);
1422 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
1426 if ((clsid=_ILGetGUIDPointer(pidl)))
1428 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1430 pShellFolder = ISF_MyComputer_Constructor();
1434 /* shell extension */
1435 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1437 return E_INVALIDARG;
1443 /* file system folder on the desktop */
1444 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1445 IPersistFolder * ppf;
1448 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1449 firstpidl = ILCloneFirst(pidl);
1450 completepidl = ILCombine(deskpidl, firstpidl);
1452 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1453 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1455 IPersistFolder_Initialize(ppf, completepidl);
1456 IPersistFolder_Release(ppf);
1458 ILFree(completepidl);
1463 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1465 *ppvOut = pShellFolder;
1467 else /* go deeper */
1469 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1470 IShellFolder_Release(pShellFolder);
1471 *ppvOut = pSubFolder;
1474 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1479 /**************************************************************************
1480 * ISF_Desktop_fnCreateViewObject
1482 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1483 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1485 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1487 LPSHELLVIEW pShellView;
1489 HRESULT hr = E_INVALIDARG;
1491 WINE_StringFromCLSID(riid,xriid);
1492 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
1498 if(IsEqualIID(riid, &IID_IDropTarget))
1500 FIXME("IDropTarget not implemented\n");
1503 else if(IsEqualIID(riid, &IID_IContextMenu))
1505 FIXME("IContextMenu not implemented\n");
1508 else if(IsEqualIID(riid, &IID_IShellView))
1510 pShellView = IShellView_Constructor((IShellFolder*)iface);
1513 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1514 IShellView_Release(pShellView);
1518 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1522 /**************************************************************************
1523 * ISF_Desktop_fnGetAttributesOf
1525 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
1527 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1533 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1535 if ( (!cidl) || (!apidl) || (!rgfInOut))
1536 return E_INVALIDARG;
1538 while (cidl > 0 && *apidl)
1542 if ((clsid=_ILGetGUIDPointer(*apidl)))
1544 if (IsEqualIID(clsid, &CLSID_MyComputer))
1546 *rgfInOut &= 0xb0000154;
1549 else if (HCR_GetFolderAttributes(clsid, &attributes))
1551 *rgfInOut &= attributes;
1555 { /* some shell-extension */
1556 *rgfInOut &= 0xb0000154;
1559 else if (_ILIsFolder( *apidl))
1561 *rgfInOut &= 0xe0000177;
1564 else if (_ILIsValue( *apidl))
1566 *rgfInOut &= 0x40000177;
1575 TRACE("-- result=0x%08lx\n",*rgfInOut);
1580 /**************************************************************************
1581 * ISF_Desktop_fnGetDisplayNameOf
1584 * special case: pidl = null gives desktop-name back
1586 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1587 IShellFolder2 * iface,
1592 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1594 CHAR szPath[MAX_PATH]= "";
1596 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1599 if(!strRet) return E_INVALIDARG;
1603 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1605 else if ( _ILIsPidlSimple(pidl) )
1607 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1611 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1612 return E_OUTOFMEMORY;
1614 strRet->uType = STRRET_CSTRA;
1615 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1618 TRACE("-- (%p)->(%s)\n", This, szPath);
1622 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1623 IShellFolder2 * iface,
1626 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1627 FIXME("(%p)\n",This);
1630 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1631 IShellFolder2 * iface,
1632 IEnumExtraSearch **ppenum)
1634 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1635 FIXME("(%p)\n",This);
1638 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1639 IShellFolder2 * iface,
1644 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1646 TRACE("(%p)\n",This);
1648 if (pSort) *pSort = 0;
1649 if (pDisplay) *pDisplay = 0;
1653 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1654 IShellFolder2 * iface,
1658 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1660 TRACE("(%p)\n",This);
1662 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1664 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1668 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1669 IShellFolder2 * iface,
1671 const SHCOLUMNID *pscid,
1674 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1675 FIXME("(%p)\n",This);
1679 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
1680 IShellFolder2 * iface,
1685 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1686 HRESULT hr = E_FAIL;;
1688 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1690 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1694 psd->fmt = DesktopSFHeader[iColumn].fmt;
1695 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
1696 psd->str.uType = STRRET_CSTRA;
1697 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1702 /* the data from the pidl */
1706 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1709 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1712 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1715 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1717 case 4: /* attributes */
1718 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1722 psd->str.uType = STRRET_CSTRA;
1727 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
1728 IShellFolder2 * iface,
1732 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1733 FIXME("(%p)\n",This);
1737 static ICOM_VTABLE(IShellFolder2) sfdvt =
1739 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1740 ISF_Desktop_fnQueryInterface,
1741 IShellFolder_fnAddRef,
1742 IShellFolder_fnRelease,
1743 ISF_Desktop_fnParseDisplayName,
1744 ISF_Desktop_fnEnumObjects,
1745 ISF_Desktop_fnBindToObject,
1746 IShellFolder_fnBindToStorage,
1747 IShellFolder_fnCompareIDs,
1748 ISF_Desktop_fnCreateViewObject,
1749 ISF_Desktop_fnGetAttributesOf,
1750 IShellFolder_fnGetUIObjectOf,
1751 ISF_Desktop_fnGetDisplayNameOf,
1752 IShellFolder_fnSetNameOf,
1755 ISF_Desktop_fnGetDefaultSearchGUID,
1756 ISF_Desktop_fnEnumSearches,
1757 ISF_Desktop_fnGetDefaultColumn,
1758 ISF_Desktop_fnGetDefaultColumnState,
1759 ISF_Desktop_fnGetDetailsEx,
1760 ISF_Desktop_fnGetDetailsOf,
1761 ISF_Desktop_fnMapNameToSCID
1765 /***********************************************************************
1766 * IShellFolder [MyComputer] implementation
1769 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
1771 static shvheader MyComputerSFHeader [] =
1773 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1774 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1775 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1776 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1778 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
1780 /**************************************************************************
1781 * ISF_MyComputer_Constructor
1783 static IShellFolder * ISF_MyComputer_Constructor(void)
1785 IGenericSFImpl * sf;
1787 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1790 ICOM_VTBL(sf)=&unkvt;
1791 sf->lpvtblShellFolder=&sfmcvt;
1792 sf->lpvtblPersistFolder = &psfvt;
1793 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
1794 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
1795 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1800 return _IShellFolder_(sf);
1803 /**************************************************************************
1804 * ISF_MyComputer_fnParseDisplayName
1806 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
1807 IShellFolder2 * iface,
1810 LPOLESTR lpszDisplayName,
1812 LPITEMIDLIST *ppidl,
1813 DWORD *pdwAttributes)
1815 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1817 HRESULT hr = E_OUTOFMEMORY;
1818 LPCWSTR szNext=NULL;
1819 WCHAR szElement[MAX_PATH];
1820 CHAR szTempA[MAX_PATH];
1821 LPITEMIDLIST pidlTemp;
1823 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1824 This,hwndOwner,pbcReserved,lpszDisplayName,
1825 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1828 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1830 if (PathIsRootW(lpszDisplayName))
1832 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
1833 WideCharToLocal(szTempA, szElement, lstrlenW(szElement) + 1);
1834 pidlTemp = _ILCreateDrive(szTempA);
1836 if (szNext && *szNext)
1838 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1847 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1852 /**************************************************************************
1853 * ISF_MyComputer_fnEnumObjects
1855 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
1856 IShellFolder2 * iface,
1859 LPENUMIDLIST* ppEnumIDList)
1861 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1863 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1865 *ppEnumIDList = NULL;
1866 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
1868 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1870 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1875 /**************************************************************************
1876 * ISF_MyComputer_fnBindToObject
1878 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1879 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1881 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1884 IShellFolder *pShellFolder, *pSubFolder;
1885 LPITEMIDLIST pidltemp;
1887 WINE_StringFromCLSID(riid,xriid);
1889 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
1891 if(!pidl || !ppvOut) return E_INVALIDARG;
1895 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
1897 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1904 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
1906 pidltemp = ILCloneFirst(pidl);
1907 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
1911 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1913 *ppvOut = pShellFolder;
1915 else /* go deeper */
1917 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
1918 IShellFolder_Release(pShellFolder);
1919 *ppvOut = pSubFolder;
1922 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1927 /**************************************************************************
1928 * ISF_MyComputer_fnCreateViewObject
1930 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
1931 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1933 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1935 LPSHELLVIEW pShellView;
1937 HRESULT hr = E_INVALIDARG;
1939 WINE_StringFromCLSID(riid,xriid);
1940 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
1946 if(IsEqualIID(riid, &IID_IDropTarget))
1948 FIXME("IDropTarget not implemented\n");
1951 else if(IsEqualIID(riid, &IID_IContextMenu))
1953 FIXME("IContextMenu not implemented\n");
1956 else if(IsEqualIID(riid, &IID_IShellView))
1958 pShellView = IShellView_Constructor((IShellFolder*)iface);
1961 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1962 IShellView_Release(pShellView);
1966 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1970 /**************************************************************************
1971 * ISF_MyComputer_fnGetAttributesOf
1973 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
1975 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1981 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
1983 if ( (!cidl) || (!apidl) || (!rgfInOut))
1984 return E_INVALIDARG;
1986 *rgfInOut = 0xffffffff;
1988 while (cidl > 0 && *apidl)
1992 if (_ILIsDrive(*apidl))
1994 *rgfInOut &= 0xf0000144;
1997 else if ((clsid=_ILGetGUIDPointer(*apidl)))
1999 if (HCR_GetFolderAttributes(clsid, &attributes))
2001 *rgfInOut &= attributes;
2011 TRACE("-- result=0x%08lx\n",*rgfInOut);
2015 /**************************************************************************
2016 * ISF_MyComputer_fnGetDisplayNameOf
2019 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2020 * SHGDN_INFOLDER makes no sense.
2022 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2023 IShellFolder2 * iface,
2028 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2030 char szPath[MAX_PATH], szDrive[18];
2034 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2037 if(!strRet) return E_INVALIDARG;
2039 szPath[0]=0x00; szDrive[0]=0x00;
2042 bSimplePidl = _ILIsPidlSimple(pidl);
2044 if (_ILIsSpecialFolder(pidl))
2046 /* take names of special folders only if its only this folder */
2049 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2054 if (!_ILIsDrive(pidl))
2056 ERR("Wrong pidl type\n");
2057 return E_INVALIDARG;
2060 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2062 /* long view "lw_name (C:)" */
2063 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2065 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2067 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2068 strcat (szDrive," (");
2069 strncat (szDrive, szPath, 2);
2070 strcat (szDrive,")");
2071 strcpy (szPath, szDrive);
2075 if (!bSimplePidl) /* go deeper if needed */
2077 PathAddBackslashA(szPath);
2078 len = strlen(szPath);
2080 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2081 return E_OUTOFMEMORY;
2083 strRet->uType = STRRET_CSTRA;
2084 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2087 TRACE("-- (%p)->(%s)\n", This, szPath);
2091 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2092 IShellFolder2 * iface,
2095 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2096 FIXME("(%p)\n",This);
2099 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2100 IShellFolder2 * iface,
2101 IEnumExtraSearch **ppenum)
2103 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2104 FIXME("(%p)\n",This);
2107 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2108 IShellFolder2 * iface,
2113 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2115 TRACE("(%p)\n",This);
2117 if (pSort) *pSort = 0;
2118 if (pDisplay) *pDisplay = 0;
2122 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2123 IShellFolder2 * iface,
2127 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2129 TRACE("(%p)\n",This);
2131 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2133 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2137 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2138 IShellFolder2 * iface,
2140 const SHCOLUMNID *pscid,
2143 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2144 FIXME("(%p)\n",This);
2149 /* fixme: drive size >4GB is rolling over */
2150 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2151 IShellFolder2 * iface,
2156 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2159 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2161 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2165 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2166 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2167 psd->str.uType = STRRET_CSTRA;
2168 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2173 char szPath[MAX_PATH];
2174 ULARGE_INTEGER ulBytes;
2176 psd->str.u.cStr[0] = 0x00;
2177 psd->str.uType = STRRET_CSTRA;
2181 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2184 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2186 case 2: /* total size */
2187 if (_ILIsDrive(pidl))
2189 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2190 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2191 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2194 case 3: /* free size */
2195 if (_ILIsDrive(pidl))
2197 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2198 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2199 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2208 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2209 IShellFolder2 * iface,
2213 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2214 FIXME("(%p)\n",This);
2218 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2220 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2221 IShellFolder_fnQueryInterface,
2222 IShellFolder_fnAddRef,
2223 IShellFolder_fnRelease,
2224 ISF_MyComputer_fnParseDisplayName,
2225 ISF_MyComputer_fnEnumObjects,
2226 ISF_MyComputer_fnBindToObject,
2227 IShellFolder_fnBindToStorage,
2228 IShellFolder_fnCompareIDs,
2229 ISF_MyComputer_fnCreateViewObject,
2230 ISF_MyComputer_fnGetAttributesOf,
2231 IShellFolder_fnGetUIObjectOf,
2232 ISF_MyComputer_fnGetDisplayNameOf,
2233 IShellFolder_fnSetNameOf,
2236 ISF_MyComputer_fnGetDefaultSearchGUID,
2237 ISF_MyComputer_fnEnumSearches,
2238 ISF_MyComputer_fnGetDefaultColumn,
2239 ISF_MyComputer_fnGetDefaultColumnState,
2240 ISF_MyComputer_fnGetDetailsEx,
2241 ISF_MyComputer_fnGetDetailsOf,
2242 ISF_MyComputer_fnMapNameToSCID
2246 /************************************************************************
2247 * ISFPersistFolder_QueryInterface (IUnknown)
2250 static HRESULT WINAPI ISFPersistFolder_QueryInterface(
2251 IPersistFolder * iface,
2255 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
2257 TRACE("(%p)\n", This);
2259 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2262 /************************************************************************
2263 * ISFPersistFolder_AddRef (IUnknown)
2266 static ULONG WINAPI ISFPersistFolder_AddRef(
2267 IPersistFolder * iface)
2269 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
2271 TRACE("(%p)\n", This);
2273 return IUnknown_AddRef(This->pUnkOuter);
2276 /************************************************************************
2277 * ISFPersistFolder_Release (IUnknown)
2280 static ULONG WINAPI ISFPersistFolder_Release(
2281 IPersistFolder * iface)
2283 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
2285 TRACE("(%p)\n", This);
2287 return IUnknown_Release(This->pUnkOuter);
2290 /************************************************************************
2291 * ISFPersistFolder_GetClassID (IPersist)
2293 static HRESULT WINAPI ISFPersistFolder_GetClassID(
2294 IPersistFolder * iface,
2297 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
2299 TRACE("(%p)\n", This);
2301 if (!lpClassId) return E_POINTER;
2302 *lpClassId = *This->pclsid;
2307 /************************************************************************
2308 * ISFPersistFolder_Initialize (IPersistFolder)
2311 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2313 static HRESULT WINAPI ISFPersistFolder_Initialize(
2314 IPersistFolder * iface,
2317 char sTemp[MAX_PATH];
2318 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
2320 TRACE("(%p)->(%p)\n", This, pidl);
2322 /* free the old stuff */
2325 SHFree(This->absPidl);
2326 This->absPidl = NULL;
2330 SHFree(This->sMyPath);
2331 This->sMyPath = NULL;
2335 This->absPidl = ILClone(pidl);
2338 if (SHGetPathFromIDListA(pidl, sTemp))
2340 This->sMyPath = SHAlloc(strlen(sTemp+1));
2341 strcpy(This->sMyPath, sTemp);
2344 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2349 static ICOM_VTABLE(IPersistFolder) psfvt =
2351 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2352 ISFPersistFolder_QueryInterface,
2353 ISFPersistFolder_AddRef,
2354 ISFPersistFolder_Release,
2355 ISFPersistFolder_GetClassID,
2356 ISFPersistFolder_Initialize
2359 /****************************************************************************
2360 * ISFDropTarget implementation
2362 static BOOL ISFDropTarget_QueryDrop(
2367 DWORD dwEffect = *pdwEffect;
2369 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2371 *pdwEffect = DROPEFFECT_NONE;
2373 if (This->fAcceptFmt)
2374 { /* Does our interpretation of the keystate ... */
2375 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2377 /* ... matches the desired effect ? */
2378 if (dwEffect & *pdwEffect)
2386 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2391 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2393 TRACE("(%p)\n", This);
2395 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2398 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2400 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2402 TRACE("(%p)\n", This);
2404 return IUnknown_AddRef(This->pUnkOuter);
2407 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2409 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2411 TRACE("(%p)\n", This);
2413 return IUnknown_Release(This->pUnkOuter);
2416 static HRESULT WINAPI ISFDropTarget_DragEnter(
2418 IDataObject *pDataObject,
2425 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2427 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2429 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2431 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2433 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2438 static HRESULT WINAPI ISFDropTarget_DragOver(
2444 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2446 TRACE("(%p)\n",This);
2448 if(!pdwEffect) return E_INVALIDARG;
2450 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2455 static HRESULT WINAPI ISFDropTarget_DragLeave(
2458 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2460 TRACE("(%p)\n",This);
2462 This->fAcceptFmt = FALSE;
2467 static HRESULT WINAPI ISFDropTarget_Drop(
2469 IDataObject* pDataObject,
2474 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2476 FIXME("(%p) object dropped\n",This);
2481 static struct ICOM_VTABLE(IDropTarget) dtvt =
2483 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2484 ISFDropTarget_QueryInterface,
2485 ISFDropTarget_AddRef,
2486 ISFDropTarget_Release,
2487 ISFDropTarget_DragEnter,
2488 ISFDropTarget_DragOver,
2489 ISFDropTarget_DragLeave,