+
/*
* Shell Folder stuff
*
- * Copyright 1997 Marcus Meissner
- * Copyright 1998, 1999 Juergen Schmied
- *
+ * Copyright 1997 Marcus Meissner
+ * Copyright 1998, 1999, 2002 Juergen Schmied
+ *
* IShellFolder2 and related interfaces
*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h"
+#include "wine/port.h"
+
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include <stdio.h>
-#include "debugtools.h"
#include "winerror.h"
+#include "windef.h"
#include "winbase.h"
+#include "winreg.h"
+#include "wingdi.h"
+#include "winuser.h"
-#include "oleidl.h"
+#include "ole2.h"
#include "shlguid.h"
#include "pidl.h"
-#include "wine/winestring.h"
-#include "wine/obj_base.h"
-#include "wine/obj_dragdrop.h"
-#include "wine/obj_shellfolder.h"
-#include "wine/undocshell.h"
+#include "undocshell.h"
#include "shell32_main.h"
#include "shresdef.h"
#include "shlwapi.h"
-
-#define INITGUID
-#include "initguid.h"
#include "shellfolder.h"
-#include "wine/obj_queryassociations.h"
-
-DEFAULT_DEBUG_CHANNEL(shell)
+#include "wine/debug.h"
+#include "debughlp.h"
+#include "shfldr.h"
+WINE_DEFAULT_DEBUG_CHANNEL (shell);
/***************************************************************************
- * debughelper: print out the return adress
+ * debughelper: print out the return address
* helps especially to track down unbalanced AddRef/Release
*/
#define MEM_DEBUG 0
#define _CALL_TRACE
#endif
-typedef struct
-{
- int colnameid;
- int pcsFlags;
- int fmt;
- int cxChar;
-
-} shvheader;
-
/***************************************************************************
* GetNextElement (internal function)
*
* LPSTR pointer to first, not yet parsed char
*/
-static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
-{ LPCWSTR pszTail = pszNext;
- DWORD dwCopy;
- TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
-
- *pszOut=0x0000;
-
- if(!pszNext || !*pszNext)
- return NULL;
-
- while(*pszTail && (*pszTail != (WCHAR)'\\'))
- pszTail++;
-
- dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
- lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
-
- if(*pszTail)
- pszTail++;
- else
- pszTail = NULL;
-
- TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
- return pszTail;
-}
-
-static HRESULT SHELL32_ParseNextElement(
- HWND hwndOwner,
- IShellFolder2 * psf,
- LPITEMIDLIST * pidlInOut,
- LPOLESTR szNext,
- DWORD *pEaten,
- DWORD *pdwAttributes)
+LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut)
{
- HRESULT hr = E_OUTOFMEMORY;
- LPITEMIDLIST pidlOut, pidlTemp = NULL;
- IShellFolder *psfChild;
-
- TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
-
+ LPCWSTR pszTail = pszNext;
+ DWORD dwCopy;
- /* get the shellfolder for the child pidl and let it analyse further */
- hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
+ TRACE ("(%s %p 0x%08lx)\n", debugstr_w (pszNext), pszOut, dwOut);
- if (psfChild)
- {
- hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
- IShellFolder_Release(psfChild);
+ *pszOut = 0x0000;
- pidlTemp = ILCombine(*pidlInOut, pidlOut);
+ if (!pszNext || !*pszNext)
+ return NULL;
- if (pidlOut)
- ILFree(pidlOut);
- }
+ while (*pszTail && (*pszTail != (WCHAR) '\\'))
+ pszTail++;
- ILFree(*pidlInOut);
- *pidlInOut = pidlTemp;
+ dwCopy = (WCHAR *) pszTail - (WCHAR *) pszNext + 1;
+ lstrcpynW (pszOut, pszNext, (dwOut < dwCopy) ? dwOut : dwCopy);
- TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
- return hr;
-}
-
-/***********************************************************************
- * SHELL32_CoCreateInitSF
- *
- * creates a initialized shell folder
- */
-static HRESULT SHELL32_CoCreateInitSF (
- LPITEMIDLIST pidlRoot,
- LPITEMIDLIST pidlChild,
- REFCLSID clsid,
- REFIID iid,
- LPVOID * ppvOut)
-{
- HRESULT hr;
- LPITEMIDLIST absPidl;
- IShellFolder2 *pShellFolder;
- IPersistFolder *pPersistFolder;
-
- TRACE("%p %p\n", pidlRoot, pidlChild);
-
- *ppvOut = NULL;
-
- /* we have to ask first for IPersistFolder, some special folders are expecting this */
- hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
- if (SUCCEEDED(hr))
- {
- hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
- if (SUCCEEDED(hr))
- {
- absPidl = ILCombine (pidlRoot, pidlChild);
- hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
- IPersistFolder_Release(pPersistFolder);
- SHFree(absPidl);
- *ppvOut = pShellFolder;
- }
- }
+ if (*pszTail)
+ pszTail++;
+ else
+ pszTail = NULL;
- TRACE("-- ret=0x%08lx\n", hr);
- return hr;
+ TRACE ("--(%s %s 0x%08lx %p)\n", debugstr_w (pszNext), debugstr_w (pszOut), dwOut, pszTail);
+ return pszTail;
}
-static HRESULT SHELL32_GetDisplayNameOfChild(
- IShellFolder2 * psf,
- LPCITEMIDLIST pidl,
- DWORD dwFlags,
- LPSTR szOut,
- DWORD dwOutLen)
+HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc,
+ LPITEMIDLIST * pidlInOut, LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes)
{
- LPITEMIDLIST pidlFirst, pidlNext;
- IShellFolder2 * psfChild;
- HRESULT hr = E_OUTOFMEMORY;
- STRRET strTemp;
-
- TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
- pdump(pidl);
-
- if ((pidlFirst = ILCloneFirst(pidl)))
- {
- hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
- if (SUCCEEDED(hr))
- {
- pidlNext = ILGetNext(pidl);
-
- hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
- if (SUCCEEDED(hr))
- {
- hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
- }
+ HRESULT hr = E_OUTOFMEMORY;
+ LPITEMIDLIST pidlOut = NULL,
+ pidlTemp = NULL;
+ IShellFolder *psfChild;
- IShellFolder_Release(psfChild);
- }
- ILFree(pidlFirst);
- }
+ TRACE ("(%p, %p, %p, %s)\n", psf, pbc, pidlInOut ? *pidlInOut : NULL, debugstr_w (szNext));
- TRACE("-- ret=0x%08lx %s\n", hr, szOut);
+ /* get the shellfolder for the child pidl and let it analyse further */
+ hr = IShellFolder_BindToObject (psf, *pidlInOut, pbc, &IID_IShellFolder, (LPVOID *) & psfChild);
- return hr;
-}
+ if (SUCCEEDED (hr)) {
+ hr = IShellFolder_ParseDisplayName (psfChild, hwndOwner, pbc, szNext, pEaten, &pidlOut, pdwAttributes);
+ IShellFolder_Release (psfChild);
-/***********************************************************************
- * SHELL32_GetItemAttributes
- *
- * NOTES
- * observerd values:
- * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
- * file: 0x40000177 FILESYSTEM
- * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
- * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
- * (seems to be default for shell extensions if no registry entry exists)
- *
- * This functions does not set flags!! It only resets flags when nessesary.
- */
-static HRESULT SHELL32_GetItemAttributes(
- IShellFolder * psf,
- LPITEMIDLIST pidl,
- LPDWORD pdwAttributes)
-{
- GUID const * clsid;
- DWORD dwAttributes;
-
- TRACE("0x%08lx\n", *pdwAttributes);
-
- if (*pdwAttributes & (0xcff3fe88))
- WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
- *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
-
- if (_ILIsDrive(pidl))
- {
- *pdwAttributes &= 0xf0000144;
- }
- else if ((clsid=_ILGetGUIDPointer(pidl)))
- {
- if (HCR_GetFolderAttributes(clsid, &dwAttributes))
- {
- *pdwAttributes &= dwAttributes;
- }
- else
- {
- *pdwAttributes &= 0xb0000154;
- }
- }
- else if (_ILGetDataPointer(pidl))
- {
- dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
- *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
+ pidlTemp = ILCombine (*pidlInOut, pidlOut);
- if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
- *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
+ if (pidlOut)
+ ILFree (pidlOut);
+ }
- if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
- *pdwAttributes &= ~SFGAO_HIDDEN;
+ ILFree (*pidlInOut);
+ *pidlInOut = pidlTemp;
- if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
- *pdwAttributes &= ~SFGAO_READONLY;
- }
- else
- {
- *pdwAttributes &= 0xb0000154;
- }
- TRACE("-- 0x%08lx\n", *pdwAttributes);
- return S_OK;
+ TRACE ("-- pidl=%p ret=0x%08lx\n", pidlInOut ? *pidlInOut : NULL, hr);
+ return hr;
}
/***********************************************************************
-* IShellFolder implementation
-*/
-
-typedef struct
-{
- ICOM_VFIELD(IUnknown);
- DWORD ref;
- ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
- ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
- ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
- ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
-
- IUnknown *pUnkOuter; /* used for aggregation */
-
- CLSID* pclsid;
-
- LPSTR sMyPath;
- LPITEMIDLIST absPidl; /* complete pidl */
-
- UINT cfShellIDList; /* clipboardformat for IDropTarget */
- BOOL fAcceptFmt; /* flag for pending Drop */
-} IGenericSFImpl;
-
-static struct ICOM_VTABLE(IUnknown) unkvt;
-static struct ICOM_VTABLE(IShellFolder2) sfvt;
-static struct ICOM_VTABLE(IPersistFolder2) psfvt;
-static struct ICOM_VTABLE(IDropTarget) dtvt;
-static struct ICOM_VTABLE(ISFHelper) shvt;
-
-static IShellFolder * ISF_MyComputer_Constructor(void);
-
-#define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
-#define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
-
-#define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
-#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
-
-#define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
-#define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
-
-#define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
-#define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
-/*
- converts This to a interface pointer
-*/
-#define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
-#define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
-#define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
-#define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
-#define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
-#define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
-#define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
-#define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
-/**************************************************************************
-* registers clipboardformat once
-*/
-static void SF_RegisterClipFmt (IGenericSFImpl * This)
-{
- TRACE("(%p)\n", This);
-
- if (!This->cfShellIDList)
- {
- This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
- }
-}
-
-/**************************************************************************
-* we need a seperate IUnknown to handle aggregation
-* (inner IUnknown)
-*/
-static HRESULT WINAPI IUnknown_fnQueryInterface(
- IUnknown * iface,
- REFIID riid,
- LPVOID *ppvObj)
-{
- ICOM_THIS(IGenericSFImpl, iface);
-
- _CALL_TRACE
- TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
-
- *ppvObj = NULL;
-
- if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
- else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
- else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
- else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
- else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
- else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
- else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
- else if(IsEqualIID(riid, &IID_IDropTarget))
- {
- *ppvObj = _IDropTarget_(This);
- SF_RegisterClipFmt(This);
- }
-
- if(*ppvObj)
- {
- IUnknown_AddRef((IUnknown*)(*ppvObj));
- TRACE("-- Interface = %p\n", *ppvObj);
- return S_OK;
- }
- TRACE("-- Interface: E_NOINTERFACE\n");
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
-{
- ICOM_THIS(IGenericSFImpl, iface);
-
- _CALL_TRACE
- TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
- shell32_ObjCount++;
- return ++(This->ref);
-}
-
-static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
-{
- ICOM_THIS(IGenericSFImpl, iface);
-
- _CALL_TRACE
- TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
- shell32_ObjCount--;
- if (!--(This->ref))
- {
- TRACE("-- destroying IShellFolder(%p)\n",This);
-
- if (pdesktopfolder == _IShellFolder_(This))
- {
- pdesktopfolder=NULL;
- TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
- }
- if(This->absPidl) SHFree(This->absPidl);
- if(This->sMyPath) SHFree(This->sMyPath);
- HeapFree(GetProcessHeap(),0,This);
- return 0;
- }
- return This->ref;
-}
-
-static ICOM_VTABLE(IUnknown) unkvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- IUnknown_fnQueryInterface,
- IUnknown_fnAddRef,
- IUnknown_fnRelease,
-};
-
-static shvheader GenericSFHeader [] =
-{
- { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
- { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
- { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
-};
-#define GENERICSHELLVIEWCOLUMNS 5
-
-/**************************************************************************
-* IShellFolder_Constructor
-*
-* NOTES
-* creating undocumented ShellFS_Folder as part of an aggregation
-* {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
-*
-* FIXME
-* when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
-*/
-HRESULT IFSFolder_Constructor(
- IUnknown * pUnkOuter,
- REFIID riid,
- LPVOID * ppv)
-{
- IGenericSFImpl * sf;
- HRESULT hr = S_OK;
-
- TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
-
- if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
- {
- hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
- }
- else
- {
- sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
- if (sf)
- {
- sf->ref=1;
- ICOM_VTBL(sf)=&unkvt;
- sf->lpvtblShellFolder=&sfvt;
- sf->lpvtblPersistFolder2=&psfvt;
- sf->lpvtblDropTarget=&dtvt;
- sf->lpvtblSFHelper=&shvt;
-
- sf->pclsid = (CLSID*)&CLSID_SFFile;
- sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
- *ppv = _IUnknown_(sf);
- hr = S_OK;
- shell32_ObjCount++;
- }
- else
- {
- hr = E_OUTOFMEMORY;
- }
- }
- return hr;
-}
-/**************************************************************************
-* IShellFolder_Constructor
-*
-* NOTES
-* THIS points to the parent folder
-*/
-
-IShellFolder * IShellFolder_Constructor(
- IShellFolder2 * iface,
- LPITEMIDLIST pidl)
-{
- IGenericSFImpl * sf;
- DWORD dwSize=0;
-
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
- sf->ref=1;
-
- ICOM_VTBL(sf)=&unkvt;
- sf->lpvtblShellFolder=&sfvt;
- sf->lpvtblPersistFolder2=&psfvt;
- sf->lpvtblDropTarget=&dtvt;
- sf->lpvtblSFHelper=&shvt;
-
- sf->pclsid = (CLSID*)&CLSID_SFFile;
- sf->pUnkOuter = _IUnknown_(sf);
-
- TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
- pdump(pidl);
-
- if(pidl && iface) /* do we have a pidl? */
- {
- int len;
-
- sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
-
- if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
- {
- if(This->sMyPath) /* get the size of the parents path */
- {
- dwSize += strlen(This->sMyPath) ;
- TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
- }
-
- dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
- sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
-
- if(!sf->sMyPath) return NULL;
- *(sf->sMyPath)=0x00;
-
- if(This->sMyPath) /* if the parent has a path, get it*/
- {
- strcpy(sf->sMyPath, This->sMyPath);
- PathAddBackslashA (sf->sMyPath);
- }
-
- len = strlen(sf->sMyPath);
- _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
- }
-
- TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
-
- pdump (sf->absPidl);
- }
-
- shell32_ObjCount++;
- return _IShellFolder_(sf);
-}
-
-/**************************************************************************
- * IShellFolder_fnQueryInterface
+ * SHELL32_CoCreateInitSF
*
- * PARAMETERS
- * REFIID riid [in ] Requested InterfaceID
- * LPVOID* ppvObject [out] Interface* to hold the result
- */
-static HRESULT WINAPI IShellFolder_fnQueryInterface(
- IShellFolder2 * iface,
- REFIID riid,
- LPVOID *ppvObj)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- _CALL_TRACE
- TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
-
- return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
-}
-
-/**************************************************************************
-* IShellFolder_AddRef
-*/
-
-static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- _CALL_TRACE
- TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
- return IUnknown_AddRef(This->pUnkOuter);
-}
-
-/**************************************************************************
- * IShellFolder_fnRelease
+ * Creates a shell folder and initializes it with a pidl via IPersistFolder.
+ * This function is meant for virtual folders not backed by a file system
+ * folder.
*/
-static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- _CALL_TRACE
- TRACE("(%p)->(count=%lu)\n",This,This->ref);
-
- return IUnknown_Release(This->pUnkOuter);
-}
-
-/**************************************************************************
-* IShellFolder_fnParseDisplayName
-* PARAMETERS
-* HWND hwndOwner, //[in ] Parent window for any message's
-* LPBC pbc, //[in ] reserved
-* LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
-* ULONG* pchEaten, //[out] (unicode) characters processed
-* LPITEMIDLIST* ppidl, //[out] complex pidl to item
-* ULONG* pdwAttributes //[out] items attributes
-*
-* NOTES
-* every folder tries to parse only its own (the leftmost) pidl and creates a
-* subfolder to evaluate the remaining parts
-* now we can parse into namespaces implemented by shell extensions
-*
-* behaviour on win98: lpszDisplayName=NULL -> chrash
-* lpszDisplayName="" -> returns mycoputer-pidl
-*
-* FIXME:
-* pdwAttributes: not set
-* pchEaten: not set like in windows
-*/
-static HRESULT WINAPI IShellFolder_fnParseDisplayName(
- IShellFolder2 * iface,
- HWND hwndOwner,
- LPBC pbcReserved,
- LPOLESTR lpszDisplayName,
- DWORD *pchEaten,
- LPITEMIDLIST *ppidl,
- DWORD *pdwAttributes)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- HRESULT hr = E_OUTOFMEMORY;
- LPCWSTR szNext=NULL;
- WCHAR szElement[MAX_PATH];
- CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
- LPITEMIDLIST pidlTemp=NULL;
-
- TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
- This,hwndOwner,pbcReserved,lpszDisplayName,
- debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
-
- if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
-
- if (pchEaten) *pchEaten = 0; /* strange but like the original */
-
- if (*lpszDisplayName)
- {
- /* get the next element */
- szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
-
- /* build the full pathname to the element */
- lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
- strcpy(szPath, This->sMyPath);
- PathAddBackslashA(szPath);
- strcat(szPath, szTempA);
-
- /* get the pidl */
- pidlTemp = SHSimpleIDListFromPathA(szPath);
-
- if (pidlTemp)
- {
- /* try to analyse the next element */
- if (szNext && *szNext)
- {
- hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
- }
- else
- {
- if (pdwAttributes && *pdwAttributes)
- {
- SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
-/* WIN32_FIND_DATAA fd;
- SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
- if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
- *pdwAttributes &= ~SFGAO_FOLDER;
- if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
- *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
-*/
- }
- hr = S_OK;
- }
- }
- }
-
- *ppidl = pidlTemp;
-
- TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
-
- return hr;
-}
-
-/**************************************************************************
-* IShellFolder_fnEnumObjects
-* PARAMETERS
-* HWND hwndOwner, //[in ] Parent Window
-* DWORD grfFlags, //[in ] SHCONTF enumeration mask
-* LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
-*/
-static HRESULT WINAPI IShellFolder_fnEnumObjects(
- IShellFolder2 * iface,
- HWND hwndOwner,
- DWORD dwFlags,
- LPENUMIDLIST* ppEnumIDList)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
-
- *ppEnumIDList = NULL;
- *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
-
- TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
-
- if(!*ppEnumIDList) return E_OUTOFMEMORY;
-
- return S_OK;
-}
-
-/**************************************************************************
-* IShellFolder_fnBindToObject
-* PARAMETERS
-* LPCITEMIDLIST pidl, //[in ] relative pidl to open
-* LPBC pbc, //[in ] reserved
-* REFIID riid, //[in ] Initial Interface
-* LPVOID* ppvObject //[out] Interface*
-*/
-static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
- LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- GUID const * iid;
- IShellFolder *pShellFolder, *pSubFolder;
- IPersistFolder *pPersistFolder;
- LPITEMIDLIST absPidl;
-
- TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
-
- if(!pidl || !ppvOut) return E_INVALIDARG;
-
- *ppvOut = NULL;
-
- if ((iid=_ILGetGUIDPointer(pidl)))
- {
- /* we have to create a alien folder */
- if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
- && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
- {
- absPidl = ILCombine (This->absPidl, pidl);
- IPersistFolder_Initialize(pPersistFolder, absPidl);
- IPersistFolder_Release(pPersistFolder);
- SHFree(absPidl);
- }
- else
- {
- return E_FAIL;
- }
- }
- else if(_ILIsFolder(pidl))
- {
- LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
- pShellFolder = IShellFolder_Constructor(iface, pidltemp);
- ILFree(pidltemp);
- }
- else
- {
- ERR("can't bind to a file\n");
- return E_FAIL;
- }
-
- if (_ILIsPidlSimple(pidl))
- {
- *ppvOut = pShellFolder;
- }
- else
- {
- IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
- IShellFolder_Release(pShellFolder);
- *ppvOut = pSubFolder;
- }
-
- TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
-
- return S_OK;
-}
-
-/**************************************************************************
-* IShellFolder_fnBindToStorage
-* PARAMETERS
-* LPCITEMIDLIST pidl, //[in ] complex pidl to store
-* LPBC pbc, //[in ] reserved
-* REFIID riid, //[in ] Initial storage interface
-* LPVOID* ppvObject //[out] Interface* returned
-*/
-static HRESULT WINAPI IShellFolder_fnBindToStorage(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- LPBC pbcReserved,
- REFIID riid,
- LPVOID *ppvOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
- This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
-
- *ppvOut = NULL;
- return E_NOTIMPL;
-}
-
-/**************************************************************************
-* IShellFolder_fnCompareIDs
-*
-* PARMETERS
-* LPARAM lParam, //[in ] Column?
-* LPCITEMIDLIST pidl1, //[in ] simple pidl
-* LPCITEMIDLIST pidl2) //[in ] simple pidl
-*
-* NOTES
-* Special case - If one of the items is a Path and the other is a File,
-* always make the Path come before the File.
-*
-* NOTES
-* use SCODE_CODE() on the return value to get the result
-*/
-
-static HRESULT WINAPI IShellFolder_fnCompareIDs(
- IShellFolder2 * iface,
- LPARAM lParam,
- LPCITEMIDLIST pidl1,
- LPCITEMIDLIST pidl2)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- CHAR szTemp1[MAX_PATH];
- CHAR szTemp2[MAX_PATH];
- int nReturn;
- IShellFolder * psf;
- HRESULT hr = E_OUTOFMEMORY;
- LPCITEMIDLIST pidlTemp;
- PIDLTYPE pt1, pt2;
-
- TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
- pdump (pidl1);
- pdump (pidl2);
-
- if (!pidl1 && !pidl2)
- {
- hr = ResultFromShort(0);
- }
- else if (!pidl1)
- {
- hr = ResultFromShort(-1);
- }
- else if (!pidl2)
- {
- hr = ResultFromShort(1);
- }
- else
- {
- LPPIDLDATA pd1, pd2;
- pd1 = _ILGetDataPointer(pidl1);
- pd2 = _ILGetDataPointer(pidl2);
-
- /* compate the types. sort order is the PT_* constant */
- pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
- pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
-
- if (pt1 != pt2)
- {
- hr = ResultFromShort(pt1-pt2);
- }
- else /* same type of pidl */
- {
- _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
- _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
- nReturn = strcasecmp(szTemp1, szTemp2);
-
- if (nReturn == 0) /* first pidl different ? */
- {
- pidl1 = ILGetNext(pidl1);
-
- if (pidl1 && pidl1->mkid.cb) /* go deeper? */
- {
- pidlTemp = ILCloneFirst(pidl1);
- pidl2 = ILGetNext(pidl2);
-
- hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
- if (SUCCEEDED(hr))
- {
- nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
- IShellFolder_Release(psf);
- hr = ResultFromShort(nReturn);
- }
- ILFree(pidlTemp);
- }
- else
- {
- hr = ResultFromShort(nReturn); /* two equal simple pidls */
- }
- }
- else
- {
- hr = ResultFromShort(nReturn); /* two different simple pidls */
- }
- }
- }
-
- TRACE("-- res=0x%08lx\n", hr);
- return hr;
-}
-
-/**************************************************************************
-* IShellFolder_fnCreateViewObject
-*/
-static HRESULT WINAPI IShellFolder_fnCreateViewObject(
- IShellFolder2 * iface,
- HWND hwndOwner,
- REFIID riid,
- LPVOID *ppvOut)
+HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot,
+ LPCITEMIDLIST pidlChild, REFCLSID clsid, REFIID iid, LPVOID * ppvOut)
{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- LPSHELLVIEW pShellView;
- HRESULT hr = E_INVALIDARG;
-
- TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
-
- if(ppvOut)
- {
- *ppvOut = NULL;
-
- if(IsEqualIID(riid, &IID_IDropTarget))
- {
- hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
- }
- else if(IsEqualIID(riid, &IID_IContextMenu))
- {
- FIXME("IContextMenu not implemented\n");
- hr = E_NOTIMPL;
- }
- else if(IsEqualIID(riid, &IID_IShellView))
- {
- pShellView = IShellView_Constructor((IShellFolder*)iface);
- if(pShellView)
- {
- hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
- IShellView_Release(pShellView);
- }
- }
- }
- TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
- return hr;
-}
-
-/**************************************************************************
-* IShellFolder_fnGetAttributesOf
-*
-* PARAMETERS
-* UINT cidl, //[in ] num elements in pidl array
-* LPCITEMIDLIST* apidl, //[in ] simple pidl array
-* ULONG* rgfInOut) //[out] result array
-*
-*/
-static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
- IShellFolder2 * iface,
- UINT cidl,
- LPCITEMIDLIST *apidl,
- DWORD *rgfInOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
+ HRESULT hr;
- HRESULT hr = S_OK;
+ TRACE ("%p %p\n", pidlRoot, pidlChild);
- TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
+ if (SUCCEEDED ((hr = SHCoCreateInstance (NULL, clsid, NULL, iid, ppvOut)))) {
- if ( (!cidl) || (!apidl) || (!rgfInOut))
- return E_INVALIDARG;
+ IPersistFolder *pPF;
- while (cidl > 0 && *apidl)
- {
- pdump (*apidl);
- SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
- apidl++;
- cidl--;
- }
+ if (SUCCEEDED ((hr = IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder, (LPVOID *) & pPF)))) {
- TRACE("-- result=0x%08lx\n",*rgfInOut);
+ LPITEMIDLIST pidlAbsolute;
- return hr;
-}
-/**************************************************************************
-* IShellFolder_fnGetUIObjectOf
-*
-* PARAMETERS
-* HWND hwndOwner, //[in ] Parent window for any output
-* UINT cidl, //[in ] array size
-* LPCITEMIDLIST* apidl, //[in ] simple pidl array
-* REFIID riid, //[in ] Requested Interface
-* UINT* prgfInOut, //[ ] reserved
-* LPVOID* ppvObject) //[out] Resulting Interface
-*
-* NOTES
-* This function gets asked to return "view objects" for one or more (multiple select)
-* items:
-* The viewobject typically is an COM object with one of the following interfaces:
-* IExtractIcon,IDataObject,IContextMenu
-* In order to support icon positions in the default Listview your DataObject
-* must implement the SetData method (in addition to GetData :) - the shell passes
-* a barely documented "Icon positions" structure to SetData when the drag starts,
-* and GetData's it if the drop is in another explorer window that needs the positions.
-*/
-static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
- IShellFolder2 * iface,
- HWND hwndOwner,
- UINT cidl,
- LPCITEMIDLIST * apidl,
- REFIID riid,
- UINT * prgfInOut,
- LPVOID * ppvOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- LPITEMIDLIST pidl;
- IUnknown* pObj = NULL;
- HRESULT hr = E_INVALIDARG;
-
- TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
- This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
-
- if (ppvOut)
- {
- *ppvOut = NULL;
-
- if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
- {
- pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
- hr = S_OK;
- }
- else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
- {
- pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
- hr = S_OK;
- }
- else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
- {
- pidl = ILCombine(This->absPidl,apidl[0]);
- pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
- SHFree(pidl);
- hr = S_OK;
- }
- else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
- {
- hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
- }
- else
- {
- hr = E_NOINTERFACE;
- }
-
- if(!pObj)
- hr = E_OUTOFMEMORY;
-
- *ppvOut = pObj;
+ pidlAbsolute = ILCombine (pidlRoot, pidlChild);
+ IPersistFolder_Initialize (pPF, pidlAbsolute);
+ IPersistFolder_Release (pPF);
+ SHFree (pidlAbsolute);
}
- TRACE("(%p)->hr=0x%08lx\n",This, hr);
- return hr;
-}
+ }
-/**************************************************************************
-* IShellFolder_fnGetDisplayNameOf
-* Retrieves the display name for the specified file object or subfolder
-*
-* PARAMETERS
-* LPCITEMIDLIST pidl, //[in ] complex pidl to item
-* DWORD dwFlags, //[in ] SHGNO formatting flags
-* LPSTRRET lpName) //[out] Returned display name
-*
-* FIXME
-* if the name is in the pidl the ret value should be a STRRET_OFFSET
-*/
-#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
-#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
-
-static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- DWORD dwFlags,
- LPSTRRET strRet)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- CHAR szPath[MAX_PATH]= "";
- int len = 0;
- BOOL bSimplePidl;
-
- TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
- pdump(pidl);
-
- if(!pidl || !strRet) return E_INVALIDARG;
-
- bSimplePidl = _ILIsPidlSimple(pidl);
-
- /* take names of special folders only if its only this folder */
- if (_ILIsSpecialFolder(pidl))
- {
- if ( bSimplePidl)
- {
- _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
- }
- }
- else
- {
- if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
- {
- strcpy (szPath, This->sMyPath); /* get path to root*/
- PathAddBackslashA(szPath);
- len = strlen(szPath);
- }
- _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
- }
-
- if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
- {
- PathAddBackslashA(szPath);
- len = strlen(szPath);
-
- if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
- return E_OUTOFMEMORY;
- }
- strRet->uType = STRRET_CSTRA;
- lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
-
- TRACE("-- (%p)->(%s)\n", This, szPath);
- return S_OK;
-}
-
-/**************************************************************************
-* IShellFolder_fnSetNameOf
-* Changes the name of a file object or subfolder, possibly changing its item
-* identifier in the process.
-*
-* PARAMETERS
-* HWND hwndOwner, //[in ] Owner window for output
-* LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
-* LPCOLESTR lpszName, //[in ] the items new display name
-* DWORD dwFlags, //[in ] SHGNO formatting flags
-* LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
-*/
-static HRESULT WINAPI IShellFolder_fnSetNameOf(
- IShellFolder2 * iface,
- HWND hwndOwner,
- LPCITEMIDLIST pidl, /*simple pidl*/
- LPCOLESTR lpName,
- DWORD dwFlags,
- LPITEMIDLIST *pPidlOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- char szSrc[MAX_PATH], szDest[MAX_PATH];
- int len;
- BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
-
- TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
- This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
-
- /* build source path */
- if (dwFlags & SHGDN_INFOLDER)
- {
- strcpy(szSrc, This->sMyPath);
- PathAddBackslashA(szSrc);
- len = strlen (szSrc);
- _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
- }
- else
- {
- SHGetPathFromIDListA(pidl, szSrc);
- }
-
- /* build destination path */
- strcpy(szDest, This->sMyPath);
- PathAddBackslashA(szDest);
- len = strlen (szDest);
- lstrcpynWtoA(szDest+len, lpName, MAX_PATH-len);
-
- TRACE("src=%s dest=%s\n", szSrc, szDest);
- if ( MoveFileA(szSrc, szDest) )
- {
- if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
- SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
- return S_OK;
- }
- return E_FAIL;
+ TRACE ("-- (%p) ret=0x%08lx\n", *ppvOut, hr);
+ return hr;
}
-static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
- IShellFolder2 * iface,
- GUID *pguid)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
- return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellFolder_fnEnumSearches(
- IShellFolder2 * iface,
- IEnumExtraSearch **ppenum)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
- return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
- IShellFolder2 * iface,
- DWORD dwRes,
- ULONG *pSort,
- ULONG *pDisplay)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)\n",This);
-
- if (pSort) *pSort = 0;
- if (pDisplay) *pDisplay = 0;
-
- return S_OK;
-}
-static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
- IShellFolder2 * iface,
- UINT iColumn,
- DWORD *pcsFlags)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)\n",This);
-
- if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
- *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
-
- return S_OK;
-}
-static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- const SHCOLUMNID *pscid,
- VARIANT *pv)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
-
- return E_NOTIMPL;
-}
-static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- UINT iColumn,
- SHELLDETAILS *psd)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- HRESULT hr = E_FAIL;
-
- TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
-
- if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
- if (!pidl)
- {
- /* the header titles */
- psd->fmt = GenericSFHeader[iColumn].fmt;
- psd->cxChar = GenericSFHeader[iColumn].cxChar;
- psd->str.uType = STRRET_CSTRA;
- LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
- return S_OK;
- }
- else
- {
- /* the data from the pidl */
- switch(iColumn)
- {
- case 0: /* name */
- hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
- break;
- case 1: /* size */
- _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
- break;
- case 2: /* type */
- _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
- break;
- case 3: /* date */
- _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
- break;
- case 4: /* attributes */
- _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
- break;
- }
- hr = S_OK;
- psd->str.uType = STRRET_CSTRA;
- }
-
- return hr;
-}
-static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
- IShellFolder2 * iface,
- LPCWSTR pwszName,
- SHCOLUMNID *pscid)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
- return E_NOTIMPL;
-}
-
-static ICOM_VTABLE(IShellFolder2) sfvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- IShellFolder_fnQueryInterface,
- IShellFolder_fnAddRef,
- IShellFolder_fnRelease,
- IShellFolder_fnParseDisplayName,
- IShellFolder_fnEnumObjects,
- IShellFolder_fnBindToObject,
- IShellFolder_fnBindToStorage,
- IShellFolder_fnCompareIDs,
- IShellFolder_fnCreateViewObject,
- IShellFolder_fnGetAttributesOf,
- IShellFolder_fnGetUIObjectOf,
- IShellFolder_fnGetDisplayNameOf,
- IShellFolder_fnSetNameOf,
-
- /* ShellFolder2 */
- IShellFolder_fnGetDefaultSearchGUID,
- IShellFolder_fnEnumSearches,
- IShellFolder_fnGetDefaultColumn,
- IShellFolder_fnGetDefaultColumnState,
- IShellFolder_fnGetDetailsEx,
- IShellFolder_fnGetDetailsOf,
- IShellFolder_fnMapNameToSCID
-};
-
-/****************************************************************************
- * ISFHelper for IShellFolder implementation
- */
-
-static HRESULT WINAPI ISFHelper_fnQueryInterface(
- ISFHelper *iface,
- REFIID riid,
- LPVOID *ppvObj)
-{
- _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
-
- TRACE("(%p)\n", This);
-
- return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
-}
-
-static ULONG WINAPI ISFHelper_fnAddRef(
- ISFHelper *iface)
-{
- _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
-
- TRACE("(%p)\n", This);
-
- return IUnknown_AddRef(This->pUnkOuter);
-}
-
-static ULONG WINAPI ISFHelper_fnRelease(
- ISFHelper *iface)
-{
- _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
-
- TRACE("(%p)\n", This);
-
- return IUnknown_Release(This->pUnkOuter);
-}
-
-
-/****************************************************************************
- * ISFHelper_fnAddFolder
+/***********************************************************************
+ * SHELL32_CoCreateInitSFEx
*
- * creates a unique folder name
- */
-
-static HRESULT WINAPI ISFHelper_fnGetUniqueName(
- ISFHelper *iface,
- LPSTR lpName,
- UINT uLen)
-{
- _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
- IEnumIDList * penum;
- HRESULT hr;
- char szText[MAX_PATH];
- char * szNewFolder = "New Folder";
-
- TRACE("(%p)(%s %u)\n", This, lpName, uLen);
-
- if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
-
- strcpy(lpName, szNewFolder);
-
- hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
- if (penum)
- {
- LPITEMIDLIST pidl;
- DWORD dwFetched;
- int i=1;
-
-next: IEnumIDList_Reset(penum);
- while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
- {
- _ILSimpleGetText(pidl, szText, MAX_PATH);
- if (0 == strcasecmp(szText, lpName))
- {
- sprintf(lpName, "%s %d", szNewFolder, i++);
- if (i > 99)
- {
- hr = E_FAIL;
- break;
- }
- goto next;
- }
- }
-
- IEnumIDList_Release(penum);
- }
- return hr;
-}
-
-/****************************************************************************
- * ISFHelper_fnAddFolder
+ * Creates a shell folder and initializes it with a pidl and a root folder
+ * via IPersistFolder3.
+ * This function is meant for virtual folders backed by a file system
+ * folder.
*
- * adds a new folder.
+ * NOTES
+ * pathRoot can be NULL for Folders beeing a drive.
+ * In this case the absolute path is build from pidlChild (eg. C:)
*/
-
-static HRESULT WINAPI ISFHelper_fnAddFolder(
- ISFHelper *iface,
- HWND hwnd,
- LPCSTR lpName,
- LPITEMIDLIST* ppidlOut)
+HRESULT SHELL32_CoCreateInitSFEx (LPCITEMIDLIST pidlRoot,
+ LPCSTR pathRoot, LPCITEMIDLIST pidlChild, REFCLSID clsid, REFIID riid, LPVOID * ppvOut)
{
- _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
- char lpstrNewDir[MAX_PATH];
- DWORD bRes;
- HRESULT hres = E_FAIL;
-
- TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
+ HRESULT hr;
+ IPersistFolder3 *ppf;
- strcpy(lpstrNewDir, This->sMyPath);
- PathAddBackslashA(lpstrNewDir);
- strcat(lpstrNewDir, lpName);
+ TRACE ("%p %s %p\n", pidlRoot, pathRoot, pidlChild);
- bRes = CreateDirectoryA(lpstrNewDir, NULL);
+ if (SUCCEEDED ((hr = SHCoCreateInstance (NULL, &CLSID_ShellFSFolder, NULL, riid, ppvOut)))) {
+ if (SUCCEEDED (IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder3, (LPVOID *) & ppf))) {
+ PERSIST_FOLDER_TARGET_INFO ppfti;
+ LPITEMIDLIST pidlAbsolute;
+ char szDestPath[MAX_PATH];
- if (bRes)
- {
- LPITEMIDLIST pidl, pidlitem;
+ ZeroMemory (&ppfti, sizeof (ppfti));
- pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
-
- pidl = ILCombine(This->absPidl, pidlitem);
- SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
- SHFree(pidl);
-
- if (ppidlOut) *ppidlOut = pidlitem;
- hres = S_OK;
- }
- else
- {
- char lpstrText[128+MAX_PATH];
- char lpstrTempText[128];
- char lpstrCaption[256];
-
- /* Cannot Create folder because of permissions */
- LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
- LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
- sprintf(lpstrText,lpstrTempText, lpstrNewDir);
- MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
- }
+ /* combine pidls */
+ pidlAbsolute = ILCombine (pidlRoot, pidlChild);
- return hres;
-}
+ /* build path */
+ if (pathRoot) {
+ lstrcpyA (szDestPath, pathRoot);
+ PathAddBackslashA(szDestPath); /* FIXME: why have drives a backslash here ? */
+ } else {
+ szDestPath[0] = '\0';
+ }
-/****************************************************************************
- * ISFHelper_fnDeleteItems
- *
- * deletes items in folder
- */
-static HRESULT WINAPI ISFHelper_fnDeleteItems(
- ISFHelper *iface,
- UINT cidl,
- LPCITEMIDLIST* apidl)
-{
- _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
- int i;
- char szPath[MAX_PATH];
-
- TRACE("(%p)(%u %p)\n", This, cidl, apidl);
-
- for(i=0; i< cidl; i++)
- {
- strcpy(szPath, This->sMyPath);
- PathAddBackslashA(szPath);
- _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
-
- if (_ILIsFolder(apidl[i]))
- {
- LPITEMIDLIST pidl;
-
- MESSAGE("delete %s\n", szPath);
- if (! SHELL_DeleteDirectoryA(szPath, TRUE)) return E_FAIL;
- pidl = ILCombine(This->absPidl, apidl[i]);
- SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
- SHFree(pidl);
- }
- else if (_ILIsValue(apidl[i]))
- {
- LPITEMIDLIST pidl;
-
- MESSAGE("delete %s\n", szPath);
- if (! DeleteFileA(szPath)) return E_FAIL;
- pidl = ILCombine(This->absPidl, apidl[i]);
- SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
- SHFree(pidl);
- }
+ if (pidlChild)
+ lstrcatA (szDestPath, _ILGetTextPointer (pidlChild));
- }
- return S_OK;
-}
+ /* fill the PERSIST_FOLDER_TARGET_INFO */
+ ppfti.dwAttributes = -1;
+ ppfti.csidl = -1;
+ MultiByteToWideChar (CP_ACP, 0, szDestPath, -1, ppfti.szTargetParsingName, MAX_PATH);
-/****************************************************************************
- * ISFHelper_fnCopyItems
- *
- * copys items to this folder
- */
-static HRESULT WINAPI ISFHelper_fnCopyItems(
- ISFHelper *iface,
- IShellFolder* pSFFrom,
- UINT cidl,
- LPCITEMIDLIST *apidl)
-{
- int i;
- IPersistFolder2 * ppf2=NULL;
- char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
- _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
-
- TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
-
- IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
- if (ppf2)
- {
- LPITEMIDLIST pidl;
- if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
- {
- for (i=0; i<cidl; i++)
- {
- SHGetPathFromIDListA(pidl, szSrcPath);
- PathAddBackslashA(szSrcPath);
- _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
-
- strcpy(szDstPath, This->sMyPath);
- PathAddBackslashA(szDstPath);
- _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
- MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
- }
- SHFree(pidl);
- }
- IPersistFolder2_Release(ppf2);
+ IPersistFolder3_InitializeEx (ppf, NULL, pidlAbsolute, &ppfti);
+ IPersistFolder3_Release (ppf);
+ ILFree (pidlAbsolute);
}
- return S_OK;
+ }
+ TRACE ("-- (%p) ret=0x%08lx\n", *ppvOut, hr);
+ return hr;
}
-static ICOM_VTABLE(ISFHelper) shvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- ISFHelper_fnQueryInterface,
- ISFHelper_fnAddRef,
- ISFHelper_fnRelease,
- ISFHelper_fnGetUniqueName,
- ISFHelper_fnAddFolder,
- ISFHelper_fnDeleteItems,
- ISFHelper_fnCopyItems,
-};
-
/***********************************************************************
-* [Desktopfolder] IShellFolder implementation
-*/
-static struct ICOM_VTABLE(IShellFolder2) sfdvt;
-
-static shvheader DesktopSFHeader [] =
-{
- { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
- { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
- { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
-};
-#define DESKTOPSHELLVIEWCOLUMNS 5
-
-/**************************************************************************
-* ISF_Desktop_Constructor
-*
-*/
-IShellFolder * ISF_Desktop_Constructor()
-{
- IGenericSFImpl * sf;
-
- sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
- sf->ref=1;
- ICOM_VTBL(sf)=&unkvt;
- sf->lpvtblShellFolder=&sfdvt;
- sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
- sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
-
- TRACE("(%p)\n",sf);
-
- shell32_ObjCount++;
- return _IShellFolder_(sf);
-}
-
-/**************************************************************************
- * ISF_Desktop_fnQueryInterface
+ * SHELL32_BindToChild
*
- * NOTES supports not IPersist/IPersistFolder
+ * Common code for IShellFolder_BindToObject.
+ * Creates a shell folder by binding to a root pidl.
*/
-static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
- IShellFolder2 * iface,
- REFIID riid,
- LPVOID *ppvObj)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
-
- *ppvObj = NULL;
-
- if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
- {
- *ppvObj = _IUnknown_(This);
- }
- else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
- {
- *ppvObj = _IShellFolder_(This);
- }
- else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
- {
- *ppvObj = _IShellFolder_(This);
- }
-
- if(*ppvObj)
- {
- IUnknown_AddRef((IUnknown*)(*ppvObj));
- TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
- return S_OK;
- }
- TRACE("-- Interface: E_NOINTERFACE\n");
- return E_NOINTERFACE;
-}
-
-/**************************************************************************
-* ISF_Desktop_fnParseDisplayName
-*
-* NOTES
-* "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
-* to MyComputer
-*/
-static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
- IShellFolder2 * iface,
- HWND hwndOwner,
- LPBC pbcReserved,
- LPOLESTR lpszDisplayName,
- DWORD *pchEaten,
- LPITEMIDLIST *ppidl,
- DWORD *pdwAttributes)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- LPCWSTR szNext=NULL;
- LPITEMIDLIST pidlTemp=NULL;
- HRESULT hr=E_OUTOFMEMORY;
-
- TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
- This,hwndOwner,pbcReserved,lpszDisplayName,
- debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
-
- *ppidl = 0;
- if (pchEaten) *pchEaten = 0; /* strange but like the original */
-
- /* fixme no real parsing implemented */
- pidlTemp = _ILCreateMyComputer();
- szNext = lpszDisplayName;
-
- if (szNext && *szNext)
- {
- hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
- }
- else
- {
- hr = S_OK;
-
- if (pdwAttributes && *pdwAttributes)
- {
- SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
- }
- }
-
- *ppidl = pidlTemp;
-
- TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
-
- return hr;
-}
-
-/**************************************************************************
-* ISF_Desktop_fnEnumObjects
-*/
-static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
- IShellFolder2 * iface,
- HWND hwndOwner,
- DWORD dwFlags,
- LPENUMIDLIST* ppEnumIDList)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
-
- *ppEnumIDList = NULL;
- *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
-
- TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
-
- if(!*ppEnumIDList) return E_OUTOFMEMORY;
-
- return S_OK;
-}
-
-/**************************************************************************
-* ISF_Desktop_fnBindToObject
-*/
-static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
- LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
+ LPCSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- GUID const * clsid;
- IShellFolder *pShellFolder, *pSubFolder;
-
- TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
- This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
-
- *ppvOut = NULL;
-
- if ((clsid=_ILGetGUIDPointer(pidl)))
- {
- if ( IsEqualIID(clsid, &CLSID_MyComputer))
- {
- pShellFolder = ISF_MyComputer_Constructor();
- }
- else
- {
- /* shell extension */
- if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
- {
- return E_INVALIDARG;
- }
- }
- }
- else
- {
- /* file system folder on the desktop */
- LPITEMIDLIST deskpidl, firstpidl, completepidl;
- IPersistFolder * ppf;
-
- /* combine pidls */
- SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
- firstpidl = ILCloneFirst(pidl);
- completepidl = ILCombine(deskpidl, firstpidl);
-
- pShellFolder = IShellFolder_Constructor(NULL, NULL);
- if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
- {
- IPersistFolder_Initialize(ppf, completepidl);
- IPersistFolder_Release(ppf);
- }
- ILFree(completepidl);
- ILFree(deskpidl);
- ILFree(firstpidl);
- }
-
- if (_ILIsPidlSimple(pidl)) /* no sub folders */
- {
- *ppvOut = pShellFolder;
- }
- else /* go deeper */
- {
- IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
- IShellFolder_Release(pShellFolder);
- *ppvOut = pSubFolder;
- }
+ GUID const *clsid;
+ IShellFolder *pSF;
+ HRESULT hr;
+ LPITEMIDLIST pidlChild;
- TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
-
- return S_OK;
-}
-
-/**************************************************************************
-* ISF_Desktop_fnCreateViewObject
-*/
-static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
- HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- LPSHELLVIEW pShellView;
- HRESULT hr = E_INVALIDARG;
-
- TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
-
- if(ppvOut)
- {
- *ppvOut = NULL;
-
- if(IsEqualIID(riid, &IID_IDropTarget))
- {
- WARN("IDropTarget not implemented\n");
- hr = E_NOTIMPL;
- }
- else if(IsEqualIID(riid, &IID_IContextMenu))
- {
- WARN("IContextMenu not implemented\n");
- hr = E_NOTIMPL;
- }
- else if(IsEqualIID(riid, &IID_IShellView))
- {
- pShellView = IShellView_Constructor((IShellFolder*)iface);
- if(pShellView)
- {
- hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
- IShellView_Release(pShellView);
- }
- }
- }
- TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
- return hr;
-}
-
-/**************************************************************************
-* ISF_Desktop_fnGetAttributesOf
-*/
-static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
- IShellFolder2 * iface,
- UINT cidl,
- LPCITEMIDLIST *apidl,
- DWORD *rgfInOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
+ if (!pidlRoot || !ppvOut)
+ return E_INVALIDARG;
- HRESULT hr = S_OK;
+ *ppvOut = NULL;
- TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
+ pidlChild = ILCloneFirst (pidlComplete);
- if ( (!cidl) || (!apidl) || (!rgfInOut))
- return E_INVALIDARG;
+ if ((clsid = _ILGetGUIDPointer (pidlChild))) {
+ /* virtual folder */
+ hr = SHELL32_CoCreateInitSF (pidlRoot, pidlChild, clsid, &IID_IShellFolder, (LPVOID *) & pSF);
+ } else {
+ /* file system folder */
+ hr = SHELL32_CoCreateInitSFEx (pidlRoot, pathRoot, pidlChild, &CLSID_ShellFSFolder, &IID_IShellFolder,
+ (LPVOID *) & pSF);
+ }
+ ILFree (pidlChild);
- while (cidl > 0 && *apidl)
- {
- pdump (*apidl);
- SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
- apidl++;
- cidl--;
+ if (SUCCEEDED (hr)) {
+ if (_ILIsPidlSimple (pidlComplete)) {
+ /* no sub folders */
+ hr = IShellFolder_QueryInterface (pSF, riid, ppvOut);
+ } else {
+ /* go deeper */
+ hr = IShellFolder_BindToObject (pSF, ILGetNext (pidlComplete), NULL, riid, ppvOut);
}
+ IShellFolder_Release (pSF);
+ }
- TRACE("-- result=0x%08lx\n",*rgfInOut);
+ TRACE ("-- returning (%p) %08lx\n", *ppvOut, hr);
- return hr;
+ return hr;
}
-/**************************************************************************
-* ISF_Desktop_fnGetDisplayNameOf
-*
-* NOTES
-* special case: pidl = null gives desktop-name back
-*/
-static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- DWORD dwFlags,
- LPSTRRET strRet)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- CHAR szPath[MAX_PATH]= "";
-
- TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
- pdump(pidl);
-
- if(!strRet) return E_INVALIDARG;
-
- if(!pidl)
- {
- HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
- }
- else if ( _ILIsPidlSimple(pidl) )
- {
- _ILSimpleGetText(pidl, szPath, MAX_PATH);
- }
- else
- {
- if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
- return E_OUTOFMEMORY;
- }
- strRet->uType = STRRET_CSTRA;
- lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
-
-
- TRACE("-- (%p)->(%s)\n", This, szPath);
- return S_OK;
-}
-
-static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
- IShellFolder2 * iface,
- GUID *pguid)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
- return E_NOTIMPL;
-}
-static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
- IShellFolder2 * iface,
- IEnumExtraSearch **ppenum)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
- return E_NOTIMPL;
-}
-static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
- IShellFolder2 * iface,
- DWORD dwRes,
- ULONG *pSort,
- ULONG *pDisplay)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)\n",This);
-
- if (pSort) *pSort = 0;
- if (pDisplay) *pDisplay = 0;
-
- return S_OK;
-}
-static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
- IShellFolder2 * iface,
- UINT iColumn,
- DWORD *pcsFlags)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)\n",This);
-
- if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
- *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
-
- return S_OK;
-}
-static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- const SHCOLUMNID *pscid,
- VARIANT *pv)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
-
- return E_NOTIMPL;
-}
-static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- UINT iColumn,
- SHELLDETAILS *psd)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- HRESULT hr = E_FAIL;;
-
- TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
-
- if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
- if (!pidl)
- {
- psd->fmt = DesktopSFHeader[iColumn].fmt;
- psd->cxChar = DesktopSFHeader[iColumn].cxChar;
- psd->str.uType = STRRET_CSTRA;
- LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
- return S_OK;
- }
- else
- {
- /* the data from the pidl */
- switch(iColumn)
- {
- case 0: /* name */
- hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
- break;
- case 1: /* size */
- _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
- break;
- case 2: /* type */
- _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
- break;
- case 3: /* date */
- _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
- break;
- case 4: /* attributes */
- _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
- break;
- }
- hr = S_OK;
- psd->str.uType = STRRET_CSTRA;
- }
-
- return hr;
-}
-static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
- IShellFolder2 * iface,
- LPCWSTR pwszName,
- SHCOLUMNID *pscid)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
- return E_NOTIMPL;
-}
-
-static ICOM_VTABLE(IShellFolder2) sfdvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- ISF_Desktop_fnQueryInterface,
- IShellFolder_fnAddRef,
- IShellFolder_fnRelease,
- ISF_Desktop_fnParseDisplayName,
- ISF_Desktop_fnEnumObjects,
- ISF_Desktop_fnBindToObject,
- IShellFolder_fnBindToStorage,
- IShellFolder_fnCompareIDs,
- ISF_Desktop_fnCreateViewObject,
- ISF_Desktop_fnGetAttributesOf,
- IShellFolder_fnGetUIObjectOf,
- ISF_Desktop_fnGetDisplayNameOf,
- IShellFolder_fnSetNameOf,
-
- /* ShellFolder2 */
- ISF_Desktop_fnGetDefaultSearchGUID,
- ISF_Desktop_fnEnumSearches,
- ISF_Desktop_fnGetDefaultColumn,
- ISF_Desktop_fnGetDefaultColumnState,
- ISF_Desktop_fnGetDetailsEx,
- ISF_Desktop_fnGetDetailsOf,
- ISF_Desktop_fnMapNameToSCID
-};
-
-
/***********************************************************************
-* IShellFolder [MyComputer] implementation
-*/
-
-static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
-
-static shvheader MyComputerSFHeader [] =
-{
- { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
- { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
- { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
-};
-#define MYCOMPUTERSHELLVIEWCOLUMNS 4
-
-/**************************************************************************
-* ISF_MyComputer_Constructor
-*/
-static IShellFolder * ISF_MyComputer_Constructor(void)
-{
- IGenericSFImpl * sf;
-
- sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
- sf->ref=1;
-
- ICOM_VTBL(sf)=&unkvt;
- sf->lpvtblShellFolder=&sfmcvt;
- sf->lpvtblPersistFolder2 = &psfvt;
- sf->pclsid = (CLSID*)&CLSID_SFMyComp;
- sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
- sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
-
- TRACE("(%p)\n",sf);
-
- shell32_ObjCount++;
- return _IShellFolder_(sf);
-}
-
-/**************************************************************************
-* ISF_MyComputer_fnParseDisplayName
-*/
-static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
- IShellFolder2 * iface,
- HWND hwndOwner,
- LPBC pbcReserved,
- LPOLESTR lpszDisplayName,
- DWORD *pchEaten,
- LPITEMIDLIST *ppidl,
- DWORD *pdwAttributes)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- HRESULT hr = E_OUTOFMEMORY;
- LPCWSTR szNext=NULL;
- WCHAR szElement[MAX_PATH];
- CHAR szTempA[MAX_PATH];
- LPITEMIDLIST pidlTemp;
-
- TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
- This,hwndOwner,pbcReserved,lpszDisplayName,
- debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
-
- *ppidl = 0;
- if (pchEaten) *pchEaten = 0; /* strange but like the original */
-
- /* do we have an absolute path name ? */
- if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
- lpszDisplayName[2] == (WCHAR)'\\')
- {
- szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
- lstrcpynWtoA(szTempA, szElement, lstrlenW(szElement) + 1);
- pidlTemp = _ILCreateDrive(szTempA);
-
- if (szNext && *szNext)
- {
- hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
- }
- else
- {
- if (pdwAttributes && *pdwAttributes)
- {
- SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
- }
- hr = S_OK;
- }
- *ppidl = pidlTemp;
- }
-
- TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
-
- return hr;
-}
-
-/**************************************************************************
-* ISF_MyComputer_fnEnumObjects
-*/
-static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
- IShellFolder2 * iface,
- HWND hwndOwner,
- DWORD dwFlags,
- LPENUMIDLIST* ppEnumIDList)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
-
- *ppEnumIDList = NULL;
- *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
-
- TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
-
- if(!*ppEnumIDList) return E_OUTOFMEMORY;
-
- return S_OK;
-}
-
-/**************************************************************************
-* ISF_MyComputer_fnBindToObject
-*/
-static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
- LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- GUID const * clsid;
- IShellFolder *pShellFolder, *pSubFolder;
- LPITEMIDLIST pidltemp;
-
- TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
- This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
-
- if(!pidl || !ppvOut) return E_INVALIDARG;
-
- *ppvOut = NULL;
-
- if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
- {
- if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
- {
- return E_FAIL;
- }
- }
- else
- {
- if (!_ILIsDrive(pidl)) return E_INVALIDARG;
-
- pidltemp = ILCloneFirst(pidl);
- pShellFolder = IShellFolder_Constructor(iface, pidltemp);
- ILFree(pidltemp);
- }
-
- if (_ILIsPidlSimple(pidl)) /* no sub folders */
- {
- *ppvOut = pShellFolder;
- }
- else /* go deeper */
- {
- IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
- IShellFolder_Release(pShellFolder);
- *ppvOut = pSubFolder;
- }
-
- TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
-
- return S_OK;
-}
-
-/**************************************************************************
-* ISF_MyComputer_fnCreateViewObject
-*/
-static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
- HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- LPSHELLVIEW pShellView;
- HRESULT hr = E_INVALIDARG;
-
- TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
-
- if(ppvOut)
- {
- *ppvOut = NULL;
-
- if(IsEqualIID(riid, &IID_IDropTarget))
- {
- WARN("IDropTarget not implemented\n");
- hr = E_NOTIMPL;
- }
- else if(IsEqualIID(riid, &IID_IContextMenu))
- {
- WARN("IContextMenu not implemented\n");
- hr = E_NOTIMPL;
- }
- else if(IsEqualIID(riid, &IID_IShellView))
- {
- pShellView = IShellView_Constructor((IShellFolder*)iface);
- if(pShellView)
- {
- hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
- IShellView_Release(pShellView);
- }
- }
- }
- TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
- return hr;
-}
-
-/**************************************************************************
-* ISF_MyComputer_fnGetAttributesOf
-*/
-static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
- IShellFolder2 * iface,
- UINT cidl,
- LPCITEMIDLIST *apidl,
- DWORD *rgfInOut)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- HRESULT hr = S_OK;
-
- TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
-
- if ( (!cidl) || (!apidl) || (!rgfInOut))
- return E_INVALIDARG;
-
- while (cidl > 0 && *apidl)
- {
- pdump (*apidl);
- SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
- apidl++;
- cidl--;
- }
-
- TRACE("-- result=0x%08lx\n",*rgfInOut);
- return hr;
-}
-
-/**************************************************************************
-* ISF_MyComputer_fnGetDisplayNameOf
-*
-* NOTES
-* The desktopfolder creates only complete paths (SHGDN_FORPARSING).
-* SHGDN_INFOLDER makes no sense.
-*/
-static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- DWORD dwFlags,
- LPSTRRET strRet)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- char szPath[MAX_PATH], szDrive[18];
- int len = 0;
- BOOL bSimplePidl;
-
- TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
- pdump(pidl);
-
- if(!strRet) return E_INVALIDARG;
-
- szPath[0]=0x00; szDrive[0]=0x00;
-
-
- bSimplePidl = _ILIsPidlSimple(pidl);
-
- if (_ILIsSpecialFolder(pidl))
- {
- /* take names of special folders only if its only this folder */
- if ( bSimplePidl )
- {
- _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
- }
- }
- else
- {
- if (!_ILIsDrive(pidl))
- {
- ERR("Wrong pidl type\n");
- return E_INVALIDARG;
- }
-
- _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
-
- /* long view "lw_name (C:)" */
- if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
- {
- DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
-
- GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
- strcat (szDrive," (");
- strncat (szDrive, szPath, 2);
- strcat (szDrive,")");
- strcpy (szPath, szDrive);
- }
- }
-
- if (!bSimplePidl) /* go deeper if needed */
- {
- PathAddBackslashA(szPath);
- len = strlen(szPath);
-
- if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
- return E_OUTOFMEMORY;
- }
- strRet->uType = STRRET_CSTRA;
- lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
-
-
- TRACE("-- (%p)->(%s)\n", This, szPath);
- return S_OK;
-}
-
-static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
- IShellFolder2 * iface,
- GUID *pguid)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
- return E_NOTIMPL;
-}
-static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
- IShellFolder2 * iface,
- IEnumExtraSearch **ppenum)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
- return E_NOTIMPL;
-}
-static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
- IShellFolder2 * iface,
- DWORD dwRes,
- ULONG *pSort,
- ULONG *pDisplay)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)\n",This);
-
- if (pSort) *pSort = 0;
- if (pDisplay) *pDisplay = 0;
-
- return S_OK;
-}
-static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
- IShellFolder2 * iface,
- UINT iColumn,
- DWORD *pcsFlags)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
-
- TRACE("(%p)\n",This);
-
- if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
- *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
-
- return S_OK;
-}
-static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- const SHCOLUMNID *pscid,
- VARIANT *pv)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
-
- return E_NOTIMPL;
-}
-
-/* fixme: drive size >4GB is rolling over */
-static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
- IShellFolder2 * iface,
- LPCITEMIDLIST pidl,
- UINT iColumn,
- SHELLDETAILS *psd)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- HRESULT hr;
-
- TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
-
- if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
-
- if (!pidl)
- {
- psd->fmt = MyComputerSFHeader[iColumn].fmt;
- psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
- psd->str.uType = STRRET_CSTRA;
- LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
- return S_OK;
- }
- else
- {
- char szPath[MAX_PATH];
- ULARGE_INTEGER ulBytes;
-
- psd->str.u.cStr[0] = 0x00;
- psd->str.uType = STRRET_CSTRA;
- switch(iColumn)
- {
- case 0: /* name */
- hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
- break;
- case 1: /* type */
- _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
- break;
- case 2: /* total size */
- if (_ILIsDrive(pidl))
- {
- _ILSimpleGetText(pidl, szPath, MAX_PATH);
- GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
- StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
- }
- break;
- case 3: /* free size */
- if (_ILIsDrive(pidl))
- {
- _ILSimpleGetText(pidl, szPath, MAX_PATH);
- GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
- StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
- }
- break;
- }
- hr = S_OK;
- }
-
- return hr;
-}
-static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
- IShellFolder2 * iface,
- LPCWSTR pwszName,
- SHCOLUMNID *pscid)
-{
- _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
- FIXME("(%p)\n",This);
- return E_NOTIMPL;
-}
-
-static ICOM_VTABLE(IShellFolder2) sfmcvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- IShellFolder_fnQueryInterface,
- IShellFolder_fnAddRef,
- IShellFolder_fnRelease,
- ISF_MyComputer_fnParseDisplayName,
- ISF_MyComputer_fnEnumObjects,
- ISF_MyComputer_fnBindToObject,
- IShellFolder_fnBindToStorage,
- IShellFolder_fnCompareIDs,
- ISF_MyComputer_fnCreateViewObject,
- ISF_MyComputer_fnGetAttributesOf,
- IShellFolder_fnGetUIObjectOf,
- ISF_MyComputer_fnGetDisplayNameOf,
- IShellFolder_fnSetNameOf,
-
- /* ShellFolder2 */
- ISF_MyComputer_fnGetDefaultSearchGUID,
- ISF_MyComputer_fnEnumSearches,
- ISF_MyComputer_fnGetDefaultColumn,
- ISF_MyComputer_fnGetDefaultColumnState,
- ISF_MyComputer_fnGetDetailsEx,
- ISF_MyComputer_fnGetDetailsOf,
- ISF_MyComputer_fnMapNameToSCID
-};
-
-
-/************************************************************************
- * ISFPersistFolder_QueryInterface (IUnknown)
+ * SHELL32_GetDisplayNameOfChild
*
- */
-static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
- IPersistFolder2 * iface,
- REFIID iid,
- LPVOID* ppvObj)
-{
- _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
-
- TRACE("(%p)\n", This);
-
- return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
-}
-
-/************************************************************************
- * ISFPersistFolder_AddRef (IUnknown)
+ * Retrives the display name of a child object of a shellfolder.
*
- */
-static ULONG WINAPI ISFPersistFolder2_AddRef(
- IPersistFolder2 * iface)
-{
- _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
-
- TRACE("(%p)\n", This);
-
- return IUnknown_AddRef(This->pUnkOuter);
-}
-
-/************************************************************************
- * ISFPersistFolder_Release (IUnknown)
+ * For a pidl eg. [subpidl1][subpidl2][subpidl3]:
+ * - it binds to the child shellfolder [subpidl1]
+ * - asks it for the displayname of [subpidl2][subpidl3]
*
+ * Is possible the pidl is a simple pidl. In this case it asks the
+ * subfolder for the displayname of a empty pidl. The subfolder
+ * returns the own displayname eg. "::{guid}". This is used for
+ * virtual folders with the registry key WantsFORPARSING set.
*/
-static ULONG WINAPI ISFPersistFolder2_Release(
- IPersistFolder2 * iface)
+HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf,
+ LPCITEMIDLIST pidl, DWORD dwFlags, LPSTR szOut, DWORD dwOutLen)
{
- _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+ LPITEMIDLIST pidlFirst;
+ HRESULT hr = E_OUTOFMEMORY;
- TRACE("(%p)\n", This);
+ TRACE ("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n", psf, pidl, dwFlags, szOut, dwOutLen);
+ pdump (pidl);
- return IUnknown_Release(This->pUnkOuter);
-}
+ pidlFirst = ILCloneFirst (pidl);
+ if (pidlFirst) {
+ IShellFolder2 *psfChild;
-/************************************************************************
- * ISFPersistFolder_GetClassID (IPersist)
- */
-static HRESULT WINAPI ISFPersistFolder2_GetClassID(
- IPersistFolder2 * iface,
- CLSID * lpClassId)
-{
- _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
+ hr = IShellFolder_BindToObject (psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID *) & psfChild);
+ if (SUCCEEDED (hr)) {
+ STRRET strTemp;
+ LPITEMIDLIST pidlNext = ILGetNext (pidl);
- TRACE("(%p)\n", This);
+ hr = IShellFolder_GetDisplayNameOf (psfChild, pidlNext, dwFlags, &strTemp);
+ if (SUCCEEDED (hr)) {
+ hr = StrRetToStrNA (szOut, dwOutLen, &strTemp, pidlNext);
+ }
+ IShellFolder_Release (psfChild);
+ }
+ ILFree (pidlFirst);
+ }
- if (!lpClassId) return E_POINTER;
- *lpClassId = *This->pclsid;
+ TRACE ("-- ret=0x%08lx %s\n", hr, szOut);
- return S_OK;
+ return hr;
}
-/************************************************************************
- * ISFPersistFolder_Initialize (IPersistFolder)
+/***********************************************************************
+ * SHELL32_GetItemAttributes
*
* NOTES
- * sMyPath is not set. Don't know how to handle in a non rooted environment.
+ * observerd values:
+ * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
+ * file: 0x40000177 FILESYSTEM
+ * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
+ * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
+ * (seems to be default for shell extensions if no registry entry exists)
+ *
+ * win2k:
+ * folder: 0xF0400177 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER
+ * file: 0x40400177 FILESYSTEM | CANMONIKER
+ * drive 0xF0400154 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR | CANMONIKER | CANRENAME (LABEL)
+ *
+ * This functions does not set flags!! It only resets flags when nessesary.
*/
-static HRESULT WINAPI ISFPersistFolder2_Initialize(
- IPersistFolder2 * iface,
- LPCITEMIDLIST pidl)
-{
- char sTemp[MAX_PATH];
- _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
-
- TRACE("(%p)->(%p)\n", This, pidl);
-
- /* free the old stuff */
- if(This->absPidl)
- {
- SHFree(This->absPidl);
- This->absPidl = NULL;
- }
- if(This->sMyPath)
- {
- SHFree(This->sMyPath);
- This->sMyPath = NULL;
+HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes)
+{
+ GUID const *clsid;
+ DWORD dwAttributes;
+ DWORD dwSupportedAttr=SFGAO_CANCOPY | /*0x00000001 */
+ SFGAO_CANMOVE | /*0x00000002 */
+ SFGAO_CANLINK | /*0x00000004 */
+ SFGAO_CANRENAME | /*0x00000010 */
+ SFGAO_CANDELETE | /*0x00000020 */
+ SFGAO_HASPROPSHEET | /*0x00000040 */
+ SFGAO_DROPTARGET | /*0x00000100 */
+ SFGAO_READONLY | /*0x00040000 */
+ SFGAO_HIDDEN | /*0x00080000 */
+ SFGAO_FILESYSANCESTOR | /*0x10000000 */
+ SFGAO_FOLDER | /*0x20000000 */
+ SFGAO_FILESYSTEM | /*0x40000000 */
+ SFGAO_HASSUBFOLDER; /*0x80000000 */
+
+ TRACE ("0x%08lx\n", *pdwAttributes);
+
+ if (*pdwAttributes & ~dwSupportedAttr)
+ {
+ WARN ("attributes 0x%08lx not implemented\n", (*pdwAttributes & ~dwSupportedAttr));
+ *pdwAttributes &= dwSupportedAttr;
+ }
+
+ if (_ILIsDrive (pidl)) {
+ *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FILESYSTEM|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANLINK;
+ } else if ((clsid = _ILGetGUIDPointer (pidl))) {
+ if (HCR_GetFolderAttributes (clsid, &dwAttributes)) {
+ *pdwAttributes &= dwAttributes;
+ } else {
+ *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK;
}
+ } else if (_ILGetDataPointer (pidl)) {
+ dwAttributes = _ILGetFileAttributes (pidl, NULL, 0);
+ *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
- /* set my pidl */
- This->absPidl = ILClone(pidl);
-
- /* set my path */
- if (SHGetPathFromIDListA(pidl, sTemp))
- {
- This->sMyPath = SHAlloc(strlen(sTemp)+1);
- strcpy(This->sMyPath, sTemp);
- }
+ if ((SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ *pdwAttributes &= ~(SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
- TRACE("--(%p)->(%s)\n", This, This->sMyPath);
+ if ((SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
+ *pdwAttributes &= ~SFGAO_HIDDEN;
- return S_OK;
+ if ((SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
+ *pdwAttributes &= ~SFGAO_READONLY;
+ } else {
+ *pdwAttributes &= SFGAO_HASSUBFOLDER|SFGAO_FOLDER|SFGAO_FILESYSANCESTOR|SFGAO_DROPTARGET|SFGAO_HASPROPSHEET|SFGAO_CANRENAME|SFGAO_CANLINK;
+ }
+ TRACE ("-- 0x%08lx\n", *pdwAttributes);
+ return S_OK;
}
-/**************************************************************************
-* IPersistFolder2_fnGetCurFolder
-*/
-static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
- IPersistFolder2 * iface,
- LPITEMIDLIST * pidl)
-{
- _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
-
- TRACE("(%p)->(%p)\n",This, pidl);
-
- if (!pidl) return E_POINTER;
-
- *pidl = ILClone(This->absPidl);
-
- return S_OK;
-}
-
-static ICOM_VTABLE(IPersistFolder2) psfvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- ISFPersistFolder2_QueryInterface,
- ISFPersistFolder2_AddRef,
- ISFPersistFolder2_Release,
- ISFPersistFolder2_GetClassID,
- ISFPersistFolder2_Initialize,
- ISFPersistFolder2_fnGetCurFolder
-};
-
-/****************************************************************************
- * ISFDropTarget implementation
+/***********************************************************************
+ * SHELL32_CompareIDs
*/
-static BOOL ISFDropTarget_QueryDrop(
- IDropTarget *iface,
- DWORD dwKeyState,
- LPDWORD pdwEffect)
-{
- DWORD dwEffect = *pdwEffect;
-
- _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
- *pdwEffect = DROPEFFECT_NONE;
-
- if (This->fAcceptFmt)
- { /* Does our interpretation of the keystate ... */
- *pdwEffect = KeyStateToDropEffect(dwKeyState);
-
- /* ... matches the desired effect ? */
- if (dwEffect & *pdwEffect)
- {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static HRESULT WINAPI ISFDropTarget_QueryInterface(
- IDropTarget *iface,
- REFIID riid,
- LPVOID *ppvObj)
-{
- _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
- TRACE("(%p)\n", This);
-
- return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
+HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+{
+ int type1,
+ type2;
+ char szTemp1[MAX_PATH];
+ char szTemp2[MAX_PATH];
+ int nReturn = 0;
+ LPITEMIDLIST firstpidl,
+ nextpidl1,
+ nextpidl2;
+ IShellFolder *psf;
+
+ /* test for empty pidls */
+ BOOL isEmpty1 = _ILIsDesktop (pidl1);
+ BOOL isEmpty2 = _ILIsDesktop (pidl2);
+
+ if (isEmpty1 && isEmpty2)
+ return 0;
+ if (isEmpty1)
+ return -1;
+ if (isEmpty2)
+ return 1;
+
+ /* test for different types. Sort order is the PT_* constant */
+ type1 = _ILGetDataPointer (pidl1)->type;
+ type2 = _ILGetDataPointer (pidl2)->type;
+ if (type1 != type2)
+ return (type1 - type2);
+
+ /* test for name of pidl */
+ _ILSimpleGetText (pidl1, szTemp1, MAX_PATH);
+ _ILSimpleGetText (pidl2, szTemp2, MAX_PATH);
+ nReturn = strcasecmp (szTemp1, szTemp2);
+ if (nReturn != 0)
+ return nReturn;
+
+ /* test of complex pidls */
+ firstpidl = ILCloneFirst (pidl1);
+ nextpidl1 = ILGetNext (pidl1);
+ nextpidl2 = ILGetNext (pidl2);
+
+ /* optimizing: test special cases and bind not deeper */
+ /* the deeper shellfolder would do the same */
+ isEmpty1 = _ILIsDesktop (nextpidl1);
+ isEmpty2 = _ILIsDesktop (nextpidl2);
+
+ if (isEmpty1 && isEmpty2) {
+ nReturn = 0;
+ } else if (isEmpty1) {
+ nReturn = -1;
+ } else if (isEmpty2) {
+ nReturn = 1;
+ /* optimizing end */
+ } else if (SUCCEEDED (IShellFolder_BindToObject (iface, firstpidl, NULL, &IID_IShellFolder, (LPVOID *) & psf))) {
+ nReturn = IShellFolder_CompareIDs (psf, lParam, nextpidl1, nextpidl2);
+ IShellFolder_Release (psf);
+ }
+ ILFree (firstpidl);
+ return nReturn;
}
-static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
-{
- _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
- TRACE("(%p)\n", This);
-
- return IUnknown_AddRef(This->pUnkOuter);
-}
-
-static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
-{
- _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
- TRACE("(%p)\n", This);
-
- return IUnknown_Release(This->pUnkOuter);
-}
-
-static HRESULT WINAPI ISFDropTarget_DragEnter(
- IDropTarget *iface,
- IDataObject *pDataObject,
- DWORD dwKeyState,
- POINTL pt,
- DWORD *pdwEffect)
-{
- FORMATETC fmt;
-
- _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
- TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
-
- InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
-
- This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
-
- ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
-
- return S_OK;
-}
-
-static HRESULT WINAPI ISFDropTarget_DragOver(
- IDropTarget *iface,
- DWORD dwKeyState,
- POINTL pt,
- DWORD *pdwEffect)
-{
- _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
- TRACE("(%p)\n",This);
-
- if(!pdwEffect) return E_INVALIDARG;
-
- ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
-
- return S_OK;
-}
-
-static HRESULT WINAPI ISFDropTarget_DragLeave(
- IDropTarget *iface)
-{
- _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
- TRACE("(%p)\n",This);
-
- This->fAcceptFmt = FALSE;
-
- return S_OK;
-}
-
-static HRESULT WINAPI ISFDropTarget_Drop(
- IDropTarget *iface,
- IDataObject* pDataObject,
- DWORD dwKeyState,
- POINTL pt,
- DWORD *pdwEffect)
+/***********************************************************************
+ * SHCreateLinks
+ *
+ * Undocumented.
+ */
+HRESULT WINAPI SHCreateLinks( HWND hWnd, LPCSTR lpszDir, LPDATAOBJECT lpDataObject,
+ UINT uFlags, LPITEMIDLIST *lppidlLinks)
{
- _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
-
- FIXME("(%p) object dropped\n",This);
-
- return E_NOTIMPL;
+ FIXME("%p %s %p %08x %p\n",hWnd,lpszDir,lpDataObject,uFlags,lppidlLinks);
+ return E_NOTIMPL;
}
-
-static struct ICOM_VTABLE(IDropTarget) dtvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- ISFDropTarget_QueryInterface,
- ISFDropTarget_AddRef,
- ISFDropTarget_Release,
- ISFDropTarget_DragEnter,
- ISFDropTarget_DragOver,
- ISFDropTarget_DragLeave,
- ISFDropTarget_Drop
-};