xref: /reactos/dll/shellext/cabview/cabview.h (revision cc3672cb)
1 /*
2  * PROJECT:     ReactOS CabView Shell Extension
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Main header file
5  * COPYRIGHT:   Copyright 2024 Whindmar Saksit <whindsaks@proton.me>
6  */
7 
8 #pragma once
9 #include "precomp.h"
10 #include "resource.h"
11 
12 #define FLATFOLDER TRUE
13 
14 EXTERN_C const GUID CLSID_CabFolder;
15 
16 enum EXTRACTCALLBACKMSG { ECM_BEGIN, ECM_FILE, ECM_PREPAREPATH, ECM_ERROR };
17 struct EXTRACTCALLBACKDATA
18 {
19     LPCWSTR Path;
20     const FDINOTIFICATION *pfdin;
21     HRESULT hr;
22 };
23 typedef HRESULT (CALLBACK*EXTRACTCALLBACK)(EXTRACTCALLBACKMSG msg, const EXTRACTCALLBACKDATA &data, LPVOID cookie);
24 HRESULT ExtractCabinet(LPCWSTR cab, LPCWSTR destination, EXTRACTCALLBACK callback, LPVOID cookie);
25 
26 class CEnumIDList :
27     public CComObjectRootEx<CComMultiThreadModelNoCS>,
28     public IEnumIDList
29 {
30 protected:
31     HDPA m_Items;
32     ULONG m_Pos;
33 
34 public:
35     static int CALLBACK DPADestroyCallback(void *pidl, void *pData)
36     {
37         SHFree(pidl);
38         return TRUE;
39     }
40 
41     CEnumIDList() : m_Pos(0)
42     {
43         m_Items = DPA_Create(0);
44     }
45 
46     virtual ~CEnumIDList()
47     {
48         DPA_DestroyCallback(m_Items, DPADestroyCallback, NULL);
49     }
50 
51     int FindNamedItem(PCUITEMID_CHILD pidl) const;
52     HRESULT Fill(LPCWSTR path, HWND hwnd = NULL, SHCONTF contf = 0);
53     HRESULT Fill(PCIDLIST_ABSOLUTE pidl, HWND hwnd = NULL, SHCONTF contf = 0);
54 
55     HRESULT Append(LPCITEMIDLIST pidl)
56     {
57         return DPA_AppendPtr(m_Items, (void*)pidl) != DPA_ERR ? S_OK : E_OUTOFMEMORY;
58     }
59 
60     UINT GetCount() const { return m_Items ? DPA_GetPtrCount(m_Items) : 0; }
61 
62     // IEnumIDList
63     IFACEMETHODIMP Next(ULONG celt, PITEMID_CHILD *rgelt, ULONG *pceltFetched)
64     {
65         if (!rgelt)
66             return E_INVALIDARG;
67         HRESULT hr = S_FALSE;
68         UINT count = GetCount(), fetched = 0;
69         if (m_Pos < count && fetched < celt)
70         {
71             if (SUCCEEDED(hr = SHILClone(DPA_FastGetPtr(m_Items, m_Pos), &rgelt[fetched])))
72                 fetched++;
73         }
74         if (pceltFetched)
75             *pceltFetched = fetched;
76         m_Pos += fetched;
77         return FAILED(hr) ? hr : (celt == fetched && fetched) ? S_OK : S_FALSE;
78     }
79 
80     IFACEMETHODIMP Reset()
81     {
82         m_Pos = 0;
83         return S_OK;
84     }
85 
86     IFACEMETHODIMP Skip(ULONG celt)
87     {
88         UINT count = GetCount(), newpos = m_Pos + celt;
89         if (celt > count || newpos >= count)
90             return E_INVALIDARG;
91         m_Pos = newpos;
92         return S_OK;
93     }
94 
95     IFACEMETHODIMP Clone(IEnumIDList **ppenum)
96     {
97         UNIMPLEMENTED;
98         *ppenum = NULL;
99         return E_NOTIMPL;
100     }
101 
102     static CEnumIDList* CreateInstance()
103     {
104         CComPtr<CEnumIDList> obj;
105         return SUCCEEDED(ShellObjectCreator(obj)) ? obj.Detach() : NULL;
106     }
107 
108     DECLARE_NO_REGISTRY()
109     DECLARE_NOT_AGGREGATABLE(CEnumIDList)
110 
111     BEGIN_COM_MAP(CEnumIDList)
112         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
113     END_COM_MAP()
114 };
115 
116 class CCabFolder :
117     public CComCoClass<CCabFolder, &CLSID_CabFolder>,
118     public CComObjectRootEx<CComMultiThreadModelNoCS>,
119     public IShellFolder2,
120     public IPersistFolder2,
121     public IShellFolderViewCB,
122     public IShellIcon
123 {
124 protected:
125     CComHeapPtr<ITEMIDLIST> m_CurDir;
126     HWND m_ShellViewWindow = NULL;
127 
128 public:
129     HRESULT ExtractFilesUI(HWND hWnd, IDataObject *pDO);
130     HRESULT GetItemDetails(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd, VARIANT *pv);
131     int MapSCIDToColumn(const SHCOLUMNID &scid);
132     HRESULT CompareID(LPARAM lParam, PCUITEMID_CHILD pidl1, PCUITEMID_CHILD pidl2);
133 
134     HRESULT CreateEnum(CEnumIDList **List)
135     {
136         CEnumIDList *pEIDL = CEnumIDList::CreateInstance();
137         *List = pEIDL;
138         return pEIDL ? pEIDL->Fill(m_CurDir) : E_OUTOFMEMORY;
139     }
140 
141     // IShellFolder2
142     IFACEMETHODIMP GetDefaultSearchGUID(GUID *pguid) override
143     {
144         return E_NOTIMPL;
145     }
146 
147     IFACEMETHODIMP EnumSearches(IEnumExtraSearch **ppenum) override
148     {
149         return E_NOTIMPL;
150     }
151 
152     IFACEMETHODIMP GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay) override;
153 
154     IFACEMETHODIMP GetDefaultColumnState(UINT iColumn, SHCOLSTATEF *pcsFlags) override;
155 
156     IFACEMETHODIMP GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv) override;
157 
158     IFACEMETHODIMP GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd) override;
159 
160     IFACEMETHODIMP MapColumnToSCID(UINT column, SHCOLUMNID *pscid) override;
161 
162     IFACEMETHODIMP ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes) override
163     {
164         UNIMPLEMENTED;
165         return E_NOTIMPL;
166     }
167 
168     IFACEMETHODIMP EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) override;
169 
170     IFACEMETHODIMP BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) override;
171 
172     IFACEMETHODIMP BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut) override
173     {
174         UNIMPLEMENTED;
175         return E_NOTIMPL;
176     }
177 
178     IFACEMETHODIMP CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) override;
179 
180     IFACEMETHODIMP CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut) override;
181 
182     IFACEMETHODIMP GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, SFGAOF *rgfInOut) override;
183 
184     IFACEMETHODIMP GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT *prgfInOut, LPVOID *ppvOut) override;
185 
186     IFACEMETHODIMP GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET pName) override;
187 
188     IFACEMETHODIMP SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut) override
189     {
190         return E_NOTIMPL;
191     }
192 
193     // IPersistFolder2
194     IFACEMETHODIMP GetCurFolder(PIDLIST_ABSOLUTE *pidl) override
195     {
196         LPITEMIDLIST curdir = (LPITEMIDLIST)m_CurDir;
197         return curdir ? SHILClone(curdir, pidl) : E_UNEXPECTED;
198     }
199 
200     IFACEMETHODIMP Initialize(PCIDLIST_ABSOLUTE pidl) override
201     {
202         WCHAR path[MAX_PATH];
203         if (SHGetPathFromIDListW(pidl, path))
204         {
205             PIDLIST_ABSOLUTE curdir = ILClone(pidl);
206             if (curdir)
207             {
208                 m_CurDir.Attach(curdir);
209                 return S_OK;
210             }
211             return E_OUTOFMEMORY;
212         }
213         return E_INVALIDARG;
214     }
215 
216     IFACEMETHODIMP GetClassID(CLSID *lpClassId) override
217     {
218         *lpClassId = CLSID_CabFolder;
219         return S_OK;
220     }
221 
222     // IShellFolderViewCB
223     IFACEMETHODIMP MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
224 
225     // IShellIcon
226     IFACEMETHODIMP GetIconOf(PCUITEMID_CHILD pidl, UINT flags, int *pIconIndex) override;
227 
228     DECLARE_NO_REGISTRY()
229     DECLARE_NOT_AGGREGATABLE(CCabFolder)
230 
231     BEGIN_COM_MAP(CCabFolder)
232         COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder)
233         COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2)
234         COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
235         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
236         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
237         COM_INTERFACE_ENTRY_IID(IID_IShellFolderViewCB, IShellFolderViewCB)
238         COM_INTERFACE_ENTRY_IID(IID_IShellIcon, IShellIcon)
239     END_COM_MAP()
240 };
241