You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
7.0 KiB
152 lines
7.0 KiB
|
|
// 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;
|
|
};
|
|
|