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);
765 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
766 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
770 if (_ILIsPidlSimple(pidl))
772 if(IsEqualIID(riid, &IID_IShellFolder))
774 *ppvOut = pShellFolder;
779 hr = IShellFolder_QueryInterface(pShellFolder, riid, ppvOut);
780 IShellFolder_Release(pShellFolder);
785 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
786 riid, (LPVOID)&pSubFolder);
787 IShellFolder_Release(pShellFolder);
788 *ppvOut = pSubFolder;
791 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
796 /**************************************************************************
797 * IShellFolder_fnBindToStorage
799 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
800 * LPBC pbc, //[in ] reserved
801 * REFIID riid, //[in ] Initial storage interface
802 * LPVOID* ppvObject //[out] Interface* returned
804 static HRESULT WINAPI IShellFolder_fnBindToStorage(
805 IShellFolder2 * iface,
811 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
813 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
814 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
820 /**************************************************************************
821 * IShellFolder_fnCompareIDs
824 * LPARAM lParam, //[in ] Column?
825 * LPCITEMIDLIST pidl1, //[in ] simple pidl
826 * LPCITEMIDLIST pidl2) //[in ] simple pidl
829 * Special case - If one of the items is a Path and the other is a File,
830 * always make the Path come before the File.
833 * use SCODE_CODE() on the return value to get the result
836 static HRESULT WINAPI IShellFolder_fnCompareIDs(
837 IShellFolder2 * iface,
842 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
844 CHAR szTemp1[MAX_PATH];
845 CHAR szTemp2[MAX_PATH];
848 HRESULT hr = E_OUTOFMEMORY;
849 LPCITEMIDLIST pidlTemp;
852 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
856 if (!pidl1 && !pidl2)
858 hr = ResultFromShort(0);
862 hr = ResultFromShort(-1);
866 hr = ResultFromShort(1);
871 pd1 = _ILGetDataPointer(pidl1);
872 pd2 = _ILGetDataPointer(pidl2);
874 /* compate the types. sort order is the PT_* constant */
875 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
876 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
880 hr = ResultFromShort(pt1-pt2);
882 else /* same type of pidl */
884 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
885 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
886 nReturn = strcasecmp(szTemp1, szTemp2);
888 if (nReturn == 0) /* first pidl different ? */
890 pidl1 = ILGetNext(pidl1);
892 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
894 pidlTemp = ILCloneFirst(pidl1);
895 pidl2 = ILGetNext(pidl2);
897 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
900 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
901 IShellFolder_Release(psf);
902 hr = ResultFromShort(nReturn);
906 else /* no deeper on #1 */
908 pidl2 = ILGetNext(pidl2);
909 if (pidl2 && pidl2->mkid.cb) /* go deeper on #2 ? */
910 hr = ResultFromShort(-1); /* two different */
912 hr = ResultFromShort(nReturn); /* two equal simple pidls */
917 hr = ResultFromShort(nReturn); /* two different simple pidls */
922 TRACE("-- res=0x%08lx\n", hr);
926 /**************************************************************************
927 * IShellFolder_fnCreateViewObject
929 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
930 IShellFolder2 * iface,
935 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
937 LPSHELLVIEW pShellView;
938 HRESULT hr = E_INVALIDARG;
940 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
946 if(IsEqualIID(riid, &IID_IDropTarget))
948 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
950 else if(IsEqualIID(riid, &IID_IContextMenu))
952 FIXME("IContextMenu not implemented\n");
955 else if(IsEqualIID(riid, &IID_IShellView))
957 pShellView = IShellView_Constructor((IShellFolder*)iface);
960 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
961 IShellView_Release(pShellView);
965 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
969 /**************************************************************************
970 * IShellFolder_fnGetAttributesOf
973 * UINT cidl, //[in ] num elements in pidl array
974 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
975 * ULONG* rgfInOut) //[out] result array
978 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
979 IShellFolder2 * iface,
981 LPCITEMIDLIST *apidl,
984 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
988 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
990 if ( (!cidl) || (!apidl) || (!rgfInOut))
993 while (cidl > 0 && *apidl)
996 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1001 TRACE("-- result=0x%08lx\n",*rgfInOut);
1005 /**************************************************************************
1006 * IShellFolder_fnGetUIObjectOf
1009 * HWND hwndOwner, //[in ] Parent window for any output
1010 * UINT cidl, //[in ] array size
1011 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1012 * REFIID riid, //[in ] Requested Interface
1013 * UINT* prgfInOut, //[ ] reserved
1014 * LPVOID* ppvObject) //[out] Resulting Interface
1017 * This function gets asked to return "view objects" for one or more (multiple select)
1019 * The viewobject typically is an COM object with one of the following interfaces:
1020 * IExtractIcon,IDataObject,IContextMenu
1021 * In order to support icon positions in the default Listview your DataObject
1022 * must implement the SetData method (in addition to GetData :) - the shell passes
1023 * a barely documented "Icon positions" structure to SetData when the drag starts,
1024 * and GetData's it if the drop is in another explorer window that needs the positions.
1026 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1027 IShellFolder2 * iface,
1030 LPCITEMIDLIST * apidl,
1035 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1038 IUnknown* pObj = NULL;
1039 HRESULT hr = E_INVALIDARG;
1041 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1042 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1048 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1050 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1053 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1055 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1058 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1060 pidl = ILCombine(This->absPidl,apidl[0]);
1061 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1065 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1067 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1079 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1083 /**************************************************************************
1084 * IShellFolder_fnGetDisplayNameOf
1085 * Retrieves the display name for the specified file object or subfolder
1088 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1089 * DWORD dwFlags, //[in ] SHGNO formatting flags
1090 * LPSTRRET lpName) //[out] Returned display name
1093 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1095 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1096 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1098 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1099 IShellFolder2 * iface,
1104 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1106 CHAR szPath[MAX_PATH]= "";
1110 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1113 if(!pidl || !strRet) return E_INVALIDARG;
1115 bSimplePidl = _ILIsPidlSimple(pidl);
1117 /* take names of special folders only if its only this folder */
1118 if (_ILIsSpecialFolder(pidl))
1122 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1127 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1129 strcpy (szPath, This->sMyPath); /* get path to root*/
1130 PathAddBackslashA(szPath);
1131 len = strlen(szPath);
1133 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1136 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1138 PathAddBackslashA(szPath);
1139 len = strlen(szPath);
1141 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1142 return E_OUTOFMEMORY;
1144 strRet->uType = STRRET_CSTRA;
1145 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1147 TRACE("-- (%p)->(%s)\n", This, szPath);
1151 /**************************************************************************
1152 * IShellFolder_fnSetNameOf
1153 * Changes the name of a file object or subfolder, possibly changing its item
1154 * identifier in the process.
1157 * HWND hwndOwner, //[in ] Owner window for output
1158 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1159 * LPCOLESTR lpszName, //[in ] the items new display name
1160 * DWORD dwFlags, //[in ] SHGNO formatting flags
1161 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1163 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1164 IShellFolder2 * iface,
1166 LPCITEMIDLIST pidl, /*simple pidl*/
1169 LPITEMIDLIST *pPidlOut)
1171 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1172 char szSrc[MAX_PATH], szDest[MAX_PATH];
1174 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1176 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1177 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1179 /* build source path */
1180 if (dwFlags & SHGDN_INFOLDER)
1182 strcpy(szSrc, This->sMyPath);
1183 PathAddBackslashA(szSrc);
1184 len = strlen (szSrc);
1185 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1189 SHGetPathFromIDListA(pidl, szSrc);
1192 /* build destination path */
1193 strcpy(szDest, This->sMyPath);
1194 PathAddBackslashA(szDest);
1195 len = strlen (szDest);
1196 WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
1197 szDest[MAX_PATH-1] = 0;
1198 TRACE("src=%s dest=%s\n", szSrc, szDest);
1199 if ( MoveFileA(szSrc, szDest) )
1201 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1202 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1208 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1209 IShellFolder2 * iface,
1212 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1213 FIXME("(%p)\n",This);
1216 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1217 IShellFolder2 * iface,
1218 IEnumExtraSearch **ppenum)
1220 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1221 FIXME("(%p)\n",This);
1224 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1225 IShellFolder2 * iface,
1230 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1232 TRACE("(%p)\n",This);
1234 if (pSort) *pSort = 0;
1235 if (pDisplay) *pDisplay = 0;
1239 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1240 IShellFolder2 * iface,
1244 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1246 TRACE("(%p)\n",This);
1248 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1250 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1254 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1255 IShellFolder2 * iface,
1257 const SHCOLUMNID *pscid,
1260 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1261 FIXME("(%p)\n",This);
1265 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1266 IShellFolder2 * iface,
1271 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1272 HRESULT hr = E_FAIL;
1274 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1276 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1280 /* the header titles */
1281 psd->fmt = GenericSFHeader[iColumn].fmt;
1282 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1283 psd->str.uType = STRRET_CSTRA;
1284 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1289 /* the data from the pidl */
1293 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1296 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1299 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1302 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1304 case 4: /* attributes */
1305 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1309 psd->str.uType = STRRET_CSTRA;
1314 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1315 IShellFolder2 * iface,
1319 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1320 FIXME("(%p)\n",This);
1324 static ICOM_VTABLE(IShellFolder2) sfvt =
1326 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1327 IShellFolder_fnQueryInterface,
1328 IShellFolder_fnAddRef,
1329 IShellFolder_fnRelease,
1330 IShellFolder_fnParseDisplayName,
1331 IShellFolder_fnEnumObjects,
1332 IShellFolder_fnBindToObject,
1333 IShellFolder_fnBindToStorage,
1334 IShellFolder_fnCompareIDs,
1335 IShellFolder_fnCreateViewObject,
1336 IShellFolder_fnGetAttributesOf,
1337 IShellFolder_fnGetUIObjectOf,
1338 IShellFolder_fnGetDisplayNameOf,
1339 IShellFolder_fnSetNameOf,
1342 IShellFolder_fnGetDefaultSearchGUID,
1343 IShellFolder_fnEnumSearches,
1344 IShellFolder_fnGetDefaultColumn,
1345 IShellFolder_fnGetDefaultColumnState,
1346 IShellFolder_fnGetDetailsEx,
1347 IShellFolder_fnGetDetailsOf,
1348 IShellFolder_fnMapNameToSCID
1351 /****************************************************************************
1352 * ISFHelper for IShellFolder implementation
1355 static HRESULT WINAPI ISFHelper_fnQueryInterface(
1360 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1362 TRACE("(%p)\n", This);
1364 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1367 static ULONG WINAPI ISFHelper_fnAddRef(
1370 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1372 TRACE("(%p)\n", This);
1374 return IUnknown_AddRef(This->pUnkOuter);
1377 static ULONG WINAPI ISFHelper_fnRelease(
1380 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1382 TRACE("(%p)\n", This);
1384 return IUnknown_Release(This->pUnkOuter);
1388 /****************************************************************************
1389 * ISFHelper_fnAddFolder
1391 * creates a unique folder name
1394 static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1399 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1400 IEnumIDList * penum;
1402 char szText[MAX_PATH];
1403 char * szNewFolder = "New Folder";
1405 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1407 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1409 strcpy(lpName, szNewFolder);
1411 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1418 next: IEnumIDList_Reset(penum);
1419 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1421 _ILSimpleGetText(pidl, szText, MAX_PATH);
1422 if (0 == strcasecmp(szText, lpName))
1424 sprintf(lpName, "%s %d", szNewFolder, i++);
1434 IEnumIDList_Release(penum);
1439 /****************************************************************************
1440 * ISFHelper_fnAddFolder
1442 * adds a new folder.
1445 static HRESULT WINAPI ISFHelper_fnAddFolder(
1449 LPITEMIDLIST* ppidlOut)
1451 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1452 char lpstrNewDir[MAX_PATH];
1454 HRESULT hres = E_FAIL;
1456 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1458 strcpy(lpstrNewDir, This->sMyPath);
1459 PathAddBackslashA(lpstrNewDir);
1460 strcat(lpstrNewDir, lpName);
1462 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1466 LPITEMIDLIST pidl, pidlitem;
1468 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1470 pidl = ILCombine(This->absPidl, pidlitem);
1471 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1474 if (ppidlOut) *ppidlOut = pidlitem;
1479 char lpstrText[128+MAX_PATH];
1480 char lpstrTempText[128];
1481 char lpstrCaption[256];
1483 /* Cannot Create folder because of permissions */
1484 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1485 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1486 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1487 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1493 /****************************************************************************
1494 * ISFHelper_fnDeleteItems
1496 * deletes items in folder
1498 static HRESULT WINAPI ISFHelper_fnDeleteItems(
1501 LPCITEMIDLIST* apidl)
1503 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1505 char szPath[MAX_PATH];
1506 BOOL bConfirm = TRUE;
1508 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1510 /* deleting multiple items so give a slightly different warning */
1514 snprintf(tmp, sizeof(tmp), "%d", cidl);
1515 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM, tmp))
1520 for(i=0; i< cidl; i++)
1522 strcpy(szPath, This->sMyPath);
1523 PathAddBackslashA(szPath);
1524 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1526 if (_ILIsFolder(apidl[i]))
1529 TRACE("delete %s\n", szPath);
1530 if (! SHELL_DeleteDirectoryA(szPath, bConfirm))
1532 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1535 pidl = ILCombine(This->absPidl, apidl[i]);
1536 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1539 else if (_ILIsValue(apidl[i]))
1543 TRACE("delete %s\n", szPath);
1544 if (! SHELL_DeleteFileA(szPath, bConfirm))
1546 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1549 pidl = ILCombine(This->absPidl, apidl[i]);
1550 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1558 /****************************************************************************
1559 * ISFHelper_fnCopyItems
1561 * copies items to this folder
1563 static HRESULT WINAPI ISFHelper_fnCopyItems(
1565 IShellFolder* pSFFrom,
1567 LPCITEMIDLIST *apidl)
1570 IPersistFolder2 * ppf2=NULL;
1571 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1572 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1574 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1576 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1580 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1582 for (i=0; i<cidl; i++)
1584 SHGetPathFromIDListA(pidl, szSrcPath);
1585 PathAddBackslashA(szSrcPath);
1586 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1588 strcpy(szDstPath, This->sMyPath);
1589 PathAddBackslashA(szDstPath);
1590 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1591 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1595 IPersistFolder2_Release(ppf2);
1600 static ICOM_VTABLE(ISFHelper) shvt =
1602 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1603 ISFHelper_fnQueryInterface,
1605 ISFHelper_fnRelease,
1606 ISFHelper_fnGetUniqueName,
1607 ISFHelper_fnAddFolder,
1608 ISFHelper_fnDeleteItems,
1609 ISFHelper_fnCopyItems,
1612 /***********************************************************************
1613 * [Desktopfolder] IShellFolder implementation
1615 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1617 static shvheader DesktopSFHeader [] =
1619 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1620 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1621 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1622 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1623 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1625 #define DESKTOPSHELLVIEWCOLUMNS 5
1627 /**************************************************************************
1628 * ISF_Desktop_Constructor
1631 IShellFolder * ISF_Desktop_Constructor()
1633 IGenericSFImpl * sf;
1635 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1637 ICOM_VTBL(sf)=&unkvt;
1638 sf->lpvtblShellFolder=&sfdvt;
1639 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1640 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1645 return _IShellFolder_(sf);
1648 /**************************************************************************
1649 * ISF_Desktop_fnQueryInterface
1651 * NOTES supports not IPersist/IPersistFolder
1653 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1654 IShellFolder2 * iface,
1658 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1660 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1664 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1666 *ppvObj = _IUnknown_(This);
1668 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1670 *ppvObj = _IShellFolder_(This);
1672 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1674 *ppvObj = _IShellFolder_(This);
1679 IUnknown_AddRef((IUnknown*)(*ppvObj));
1680 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1683 TRACE("-- Interface: E_NOINTERFACE\n");
1684 return E_NOINTERFACE;
1687 /**************************************************************************
1688 * ISF_Desktop_fnParseDisplayName
1691 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1694 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1695 IShellFolder2 * iface,
1698 LPOLESTR lpszDisplayName,
1700 LPITEMIDLIST *ppidl,
1701 DWORD *pdwAttributes)
1703 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1705 LPCWSTR szNext=NULL;
1706 LPITEMIDLIST pidlTemp=NULL;
1707 HRESULT hr=E_OUTOFMEMORY;
1709 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1710 This,hwndOwner,pbcReserved,lpszDisplayName,
1711 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1714 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1716 /* FIXME no real parsing implemented */
1717 pidlTemp = _ILCreateMyComputer();
1718 szNext = lpszDisplayName;
1720 if (szNext && *szNext)
1722 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1728 if (pdwAttributes && *pdwAttributes)
1730 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1736 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1741 /**************************************************************************
1742 * ISF_Desktop_fnEnumObjects
1744 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1745 IShellFolder2 * iface,
1748 LPENUMIDLIST* ppEnumIDList)
1750 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1752 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1754 *ppEnumIDList = NULL;
1755 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1757 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1759 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1764 /**************************************************************************
1765 * ISF_Desktop_fnBindToObject
1767 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1768 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1770 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1772 IShellFolder *pShellFolder, *pSubFolder;
1775 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1776 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1780 if ((clsid=_ILGetGUIDPointer(pidl)))
1782 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1784 pShellFolder = ISF_MyComputer_Constructor();
1788 /* shell extension */
1789 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1791 return E_INVALIDARG;
1797 /* file system folder on the desktop */
1798 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1799 IPersistFolder * ppf;
1802 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1803 firstpidl = ILCloneFirst(pidl);
1804 completepidl = ILCombine(deskpidl, firstpidl);
1806 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1807 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1809 IPersistFolder_Initialize(ppf, completepidl);
1810 IPersistFolder_Release(ppf);
1812 ILFree(completepidl);
1817 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1819 *ppvOut = pShellFolder;
1822 else /* go deeper */
1824 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1825 IShellFolder_Release(pShellFolder);
1826 *ppvOut = pSubFolder;
1829 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
1834 /**************************************************************************
1835 * ISF_Desktop_fnCreateViewObject
1837 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1838 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1840 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1842 LPSHELLVIEW pShellView;
1843 HRESULT hr = E_INVALIDARG;
1845 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1851 if(IsEqualIID(riid, &IID_IDropTarget))
1853 WARN("IDropTarget not implemented\n");
1856 else if(IsEqualIID(riid, &IID_IContextMenu))
1858 WARN("IContextMenu not implemented\n");
1861 else if(IsEqualIID(riid, &IID_IShellView))
1863 pShellView = IShellView_Constructor((IShellFolder*)iface);
1866 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1867 IShellView_Release(pShellView);
1871 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1875 /**************************************************************************
1876 * ISF_Desktop_fnGetAttributesOf
1878 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1879 IShellFolder2 * iface,
1881 LPCITEMIDLIST *apidl,
1884 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1888 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1890 if ( (!cidl) || (!apidl) || (!rgfInOut))
1891 return E_INVALIDARG;
1893 while (cidl > 0 && *apidl)
1896 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1901 TRACE("-- result=0x%08lx\n",*rgfInOut);
1906 /**************************************************************************
1907 * ISF_Desktop_fnGetDisplayNameOf
1910 * special case: pidl = null gives desktop-name back
1912 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1913 IShellFolder2 * iface,
1918 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1920 CHAR szPath[MAX_PATH]= "";
1922 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1925 if(!strRet) return E_INVALIDARG;
1929 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1931 else if ( _ILIsPidlSimple(pidl) )
1933 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1937 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1938 return E_OUTOFMEMORY;
1940 strRet->uType = STRRET_CSTRA;
1941 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1944 TRACE("-- (%p)->(%s)\n", This, szPath);
1948 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1949 IShellFolder2 * iface,
1952 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1953 FIXME("(%p)\n",This);
1956 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1957 IShellFolder2 * iface,
1958 IEnumExtraSearch **ppenum)
1960 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1961 FIXME("(%p)\n",This);
1964 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1965 IShellFolder2 * iface,
1970 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1972 TRACE("(%p)\n",This);
1974 if (pSort) *pSort = 0;
1975 if (pDisplay) *pDisplay = 0;
1979 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1980 IShellFolder2 * iface,
1984 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1986 TRACE("(%p)\n",This);
1988 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1990 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1994 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1995 IShellFolder2 * iface,
1997 const SHCOLUMNID *pscid,
2000 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2001 FIXME("(%p)\n",This);
2005 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
2006 IShellFolder2 * iface,
2011 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2012 HRESULT hr = E_FAIL;;
2014 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2016 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2020 psd->fmt = DesktopSFHeader[iColumn].fmt;
2021 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
2022 psd->str.uType = STRRET_CSTRA;
2023 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2028 /* the data from the pidl */
2032 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2035 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2038 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2041 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2043 case 4: /* attributes */
2044 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2048 psd->str.uType = STRRET_CSTRA;
2053 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2054 IShellFolder2 * iface,
2058 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2059 FIXME("(%p)\n",This);
2063 static ICOM_VTABLE(IShellFolder2) sfdvt =
2065 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2066 ISF_Desktop_fnQueryInterface,
2067 IShellFolder_fnAddRef,
2068 IShellFolder_fnRelease,
2069 ISF_Desktop_fnParseDisplayName,
2070 ISF_Desktop_fnEnumObjects,
2071 ISF_Desktop_fnBindToObject,
2072 IShellFolder_fnBindToStorage,
2073 IShellFolder_fnCompareIDs,
2074 ISF_Desktop_fnCreateViewObject,
2075 ISF_Desktop_fnGetAttributesOf,
2076 IShellFolder_fnGetUIObjectOf,
2077 ISF_Desktop_fnGetDisplayNameOf,
2078 IShellFolder_fnSetNameOf,
2081 ISF_Desktop_fnGetDefaultSearchGUID,
2082 ISF_Desktop_fnEnumSearches,
2083 ISF_Desktop_fnGetDefaultColumn,
2084 ISF_Desktop_fnGetDefaultColumnState,
2085 ISF_Desktop_fnGetDetailsEx,
2086 ISF_Desktop_fnGetDetailsOf,
2087 ISF_Desktop_fnMapNameToSCID
2091 /***********************************************************************
2092 * IShellFolder [MyComputer] implementation
2095 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2097 static shvheader MyComputerSFHeader [] =
2099 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2100 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2101 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2102 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2104 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2106 /**************************************************************************
2107 * ISF_MyComputer_Constructor
2109 static IShellFolder * ISF_MyComputer_Constructor(void)
2111 IGenericSFImpl * sf;
2113 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2116 ICOM_VTBL(sf)=&unkvt;
2117 sf->lpvtblShellFolder=&sfmcvt;
2118 sf->lpvtblPersistFolder2 = &psfvt;
2119 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2120 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2121 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2126 return _IShellFolder_(sf);
2129 /**************************************************************************
2130 * ISF_MyComputer_fnParseDisplayName
2132 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2133 IShellFolder2 * iface,
2136 LPOLESTR lpszDisplayName,
2138 LPITEMIDLIST *ppidl,
2139 DWORD *pdwAttributes)
2141 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2143 HRESULT hr = E_OUTOFMEMORY;
2144 LPCWSTR szNext=NULL;
2145 WCHAR szElement[MAX_PATH];
2146 CHAR szTempA[MAX_PATH];
2147 LPITEMIDLIST pidlTemp;
2149 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2150 This,hwndOwner,pbcReserved,lpszDisplayName,
2151 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2154 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2156 /* do we have an absolute path name ? */
2157 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2158 lpszDisplayName[2] == (WCHAR)'\\')
2160 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2161 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
2162 pidlTemp = _ILCreateDrive(szTempA);
2164 if (szNext && *szNext)
2166 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2170 if (pdwAttributes && *pdwAttributes)
2172 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2179 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2184 /**************************************************************************
2185 * ISF_MyComputer_fnEnumObjects
2187 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2188 IShellFolder2 * iface,
2191 LPENUMIDLIST* ppEnumIDList)
2193 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2195 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2197 *ppEnumIDList = NULL;
2198 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2200 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2202 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2207 /**************************************************************************
2208 * ISF_MyComputer_fnBindToObject
2210 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2211 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2213 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2215 IShellFolder *pShellFolder, *pSubFolder;
2216 LPITEMIDLIST pidltemp;
2219 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2220 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2222 if(!pidl || !ppvOut) return E_INVALIDARG;
2226 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2228 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2235 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2237 pidltemp = ILCloneFirst(pidl);
2238 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2242 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2244 *ppvOut = pShellFolder;
2247 else /* go deeper */
2249 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
2250 riid, (LPVOID)&pSubFolder);
2251 IShellFolder_Release(pShellFolder);
2252 *ppvOut = pSubFolder;
2255 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
2260 /**************************************************************************
2261 * ISF_MyComputer_fnCreateViewObject
2263 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2264 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2266 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2268 LPSHELLVIEW pShellView;
2269 HRESULT hr = E_INVALIDARG;
2271 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2277 if(IsEqualIID(riid, &IID_IDropTarget))
2279 WARN("IDropTarget not implemented\n");
2282 else if(IsEqualIID(riid, &IID_IContextMenu))
2284 WARN("IContextMenu not implemented\n");
2287 else if(IsEqualIID(riid, &IID_IShellView))
2289 pShellView = IShellView_Constructor((IShellFolder*)iface);
2292 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2293 IShellView_Release(pShellView);
2297 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2301 /**************************************************************************
2302 * ISF_MyComputer_fnGetAttributesOf
2304 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2305 IShellFolder2 * iface,
2307 LPCITEMIDLIST *apidl,
2310 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2314 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2316 if ( (!cidl) || (!apidl) || (!rgfInOut))
2317 return E_INVALIDARG;
2319 while (cidl > 0 && *apidl)
2322 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2327 TRACE("-- result=0x%08lx\n",*rgfInOut);
2331 /**************************************************************************
2332 * ISF_MyComputer_fnGetDisplayNameOf
2335 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2336 * SHGDN_INFOLDER makes no sense.
2338 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2339 IShellFolder2 * iface,
2344 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2346 char szPath[MAX_PATH], szDrive[18];
2350 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2353 if(!strRet) return E_INVALIDARG;
2355 szPath[0]=0x00; szDrive[0]=0x00;
2358 bSimplePidl = _ILIsPidlSimple(pidl);
2360 if (_ILIsSpecialFolder(pidl))
2362 /* take names of special folders only if its only this folder */
2365 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2370 if (!_ILIsDrive(pidl))
2372 ERR("Wrong pidl type\n");
2373 return E_INVALIDARG;
2376 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2378 /* long view "lw_name (C:)" */
2379 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2381 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2383 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2384 strcat (szDrive," (");
2385 strncat (szDrive, szPath, 2);
2386 strcat (szDrive,")");
2387 strcpy (szPath, szDrive);
2391 if (!bSimplePidl) /* go deeper if needed */
2393 PathAddBackslashA(szPath);
2394 len = strlen(szPath);
2396 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2397 return E_OUTOFMEMORY;
2399 strRet->uType = STRRET_CSTRA;
2400 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2403 TRACE("-- (%p)->(%s)\n", This, szPath);
2407 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2408 IShellFolder2 * iface,
2411 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2412 FIXME("(%p)\n",This);
2415 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2416 IShellFolder2 * iface,
2417 IEnumExtraSearch **ppenum)
2419 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2420 FIXME("(%p)\n",This);
2423 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2424 IShellFolder2 * iface,
2429 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2431 TRACE("(%p)\n",This);
2433 if (pSort) *pSort = 0;
2434 if (pDisplay) *pDisplay = 0;
2438 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2439 IShellFolder2 * iface,
2443 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2445 TRACE("(%p)\n",This);
2447 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2449 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2453 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2454 IShellFolder2 * iface,
2456 const SHCOLUMNID *pscid,
2459 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2460 FIXME("(%p)\n",This);
2465 /* FIXME: drive size >4GB is rolling over */
2466 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2467 IShellFolder2 * iface,
2472 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2475 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2477 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2481 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2482 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2483 psd->str.uType = STRRET_CSTRA;
2484 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2489 char szPath[MAX_PATH];
2490 ULARGE_INTEGER ulBytes;
2492 psd->str.u.cStr[0] = 0x00;
2493 psd->str.uType = STRRET_CSTRA;
2497 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2500 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2502 case 2: /* total size */
2503 if (_ILIsDrive(pidl))
2505 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2506 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2507 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2510 case 3: /* free size */
2511 if (_ILIsDrive(pidl))
2513 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2514 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2515 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2524 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2525 IShellFolder2 * iface,
2529 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2530 FIXME("(%p)\n",This);
2534 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2536 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2537 IShellFolder_fnQueryInterface,
2538 IShellFolder_fnAddRef,
2539 IShellFolder_fnRelease,
2540 ISF_MyComputer_fnParseDisplayName,
2541 ISF_MyComputer_fnEnumObjects,
2542 ISF_MyComputer_fnBindToObject,
2543 IShellFolder_fnBindToStorage,
2544 IShellFolder_fnCompareIDs,
2545 ISF_MyComputer_fnCreateViewObject,
2546 ISF_MyComputer_fnGetAttributesOf,
2547 IShellFolder_fnGetUIObjectOf,
2548 ISF_MyComputer_fnGetDisplayNameOf,
2549 IShellFolder_fnSetNameOf,
2552 ISF_MyComputer_fnGetDefaultSearchGUID,
2553 ISF_MyComputer_fnEnumSearches,
2554 ISF_MyComputer_fnGetDefaultColumn,
2555 ISF_MyComputer_fnGetDefaultColumnState,
2556 ISF_MyComputer_fnGetDetailsEx,
2557 ISF_MyComputer_fnGetDetailsOf,
2558 ISF_MyComputer_fnMapNameToSCID
2562 /************************************************************************
2563 * ISFPersistFolder_QueryInterface (IUnknown)
2566 static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2567 IPersistFolder2 * iface,
2571 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2573 TRACE("(%p)\n", This);
2575 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2578 /************************************************************************
2579 * ISFPersistFolder_AddRef (IUnknown)
2582 static ULONG WINAPI ISFPersistFolder2_AddRef(
2583 IPersistFolder2 * iface)
2585 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2587 TRACE("(%p)\n", This);
2589 return IUnknown_AddRef(This->pUnkOuter);
2592 /************************************************************************
2593 * ISFPersistFolder_Release (IUnknown)
2596 static ULONG WINAPI ISFPersistFolder2_Release(
2597 IPersistFolder2 * iface)
2599 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2601 TRACE("(%p)\n", This);
2603 return IUnknown_Release(This->pUnkOuter);
2606 /************************************************************************
2607 * ISFPersistFolder_GetClassID (IPersist)
2609 static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2610 IPersistFolder2 * iface,
2613 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2615 TRACE("(%p)\n", This);
2617 if (!lpClassId) return E_POINTER;
2618 *lpClassId = *This->pclsid;
2623 /************************************************************************
2624 * ISFPersistFolder_Initialize (IPersistFolder)
2627 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2629 static HRESULT WINAPI ISFPersistFolder2_Initialize(
2630 IPersistFolder2 * iface,
2633 char sTemp[MAX_PATH];
2634 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2636 TRACE("(%p)->(%p)\n", This, pidl);
2638 /* free the old stuff */
2641 SHFree(This->absPidl);
2642 This->absPidl = NULL;
2646 SHFree(This->sMyPath);
2647 This->sMyPath = NULL;
2651 This->absPidl = ILClone(pidl);
2654 if (SHGetPathFromIDListA(pidl, sTemp))
2656 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2657 strcpy(This->sMyPath, sTemp);
2660 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2665 /**************************************************************************
2666 * IPersistFolder2_fnGetCurFolder
2668 static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2669 IPersistFolder2 * iface,
2670 LPITEMIDLIST * pidl)
2672 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2674 TRACE("(%p)->(%p)\n",This, pidl);
2676 if (!pidl) return E_POINTER;
2678 *pidl = ILClone(This->absPidl);
2683 static ICOM_VTABLE(IPersistFolder2) psfvt =
2685 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2686 ISFPersistFolder2_QueryInterface,
2687 ISFPersistFolder2_AddRef,
2688 ISFPersistFolder2_Release,
2689 ISFPersistFolder2_GetClassID,
2690 ISFPersistFolder2_Initialize,
2691 ISFPersistFolder2_fnGetCurFolder
2694 /****************************************************************************
2695 * ISFDropTarget implementation
2697 static BOOL ISFDropTarget_QueryDrop(
2702 DWORD dwEffect = *pdwEffect;
2704 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2706 *pdwEffect = DROPEFFECT_NONE;
2708 if (This->fAcceptFmt)
2709 { /* Does our interpretation of the keystate ... */
2710 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2712 /* ... matches the desired effect ? */
2713 if (dwEffect & *pdwEffect)
2721 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2726 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2728 TRACE("(%p)\n", This);
2730 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2733 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2735 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2737 TRACE("(%p)\n", This);
2739 return IUnknown_AddRef(This->pUnkOuter);
2742 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2744 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2746 TRACE("(%p)\n", This);
2748 return IUnknown_Release(This->pUnkOuter);
2751 static HRESULT WINAPI ISFDropTarget_DragEnter(
2753 IDataObject *pDataObject,
2760 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2762 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2764 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2766 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2768 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2773 static HRESULT WINAPI ISFDropTarget_DragOver(
2779 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2781 TRACE("(%p)\n",This);
2783 if(!pdwEffect) return E_INVALIDARG;
2785 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2790 static HRESULT WINAPI ISFDropTarget_DragLeave(
2793 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2795 TRACE("(%p)\n",This);
2797 This->fAcceptFmt = FALSE;
2802 static HRESULT WINAPI ISFDropTarget_Drop(
2804 IDataObject* pDataObject,
2809 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2811 FIXME("(%p) object dropped\n",This);
2816 static struct ICOM_VTABLE(IDropTarget) dtvt =
2818 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2819 ISFDropTarget_QueryInterface,
2820 ISFDropTarget_AddRef,
2821 ISFDropTarget_Release,
2822 ISFDropTarget_DragEnter,
2823 ISFDropTarget_DragOver,
2824 ISFDropTarget_DragLeave,