[2/2] shell32: Add stub implementations of IKnownFolder and IKnownFolderManager.
Hans Leidekker
hans at codeweavers.com
Thu Sep 23 02:25:57 CDT 2010
See http://bugs.winehq.org/show_bug.cgi?id=24484
---
dlls/shell32/regsvr.c | 7 +
dlls/shell32/shell32_main.h | 1 +
dlls/shell32/shellole.c | 1 +
dlls/shell32/shellpath.c | 443 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 452 insertions(+), 0 deletions(-)
diff --git a/dlls/shell32/regsvr.c b/dlls/shell32/regsvr.c
index 7a3c188..9759b00 100644
--- a/dlls/shell32/regsvr.c
+++ b/dlls/shell32/regsvr.c
@@ -688,6 +688,13 @@ static struct regsvr_coclass const coclass_list[] = {
"shell32.dll",
"Apartment"
},
+ { &CLSID_KnownFolderManager,
+ "Known Folder Manager",
+ 0,
+ NULL,
+ "shell32.dll",
+ "Apartment"
+ },
{ NULL } /* list terminator */
};
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index 6025899..af83fe4 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -98,6 +98,7 @@ HRESULT WINAPI MyDocuments_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID
HRESULT WINAPI RecycleBin_Constructor(IUnknown * pUnkOuter, REFIID riif, LPVOID *ppv);
HRESULT WINAPI QueryAssociations_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppOutput);
HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv);
+HRESULT WINAPI KnownFolderManager_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv);
extern HRESULT CPanel_GetIconLocationW(LPCITEMIDLIST, LPWSTR, UINT, int*);
HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c
index 9afb313..6d284b5 100644
--- a/dlls/shell32/shellole.c
+++ b/dlls/shell32/shellole.c
@@ -78,6 +78,7 @@ static const struct {
{&CLSID_UnixDosFolder, UnixDosFolder_Constructor},
{&CLSID_UnixFolder, UnixFolder_Constructor},
{&CLSID_ExplorerBrowser,ExplorerBrowser_Constructor},
+ {&CLSID_KnownFolderManager, KnownFolderManager_Constructor},
{NULL, NULL}
};
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index 54d7efa..8f3140b 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -24,6 +24,8 @@
*
*/
+#define COBJMACROS
+
#include "config.h"
#include "wine/port.h"
@@ -51,6 +53,7 @@
#include "sddl.h"
#define INITGUID
#include "knownfolders.h"
+#include "shobjidl.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -2998,3 +3001,443 @@ HRESULT WINAPI SHGetFolderPathEx(REFKNOWNFOLDERID rfid, DWORD flags, HANDLE toke
}
return hr;
}
+
+struct knownfolder
+{
+ const struct IKnownFolderVtbl *vtbl;
+ LONG refs;
+ KNOWNFOLDERID id;
+};
+
+static inline struct knownfolder *impl_from_IKnownFolder( IKnownFolder *iface )
+{
+ return (struct knownfolder *)((char *)iface - FIELD_OFFSET( struct knownfolder, vtbl ));
+}
+
+static ULONG WINAPI knownfolder_AddRef(
+ IKnownFolder *iface )
+{
+ struct knownfolder *knownfolder = impl_from_IKnownFolder( iface );
+ return InterlockedIncrement( &knownfolder->refs );
+}
+
+static ULONG WINAPI knownfolder_Release(
+ IKnownFolder *iface )
+{
+ struct knownfolder *knownfolder = impl_from_IKnownFolder( iface );
+ LONG refs = InterlockedDecrement( &knownfolder->refs );
+ if (!refs)
+ {
+ TRACE("destroying %p\n", knownfolder);
+ HeapFree( GetProcessHeap(), 0, knownfolder );
+ }
+ return refs;
+}
+
+static HRESULT WINAPI knownfolder_QueryInterface(
+ IKnownFolder *iface,
+ REFIID riid,
+ void **ppv )
+{
+ struct knownfolder *This = impl_from_IKnownFolder( iface );
+
+ TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppv );
+
+ if ( IsEqualGUID( riid, &IID_IKnownFolder ) ||
+ IsEqualGUID( riid, &IID_IUnknown ) )
+ {
+ *ppv = iface;
+ }
+ else
+ {
+ FIXME("interface %s not implemented\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+ }
+ IKnownFolder_AddRef( iface );
+ return S_OK;
+}
+
+static HRESULT knowfolder_set_id(
+ IKnownFolder *iface,
+ const KNOWNFOLDERID *kfid)
+{
+ struct knownfolder *knownfolder = impl_from_IKnownFolder( iface );
+
+ TRACE("%s\n", debugstr_guid(kfid));
+
+ knownfolder->id = *kfid;
+ return S_OK;
+}
+
+static HRESULT WINAPI knownfolder_GetId(
+ IKnownFolder *iface,
+ KNOWNFOLDERID *pkfid)
+{
+ struct knownfolder *knownfolder = impl_from_IKnownFolder( iface );
+
+ TRACE("%p\n", pkfid);
+
+ *pkfid = knownfolder->id;
+ return S_OK;
+}
+
+static HRESULT WINAPI knownfolder_GetCategory(
+ IKnownFolder *iface,
+ KF_CATEGORY *pCategory)
+{
+ FIXME("%p\n", pCategory);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI knownfolder_GetShellItem(
+ IKnownFolder *iface,
+ DWORD dwFlags,
+ REFIID riid,
+ void **ppv)
+{
+ FIXME("0x%08x, %s, %p\n", dwFlags, debugstr_guid(riid), ppv);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI knownfolder_GetPath(
+ IKnownFolder *iface,
+ DWORD dwFlags,
+ LPWSTR *ppszPath)
+{
+ struct knownfolder *knownfolder = impl_from_IKnownFolder( iface );
+
+ TRACE("0x%08x, %p\n", dwFlags, ppszPath);
+ return SHGetKnownFolderPath( &knownfolder->id, dwFlags, NULL, ppszPath );
+}
+
+static HRESULT WINAPI knownfolder_SetPath(
+ IKnownFolder *iface,
+ DWORD dwFlags,
+ LPCWSTR pszPath)
+{
+ FIXME("0x%08x, %p\n", dwFlags, debugstr_w(pszPath));
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI knownfolder_GetIDList(
+ IKnownFolder *iface,
+ DWORD dwFlags,
+ PIDLIST_ABSOLUTE *ppidl)
+{
+ FIXME("0x%08x, %p\n", dwFlags, ppidl);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI knownfolder_GetFolderType(
+ IKnownFolder *iface,
+ FOLDERTYPEID *pftid)
+{
+ FIXME("%p\n", pftid);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI knownfolder_GetRedirectionCapabilities(
+ IKnownFolder *iface,
+ KF_REDIRECTION_CAPABILITIES *pCapabilities)
+{
+ FIXME("%p\n", pCapabilities);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI knownfolder_GetFolderDefinition(
+ IKnownFolder *iface,
+ KNOWNFOLDER_DEFINITION *pKFD)
+{
+ FIXME("%p\n", pKFD);
+ return E_NOTIMPL;
+}
+
+static const struct IKnownFolderVtbl knownfolder_vtbl =
+{
+ knownfolder_QueryInterface,
+ knownfolder_AddRef,
+ knownfolder_Release,
+ knownfolder_GetId,
+ knownfolder_GetCategory,
+ knownfolder_GetShellItem,
+ knownfolder_GetPath,
+ knownfolder_SetPath,
+ knownfolder_GetIDList,
+ knownfolder_GetFolderType,
+ knownfolder_GetRedirectionCapabilities,
+ knownfolder_GetFolderDefinition
+};
+
+static HRESULT knownfolder_create( void **ppv )
+{
+ struct knownfolder *kf;
+
+ kf = HeapAlloc( GetProcessHeap(), 0, sizeof(*kf) );
+ if (!kf) return E_OUTOFMEMORY;
+
+ kf->vtbl = &knownfolder_vtbl;
+ kf->refs = 1;
+ memset( &kf->id, 0, sizeof(kf->id) );
+
+ *ppv = &kf->vtbl;
+
+ TRACE("returning iface %p\n", *ppv);
+ return S_OK;
+}
+
+struct foldermanager
+{
+ const struct IKnownFolderManagerVtbl *vtbl;
+ LONG refs;
+ UINT num_ids;
+ KNOWNFOLDERID *ids;
+};
+
+static inline struct foldermanager *impl_from_IKnownFolderManager( IKnownFolderManager *iface )
+{
+ return (struct foldermanager *)((char *)iface - FIELD_OFFSET( struct foldermanager, vtbl ));
+}
+
+static ULONG WINAPI foldermanager_AddRef(
+ IKnownFolderManager *iface )
+{
+ struct foldermanager *foldermanager = impl_from_IKnownFolderManager( iface );
+ return InterlockedIncrement( &foldermanager->refs );
+}
+
+static ULONG WINAPI foldermanager_Release(
+ IKnownFolderManager *iface )
+{
+ struct foldermanager *foldermanager = impl_from_IKnownFolderManager( iface );
+ LONG refs = InterlockedDecrement( &foldermanager->refs );
+ if (!refs)
+ {
+ TRACE("destroying %p\n", foldermanager);
+ HeapFree( GetProcessHeap(), 0, foldermanager->ids );
+ HeapFree( GetProcessHeap(), 0, foldermanager );
+ }
+ return refs;
+}
+
+static HRESULT WINAPI foldermanager_QueryInterface(
+ IKnownFolderManager *iface,
+ REFIID riid,
+ void **ppv )
+{
+ struct foldermanager *This = impl_from_IKnownFolderManager( iface );
+
+ TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppv );
+
+ if ( IsEqualGUID( riid, &IID_IKnownFolderManager ) ||
+ IsEqualGUID( riid, &IID_IUnknown ) )
+ {
+ *ppv = iface;
+ }
+ else
+ {
+ FIXME("interface %s not implemented\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+ }
+ IKnownFolderManager_AddRef( iface );
+ return S_OK;
+}
+
+static HRESULT WINAPI foldermanager_FolderIdFromCsidl(
+ IKnownFolderManager *iface,
+ int nCsidl,
+ KNOWNFOLDERID *pfid)
+{
+ TRACE("%d, %p\n", nCsidl, pfid);
+
+ if (nCsidl >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0]))
+ return E_INVALIDARG;
+ *pfid = *CSIDL_Data[nCsidl].id;
+ return S_OK;
+}
+
+static HRESULT WINAPI foldermanager_FolderIdToCsidl(
+ IKnownFolderManager *iface,
+ REFKNOWNFOLDERID rfid,
+ int *pnCsidl)
+{
+ int csidl;
+
+ TRACE("%s, %p\n", debugstr_guid(rfid), pnCsidl);
+
+ csidl = csidl_from_id( rfid );
+ if (csidl == -1) return E_INVALIDARG;
+ *pnCsidl = csidl;
+ return S_OK;
+}
+
+static HRESULT WINAPI foldermanager_GetFolderIds(
+ IKnownFolderManager *iface,
+ KNOWNFOLDERID **ppKFId,
+ UINT *pCount)
+{
+ struct foldermanager *fm = impl_from_IKnownFolderManager( iface );
+
+ TRACE("%p, %p\n", ppKFId, pCount);
+
+ *ppKFId = fm->ids;
+ *pCount = fm->num_ids;
+ return S_OK;
+}
+
+static BOOL is_knownfolder( struct foldermanager *fm, const KNOWNFOLDERID *id )
+{
+ UINT i;
+
+ for (i = 0; i < fm->num_ids; i++)
+ if (IsEqualGUID( &fm->ids[i], id )) return TRUE;
+
+ return FALSE;
+}
+
+static HRESULT WINAPI foldermanager_GetFolder(
+ IKnownFolderManager *iface,
+ REFKNOWNFOLDERID rfid,
+ IKnownFolder **ppkf)
+{
+ struct foldermanager *fm = impl_from_IKnownFolderManager( iface );
+ HRESULT hr;
+
+ TRACE("%s, %p\n", debugstr_guid(rfid), ppkf);
+
+ if (!is_knownfolder( fm, rfid ))
+ {
+ WARN("unknown folder\n");
+ return E_INVALIDARG;
+ }
+ hr = knownfolder_create( (void **)ppkf );
+ if (SUCCEEDED( hr ))
+ hr = knowfolder_set_id( *ppkf, rfid );
+
+ return hr;
+}
+
+static HRESULT WINAPI foldermanager_GetFolderByName(
+ IKnownFolderManager *iface,
+ LPCWSTR pszCanonicalName,
+ IKnownFolder **ppkf)
+{
+ FIXME("%s, %p\n", debugstr_w(pszCanonicalName), ppkf);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI foldermanager_RegisterFolder(
+ IKnownFolderManager *iface,
+ REFKNOWNFOLDERID rfid,
+ KNOWNFOLDER_DEFINITION const *pKFD)
+{
+ FIXME("%p, %p\n", rfid, pKFD);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI foldermanager_UnregisterFolder(
+ IKnownFolderManager *iface,
+ REFKNOWNFOLDERID rfid)
+{
+ FIXME("%p\n", rfid);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI foldermanager_FindFolderFromPath(
+ IKnownFolderManager *iface,
+ LPCWSTR pszPath,
+ FFFP_MODE mode,
+ IKnownFolder **ppkf)
+{
+ FIXME("%s, 0x%08x, %p\n", debugstr_w(pszPath), mode, ppkf);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI foldermanager_FindFolderFromIDList(
+ IKnownFolderManager *iface,
+ PCIDLIST_ABSOLUTE pidl,
+ IKnownFolder **ppkf)
+{
+ FIXME("%p, %p\n", pidl, ppkf);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI foldermanager_Redirect(
+ IKnownFolderManager *iface,
+ REFKNOWNFOLDERID rfid,
+ HWND hwnd,
+ KF_REDIRECT_FLAGS flags,
+ LPCWSTR pszTargetPath,
+ UINT cFolders,
+ KNOWNFOLDERID const *pExclusion,
+ LPWSTR *ppszError)
+{
+ FIXME("%p, %p, 0x%08x, %s, %u, %p, %p\n", rfid, hwnd, flags,
+ debugstr_w(pszTargetPath), cFolders, pExclusion, ppszError);
+ return E_NOTIMPL;
+}
+
+static const struct IKnownFolderManagerVtbl foldermanager_vtbl =
+{
+ foldermanager_QueryInterface,
+ foldermanager_AddRef,
+ foldermanager_Release,
+ foldermanager_FolderIdFromCsidl,
+ foldermanager_FolderIdToCsidl,
+ foldermanager_GetFolderIds,
+ foldermanager_GetFolder,
+ foldermanager_GetFolderByName,
+ foldermanager_RegisterFolder,
+ foldermanager_UnregisterFolder,
+ foldermanager_FindFolderFromPath,
+ foldermanager_FindFolderFromIDList,
+ foldermanager_Redirect
+};
+
+static HRESULT foldermanager_create( void **ppv )
+{
+ UINT i, j;
+ struct foldermanager *fm;
+
+ fm = HeapAlloc( GetProcessHeap(), 0, sizeof(*fm) );
+ if (!fm) return E_OUTOFMEMORY;
+
+ fm->vtbl = &foldermanager_vtbl;
+ fm->refs = 1;
+ fm->num_ids = 0;
+
+ for (i = 0; i < sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0]); i++)
+ {
+ if (!IsEqualGUID( CSIDL_Data[i].id, &GUID_NULL )) fm->num_ids++;
+ }
+ fm->ids = HeapAlloc( GetProcessHeap(), 0, fm->num_ids * sizeof(KNOWNFOLDERID) );
+ if (!fm->ids)
+ {
+ HeapFree( GetProcessHeap(), 0, fm );
+ return E_OUTOFMEMORY;
+ }
+ for (i = j = 0; i < sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0]); i++)
+ {
+ if (!IsEqualGUID( CSIDL_Data[i].id, &GUID_NULL ))
+ {
+ fm->ids[j] = *CSIDL_Data[i].id;
+ j++;
+ }
+ }
+ TRACE("found %u known folders\n", fm->num_ids);
+ *ppv = &fm->vtbl;
+
+ TRACE("returning iface %p\n", *ppv);
+ return S_OK;
+}
+
+HRESULT WINAPI KnownFolderManager_Constructor( IUnknown *punk, REFIID riid, void **ppv )
+{
+ TRACE("%p, %s, %p\n", punk, debugstr_guid(riid), ppv);
+
+ if (!ppv)
+ return E_POINTER;
+ if (punk)
+ return CLASS_E_NOAGGREGATION;
+
+ return foldermanager_create( ppv );
+}
--
1.7.0.4
More information about the wine-patches
mailing list