Make RDW_ValidateParent() modify the update region of all parents, not
[wine/multimedia.git] / dlls / shell32 / shlfolder.c
blob5512f71035c70851024cf7c6576064c42fc61e42
1 /*
2 * Shell Folder stuff
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
6 *
7 * IShellFolder2 and related interfaces
9 */
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdio.h>
15 #include "debugtools.h"
16 #include "winerror.h"
18 #include "oleidl.h"
19 #include "shlguid.h"
21 #include "pidl.h"
22 #include "wine/obj_base.h"
23 #include "wine/obj_dragdrop.h"
24 #include "wine/obj_shellfolder.h"
25 #include "wine/undocshell.h"
26 #include "shell32_main.h"
27 #include "shresdef.h"
29 #define INITGUID
30 #include "initguid.h"
31 #include "shellfolder.h"
34 DEFAULT_DEBUG_CHANNEL(shell)
37 /***************************************************************************
38 * debughelper: print out the return adress
39 * helps especially to track down unbalanced AddRef/Release
41 #define MEM_DEBUG 0
43 #if MEM_DEBUG
44 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
45 #else
46 #define _CALL_TRACE
47 #endif
49 typedef struct
51 int colnameid;
52 int pcsFlags;
53 int fmt;
54 int cxChar;
56 } shvheader;
58 /***************************************************************************
59 * GetNextElement (internal function)
61 * gets a part of a string till the first backslash
63 * PARAMETERS
64 * pszNext [IN] string to get the element from
65 * pszOut [IN] pointer to buffer whitch receives string
66 * dwOut [IN] length of pszOut
68 * RETURNS
69 * LPSTR pointer to first, not yet parsed char
72 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
73 { LPCWSTR pszTail = pszNext;
74 DWORD dwCopy;
75 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
77 *pszOut=0x0000;
79 if(!pszNext || !*pszNext)
80 return NULL;
82 while(*pszTail && (*pszTail != (WCHAR)'\\'))
83 pszTail++;
85 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
86 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
88 if(*pszTail)
89 pszTail++;
90 else
91 pszTail = NULL;
93 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
94 return pszTail;
97 static HRESULT SHELL32_ParseNextElement(
98 HWND hwndOwner,
99 IShellFolder2 * psf,
100 LPITEMIDLIST * pidlInOut,
101 LPOLESTR szNext,
102 DWORD *pEaten,
103 DWORD *pdwAttributes)
105 HRESULT hr = E_OUTOFMEMORY;
106 LPITEMIDLIST pidlOut, pidlTemp = NULL;
107 IShellFolder *psfChild;
109 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
112 /* get the shellfolder for the child pidl and let it analyse further */
113 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
115 if (psfChild)
117 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
118 IShellFolder_Release(psfChild);
120 pidlTemp = ILCombine(*pidlInOut, pidlOut);
122 if (pidlOut)
123 ILFree(pidlOut);
126 ILFree(*pidlInOut);
127 *pidlInOut = pidlTemp;
129 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
130 return hr;
133 /***********************************************************************
134 * SHELL32_CoCreateInitSF
136 * creates a initialized shell folder
138 static HRESULT SHELL32_CoCreateInitSF (
139 LPITEMIDLIST pidlRoot,
140 LPITEMIDLIST pidlChild,
141 REFCLSID clsid,
142 REFIID iid,
143 LPVOID * ppvOut)
145 HRESULT hr;
146 LPITEMIDLIST absPidl;
147 IShellFolder2 *pShellFolder;
148 IPersistFolder *pPersistFolder;
150 TRACE("%p %p\n", pidlRoot, pidlChild);
152 *ppvOut = NULL;
154 /* we have to ask first for IPersistFolder, some special folders are expecting this */
155 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
156 if (SUCCEEDED(hr))
158 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
159 if (SUCCEEDED(hr))
161 absPidl = ILCombine (pidlRoot, pidlChild);
162 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
163 IPersistFolder_Release(pPersistFolder);
164 SHFree(absPidl);
165 *ppvOut = pShellFolder;
169 TRACE("-- ret=0x%08lx\n", hr);
170 return hr;
173 static HRESULT SHELL32_GetDisplayNameOfChild(
174 IShellFolder2 * psf,
175 LPCITEMIDLIST pidl,
176 DWORD dwFlags,
177 LPSTR szOut,
178 DWORD dwOutLen)
180 LPITEMIDLIST pidlFirst, pidlNext;
181 IShellFolder2 * psfChild;
182 HRESULT hr = E_OUTOFMEMORY;
183 STRRET strTemp;
185 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
186 pdump(pidl);
188 if ((pidlFirst = ILCloneFirst(pidl)))
190 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
191 if (SUCCEEDED(hr))
193 pidlNext = ILGetNext(pidl);
195 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
196 if (SUCCEEDED(hr))
198 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
201 IShellFolder_Release(psfChild);
203 ILFree(pidlFirst);
206 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
208 return hr;
211 /***********************************************************************
212 * IShellFolder implementation
215 typedef struct
217 ICOM_VFIELD(IUnknown);
218 DWORD ref;
219 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
220 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
221 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
222 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
224 IUnknown *pUnkOuter; /* used for aggregation */
226 CLSID* pclsid;
228 LPSTR sMyPath;
229 LPITEMIDLIST absPidl; /* complete pidl */
231 UINT cfShellIDList; /* clipboardformat for IDropTarget */
232 BOOL fAcceptFmt; /* flag for pending Drop */
233 } IGenericSFImpl;
235 static struct ICOM_VTABLE(IUnknown) unkvt;
236 static struct ICOM_VTABLE(IShellFolder2) sfvt;
237 static struct ICOM_VTABLE(IPersistFolder2) psfvt;
238 static struct ICOM_VTABLE(IDropTarget) dtvt;
239 static struct ICOM_VTABLE(ISFHelper) shvt;
241 static IShellFolder * ISF_MyComputer_Constructor(void);
243 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
244 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
246 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
247 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
249 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
250 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
252 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
253 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
255 converts This to a interface pointer
257 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
258 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
259 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
260 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
261 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
262 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
263 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
264 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
265 /**************************************************************************
266 * registers clipboardformat once
268 static void SF_RegisterClipFmt (IGenericSFImpl * This)
270 TRACE("(%p)\n", This);
272 if (!This->cfShellIDList)
274 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
278 /**************************************************************************
279 * we need a seperate IUnknown to handle aggregation
280 * (inner IUnknown)
282 static HRESULT WINAPI IUnknown_fnQueryInterface(
283 IUnknown * iface,
284 REFIID riid,
285 LPVOID *ppvObj)
287 ICOM_THIS(IGenericSFImpl, iface);
289 _CALL_TRACE
290 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
292 *ppvObj = NULL;
294 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
295 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
296 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
297 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
298 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
299 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
300 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
301 else if(IsEqualIID(riid, &IID_IDropTarget))
303 *ppvObj = _IDropTarget_(This);
304 SF_RegisterClipFmt(This);
307 if(*ppvObj)
309 IUnknown_AddRef((IUnknown*)(*ppvObj));
310 TRACE("-- Interface = %p\n", *ppvObj);
311 return S_OK;
313 TRACE("-- Interface: E_NOINTERFACE\n");
314 return E_NOINTERFACE;
317 static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
319 ICOM_THIS(IGenericSFImpl, iface);
321 _CALL_TRACE
322 TRACE("(%p)->(count=%lu)\n",This,This->ref);
324 shell32_ObjCount++;
325 return ++(This->ref);
328 static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
330 ICOM_THIS(IGenericSFImpl, iface);
332 _CALL_TRACE
333 TRACE("(%p)->(count=%lu)\n",This,This->ref);
335 shell32_ObjCount--;
336 if (!--(This->ref))
338 TRACE("-- destroying IShellFolder(%p)\n",This);
340 if (pdesktopfolder == _IShellFolder_(This))
342 pdesktopfolder=NULL;
343 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
345 if(This->absPidl) SHFree(This->absPidl);
346 if(This->sMyPath) SHFree(This->sMyPath);
347 HeapFree(GetProcessHeap(),0,This);
348 return 0;
350 return This->ref;
353 static ICOM_VTABLE(IUnknown) unkvt =
355 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
356 IUnknown_fnQueryInterface,
357 IUnknown_fnAddRef,
358 IUnknown_fnRelease,
361 static shvheader GenericSFHeader [] =
363 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
364 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
365 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
366 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
367 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
369 #define GENERICSHELLVIEWCOLUMNS 5
371 /**************************************************************************
372 * IShellFolder_Constructor
374 * NOTES
375 * creating undocumented ShellFS_Folder as part of an aggregation
376 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
378 * FIXME
379 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
381 HRESULT IFSFolder_Constructor(
382 IUnknown * pUnkOuter,
383 REFIID riid,
384 LPVOID * ppv)
386 IGenericSFImpl * sf;
387 HRESULT hr = S_OK;
389 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
391 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
393 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
395 else
397 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
398 if (sf)
400 sf->ref=1;
401 ICOM_VTBL(sf)=&unkvt;
402 sf->lpvtblShellFolder=&sfvt;
403 sf->lpvtblPersistFolder2=&psfvt;
404 sf->lpvtblDropTarget=&dtvt;
405 sf->lpvtblSFHelper=&shvt;
407 sf->pclsid = (CLSID*)&CLSID_SFFile;
408 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
409 *ppv = _IUnknown_(sf);
410 hr = S_OK;
411 shell32_ObjCount++;
413 else
415 hr = E_OUTOFMEMORY;
418 return hr;
420 /**************************************************************************
421 * IShellFolder_Constructor
423 * NOTES
424 * THIS points to the parent folder
427 IShellFolder * IShellFolder_Constructor(
428 IShellFolder2 * iface,
429 LPITEMIDLIST pidl)
431 IGenericSFImpl * sf;
432 DWORD dwSize=0;
434 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
436 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
437 sf->ref=1;
439 ICOM_VTBL(sf)=&unkvt;
440 sf->lpvtblShellFolder=&sfvt;
441 sf->lpvtblPersistFolder2=&psfvt;
442 sf->lpvtblDropTarget=&dtvt;
443 sf->lpvtblSFHelper=&shvt;
445 sf->pclsid = (CLSID*)&CLSID_SFFile;
446 sf->pUnkOuter = _IUnknown_(sf);
448 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
449 pdump(pidl);
451 if(pidl && iface) /* do we have a pidl? */
453 int len;
455 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
457 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
459 if(This->sMyPath) /* get the size of the parents path */
461 dwSize += strlen(This->sMyPath) ;
462 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
465 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
466 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
468 if(!sf->sMyPath) return NULL;
469 *(sf->sMyPath)=0x00;
471 if(This->sMyPath) /* if the parent has a path, get it*/
473 strcpy(sf->sMyPath, This->sMyPath);
474 PathAddBackslashA (sf->sMyPath);
477 len = strlen(sf->sMyPath);
478 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
481 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
483 pdump (sf->absPidl);
486 shell32_ObjCount++;
487 return _IShellFolder_(sf);
490 /**************************************************************************
491 * IShellFolder_fnQueryInterface
493 * PARAMETERS
494 * REFIID riid [in ] Requested InterfaceID
495 * LPVOID* ppvObject [out] Interface* to hold the result
497 static HRESULT WINAPI IShellFolder_fnQueryInterface(
498 IShellFolder2 * iface,
499 REFIID riid,
500 LPVOID *ppvObj)
502 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
504 _CALL_TRACE
505 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
507 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
510 /**************************************************************************
511 * IShellFolder_AddRef
514 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
516 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
518 _CALL_TRACE
519 TRACE("(%p)->(count=%lu)\n",This,This->ref);
521 return IUnknown_AddRef(This->pUnkOuter);
524 /**************************************************************************
525 * IShellFolder_fnRelease
527 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
529 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
531 _CALL_TRACE
532 TRACE("(%p)->(count=%lu)\n",This,This->ref);
534 return IUnknown_Release(This->pUnkOuter);
537 /**************************************************************************
538 * IShellFolder_fnParseDisplayName
539 * PARAMETERS
540 * HWND hwndOwner, //[in ] Parent window for any message's
541 * LPBC pbc, //[in ] reserved
542 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
543 * ULONG* pchEaten, //[out] (unicode) characters processed
544 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
545 * ULONG* pdwAttributes //[out] items attributes
547 * NOTES
548 * every folder trys to parse only it's own (the leftmost) pidl and creates a
549 * subfolder to evaluate the remaining parts
550 * now we can parse into namespaces implemented by shell extensions
552 * behaviour on win98: lpszDisplayName=NULL -> chrash
553 * lpszDisplayName="" -> returns mycoputer-pidl
555 * FIXME:
556 * pdwAttributes: not set
557 * pchEaten: not set like in windows
559 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
560 IShellFolder2 * iface,
561 HWND hwndOwner,
562 LPBC pbcReserved,
563 LPOLESTR lpszDisplayName,
564 DWORD *pchEaten,
565 LPITEMIDLIST *ppidl,
566 DWORD *pdwAttributes)
568 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
570 HRESULT hr = E_OUTOFMEMORY;
571 LPCWSTR szNext=NULL;
572 WCHAR szElement[MAX_PATH];
573 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
574 LPITEMIDLIST pidlTemp=NULL;
576 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
577 This,hwndOwner,pbcReserved,lpszDisplayName,
578 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
580 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
582 if (pchEaten) *pchEaten = 0; /* strange but like the original */
584 if (*lpszDisplayName)
586 /* get the next element */
587 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
589 /* build the full pathname to the element */
590 lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
591 strcpy(szPath, This->sMyPath);
592 PathAddBackslashA(szPath);
593 strcat(szPath, szTempA);
595 /* get the pidl */
596 pidlTemp = SHSimpleIDListFromPathA(szPath);
598 if (pidlTemp)
600 /* try to analyse the next element */
601 if (szNext && *szNext)
603 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
605 else
607 hr = S_OK;
612 *ppidl = pidlTemp;
614 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
616 return hr;
619 /**************************************************************************
620 * IShellFolder_fnEnumObjects
621 * PARAMETERS
622 * HWND hwndOwner, //[in ] Parent Window
623 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
624 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
626 static HRESULT WINAPI IShellFolder_fnEnumObjects(
627 IShellFolder2 * iface,
628 HWND hwndOwner,
629 DWORD dwFlags,
630 LPENUMIDLIST* ppEnumIDList)
632 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
634 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
636 *ppEnumIDList = NULL;
637 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
639 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
641 if(!*ppEnumIDList) return E_OUTOFMEMORY;
643 return S_OK;
646 /**************************************************************************
647 * IShellFolder_fnBindToObject
648 * PARAMETERS
649 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
650 * LPBC pbc, //[in ] reserved
651 * REFIID riid, //[in ] Initial Interface
652 * LPVOID* ppvObject //[out] Interface*
654 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
655 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
657 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
658 GUID const * iid;
659 IShellFolder *pShellFolder, *pSubFolder;
660 IPersistFolder *pPersistFolder;
661 LPITEMIDLIST absPidl;
663 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
665 if(!pidl || !ppvOut) return E_INVALIDARG;
667 *ppvOut = NULL;
669 if ((iid=_ILGetGUIDPointer(pidl)))
671 /* we have to create a alien folder */
672 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
673 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
675 absPidl = ILCombine (This->absPidl, pidl);
676 IPersistFolder_Initialize(pPersistFolder, absPidl);
677 IPersistFolder_Release(pPersistFolder);
678 SHFree(absPidl);
680 else
682 return E_FAIL;
685 else
687 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
688 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
689 ILFree(pidltemp);
692 if (_ILIsPidlSimple(pidl))
694 *ppvOut = pShellFolder;
696 else
698 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
699 IShellFolder_Release(pShellFolder);
700 *ppvOut = pSubFolder;
703 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
705 return S_OK;
708 /**************************************************************************
709 * IShellFolder_fnBindToStorage
710 * PARAMETERS
711 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
712 * LPBC pbc, //[in ] reserved
713 * REFIID riid, //[in ] Initial storage interface
714 * LPVOID* ppvObject //[out] Interface* returned
716 static HRESULT WINAPI IShellFolder_fnBindToStorage(
717 IShellFolder2 * iface,
718 LPCITEMIDLIST pidl,
719 LPBC pbcReserved,
720 REFIID riid,
721 LPVOID *ppvOut)
723 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
725 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
726 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
728 *ppvOut = NULL;
729 return E_NOTIMPL;
732 /**************************************************************************
733 * IShellFolder_fnCompareIDs
735 * PARMETERS
736 * LPARAM lParam, //[in ] Column?
737 * LPCITEMIDLIST pidl1, //[in ] simple pidl
738 * LPCITEMIDLIST pidl2) //[in ] simple pidl
740 * NOTES
741 * Special case - If one of the items is a Path and the other is a File,
742 * always make the Path come before the File.
744 * NOTES
745 * use SCODE_CODE() on the return value to get the result
748 static HRESULT WINAPI IShellFolder_fnCompareIDs(
749 IShellFolder2 * iface,
750 LPARAM lParam,
751 LPCITEMIDLIST pidl1,
752 LPCITEMIDLIST pidl2)
754 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
756 CHAR szTemp1[MAX_PATH];
757 CHAR szTemp2[MAX_PATH];
758 int nReturn;
759 IShellFolder * psf;
760 HRESULT hr = E_OUTOFMEMORY;
761 LPCITEMIDLIST pidlTemp;
762 PIDLTYPE pt1, pt2;
764 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
765 pdump (pidl1);
766 pdump (pidl2);
768 if (!pidl1 && !pidl2)
770 hr = ResultFromShort(0);
772 else if (!pidl1)
774 hr = ResultFromShort(-1);
776 else if (!pidl2)
778 hr = ResultFromShort(1);
780 else
782 LPPIDLDATA pd1, pd2;
783 pd1 = _ILGetDataPointer(pidl1);
784 pd2 = _ILGetDataPointer(pidl2);
786 /* compate the types. sort order is the PT_* constant */
787 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
788 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
790 if (pt1 != pt2)
792 hr = ResultFromShort(pt1-pt2);
794 else /* same type of pidl */
796 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
797 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
798 nReturn = strcasecmp(szTemp1, szTemp2);
800 if (nReturn == 0) /* first pidl different ? */
802 pidl1 = ILGetNext(pidl1);
804 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
806 pidlTemp = ILCloneFirst(pidl1);
807 pidl2 = ILGetNext(pidl2);
809 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
810 if (SUCCEEDED(hr))
812 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
813 IShellFolder_Release(psf);
814 hr = ResultFromShort(nReturn);
816 ILFree(pidlTemp);
818 else
820 hr = ResultFromShort(nReturn); /* two equal simple pidls */
823 else
825 hr = ResultFromShort(nReturn); /* two different simple pidls */
830 TRACE("-- res=0x%08lx\n", hr);
831 return hr;
834 /**************************************************************************
835 * IShellFolder_fnCreateViewObject
837 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
838 IShellFolder2 * iface,
839 HWND hwndOwner,
840 REFIID riid,
841 LPVOID *ppvOut)
843 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
845 LPSHELLVIEW pShellView;
846 HRESULT hr = E_INVALIDARG;
848 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
850 if(ppvOut)
852 *ppvOut = NULL;
854 if(IsEqualIID(riid, &IID_IDropTarget))
856 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
858 else if(IsEqualIID(riid, &IID_IContextMenu))
860 FIXME("IContextMenu not implemented\n");
861 hr = E_NOTIMPL;
863 else if(IsEqualIID(riid, &IID_IShellView))
865 pShellView = IShellView_Constructor((IShellFolder*)iface);
866 if(pShellView)
868 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
869 IShellView_Release(pShellView);
873 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
874 return hr;
877 /**************************************************************************
878 * IShellFolder_fnGetAttributesOf
880 * PARAMETERS
881 * UINT cidl, //[in ] num elements in pidl array
882 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
883 * ULONG* rgfInOut) //[out] result array
886 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
887 IShellFolder2 * iface,
888 UINT cidl,
889 LPCITEMIDLIST *apidl,
890 DWORD *rgfInOut)
892 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
894 HRESULT hr = S_OK;
896 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
898 if ( (!cidl) || (!apidl) || (!rgfInOut))
899 return E_INVALIDARG;
901 while (cidl > 0 && *apidl)
903 pdump (*apidl);
904 if (_ILIsFolder( *apidl))
906 *rgfInOut &= 0xe0000177;
907 goto next;
909 else if (_ILIsValue( *apidl))
911 *rgfInOut &= 0x40000177;
912 goto next;
914 hr = E_INVALIDARG;
916 next: apidl++;
917 cidl--;
920 TRACE("-- result=0x%08lx\n",*rgfInOut);
922 return hr;
924 /**************************************************************************
925 * IShellFolder_fnGetUIObjectOf
927 * PARAMETERS
928 * HWND hwndOwner, //[in ] Parent window for any output
929 * UINT cidl, //[in ] array size
930 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
931 * REFIID riid, //[in ] Requested Interface
932 * UINT* prgfInOut, //[ ] reserved
933 * LPVOID* ppvObject) //[out] Resulting Interface
935 * NOTES
936 * This function gets asked to return "view objects" for one or more (multiple select)
937 * items:
938 * The viewobject typically is an COM object with one of the following interfaces:
939 * IExtractIcon,IDataObject,IContextMenu
940 * In order to support icon positions in the default Listview your DataObject
941 * must implement the SetData method (in addition to GetData :) - the shell passes
942 * a barely documented "Icon positions" structure to SetData when the drag starts,
943 * and GetData's it if the drop is in another explorer window that needs the positions.
945 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
946 IShellFolder2 * iface,
947 HWND hwndOwner,
948 UINT cidl,
949 LPCITEMIDLIST * apidl,
950 REFIID riid,
951 UINT * prgfInOut,
952 LPVOID * ppvOut)
954 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
956 LPITEMIDLIST pidl;
957 IUnknown* pObj = NULL;
958 HRESULT hr = E_INVALIDARG;
960 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
961 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
963 if (ppvOut)
965 *ppvOut = NULL;
967 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
969 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
970 hr = S_OK;
972 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
974 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
975 hr = S_OK;
977 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
979 pidl = ILCombine(This->absPidl,apidl[0]);
980 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
981 SHFree(pidl);
982 hr = S_OK;
984 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
986 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
988 else
990 hr = E_NOINTERFACE;
993 if(!pObj)
994 hr = E_OUTOFMEMORY;
996 *ppvOut = pObj;
998 TRACE("(%p)->hr=0x%08lx\n",This, hr);
999 return hr;
1002 /**************************************************************************
1003 * IShellFolder_fnGetDisplayNameOf
1004 * Retrieves the display name for the specified file object or subfolder
1006 * PARAMETERS
1007 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1008 * DWORD dwFlags, //[in ] SHGNO formatting flags
1009 * LPSTRRET lpName) //[out] Returned display name
1011 * FIXME
1012 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1014 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1015 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1017 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1018 IShellFolder2 * iface,
1019 LPCITEMIDLIST pidl,
1020 DWORD dwFlags,
1021 LPSTRRET strRet)
1023 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1025 CHAR szPath[MAX_PATH]= "";
1026 int len = 0;
1027 BOOL bSimplePidl;
1029 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1030 pdump(pidl);
1032 if(!pidl || !strRet) return E_INVALIDARG;
1034 bSimplePidl = _ILIsPidlSimple(pidl);
1036 /* take names of special folders only if its only this folder */
1037 if (_ILIsSpecialFolder(pidl))
1039 if ( bSimplePidl)
1041 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1044 else
1046 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1048 strcpy (szPath, This->sMyPath); /* get path to root*/
1049 PathAddBackslashA(szPath);
1050 len = strlen(szPath);
1052 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1055 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1057 PathAddBackslashA(szPath);
1058 len = strlen(szPath);
1060 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1061 return E_OUTOFMEMORY;
1063 strRet->uType = STRRET_CSTRA;
1064 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1066 TRACE("-- (%p)->(%s)\n", This, szPath);
1067 return S_OK;
1070 /**************************************************************************
1071 * IShellFolder_fnSetNameOf
1072 * Changes the name of a file object or subfolder, possibly changing its item
1073 * identifier in the process.
1075 * PARAMETERS
1076 * HWND hwndOwner, //[in ] Owner window for output
1077 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1078 * LPCOLESTR lpszName, //[in ] the items new display name
1079 * DWORD dwFlags, //[in ] SHGNO formatting flags
1080 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1082 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1083 IShellFolder2 * iface,
1084 HWND hwndOwner,
1085 LPCITEMIDLIST pidl, /*simple pidl*/
1086 LPCOLESTR lpName,
1087 DWORD dwFlags,
1088 LPITEMIDLIST *pPidlOut)
1090 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1091 char szSrc[MAX_PATH], szDest[MAX_PATH];
1092 int len;
1093 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1095 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1096 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1098 /* build source path */
1099 if (dwFlags & SHGDN_INFOLDER)
1101 strcpy(szSrc, This->sMyPath);
1102 PathAddBackslashA(szSrc);
1103 len = strlen (szSrc);
1104 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1106 else
1108 SHGetPathFromIDListA(pidl, szSrc);
1111 /* build destination path */
1112 strcpy(szDest, This->sMyPath);
1113 PathAddBackslashA(szDest);
1114 len = strlen (szDest);
1115 lstrcpynWtoA(szDest+len, lpName, MAX_PATH-len);
1117 TRACE("src=%s dest=%s\n", szSrc, szDest);
1118 if ( MoveFileA(szSrc, szDest) )
1120 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1121 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1122 return S_OK;
1124 return E_FAIL;
1127 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1128 IShellFolder2 * iface,
1129 GUID *pguid)
1131 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1132 FIXME("(%p)\n",This);
1133 return E_NOTIMPL;
1135 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1136 IShellFolder2 * iface,
1137 IEnumExtraSearch **ppenum)
1139 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1140 FIXME("(%p)\n",This);
1141 return E_NOTIMPL;
1143 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1144 IShellFolder2 * iface,
1145 DWORD dwRes,
1146 ULONG *pSort,
1147 ULONG *pDisplay)
1149 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1151 TRACE("(%p)\n",This);
1153 if (pSort) *pSort = 0;
1154 if (pDisplay) *pDisplay = 0;
1156 return S_OK;
1158 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1159 IShellFolder2 * iface,
1160 UINT iColumn,
1161 DWORD *pcsFlags)
1163 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1165 TRACE("(%p)\n",This);
1167 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1169 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1171 return S_OK;
1173 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1174 IShellFolder2 * iface,
1175 LPCITEMIDLIST pidl,
1176 const SHCOLUMNID *pscid,
1177 VARIANT *pv)
1179 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1180 FIXME("(%p)\n",This);
1182 return E_NOTIMPL;
1184 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1185 IShellFolder2 * iface,
1186 LPCITEMIDLIST pidl,
1187 UINT iColumn,
1188 SHELLDETAILS *psd)
1190 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1191 HRESULT hr = E_FAIL;
1193 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1195 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1197 if (!pidl)
1199 /* the header titles */
1200 psd->fmt = GenericSFHeader[iColumn].fmt;
1201 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1202 psd->str.uType = STRRET_CSTRA;
1203 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1204 return S_OK;
1206 else
1208 /* the data from the pidl */
1209 switch(iColumn)
1211 case 0: /* name */
1212 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1213 break;
1214 case 1: /* size */
1215 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1216 break;
1217 case 2: /* type */
1218 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1219 break;
1220 case 3: /* date */
1221 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1222 break;
1223 case 4: /* attributes */
1224 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1225 break;
1227 hr = S_OK;
1228 psd->str.uType = STRRET_CSTRA;
1231 return hr;
1233 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1234 IShellFolder2 * iface,
1235 LPCWSTR pwszName,
1236 SHCOLUMNID *pscid)
1238 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1239 FIXME("(%p)\n",This);
1240 return E_NOTIMPL;
1243 static ICOM_VTABLE(IShellFolder2) sfvt =
1245 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1246 IShellFolder_fnQueryInterface,
1247 IShellFolder_fnAddRef,
1248 IShellFolder_fnRelease,
1249 IShellFolder_fnParseDisplayName,
1250 IShellFolder_fnEnumObjects,
1251 IShellFolder_fnBindToObject,
1252 IShellFolder_fnBindToStorage,
1253 IShellFolder_fnCompareIDs,
1254 IShellFolder_fnCreateViewObject,
1255 IShellFolder_fnGetAttributesOf,
1256 IShellFolder_fnGetUIObjectOf,
1257 IShellFolder_fnGetDisplayNameOf,
1258 IShellFolder_fnSetNameOf,
1260 /* ShellFolder2 */
1261 IShellFolder_fnGetDefaultSearchGUID,
1262 IShellFolder_fnEnumSearches,
1263 IShellFolder_fnGetDefaultColumn,
1264 IShellFolder_fnGetDefaultColumnState,
1265 IShellFolder_fnGetDetailsEx,
1266 IShellFolder_fnGetDetailsOf,
1267 IShellFolder_fnMapNameToSCID
1270 /****************************************************************************
1271 * ISFHelper for IShellFolder implementation
1274 static HRESULT WINAPI ISFHelper_fnQueryInterface(
1275 ISFHelper *iface,
1276 REFIID riid,
1277 LPVOID *ppvObj)
1279 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1281 TRACE("(%p)\n", This);
1283 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1286 static ULONG WINAPI ISFHelper_fnAddRef(
1287 ISFHelper *iface)
1289 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1291 TRACE("(%p)\n", This);
1293 return IUnknown_AddRef(This->pUnkOuter);
1296 static ULONG WINAPI ISFHelper_fnRelease(
1297 ISFHelper *iface)
1299 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1301 TRACE("(%p)\n", This);
1303 return IUnknown_Release(This->pUnkOuter);
1307 /****************************************************************************
1308 * ISFHelper_fnAddFolder
1310 * creates a unique folder name
1313 static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1314 ISFHelper *iface,
1315 LPSTR lpName,
1316 UINT uLen)
1318 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1319 IEnumIDList * penum;
1320 HRESULT hr;
1321 char szText[MAX_PATH];
1322 char * szNewFolder = "New Folder";
1324 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1326 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1328 strcpy(lpName, szNewFolder);
1330 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1331 if (penum)
1333 LPITEMIDLIST pidl;
1334 DWORD dwFetched;
1335 int i=1;
1337 next: IEnumIDList_Reset(penum);
1338 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1340 _ILSimpleGetText(pidl, szText, MAX_PATH);
1341 if (0 == strcasecmp(szText, lpName))
1343 sprintf(lpName, "%s %d", szNewFolder, i++);
1344 if (i > 99)
1346 hr = E_FAIL;
1347 break;
1349 goto next;
1353 IEnumIDList_Release(penum);
1355 return hr;
1358 /****************************************************************************
1359 * ISFHelper_fnAddFolder
1361 * adds a new folder.
1364 static HRESULT WINAPI ISFHelper_fnAddFolder(
1365 ISFHelper *iface,
1366 HWND hwnd,
1367 LPCSTR lpName,
1368 LPITEMIDLIST* ppidlOut)
1370 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1371 char lpstrNewDir[MAX_PATH];
1372 DWORD bRes;
1373 HRESULT hres = E_FAIL;
1375 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1377 strcpy(lpstrNewDir, This->sMyPath);
1378 PathAddBackslashA(lpstrNewDir);
1379 strcat(lpstrNewDir, lpName);
1381 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1383 if (bRes)
1385 LPITEMIDLIST pidl, pidlitem;
1387 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1389 pidl = ILCombine(This->absPidl, pidlitem);
1390 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1391 SHFree(pidl);
1393 if (ppidlOut) *ppidlOut = pidlitem;
1394 hres = S_OK;
1396 else
1398 char lpstrText[128+MAX_PATH];
1399 char lpstrTempText[128];
1400 char lpstrCaption[256];
1402 /* Cannot Create folder because of permissions */
1403 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1404 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1405 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1406 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1409 return hres;
1412 /****************************************************************************
1413 * ISFHelper_fnDeleteItems
1415 * deletes items in folder
1417 static HRESULT WINAPI ISFHelper_fnDeleteItems(
1418 ISFHelper *iface,
1419 UINT cidl,
1420 LPCITEMIDLIST* apidl)
1422 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1423 int i;
1424 char szPath[MAX_PATH];
1426 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1428 for(i=0; i< cidl; i++)
1430 strcpy(szPath, This->sMyPath);
1431 PathAddBackslashA(szPath);
1432 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1434 if (_ILIsFolder(apidl[i]))
1436 LPITEMIDLIST pidl;
1438 MESSAGE("delete %s\n", szPath);
1439 if (! RemoveDirectoryA(szPath)) return E_FAIL;
1440 pidl = ILCombine(This->absPidl, apidl[i]);
1441 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1442 SHFree(pidl);
1444 else if (_ILIsValue(apidl[i]))
1446 LPITEMIDLIST pidl;
1448 MESSAGE("delete %s\n", szPath);
1449 if (! DeleteFileA(szPath)) return E_FAIL;
1450 pidl = ILCombine(This->absPidl, apidl[i]);
1451 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1452 SHFree(pidl);
1456 return S_OK;
1459 /****************************************************************************
1460 * ISFHelper_fnCopyItems
1462 * copys items to this folder
1464 static HRESULT WINAPI ISFHelper_fnCopyItems(
1465 ISFHelper *iface,
1466 IShellFolder* pSFFrom,
1467 UINT cidl,
1468 LPCITEMIDLIST *apidl)
1470 int i;
1471 IPersistFolder2 * ppf2=NULL;
1472 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1473 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1475 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1477 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1478 if (ppf2)
1480 LPITEMIDLIST pidl;
1481 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1483 for (i=0; i<cidl; i++)
1485 SHGetPathFromIDListA(pidl, szSrcPath);
1486 PathAddBackslashA(szSrcPath);
1487 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1489 strcpy(szDstPath, This->sMyPath);
1490 PathAddBackslashA(szDstPath);
1491 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1492 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1494 SHFree(pidl);
1496 IPersistFolder2_Release(ppf2);
1498 return S_OK;
1501 static ICOM_VTABLE(ISFHelper) shvt =
1503 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1504 ISFHelper_fnQueryInterface,
1505 ISFHelper_fnAddRef,
1506 ISFHelper_fnRelease,
1507 ISFHelper_fnGetUniqueName,
1508 ISFHelper_fnAddFolder,
1509 ISFHelper_fnDeleteItems,
1510 ISFHelper_fnCopyItems,
1513 /***********************************************************************
1514 * [Desktopfolder] IShellFolder implementation
1516 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1518 static shvheader DesktopSFHeader [] =
1520 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1521 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1522 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1523 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1524 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1526 #define DESKTOPSHELLVIEWCOLUMNS 5
1528 /**************************************************************************
1529 * ISF_Desktop_Constructor
1532 IShellFolder * ISF_Desktop_Constructor()
1534 IGenericSFImpl * sf;
1536 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1537 sf->ref=1;
1538 ICOM_VTBL(sf)=&unkvt;
1539 sf->lpvtblShellFolder=&sfdvt;
1540 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1541 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1543 TRACE("(%p)\n",sf);
1545 shell32_ObjCount++;
1546 return _IShellFolder_(sf);
1549 /**************************************************************************
1550 * ISF_Desktop_fnQueryInterface
1552 * NOTES supports not IPersist/IPersistFolder
1554 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1555 IShellFolder2 * iface,
1556 REFIID riid,
1557 LPVOID *ppvObj)
1559 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1561 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1563 *ppvObj = NULL;
1565 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1567 *ppvObj = _IUnknown_(This);
1569 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1571 *ppvObj = _IShellFolder_(This);
1573 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1575 *ppvObj = _IShellFolder_(This);
1578 if(*ppvObj)
1580 IUnknown_AddRef((IUnknown*)(*ppvObj));
1581 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1582 return S_OK;
1584 TRACE("-- Interface: E_NOINTERFACE\n");
1585 return E_NOINTERFACE;
1588 /**************************************************************************
1589 * ISF_Desktop_fnParseDisplayName
1591 * NOTES
1592 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1593 * to MyComputer
1595 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1596 IShellFolder2 * iface,
1597 HWND hwndOwner,
1598 LPBC pbcReserved,
1599 LPOLESTR lpszDisplayName,
1600 DWORD *pchEaten,
1601 LPITEMIDLIST *ppidl,
1602 DWORD *pdwAttributes)
1604 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1606 LPCWSTR szNext=NULL;
1607 LPITEMIDLIST pidlTemp=NULL;
1608 HRESULT hr=E_OUTOFMEMORY;
1610 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1611 This,hwndOwner,pbcReserved,lpszDisplayName,
1612 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1614 *ppidl = 0;
1615 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1617 /* fixme no real parsing implemented */
1618 pidlTemp = _ILCreateMyComputer();
1619 szNext = lpszDisplayName;
1621 if (szNext && *szNext)
1623 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1625 else
1627 hr = S_OK;
1630 *ppidl = pidlTemp;
1632 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1634 return hr;
1637 /**************************************************************************
1638 * ISF_Desktop_fnEnumObjects
1640 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1641 IShellFolder2 * iface,
1642 HWND hwndOwner,
1643 DWORD dwFlags,
1644 LPENUMIDLIST* ppEnumIDList)
1646 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1648 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1650 *ppEnumIDList = NULL;
1651 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1653 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1655 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1657 return S_OK;
1660 /**************************************************************************
1661 * ISF_Desktop_fnBindToObject
1663 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1664 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1666 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1667 GUID const * clsid;
1668 IShellFolder *pShellFolder, *pSubFolder;
1670 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1671 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1673 *ppvOut = NULL;
1675 if ((clsid=_ILGetGUIDPointer(pidl)))
1677 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1679 pShellFolder = ISF_MyComputer_Constructor();
1681 else
1683 /* shell extension */
1684 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1686 return E_INVALIDARG;
1690 else
1692 /* file system folder on the desktop */
1693 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1694 IPersistFolder * ppf;
1696 /* combine pidls */
1697 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1698 firstpidl = ILCloneFirst(pidl);
1699 completepidl = ILCombine(deskpidl, firstpidl);
1701 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1702 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1704 IPersistFolder_Initialize(ppf, completepidl);
1705 IPersistFolder_Release(ppf);
1707 ILFree(completepidl);
1708 ILFree(deskpidl);
1709 ILFree(firstpidl);
1712 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1714 *ppvOut = pShellFolder;
1716 else /* go deeper */
1718 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1719 IShellFolder_Release(pShellFolder);
1720 *ppvOut = pSubFolder;
1723 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1725 return S_OK;
1728 /**************************************************************************
1729 * ISF_Desktop_fnCreateViewObject
1731 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1732 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1734 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1736 LPSHELLVIEW pShellView;
1737 HRESULT hr = E_INVALIDARG;
1739 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1741 if(ppvOut)
1743 *ppvOut = NULL;
1745 if(IsEqualIID(riid, &IID_IDropTarget))
1747 FIXME("IDropTarget not implemented\n");
1748 hr = E_NOTIMPL;
1750 else if(IsEqualIID(riid, &IID_IContextMenu))
1752 FIXME("IContextMenu not implemented\n");
1753 hr = E_NOTIMPL;
1755 else if(IsEqualIID(riid, &IID_IShellView))
1757 pShellView = IShellView_Constructor((IShellFolder*)iface);
1758 if(pShellView)
1760 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1761 IShellView_Release(pShellView);
1765 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1766 return hr;
1769 /**************************************************************************
1770 * ISF_Desktop_fnGetAttributesOf
1772 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
1774 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1776 GUID const * clsid;
1777 DWORD attributes;
1778 HRESULT hr = S_OK;
1780 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1782 if ( (!cidl) || (!apidl) || (!rgfInOut))
1783 return E_INVALIDARG;
1785 while (cidl > 0 && *apidl)
1787 pdump (*apidl);
1789 if ((clsid=_ILGetGUIDPointer(*apidl)))
1791 if (IsEqualIID(clsid, &CLSID_MyComputer))
1793 *rgfInOut &= 0xb0000154;
1794 goto next;
1796 else if (HCR_GetFolderAttributes(clsid, &attributes))
1798 *rgfInOut &= attributes;
1799 goto next;
1801 else
1802 { /* some shell-extension */
1803 *rgfInOut &= 0xb0000154;
1806 else if (_ILIsFolder( *apidl))
1808 *rgfInOut &= 0xe0000177;
1809 goto next;
1811 else if (_ILIsValue( *apidl))
1813 *rgfInOut &= 0x40000177;
1814 goto next;
1816 hr = E_INVALIDARG;
1818 next: apidl++;
1819 cidl--;
1822 TRACE("-- result=0x%08lx\n",*rgfInOut);
1824 return hr;
1827 /**************************************************************************
1828 * ISF_Desktop_fnGetDisplayNameOf
1830 * NOTES
1831 * special case: pidl = null gives desktop-name back
1833 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1834 IShellFolder2 * iface,
1835 LPCITEMIDLIST pidl,
1836 DWORD dwFlags,
1837 LPSTRRET strRet)
1839 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1841 CHAR szPath[MAX_PATH]= "";
1843 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1844 pdump(pidl);
1846 if(!strRet) return E_INVALIDARG;
1848 if(!pidl)
1850 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1852 else if ( _ILIsPidlSimple(pidl) )
1854 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1856 else
1858 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1859 return E_OUTOFMEMORY;
1861 strRet->uType = STRRET_CSTRA;
1862 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1865 TRACE("-- (%p)->(%s)\n", This, szPath);
1866 return S_OK;
1869 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1870 IShellFolder2 * iface,
1871 GUID *pguid)
1873 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1874 FIXME("(%p)\n",This);
1875 return E_NOTIMPL;
1877 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1878 IShellFolder2 * iface,
1879 IEnumExtraSearch **ppenum)
1881 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1882 FIXME("(%p)\n",This);
1883 return E_NOTIMPL;
1885 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1886 IShellFolder2 * iface,
1887 DWORD dwRes,
1888 ULONG *pSort,
1889 ULONG *pDisplay)
1891 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1893 TRACE("(%p)\n",This);
1895 if (pSort) *pSort = 0;
1896 if (pDisplay) *pDisplay = 0;
1898 return S_OK;
1900 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1901 IShellFolder2 * iface,
1902 UINT iColumn,
1903 DWORD *pcsFlags)
1905 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1907 TRACE("(%p)\n",This);
1909 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1911 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1913 return S_OK;
1915 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1916 IShellFolder2 * iface,
1917 LPCITEMIDLIST pidl,
1918 const SHCOLUMNID *pscid,
1919 VARIANT *pv)
1921 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1922 FIXME("(%p)\n",This);
1924 return E_NOTIMPL;
1926 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
1927 IShellFolder2 * iface,
1928 LPCITEMIDLIST pidl,
1929 UINT iColumn,
1930 SHELLDETAILS *psd)
1932 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1933 HRESULT hr = E_FAIL;;
1935 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1937 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1939 if (!pidl)
1941 psd->fmt = DesktopSFHeader[iColumn].fmt;
1942 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
1943 psd->str.uType = STRRET_CSTRA;
1944 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1945 return S_OK;
1947 else
1949 /* the data from the pidl */
1950 switch(iColumn)
1952 case 0: /* name */
1953 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1954 break;
1955 case 1: /* size */
1956 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1957 break;
1958 case 2: /* type */
1959 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1960 break;
1961 case 3: /* date */
1962 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1963 break;
1964 case 4: /* attributes */
1965 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1966 break;
1968 hr = S_OK;
1969 psd->str.uType = STRRET_CSTRA;
1972 return hr;
1974 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
1975 IShellFolder2 * iface,
1976 LPCWSTR pwszName,
1977 SHCOLUMNID *pscid)
1979 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1980 FIXME("(%p)\n",This);
1981 return E_NOTIMPL;
1984 static ICOM_VTABLE(IShellFolder2) sfdvt =
1986 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1987 ISF_Desktop_fnQueryInterface,
1988 IShellFolder_fnAddRef,
1989 IShellFolder_fnRelease,
1990 ISF_Desktop_fnParseDisplayName,
1991 ISF_Desktop_fnEnumObjects,
1992 ISF_Desktop_fnBindToObject,
1993 IShellFolder_fnBindToStorage,
1994 IShellFolder_fnCompareIDs,
1995 ISF_Desktop_fnCreateViewObject,
1996 ISF_Desktop_fnGetAttributesOf,
1997 IShellFolder_fnGetUIObjectOf,
1998 ISF_Desktop_fnGetDisplayNameOf,
1999 IShellFolder_fnSetNameOf,
2001 /* ShellFolder2 */
2002 ISF_Desktop_fnGetDefaultSearchGUID,
2003 ISF_Desktop_fnEnumSearches,
2004 ISF_Desktop_fnGetDefaultColumn,
2005 ISF_Desktop_fnGetDefaultColumnState,
2006 ISF_Desktop_fnGetDetailsEx,
2007 ISF_Desktop_fnGetDetailsOf,
2008 ISF_Desktop_fnMapNameToSCID
2012 /***********************************************************************
2013 * IShellFolder [MyComputer] implementation
2016 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2018 static shvheader MyComputerSFHeader [] =
2020 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2021 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2022 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2023 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2025 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2027 /**************************************************************************
2028 * ISF_MyComputer_Constructor
2030 static IShellFolder * ISF_MyComputer_Constructor(void)
2032 IGenericSFImpl * sf;
2034 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2035 sf->ref=1;
2037 ICOM_VTBL(sf)=&unkvt;
2038 sf->lpvtblShellFolder=&sfmcvt;
2039 sf->lpvtblPersistFolder2 = &psfvt;
2040 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2041 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2042 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2044 TRACE("(%p)\n",sf);
2046 shell32_ObjCount++;
2047 return _IShellFolder_(sf);
2050 /**************************************************************************
2051 * ISF_MyComputer_fnParseDisplayName
2053 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2054 IShellFolder2 * iface,
2055 HWND hwndOwner,
2056 LPBC pbcReserved,
2057 LPOLESTR lpszDisplayName,
2058 DWORD *pchEaten,
2059 LPITEMIDLIST *ppidl,
2060 DWORD *pdwAttributes)
2062 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2064 HRESULT hr = E_OUTOFMEMORY;
2065 LPCWSTR szNext=NULL;
2066 WCHAR szElement[MAX_PATH];
2067 CHAR szTempA[MAX_PATH];
2068 LPITEMIDLIST pidlTemp;
2070 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2071 This,hwndOwner,pbcReserved,lpszDisplayName,
2072 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2074 *ppidl = 0;
2075 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2077 if (PathIsRootW(lpszDisplayName))
2079 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2080 lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
2081 pidlTemp = _ILCreateDrive(szTempA);
2083 if (szNext && *szNext)
2085 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2087 else
2089 hr = S_OK;
2091 *ppidl = pidlTemp;
2094 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2096 return hr;
2099 /**************************************************************************
2100 * ISF_MyComputer_fnEnumObjects
2102 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2103 IShellFolder2 * iface,
2104 HWND hwndOwner,
2105 DWORD dwFlags,
2106 LPENUMIDLIST* ppEnumIDList)
2108 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2110 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2112 *ppEnumIDList = NULL;
2113 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2115 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2117 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2119 return S_OK;
2122 /**************************************************************************
2123 * ISF_MyComputer_fnBindToObject
2125 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2126 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2128 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2129 GUID const * clsid;
2130 IShellFolder *pShellFolder, *pSubFolder;
2131 LPITEMIDLIST pidltemp;
2133 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2134 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2136 if(!pidl || !ppvOut) return E_INVALIDARG;
2138 *ppvOut = NULL;
2140 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2142 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2144 return E_FAIL;
2147 else
2149 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2151 pidltemp = ILCloneFirst(pidl);
2152 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2153 ILFree(pidltemp);
2156 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2158 *ppvOut = pShellFolder;
2160 else /* go deeper */
2162 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
2163 IShellFolder_Release(pShellFolder);
2164 *ppvOut = pSubFolder;
2167 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
2169 return S_OK;
2172 /**************************************************************************
2173 * ISF_MyComputer_fnCreateViewObject
2175 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2176 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2178 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2180 LPSHELLVIEW pShellView;
2181 HRESULT hr = E_INVALIDARG;
2183 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2185 if(ppvOut)
2187 *ppvOut = NULL;
2189 if(IsEqualIID(riid, &IID_IDropTarget))
2191 FIXME("IDropTarget not implemented\n");
2192 hr = E_NOTIMPL;
2194 else if(IsEqualIID(riid, &IID_IContextMenu))
2196 FIXME("IContextMenu not implemented\n");
2197 hr = E_NOTIMPL;
2199 else if(IsEqualIID(riid, &IID_IShellView))
2201 pShellView = IShellView_Constructor((IShellFolder*)iface);
2202 if(pShellView)
2204 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2205 IShellView_Release(pShellView);
2209 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2210 return hr;
2213 /**************************************************************************
2214 * ISF_MyComputer_fnGetAttributesOf
2216 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
2218 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2220 GUID const * clsid;
2221 DWORD attributes;
2222 HRESULT hr = S_OK;
2224 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2226 if ( (!cidl) || (!apidl) || (!rgfInOut))
2227 return E_INVALIDARG;
2229 *rgfInOut = 0xffffffff;
2231 while (cidl > 0 && *apidl)
2233 pdump (*apidl);
2235 if (_ILIsDrive(*apidl))
2237 *rgfInOut &= 0xf0000144;
2238 goto next;
2240 else if ((clsid=_ILGetGUIDPointer(*apidl)))
2242 if (HCR_GetFolderAttributes(clsid, &attributes))
2244 *rgfInOut &= attributes;
2245 goto next;
2248 hr = E_INVALIDARG;
2250 next: apidl++;
2251 cidl--;
2254 TRACE("-- result=0x%08lx\n",*rgfInOut);
2255 return hr;
2258 /**************************************************************************
2259 * ISF_MyComputer_fnGetDisplayNameOf
2261 * NOTES
2262 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2263 * SHGDN_INFOLDER makes no sense.
2265 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2266 IShellFolder2 * iface,
2267 LPCITEMIDLIST pidl,
2268 DWORD dwFlags,
2269 LPSTRRET strRet)
2271 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2273 char szPath[MAX_PATH], szDrive[18];
2274 int len = 0;
2275 BOOL bSimplePidl;
2277 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2278 pdump(pidl);
2280 if(!strRet) return E_INVALIDARG;
2282 szPath[0]=0x00; szDrive[0]=0x00;
2285 bSimplePidl = _ILIsPidlSimple(pidl);
2287 if (_ILIsSpecialFolder(pidl))
2289 /* take names of special folders only if its only this folder */
2290 if ( bSimplePidl )
2292 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2295 else
2297 if (!_ILIsDrive(pidl))
2299 ERR("Wrong pidl type\n");
2300 return E_INVALIDARG;
2303 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2305 /* long view "lw_name (C:)" */
2306 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2308 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2310 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2311 strcat (szDrive," (");
2312 strncat (szDrive, szPath, 2);
2313 strcat (szDrive,")");
2314 strcpy (szPath, szDrive);
2318 if (!bSimplePidl) /* go deeper if needed */
2320 PathAddBackslashA(szPath);
2321 len = strlen(szPath);
2323 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2324 return E_OUTOFMEMORY;
2326 strRet->uType = STRRET_CSTRA;
2327 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2330 TRACE("-- (%p)->(%s)\n", This, szPath);
2331 return S_OK;
2334 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2335 IShellFolder2 * iface,
2336 GUID *pguid)
2338 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2339 FIXME("(%p)\n",This);
2340 return E_NOTIMPL;
2342 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2343 IShellFolder2 * iface,
2344 IEnumExtraSearch **ppenum)
2346 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2347 FIXME("(%p)\n",This);
2348 return E_NOTIMPL;
2350 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2351 IShellFolder2 * iface,
2352 DWORD dwRes,
2353 ULONG *pSort,
2354 ULONG *pDisplay)
2356 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2358 TRACE("(%p)\n",This);
2360 if (pSort) *pSort = 0;
2361 if (pDisplay) *pDisplay = 0;
2363 return S_OK;
2365 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2366 IShellFolder2 * iface,
2367 UINT iColumn,
2368 DWORD *pcsFlags)
2370 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2372 TRACE("(%p)\n",This);
2374 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2376 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2378 return S_OK;
2380 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2381 IShellFolder2 * iface,
2382 LPCITEMIDLIST pidl,
2383 const SHCOLUMNID *pscid,
2384 VARIANT *pv)
2386 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2387 FIXME("(%p)\n",This);
2389 return E_NOTIMPL;
2392 /* fixme: drive size >4GB is rolling over */
2393 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2394 IShellFolder2 * iface,
2395 LPCITEMIDLIST pidl,
2396 UINT iColumn,
2397 SHELLDETAILS *psd)
2399 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2400 HRESULT hr;
2402 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2404 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2406 if (!pidl)
2408 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2409 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2410 psd->str.uType = STRRET_CSTRA;
2411 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2412 return S_OK;
2414 else
2416 char szPath[MAX_PATH];
2417 ULARGE_INTEGER ulBytes;
2419 psd->str.u.cStr[0] = 0x00;
2420 psd->str.uType = STRRET_CSTRA;
2421 switch(iColumn)
2423 case 0: /* name */
2424 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2425 break;
2426 case 1: /* type */
2427 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2428 break;
2429 case 2: /* total size */
2430 if (_ILIsDrive(pidl))
2432 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2433 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2434 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2436 break;
2437 case 3: /* free size */
2438 if (_ILIsDrive(pidl))
2440 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2441 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2442 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2444 break;
2446 hr = S_OK;
2449 return hr;
2451 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2452 IShellFolder2 * iface,
2453 LPCWSTR pwszName,
2454 SHCOLUMNID *pscid)
2456 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2457 FIXME("(%p)\n",This);
2458 return E_NOTIMPL;
2461 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2463 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2464 IShellFolder_fnQueryInterface,
2465 IShellFolder_fnAddRef,
2466 IShellFolder_fnRelease,
2467 ISF_MyComputer_fnParseDisplayName,
2468 ISF_MyComputer_fnEnumObjects,
2469 ISF_MyComputer_fnBindToObject,
2470 IShellFolder_fnBindToStorage,
2471 IShellFolder_fnCompareIDs,
2472 ISF_MyComputer_fnCreateViewObject,
2473 ISF_MyComputer_fnGetAttributesOf,
2474 IShellFolder_fnGetUIObjectOf,
2475 ISF_MyComputer_fnGetDisplayNameOf,
2476 IShellFolder_fnSetNameOf,
2478 /* ShellFolder2 */
2479 ISF_MyComputer_fnGetDefaultSearchGUID,
2480 ISF_MyComputer_fnEnumSearches,
2481 ISF_MyComputer_fnGetDefaultColumn,
2482 ISF_MyComputer_fnGetDefaultColumnState,
2483 ISF_MyComputer_fnGetDetailsEx,
2484 ISF_MyComputer_fnGetDetailsOf,
2485 ISF_MyComputer_fnMapNameToSCID
2489 /************************************************************************
2490 * ISFPersistFolder_QueryInterface (IUnknown)
2493 static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2494 IPersistFolder2 * iface,
2495 REFIID iid,
2496 LPVOID* ppvObj)
2498 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2500 TRACE("(%p)\n", This);
2502 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2505 /************************************************************************
2506 * ISFPersistFolder_AddRef (IUnknown)
2509 static ULONG WINAPI ISFPersistFolder2_AddRef(
2510 IPersistFolder2 * iface)
2512 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2514 TRACE("(%p)\n", This);
2516 return IUnknown_AddRef(This->pUnkOuter);
2519 /************************************************************************
2520 * ISFPersistFolder_Release (IUnknown)
2523 static ULONG WINAPI ISFPersistFolder2_Release(
2524 IPersistFolder2 * iface)
2526 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2528 TRACE("(%p)\n", This);
2530 return IUnknown_Release(This->pUnkOuter);
2533 /************************************************************************
2534 * ISFPersistFolder_GetClassID (IPersist)
2536 static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2537 IPersistFolder2 * iface,
2538 CLSID * lpClassId)
2540 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2542 TRACE("(%p)\n", This);
2544 if (!lpClassId) return E_POINTER;
2545 *lpClassId = *This->pclsid;
2547 return S_OK;
2550 /************************************************************************
2551 * ISFPersistFolder_Initialize (IPersistFolder)
2553 * NOTES
2554 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2556 static HRESULT WINAPI ISFPersistFolder2_Initialize(
2557 IPersistFolder2 * iface,
2558 LPCITEMIDLIST pidl)
2560 char sTemp[MAX_PATH];
2561 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2563 TRACE("(%p)->(%p)\n", This, pidl);
2565 /* free the old stuff */
2566 if(This->absPidl)
2568 SHFree(This->absPidl);
2569 This->absPidl = NULL;
2571 if(This->sMyPath)
2573 SHFree(This->sMyPath);
2574 This->sMyPath = NULL;
2577 /* set my pidl */
2578 This->absPidl = ILClone(pidl);
2580 /* set my path */
2581 if (SHGetPathFromIDListA(pidl, sTemp))
2583 This->sMyPath = SHAlloc(strlen(sTemp+1));
2584 strcpy(This->sMyPath, sTemp);
2587 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2589 return S_OK;
2592 /**************************************************************************
2593 * IPersistFolder2_fnGetCurFolder
2595 static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2596 IPersistFolder2 * iface,
2597 LPITEMIDLIST * pidl)
2599 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2601 TRACE("(%p)->(%p)\n",This, pidl);
2603 if (!pidl) return E_POINTER;
2605 *pidl = ILClone(This->absPidl);
2607 return S_OK;
2610 static ICOM_VTABLE(IPersistFolder2) psfvt =
2612 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2613 ISFPersistFolder2_QueryInterface,
2614 ISFPersistFolder2_AddRef,
2615 ISFPersistFolder2_Release,
2616 ISFPersistFolder2_GetClassID,
2617 ISFPersistFolder2_Initialize,
2618 ISFPersistFolder2_fnGetCurFolder
2621 /****************************************************************************
2622 * ISFDropTarget implementation
2624 static BOOL ISFDropTarget_QueryDrop(
2625 IDropTarget *iface,
2626 DWORD dwKeyState,
2627 LPDWORD pdwEffect)
2629 DWORD dwEffect = *pdwEffect;
2631 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2633 *pdwEffect = DROPEFFECT_NONE;
2635 if (This->fAcceptFmt)
2636 { /* Does our interpretation of the keystate ... */
2637 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2639 /* ... matches the desired effect ? */
2640 if (dwEffect & *pdwEffect)
2642 return TRUE;
2645 return FALSE;
2648 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2649 IDropTarget *iface,
2650 REFIID riid,
2651 LPVOID *ppvObj)
2653 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2655 TRACE("(%p)\n", This);
2657 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2660 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2662 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2664 TRACE("(%p)\n", This);
2666 return IUnknown_AddRef(This->pUnkOuter);
2669 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2671 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2673 TRACE("(%p)\n", This);
2675 return IUnknown_Release(This->pUnkOuter);
2678 static HRESULT WINAPI ISFDropTarget_DragEnter(
2679 IDropTarget *iface,
2680 IDataObject *pDataObject,
2681 DWORD dwKeyState,
2682 POINTL pt,
2683 DWORD *pdwEffect)
2685 FORMATETC fmt;
2687 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2689 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2691 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2693 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2695 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2697 return S_OK;
2700 static HRESULT WINAPI ISFDropTarget_DragOver(
2701 IDropTarget *iface,
2702 DWORD dwKeyState,
2703 POINTL pt,
2704 DWORD *pdwEffect)
2706 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2708 TRACE("(%p)\n",This);
2710 if(!pdwEffect) return E_INVALIDARG;
2712 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2714 return S_OK;
2717 static HRESULT WINAPI ISFDropTarget_DragLeave(
2718 IDropTarget *iface)
2720 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2722 TRACE("(%p)\n",This);
2724 This->fAcceptFmt = FALSE;
2726 return S_OK;
2729 static HRESULT WINAPI ISFDropTarget_Drop(
2730 IDropTarget *iface,
2731 IDataObject* pDataObject,
2732 DWORD dwKeyState,
2733 POINTL pt,
2734 DWORD *pdwEffect)
2736 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2738 FIXME("(%p) object dropped\n",This);
2740 return E_NOTIMPL;
2743 static struct ICOM_VTABLE(IDropTarget) dtvt =
2745 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2746 ISFDropTarget_QueryInterface,
2747 ISFDropTarget_AddRef,
2748 ISFDropTarget_Release,
2749 ISFDropTarget_DragEnter,
2750 ISFDropTarget_DragOver,
2751 ISFDropTarget_DragLeave,
2752 ISFDropTarget_Drop