Moved GET_IP out of winnt.h.
[wine/multimedia.git] / dlls / shell32 / shlfolder.c
blob155aa7b2db5f6d3c9dbd8af4d79b4c02f203d6d5
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"
17 #include "winbase.h"
19 #include "oleidl.h"
20 #include "shlguid.h"
22 #include "pidl.h"
23 #include "wine/winestring.h"
24 #include "wine/obj_base.h"
25 #include "wine/obj_dragdrop.h"
26 #include "wine/obj_shellfolder.h"
27 #include "wine/undocshell.h"
28 #include "shell32_main.h"
29 #include "shresdef.h"
30 #include "shlwapi.h"
32 #define INITGUID
33 #include "initguid.h"
34 #include "shellfolder.h"
35 #include "wine/obj_queryassociations.h"
37 DEFAULT_DEBUG_CHANNEL(shell)
40 /***************************************************************************
41 * debughelper: print out the return adress
42 * helps especially to track down unbalanced AddRef/Release
44 #define MEM_DEBUG 0
46 #if MEM_DEBUG
47 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
48 #else
49 #define _CALL_TRACE
50 #endif
52 typedef struct
54 int colnameid;
55 int pcsFlags;
56 int fmt;
57 int cxChar;
59 } shvheader;
61 /***************************************************************************
62 * GetNextElement (internal function)
64 * gets a part of a string till the first backslash
66 * PARAMETERS
67 * pszNext [IN] string to get the element from
68 * pszOut [IN] pointer to buffer whitch receives string
69 * dwOut [IN] length of pszOut
71 * RETURNS
72 * LPSTR pointer to first, not yet parsed char
75 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
76 { LPCWSTR pszTail = pszNext;
77 DWORD dwCopy;
78 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
80 *pszOut=0x0000;
82 if(!pszNext || !*pszNext)
83 return NULL;
85 while(*pszTail && (*pszTail != (WCHAR)'\\'))
86 pszTail++;
88 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
89 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
91 if(*pszTail)
92 pszTail++;
93 else
94 pszTail = NULL;
96 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
97 return pszTail;
100 static HRESULT SHELL32_ParseNextElement(
101 HWND hwndOwner,
102 IShellFolder2 * psf,
103 LPITEMIDLIST * pidlInOut,
104 LPOLESTR szNext,
105 DWORD *pEaten,
106 DWORD *pdwAttributes)
108 HRESULT hr = E_OUTOFMEMORY;
109 LPITEMIDLIST pidlOut, pidlTemp = NULL;
110 IShellFolder *psfChild;
112 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
115 /* get the shellfolder for the child pidl and let it analyse further */
116 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
118 if (psfChild)
120 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
121 IShellFolder_Release(psfChild);
123 pidlTemp = ILCombine(*pidlInOut, pidlOut);
125 if (pidlOut)
126 ILFree(pidlOut);
129 ILFree(*pidlInOut);
130 *pidlInOut = pidlTemp;
132 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
133 return hr;
136 /***********************************************************************
137 * SHELL32_CoCreateInitSF
139 * creates a initialized shell folder
141 static HRESULT SHELL32_CoCreateInitSF (
142 LPITEMIDLIST pidlRoot,
143 LPITEMIDLIST pidlChild,
144 REFCLSID clsid,
145 REFIID iid,
146 LPVOID * ppvOut)
148 HRESULT hr;
149 LPITEMIDLIST absPidl;
150 IShellFolder2 *pShellFolder;
151 IPersistFolder *pPersistFolder;
153 TRACE("%p %p\n", pidlRoot, pidlChild);
155 *ppvOut = NULL;
157 /* we have to ask first for IPersistFolder, some special folders are expecting this */
158 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
159 if (SUCCEEDED(hr))
161 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
162 if (SUCCEEDED(hr))
164 absPidl = ILCombine (pidlRoot, pidlChild);
165 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
166 IPersistFolder_Release(pPersistFolder);
167 SHFree(absPidl);
168 *ppvOut = pShellFolder;
172 TRACE("-- ret=0x%08lx\n", hr);
173 return hr;
176 static HRESULT SHELL32_GetDisplayNameOfChild(
177 IShellFolder2 * psf,
178 LPCITEMIDLIST pidl,
179 DWORD dwFlags,
180 LPSTR szOut,
181 DWORD dwOutLen)
183 LPITEMIDLIST pidlFirst, pidlNext;
184 IShellFolder2 * psfChild;
185 HRESULT hr = E_OUTOFMEMORY;
186 STRRET strTemp;
188 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
189 pdump(pidl);
191 if ((pidlFirst = ILCloneFirst(pidl)))
193 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
194 if (SUCCEEDED(hr))
196 pidlNext = ILGetNext(pidl);
198 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
199 if (SUCCEEDED(hr))
201 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
204 IShellFolder_Release(psfChild);
206 ILFree(pidlFirst);
209 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
211 return hr;
214 /***********************************************************************
215 * SHELL32_GetItemAttributes
217 * NOTES
218 * observerd values:
219 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
220 * file: 0x40000177 FILESYSTEM
221 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
222 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
223 * (seems to be default for shell extensions if no registry entry exists)
225 * This functions does not set flags!! It only resets flags when nessesary.
227 static HRESULT SHELL32_GetItemAttributes(
228 IShellFolder * psf,
229 LPITEMIDLIST pidl,
230 LPDWORD pdwAttributes)
232 GUID const * clsid;
233 DWORD dwAttributes;
235 TRACE("0x%08lx\n", *pdwAttributes);
237 if (*pdwAttributes & (0xcff3fe88))
238 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
239 *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
241 if (_ILIsDrive(pidl))
243 *pdwAttributes &= 0xf0000144;
245 else if ((clsid=_ILGetGUIDPointer(pidl)))
247 if (HCR_GetFolderAttributes(clsid, &dwAttributes))
249 *pdwAttributes &= dwAttributes;
251 else
253 *pdwAttributes &= 0xb0000154;
256 else if (_ILGetDataPointer(pidl))
258 dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
259 *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
261 if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
262 *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
264 if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
265 *pdwAttributes &= ~SFGAO_HIDDEN;
267 if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
268 *pdwAttributes &= ~SFGAO_READONLY;
270 else
272 *pdwAttributes &= 0xb0000154;
274 TRACE("-- 0x%08lx\n", *pdwAttributes);
275 return S_OK;
278 /***********************************************************************
279 * IShellFolder implementation
282 typedef struct
284 ICOM_VFIELD(IUnknown);
285 DWORD ref;
286 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
287 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
288 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
289 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
291 IUnknown *pUnkOuter; /* used for aggregation */
293 CLSID* pclsid;
295 LPSTR sMyPath;
296 LPITEMIDLIST absPidl; /* complete pidl */
298 UINT cfShellIDList; /* clipboardformat for IDropTarget */
299 BOOL fAcceptFmt; /* flag for pending Drop */
300 } IGenericSFImpl;
302 static struct ICOM_VTABLE(IUnknown) unkvt;
303 static struct ICOM_VTABLE(IShellFolder2) sfvt;
304 static struct ICOM_VTABLE(IPersistFolder2) psfvt;
305 static struct ICOM_VTABLE(IDropTarget) dtvt;
306 static struct ICOM_VTABLE(ISFHelper) shvt;
308 static IShellFolder * ISF_MyComputer_Constructor(void);
310 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
311 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
313 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
314 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
316 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
317 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
319 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
320 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
322 converts This to a interface pointer
324 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
325 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
326 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
327 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
328 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
329 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
330 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
331 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
332 /**************************************************************************
333 * registers clipboardformat once
335 static void SF_RegisterClipFmt (IGenericSFImpl * This)
337 TRACE("(%p)\n", This);
339 if (!This->cfShellIDList)
341 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
345 /**************************************************************************
346 * we need a seperate IUnknown to handle aggregation
347 * (inner IUnknown)
349 static HRESULT WINAPI IUnknown_fnQueryInterface(
350 IUnknown * iface,
351 REFIID riid,
352 LPVOID *ppvObj)
354 ICOM_THIS(IGenericSFImpl, iface);
356 _CALL_TRACE
357 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
359 *ppvObj = NULL;
361 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
362 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
363 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
364 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
365 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
366 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
367 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
368 else if(IsEqualIID(riid, &IID_IDropTarget))
370 *ppvObj = _IDropTarget_(This);
371 SF_RegisterClipFmt(This);
374 if(*ppvObj)
376 IUnknown_AddRef((IUnknown*)(*ppvObj));
377 TRACE("-- Interface = %p\n", *ppvObj);
378 return S_OK;
380 TRACE("-- Interface: E_NOINTERFACE\n");
381 return E_NOINTERFACE;
384 static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
386 ICOM_THIS(IGenericSFImpl, iface);
388 _CALL_TRACE
389 TRACE("(%p)->(count=%lu)\n",This,This->ref);
391 shell32_ObjCount++;
392 return ++(This->ref);
395 static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
397 ICOM_THIS(IGenericSFImpl, iface);
399 _CALL_TRACE
400 TRACE("(%p)->(count=%lu)\n",This,This->ref);
402 shell32_ObjCount--;
403 if (!--(This->ref))
405 TRACE("-- destroying IShellFolder(%p)\n",This);
407 if (pdesktopfolder == _IShellFolder_(This))
409 pdesktopfolder=NULL;
410 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
412 if(This->absPidl) SHFree(This->absPidl);
413 if(This->sMyPath) SHFree(This->sMyPath);
414 HeapFree(GetProcessHeap(),0,This);
415 return 0;
417 return This->ref;
420 static ICOM_VTABLE(IUnknown) unkvt =
422 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
423 IUnknown_fnQueryInterface,
424 IUnknown_fnAddRef,
425 IUnknown_fnRelease,
428 static shvheader GenericSFHeader [] =
430 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
431 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
432 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
433 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
434 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
436 #define GENERICSHELLVIEWCOLUMNS 5
438 /**************************************************************************
439 * IShellFolder_Constructor
441 * NOTES
442 * creating undocumented ShellFS_Folder as part of an aggregation
443 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
445 * FIXME
446 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
448 HRESULT IFSFolder_Constructor(
449 IUnknown * pUnkOuter,
450 REFIID riid,
451 LPVOID * ppv)
453 IGenericSFImpl * sf;
454 HRESULT hr = S_OK;
456 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
458 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
460 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
462 else
464 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
465 if (sf)
467 sf->ref=1;
468 ICOM_VTBL(sf)=&unkvt;
469 sf->lpvtblShellFolder=&sfvt;
470 sf->lpvtblPersistFolder2=&psfvt;
471 sf->lpvtblDropTarget=&dtvt;
472 sf->lpvtblSFHelper=&shvt;
474 sf->pclsid = (CLSID*)&CLSID_SFFile;
475 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
476 *ppv = _IUnknown_(sf);
477 hr = S_OK;
478 shell32_ObjCount++;
480 else
482 hr = E_OUTOFMEMORY;
485 return hr;
487 /**************************************************************************
488 * IShellFolder_Constructor
490 * NOTES
491 * THIS points to the parent folder
494 IShellFolder * IShellFolder_Constructor(
495 IShellFolder2 * iface,
496 LPITEMIDLIST pidl)
498 IGenericSFImpl * sf;
499 DWORD dwSize=0;
501 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
503 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
504 sf->ref=1;
506 ICOM_VTBL(sf)=&unkvt;
507 sf->lpvtblShellFolder=&sfvt;
508 sf->lpvtblPersistFolder2=&psfvt;
509 sf->lpvtblDropTarget=&dtvt;
510 sf->lpvtblSFHelper=&shvt;
512 sf->pclsid = (CLSID*)&CLSID_SFFile;
513 sf->pUnkOuter = _IUnknown_(sf);
515 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
516 pdump(pidl);
518 if(pidl && iface) /* do we have a pidl? */
520 int len;
522 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
524 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
526 if(This->sMyPath) /* get the size of the parents path */
528 dwSize += strlen(This->sMyPath) ;
529 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
532 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
533 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
535 if(!sf->sMyPath) return NULL;
536 *(sf->sMyPath)=0x00;
538 if(This->sMyPath) /* if the parent has a path, get it*/
540 strcpy(sf->sMyPath, This->sMyPath);
541 PathAddBackslashA (sf->sMyPath);
544 len = strlen(sf->sMyPath);
545 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
548 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
550 pdump (sf->absPidl);
553 shell32_ObjCount++;
554 return _IShellFolder_(sf);
557 /**************************************************************************
558 * IShellFolder_fnQueryInterface
560 * PARAMETERS
561 * REFIID riid [in ] Requested InterfaceID
562 * LPVOID* ppvObject [out] Interface* to hold the result
564 static HRESULT WINAPI IShellFolder_fnQueryInterface(
565 IShellFolder2 * iface,
566 REFIID riid,
567 LPVOID *ppvObj)
569 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
571 _CALL_TRACE
572 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
574 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
577 /**************************************************************************
578 * IShellFolder_AddRef
581 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
583 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
585 _CALL_TRACE
586 TRACE("(%p)->(count=%lu)\n",This,This->ref);
588 return IUnknown_AddRef(This->pUnkOuter);
591 /**************************************************************************
592 * IShellFolder_fnRelease
594 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
596 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
598 _CALL_TRACE
599 TRACE("(%p)->(count=%lu)\n",This,This->ref);
601 return IUnknown_Release(This->pUnkOuter);
604 /**************************************************************************
605 * IShellFolder_fnParseDisplayName
606 * PARAMETERS
607 * HWND hwndOwner, //[in ] Parent window for any message's
608 * LPBC pbc, //[in ] reserved
609 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
610 * ULONG* pchEaten, //[out] (unicode) characters processed
611 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
612 * ULONG* pdwAttributes //[out] items attributes
614 * NOTES
615 * every folder tries to parse only its own (the leftmost) pidl and creates a
616 * subfolder to evaluate the remaining parts
617 * now we can parse into namespaces implemented by shell extensions
619 * behaviour on win98: lpszDisplayName=NULL -> chrash
620 * lpszDisplayName="" -> returns mycoputer-pidl
622 * FIXME:
623 * pdwAttributes: not set
624 * pchEaten: not set like in windows
626 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
627 IShellFolder2 * iface,
628 HWND hwndOwner,
629 LPBC pbcReserved,
630 LPOLESTR lpszDisplayName,
631 DWORD *pchEaten,
632 LPITEMIDLIST *ppidl,
633 DWORD *pdwAttributes)
635 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
637 HRESULT hr = E_OUTOFMEMORY;
638 LPCWSTR szNext=NULL;
639 WCHAR szElement[MAX_PATH];
640 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
641 LPITEMIDLIST pidlTemp=NULL;
643 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
644 This,hwndOwner,pbcReserved,lpszDisplayName,
645 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
647 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
649 if (pchEaten) *pchEaten = 0; /* strange but like the original */
651 if (*lpszDisplayName)
653 /* get the next element */
654 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
656 /* build the full pathname to the element */
657 lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
658 strcpy(szPath, This->sMyPath);
659 PathAddBackslashA(szPath);
660 strcat(szPath, szTempA);
662 /* get the pidl */
663 pidlTemp = SHSimpleIDListFromPathA(szPath);
665 if (pidlTemp)
667 /* try to analyse the next element */
668 if (szNext && *szNext)
670 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
672 else
674 if (pdwAttributes && *pdwAttributes)
676 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
677 /* WIN32_FIND_DATAA fd;
678 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
679 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
680 *pdwAttributes &= ~SFGAO_FOLDER;
681 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
682 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
685 hr = S_OK;
690 *ppidl = pidlTemp;
692 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
694 return hr;
697 /**************************************************************************
698 * IShellFolder_fnEnumObjects
699 * PARAMETERS
700 * HWND hwndOwner, //[in ] Parent Window
701 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
702 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
704 static HRESULT WINAPI IShellFolder_fnEnumObjects(
705 IShellFolder2 * iface,
706 HWND hwndOwner,
707 DWORD dwFlags,
708 LPENUMIDLIST* ppEnumIDList)
710 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
712 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
714 *ppEnumIDList = NULL;
715 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
717 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
719 if(!*ppEnumIDList) return E_OUTOFMEMORY;
721 return S_OK;
724 /**************************************************************************
725 * IShellFolder_fnBindToObject
726 * PARAMETERS
727 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
728 * LPBC pbc, //[in ] reserved
729 * REFIID riid, //[in ] Initial Interface
730 * LPVOID* ppvObject //[out] Interface*
732 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
733 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
735 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
736 GUID const * iid;
737 IShellFolder *pShellFolder, *pSubFolder;
738 IPersistFolder *pPersistFolder;
739 LPITEMIDLIST absPidl;
741 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
743 if(!pidl || !ppvOut) return E_INVALIDARG;
745 *ppvOut = NULL;
747 if ((iid=_ILGetGUIDPointer(pidl)))
749 /* we have to create a alien folder */
750 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
751 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
753 absPidl = ILCombine (This->absPidl, pidl);
754 IPersistFolder_Initialize(pPersistFolder, absPidl);
755 IPersistFolder_Release(pPersistFolder);
756 SHFree(absPidl);
758 else
760 return E_FAIL;
763 else if(_ILIsFolder(pidl))
765 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
766 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
767 ILFree(pidltemp);
769 else
771 ERR("can't bind to a file\n");
772 return E_FAIL;
775 if (_ILIsPidlSimple(pidl))
777 *ppvOut = pShellFolder;
779 else
781 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
782 IShellFolder_Release(pShellFolder);
783 *ppvOut = pSubFolder;
786 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
788 return S_OK;
791 /**************************************************************************
792 * IShellFolder_fnBindToStorage
793 * PARAMETERS
794 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
795 * LPBC pbc, //[in ] reserved
796 * REFIID riid, //[in ] Initial storage interface
797 * LPVOID* ppvObject //[out] Interface* returned
799 static HRESULT WINAPI IShellFolder_fnBindToStorage(
800 IShellFolder2 * iface,
801 LPCITEMIDLIST pidl,
802 LPBC pbcReserved,
803 REFIID riid,
804 LPVOID *ppvOut)
806 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
808 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
809 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
811 *ppvOut = NULL;
812 return E_NOTIMPL;
815 /**************************************************************************
816 * IShellFolder_fnCompareIDs
818 * PARMETERS
819 * LPARAM lParam, //[in ] Column?
820 * LPCITEMIDLIST pidl1, //[in ] simple pidl
821 * LPCITEMIDLIST pidl2) //[in ] simple pidl
823 * NOTES
824 * Special case - If one of the items is a Path and the other is a File,
825 * always make the Path come before the File.
827 * NOTES
828 * use SCODE_CODE() on the return value to get the result
831 static HRESULT WINAPI IShellFolder_fnCompareIDs(
832 IShellFolder2 * iface,
833 LPARAM lParam,
834 LPCITEMIDLIST pidl1,
835 LPCITEMIDLIST pidl2)
837 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
839 CHAR szTemp1[MAX_PATH];
840 CHAR szTemp2[MAX_PATH];
841 int nReturn;
842 IShellFolder * psf;
843 HRESULT hr = E_OUTOFMEMORY;
844 LPCITEMIDLIST pidlTemp;
845 PIDLTYPE pt1, pt2;
847 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
848 pdump (pidl1);
849 pdump (pidl2);
851 if (!pidl1 && !pidl2)
853 hr = ResultFromShort(0);
855 else if (!pidl1)
857 hr = ResultFromShort(-1);
859 else if (!pidl2)
861 hr = ResultFromShort(1);
863 else
865 LPPIDLDATA pd1, pd2;
866 pd1 = _ILGetDataPointer(pidl1);
867 pd2 = _ILGetDataPointer(pidl2);
869 /* compate the types. sort order is the PT_* constant */
870 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
871 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
873 if (pt1 != pt2)
875 hr = ResultFromShort(pt1-pt2);
877 else /* same type of pidl */
879 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
880 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
881 nReturn = strcasecmp(szTemp1, szTemp2);
883 if (nReturn == 0) /* first pidl different ? */
885 pidl1 = ILGetNext(pidl1);
887 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
889 pidlTemp = ILCloneFirst(pidl1);
890 pidl2 = ILGetNext(pidl2);
892 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
893 if (SUCCEEDED(hr))
895 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
896 IShellFolder_Release(psf);
897 hr = ResultFromShort(nReturn);
899 ILFree(pidlTemp);
901 else
903 hr = ResultFromShort(nReturn); /* two equal simple pidls */
906 else
908 hr = ResultFromShort(nReturn); /* two different simple pidls */
913 TRACE("-- res=0x%08lx\n", hr);
914 return hr;
917 /**************************************************************************
918 * IShellFolder_fnCreateViewObject
920 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
921 IShellFolder2 * iface,
922 HWND hwndOwner,
923 REFIID riid,
924 LPVOID *ppvOut)
926 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
928 LPSHELLVIEW pShellView;
929 HRESULT hr = E_INVALIDARG;
931 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
933 if(ppvOut)
935 *ppvOut = NULL;
937 if(IsEqualIID(riid, &IID_IDropTarget))
939 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
941 else if(IsEqualIID(riid, &IID_IContextMenu))
943 FIXME("IContextMenu not implemented\n");
944 hr = E_NOTIMPL;
946 else if(IsEqualIID(riid, &IID_IShellView))
948 pShellView = IShellView_Constructor((IShellFolder*)iface);
949 if(pShellView)
951 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
952 IShellView_Release(pShellView);
956 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
957 return hr;
960 /**************************************************************************
961 * IShellFolder_fnGetAttributesOf
963 * PARAMETERS
964 * UINT cidl, //[in ] num elements in pidl array
965 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
966 * ULONG* rgfInOut) //[out] result array
969 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
970 IShellFolder2 * iface,
971 UINT cidl,
972 LPCITEMIDLIST *apidl,
973 DWORD *rgfInOut)
975 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
977 HRESULT hr = S_OK;
979 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
981 if ( (!cidl) || (!apidl) || (!rgfInOut))
982 return E_INVALIDARG;
984 while (cidl > 0 && *apidl)
986 pdump (*apidl);
987 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
988 apidl++;
989 cidl--;
992 TRACE("-- result=0x%08lx\n",*rgfInOut);
994 return hr;
996 /**************************************************************************
997 * IShellFolder_fnGetUIObjectOf
999 * PARAMETERS
1000 * HWND hwndOwner, //[in ] Parent window for any output
1001 * UINT cidl, //[in ] array size
1002 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1003 * REFIID riid, //[in ] Requested Interface
1004 * UINT* prgfInOut, //[ ] reserved
1005 * LPVOID* ppvObject) //[out] Resulting Interface
1007 * NOTES
1008 * This function gets asked to return "view objects" for one or more (multiple select)
1009 * items:
1010 * The viewobject typically is an COM object with one of the following interfaces:
1011 * IExtractIcon,IDataObject,IContextMenu
1012 * In order to support icon positions in the default Listview your DataObject
1013 * must implement the SetData method (in addition to GetData :) - the shell passes
1014 * a barely documented "Icon positions" structure to SetData when the drag starts,
1015 * and GetData's it if the drop is in another explorer window that needs the positions.
1017 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1018 IShellFolder2 * iface,
1019 HWND hwndOwner,
1020 UINT cidl,
1021 LPCITEMIDLIST * apidl,
1022 REFIID riid,
1023 UINT * prgfInOut,
1024 LPVOID * ppvOut)
1026 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1028 LPITEMIDLIST pidl;
1029 IUnknown* pObj = NULL;
1030 HRESULT hr = E_INVALIDARG;
1032 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1033 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1035 if (ppvOut)
1037 *ppvOut = NULL;
1039 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1041 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1042 hr = S_OK;
1044 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1046 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1047 hr = S_OK;
1049 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1051 pidl = ILCombine(This->absPidl,apidl[0]);
1052 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1053 SHFree(pidl);
1054 hr = S_OK;
1056 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1058 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1060 else
1062 hr = E_NOINTERFACE;
1065 if(!pObj)
1066 hr = E_OUTOFMEMORY;
1068 *ppvOut = pObj;
1070 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1071 return hr;
1074 /**************************************************************************
1075 * IShellFolder_fnGetDisplayNameOf
1076 * Retrieves the display name for the specified file object or subfolder
1078 * PARAMETERS
1079 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1080 * DWORD dwFlags, //[in ] SHGNO formatting flags
1081 * LPSTRRET lpName) //[out] Returned display name
1083 * FIXME
1084 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1086 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1087 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1089 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1090 IShellFolder2 * iface,
1091 LPCITEMIDLIST pidl,
1092 DWORD dwFlags,
1093 LPSTRRET strRet)
1095 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1097 CHAR szPath[MAX_PATH]= "";
1098 int len = 0;
1099 BOOL bSimplePidl;
1101 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1102 pdump(pidl);
1104 if(!pidl || !strRet) return E_INVALIDARG;
1106 bSimplePidl = _ILIsPidlSimple(pidl);
1108 /* take names of special folders only if its only this folder */
1109 if (_ILIsSpecialFolder(pidl))
1111 if ( bSimplePidl)
1113 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1116 else
1118 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1120 strcpy (szPath, This->sMyPath); /* get path to root*/
1121 PathAddBackslashA(szPath);
1122 len = strlen(szPath);
1124 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1127 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1129 PathAddBackslashA(szPath);
1130 len = strlen(szPath);
1132 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1133 return E_OUTOFMEMORY;
1135 strRet->uType = STRRET_CSTRA;
1136 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1138 TRACE("-- (%p)->(%s)\n", This, szPath);
1139 return S_OK;
1142 /**************************************************************************
1143 * IShellFolder_fnSetNameOf
1144 * Changes the name of a file object or subfolder, possibly changing its item
1145 * identifier in the process.
1147 * PARAMETERS
1148 * HWND hwndOwner, //[in ] Owner window for output
1149 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1150 * LPCOLESTR lpszName, //[in ] the items new display name
1151 * DWORD dwFlags, //[in ] SHGNO formatting flags
1152 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1154 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1155 IShellFolder2 * iface,
1156 HWND hwndOwner,
1157 LPCITEMIDLIST pidl, /*simple pidl*/
1158 LPCOLESTR lpName,
1159 DWORD dwFlags,
1160 LPITEMIDLIST *pPidlOut)
1162 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1163 char szSrc[MAX_PATH], szDest[MAX_PATH];
1164 int len;
1165 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1167 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1168 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1170 /* build source path */
1171 if (dwFlags & SHGDN_INFOLDER)
1173 strcpy(szSrc, This->sMyPath);
1174 PathAddBackslashA(szSrc);
1175 len = strlen (szSrc);
1176 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1178 else
1180 SHGetPathFromIDListA(pidl, szSrc);
1183 /* build destination path */
1184 strcpy(szDest, This->sMyPath);
1185 PathAddBackslashA(szDest);
1186 len = strlen (szDest);
1187 lstrcpynWtoA(szDest+len, lpName, MAX_PATH-len);
1189 TRACE("src=%s dest=%s\n", szSrc, szDest);
1190 if ( MoveFileA(szSrc, szDest) )
1192 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1193 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1194 return S_OK;
1196 return E_FAIL;
1199 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1200 IShellFolder2 * iface,
1201 GUID *pguid)
1203 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1204 FIXME("(%p)\n",This);
1205 return E_NOTIMPL;
1207 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1208 IShellFolder2 * iface,
1209 IEnumExtraSearch **ppenum)
1211 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1212 FIXME("(%p)\n",This);
1213 return E_NOTIMPL;
1215 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1216 IShellFolder2 * iface,
1217 DWORD dwRes,
1218 ULONG *pSort,
1219 ULONG *pDisplay)
1221 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1223 TRACE("(%p)\n",This);
1225 if (pSort) *pSort = 0;
1226 if (pDisplay) *pDisplay = 0;
1228 return S_OK;
1230 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1231 IShellFolder2 * iface,
1232 UINT iColumn,
1233 DWORD *pcsFlags)
1235 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1237 TRACE("(%p)\n",This);
1239 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1241 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1243 return S_OK;
1245 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1246 IShellFolder2 * iface,
1247 LPCITEMIDLIST pidl,
1248 const SHCOLUMNID *pscid,
1249 VARIANT *pv)
1251 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1252 FIXME("(%p)\n",This);
1254 return E_NOTIMPL;
1256 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1257 IShellFolder2 * iface,
1258 LPCITEMIDLIST pidl,
1259 UINT iColumn,
1260 SHELLDETAILS *psd)
1262 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1263 HRESULT hr = E_FAIL;
1265 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1267 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1269 if (!pidl)
1271 /* the header titles */
1272 psd->fmt = GenericSFHeader[iColumn].fmt;
1273 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1274 psd->str.uType = STRRET_CSTRA;
1275 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1276 return S_OK;
1278 else
1280 /* the data from the pidl */
1281 switch(iColumn)
1283 case 0: /* name */
1284 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1285 break;
1286 case 1: /* size */
1287 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1288 break;
1289 case 2: /* type */
1290 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1291 break;
1292 case 3: /* date */
1293 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1294 break;
1295 case 4: /* attributes */
1296 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1297 break;
1299 hr = S_OK;
1300 psd->str.uType = STRRET_CSTRA;
1303 return hr;
1305 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1306 IShellFolder2 * iface,
1307 LPCWSTR pwszName,
1308 SHCOLUMNID *pscid)
1310 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1311 FIXME("(%p)\n",This);
1312 return E_NOTIMPL;
1315 static ICOM_VTABLE(IShellFolder2) sfvt =
1317 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1318 IShellFolder_fnQueryInterface,
1319 IShellFolder_fnAddRef,
1320 IShellFolder_fnRelease,
1321 IShellFolder_fnParseDisplayName,
1322 IShellFolder_fnEnumObjects,
1323 IShellFolder_fnBindToObject,
1324 IShellFolder_fnBindToStorage,
1325 IShellFolder_fnCompareIDs,
1326 IShellFolder_fnCreateViewObject,
1327 IShellFolder_fnGetAttributesOf,
1328 IShellFolder_fnGetUIObjectOf,
1329 IShellFolder_fnGetDisplayNameOf,
1330 IShellFolder_fnSetNameOf,
1332 /* ShellFolder2 */
1333 IShellFolder_fnGetDefaultSearchGUID,
1334 IShellFolder_fnEnumSearches,
1335 IShellFolder_fnGetDefaultColumn,
1336 IShellFolder_fnGetDefaultColumnState,
1337 IShellFolder_fnGetDetailsEx,
1338 IShellFolder_fnGetDetailsOf,
1339 IShellFolder_fnMapNameToSCID
1342 /****************************************************************************
1343 * ISFHelper for IShellFolder implementation
1346 static HRESULT WINAPI ISFHelper_fnQueryInterface(
1347 ISFHelper *iface,
1348 REFIID riid,
1349 LPVOID *ppvObj)
1351 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1353 TRACE("(%p)\n", This);
1355 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1358 static ULONG WINAPI ISFHelper_fnAddRef(
1359 ISFHelper *iface)
1361 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1363 TRACE("(%p)\n", This);
1365 return IUnknown_AddRef(This->pUnkOuter);
1368 static ULONG WINAPI ISFHelper_fnRelease(
1369 ISFHelper *iface)
1371 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1373 TRACE("(%p)\n", This);
1375 return IUnknown_Release(This->pUnkOuter);
1379 /****************************************************************************
1380 * ISFHelper_fnAddFolder
1382 * creates a unique folder name
1385 static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1386 ISFHelper *iface,
1387 LPSTR lpName,
1388 UINT uLen)
1390 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1391 IEnumIDList * penum;
1392 HRESULT hr;
1393 char szText[MAX_PATH];
1394 char * szNewFolder = "New Folder";
1396 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1398 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1400 strcpy(lpName, szNewFolder);
1402 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1403 if (penum)
1405 LPITEMIDLIST pidl;
1406 DWORD dwFetched;
1407 int i=1;
1409 next: IEnumIDList_Reset(penum);
1410 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1412 _ILSimpleGetText(pidl, szText, MAX_PATH);
1413 if (0 == strcasecmp(szText, lpName))
1415 sprintf(lpName, "%s %d", szNewFolder, i++);
1416 if (i > 99)
1418 hr = E_FAIL;
1419 break;
1421 goto next;
1425 IEnumIDList_Release(penum);
1427 return hr;
1430 /****************************************************************************
1431 * ISFHelper_fnAddFolder
1433 * adds a new folder.
1436 static HRESULT WINAPI ISFHelper_fnAddFolder(
1437 ISFHelper *iface,
1438 HWND hwnd,
1439 LPCSTR lpName,
1440 LPITEMIDLIST* ppidlOut)
1442 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1443 char lpstrNewDir[MAX_PATH];
1444 DWORD bRes;
1445 HRESULT hres = E_FAIL;
1447 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1449 strcpy(lpstrNewDir, This->sMyPath);
1450 PathAddBackslashA(lpstrNewDir);
1451 strcat(lpstrNewDir, lpName);
1453 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1455 if (bRes)
1457 LPITEMIDLIST pidl, pidlitem;
1459 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1461 pidl = ILCombine(This->absPidl, pidlitem);
1462 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1463 SHFree(pidl);
1465 if (ppidlOut) *ppidlOut = pidlitem;
1466 hres = S_OK;
1468 else
1470 char lpstrText[128+MAX_PATH];
1471 char lpstrTempText[128];
1472 char lpstrCaption[256];
1474 /* Cannot Create folder because of permissions */
1475 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1476 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1477 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1478 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1481 return hres;
1484 /****************************************************************************
1485 * ISFHelper_fnDeleteItems
1487 * deletes items in folder
1489 static HRESULT WINAPI ISFHelper_fnDeleteItems(
1490 ISFHelper *iface,
1491 UINT cidl,
1492 LPCITEMIDLIST* apidl)
1494 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1495 int i;
1496 char szPath[MAX_PATH];
1498 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1500 for(i=0; i< cidl; i++)
1502 strcpy(szPath, This->sMyPath);
1503 PathAddBackslashA(szPath);
1504 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1506 if (_ILIsFolder(apidl[i]))
1508 LPITEMIDLIST pidl;
1510 MESSAGE("delete %s\n", szPath);
1511 if (! SHELL_DeleteDirectoryA(szPath, TRUE)) return E_FAIL;
1512 pidl = ILCombine(This->absPidl, apidl[i]);
1513 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1514 SHFree(pidl);
1516 else if (_ILIsValue(apidl[i]))
1518 LPITEMIDLIST pidl;
1520 MESSAGE("delete %s\n", szPath);
1521 if (! DeleteFileA(szPath)) return E_FAIL;
1522 pidl = ILCombine(This->absPidl, apidl[i]);
1523 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1524 SHFree(pidl);
1528 return S_OK;
1531 /****************************************************************************
1532 * ISFHelper_fnCopyItems
1534 * copys items to this folder
1536 static HRESULT WINAPI ISFHelper_fnCopyItems(
1537 ISFHelper *iface,
1538 IShellFolder* pSFFrom,
1539 UINT cidl,
1540 LPCITEMIDLIST *apidl)
1542 int i;
1543 IPersistFolder2 * ppf2=NULL;
1544 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1545 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1547 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1549 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1550 if (ppf2)
1552 LPITEMIDLIST pidl;
1553 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1555 for (i=0; i<cidl; i++)
1557 SHGetPathFromIDListA(pidl, szSrcPath);
1558 PathAddBackslashA(szSrcPath);
1559 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1561 strcpy(szDstPath, This->sMyPath);
1562 PathAddBackslashA(szDstPath);
1563 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1564 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1566 SHFree(pidl);
1568 IPersistFolder2_Release(ppf2);
1570 return S_OK;
1573 static ICOM_VTABLE(ISFHelper) shvt =
1575 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1576 ISFHelper_fnQueryInterface,
1577 ISFHelper_fnAddRef,
1578 ISFHelper_fnRelease,
1579 ISFHelper_fnGetUniqueName,
1580 ISFHelper_fnAddFolder,
1581 ISFHelper_fnDeleteItems,
1582 ISFHelper_fnCopyItems,
1585 /***********************************************************************
1586 * [Desktopfolder] IShellFolder implementation
1588 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1590 static shvheader DesktopSFHeader [] =
1592 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1593 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1594 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1595 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1596 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1598 #define DESKTOPSHELLVIEWCOLUMNS 5
1600 /**************************************************************************
1601 * ISF_Desktop_Constructor
1604 IShellFolder * ISF_Desktop_Constructor()
1606 IGenericSFImpl * sf;
1608 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1609 sf->ref=1;
1610 ICOM_VTBL(sf)=&unkvt;
1611 sf->lpvtblShellFolder=&sfdvt;
1612 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1613 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1615 TRACE("(%p)\n",sf);
1617 shell32_ObjCount++;
1618 return _IShellFolder_(sf);
1621 /**************************************************************************
1622 * ISF_Desktop_fnQueryInterface
1624 * NOTES supports not IPersist/IPersistFolder
1626 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1627 IShellFolder2 * iface,
1628 REFIID riid,
1629 LPVOID *ppvObj)
1631 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1633 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1635 *ppvObj = NULL;
1637 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1639 *ppvObj = _IUnknown_(This);
1641 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1643 *ppvObj = _IShellFolder_(This);
1645 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1647 *ppvObj = _IShellFolder_(This);
1650 if(*ppvObj)
1652 IUnknown_AddRef((IUnknown*)(*ppvObj));
1653 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1654 return S_OK;
1656 TRACE("-- Interface: E_NOINTERFACE\n");
1657 return E_NOINTERFACE;
1660 /**************************************************************************
1661 * ISF_Desktop_fnParseDisplayName
1663 * NOTES
1664 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1665 * to MyComputer
1667 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1668 IShellFolder2 * iface,
1669 HWND hwndOwner,
1670 LPBC pbcReserved,
1671 LPOLESTR lpszDisplayName,
1672 DWORD *pchEaten,
1673 LPITEMIDLIST *ppidl,
1674 DWORD *pdwAttributes)
1676 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1678 LPCWSTR szNext=NULL;
1679 LPITEMIDLIST pidlTemp=NULL;
1680 HRESULT hr=E_OUTOFMEMORY;
1682 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1683 This,hwndOwner,pbcReserved,lpszDisplayName,
1684 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1686 *ppidl = 0;
1687 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1689 /* fixme no real parsing implemented */
1690 pidlTemp = _ILCreateMyComputer();
1691 szNext = lpszDisplayName;
1693 if (szNext && *szNext)
1695 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1697 else
1699 hr = S_OK;
1701 if (pdwAttributes && *pdwAttributes)
1703 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1707 *ppidl = pidlTemp;
1709 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1711 return hr;
1714 /**************************************************************************
1715 * ISF_Desktop_fnEnumObjects
1717 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1718 IShellFolder2 * iface,
1719 HWND hwndOwner,
1720 DWORD dwFlags,
1721 LPENUMIDLIST* ppEnumIDList)
1723 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1725 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1727 *ppEnumIDList = NULL;
1728 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1730 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1732 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1734 return S_OK;
1737 /**************************************************************************
1738 * ISF_Desktop_fnBindToObject
1740 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1741 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1743 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1744 GUID const * clsid;
1745 IShellFolder *pShellFolder, *pSubFolder;
1747 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1748 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1750 *ppvOut = NULL;
1752 if ((clsid=_ILGetGUIDPointer(pidl)))
1754 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1756 pShellFolder = ISF_MyComputer_Constructor();
1758 else
1760 /* shell extension */
1761 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1763 return E_INVALIDARG;
1767 else
1769 /* file system folder on the desktop */
1770 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1771 IPersistFolder * ppf;
1773 /* combine pidls */
1774 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1775 firstpidl = ILCloneFirst(pidl);
1776 completepidl = ILCombine(deskpidl, firstpidl);
1778 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1779 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1781 IPersistFolder_Initialize(ppf, completepidl);
1782 IPersistFolder_Release(ppf);
1784 ILFree(completepidl);
1785 ILFree(deskpidl);
1786 ILFree(firstpidl);
1789 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1791 *ppvOut = pShellFolder;
1793 else /* go deeper */
1795 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1796 IShellFolder_Release(pShellFolder);
1797 *ppvOut = pSubFolder;
1800 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1802 return S_OK;
1805 /**************************************************************************
1806 * ISF_Desktop_fnCreateViewObject
1808 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1809 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1811 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1813 LPSHELLVIEW pShellView;
1814 HRESULT hr = E_INVALIDARG;
1816 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1818 if(ppvOut)
1820 *ppvOut = NULL;
1822 if(IsEqualIID(riid, &IID_IDropTarget))
1824 WARN("IDropTarget not implemented\n");
1825 hr = E_NOTIMPL;
1827 else if(IsEqualIID(riid, &IID_IContextMenu))
1829 WARN("IContextMenu not implemented\n");
1830 hr = E_NOTIMPL;
1832 else if(IsEqualIID(riid, &IID_IShellView))
1834 pShellView = IShellView_Constructor((IShellFolder*)iface);
1835 if(pShellView)
1837 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1838 IShellView_Release(pShellView);
1842 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1843 return hr;
1846 /**************************************************************************
1847 * ISF_Desktop_fnGetAttributesOf
1849 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1850 IShellFolder2 * iface,
1851 UINT cidl,
1852 LPCITEMIDLIST *apidl,
1853 DWORD *rgfInOut)
1855 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1857 HRESULT hr = S_OK;
1859 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1861 if ( (!cidl) || (!apidl) || (!rgfInOut))
1862 return E_INVALIDARG;
1864 while (cidl > 0 && *apidl)
1866 pdump (*apidl);
1867 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1868 apidl++;
1869 cidl--;
1872 TRACE("-- result=0x%08lx\n",*rgfInOut);
1874 return hr;
1877 /**************************************************************************
1878 * ISF_Desktop_fnGetDisplayNameOf
1880 * NOTES
1881 * special case: pidl = null gives desktop-name back
1883 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1884 IShellFolder2 * iface,
1885 LPCITEMIDLIST pidl,
1886 DWORD dwFlags,
1887 LPSTRRET strRet)
1889 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1891 CHAR szPath[MAX_PATH]= "";
1893 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1894 pdump(pidl);
1896 if(!strRet) return E_INVALIDARG;
1898 if(!pidl)
1900 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1902 else if ( _ILIsPidlSimple(pidl) )
1904 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1906 else
1908 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1909 return E_OUTOFMEMORY;
1911 strRet->uType = STRRET_CSTRA;
1912 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1915 TRACE("-- (%p)->(%s)\n", This, szPath);
1916 return S_OK;
1919 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1920 IShellFolder2 * iface,
1921 GUID *pguid)
1923 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1924 FIXME("(%p)\n",This);
1925 return E_NOTIMPL;
1927 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1928 IShellFolder2 * iface,
1929 IEnumExtraSearch **ppenum)
1931 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1932 FIXME("(%p)\n",This);
1933 return E_NOTIMPL;
1935 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1936 IShellFolder2 * iface,
1937 DWORD dwRes,
1938 ULONG *pSort,
1939 ULONG *pDisplay)
1941 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1943 TRACE("(%p)\n",This);
1945 if (pSort) *pSort = 0;
1946 if (pDisplay) *pDisplay = 0;
1948 return S_OK;
1950 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1951 IShellFolder2 * iface,
1952 UINT iColumn,
1953 DWORD *pcsFlags)
1955 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1957 TRACE("(%p)\n",This);
1959 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1961 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1963 return S_OK;
1965 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1966 IShellFolder2 * iface,
1967 LPCITEMIDLIST pidl,
1968 const SHCOLUMNID *pscid,
1969 VARIANT *pv)
1971 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1972 FIXME("(%p)\n",This);
1974 return E_NOTIMPL;
1976 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
1977 IShellFolder2 * iface,
1978 LPCITEMIDLIST pidl,
1979 UINT iColumn,
1980 SHELLDETAILS *psd)
1982 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1983 HRESULT hr = E_FAIL;;
1985 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1987 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1989 if (!pidl)
1991 psd->fmt = DesktopSFHeader[iColumn].fmt;
1992 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
1993 psd->str.uType = STRRET_CSTRA;
1994 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1995 return S_OK;
1997 else
1999 /* the data from the pidl */
2000 switch(iColumn)
2002 case 0: /* name */
2003 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2004 break;
2005 case 1: /* size */
2006 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2007 break;
2008 case 2: /* type */
2009 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2010 break;
2011 case 3: /* date */
2012 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2013 break;
2014 case 4: /* attributes */
2015 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2016 break;
2018 hr = S_OK;
2019 psd->str.uType = STRRET_CSTRA;
2022 return hr;
2024 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2025 IShellFolder2 * iface,
2026 LPCWSTR pwszName,
2027 SHCOLUMNID *pscid)
2029 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2030 FIXME("(%p)\n",This);
2031 return E_NOTIMPL;
2034 static ICOM_VTABLE(IShellFolder2) sfdvt =
2036 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2037 ISF_Desktop_fnQueryInterface,
2038 IShellFolder_fnAddRef,
2039 IShellFolder_fnRelease,
2040 ISF_Desktop_fnParseDisplayName,
2041 ISF_Desktop_fnEnumObjects,
2042 ISF_Desktop_fnBindToObject,
2043 IShellFolder_fnBindToStorage,
2044 IShellFolder_fnCompareIDs,
2045 ISF_Desktop_fnCreateViewObject,
2046 ISF_Desktop_fnGetAttributesOf,
2047 IShellFolder_fnGetUIObjectOf,
2048 ISF_Desktop_fnGetDisplayNameOf,
2049 IShellFolder_fnSetNameOf,
2051 /* ShellFolder2 */
2052 ISF_Desktop_fnGetDefaultSearchGUID,
2053 ISF_Desktop_fnEnumSearches,
2054 ISF_Desktop_fnGetDefaultColumn,
2055 ISF_Desktop_fnGetDefaultColumnState,
2056 ISF_Desktop_fnGetDetailsEx,
2057 ISF_Desktop_fnGetDetailsOf,
2058 ISF_Desktop_fnMapNameToSCID
2062 /***********************************************************************
2063 * IShellFolder [MyComputer] implementation
2066 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2068 static shvheader MyComputerSFHeader [] =
2070 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2071 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2072 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2073 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2075 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2077 /**************************************************************************
2078 * ISF_MyComputer_Constructor
2080 static IShellFolder * ISF_MyComputer_Constructor(void)
2082 IGenericSFImpl * sf;
2084 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2085 sf->ref=1;
2087 ICOM_VTBL(sf)=&unkvt;
2088 sf->lpvtblShellFolder=&sfmcvt;
2089 sf->lpvtblPersistFolder2 = &psfvt;
2090 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2091 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2092 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2094 TRACE("(%p)\n",sf);
2096 shell32_ObjCount++;
2097 return _IShellFolder_(sf);
2100 /**************************************************************************
2101 * ISF_MyComputer_fnParseDisplayName
2103 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2104 IShellFolder2 * iface,
2105 HWND hwndOwner,
2106 LPBC pbcReserved,
2107 LPOLESTR lpszDisplayName,
2108 DWORD *pchEaten,
2109 LPITEMIDLIST *ppidl,
2110 DWORD *pdwAttributes)
2112 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2114 HRESULT hr = E_OUTOFMEMORY;
2115 LPCWSTR szNext=NULL;
2116 WCHAR szElement[MAX_PATH];
2117 CHAR szTempA[MAX_PATH];
2118 LPITEMIDLIST pidlTemp;
2120 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2121 This,hwndOwner,pbcReserved,lpszDisplayName,
2122 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2124 *ppidl = 0;
2125 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2127 /* do we have an absolute path name ? */
2128 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2129 lpszDisplayName[2] == (WCHAR)'\\')
2131 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2132 lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
2133 pidlTemp = _ILCreateDrive(szTempA);
2135 if (szNext && *szNext)
2137 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2139 else
2141 if (pdwAttributes && *pdwAttributes)
2143 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2145 hr = S_OK;
2147 *ppidl = pidlTemp;
2150 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2152 return hr;
2155 /**************************************************************************
2156 * ISF_MyComputer_fnEnumObjects
2158 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2159 IShellFolder2 * iface,
2160 HWND hwndOwner,
2161 DWORD dwFlags,
2162 LPENUMIDLIST* ppEnumIDList)
2164 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2166 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2168 *ppEnumIDList = NULL;
2169 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2171 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2173 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2175 return S_OK;
2178 /**************************************************************************
2179 * ISF_MyComputer_fnBindToObject
2181 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2182 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2184 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2185 GUID const * clsid;
2186 IShellFolder *pShellFolder, *pSubFolder;
2187 LPITEMIDLIST pidltemp;
2189 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2190 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2192 if(!pidl || !ppvOut) return E_INVALIDARG;
2194 *ppvOut = NULL;
2196 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2198 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2200 return E_FAIL;
2203 else
2205 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2207 pidltemp = ILCloneFirst(pidl);
2208 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2209 ILFree(pidltemp);
2212 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2214 *ppvOut = pShellFolder;
2216 else /* go deeper */
2218 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
2219 IShellFolder_Release(pShellFolder);
2220 *ppvOut = pSubFolder;
2223 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
2225 return S_OK;
2228 /**************************************************************************
2229 * ISF_MyComputer_fnCreateViewObject
2231 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2232 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2234 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2236 LPSHELLVIEW pShellView;
2237 HRESULT hr = E_INVALIDARG;
2239 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2241 if(ppvOut)
2243 *ppvOut = NULL;
2245 if(IsEqualIID(riid, &IID_IDropTarget))
2247 WARN("IDropTarget not implemented\n");
2248 hr = E_NOTIMPL;
2250 else if(IsEqualIID(riid, &IID_IContextMenu))
2252 WARN("IContextMenu not implemented\n");
2253 hr = E_NOTIMPL;
2255 else if(IsEqualIID(riid, &IID_IShellView))
2257 pShellView = IShellView_Constructor((IShellFolder*)iface);
2258 if(pShellView)
2260 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2261 IShellView_Release(pShellView);
2265 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2266 return hr;
2269 /**************************************************************************
2270 * ISF_MyComputer_fnGetAttributesOf
2272 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2273 IShellFolder2 * iface,
2274 UINT cidl,
2275 LPCITEMIDLIST *apidl,
2276 DWORD *rgfInOut)
2278 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2280 HRESULT hr = S_OK;
2282 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2284 if ( (!cidl) || (!apidl) || (!rgfInOut))
2285 return E_INVALIDARG;
2287 while (cidl > 0 && *apidl)
2289 pdump (*apidl);
2290 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2291 apidl++;
2292 cidl--;
2295 TRACE("-- result=0x%08lx\n",*rgfInOut);
2296 return hr;
2299 /**************************************************************************
2300 * ISF_MyComputer_fnGetDisplayNameOf
2302 * NOTES
2303 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2304 * SHGDN_INFOLDER makes no sense.
2306 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2307 IShellFolder2 * iface,
2308 LPCITEMIDLIST pidl,
2309 DWORD dwFlags,
2310 LPSTRRET strRet)
2312 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2314 char szPath[MAX_PATH], szDrive[18];
2315 int len = 0;
2316 BOOL bSimplePidl;
2318 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2319 pdump(pidl);
2321 if(!strRet) return E_INVALIDARG;
2323 szPath[0]=0x00; szDrive[0]=0x00;
2326 bSimplePidl = _ILIsPidlSimple(pidl);
2328 if (_ILIsSpecialFolder(pidl))
2330 /* take names of special folders only if its only this folder */
2331 if ( bSimplePidl )
2333 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2336 else
2338 if (!_ILIsDrive(pidl))
2340 ERR("Wrong pidl type\n");
2341 return E_INVALIDARG;
2344 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2346 /* long view "lw_name (C:)" */
2347 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2349 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2351 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2352 strcat (szDrive," (");
2353 strncat (szDrive, szPath, 2);
2354 strcat (szDrive,")");
2355 strcpy (szPath, szDrive);
2359 if (!bSimplePidl) /* go deeper if needed */
2361 PathAddBackslashA(szPath);
2362 len = strlen(szPath);
2364 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2365 return E_OUTOFMEMORY;
2367 strRet->uType = STRRET_CSTRA;
2368 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2371 TRACE("-- (%p)->(%s)\n", This, szPath);
2372 return S_OK;
2375 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2376 IShellFolder2 * iface,
2377 GUID *pguid)
2379 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2380 FIXME("(%p)\n",This);
2381 return E_NOTIMPL;
2383 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2384 IShellFolder2 * iface,
2385 IEnumExtraSearch **ppenum)
2387 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2388 FIXME("(%p)\n",This);
2389 return E_NOTIMPL;
2391 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2392 IShellFolder2 * iface,
2393 DWORD dwRes,
2394 ULONG *pSort,
2395 ULONG *pDisplay)
2397 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2399 TRACE("(%p)\n",This);
2401 if (pSort) *pSort = 0;
2402 if (pDisplay) *pDisplay = 0;
2404 return S_OK;
2406 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2407 IShellFolder2 * iface,
2408 UINT iColumn,
2409 DWORD *pcsFlags)
2411 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2413 TRACE("(%p)\n",This);
2415 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2417 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2419 return S_OK;
2421 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2422 IShellFolder2 * iface,
2423 LPCITEMIDLIST pidl,
2424 const SHCOLUMNID *pscid,
2425 VARIANT *pv)
2427 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2428 FIXME("(%p)\n",This);
2430 return E_NOTIMPL;
2433 /* fixme: drive size >4GB is rolling over */
2434 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2435 IShellFolder2 * iface,
2436 LPCITEMIDLIST pidl,
2437 UINT iColumn,
2438 SHELLDETAILS *psd)
2440 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2441 HRESULT hr;
2443 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2445 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2447 if (!pidl)
2449 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2450 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2451 psd->str.uType = STRRET_CSTRA;
2452 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2453 return S_OK;
2455 else
2457 char szPath[MAX_PATH];
2458 ULARGE_INTEGER ulBytes;
2460 psd->str.u.cStr[0] = 0x00;
2461 psd->str.uType = STRRET_CSTRA;
2462 switch(iColumn)
2464 case 0: /* name */
2465 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2466 break;
2467 case 1: /* type */
2468 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2469 break;
2470 case 2: /* total size */
2471 if (_ILIsDrive(pidl))
2473 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2474 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2475 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2477 break;
2478 case 3: /* free size */
2479 if (_ILIsDrive(pidl))
2481 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2482 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2483 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2485 break;
2487 hr = S_OK;
2490 return hr;
2492 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2493 IShellFolder2 * iface,
2494 LPCWSTR pwszName,
2495 SHCOLUMNID *pscid)
2497 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2498 FIXME("(%p)\n",This);
2499 return E_NOTIMPL;
2502 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2504 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2505 IShellFolder_fnQueryInterface,
2506 IShellFolder_fnAddRef,
2507 IShellFolder_fnRelease,
2508 ISF_MyComputer_fnParseDisplayName,
2509 ISF_MyComputer_fnEnumObjects,
2510 ISF_MyComputer_fnBindToObject,
2511 IShellFolder_fnBindToStorage,
2512 IShellFolder_fnCompareIDs,
2513 ISF_MyComputer_fnCreateViewObject,
2514 ISF_MyComputer_fnGetAttributesOf,
2515 IShellFolder_fnGetUIObjectOf,
2516 ISF_MyComputer_fnGetDisplayNameOf,
2517 IShellFolder_fnSetNameOf,
2519 /* ShellFolder2 */
2520 ISF_MyComputer_fnGetDefaultSearchGUID,
2521 ISF_MyComputer_fnEnumSearches,
2522 ISF_MyComputer_fnGetDefaultColumn,
2523 ISF_MyComputer_fnGetDefaultColumnState,
2524 ISF_MyComputer_fnGetDetailsEx,
2525 ISF_MyComputer_fnGetDetailsOf,
2526 ISF_MyComputer_fnMapNameToSCID
2530 /************************************************************************
2531 * ISFPersistFolder_QueryInterface (IUnknown)
2534 static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2535 IPersistFolder2 * iface,
2536 REFIID iid,
2537 LPVOID* ppvObj)
2539 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2541 TRACE("(%p)\n", This);
2543 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2546 /************************************************************************
2547 * ISFPersistFolder_AddRef (IUnknown)
2550 static ULONG WINAPI ISFPersistFolder2_AddRef(
2551 IPersistFolder2 * iface)
2553 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2555 TRACE("(%p)\n", This);
2557 return IUnknown_AddRef(This->pUnkOuter);
2560 /************************************************************************
2561 * ISFPersistFolder_Release (IUnknown)
2564 static ULONG WINAPI ISFPersistFolder2_Release(
2565 IPersistFolder2 * iface)
2567 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2569 TRACE("(%p)\n", This);
2571 return IUnknown_Release(This->pUnkOuter);
2574 /************************************************************************
2575 * ISFPersistFolder_GetClassID (IPersist)
2577 static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2578 IPersistFolder2 * iface,
2579 CLSID * lpClassId)
2581 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2583 TRACE("(%p)\n", This);
2585 if (!lpClassId) return E_POINTER;
2586 *lpClassId = *This->pclsid;
2588 return S_OK;
2591 /************************************************************************
2592 * ISFPersistFolder_Initialize (IPersistFolder)
2594 * NOTES
2595 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2597 static HRESULT WINAPI ISFPersistFolder2_Initialize(
2598 IPersistFolder2 * iface,
2599 LPCITEMIDLIST pidl)
2601 char sTemp[MAX_PATH];
2602 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2604 TRACE("(%p)->(%p)\n", This, pidl);
2606 /* free the old stuff */
2607 if(This->absPidl)
2609 SHFree(This->absPidl);
2610 This->absPidl = NULL;
2612 if(This->sMyPath)
2614 SHFree(This->sMyPath);
2615 This->sMyPath = NULL;
2618 /* set my pidl */
2619 This->absPidl = ILClone(pidl);
2621 /* set my path */
2622 if (SHGetPathFromIDListA(pidl, sTemp))
2624 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2625 strcpy(This->sMyPath, sTemp);
2628 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2630 return S_OK;
2633 /**************************************************************************
2634 * IPersistFolder2_fnGetCurFolder
2636 static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2637 IPersistFolder2 * iface,
2638 LPITEMIDLIST * pidl)
2640 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2642 TRACE("(%p)->(%p)\n",This, pidl);
2644 if (!pidl) return E_POINTER;
2646 *pidl = ILClone(This->absPidl);
2648 return S_OK;
2651 static ICOM_VTABLE(IPersistFolder2) psfvt =
2653 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2654 ISFPersistFolder2_QueryInterface,
2655 ISFPersistFolder2_AddRef,
2656 ISFPersistFolder2_Release,
2657 ISFPersistFolder2_GetClassID,
2658 ISFPersistFolder2_Initialize,
2659 ISFPersistFolder2_fnGetCurFolder
2662 /****************************************************************************
2663 * ISFDropTarget implementation
2665 static BOOL ISFDropTarget_QueryDrop(
2666 IDropTarget *iface,
2667 DWORD dwKeyState,
2668 LPDWORD pdwEffect)
2670 DWORD dwEffect = *pdwEffect;
2672 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2674 *pdwEffect = DROPEFFECT_NONE;
2676 if (This->fAcceptFmt)
2677 { /* Does our interpretation of the keystate ... */
2678 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2680 /* ... matches the desired effect ? */
2681 if (dwEffect & *pdwEffect)
2683 return TRUE;
2686 return FALSE;
2689 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2690 IDropTarget *iface,
2691 REFIID riid,
2692 LPVOID *ppvObj)
2694 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2696 TRACE("(%p)\n", This);
2698 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2701 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2703 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2705 TRACE("(%p)\n", This);
2707 return IUnknown_AddRef(This->pUnkOuter);
2710 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2712 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2714 TRACE("(%p)\n", This);
2716 return IUnknown_Release(This->pUnkOuter);
2719 static HRESULT WINAPI ISFDropTarget_DragEnter(
2720 IDropTarget *iface,
2721 IDataObject *pDataObject,
2722 DWORD dwKeyState,
2723 POINTL pt,
2724 DWORD *pdwEffect)
2726 FORMATETC fmt;
2728 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2730 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2732 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2734 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2736 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2738 return S_OK;
2741 static HRESULT WINAPI ISFDropTarget_DragOver(
2742 IDropTarget *iface,
2743 DWORD dwKeyState,
2744 POINTL pt,
2745 DWORD *pdwEffect)
2747 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2749 TRACE("(%p)\n",This);
2751 if(!pdwEffect) return E_INVALIDARG;
2753 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2755 return S_OK;
2758 static HRESULT WINAPI ISFDropTarget_DragLeave(
2759 IDropTarget *iface)
2761 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2763 TRACE("(%p)\n",This);
2765 This->fAcceptFmt = FALSE;
2767 return S_OK;
2770 static HRESULT WINAPI ISFDropTarget_Drop(
2771 IDropTarget *iface,
2772 IDataObject* pDataObject,
2773 DWORD dwKeyState,
2774 POINTL pt,
2775 DWORD *pdwEffect)
2777 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2779 FIXME("(%p) object dropped\n",This);
2781 return E_NOTIMPL;
2784 static struct ICOM_VTABLE(IDropTarget) dtvt =
2786 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2787 ISFDropTarget_QueryInterface,
2788 ISFDropTarget_AddRef,
2789 ISFDropTarget_Release,
2790 ISFDropTarget_DragEnter,
2791 ISFDropTarget_DragOver,
2792 ISFDropTarget_DragLeave,
2793 ISFDropTarget_Drop