4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
7 * IShellFolder2 and related interfaces
23 #include "wine/obj_base.h"
24 #include "wine/obj_dragdrop.h"
25 #include "wine/obj_shellfolder.h"
26 #include "undocshell.h"
27 #include "shell32_main.h"
30 #include "shellfolder.h"
31 #include "debugtools.h"
33 DEFAULT_DEBUG_CHANNEL(shell);
36 /***************************************************************************
37 * debughelper: print out the return adress
38 * helps especially to track down unbalanced AddRef/Release
43 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
57 /***************************************************************************
58 * GetNextElement (internal function)
60 * gets a part of a string till the first backslash
63 * pszNext [IN] string to get the element from
64 * pszOut [IN] pointer to buffer whitch receives string
65 * dwOut [IN] length of pszOut
68 * LPSTR pointer to first, not yet parsed char
71 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
72 { LPCWSTR pszTail = pszNext;
74 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
78 if(!pszNext || !*pszNext)
81 while(*pszTail && (*pszTail != (WCHAR)'\\'))
84 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
85 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
92 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
96 static HRESULT SHELL32_ParseNextElement(
99 LPITEMIDLIST * pidlInOut,
102 DWORD *pdwAttributes)
104 HRESULT hr = E_OUTOFMEMORY;
105 LPITEMIDLIST pidlOut, pidlTemp = NULL;
106 IShellFolder *psfChild;
108 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
111 /* get the shellfolder for the child pidl and let it analyse further */
112 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
116 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
117 IShellFolder_Release(psfChild);
119 pidlTemp = ILCombine(*pidlInOut, pidlOut);
126 *pidlInOut = pidlTemp;
128 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
132 /***********************************************************************
133 * SHELL32_CoCreateInitSF
135 * creates a initialized shell folder
137 static HRESULT SHELL32_CoCreateInitSF (
138 LPITEMIDLIST pidlRoot,
139 LPITEMIDLIST pidlChild,
145 LPITEMIDLIST absPidl;
146 IShellFolder2 *pShellFolder;
147 IPersistFolder *pPersistFolder;
149 TRACE("%p %p\n", pidlRoot, pidlChild);
153 /* we have to ask first for IPersistFolder, some special folders are expecting this */
154 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
157 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
160 absPidl = ILCombine (pidlRoot, pidlChild);
161 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
162 IPersistFolder_Release(pPersistFolder);
164 *ppvOut = pShellFolder;
168 TRACE("-- ret=0x%08lx\n", hr);
172 static HRESULT SHELL32_GetDisplayNameOfChild(
179 LPITEMIDLIST pidlFirst, pidlNext;
180 IShellFolder2 * psfChild;
181 HRESULT hr = E_OUTOFMEMORY;
184 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
187 if ((pidlFirst = ILCloneFirst(pidl)))
189 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
192 pidlNext = ILGetNext(pidl);
194 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
197 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
200 IShellFolder_Release(psfChild);
205 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
210 /***********************************************************************
211 * SHELL32_GetItemAttributes
215 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
216 * file: 0x40000177 FILESYSTEM
217 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
218 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
219 * (seems to be default for shell extensions if no registry entry exists)
221 * This functions does not set flags!! It only resets flags when nessesary.
223 static HRESULT SHELL32_GetItemAttributes(
226 LPDWORD pdwAttributes)
231 TRACE("0x%08lx\n", *pdwAttributes);
233 if (*pdwAttributes & (0xcff3fe88))
234 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
235 *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
237 if (_ILIsDrive(pidl))
239 *pdwAttributes &= 0xf0000144;
241 else if ((clsid=_ILGetGUIDPointer(pidl)))
243 if (HCR_GetFolderAttributes(clsid, &dwAttributes))
245 *pdwAttributes &= dwAttributes;
249 *pdwAttributes &= 0xb0000154;
252 else if (_ILGetDataPointer(pidl))
254 dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
255 *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
257 if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
258 *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
260 if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
261 *pdwAttributes &= ~SFGAO_HIDDEN;
263 if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
264 *pdwAttributes &= ~SFGAO_READONLY;
268 *pdwAttributes &= 0xb0000154;
270 TRACE("-- 0x%08lx\n", *pdwAttributes);
274 /***********************************************************************
275 * IShellFolder implementation
280 ICOM_VFIELD(IUnknown);
282 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
283 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
284 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
285 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
287 IUnknown *pUnkOuter; /* used for aggregation */
292 LPITEMIDLIST absPidl; /* complete pidl */
294 UINT cfShellIDList; /* clipboardformat for IDropTarget */
295 BOOL fAcceptFmt; /* flag for pending Drop */
298 static struct ICOM_VTABLE(IUnknown) unkvt;
299 static struct ICOM_VTABLE(IShellFolder2) sfvt;
300 static struct ICOM_VTABLE(IPersistFolder2) psfvt;
301 static struct ICOM_VTABLE(IDropTarget) dtvt;
302 static struct ICOM_VTABLE(ISFHelper) shvt;
304 static IShellFolder * ISF_MyComputer_Constructor(void);
306 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
307 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
309 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
310 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
312 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
313 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
315 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
316 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
318 converts This to a interface pointer
320 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
321 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
322 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
323 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
324 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
325 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
326 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
327 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
328 /**************************************************************************
329 * registers clipboardformat once
331 static void SF_RegisterClipFmt (IGenericSFImpl * This)
333 TRACE("(%p)\n", This);
335 if (!This->cfShellIDList)
337 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
341 /**************************************************************************
342 * we need a separate IUnknown to handle aggregation
345 static HRESULT WINAPI IUnknown_fnQueryInterface(
350 ICOM_THIS(IGenericSFImpl, iface);
353 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
357 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
358 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
359 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
360 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
361 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
362 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
363 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
364 else if(IsEqualIID(riid, &IID_IDropTarget))
366 *ppvObj = _IDropTarget_(This);
367 SF_RegisterClipFmt(This);
372 IUnknown_AddRef((IUnknown*)(*ppvObj));
373 TRACE("-- Interface = %p\n", *ppvObj);
376 TRACE("-- Interface: E_NOINTERFACE\n");
377 return E_NOINTERFACE;
380 static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
382 ICOM_THIS(IGenericSFImpl, iface);
385 TRACE("(%p)->(count=%lu)\n",This,This->ref);
388 return ++(This->ref);
391 static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
393 ICOM_THIS(IGenericSFImpl, iface);
396 TRACE("(%p)->(count=%lu)\n",This,This->ref);
401 TRACE("-- destroying IShellFolder(%p)\n",This);
403 if (pdesktopfolder == _IShellFolder_(This))
406 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
408 if(This->absPidl) SHFree(This->absPidl);
409 if(This->sMyPath) SHFree(This->sMyPath);
410 HeapFree(GetProcessHeap(),0,This);
416 static ICOM_VTABLE(IUnknown) unkvt =
418 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
419 IUnknown_fnQueryInterface,
424 static shvheader GenericSFHeader [] =
426 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
427 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
428 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
429 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
430 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
432 #define GENERICSHELLVIEWCOLUMNS 5
434 /**************************************************************************
435 * IShellFolder_Constructor
438 * creating undocumented ShellFS_Folder as part of an aggregation
439 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
442 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
444 HRESULT IFSFolder_Constructor(
445 IUnknown * pUnkOuter,
452 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
454 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
456 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
460 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
464 ICOM_VTBL(sf)=&unkvt;
465 sf->lpvtblShellFolder=&sfvt;
466 sf->lpvtblPersistFolder2=&psfvt;
467 sf->lpvtblDropTarget=&dtvt;
468 sf->lpvtblSFHelper=&shvt;
470 sf->pclsid = (CLSID*)&CLSID_SFFile;
471 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
472 *ppv = _IUnknown_(sf);
483 /**************************************************************************
484 * IShellFolder_Constructor
487 * THIS points to the parent folder
490 IShellFolder * IShellFolder_Constructor(
491 IShellFolder2 * iface,
497 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
499 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
502 ICOM_VTBL(sf)=&unkvt;
503 sf->lpvtblShellFolder=&sfvt;
504 sf->lpvtblPersistFolder2=&psfvt;
505 sf->lpvtblDropTarget=&dtvt;
506 sf->lpvtblSFHelper=&shvt;
508 sf->pclsid = (CLSID*)&CLSID_SFFile;
509 sf->pUnkOuter = _IUnknown_(sf);
511 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
514 if(pidl && iface) /* do we have a pidl? */
518 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
520 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
522 if(This->sMyPath) /* get the size of the parents path */
524 dwSize += strlen(This->sMyPath) ;
525 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
528 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
529 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
531 if(!sf->sMyPath) return NULL;
534 if(This->sMyPath) /* if the parent has a path, get it*/
536 strcpy(sf->sMyPath, This->sMyPath);
537 PathAddBackslashA (sf->sMyPath);
540 len = strlen(sf->sMyPath);
541 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
544 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
550 return _IShellFolder_(sf);
553 /**************************************************************************
554 * IShellFolder_fnQueryInterface
557 * REFIID riid [in ] Requested InterfaceID
558 * LPVOID* ppvObject [out] Interface* to hold the result
560 static HRESULT WINAPI IShellFolder_fnQueryInterface(
561 IShellFolder2 * iface,
565 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
568 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
570 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
573 /**************************************************************************
574 * IShellFolder_AddRef
577 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
579 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
582 TRACE("(%p)->(count=%lu)\n",This,This->ref);
584 return IUnknown_AddRef(This->pUnkOuter);
587 /**************************************************************************
588 * IShellFolder_fnRelease
590 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
592 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
595 TRACE("(%p)->(count=%lu)\n",This,This->ref);
597 return IUnknown_Release(This->pUnkOuter);
600 /**************************************************************************
601 * IShellFolder_fnParseDisplayName
603 * HWND hwndOwner, //[in ] Parent window for any message's
604 * LPBC pbc, //[in ] reserved
605 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
606 * ULONG* pchEaten, //[out] (unicode) characters processed
607 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
608 * ULONG* pdwAttributes //[out] items attributes
611 * every folder tries to parse only its own (the leftmost) pidl and creates a
612 * subfolder to evaluate the remaining parts
613 * now we can parse into namespaces implemented by shell extensions
615 * behaviour on win98: lpszDisplayName=NULL -> chrash
616 * lpszDisplayName="" -> returns mycoputer-pidl
619 * pdwAttributes: not set
620 * pchEaten: not set like in windows
622 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
623 IShellFolder2 * iface,
626 LPOLESTR lpszDisplayName,
629 DWORD *pdwAttributes)
631 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
633 HRESULT hr = E_OUTOFMEMORY;
635 WCHAR szElement[MAX_PATH];
636 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
637 LPITEMIDLIST pidlTemp=NULL;
639 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
640 This,hwndOwner,pbcReserved,lpszDisplayName,
641 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
643 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
645 if (pchEaten) *pchEaten = 0; /* strange but like the original */
647 if (*lpszDisplayName)
649 /* get the next element */
650 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
652 /* build the full pathname to the element */
653 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
654 strcpy(szPath, This->sMyPath);
655 PathAddBackslashA(szPath);
656 strcat(szPath, szTempA);
659 pidlTemp = SHSimpleIDListFromPathA(szPath);
663 /* try to analyse the next element */
664 if (szNext && *szNext)
666 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
670 if (pdwAttributes && *pdwAttributes)
672 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
673 /* WIN32_FIND_DATAA fd;
674 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
675 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
676 *pdwAttributes &= ~SFGAO_FOLDER;
677 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
678 *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;
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;
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);
763 else if(_ILIsFolder(pidl))
765 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
766 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
771 ERR("can't bind to a file\n");
775 if (_ILIsPidlSimple(pidl))
777 if(IsEqualIID(riid, &IID_IShellFolder))
779 *ppvOut = pShellFolder;
784 hr = IShellFolder_QueryInterface(pShellFolder, riid, ppvOut);
785 IShellFolder_Release(pShellFolder);
790 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
791 riid, (LPVOID)&pSubFolder);
792 IShellFolder_Release(pShellFolder);
793 *ppvOut = pSubFolder;
796 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
801 /**************************************************************************
802 * IShellFolder_fnBindToStorage
804 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
805 * LPBC pbc, //[in ] reserved
806 * REFIID riid, //[in ] Initial storage interface
807 * LPVOID* ppvObject //[out] Interface* returned
809 static HRESULT WINAPI IShellFolder_fnBindToStorage(
810 IShellFolder2 * iface,
816 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
818 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
819 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
825 /**************************************************************************
826 * IShellFolder_fnCompareIDs
829 * LPARAM lParam, //[in ] Column?
830 * LPCITEMIDLIST pidl1, //[in ] simple pidl
831 * LPCITEMIDLIST pidl2) //[in ] simple pidl
834 * Special case - If one of the items is a Path and the other is a File,
835 * always make the Path come before the File.
838 * use SCODE_CODE() on the return value to get the result
841 static HRESULT WINAPI IShellFolder_fnCompareIDs(
842 IShellFolder2 * iface,
847 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
849 CHAR szTemp1[MAX_PATH];
850 CHAR szTemp2[MAX_PATH];
853 HRESULT hr = E_OUTOFMEMORY;
854 LPCITEMIDLIST pidlTemp;
857 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
861 if (!pidl1 && !pidl2)
863 hr = ResultFromShort(0);
867 hr = ResultFromShort(-1);
871 hr = ResultFromShort(1);
876 pd1 = _ILGetDataPointer(pidl1);
877 pd2 = _ILGetDataPointer(pidl2);
879 /* compate the types. sort order is the PT_* constant */
880 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
881 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
885 hr = ResultFromShort(pt1-pt2);
887 else /* same type of pidl */
889 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
890 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
891 nReturn = strcasecmp(szTemp1, szTemp2);
893 if (nReturn == 0) /* first pidl different ? */
895 pidl1 = ILGetNext(pidl1);
897 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
899 pidlTemp = ILCloneFirst(pidl1);
900 pidl2 = ILGetNext(pidl2);
902 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
905 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
906 IShellFolder_Release(psf);
907 hr = ResultFromShort(nReturn);
911 else /* no deeper on #1 */
913 pidl2 = ILGetNext(pidl2);
914 if (pidl2 && pidl2->mkid.cb) /* go deeper on #2 ? */
915 hr = ResultFromShort(-1); /* two different */
917 hr = ResultFromShort(nReturn); /* two equal simple pidls */
922 hr = ResultFromShort(nReturn); /* two different simple pidls */
927 TRACE("-- res=0x%08lx\n", hr);
931 /**************************************************************************
932 * IShellFolder_fnCreateViewObject
934 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
935 IShellFolder2 * iface,
940 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
942 LPSHELLVIEW pShellView;
943 HRESULT hr = E_INVALIDARG;
945 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
951 if(IsEqualIID(riid, &IID_IDropTarget))
953 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
955 else if(IsEqualIID(riid, &IID_IContextMenu))
957 FIXME("IContextMenu not implemented\n");
960 else if(IsEqualIID(riid, &IID_IShellView))
962 pShellView = IShellView_Constructor((IShellFolder*)iface);
965 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
966 IShellView_Release(pShellView);
970 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
974 /**************************************************************************
975 * IShellFolder_fnGetAttributesOf
978 * UINT cidl, //[in ] num elements in pidl array
979 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
980 * ULONG* rgfInOut) //[out] result array
983 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
984 IShellFolder2 * iface,
986 LPCITEMIDLIST *apidl,
989 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
993 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
995 if ( (!cidl) || (!apidl) || (!rgfInOut))
998 while (cidl > 0 && *apidl)
1001 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1006 TRACE("-- result=0x%08lx\n",*rgfInOut);
1010 /**************************************************************************
1011 * IShellFolder_fnGetUIObjectOf
1014 * HWND hwndOwner, //[in ] Parent window for any output
1015 * UINT cidl, //[in ] array size
1016 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1017 * REFIID riid, //[in ] Requested Interface
1018 * UINT* prgfInOut, //[ ] reserved
1019 * LPVOID* ppvObject) //[out] Resulting Interface
1022 * This function gets asked to return "view objects" for one or more (multiple select)
1024 * The viewobject typically is an COM object with one of the following interfaces:
1025 * IExtractIcon,IDataObject,IContextMenu
1026 * In order to support icon positions in the default Listview your DataObject
1027 * must implement the SetData method (in addition to GetData :) - the shell passes
1028 * a barely documented "Icon positions" structure to SetData when the drag starts,
1029 * and GetData's it if the drop is in another explorer window that needs the positions.
1031 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1032 IShellFolder2 * iface,
1035 LPCITEMIDLIST * apidl,
1040 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1043 IUnknown* pObj = NULL;
1044 HRESULT hr = E_INVALIDARG;
1046 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1047 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1053 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1055 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1058 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1060 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1063 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1065 pidl = ILCombine(This->absPidl,apidl[0]);
1066 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1070 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1072 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1084 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1088 /**************************************************************************
1089 * IShellFolder_fnGetDisplayNameOf
1090 * Retrieves the display name for the specified file object or subfolder
1093 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1094 * DWORD dwFlags, //[in ] SHGNO formatting flags
1095 * LPSTRRET lpName) //[out] Returned display name
1098 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1100 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1101 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1103 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1104 IShellFolder2 * iface,
1109 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1111 CHAR szPath[MAX_PATH]= "";
1115 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1118 if(!pidl || !strRet) return E_INVALIDARG;
1120 bSimplePidl = _ILIsPidlSimple(pidl);
1122 /* take names of special folders only if its only this folder */
1123 if (_ILIsSpecialFolder(pidl))
1127 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1132 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1134 strcpy (szPath, This->sMyPath); /* get path to root*/
1135 PathAddBackslashA(szPath);
1136 len = strlen(szPath);
1138 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1141 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1143 PathAddBackslashA(szPath);
1144 len = strlen(szPath);
1146 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1147 return E_OUTOFMEMORY;
1149 strRet->uType = STRRET_CSTRA;
1150 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1152 TRACE("-- (%p)->(%s)\n", This, szPath);
1156 /**************************************************************************
1157 * IShellFolder_fnSetNameOf
1158 * Changes the name of a file object or subfolder, possibly changing its item
1159 * identifier in the process.
1162 * HWND hwndOwner, //[in ] Owner window for output
1163 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1164 * LPCOLESTR lpszName, //[in ] the items new display name
1165 * DWORD dwFlags, //[in ] SHGNO formatting flags
1166 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1168 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1169 IShellFolder2 * iface,
1171 LPCITEMIDLIST pidl, /*simple pidl*/
1174 LPITEMIDLIST *pPidlOut)
1176 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1177 char szSrc[MAX_PATH], szDest[MAX_PATH];
1179 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1181 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1182 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1184 /* build source path */
1185 if (dwFlags & SHGDN_INFOLDER)
1187 strcpy(szSrc, This->sMyPath);
1188 PathAddBackslashA(szSrc);
1189 len = strlen (szSrc);
1190 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1194 SHGetPathFromIDListA(pidl, szSrc);
1197 /* build destination path */
1198 strcpy(szDest, This->sMyPath);
1199 PathAddBackslashA(szDest);
1200 len = strlen (szDest);
1201 WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
1202 szDest[MAX_PATH-1] = 0;
1203 TRACE("src=%s dest=%s\n", szSrc, szDest);
1204 if ( MoveFileA(szSrc, szDest) )
1206 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1207 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1213 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1214 IShellFolder2 * iface,
1217 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1218 FIXME("(%p)\n",This);
1221 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1222 IShellFolder2 * iface,
1223 IEnumExtraSearch **ppenum)
1225 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1226 FIXME("(%p)\n",This);
1229 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1230 IShellFolder2 * iface,
1235 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1237 TRACE("(%p)\n",This);
1239 if (pSort) *pSort = 0;
1240 if (pDisplay) *pDisplay = 0;
1244 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1245 IShellFolder2 * iface,
1249 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1251 TRACE("(%p)\n",This);
1253 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1255 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1259 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1260 IShellFolder2 * iface,
1262 const SHCOLUMNID *pscid,
1265 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1266 FIXME("(%p)\n",This);
1270 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1271 IShellFolder2 * iface,
1276 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1277 HRESULT hr = E_FAIL;
1279 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1281 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1285 /* the header titles */
1286 psd->fmt = GenericSFHeader[iColumn].fmt;
1287 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1288 psd->str.uType = STRRET_CSTRA;
1289 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1294 /* the data from the pidl */
1298 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1301 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1304 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1307 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1309 case 4: /* attributes */
1310 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1314 psd->str.uType = STRRET_CSTRA;
1319 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1320 IShellFolder2 * iface,
1324 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1325 FIXME("(%p)\n",This);
1329 static ICOM_VTABLE(IShellFolder2) sfvt =
1331 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1332 IShellFolder_fnQueryInterface,
1333 IShellFolder_fnAddRef,
1334 IShellFolder_fnRelease,
1335 IShellFolder_fnParseDisplayName,
1336 IShellFolder_fnEnumObjects,
1337 IShellFolder_fnBindToObject,
1338 IShellFolder_fnBindToStorage,
1339 IShellFolder_fnCompareIDs,
1340 IShellFolder_fnCreateViewObject,
1341 IShellFolder_fnGetAttributesOf,
1342 IShellFolder_fnGetUIObjectOf,
1343 IShellFolder_fnGetDisplayNameOf,
1344 IShellFolder_fnSetNameOf,
1347 IShellFolder_fnGetDefaultSearchGUID,
1348 IShellFolder_fnEnumSearches,
1349 IShellFolder_fnGetDefaultColumn,
1350 IShellFolder_fnGetDefaultColumnState,
1351 IShellFolder_fnGetDetailsEx,
1352 IShellFolder_fnGetDetailsOf,
1353 IShellFolder_fnMapNameToSCID
1356 /****************************************************************************
1357 * ISFHelper for IShellFolder implementation
1360 static HRESULT WINAPI ISFHelper_fnQueryInterface(
1365 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1367 TRACE("(%p)\n", This);
1369 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1372 static ULONG WINAPI ISFHelper_fnAddRef(
1375 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1377 TRACE("(%p)\n", This);
1379 return IUnknown_AddRef(This->pUnkOuter);
1382 static ULONG WINAPI ISFHelper_fnRelease(
1385 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1387 TRACE("(%p)\n", This);
1389 return IUnknown_Release(This->pUnkOuter);
1393 /****************************************************************************
1394 * ISFHelper_fnAddFolder
1396 * creates a unique folder name
1399 static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1404 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1405 IEnumIDList * penum;
1407 char szText[MAX_PATH];
1408 char * szNewFolder = "New Folder";
1410 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1412 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1414 strcpy(lpName, szNewFolder);
1416 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1423 next: IEnumIDList_Reset(penum);
1424 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1426 _ILSimpleGetText(pidl, szText, MAX_PATH);
1427 if (0 == strcasecmp(szText, lpName))
1429 sprintf(lpName, "%s %d", szNewFolder, i++);
1439 IEnumIDList_Release(penum);
1444 /****************************************************************************
1445 * ISFHelper_fnAddFolder
1447 * adds a new folder.
1450 static HRESULT WINAPI ISFHelper_fnAddFolder(
1454 LPITEMIDLIST* ppidlOut)
1456 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1457 char lpstrNewDir[MAX_PATH];
1459 HRESULT hres = E_FAIL;
1461 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1463 strcpy(lpstrNewDir, This->sMyPath);
1464 PathAddBackslashA(lpstrNewDir);
1465 strcat(lpstrNewDir, lpName);
1467 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1471 LPITEMIDLIST pidl, pidlitem;
1473 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1475 pidl = ILCombine(This->absPidl, pidlitem);
1476 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1479 if (ppidlOut) *ppidlOut = pidlitem;
1484 char lpstrText[128+MAX_PATH];
1485 char lpstrTempText[128];
1486 char lpstrCaption[256];
1488 /* Cannot Create folder because of permissions */
1489 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1490 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1491 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1492 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1498 /****************************************************************************
1499 * ISFHelper_fnDeleteItems
1501 * deletes items in folder
1503 static HRESULT WINAPI ISFHelper_fnDeleteItems(
1506 LPCITEMIDLIST* apidl)
1508 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1510 char szPath[MAX_PATH];
1511 BOOL bConfirm = TRUE;
1513 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1515 /* deleting multiple items so give a slightly different warning */
1519 snprintf(tmp, sizeof(tmp), "%d", cidl);
1520 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM, tmp))
1525 for(i=0; i< cidl; i++)
1527 strcpy(szPath, This->sMyPath);
1528 PathAddBackslashA(szPath);
1529 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1531 if (_ILIsFolder(apidl[i]))
1534 TRACE("delete %s\n", szPath);
1535 if (! SHELL_DeleteDirectoryA(szPath, bConfirm))
1537 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1540 pidl = ILCombine(This->absPidl, apidl[i]);
1541 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1544 else if (_ILIsValue(apidl[i]))
1548 TRACE("delete %s\n", szPath);
1549 if (! SHELL_DeleteFileA(szPath, bConfirm))
1551 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1554 pidl = ILCombine(This->absPidl, apidl[i]);
1555 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1563 /****************************************************************************
1564 * ISFHelper_fnCopyItems
1566 * copies items to this folder
1568 static HRESULT WINAPI ISFHelper_fnCopyItems(
1570 IShellFolder* pSFFrom,
1572 LPCITEMIDLIST *apidl)
1575 IPersistFolder2 * ppf2=NULL;
1576 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1577 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1579 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1581 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1585 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1587 for (i=0; i<cidl; i++)
1589 SHGetPathFromIDListA(pidl, szSrcPath);
1590 PathAddBackslashA(szSrcPath);
1591 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1593 strcpy(szDstPath, This->sMyPath);
1594 PathAddBackslashA(szDstPath);
1595 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1596 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1600 IPersistFolder2_Release(ppf2);
1605 static ICOM_VTABLE(ISFHelper) shvt =
1607 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1608 ISFHelper_fnQueryInterface,
1610 ISFHelper_fnRelease,
1611 ISFHelper_fnGetUniqueName,
1612 ISFHelper_fnAddFolder,
1613 ISFHelper_fnDeleteItems,
1614 ISFHelper_fnCopyItems,
1617 /***********************************************************************
1618 * [Desktopfolder] IShellFolder implementation
1620 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1622 static shvheader DesktopSFHeader [] =
1624 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1625 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1626 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1627 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1628 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1630 #define DESKTOPSHELLVIEWCOLUMNS 5
1632 /**************************************************************************
1633 * ISF_Desktop_Constructor
1636 IShellFolder * ISF_Desktop_Constructor()
1638 IGenericSFImpl * sf;
1640 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1642 ICOM_VTBL(sf)=&unkvt;
1643 sf->lpvtblShellFolder=&sfdvt;
1644 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1645 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1650 return _IShellFolder_(sf);
1653 /**************************************************************************
1654 * ISF_Desktop_fnQueryInterface
1656 * NOTES supports not IPersist/IPersistFolder
1658 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1659 IShellFolder2 * iface,
1663 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1665 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1669 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1671 *ppvObj = _IUnknown_(This);
1673 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1675 *ppvObj = _IShellFolder_(This);
1677 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1679 *ppvObj = _IShellFolder_(This);
1684 IUnknown_AddRef((IUnknown*)(*ppvObj));
1685 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1688 TRACE("-- Interface: E_NOINTERFACE\n");
1689 return E_NOINTERFACE;
1692 /**************************************************************************
1693 * ISF_Desktop_fnParseDisplayName
1696 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1699 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1700 IShellFolder2 * iface,
1703 LPOLESTR lpszDisplayName,
1705 LPITEMIDLIST *ppidl,
1706 DWORD *pdwAttributes)
1708 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1710 LPCWSTR szNext=NULL;
1711 LPITEMIDLIST pidlTemp=NULL;
1712 HRESULT hr=E_OUTOFMEMORY;
1714 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1715 This,hwndOwner,pbcReserved,lpszDisplayName,
1716 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1719 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1721 /* fixme no real parsing implemented */
1722 pidlTemp = _ILCreateMyComputer();
1723 szNext = lpszDisplayName;
1725 if (szNext && *szNext)
1727 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1733 if (pdwAttributes && *pdwAttributes)
1735 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1741 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1746 /**************************************************************************
1747 * ISF_Desktop_fnEnumObjects
1749 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1750 IShellFolder2 * iface,
1753 LPENUMIDLIST* ppEnumIDList)
1755 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1757 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1759 *ppEnumIDList = NULL;
1760 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1762 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1764 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1769 /**************************************************************************
1770 * ISF_Desktop_fnBindToObject
1772 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1773 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1775 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1777 IShellFolder *pShellFolder, *pSubFolder;
1780 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1781 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1785 if ((clsid=_ILGetGUIDPointer(pidl)))
1787 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1789 pShellFolder = ISF_MyComputer_Constructor();
1793 /* shell extension */
1794 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1796 return E_INVALIDARG;
1802 /* file system folder on the desktop */
1803 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1804 IPersistFolder * ppf;
1807 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1808 firstpidl = ILCloneFirst(pidl);
1809 completepidl = ILCombine(deskpidl, firstpidl);
1811 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1812 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1814 IPersistFolder_Initialize(ppf, completepidl);
1815 IPersistFolder_Release(ppf);
1817 ILFree(completepidl);
1822 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1824 *ppvOut = pShellFolder;
1827 else /* go deeper */
1829 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1830 IShellFolder_Release(pShellFolder);
1831 *ppvOut = pSubFolder;
1834 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
1839 /**************************************************************************
1840 * ISF_Desktop_fnCreateViewObject
1842 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1843 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1845 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1847 LPSHELLVIEW pShellView;
1848 HRESULT hr = E_INVALIDARG;
1850 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1856 if(IsEqualIID(riid, &IID_IDropTarget))
1858 WARN("IDropTarget not implemented\n");
1861 else if(IsEqualIID(riid, &IID_IContextMenu))
1863 WARN("IContextMenu not implemented\n");
1866 else if(IsEqualIID(riid, &IID_IShellView))
1868 pShellView = IShellView_Constructor((IShellFolder*)iface);
1871 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1872 IShellView_Release(pShellView);
1876 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1880 /**************************************************************************
1881 * ISF_Desktop_fnGetAttributesOf
1883 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1884 IShellFolder2 * iface,
1886 LPCITEMIDLIST *apidl,
1889 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1893 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1895 if ( (!cidl) || (!apidl) || (!rgfInOut))
1896 return E_INVALIDARG;
1898 while (cidl > 0 && *apidl)
1901 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1906 TRACE("-- result=0x%08lx\n",*rgfInOut);
1911 /**************************************************************************
1912 * ISF_Desktop_fnGetDisplayNameOf
1915 * special case: pidl = null gives desktop-name back
1917 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1918 IShellFolder2 * iface,
1923 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1925 CHAR szPath[MAX_PATH]= "";
1927 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1930 if(!strRet) return E_INVALIDARG;
1934 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1936 else if ( _ILIsPidlSimple(pidl) )
1938 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1942 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1943 return E_OUTOFMEMORY;
1945 strRet->uType = STRRET_CSTRA;
1946 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1949 TRACE("-- (%p)->(%s)\n", This, szPath);
1953 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1954 IShellFolder2 * iface,
1957 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1958 FIXME("(%p)\n",This);
1961 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1962 IShellFolder2 * iface,
1963 IEnumExtraSearch **ppenum)
1965 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1966 FIXME("(%p)\n",This);
1969 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1970 IShellFolder2 * iface,
1975 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1977 TRACE("(%p)\n",This);
1979 if (pSort) *pSort = 0;
1980 if (pDisplay) *pDisplay = 0;
1984 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1985 IShellFolder2 * iface,
1989 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1991 TRACE("(%p)\n",This);
1993 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1995 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1999 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
2000 IShellFolder2 * iface,
2002 const SHCOLUMNID *pscid,
2005 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2006 FIXME("(%p)\n",This);
2010 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
2011 IShellFolder2 * iface,
2016 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2017 HRESULT hr = E_FAIL;;
2019 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2021 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2025 psd->fmt = DesktopSFHeader[iColumn].fmt;
2026 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
2027 psd->str.uType = STRRET_CSTRA;
2028 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2033 /* the data from the pidl */
2037 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2040 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2043 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2046 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2048 case 4: /* attributes */
2049 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2053 psd->str.uType = STRRET_CSTRA;
2058 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2059 IShellFolder2 * iface,
2063 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2064 FIXME("(%p)\n",This);
2068 static ICOM_VTABLE(IShellFolder2) sfdvt =
2070 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2071 ISF_Desktop_fnQueryInterface,
2072 IShellFolder_fnAddRef,
2073 IShellFolder_fnRelease,
2074 ISF_Desktop_fnParseDisplayName,
2075 ISF_Desktop_fnEnumObjects,
2076 ISF_Desktop_fnBindToObject,
2077 IShellFolder_fnBindToStorage,
2078 IShellFolder_fnCompareIDs,
2079 ISF_Desktop_fnCreateViewObject,
2080 ISF_Desktop_fnGetAttributesOf,
2081 IShellFolder_fnGetUIObjectOf,
2082 ISF_Desktop_fnGetDisplayNameOf,
2083 IShellFolder_fnSetNameOf,
2086 ISF_Desktop_fnGetDefaultSearchGUID,
2087 ISF_Desktop_fnEnumSearches,
2088 ISF_Desktop_fnGetDefaultColumn,
2089 ISF_Desktop_fnGetDefaultColumnState,
2090 ISF_Desktop_fnGetDetailsEx,
2091 ISF_Desktop_fnGetDetailsOf,
2092 ISF_Desktop_fnMapNameToSCID
2096 /***********************************************************************
2097 * IShellFolder [MyComputer] implementation
2100 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2102 static shvheader MyComputerSFHeader [] =
2104 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2105 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2106 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2107 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2109 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2111 /**************************************************************************
2112 * ISF_MyComputer_Constructor
2114 static IShellFolder * ISF_MyComputer_Constructor(void)
2116 IGenericSFImpl * sf;
2118 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2121 ICOM_VTBL(sf)=&unkvt;
2122 sf->lpvtblShellFolder=&sfmcvt;
2123 sf->lpvtblPersistFolder2 = &psfvt;
2124 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2125 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2126 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2131 return _IShellFolder_(sf);
2134 /**************************************************************************
2135 * ISF_MyComputer_fnParseDisplayName
2137 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2138 IShellFolder2 * iface,
2141 LPOLESTR lpszDisplayName,
2143 LPITEMIDLIST *ppidl,
2144 DWORD *pdwAttributes)
2146 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2148 HRESULT hr = E_OUTOFMEMORY;
2149 LPCWSTR szNext=NULL;
2150 WCHAR szElement[MAX_PATH];
2151 CHAR szTempA[MAX_PATH];
2152 LPITEMIDLIST pidlTemp;
2154 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2155 This,hwndOwner,pbcReserved,lpszDisplayName,
2156 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2159 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2161 /* do we have an absolute path name ? */
2162 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2163 lpszDisplayName[2] == (WCHAR)'\\')
2165 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2166 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
2167 pidlTemp = _ILCreateDrive(szTempA);
2169 if (szNext && *szNext)
2171 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2175 if (pdwAttributes && *pdwAttributes)
2177 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2184 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2189 /**************************************************************************
2190 * ISF_MyComputer_fnEnumObjects
2192 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2193 IShellFolder2 * iface,
2196 LPENUMIDLIST* ppEnumIDList)
2198 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2200 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2202 *ppEnumIDList = NULL;
2203 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2205 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2207 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2212 /**************************************************************************
2213 * ISF_MyComputer_fnBindToObject
2215 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2216 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2218 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2220 IShellFolder *pShellFolder, *pSubFolder;
2221 LPITEMIDLIST pidltemp;
2224 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2225 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2227 if(!pidl || !ppvOut) return E_INVALIDARG;
2231 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2233 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2240 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2242 pidltemp = ILCloneFirst(pidl);
2243 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2247 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2249 *ppvOut = pShellFolder;
2252 else /* go deeper */
2254 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
2255 riid, (LPVOID)&pSubFolder);
2256 IShellFolder_Release(pShellFolder);
2257 *ppvOut = pSubFolder;
2260 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
2265 /**************************************************************************
2266 * ISF_MyComputer_fnCreateViewObject
2268 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2269 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2271 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2273 LPSHELLVIEW pShellView;
2274 HRESULT hr = E_INVALIDARG;
2276 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2282 if(IsEqualIID(riid, &IID_IDropTarget))
2284 WARN("IDropTarget not implemented\n");
2287 else if(IsEqualIID(riid, &IID_IContextMenu))
2289 WARN("IContextMenu not implemented\n");
2292 else if(IsEqualIID(riid, &IID_IShellView))
2294 pShellView = IShellView_Constructor((IShellFolder*)iface);
2297 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2298 IShellView_Release(pShellView);
2302 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2306 /**************************************************************************
2307 * ISF_MyComputer_fnGetAttributesOf
2309 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2310 IShellFolder2 * iface,
2312 LPCITEMIDLIST *apidl,
2315 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2319 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2321 if ( (!cidl) || (!apidl) || (!rgfInOut))
2322 return E_INVALIDARG;
2324 while (cidl > 0 && *apidl)
2327 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2332 TRACE("-- result=0x%08lx\n",*rgfInOut);
2336 /**************************************************************************
2337 * ISF_MyComputer_fnGetDisplayNameOf
2340 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2341 * SHGDN_INFOLDER makes no sense.
2343 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2344 IShellFolder2 * iface,
2349 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2351 char szPath[MAX_PATH], szDrive[18];
2355 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2358 if(!strRet) return E_INVALIDARG;
2360 szPath[0]=0x00; szDrive[0]=0x00;
2363 bSimplePidl = _ILIsPidlSimple(pidl);
2365 if (_ILIsSpecialFolder(pidl))
2367 /* take names of special folders only if its only this folder */
2370 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2375 if (!_ILIsDrive(pidl))
2377 ERR("Wrong pidl type\n");
2378 return E_INVALIDARG;
2381 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2383 /* long view "lw_name (C:)" */
2384 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2386 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2388 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2389 strcat (szDrive," (");
2390 strncat (szDrive, szPath, 2);
2391 strcat (szDrive,")");
2392 strcpy (szPath, szDrive);
2396 if (!bSimplePidl) /* go deeper if needed */
2398 PathAddBackslashA(szPath);
2399 len = strlen(szPath);
2401 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2402 return E_OUTOFMEMORY;
2404 strRet->uType = STRRET_CSTRA;
2405 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2408 TRACE("-- (%p)->(%s)\n", This, szPath);
2412 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2413 IShellFolder2 * iface,
2416 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2417 FIXME("(%p)\n",This);
2420 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2421 IShellFolder2 * iface,
2422 IEnumExtraSearch **ppenum)
2424 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2425 FIXME("(%p)\n",This);
2428 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2429 IShellFolder2 * iface,
2434 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2436 TRACE("(%p)\n",This);
2438 if (pSort) *pSort = 0;
2439 if (pDisplay) *pDisplay = 0;
2443 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2444 IShellFolder2 * iface,
2448 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2450 TRACE("(%p)\n",This);
2452 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2454 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2458 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2459 IShellFolder2 * iface,
2461 const SHCOLUMNID *pscid,
2464 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2465 FIXME("(%p)\n",This);
2470 /* fixme: drive size >4GB is rolling over */
2471 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2472 IShellFolder2 * iface,
2477 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2480 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2482 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2486 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2487 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2488 psd->str.uType = STRRET_CSTRA;
2489 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2494 char szPath[MAX_PATH];
2495 ULARGE_INTEGER ulBytes;
2497 psd->str.u.cStr[0] = 0x00;
2498 psd->str.uType = STRRET_CSTRA;
2502 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2505 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2507 case 2: /* total size */
2508 if (_ILIsDrive(pidl))
2510 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2511 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2512 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2515 case 3: /* free size */
2516 if (_ILIsDrive(pidl))
2518 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2519 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2520 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2529 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2530 IShellFolder2 * iface,
2534 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2535 FIXME("(%p)\n",This);
2539 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2541 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2542 IShellFolder_fnQueryInterface,
2543 IShellFolder_fnAddRef,
2544 IShellFolder_fnRelease,
2545 ISF_MyComputer_fnParseDisplayName,
2546 ISF_MyComputer_fnEnumObjects,
2547 ISF_MyComputer_fnBindToObject,
2548 IShellFolder_fnBindToStorage,
2549 IShellFolder_fnCompareIDs,
2550 ISF_MyComputer_fnCreateViewObject,
2551 ISF_MyComputer_fnGetAttributesOf,
2552 IShellFolder_fnGetUIObjectOf,
2553 ISF_MyComputer_fnGetDisplayNameOf,
2554 IShellFolder_fnSetNameOf,
2557 ISF_MyComputer_fnGetDefaultSearchGUID,
2558 ISF_MyComputer_fnEnumSearches,
2559 ISF_MyComputer_fnGetDefaultColumn,
2560 ISF_MyComputer_fnGetDefaultColumnState,
2561 ISF_MyComputer_fnGetDetailsEx,
2562 ISF_MyComputer_fnGetDetailsOf,
2563 ISF_MyComputer_fnMapNameToSCID
2567 /************************************************************************
2568 * ISFPersistFolder_QueryInterface (IUnknown)
2571 static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2572 IPersistFolder2 * iface,
2576 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2578 TRACE("(%p)\n", This);
2580 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2583 /************************************************************************
2584 * ISFPersistFolder_AddRef (IUnknown)
2587 static ULONG WINAPI ISFPersistFolder2_AddRef(
2588 IPersistFolder2 * iface)
2590 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2592 TRACE("(%p)\n", This);
2594 return IUnknown_AddRef(This->pUnkOuter);
2597 /************************************************************************
2598 * ISFPersistFolder_Release (IUnknown)
2601 static ULONG WINAPI ISFPersistFolder2_Release(
2602 IPersistFolder2 * iface)
2604 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2606 TRACE("(%p)\n", This);
2608 return IUnknown_Release(This->pUnkOuter);
2611 /************************************************************************
2612 * ISFPersistFolder_GetClassID (IPersist)
2614 static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2615 IPersistFolder2 * iface,
2618 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2620 TRACE("(%p)\n", This);
2622 if (!lpClassId) return E_POINTER;
2623 *lpClassId = *This->pclsid;
2628 /************************************************************************
2629 * ISFPersistFolder_Initialize (IPersistFolder)
2632 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2634 static HRESULT WINAPI ISFPersistFolder2_Initialize(
2635 IPersistFolder2 * iface,
2638 char sTemp[MAX_PATH];
2639 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2641 TRACE("(%p)->(%p)\n", This, pidl);
2643 /* free the old stuff */
2646 SHFree(This->absPidl);
2647 This->absPidl = NULL;
2651 SHFree(This->sMyPath);
2652 This->sMyPath = NULL;
2656 This->absPidl = ILClone(pidl);
2659 if (SHGetPathFromIDListA(pidl, sTemp))
2661 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2662 strcpy(This->sMyPath, sTemp);
2665 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2670 /**************************************************************************
2671 * IPersistFolder2_fnGetCurFolder
2673 static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2674 IPersistFolder2 * iface,
2675 LPITEMIDLIST * pidl)
2677 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2679 TRACE("(%p)->(%p)\n",This, pidl);
2681 if (!pidl) return E_POINTER;
2683 *pidl = ILClone(This->absPidl);
2688 static ICOM_VTABLE(IPersistFolder2) psfvt =
2690 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2691 ISFPersistFolder2_QueryInterface,
2692 ISFPersistFolder2_AddRef,
2693 ISFPersistFolder2_Release,
2694 ISFPersistFolder2_GetClassID,
2695 ISFPersistFolder2_Initialize,
2696 ISFPersistFolder2_fnGetCurFolder
2699 /****************************************************************************
2700 * ISFDropTarget implementation
2702 static BOOL ISFDropTarget_QueryDrop(
2707 DWORD dwEffect = *pdwEffect;
2709 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2711 *pdwEffect = DROPEFFECT_NONE;
2713 if (This->fAcceptFmt)
2714 { /* Does our interpretation of the keystate ... */
2715 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2717 /* ... matches the desired effect ? */
2718 if (dwEffect & *pdwEffect)
2726 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2731 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2733 TRACE("(%p)\n", This);
2735 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2738 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2740 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2742 TRACE("(%p)\n", This);
2744 return IUnknown_AddRef(This->pUnkOuter);
2747 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2749 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2751 TRACE("(%p)\n", This);
2753 return IUnknown_Release(This->pUnkOuter);
2756 static HRESULT WINAPI ISFDropTarget_DragEnter(
2758 IDataObject *pDataObject,
2765 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2767 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2769 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2771 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2773 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2778 static HRESULT WINAPI ISFDropTarget_DragOver(
2784 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2786 TRACE("(%p)\n",This);
2788 if(!pdwEffect) return E_INVALIDARG;
2790 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2795 static HRESULT WINAPI ISFDropTarget_DragLeave(
2798 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2800 TRACE("(%p)\n",This);
2802 This->fAcceptFmt = FALSE;
2807 static HRESULT WINAPI ISFDropTarget_Drop(
2809 IDataObject* pDataObject,
2814 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2816 FIXME("(%p) object dropped\n",This);
2821 static struct ICOM_VTABLE(IDropTarget) dtvt =
2823 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2824 ISFDropTarget_QueryInterface,
2825 ISFDropTarget_AddRef,
2826 ISFDropTarget_Release,
2827 ISFDropTarget_DragEnter,
2828 ISFDropTarget_DragOver,
2829 ISFDropTarget_DragLeave,