|
|
// Shell folder implementation for timewarp. The purpose of this object is
// 1) to prevent write actions (move, delete) from being attempted
// 2) to prevent upward navigation in the filesystem namespace
// 3) to provide a friendly version of the date stamp as the folder name
// NOTE: This object aggregates the file system folder so we get away with a
// minimal set of interfaces on this object. The real file system folder does
// stuff like IPersistFolder2 for us.
extern const CLSID CLSID_TimeWarpFolder;// {9DB7A13C-F208-4981-8353-73CC61AE2783}
#define TIMEWARP_SIGNATURE 0x5754 // "TW" in the debugger
#pragma pack(1)
typedef struct _IDTIMEWARP { // these memebers overlap DELEGATEITEMID struct
// for our IDelegateFolder support
WORD cbSize; WORD wOuter; WORD cbInner;
// Timewarp stuff
WORD wSignature; DWORD dwFlags; // currently unused
FILETIME ftSnapTime; WCHAR wszPath[1]; // always room for at least NULL
} IDTIMEWARP; typedef UNALIGNED IDTIMEWARP *PUIDTIMEWARP; typedef const UNALIGNED IDTIMEWARP *PCUIDTIMEWARP; #pragma pack()
class CTimeWarpRegFolder : public IPersistFolder, public IDelegateFolder, public IShellFolder { public: static HRESULT CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi);
// IUnknown
STDMETHOD(QueryInterface)(REFIID riid, void **ppv); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)();
// IPersist, IPersistFreeThreadedObject
STDMETHOD(GetClassID)(CLSID *pClassID);
// IPersistFolder
STDMETHOD(Initialize)(PCIDLIST_ABSOLUTE pidl);
// IDelegateFolder
STDMETHOD(SetItemAlloc)(IMalloc *pmalloc); // IShellFolder
STDMETHOD(ParseDisplayName)(HWND hwnd, LPBC pbc, LPOLESTR pDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes); STDMETHOD(EnumObjects)(HWND hwnd, DWORD grfFlags, IEnumIDList **ppEnumIDList); STDMETHOD(BindToObject)(PCUIDLIST_RELATIVE pidl, LPBC pbc, REFIID riid, void **ppv); STDMETHOD(BindToStorage)(PCUIDLIST_RELATIVE pidl, LPBC pbc, REFIID riid, void **ppv); STDMETHOD(CompareIDs)(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2); STDMETHOD(CreateViewObject)(HWND hwnd, REFIID riid, void **ppv); STDMETHOD(GetAttributesOf)(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, SFGAOF *rgfInOut); STDMETHOD(GetUIObjectOf)(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *prgfInOut, void **ppv); STDMETHOD(GetDisplayNameOf)(PCUITEMID_CHILD pidl, DWORD uFlags, STRRET *pName); STDMETHOD(SetNameOf)(HWND hwnd, PCUITEMID_CHILD pidl, LPCOLESTR pszName, SHGDNF uFlags, PITEMID_CHILD *ppidlOut);
private: CTimeWarpRegFolder(); ~CTimeWarpRegFolder();
HRESULT _CreateAndInit(PCUIDLIST_RELATIVE pidl, LPBC pbc, REFIID riid, void **ppv); HRESULT _CreateDefExtIcon(PCUIDTIMEWARP pidTW, REFIID riid, void **ppv);
static STDMETHODIMP ContextMenuCB(IShellFolder *psf, HWND hwnd, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam);
LONG _cRef; IMalloc * _pmalloc; PIDLIST_ABSOLUTE _pidl; // copy of pidl passed to us in Initialize()
};
//
// Note that we don't need to override any of the IShellFolder2 methods, but
// we have to implement IShellFolder2 anyway. Otherwise, a caller could QI
// for IShellFolder2, which would come from the aggregated CFSFolder code,
// and then call IShellFolder methods on it. Those calls would go directly
// to CFSFolder, bypassing our implementation of IShellFolder.
//
class CTimeWarpFolder : public IPersistFolder, public IShellFolder2 { public: static STDMETHODIMP CreateInstance(REFCLSID rclsid, PCIDLIST_ABSOLUTE pidlRoot, PCIDLIST_ABSOLUTE pidlTarget, LPCWSTR pszTargetPath, const FILETIME UNALIGNED *pftSnapTime, REFIID riid, void **ppv);
// IUnknown
STDMETHOD(QueryInterface)(REFIID riid, void **ppv); STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)();
// IPersist, IPersistFreeThreadedObject
STDMETHOD(GetClassID)(CLSID *pClassID);
// IPersistFolder
STDMETHOD(Initialize)(PCIDLIST_ABSOLUTE pidl);
// IPersistFolder2, IPersistFolder3, etc are all implemented by
// the folder we aggregate, CFSFolder, so we don't want to implement them
// IShellFolder
STDMETHOD(ParseDisplayName)(HWND hwnd, LPBC pbc, LPOLESTR pDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes); STDMETHOD(EnumObjects)(HWND hwnd, DWORD grfFlags, IEnumIDList **ppEnumIDList); STDMETHOD(BindToObject)(PCUIDLIST_RELATIVE pidl, LPBC pbc, REFIID riid, void **ppv); STDMETHOD(BindToStorage)(PCUIDLIST_RELATIVE pidl, LPBC pbc, REFIID riid, void **ppv); STDMETHOD(CompareIDs)(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2); STDMETHOD(CreateViewObject)(HWND hwnd, REFIID riid, void **ppv); STDMETHOD(GetAttributesOf)(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, SFGAOF *rgfInOut); STDMETHOD(GetUIObjectOf)(HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *prgfInOut, void **ppv); STDMETHOD(GetDisplayNameOf)(PCUITEMID_CHILD pidl, DWORD uFlags, STRRET *pName); STDMETHOD(SetNameOf)(HWND hwnd, PCUITEMID_CHILD pidl, LPCOLESTR pszName, SHGDNF uFlags, PITEMID_CHILD *ppidlOut);
// IShellFolder2
STDMETHOD(GetDefaultSearchGUID)(LPGUID lpGuid); STDMETHOD(EnumSearches)(LPENUMEXTRASEARCH *ppenum); STDMETHOD(GetDefaultColumn)(DWORD dwRes, ULONG *pSort, ULONG *pDisplay); STDMETHOD(GetDefaultColumnState)(UINT iColumn, DWORD *pbState); STDMETHOD(GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv); STDMETHOD(GetDetailsOf))(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *pDetails); STDMETHOD(MapColumnToSCID)(UINT iCol, SHCOLUMNID *pscid);
private: CTimeWarpFolder(const FILETIME UNALIGNED *pftSnapTime); ~CTimeWarpFolder();
HRESULT _Init(REFCLSID rclsid, PCIDLIST_ABSOLUTE pidlRoot, PCIDLIST_ABSOLUTE pidlTarget, LPCWSTR pszTargetPath); HRESULT _CreateAndInit(REFCLSID rclsid, PCUIDLIST_RELATIVE pidl, LPBC pbc, REFIID riid, void **ppv); HRESULT _GetFolder(); HRESULT _GetFolder2(); HRESULT _GetClass(PCUITEMID_CHILD pidlChild, CLSID *pclsid);
LONG _cRef; IUnknown * _punk; // points to IUnknown for shell folder in use...
IShellFolder * _psf; // points to shell folder in use...
IShellFolder2 * _psf2; // points to shell folder in use...
IPersistFolder3 * _ppf3; // points to shell folder in use...
PIDLIST_ABSOLUTE _pidlRoot; // copy of pidl passed to us in Initialize()
FILETIME _ftSnapTime; };
|