1 /*
2  * PROJECT:     ReactOS Zip Shell Extension
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     CEnumZipContents
5  * COPYRIGHT:   Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
6  *              Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7  */
8 
9 #include "precomp.h"
10 
11 class CEnumZipContents :
12     public CComObjectRootEx<CComMultiThreadModelNoCS>,
13     public IEnumIDList
14 {
15 private:
16     CZipEnumerator mEnumerator;
17     DWORD dwFlags;
18     CStringW m_Prefix;
19 public:
20     CEnumZipContents()
21         :dwFlags(0)
22     {
23     }
24 
25     STDMETHODIMP Initialize(IZip* zip, DWORD flags, PCWSTR prefix)
26     {
27         dwFlags = flags;
28         m_Prefix = prefix;
29         if (mEnumerator.initialize(zip))
30             return S_OK;
31         return E_FAIL;
32     }
33 
34     // *** IEnumIDList methods ***
35     STDMETHODIMP Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched)
36     {
37         if (!rgelt || (!pceltFetched && celt != 1))
38             return E_POINTER;
39 
40         HRESULT hr = S_OK;
41         ULONG fetched = 0;
42         LPITEMIDLIST item;
43         CStringW name;
44         bool dir;
45         unz_file_info64 info;
46 
47         while (fetched < celt)
48         {
49             if (mEnumerator.next_unique(m_Prefix, name, dir, info))
50             {
51                 item = _ILCreate(dir ? ZIP_PIDL_DIRECTORY : ZIP_PIDL_FILE, name, info);
52                 if (!item)
53                 {
54                     hr = fetched ? S_FALSE : E_OUTOFMEMORY;
55                     break;
56                 }
57                 rgelt[fetched++] = item;
58             }
59             else
60             {
61                 hr = S_FALSE;
62                 break;
63             }
64         }
65 
66         if (pceltFetched)
67             *pceltFetched = fetched;
68         return hr;
69     }
70     STDMETHODIMP Skip(ULONG celt)
71     {
72         CStringW name;
73         bool dir;
74         unz_file_info64 info;
75         while (celt--)
76         {
77             if (!mEnumerator.next_unique(m_Prefix, name, dir, info))
78                 return E_FAIL;
79             ;
80         }
81         return S_OK;
82     }
83     STDMETHODIMP Reset()
84     {
85         if (mEnumerator.reset())
86             return S_OK;
87         return E_FAIL;
88     }
89     STDMETHODIMP Clone(IEnumIDList **ppenum)
90     {
91         return E_NOTIMPL;
92     }
93 
94 
95 public:
96     DECLARE_NOT_AGGREGATABLE(CEnumZipContents)
97     DECLARE_PROTECT_FINAL_CONSTRUCT()
98 
99     BEGIN_COM_MAP(CEnumZipContents)
100         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
101     END_COM_MAP()
102 };
103 
104 
105 HRESULT _CEnumZipContents_CreateInstance(IZip* zip, DWORD flags, PCWSTR prefix, REFIID riid, LPVOID * ppvOut)
106 {
107     return ShellObjectCreatorInit<CEnumZipContents>(zip, flags, prefix, riid, ppvOut);
108 }
109 
110