4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
7 * IShellFolder2 and related interfaces
15 #include "debugtools.h"
23 #include "wine/obj_base.h"
24 #include "wine/obj_dragdrop.h"
25 #include "wine/obj_shellfolder.h"
26 #include "wine/undocshell.h"
27 #include "shell32_main.h"
33 #include "shellfolder.h"
34 #include "wine/obj_queryassociations.h"
36 DEFAULT_DEBUG_CHANNEL(shell);
39 /***************************************************************************
40 * debughelper: print out the return adress
41 * helps especially to track down unbalanced AddRef/Release
46 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
60 /***************************************************************************
61 * GetNextElement (internal function)
63 * gets a part of a string till the first backslash
66 * pszNext [IN] string to get the element from
67 * pszOut [IN] pointer to buffer whitch receives string
68 * dwOut [IN] length of pszOut
71 * LPSTR pointer to first, not yet parsed char
74 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
75 { LPCWSTR pszTail = pszNext;
77 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
81 if(!pszNext || !*pszNext)
84 while(*pszTail && (*pszTail != (WCHAR)'\\'))
87 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
88 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
95 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
99 static HRESULT SHELL32_ParseNextElement(
102 LPITEMIDLIST * pidlInOut,
105 DWORD *pdwAttributes)
107 HRESULT hr = E_OUTOFMEMORY;
108 LPITEMIDLIST pidlOut, pidlTemp = NULL;
109 IShellFolder *psfChild;
111 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
114 /* get the shellfolder for the child pidl and let it analyse further */
115 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
119 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
120 IShellFolder_Release(psfChild);
122 pidlTemp = ILCombine(*pidlInOut, pidlOut);
129 *pidlInOut = pidlTemp;
131 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
135 /***********************************************************************
136 * SHELL32_CoCreateInitSF
138 * creates a initialized shell folder
140 static HRESULT SHELL32_CoCreateInitSF (
141 LPITEMIDLIST pidlRoot,
142 LPITEMIDLIST pidlChild,
148 LPITEMIDLIST absPidl;
149 IShellFolder2 *pShellFolder;
150 IPersistFolder *pPersistFolder;
152 TRACE("%p %p\n", pidlRoot, pidlChild);
156 /* we have to ask first for IPersistFolder, some special folders are expecting this */
157 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
160 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
163 absPidl = ILCombine (pidlRoot, pidlChild);
164 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
165 IPersistFolder_Release(pPersistFolder);
167 *ppvOut = pShellFolder;
171 TRACE("-- ret=0x%08lx\n", hr);
175 static HRESULT SHELL32_GetDisplayNameOfChild(
182 LPITEMIDLIST pidlFirst, pidlNext;
183 IShellFolder2 * psfChild;
184 HRESULT hr = E_OUTOFMEMORY;
187 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
190 if ((pidlFirst = ILCloneFirst(pidl)))
192 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
195 pidlNext = ILGetNext(pidl);
197 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
200 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
203 IShellFolder_Release(psfChild);
208 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
213 /***********************************************************************
214 * SHELL32_GetItemAttributes
218 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
219 * file: 0x40000177 FILESYSTEM
220 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
221 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
222 * (seems to be default for shell extensions if no registry entry exists)
224 * This functions does not set flags!! It only resets flags when nessesary.
226 static HRESULT SHELL32_GetItemAttributes(
229 LPDWORD pdwAttributes)
234 TRACE("0x%08lx\n", *pdwAttributes);
236 if (*pdwAttributes & (0xcff3fe88))
237 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
238 *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
240 if (_ILIsDrive(pidl))
242 *pdwAttributes &= 0xf0000144;
244 else if ((clsid=_ILGetGUIDPointer(pidl)))
246 if (HCR_GetFolderAttributes(clsid, &dwAttributes))
248 *pdwAttributes &= dwAttributes;
252 *pdwAttributes &= 0xb0000154;
255 else if (_ILGetDataPointer(pidl))
257 dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
258 *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
260 if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
261 *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
263 if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
264 *pdwAttributes &= ~SFGAO_HIDDEN;
266 if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
267 *pdwAttributes &= ~SFGAO_READONLY;
271 *pdwAttributes &= 0xb0000154;
273 TRACE("-- 0x%08lx\n", *pdwAttributes);
277 /***********************************************************************
278 * IShellFolder implementation
283 ICOM_VFIELD(IUnknown);
285 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
286 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
287 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
288 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
290 IUnknown *pUnkOuter; /* used for aggregation */
295 LPITEMIDLIST absPidl; /* complete pidl */
297 UINT cfShellIDList; /* clipboardformat for IDropTarget */
298 BOOL fAcceptFmt; /* flag for pending Drop */
301 static struct ICOM_VTABLE(IUnknown) unkvt;
302 static struct ICOM_VTABLE(IShellFolder2) sfvt;
303 static struct ICOM_VTABLE(IPersistFolder2) psfvt;
304 static struct ICOM_VTABLE(IDropTarget) dtvt;
305 static struct ICOM_VTABLE(ISFHelper) shvt;
307 static IShellFolder * ISF_MyComputer_Constructor(void);
309 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
310 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
312 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
313 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
315 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
316 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
318 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
319 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
321 converts This to a interface pointer
323 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
324 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
325 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
326 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
327 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
328 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
329 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
330 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
331 /**************************************************************************
332 * registers clipboardformat once
334 static void SF_RegisterClipFmt (IGenericSFImpl * This)
336 TRACE("(%p)\n", This);
338 if (!This->cfShellIDList)
340 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
344 /**************************************************************************
345 * we need a seperate IUnknown to handle aggregation
348 static HRESULT WINAPI IUnknown_fnQueryInterface(
353 ICOM_THIS(IGenericSFImpl, iface);
356 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
360 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
361 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
362 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
363 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
364 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
365 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
366 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
367 else if(IsEqualIID(riid, &IID_IDropTarget))
369 *ppvObj = _IDropTarget_(This);
370 SF_RegisterClipFmt(This);
375 IUnknown_AddRef((IUnknown*)(*ppvObj));
376 TRACE("-- Interface = %p\n", *ppvObj);
379 TRACE("-- Interface: E_NOINTERFACE\n");
380 return E_NOINTERFACE;
383 static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
385 ICOM_THIS(IGenericSFImpl, iface);
388 TRACE("(%p)->(count=%lu)\n",This,This->ref);
391 return ++(This->ref);
394 static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
396 ICOM_THIS(IGenericSFImpl, iface);
399 TRACE("(%p)->(count=%lu)\n",This,This->ref);
404 TRACE("-- destroying IShellFolder(%p)\n",This);
406 if (pdesktopfolder == _IShellFolder_(This))
409 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
411 if(This->absPidl) SHFree(This->absPidl);
412 if(This->sMyPath) SHFree(This->sMyPath);
413 HeapFree(GetProcessHeap(),0,This);
419 static ICOM_VTABLE(IUnknown) unkvt =
421 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
422 IUnknown_fnQueryInterface,
427 static shvheader GenericSFHeader [] =
429 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
430 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
431 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
432 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
433 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
435 #define GENERICSHELLVIEWCOLUMNS 5
437 /**************************************************************************
438 * IShellFolder_Constructor
441 * creating undocumented ShellFS_Folder as part of an aggregation
442 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
445 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
447 HRESULT IFSFolder_Constructor(
448 IUnknown * pUnkOuter,
455 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
457 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
459 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
463 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
467 ICOM_VTBL(sf)=&unkvt;
468 sf->lpvtblShellFolder=&sfvt;
469 sf->lpvtblPersistFolder2=&psfvt;
470 sf->lpvtblDropTarget=&dtvt;
471 sf->lpvtblSFHelper=&shvt;
473 sf->pclsid = (CLSID*)&CLSID_SFFile;
474 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
475 *ppv = _IUnknown_(sf);
486 /**************************************************************************
487 * IShellFolder_Constructor
490 * THIS points to the parent folder
493 IShellFolder * IShellFolder_Constructor(
494 IShellFolder2 * iface,
500 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
502 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
505 ICOM_VTBL(sf)=&unkvt;
506 sf->lpvtblShellFolder=&sfvt;
507 sf->lpvtblPersistFolder2=&psfvt;
508 sf->lpvtblDropTarget=&dtvt;
509 sf->lpvtblSFHelper=&shvt;
511 sf->pclsid = (CLSID*)&CLSID_SFFile;
512 sf->pUnkOuter = _IUnknown_(sf);
514 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
517 if(pidl && iface) /* do we have a pidl? */
521 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
523 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
525 if(This->sMyPath) /* get the size of the parents path */
527 dwSize += strlen(This->sMyPath) ;
528 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
531 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
532 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
534 if(!sf->sMyPath) return NULL;
537 if(This->sMyPath) /* if the parent has a path, get it*/
539 strcpy(sf->sMyPath, This->sMyPath);
540 PathAddBackslashA (sf->sMyPath);
543 len = strlen(sf->sMyPath);
544 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
547 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
553 return _IShellFolder_(sf);
556 /**************************************************************************
557 * IShellFolder_fnQueryInterface
560 * REFIID riid [in ] Requested InterfaceID
561 * LPVOID* ppvObject [out] Interface* to hold the result
563 static HRESULT WINAPI IShellFolder_fnQueryInterface(
564 IShellFolder2 * iface,
568 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
571 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
573 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
576 /**************************************************************************
577 * IShellFolder_AddRef
580 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
582 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
585 TRACE("(%p)->(count=%lu)\n",This,This->ref);
587 return IUnknown_AddRef(This->pUnkOuter);
590 /**************************************************************************
591 * IShellFolder_fnRelease
593 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
595 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
598 TRACE("(%p)->(count=%lu)\n",This,This->ref);
600 return IUnknown_Release(This->pUnkOuter);
603 /**************************************************************************
604 * IShellFolder_fnParseDisplayName
606 * HWND hwndOwner, //[in ] Parent window for any message's
607 * LPBC pbc, //[in ] reserved
608 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
609 * ULONG* pchEaten, //[out] (unicode) characters processed
610 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
611 * ULONG* pdwAttributes //[out] items attributes
614 * every folder tries to parse only its own (the leftmost) pidl and creates a
615 * subfolder to evaluate the remaining parts
616 * now we can parse into namespaces implemented by shell extensions
618 * behaviour on win98: lpszDisplayName=NULL -> chrash
619 * lpszDisplayName="" -> returns mycoputer-pidl
622 * pdwAttributes: not set
623 * pchEaten: not set like in windows
625 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
626 IShellFolder2 * iface,
629 LPOLESTR lpszDisplayName,
632 DWORD *pdwAttributes)
634 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
636 HRESULT hr = E_OUTOFMEMORY;
638 WCHAR szElement[MAX_PATH];
639 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
640 LPITEMIDLIST pidlTemp=NULL;
642 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
643 This,hwndOwner,pbcReserved,lpszDisplayName,
644 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
646 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
648 if (pchEaten) *pchEaten = 0; /* strange but like the original */
650 if (*lpszDisplayName)
652 /* get the next element */
653 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
655 /* build the full pathname to the element */
656 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
657 strcpy(szPath, This->sMyPath);
658 PathAddBackslashA(szPath);
659 strcat(szPath, szTempA);
662 pidlTemp = SHSimpleIDListFromPathA(szPath);
666 /* try to analyse the next element */
667 if (szNext && *szNext)
669 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
673 if (pdwAttributes && *pdwAttributes)
675 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
676 /* WIN32_FIND_DATAA fd;
677 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
678 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
679 *pdwAttributes &= ~SFGAO_FOLDER;
680 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
681 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
691 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
696 /**************************************************************************
697 * IShellFolder_fnEnumObjects
699 * HWND hwndOwner, //[in ] Parent Window
700 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
701 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
703 static HRESULT WINAPI IShellFolder_fnEnumObjects(
704 IShellFolder2 * iface,
707 LPENUMIDLIST* ppEnumIDList)
709 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
711 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
713 *ppEnumIDList = NULL;
714 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
716 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
718 if(!*ppEnumIDList) return E_OUTOFMEMORY;
723 /**************************************************************************
724 * IShellFolder_fnBindToObject
726 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
727 * LPBC pbc, //[in ] reserved
728 * REFIID riid, //[in ] Initial Interface
729 * LPVOID* ppvObject //[out] Interface*
731 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
732 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
734 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
736 IShellFolder *pShellFolder, *pSubFolder;
737 IPersistFolder *pPersistFolder;
738 LPITEMIDLIST absPidl;
740 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
742 if(!pidl || !ppvOut) return E_INVALIDARG;
746 if ((iid=_ILGetGUIDPointer(pidl)))
748 /* we have to create a alien folder */
749 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
750 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
752 absPidl = ILCombine (This->absPidl, pidl);
753 IPersistFolder_Initialize(pPersistFolder, absPidl);
754 IPersistFolder_Release(pPersistFolder);
762 else if(_ILIsFolder(pidl))
764 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
765 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
770 ERR("can't bind to a file\n");
774 if (_ILIsPidlSimple(pidl))
776 *ppvOut = pShellFolder;
780 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
781 IShellFolder_Release(pShellFolder);
782 *ppvOut = pSubFolder;
785 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
790 /**************************************************************************
791 * IShellFolder_fnBindToStorage
793 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
794 * LPBC pbc, //[in ] reserved
795 * REFIID riid, //[in ] Initial storage interface
796 * LPVOID* ppvObject //[out] Interface* returned
798 static HRESULT WINAPI IShellFolder_fnBindToStorage(
799 IShellFolder2 * iface,
805 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
807 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
808 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
814 /**************************************************************************
815 * IShellFolder_fnCompareIDs
818 * LPARAM lParam, //[in ] Column?
819 * LPCITEMIDLIST pidl1, //[in ] simple pidl
820 * LPCITEMIDLIST pidl2) //[in ] simple pidl
823 * Special case - If one of the items is a Path and the other is a File,
824 * always make the Path come before the File.
827 * use SCODE_CODE() on the return value to get the result
830 static HRESULT WINAPI IShellFolder_fnCompareIDs(
831 IShellFolder2 * iface,
836 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
838 CHAR szTemp1[MAX_PATH];
839 CHAR szTemp2[MAX_PATH];
842 HRESULT hr = E_OUTOFMEMORY;
843 LPCITEMIDLIST pidlTemp;
846 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
850 if (!pidl1 && !pidl2)
852 hr = ResultFromShort(0);
856 hr = ResultFromShort(-1);
860 hr = ResultFromShort(1);
865 pd1 = _ILGetDataPointer(pidl1);
866 pd2 = _ILGetDataPointer(pidl2);
868 /* compate the types. sort order is the PT_* constant */
869 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
870 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
874 hr = ResultFromShort(pt1-pt2);
876 else /* same type of pidl */
878 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
879 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
880 nReturn = strcasecmp(szTemp1, szTemp2);
882 if (nReturn == 0) /* first pidl different ? */
884 pidl1 = ILGetNext(pidl1);
886 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
888 pidlTemp = ILCloneFirst(pidl1);
889 pidl2 = ILGetNext(pidl2);
891 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
894 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
895 IShellFolder_Release(psf);
896 hr = ResultFromShort(nReturn);
902 hr = ResultFromShort(nReturn); /* two equal simple pidls */
907 hr = ResultFromShort(nReturn); /* two different simple pidls */
912 TRACE("-- res=0x%08lx\n", hr);
916 /**************************************************************************
917 * IShellFolder_fnCreateViewObject
919 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
920 IShellFolder2 * iface,
925 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
927 LPSHELLVIEW pShellView;
928 HRESULT hr = E_INVALIDARG;
930 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
936 if(IsEqualIID(riid, &IID_IDropTarget))
938 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
940 else if(IsEqualIID(riid, &IID_IContextMenu))
942 FIXME("IContextMenu not implemented\n");
945 else if(IsEqualIID(riid, &IID_IShellView))
947 pShellView = IShellView_Constructor((IShellFolder*)iface);
950 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
951 IShellView_Release(pShellView);
955 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
959 /**************************************************************************
960 * IShellFolder_fnGetAttributesOf
963 * UINT cidl, //[in ] num elements in pidl array
964 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
965 * ULONG* rgfInOut) //[out] result array
968 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
969 IShellFolder2 * iface,
971 LPCITEMIDLIST *apidl,
974 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
978 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
980 if ( (!cidl) || (!apidl) || (!rgfInOut))
983 while (cidl > 0 && *apidl)
986 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
991 TRACE("-- result=0x%08lx\n",*rgfInOut);
995 /**************************************************************************
996 * IShellFolder_fnGetUIObjectOf
999 * HWND hwndOwner, //[in ] Parent window for any output
1000 * UINT cidl, //[in ] array size
1001 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1002 * REFIID riid, //[in ] Requested Interface
1003 * UINT* prgfInOut, //[ ] reserved
1004 * LPVOID* ppvObject) //[out] Resulting Interface
1007 * This function gets asked to return "view objects" for one or more (multiple select)
1009 * The viewobject typically is an COM object with one of the following interfaces:
1010 * IExtractIcon,IDataObject,IContextMenu
1011 * In order to support icon positions in the default Listview your DataObject
1012 * must implement the SetData method (in addition to GetData :) - the shell passes
1013 * a barely documented "Icon positions" structure to SetData when the drag starts,
1014 * and GetData's it if the drop is in another explorer window that needs the positions.
1016 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1017 IShellFolder2 * iface,
1020 LPCITEMIDLIST * apidl,
1025 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1028 IUnknown* pObj = NULL;
1029 HRESULT hr = E_INVALIDARG;
1031 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1032 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1038 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1040 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1043 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1045 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1048 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1050 pidl = ILCombine(This->absPidl,apidl[0]);
1051 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1055 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1057 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1069 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1073 /**************************************************************************
1074 * IShellFolder_fnGetDisplayNameOf
1075 * Retrieves the display name for the specified file object or subfolder
1078 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1079 * DWORD dwFlags, //[in ] SHGNO formatting flags
1080 * LPSTRRET lpName) //[out] Returned display name
1083 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1085 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1086 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1088 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1089 IShellFolder2 * iface,
1094 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1096 CHAR szPath[MAX_PATH]= "";
1100 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1103 if(!pidl || !strRet) return E_INVALIDARG;
1105 bSimplePidl = _ILIsPidlSimple(pidl);
1107 /* take names of special folders only if its only this folder */
1108 if (_ILIsSpecialFolder(pidl))
1112 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1117 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1119 strcpy (szPath, This->sMyPath); /* get path to root*/
1120 PathAddBackslashA(szPath);
1121 len = strlen(szPath);
1123 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1126 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1128 PathAddBackslashA(szPath);
1129 len = strlen(szPath);
1131 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1132 return E_OUTOFMEMORY;
1134 strRet->uType = STRRET_CSTRA;
1135 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1137 TRACE("-- (%p)->(%s)\n", This, szPath);
1141 /**************************************************************************
1142 * IShellFolder_fnSetNameOf
1143 * Changes the name of a file object or subfolder, possibly changing its item
1144 * identifier in the process.
1147 * HWND hwndOwner, //[in ] Owner window for output
1148 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1149 * LPCOLESTR lpszName, //[in ] the items new display name
1150 * DWORD dwFlags, //[in ] SHGNO formatting flags
1151 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1153 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1154 IShellFolder2 * iface,
1156 LPCITEMIDLIST pidl, /*simple pidl*/
1159 LPITEMIDLIST *pPidlOut)
1161 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1162 char szSrc[MAX_PATH], szDest[MAX_PATH];
1164 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1166 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1167 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1169 /* build source path */
1170 if (dwFlags & SHGDN_INFOLDER)
1172 strcpy(szSrc, This->sMyPath);
1173 PathAddBackslashA(szSrc);
1174 len = strlen (szSrc);
1175 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1179 SHGetPathFromIDListA(pidl, szSrc);
1182 /* build destination path */
1183 strcpy(szDest, This->sMyPath);
1184 PathAddBackslashA(szDest);
1185 len = strlen (szDest);
1186 WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
1187 szDest[MAX_PATH-1] = 0;
1188 TRACE("src=%s dest=%s\n", szSrc, szDest);
1189 if ( MoveFileA(szSrc, szDest) )
1191 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1192 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1198 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1199 IShellFolder2 * iface,
1202 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1203 FIXME("(%p)\n",This);
1206 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1207 IShellFolder2 * iface,
1208 IEnumExtraSearch **ppenum)
1210 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1211 FIXME("(%p)\n",This);
1214 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1215 IShellFolder2 * iface,
1220 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1222 TRACE("(%p)\n",This);
1224 if (pSort) *pSort = 0;
1225 if (pDisplay) *pDisplay = 0;
1229 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1230 IShellFolder2 * iface,
1234 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1236 TRACE("(%p)\n",This);
1238 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1240 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1244 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1245 IShellFolder2 * iface,
1247 const SHCOLUMNID *pscid,
1250 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1251 FIXME("(%p)\n",This);
1255 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1256 IShellFolder2 * iface,
1261 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1262 HRESULT hr = E_FAIL;
1264 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1266 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1270 /* the header titles */
1271 psd->fmt = GenericSFHeader[iColumn].fmt;
1272 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1273 psd->str.uType = STRRET_CSTRA;
1274 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1279 /* the data from the pidl */
1283 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1286 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1289 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1292 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1294 case 4: /* attributes */
1295 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1299 psd->str.uType = STRRET_CSTRA;
1304 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1305 IShellFolder2 * iface,
1309 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1310 FIXME("(%p)\n",This);
1314 static ICOM_VTABLE(IShellFolder2) sfvt =
1316 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1317 IShellFolder_fnQueryInterface,
1318 IShellFolder_fnAddRef,
1319 IShellFolder_fnRelease,
1320 IShellFolder_fnParseDisplayName,
1321 IShellFolder_fnEnumObjects,
1322 IShellFolder_fnBindToObject,
1323 IShellFolder_fnBindToStorage,
1324 IShellFolder_fnCompareIDs,
1325 IShellFolder_fnCreateViewObject,
1326 IShellFolder_fnGetAttributesOf,
1327 IShellFolder_fnGetUIObjectOf,
1328 IShellFolder_fnGetDisplayNameOf,
1329 IShellFolder_fnSetNameOf,
1332 IShellFolder_fnGetDefaultSearchGUID,
1333 IShellFolder_fnEnumSearches,
1334 IShellFolder_fnGetDefaultColumn,
1335 IShellFolder_fnGetDefaultColumnState,
1336 IShellFolder_fnGetDetailsEx,
1337 IShellFolder_fnGetDetailsOf,
1338 IShellFolder_fnMapNameToSCID
1341 /****************************************************************************
1342 * ISFHelper for IShellFolder implementation
1345 static HRESULT WINAPI ISFHelper_fnQueryInterface(
1350 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1352 TRACE("(%p)\n", This);
1354 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1357 static ULONG WINAPI ISFHelper_fnAddRef(
1360 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1362 TRACE("(%p)\n", This);
1364 return IUnknown_AddRef(This->pUnkOuter);
1367 static ULONG WINAPI ISFHelper_fnRelease(
1370 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1372 TRACE("(%p)\n", This);
1374 return IUnknown_Release(This->pUnkOuter);
1378 /****************************************************************************
1379 * ISFHelper_fnAddFolder
1381 * creates a unique folder name
1384 static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1389 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1390 IEnumIDList * penum;
1392 char szText[MAX_PATH];
1393 char * szNewFolder = "New Folder";
1395 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1397 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1399 strcpy(lpName, szNewFolder);
1401 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1408 next: IEnumIDList_Reset(penum);
1409 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1411 _ILSimpleGetText(pidl, szText, MAX_PATH);
1412 if (0 == strcasecmp(szText, lpName))
1414 sprintf(lpName, "%s %d", szNewFolder, i++);
1424 IEnumIDList_Release(penum);
1429 /****************************************************************************
1430 * ISFHelper_fnAddFolder
1432 * adds a new folder.
1435 static HRESULT WINAPI ISFHelper_fnAddFolder(
1439 LPITEMIDLIST* ppidlOut)
1441 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1442 char lpstrNewDir[MAX_PATH];
1444 HRESULT hres = E_FAIL;
1446 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1448 strcpy(lpstrNewDir, This->sMyPath);
1449 PathAddBackslashA(lpstrNewDir);
1450 strcat(lpstrNewDir, lpName);
1452 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1456 LPITEMIDLIST pidl, pidlitem;
1458 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1460 pidl = ILCombine(This->absPidl, pidlitem);
1461 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1464 if (ppidlOut) *ppidlOut = pidlitem;
1469 char lpstrText[128+MAX_PATH];
1470 char lpstrTempText[128];
1471 char lpstrCaption[256];
1473 /* Cannot Create folder because of permissions */
1474 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1475 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1476 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1477 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1483 /****************************************************************************
1484 * ISFHelper_fnDeleteItems
1486 * deletes items in folder
1488 static HRESULT WINAPI ISFHelper_fnDeleteItems(
1491 LPCITEMIDLIST* apidl)
1493 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1495 char szPath[MAX_PATH];
1497 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1499 for(i=0; i< cidl; i++)
1501 strcpy(szPath, This->sMyPath);
1502 PathAddBackslashA(szPath);
1503 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1505 if (_ILIsFolder(apidl[i]))
1509 MESSAGE("delete %s\n", szPath);
1510 if (! SHELL_DeleteDirectoryA(szPath, TRUE)) return E_FAIL;
1511 pidl = ILCombine(This->absPidl, apidl[i]);
1512 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1515 else if (_ILIsValue(apidl[i]))
1519 MESSAGE("delete %s\n", szPath);
1520 if (! DeleteFileA(szPath)) return E_FAIL;
1521 pidl = ILCombine(This->absPidl, apidl[i]);
1522 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1530 /****************************************************************************
1531 * ISFHelper_fnCopyItems
1533 * copys items to this folder
1535 static HRESULT WINAPI ISFHelper_fnCopyItems(
1537 IShellFolder* pSFFrom,
1539 LPCITEMIDLIST *apidl)
1542 IPersistFolder2 * ppf2=NULL;
1543 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1544 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1546 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1548 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1552 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1554 for (i=0; i<cidl; i++)
1556 SHGetPathFromIDListA(pidl, szSrcPath);
1557 PathAddBackslashA(szSrcPath);
1558 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1560 strcpy(szDstPath, This->sMyPath);
1561 PathAddBackslashA(szDstPath);
1562 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1563 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1567 IPersistFolder2_Release(ppf2);
1572 static ICOM_VTABLE(ISFHelper) shvt =
1574 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1575 ISFHelper_fnQueryInterface,
1577 ISFHelper_fnRelease,
1578 ISFHelper_fnGetUniqueName,
1579 ISFHelper_fnAddFolder,
1580 ISFHelper_fnDeleteItems,
1581 ISFHelper_fnCopyItems,
1584 /***********************************************************************
1585 * [Desktopfolder] IShellFolder implementation
1587 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1589 static shvheader DesktopSFHeader [] =
1591 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1592 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1593 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1594 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1595 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1597 #define DESKTOPSHELLVIEWCOLUMNS 5
1599 /**************************************************************************
1600 * ISF_Desktop_Constructor
1603 IShellFolder * ISF_Desktop_Constructor()
1605 IGenericSFImpl * sf;
1607 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1609 ICOM_VTBL(sf)=&unkvt;
1610 sf->lpvtblShellFolder=&sfdvt;
1611 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1612 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1617 return _IShellFolder_(sf);
1620 /**************************************************************************
1621 * ISF_Desktop_fnQueryInterface
1623 * NOTES supports not IPersist/IPersistFolder
1625 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1626 IShellFolder2 * iface,
1630 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1632 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1636 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1638 *ppvObj = _IUnknown_(This);
1640 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1642 *ppvObj = _IShellFolder_(This);
1644 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1646 *ppvObj = _IShellFolder_(This);
1651 IUnknown_AddRef((IUnknown*)(*ppvObj));
1652 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1655 TRACE("-- Interface: E_NOINTERFACE\n");
1656 return E_NOINTERFACE;
1659 /**************************************************************************
1660 * ISF_Desktop_fnParseDisplayName
1663 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1666 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1667 IShellFolder2 * iface,
1670 LPOLESTR lpszDisplayName,
1672 LPITEMIDLIST *ppidl,
1673 DWORD *pdwAttributes)
1675 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1677 LPCWSTR szNext=NULL;
1678 LPITEMIDLIST pidlTemp=NULL;
1679 HRESULT hr=E_OUTOFMEMORY;
1681 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1682 This,hwndOwner,pbcReserved,lpszDisplayName,
1683 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1686 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1688 /* fixme no real parsing implemented */
1689 pidlTemp = _ILCreateMyComputer();
1690 szNext = lpszDisplayName;
1692 if (szNext && *szNext)
1694 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1700 if (pdwAttributes && *pdwAttributes)
1702 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1708 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1713 /**************************************************************************
1714 * ISF_Desktop_fnEnumObjects
1716 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1717 IShellFolder2 * iface,
1720 LPENUMIDLIST* ppEnumIDList)
1722 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1724 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1726 *ppEnumIDList = NULL;
1727 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1729 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1731 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1736 /**************************************************************************
1737 * ISF_Desktop_fnBindToObject
1739 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1740 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1742 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1744 IShellFolder *pShellFolder, *pSubFolder;
1746 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1747 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1751 if ((clsid=_ILGetGUIDPointer(pidl)))
1753 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1755 pShellFolder = ISF_MyComputer_Constructor();
1759 /* shell extension */
1760 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1762 return E_INVALIDARG;
1768 /* file system folder on the desktop */
1769 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1770 IPersistFolder * ppf;
1773 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1774 firstpidl = ILCloneFirst(pidl);
1775 completepidl = ILCombine(deskpidl, firstpidl);
1777 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1778 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1780 IPersistFolder_Initialize(ppf, completepidl);
1781 IPersistFolder_Release(ppf);
1783 ILFree(completepidl);
1788 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1790 *ppvOut = pShellFolder;
1792 else /* go deeper */
1794 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1795 IShellFolder_Release(pShellFolder);
1796 *ppvOut = pSubFolder;
1799 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1804 /**************************************************************************
1805 * ISF_Desktop_fnCreateViewObject
1807 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1808 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1810 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1812 LPSHELLVIEW pShellView;
1813 HRESULT hr = E_INVALIDARG;
1815 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1821 if(IsEqualIID(riid, &IID_IDropTarget))
1823 WARN("IDropTarget not implemented\n");
1826 else if(IsEqualIID(riid, &IID_IContextMenu))
1828 WARN("IContextMenu not implemented\n");
1831 else if(IsEqualIID(riid, &IID_IShellView))
1833 pShellView = IShellView_Constructor((IShellFolder*)iface);
1836 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1837 IShellView_Release(pShellView);
1841 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1845 /**************************************************************************
1846 * ISF_Desktop_fnGetAttributesOf
1848 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1849 IShellFolder2 * iface,
1851 LPCITEMIDLIST *apidl,
1854 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1858 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1860 if ( (!cidl) || (!apidl) || (!rgfInOut))
1861 return E_INVALIDARG;
1863 while (cidl > 0 && *apidl)
1866 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1871 TRACE("-- result=0x%08lx\n",*rgfInOut);
1876 /**************************************************************************
1877 * ISF_Desktop_fnGetDisplayNameOf
1880 * special case: pidl = null gives desktop-name back
1882 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1883 IShellFolder2 * iface,
1888 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1890 CHAR szPath[MAX_PATH]= "";
1892 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1895 if(!strRet) return E_INVALIDARG;
1899 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1901 else if ( _ILIsPidlSimple(pidl) )
1903 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1907 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1908 return E_OUTOFMEMORY;
1910 strRet->uType = STRRET_CSTRA;
1911 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1914 TRACE("-- (%p)->(%s)\n", This, szPath);
1918 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1919 IShellFolder2 * iface,
1922 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1923 FIXME("(%p)\n",This);
1926 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1927 IShellFolder2 * iface,
1928 IEnumExtraSearch **ppenum)
1930 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1931 FIXME("(%p)\n",This);
1934 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1935 IShellFolder2 * iface,
1940 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1942 TRACE("(%p)\n",This);
1944 if (pSort) *pSort = 0;
1945 if (pDisplay) *pDisplay = 0;
1949 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1950 IShellFolder2 * iface,
1954 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1956 TRACE("(%p)\n",This);
1958 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1960 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1964 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1965 IShellFolder2 * iface,
1967 const SHCOLUMNID *pscid,
1970 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1971 FIXME("(%p)\n",This);
1975 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
1976 IShellFolder2 * iface,
1981 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1982 HRESULT hr = E_FAIL;;
1984 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1986 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1990 psd->fmt = DesktopSFHeader[iColumn].fmt;
1991 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
1992 psd->str.uType = STRRET_CSTRA;
1993 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1998 /* the data from the pidl */
2002 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2005 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2008 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2011 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2013 case 4: /* attributes */
2014 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2018 psd->str.uType = STRRET_CSTRA;
2023 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2024 IShellFolder2 * iface,
2028 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2029 FIXME("(%p)\n",This);
2033 static ICOM_VTABLE(IShellFolder2) sfdvt =
2035 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2036 ISF_Desktop_fnQueryInterface,
2037 IShellFolder_fnAddRef,
2038 IShellFolder_fnRelease,
2039 ISF_Desktop_fnParseDisplayName,
2040 ISF_Desktop_fnEnumObjects,
2041 ISF_Desktop_fnBindToObject,
2042 IShellFolder_fnBindToStorage,
2043 IShellFolder_fnCompareIDs,
2044 ISF_Desktop_fnCreateViewObject,
2045 ISF_Desktop_fnGetAttributesOf,
2046 IShellFolder_fnGetUIObjectOf,
2047 ISF_Desktop_fnGetDisplayNameOf,
2048 IShellFolder_fnSetNameOf,
2051 ISF_Desktop_fnGetDefaultSearchGUID,
2052 ISF_Desktop_fnEnumSearches,
2053 ISF_Desktop_fnGetDefaultColumn,
2054 ISF_Desktop_fnGetDefaultColumnState,
2055 ISF_Desktop_fnGetDetailsEx,
2056 ISF_Desktop_fnGetDetailsOf,
2057 ISF_Desktop_fnMapNameToSCID
2061 /***********************************************************************
2062 * IShellFolder [MyComputer] implementation
2065 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2067 static shvheader MyComputerSFHeader [] =
2069 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2070 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2071 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2072 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2074 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2076 /**************************************************************************
2077 * ISF_MyComputer_Constructor
2079 static IShellFolder * ISF_MyComputer_Constructor(void)
2081 IGenericSFImpl * sf;
2083 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2086 ICOM_VTBL(sf)=&unkvt;
2087 sf->lpvtblShellFolder=&sfmcvt;
2088 sf->lpvtblPersistFolder2 = &psfvt;
2089 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2090 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2091 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2096 return _IShellFolder_(sf);
2099 /**************************************************************************
2100 * ISF_MyComputer_fnParseDisplayName
2102 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2103 IShellFolder2 * iface,
2106 LPOLESTR lpszDisplayName,
2108 LPITEMIDLIST *ppidl,
2109 DWORD *pdwAttributes)
2111 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2113 HRESULT hr = E_OUTOFMEMORY;
2114 LPCWSTR szNext=NULL;
2115 WCHAR szElement[MAX_PATH];
2116 CHAR szTempA[MAX_PATH];
2117 LPITEMIDLIST pidlTemp;
2119 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2120 This,hwndOwner,pbcReserved,lpszDisplayName,
2121 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2124 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2126 /* do we have an absolute path name ? */
2127 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2128 lpszDisplayName[2] == (WCHAR)'\\')
2130 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2131 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
2132 pidlTemp = _ILCreateDrive(szTempA);
2134 if (szNext && *szNext)
2136 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2140 if (pdwAttributes && *pdwAttributes)
2142 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2149 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2154 /**************************************************************************
2155 * ISF_MyComputer_fnEnumObjects
2157 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2158 IShellFolder2 * iface,
2161 LPENUMIDLIST* ppEnumIDList)
2163 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2165 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2167 *ppEnumIDList = NULL;
2168 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2170 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2172 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2177 /**************************************************************************
2178 * ISF_MyComputer_fnBindToObject
2180 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2181 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2183 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2185 IShellFolder *pShellFolder, *pSubFolder;
2186 LPITEMIDLIST pidltemp;
2188 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2189 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2191 if(!pidl || !ppvOut) return E_INVALIDARG;
2195 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2197 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2204 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2206 pidltemp = ILCloneFirst(pidl);
2207 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2211 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2213 *ppvOut = pShellFolder;
2215 else /* go deeper */
2217 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
2218 IShellFolder_Release(pShellFolder);
2219 *ppvOut = pSubFolder;
2222 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
2227 /**************************************************************************
2228 * ISF_MyComputer_fnCreateViewObject
2230 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2231 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2233 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2235 LPSHELLVIEW pShellView;
2236 HRESULT hr = E_INVALIDARG;
2238 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2244 if(IsEqualIID(riid, &IID_IDropTarget))
2246 WARN("IDropTarget not implemented\n");
2249 else if(IsEqualIID(riid, &IID_IContextMenu))
2251 WARN("IContextMenu not implemented\n");
2254 else if(IsEqualIID(riid, &IID_IShellView))
2256 pShellView = IShellView_Constructor((IShellFolder*)iface);
2259 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2260 IShellView_Release(pShellView);
2264 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2268 /**************************************************************************
2269 * ISF_MyComputer_fnGetAttributesOf
2271 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2272 IShellFolder2 * iface,
2274 LPCITEMIDLIST *apidl,
2277 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2281 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2283 if ( (!cidl) || (!apidl) || (!rgfInOut))
2284 return E_INVALIDARG;
2286 while (cidl > 0 && *apidl)
2289 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2294 TRACE("-- result=0x%08lx\n",*rgfInOut);
2298 /**************************************************************************
2299 * ISF_MyComputer_fnGetDisplayNameOf
2302 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2303 * SHGDN_INFOLDER makes no sense.
2305 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2306 IShellFolder2 * iface,
2311 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2313 char szPath[MAX_PATH], szDrive[18];
2317 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2320 if(!strRet) return E_INVALIDARG;
2322 szPath[0]=0x00; szDrive[0]=0x00;
2325 bSimplePidl = _ILIsPidlSimple(pidl);
2327 if (_ILIsSpecialFolder(pidl))
2329 /* take names of special folders only if its only this folder */
2332 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2337 if (!_ILIsDrive(pidl))
2339 ERR("Wrong pidl type\n");
2340 return E_INVALIDARG;
2343 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2345 /* long view "lw_name (C:)" */
2346 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2348 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2350 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2351 strcat (szDrive," (");
2352 strncat (szDrive, szPath, 2);
2353 strcat (szDrive,")");
2354 strcpy (szPath, szDrive);
2358 if (!bSimplePidl) /* go deeper if needed */
2360 PathAddBackslashA(szPath);
2361 len = strlen(szPath);
2363 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2364 return E_OUTOFMEMORY;
2366 strRet->uType = STRRET_CSTRA;
2367 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2370 TRACE("-- (%p)->(%s)\n", This, szPath);
2374 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2375 IShellFolder2 * iface,
2378 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2379 FIXME("(%p)\n",This);
2382 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2383 IShellFolder2 * iface,
2384 IEnumExtraSearch **ppenum)
2386 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2387 FIXME("(%p)\n",This);
2390 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2391 IShellFolder2 * iface,
2396 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2398 TRACE("(%p)\n",This);
2400 if (pSort) *pSort = 0;
2401 if (pDisplay) *pDisplay = 0;
2405 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2406 IShellFolder2 * iface,
2410 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2412 TRACE("(%p)\n",This);
2414 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2416 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2420 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2421 IShellFolder2 * iface,
2423 const SHCOLUMNID *pscid,
2426 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2427 FIXME("(%p)\n",This);
2432 /* fixme: drive size >4GB is rolling over */
2433 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2434 IShellFolder2 * iface,
2439 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2442 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2444 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2448 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2449 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2450 psd->str.uType = STRRET_CSTRA;
2451 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2456 char szPath[MAX_PATH];
2457 ULARGE_INTEGER ulBytes;
2459 psd->str.u.cStr[0] = 0x00;
2460 psd->str.uType = STRRET_CSTRA;
2464 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2467 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2469 case 2: /* total size */
2470 if (_ILIsDrive(pidl))
2472 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2473 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2474 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2477 case 3: /* free size */
2478 if (_ILIsDrive(pidl))
2480 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2481 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2482 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2491 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2492 IShellFolder2 * iface,
2496 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2497 FIXME("(%p)\n",This);
2501 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2503 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2504 IShellFolder_fnQueryInterface,
2505 IShellFolder_fnAddRef,
2506 IShellFolder_fnRelease,
2507 ISF_MyComputer_fnParseDisplayName,
2508 ISF_MyComputer_fnEnumObjects,
2509 ISF_MyComputer_fnBindToObject,
2510 IShellFolder_fnBindToStorage,
2511 IShellFolder_fnCompareIDs,
2512 ISF_MyComputer_fnCreateViewObject,
2513 ISF_MyComputer_fnGetAttributesOf,
2514 IShellFolder_fnGetUIObjectOf,
2515 ISF_MyComputer_fnGetDisplayNameOf,
2516 IShellFolder_fnSetNameOf,
2519 ISF_MyComputer_fnGetDefaultSearchGUID,
2520 ISF_MyComputer_fnEnumSearches,
2521 ISF_MyComputer_fnGetDefaultColumn,
2522 ISF_MyComputer_fnGetDefaultColumnState,
2523 ISF_MyComputer_fnGetDetailsEx,
2524 ISF_MyComputer_fnGetDetailsOf,
2525 ISF_MyComputer_fnMapNameToSCID
2529 /************************************************************************
2530 * ISFPersistFolder_QueryInterface (IUnknown)
2533 static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2534 IPersistFolder2 * iface,
2538 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2540 TRACE("(%p)\n", This);
2542 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2545 /************************************************************************
2546 * ISFPersistFolder_AddRef (IUnknown)
2549 static ULONG WINAPI ISFPersistFolder2_AddRef(
2550 IPersistFolder2 * iface)
2552 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2554 TRACE("(%p)\n", This);
2556 return IUnknown_AddRef(This->pUnkOuter);
2559 /************************************************************************
2560 * ISFPersistFolder_Release (IUnknown)
2563 static ULONG WINAPI ISFPersistFolder2_Release(
2564 IPersistFolder2 * iface)
2566 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2568 TRACE("(%p)\n", This);
2570 return IUnknown_Release(This->pUnkOuter);
2573 /************************************************************************
2574 * ISFPersistFolder_GetClassID (IPersist)
2576 static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2577 IPersistFolder2 * iface,
2580 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2582 TRACE("(%p)\n", This);
2584 if (!lpClassId) return E_POINTER;
2585 *lpClassId = *This->pclsid;
2590 /************************************************************************
2591 * ISFPersistFolder_Initialize (IPersistFolder)
2594 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2596 static HRESULT WINAPI ISFPersistFolder2_Initialize(
2597 IPersistFolder2 * iface,
2600 char sTemp[MAX_PATH];
2601 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2603 TRACE("(%p)->(%p)\n", This, pidl);
2605 /* free the old stuff */
2608 SHFree(This->absPidl);
2609 This->absPidl = NULL;
2613 SHFree(This->sMyPath);
2614 This->sMyPath = NULL;
2618 This->absPidl = ILClone(pidl);
2621 if (SHGetPathFromIDListA(pidl, sTemp))
2623 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2624 strcpy(This->sMyPath, sTemp);
2627 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2632 /**************************************************************************
2633 * IPersistFolder2_fnGetCurFolder
2635 static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2636 IPersistFolder2 * iface,
2637 LPITEMIDLIST * pidl)
2639 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2641 TRACE("(%p)->(%p)\n",This, pidl);
2643 if (!pidl) return E_POINTER;
2645 *pidl = ILClone(This->absPidl);
2650 static ICOM_VTABLE(IPersistFolder2) psfvt =
2652 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2653 ISFPersistFolder2_QueryInterface,
2654 ISFPersistFolder2_AddRef,
2655 ISFPersistFolder2_Release,
2656 ISFPersistFolder2_GetClassID,
2657 ISFPersistFolder2_Initialize,
2658 ISFPersistFolder2_fnGetCurFolder
2661 /****************************************************************************
2662 * ISFDropTarget implementation
2664 static BOOL ISFDropTarget_QueryDrop(
2669 DWORD dwEffect = *pdwEffect;
2671 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2673 *pdwEffect = DROPEFFECT_NONE;
2675 if (This->fAcceptFmt)
2676 { /* Does our interpretation of the keystate ... */
2677 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2679 /* ... matches the desired effect ? */
2680 if (dwEffect & *pdwEffect)
2688 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2693 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2695 TRACE("(%p)\n", This);
2697 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2700 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2702 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2704 TRACE("(%p)\n", This);
2706 return IUnknown_AddRef(This->pUnkOuter);
2709 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2711 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2713 TRACE("(%p)\n", This);
2715 return IUnknown_Release(This->pUnkOuter);
2718 static HRESULT WINAPI ISFDropTarget_DragEnter(
2720 IDataObject *pDataObject,
2727 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2729 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2731 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2733 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2735 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2740 static HRESULT WINAPI ISFDropTarget_DragOver(
2746 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2748 TRACE("(%p)\n",This);
2750 if(!pdwEffect) return E_INVALIDARG;
2752 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2757 static HRESULT WINAPI ISFDropTarget_DragLeave(
2760 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2762 TRACE("(%p)\n",This);
2764 This->fAcceptFmt = FALSE;
2769 static HRESULT WINAPI ISFDropTarget_Drop(
2771 IDataObject* pDataObject,
2776 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2778 FIXME("(%p) object dropped\n",This);
2783 static struct ICOM_VTABLE(IDropTarget) dtvt =
2785 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2786 ISFDropTarget_QueryInterface,
2787 ISFDropTarget_AddRef,
2788 ISFDropTarget_Release,
2789 ISFDropTarget_DragEnter,
2790 ISFDropTarget_DragOver,
2791 ISFDropTarget_DragLeave,