1 /*
2  * Shell Menu Site
3  *
4  * Copyright 2014 David Quintana
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 #pragma once
21 
22 interface IAugmentedShellFolder : public IShellFolder
23 {
24     STDMETHOD(AddNameSpace)(LPGUID, IShellFolder *, LPCITEMIDLIST, ULONG) PURE;
25     STDMETHOD(GetNameSpaceID)(LPCITEMIDLIST, LPGUID) PURE;
26     STDMETHOD(QueryNameSpace)(ULONG, LPGUID, IShellFolder **) PURE;
27     STDMETHOD(EnumNameSpace)(ULONG, PULONG) PURE;
28 };
29 
30 interface IAugmentedShellFolder2 : public IAugmentedShellFolder
31 {
32     STDMETHOD(UnWrapIDList)(LPCITEMIDLIST, LONG, IShellFolder **, LPITEMIDLIST *, LPITEMIDLIST *, LONG *) PURE;
33 };
34 
35 /* No idea what QUERYNAMESPACEINFO struct contains, yet */
36 struct QUERYNAMESPACEINFO
37 {
38     BYTE unknown[1];
39 };
40 
41 interface IAugmentedShellFolder3 : public IAugmentedShellFolder2
42 {
43     STDMETHOD(QueryNameSpace2)(ULONG, QUERYNAMESPACEINFO *) PURE;
44 };
45 
46 class CEnumMergedFolder;
47 
48 class CMergedFolder :
49     public CComCoClass<CMergedFolder, &CLSID_MergedFolder>,
50     public CComObjectRootEx<CComMultiThreadModelNoCS>,
51     public IShellFolder2,
52     public IPersistFolder2,
53     public IItemNameLimits,
54     public IAugmentedShellFolder3     // -- undocumented
55     //public IShellService,              // DEPRECATED IE4 interface: https://msdn.microsoft.com/en-us/library/windows/desktop/bb774870%28v=vs.85%29.aspx
56     //public ITranslateShellChangeNotify,// -- undocumented
57     //public IStorage,
58     //public IPersistPropertyBag,
59     //public IShellIconOverlay,          // -- undocumented
60     //public ICompositeFolder,           // -- undocumented
61     //public IItemNameLimits,            // https://msdn.microsoft.com/en-us/library/windows/desktop/bb761776%28v=vs.85%29.aspx
62 {
63 private:
64     CComPtr<IShellFolder> m_UserLocal;
65     CComPtr<IShellFolder> m_AllUsers;
66     CComPtr<CEnumMergedFolder> m_EnumSource;
67 
68     LPITEMIDLIST m_UserLocalPidl;
69     LPITEMIDLIST m_AllUsersPidl;
70     LPITEMIDLIST m_shellPidl;
71 
72 public:
73     CMergedFolder();
74     virtual ~CMergedFolder();
75 
76     HRESULT _SetSources(IShellFolder* userLocal, IShellFolder* allUSers);
77 
78     DECLARE_REGISTRY_RESOURCEID(IDR_MERGEDFOLDER)
79     DECLARE_NOT_AGGREGATABLE(CMergedFolder)
80     DECLARE_PROTECT_FINAL_CONSTRUCT()
81 
82     BEGIN_COM_MAP(CMergedFolder)
83         COM_INTERFACE_ENTRY2_IID(IID_IShellFolder, IShellFolder, IShellFolder2)
84         COM_INTERFACE_ENTRY_IID(IID_IShellFolder2,   IShellFolder2)
85         COM_INTERFACE_ENTRY_IID(IID_IPersist,        IPersist)
86         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder,  IPersistFolder)
87         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
88         COM_INTERFACE_ENTRY_IID(IID_IItemNameLimits, IItemNameLimits)
89         COM_INTERFACE_ENTRY_IID(IID_IAugmentedShellFolder,  IAugmentedShellFolder)
90         COM_INTERFACE_ENTRY_IID(IID_IAugmentedShellFolder2, IAugmentedShellFolder2)
91         COM_INTERFACE_ENTRY_IID(IID_IAugmentedShellFolder3, IAugmentedShellFolder3)
92         //COM_INTERFACE_ENTRY_IID(IID_IStorage,                   IStorage)
93         //COM_INTERFACE_ENTRY_IID(IID_IShellService,              IShellService)
94         //COM_INTERFACE_ENTRY_IID(IID_ITranslateShellChangeNotify,ITranslateShellChangeNotify)
95         //COM_INTERFACE_ENTRY_IID(IID_IPersistPropertyBag,IPersistPropertyBag)
96         //COM_INTERFACE_ENTRY_IID(IID_IShellIconOverlay,  IShellIconOverlay)
97         //COM_INTERFACE_ENTRY_IID(IID_ICompositeFolder,   ICompositeFolder)
98         //COM_INTERFACE_ENTRY_IID(IID_IItemNameLimits,    IItemNameLimits)
99     END_COM_MAP()
100 
101     // IShellFolder
102     STDMETHOD(ParseDisplayName)(
103         HWND hwndOwner,
104         LPBC pbcReserved,
105         LPOLESTR lpszDisplayName,
106         ULONG *pchEaten,
107         LPITEMIDLIST *ppidl,
108         ULONG *pdwAttributes) override;
109 
110     STDMETHOD(EnumObjects)(
111         HWND hwndOwner,
112         SHCONTF grfFlags,
113         IEnumIDList **ppenumIDList) override;
114 
115     STDMETHOD(BindToObject)(
116         LPCITEMIDLIST pidl,
117         LPBC pbcReserved,
118         REFIID riid,
119         void **ppvOut) override;
120 
121     STDMETHOD(BindToStorage)(
122         LPCITEMIDLIST pidl,
123         LPBC pbcReserved,
124         REFIID riid,
125         void **ppvObj) override;
126 
127     STDMETHOD(CompareIDs)(
128         LPARAM lParam,
129         LPCITEMIDLIST pidl1,
130         LPCITEMIDLIST pidl2) override;
131 
132     STDMETHOD(CreateViewObject)(
133         HWND hwndOwner,
134         REFIID riid,
135         void **ppvOut) override;
136 
137     STDMETHOD(GetAttributesOf)(
138         UINT cidl,
139         PCUITEMID_CHILD_ARRAY apidl,
140         SFGAOF *rgfInOut) override;
141 
142     STDMETHOD(GetUIObjectOf)(
143         HWND hwndOwner,
144         UINT cidl,
145         PCUITEMID_CHILD_ARRAY apidl,
146         REFIID riid,
147         UINT *prgfInOut,
148         void **ppvOut) override;
149 
150     STDMETHOD(GetDisplayNameOf)(
151         LPCITEMIDLIST pidl,
152         SHGDNF uFlags,
153         STRRET *lpName) override;
154 
155     STDMETHOD(SetNameOf)(
156         HWND hwnd,
157         LPCITEMIDLIST pidl,
158         LPCOLESTR lpszName,
159         SHGDNF uFlags,
160         LPITEMIDLIST *ppidlOut) override;
161 
162     // IShellFolder2
163     STDMETHOD(GetDefaultSearchGUID)(
164         GUID *lpguid) override;
165 
166     STDMETHOD(EnumSearches)(
167         IEnumExtraSearch **ppenum) override;
168 
169     STDMETHOD(GetDefaultColumn)(
170         DWORD dwReserved,
171         ULONG *pSort,
172         ULONG *pDisplay) override;
173 
174     STDMETHOD(GetDefaultColumnState)(
175         UINT iColumn,
176         SHCOLSTATEF *pcsFlags) override;
177 
178     STDMETHOD(GetDetailsEx)(
179         LPCITEMIDLIST pidl,
180         const SHCOLUMNID *pscid,
181         VARIANT *pv) override;
182 
183     STDMETHOD(GetDetailsOf)(
184         LPCITEMIDLIST pidl,
185         UINT iColumn,
186         SHELLDETAILS *psd) override;
187 
188     STDMETHOD(MapColumnToSCID)(
189         UINT iColumn,
190         SHCOLUMNID *pscid) override;
191 
192     // IPersist
193     STDMETHOD(GetClassID)(CLSID *lpClassId) override;
194 
195     // IPersistFolder
196     STDMETHOD(Initialize)(PCIDLIST_ABSOLUTE pidl) override;
197 
198     // IPersistFolder2
199     STDMETHOD(GetCurFolder)(PIDLIST_ABSOLUTE * pidl) override;
200 
201     /*** IItemNameLimits methods ***/
202 
GetMaxLength(LPCWSTR pszName,int * piMaxNameLen)203     STDMETHODIMP GetMaxLength(LPCWSTR pszName, int *piMaxNameLen) override
204     {
205         return E_NOTIMPL;
206     }
207 
208     STDMETHODIMP
GetValidCharacters(LPWSTR * ppwszValidChars,LPWSTR * ppwszInvalidChars)209     GetValidCharacters(LPWSTR *ppwszValidChars, LPWSTR *ppwszInvalidChars) override
210     {
211         if (ppwszValidChars)
212         {
213             *ppwszValidChars = NULL;
214         }
215         if (ppwszInvalidChars)
216         {
217             SHStrDupW(INVALID_FILETITLE_CHARACTERSW, ppwszInvalidChars);
218         }
219         return S_OK;
220     }
221 
222     // IAugmentedShellFolder2
223     STDMETHOD(AddNameSpace)(LPGUID lpGuid, IShellFolder * psf, LPCITEMIDLIST pcidl, ULONG dwUnknown) override;
224     STDMETHOD(GetNameSpaceID)(LPCITEMIDLIST pcidl, LPGUID lpGuid) override;
225     STDMETHOD(QueryNameSpace)(ULONG dwUnknown, LPGUID lpGuid, IShellFolder ** ppsf) override;
226     STDMETHOD(EnumNameSpace)(ULONG dwUnknown, PULONG lpUnknown) override;
227     STDMETHOD(UnWrapIDList)(LPCITEMIDLIST pcidl, LONG lUnknown, IShellFolder ** ppsf, LPITEMIDLIST * ppidl1, LPITEMIDLIST *ppidl2, LONG * lpUnknown) override;
228 
229     // IAugmentedShellFolder3
230     STDMETHOD(QueryNameSpace2)(ULONG, QUERYNAMESPACEINFO *) override;
231 };
232