1 /* 2 * PROJECT: ReactOS Zip Shell Extension 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: CZipEnumerator 5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org) 6 * Copyright 2023 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) 7 */ 8 9 struct CZipEnumerator 10 { 11 private: 12 CComPtr<IZip> m_Zip; 13 bool m_First; 14 CAtlList<CStringW> m_Returned; 15 UINT m_nCodePage; 16 public: 17 CZipEnumerator() 18 : m_First(true) 19 , m_nCodePage(GetZipCodePage(TRUE)) 20 { 21 } 22 23 bool initialize(IZip* zip) 24 { 25 m_Zip = zip; 26 return reset(); 27 } 28 29 bool reset() 30 { 31 unzFile uf = m_Zip->getZip(); 32 m_First = true; 33 if (unzGoToFirstFile(uf) != UNZ_OK) 34 return false; 35 m_Returned.RemoveAll(); 36 return true; 37 } 38 39 bool next_unique(PCWSTR prefix, CStringW& name, bool& folder, unz_file_info64& info) 40 { 41 size_t len = wcslen(prefix); 42 CStringW tmp; 43 while (next(tmp, info)) 44 { 45 if (!_wcsnicmp(tmp, prefix, len)) 46 { 47 int pos = tmp.Find(L'/', len); 48 if (pos < 0) 49 { 50 name = tmp.Mid(len); 51 folder = false; 52 } 53 else 54 { 55 name = tmp.Mid(len, pos - len); 56 folder = true; 57 } 58 tmp = name; 59 tmp.MakeLower(); 60 61 POSITION it = m_Returned.Find(tmp); 62 if (!name.IsEmpty() && !it) 63 { 64 m_Returned.AddTail(tmp); 65 return true; 66 } 67 } 68 } 69 return false; 70 } 71 72 bool next(CStringW& name, unz_file_info64& info) 73 { 74 int err; 75 76 unzFile uf = m_Zip->getZip(); 77 if (!m_First) 78 { 79 err = unzGoToNextFile(uf); 80 if (err == UNZ_END_OF_LIST_OF_FILE) 81 { 82 return false; 83 } 84 } 85 m_First = false; 86 87 err = unzGetCurrentFileInfo64(uf, &info, NULL, 0, NULL, 0, NULL, 0); 88 if (err == UNZ_OK) 89 { 90 CStringA nameA; 91 PSTR buf = nameA.GetBuffer(info.size_filename); 92 err = unzGetCurrentFileInfo64(uf, NULL, buf, nameA.GetAllocLength(), NULL, 0, NULL, 0); 93 nameA.ReleaseBuffer(info.size_filename); 94 nameA.Replace('\\', '/'); 95 96 if (info.flag & MINIZIP_UTF8_FLAG) 97 name = CA2WEX<MAX_PATH>(nameA, CP_UTF8); 98 else 99 name = CA2WEX<MAX_PATH>(nameA, m_nCodePage); 100 } 101 return err == UNZ_OK; 102 } 103 }; 104 105