├── AUTHORS ├── .gitmodules ├── src ├── OSFunctions_Win32.h ├── OSFunctions_UnixLike.h ├── OSFunctions.h ├── OSFunctions_OS2.h ├── 7ZipCodecInfo.h ├── 7ZipObjectPtrArray.cpp ├── 7ZipFormatInfo.h ├── 7ZipInStreamWrapper.h ├── 7ZipFunctions.h ├── 7ZipCompressCodecsInfo.h ├── 7ZipInStreamWrapper.cpp ├── 7ZipArchiveOpenCallback.h ├── 7ZipDllHandler.h ├── CMakeLists.txt ├── OSFunctions_Win32.cpp ├── HelperFuncs.h ├── 7ZipCodecInfo.cpp ├── 7ZipArchiveOpenCallback.cpp ├── 7ZipCompressCodecsInfo.cpp ├── 7ZipDllHandler.cpp ├── OSFunctions_OS2.cpp ├── OSFunctions_UnixLike.cpp ├── 7zipLibrary.cpp ├── 7ZipFormatInfo.cpp ├── lib7zip.h ├── 7ZipArchiveItem.cpp ├── HelperFuncs.cpp ├── 7ZipOpenArchive.cpp └── 7ZipArchive.cpp ├── test ├── stdafx.cpp ├── stdafx.h ├── CMakeLists.txt ├── test7zipprops.cpp ├── test_archive.cpp ├── Test7Zip.cpp ├── Test7ZipRar5.cpp ├── Test7Zip2.cpp ├── Test7ZipSignature.cpp ├── Test7ZipMulti.cpp ├── Test7ZipDmg.cpp └── Test7ZipCryptFileName.cpp ├── .hgignore ├── .gitignore ├── CMakeLists.txt ├── README.md └── COPYING /AUTHORS: -------------------------------------------------------------------------------- 1 | Maintainer: jingnan si 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/p7zip"] 2 | path = third_party/p7zip 3 | url = https://github.com/jinfeihan57/p7zip.git 4 | -------------------------------------------------------------------------------- /src/OSFunctions_Win32.h: -------------------------------------------------------------------------------- 1 | #ifndef __OS_FUNCTIONS_WIN32_H__ 2 | #define __OS_FUNCTIONS_WIN32_H__ 3 | 4 | 5 | #endif // __OS_FUNCTIONS_WIN32_H__ 6 | -------------------------------------------------------------------------------- /src/OSFunctions_UnixLike.h: -------------------------------------------------------------------------------- 1 | #ifndef __OS_FUNCTIONS_UNIX_LIKE_H__ 2 | #define __OS_FUNCTIONS_UNIX_LIKE_H__ 3 | 4 | #define GetProcAddress dlsym 5 | #define HMODULE void * 6 | 7 | #ifndef _GNU_SOURCE 8 | #define _GNU_SOURCE 9 | #endif 10 | #include "dlfcn.h" 11 | 12 | #endif // __OS_FUNCTIONS_UNIX_LIKE_H__ 13 | -------------------------------------------------------------------------------- /test/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // Test7Zip.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /src/OSFunctions.h: -------------------------------------------------------------------------------- 1 | #ifndef __OS_FUNCTIONS_H__ 2 | #define __OS_FUNCTIONS_H__ 3 | 4 | #if defined(_WIN32) 5 | #include "OSFunctions_Win32.h" 6 | #elif defined(_OS2) 7 | #include "OSFunctions_OS2.h" 8 | #else 9 | #include "OSFunctions_UnixLike.h" 10 | #endif 11 | 12 | wstring GetHandlerPath(void * pHandle); 13 | HMODULE Load7ZLibrary(const wstring & library); 14 | void Free7ZLibrary(HMODULE pModule); 15 | 16 | #endif //__OS_FUNCTIONS_H__ 17 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | .*\.pbxuser 2 | .*\.perspectivev.? 3 | \.DS_Store 4 | build$ 5 | linux-build$ 6 | \.svn 7 | depcomp$ 8 | missing$ 9 | install-sh$ 10 | autom4te\.cache$ 11 | Makefile\.in$ 12 | aclocal\.m4$ 13 | \.deps$ 14 | config\.log$ 15 | configure$ 16 | config\.status$ 17 | Makefile$ 18 | includes/C$ 19 | includes/CPP$ 20 | .*\.o 21 | .*\.a 22 | .*\.lo 23 | .*\.la 24 | .*\.so\.?.* 25 | m4/.* 26 | libtool 27 | config.guess 28 | config.sub 29 | ltmain.sh -------------------------------------------------------------------------------- /src/OSFunctions_OS2.h: -------------------------------------------------------------------------------- 1 | #ifndef __OS_FUNCTIONS_OS2_H__ 2 | #define __OS_FUNCTIONS_OS2_H__ 3 | 4 | #include "unistd.h" 5 | #include "dirent.h" 6 | #define INCL_DOSMODULEMGR 7 | #define INCL_DOSERRORS 8 | #include 9 | #include 10 | 11 | typedef basic_ostringstream wostringstream; 12 | typedef basic_ostringstream ostringstream; 13 | 14 | void *GetProcAddress (HMODULE hmod, const char *symbol); 15 | 16 | #endif // __OS_FUNCTIONS_OS2_H__ 17 | -------------------------------------------------------------------------------- /src/7ZipCodecInfo.h: -------------------------------------------------------------------------------- 1 | #ifndef __7ZIP_CODEC_INFO_H__ 2 | #define __7ZIP_CODEC_INFO_H__ 3 | 4 | /*-------------- internal classes ------------------------*/ 5 | class C7ZipCodecInfo : public virtual C7ZipObject 6 | { 7 | public: 8 | C7ZipCodecInfo(); 9 | virtual ~C7ZipCodecInfo(); 10 | 11 | public: 12 | wstring m_Name; 13 | GUID m_ClassID; 14 | 15 | GUID Encoder; 16 | bool EncoderAssigned; 17 | 18 | GUID Decoder; 19 | bool DecoderAssigned; 20 | 21 | int CodecIndex; 22 | 23 | pU7ZipFunctions Functions; 24 | }; 25 | 26 | #endif //__7ZIP_CODEC_INFO_H__ 27 | -------------------------------------------------------------------------------- /src/7ZipObjectPtrArray.cpp: -------------------------------------------------------------------------------- 1 | #include "lib7zip.h" 2 | 3 | #ifdef S_OK 4 | #undef S_OK 5 | #endif 6 | 7 | /*------------------------ C7ZipObjectPtrArray ---------------------*/ 8 | C7ZipObjectPtrArray::C7ZipObjectPtrArray(bool auto_release) : m_bAutoRelease(auto_release) 9 | { 10 | } 11 | 12 | C7ZipObjectPtrArray::~C7ZipObjectPtrArray() 13 | { 14 | clear(); 15 | } 16 | 17 | void C7ZipObjectPtrArray::clear() 18 | { 19 | if (m_bAutoRelease) 20 | { 21 | for(C7ZipObjectPtrArray::iterator it = begin(); it != end(); it ++) 22 | { 23 | delete *it; 24 | } 25 | } 26 | 27 | std::vector::clear(); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /test/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #ifdef _WIN32 9 | #define _CRT_SECURE_NO_WARNINGS 10 | #include 11 | #include 12 | #endif 13 | 14 | #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. 15 | #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. 16 | #endif 17 | 18 | #include 19 | 20 | 21 | 22 | // TODO: reference additional headers your program requires here 23 | -------------------------------------------------------------------------------- /src/7ZipFormatInfo.h: -------------------------------------------------------------------------------- 1 | #ifndef __7ZIP_FORMAT_INFO_H__ 2 | #define __7ZIP_FORMAT_INFO_H__ 3 | 4 | class C7ZipFormatInfo : public virtual C7ZipObject 5 | { 6 | public: 7 | C7ZipFormatInfo(); 8 | virtual ~C7ZipFormatInfo(); 9 | 10 | public: 11 | wstring m_Name; 12 | GUID m_ClassID; 13 | bool m_UpdateEnabled; 14 | bool m_KeepName; 15 | 16 | WStringArray Exts; 17 | WStringArray AddExts; 18 | 19 | CByteBuffer m_StartSignature; 20 | CByteBuffer m_FinishSignature; 21 | 22 | #if MY_VER_MAJOR >= 15 23 | UInt32 SignatureOffset; 24 | CObjectVector Signatures; 25 | #endif 26 | 27 | int FormatIndex; 28 | }; 29 | 30 | #endif //__7ZIP_FORMAT_INFO_H__ 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*\.pbxuser 2 | .*\.perspectivev.? 3 | \.DS_Store 4 | build$ 5 | linux-build$ 6 | \.svn 7 | depcomp$ 8 | missing$ 9 | install-sh$ 10 | autom4te\.cache$ 11 | Makefile\.in$ 12 | aclocal\.m4$ 13 | \.deps$ 14 | config\.log$ 15 | configure$ 16 | config\.status$ 17 | Makefile$ 18 | includes/C$ 19 | includes/CPP$ 20 | .*\.o 21 | .*\.a 22 | .*\.lo 23 | .*\.la 24 | .*\.so\.?.* 25 | m4/.* 26 | libtool 27 | config.guess 28 | config.sub 29 | ltmain.sh 30 | # http://www.gnu.org/software/automake 31 | 32 | Makefile.in 33 | 34 | # http://www.gnu.org/software/autoconf 35 | 36 | /autom4te.cache 37 | /aclocal.m4 38 | /compile 39 | /configure 40 | /depcomp 41 | /install-sh 42 | /missing 43 | /stamp-h1 44 | /ar-lib 45 | /m4 46 | /build -------------------------------------------------------------------------------- /src/7ZipInStreamWrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef __7ZIP_IN_STREAM_WRAPPER_H__ 2 | #define __7ZIP_IN_STREAM_WRAPPER_H__ 3 | 4 | class C7ZipInStreamWrapper: 5 | public IInStream, 6 | public IStreamGetSize, 7 | public CMyUnknownImp 8 | { 9 | public: 10 | C7ZipInStreamWrapper(C7ZipInStream * pInStream); 11 | virtual ~C7ZipInStreamWrapper() {} 12 | 13 | public: 14 | MY_UNKNOWN_IMP2(IInStream, IStreamGetSize) 15 | 16 | STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 17 | STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 18 | 19 | STDMETHOD(GetSize)(UInt64 *size); 20 | 21 | private: 22 | C7ZipInStream * m_pInStream; 23 | }; 24 | 25 | #endif //__7ZIP_IN_STREAM_WRAPPER_H__ 26 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(common_src 2 | stdafx.cpp stdafx.h 3 | ) 4 | 5 | SET (test_src Test7Zip.cpp Test7ZipCryptFileName.cpp Test7ZipMulti.cpp Test7ZipSignature.cpp 6 | Test7Zip2.cpp Test7ZipDmg.cpp Test7ZipRar5.cpp test_archive.cpp 7 | ) 8 | 9 | FOREACH(f ${test_src}) 10 | 11 | GET_FILENAME_COMPONENT(test_target_name ${f} NAME_WE) 12 | 13 | MESSAGE("generate target ${test_target_name} for ${f}") 14 | 15 | ADD_EXECUTABLE(${test_target_name} 16 | ${common_src} 17 | ${f} 18 | ) 19 | 20 | TARGET_INCLUDE_DIRECTORIES(${test_target_name} PRIVATE 21 | "../src" 22 | ) 23 | 24 | TARGET_LINK_LIBRARIES(${test_target_name} 25 | lib7zip 26 | ${CMAKE_DL_LIBS} 27 | ) 28 | 29 | ENDFOREACH() 30 | -------------------------------------------------------------------------------- /src/7ZipFunctions.h: -------------------------------------------------------------------------------- 1 | #ifndef __7ZIP_FUNCTIONS_H__ 2 | #define __7ZIP_FUNCTIONS_H__ 3 | 4 | typedef union _union_7zip_functions 5 | { 6 | unsigned char data[sizeof(void *) * 7]; 7 | 8 | struct 9 | { 10 | GetMethodPropertyFunc GetMethodProperty; 11 | GetNumberOfMethodsFunc GetNumberOfMethods; 12 | GetNumberOfFormatsFunc GetNumberOfFormats; 13 | GetHandlerPropertyFunc GetHandlerProperty; 14 | GetHandlerPropertyFunc2 GetHandlerProperty2; 15 | CreateObjectFunc CreateObject; 16 | SetLargePageModeFunc SetLargePageMode; 17 | 18 | bool IsValid() 19 | { 20 | return GetMethodProperty != NULL && 21 | GetNumberOfMethods != NULL && 22 | CreateObject != NULL; 23 | } 24 | } v; 25 | } U7ZipFunctions, * pU7ZipFunctions; 26 | 27 | #endif // __7ZIP_FUNCTIONS_H__ 28 | -------------------------------------------------------------------------------- /src/7ZipCompressCodecsInfo.h: -------------------------------------------------------------------------------- 1 | #ifndef __7ZIP_COMPRESS_CODECS_INFO_H__ 2 | #define __7ZIP_COMPRESS_CODECS_INFO_H__ 3 | 4 | class C7ZipCompressCodecsInfo : public ICompressCodecsInfo, 5 | public CMyUnknownImp, 6 | public virtual C7ZipObject 7 | { 8 | public: 9 | C7ZipCompressCodecsInfo(C7ZipLibrary * pLibrary); 10 | virtual ~C7ZipCompressCodecsInfo(); 11 | 12 | MY_UNKNOWN_IMP1(ICompressCodecsInfo) 13 | 14 | #if MY_VER_MAJOR >= 15 15 | STDMETHOD(GetNumMethods)(UInt32 *numMethods); 16 | #else 17 | STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods); 18 | #endif 19 | STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); 20 | STDMETHOD(CreateDecoder)(UInt32 index, const GUID *interfaceID, void **coder); 21 | STDMETHOD(CreateEncoder)(UInt32 index, const GUID *interfaceID, void **coder); 22 | 23 | void InitData(); 24 | private: 25 | C7ZipLibrary * m_pLibrary; 26 | C7ZipObjectPtrArray m_CodecInfoArray; 27 | }; 28 | 29 | #endif //__7ZIP_COMPRESS_CODECS_INFO_H__ 30 | 31 | -------------------------------------------------------------------------------- /src/7ZipInStreamWrapper.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(_OS2) 2 | #include "CPP/myWindows/StdAfx.h" 3 | #include "CPP/include_windows/windows.h" 4 | #endif 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "Common/ComTry.h" 13 | #include "Windows/PropVariant.h" 14 | using namespace NWindows; 15 | 16 | #include "lib7zip.h" 17 | #include "7ZipInStreamWrapper.h" 18 | 19 | /*----------------- C7ZipInStreamWrapper ---------------------*/ 20 | C7ZipInStreamWrapper::C7ZipInStreamWrapper(C7ZipInStream * pInStream) : 21 | m_pInStream(pInStream) 22 | { 23 | } 24 | 25 | STDMETHODIMP C7ZipInStreamWrapper::Read(void *data, UInt32 size, UInt32 *processedSize) 26 | { 27 | return m_pInStream->Read(data,size,processedSize); 28 | } 29 | 30 | STDMETHODIMP C7ZipInStreamWrapper::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) 31 | { 32 | return m_pInStream->Seek(offset,seekOrigin,newPosition); 33 | } 34 | 35 | STDMETHODIMP C7ZipInStreamWrapper::GetSize(UInt64 *size) 36 | { 37 | return m_pInStream->GetSize(size); 38 | } 39 | -------------------------------------------------------------------------------- /src/7ZipArchiveOpenCallback.h: -------------------------------------------------------------------------------- 1 | #ifndef __7ZIP_ARCHIVE_OPEN_CALLBACK_H__ 2 | #define __7ZIP_ARCHIVE_OPEN_CALLBACK_H__ 3 | 4 | #define E_NEEDPASSWORD ((HRESULT)0x80040001L) 5 | 6 | class C7ZipArchiveOpenCallback: 7 | public IArchiveOpenCallback, 8 | public ICryptoGetTextPassword, 9 | public IArchiveOpenVolumeCallback, 10 | public IArchiveOpenSetSubArchiveName, 11 | public CMyUnknownImp 12 | { 13 | public: 14 | MY_UNKNOWN_IMP3( 15 | IArchiveOpenVolumeCallback, 16 | ICryptoGetTextPassword, 17 | IArchiveOpenSetSubArchiveName 18 | ); 19 | 20 | INTERFACE_IArchiveOpenCallback(;); 21 | INTERFACE_IArchiveOpenVolumeCallback(;); 22 | 23 | STDMETHOD(CryptoGetTextPassword)(BSTR *password); 24 | 25 | STDMETHOD(SetSubArchiveName(const wchar_t *name)) { 26 | _subArchiveMode = true; 27 | _subArchiveName = name; 28 | TotalSize = 0; 29 | return S_OK; 30 | } 31 | 32 | bool PasswordIsDefined; 33 | wstring Password; 34 | 35 | wstring _subArchiveName; 36 | bool _subArchiveMode; 37 | UInt64 TotalSize; 38 | 39 | C7ZipMultiVolumes * m_pMultiVolumes; 40 | bool m_bMultiVolume; 41 | 42 | C7ZipArchiveOpenCallback(C7ZipMultiVolumes * pMultiVolumes) : PasswordIsDefined(false), 43 | _subArchiveMode(false), 44 | m_pMultiVolumes(pMultiVolumes), 45 | m_bMultiVolume(pMultiVolumes != NULL) { 46 | } 47 | }; 48 | 49 | #endif // __7ZIP_ARCHIVE_OPEN_CALLBACK_H__ 50 | -------------------------------------------------------------------------------- /src/7ZipDllHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef __7ZIP_DLL_HANDLER_H__ 2 | #define __7ZIP_DLL_HANDLER_H__ 3 | 4 | class C7ZipDllHandler : 5 | public virtual C7ZipObject 6 | { 7 | public: 8 | C7ZipDllHandler(C7ZipLibrary * pLibrary, void * pHandler); 9 | virtual ~C7ZipDllHandler(); 10 | 11 | public: 12 | bool GetSupportedExts(WStringArray & exts); 13 | bool OpenArchive(C7ZipInStream * pInStream, 14 | C7ZipMultiVolumes * pMultiVolumes, 15 | C7ZipArchive ** ppArchive, 16 | const wstring & passwd, 17 | HRESULT * pResult, 18 | bool fCheckFileTypeBySignature); 19 | bool IsInitialized() const { return m_bInitialized; } 20 | C7ZipLibrary * GetLibrary() const { return m_pLibrary; } 21 | const C7ZipObjectPtrArray & GetFormatInfoArray() const { return m_FormatInfoArray; } 22 | const C7ZipObjectPtrArray & GetCodecInfoArray() const { return m_CodecInfoArray; } 23 | pU7ZipFunctions GetFunctions() const { return const_cast(&m_Functions); } 24 | 25 | wstring GetHandlerPath() const; 26 | 27 | private: 28 | C7ZipLibrary * m_pLibrary; 29 | bool m_bInitialized; 30 | void * m_pHandler; 31 | U7ZipFunctions m_Functions; 32 | C7ZipObjectPtrArray m_CodecInfoArray; 33 | C7ZipObjectPtrArray m_FormatInfoArray; 34 | 35 | void Initialize(); 36 | void Deinitialize(); 37 | }; 38 | 39 | #endif //__7ZIP_DLL_HANDLER_H__ 40 | 41 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(lib7zip_src 2 | 7ZipArchive.cpp 7ZipCompressCodecsInfo.cpp 7ZipFunctions.h OSFunctions_UnixLike.cpp 3 | 7ZipArchiveItem.cpp 7ZipCompressCodecsInfo.h 7ZipInStreamWrapper.cpp HelperFuncs.cpp OSFunctions_UnixLike.h 4 | 7ZipArchiveOpenCallback.cpp 7ZipDllHandler.cpp 7ZipInStreamWrapper.h HelperFuncs.h OSFunctions_Win32.cpp 5 | 7ZipArchiveOpenCallback.h 7ZipDllHandler.h 7ZipObjectPtrArray.cpp OSFunctions.h OSFunctions_Win32.h 6 | 7ZipCodecInfo.cpp 7ZipFormatInfo.cpp 7ZipOpenArchive.cpp OSFunctions_OS2.cpp lib7zip.h 7 | 7ZipCodecInfo.h 7ZipFormatInfo.h 7zipLibrary.cpp OSFunctions_OS2.h 8 | ) 9 | 10 | SET(lib7zip_NODIST_SOURCES ${P7ZIP_SOURCE_DIR}/CPP/Common/MyWindows.cpp 11 | ${P7ZIP_SOURCE_DIR}/CPP/Windows/PropVariant.cpp 12 | ) 13 | 14 | ADD_LIBRARY(lib7zip STATIC ${lib7zip_src} 15 | ${lib7zip_NODIST_SOURCES} 16 | ) 17 | 18 | SET_TARGET_PROPERTIES(lib7zip PROPERTIES 19 | OUTPUT_NAME "7zip" 20 | ) 21 | 22 | SET_TARGET_PROPERTIES(lib7zip PROPERTIES LINKER_LANGUAGE CXX) 23 | 24 | TARGET_INCLUDE_DIRECTORIES(lib7zip PRIVATE 25 | "${P7ZIP_INCLUDE_PATH}" 26 | ) 27 | 28 | IF (BUILD_SHARED_LIB) 29 | ADD_LIBRARY(lib7zip_shared SHARED ${lib7zip_src} 30 | ${lib7zip_NODIST_SOURCES} 31 | ) 32 | SET_TARGET_PROPERTIES(lib7zip_shared PROPERTIES 33 | OUTPUT_NAME "7zip" 34 | ) 35 | 36 | SET_TARGET_PROPERTIES(lib7zip_shared PROPERTIES LINKER_LANGUAGE CXX) 37 | 38 | TARGET_INCLUDE_DIRECTORIES(lib7zip_shared PRIVATE 39 | "${P7ZIP_INCLUDE_PATH}" 40 | ) 41 | ENDIF() 42 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 2 | 3 | CMAKE_POLICY( 4 | SET CMP0048 NEW 5 | ) 6 | 7 | PROJECT (lib7zip 8 | VERSION 3.0.0 9 | ) 10 | 11 | INCLUDE(ExternalProject) 12 | 13 | IF(APPLE) 14 | SET(CMAKE_MACOSX_RPATH 1) 15 | SET(CMAKE_PREFIX_PATH /usr/local) 16 | ENDIF() 17 | 18 | IF(NOT CMAKE_BUILD_TYPE) 19 | SET(CMAKE_BUILD_TYPE "DEBUG") 20 | #SET(CMAKE_BUILD_TYPE "RELEASE") 21 | #SET(CMAKE_BUILD_TYPE "RELWITHDEBINFO") 22 | #SET(CMAKE_BUILD_TYPE "MINSIZEREL") 23 | ENDIF() 24 | 25 | SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/") 26 | 27 | OPTION(BUILD_SHARED_LIB "build shared library" OFF) 28 | SET(P7ZIP_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/p7zip" CACHE PATH "pzip/7zip source code path") 29 | 30 | IF (NOT IS_DIRECTORY ${P7ZIP_SOURCE_DIR}) 31 | MESSAGE(FATAL_ERROR "must proivde p7zip/7zip source path using -DP7ZIP_SOURCE_DIR") 32 | ENDIF() 33 | 34 | SET(P7ZIP_INCLUDE_PATH "${P7ZIP_SOURCE_DIR}" 35 | "${P7ZIP_SOURCE_DIR}/CPP" 36 | "${P7ZIP_SOURCE_DIR}/CPP/myWindows" 37 | "${P7ZIP_SOURCE_DIR}/CPP/include_windows" 38 | ) 39 | 40 | 41 | if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") 42 | set(warnings -Wall -Wextra -Werror -Wno-unused-parameter) 43 | set(cxx_warnings -Wno-class-memaccess) 44 | set(no_undefined -Wl,--no-undefined) 45 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 46 | set(warnings -Wall -Wextra -Werror -Wno-inconsistent-missing-override -Wno-unused-parameter) 47 | set(cxx_warnings "") 48 | set(no_undefined -Wl,-undefined,error) 49 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 50 | set(warnings /W4 /WX /EHsc) 51 | set(no_undefined "") 52 | set(cxx_warnings "") 53 | endif() 54 | 55 | SET(CXX_STANDARD_REQUIRED OFF) 56 | SET(CXX_EXTENSION NO) 57 | 58 | if (NOT CONFIGURED_ONCE) 59 | ADD_COMPILE_OPTIONS(-fPIC -std=c++14 ${warnings} ${cxx_warnings}) 60 | ADD_LINK_OPTIONS(${no_undefined}) 61 | endif() 62 | 63 | ADD_SUBDIRECTORY(src) 64 | ADD_SUBDIRECTORY(test) 65 | -------------------------------------------------------------------------------- /src/OSFunctions_Win32.cpp: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include "lib7zip.h" 3 | 4 | #ifdef S_OK 5 | #undef S_OK 6 | #endif 7 | 8 | #include "C/7zVersion.h" 9 | #include "CPP/7zip/Archive/IArchive.h" 10 | #include "CPP/Windows/PropVariant.h" 11 | #include "CPP/Common/MyCom.h" 12 | #include "CPP/7zip/ICoder.h" 13 | #include "CPP/7zip/IPassword.h" 14 | #include "Common/ComTry.h" 15 | #include "Windows/PropVariant.h" 16 | using namespace NWindows; 17 | 18 | #include "HelperFuncs.h" 19 | #include "7ZipFunctions.h" 20 | #include "7ZipDllHandler.h" 21 | 22 | bool LoadDllFromFolder(C7ZipDllHandler * pMainHandler, 23 | const wstring & folder_name, 24 | C7ZipObjectPtrArray & handlers) 25 | { 26 | WIN32_FIND_DATA data; 27 | 28 | wstring path = pMainHandler->GetHandlerPath() + 29 | L"\\" + 30 | folder_name + 31 | L"\\*.*"; 32 | 33 | HANDLE hFind = ::FindFirstFile(path.c_str(), &data); 34 | 35 | if (hFind == INVALID_HANDLE_VALUE) 36 | return false; 37 | 38 | do 39 | { 40 | if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) 41 | { 42 | wstring dirname = data.cFileName; 43 | 44 | if (dirname == L"." || dirname == L"..") 45 | { 46 | } 47 | else 48 | { 49 | LoadDllFromFolder(pMainHandler, data.cFileName, handlers); 50 | } 51 | } 52 | else 53 | { 54 | void * pHandler = LoadLibrary(data.cFileName); 55 | 56 | C7ZipDllHandler * p7ZipHandler = new C7ZipDllHandler(pMainHandler->GetLibrary(), 57 | pHandler); 58 | 59 | if (p7ZipHandler->IsInitialized()) 60 | { 61 | handlers.push_back(p7ZipHandler); 62 | } 63 | else 64 | { 65 | delete p7ZipHandler; 66 | } 67 | } 68 | } 69 | while(::FindNextFile(hFind, &data)); 70 | 71 | ::FindClose(hFind); 72 | 73 | return true; 74 | } 75 | 76 | wstring GetHandlerPath(void * pHandler) 77 | { 78 | wchar_t buf[255] = {0}; 79 | 80 | if (GetModuleFileName((HMODULE)pHandler, buf, 254) > 0) 81 | { 82 | wstring path = buf; 83 | 84 | size_t pos = path.rfind(L"\\"); 85 | 86 | if (pos != wstring::npos) 87 | { 88 | return path.substr(0, pos); 89 | } 90 | } 91 | 92 | return L"."; 93 | } 94 | 95 | HMODULE Load7ZLibrary(const wstring & library) 96 | { 97 | return LoadLibrary(library.c_str()); 98 | } 99 | 100 | void Free7ZLibrary(HMODULE pModule) 101 | { 102 | ::FreeLibrary(pModule); 103 | } 104 | #endif //_WIN_32 105 | -------------------------------------------------------------------------------- /src/HelperFuncs.h: -------------------------------------------------------------------------------- 1 | #ifndef __HELPER_FUNCS_H__ 2 | #define __HELPER_FUNCS_H__ 3 | 4 | #ifndef RBOOLOK 5 | #define RBOOLOK(x) { int __result__ = (x); if (__result__ != 0) return false; } 6 | #endif 7 | 8 | #ifndef FAIL_RET 9 | #define FAIL_RET(x, pResult) { HRESULT __result__ = (x); if (pResult) *pResult = __result__; if (__result__ != S_OK) return __result__; } 10 | #endif 11 | 12 | #if MY_VER_MAJOR >= 15 13 | #define LIB7ZIP_THROW throw() 14 | #else 15 | #define LIB7ZIP_THROW 16 | #ifndef _WIN32 17 | #define WINAPI 18 | #endif 19 | #endif 20 | 21 | typedef UInt32 (WINAPI *GetMethodPropertyFunc)(UInt32 index, PROPID propID, PROPVARIANT *value); 22 | typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods); 23 | typedef UInt32 (WINAPI *GetNumberOfFormatsFunc)(UInt32 *numFormats); 24 | typedef UInt32 (WINAPI *GetHandlerPropertyFunc)(PROPID propID, PROPVARIANT *value); 25 | typedef UInt32 (WINAPI *GetHandlerPropertyFunc2)(UInt32 index, PROPID propID, PROPVARIANT *value); 26 | typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *iid, void **outObject); 27 | typedef UInt32 (WINAPI *SetLargePageModeFunc)(); 28 | 29 | const wchar_t kDirDelimiter = CHAR_PATH_SEPARATOR; 30 | 31 | HRESULT ReadProp(GetHandlerPropertyFunc getProp, 32 | GetHandlerPropertyFunc2 getProp2, 33 | UInt32 index, PROPID propID, 34 | NWindows::NCOM::CPropVariant &prop); 35 | 36 | HRESULT ReadBoolProp(GetHandlerPropertyFunc getProp, 37 | GetHandlerPropertyFunc2 getProp2, 38 | UInt32 index, PROPID propID, bool &res); 39 | 40 | HRESULT ReadStringProp(GetHandlerPropertyFunc getProp, 41 | GetHandlerPropertyFunc2 getProp2, 42 | UInt32 index, PROPID propID, wstring &res); 43 | 44 | void SplitString(const wstring &srcString, WStringArray &destStrings); 45 | 46 | HRESULT GetCoderClass(GetMethodPropertyFunc getMethodProperty, UInt32 index, 47 | PROPID propId, GUID & clsId, bool &isAssigned); 48 | 49 | HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result); 50 | 51 | int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) LIB7ZIP_THROW; 52 | 53 | HRESULT GetMethodPropertyString(GetMethodPropertyFunc getMethodProperty, UInt32 index, 54 | PROPID propId, wstring & val); 55 | HRESULT GetMethodPropertyGUID(GetMethodPropertyFunc getMethodProperty, UInt32 index, 56 | PROPID propId, GUID & val); 57 | 58 | UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &); 59 | 60 | HRESULT GetFilePathExt(const wstring & path, wstring & ext); 61 | HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, wstring &result); 62 | HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const wstring &defaultName, wstring &result); 63 | wstring WidenString( const string& str ); 64 | string NarrowString( const wstring& str ); 65 | 66 | #endif 67 | 68 | -------------------------------------------------------------------------------- /src/7ZipCodecInfo.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(_OS2) 2 | #include "CPP/myWindows/StdAfx.h" 3 | #include "CPP/include_windows/windows.h" 4 | #endif 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "Common/ComTry.h" 13 | #include "Windows/PropVariant.h" 14 | using namespace NWindows; 15 | 16 | #include "stdlib.h" 17 | 18 | #include "lib7zip.h" 19 | 20 | #include "HelperFuncs.h" 21 | #include "7ZipFunctions.h" 22 | 23 | #include "7ZipCodecInfo.h" 24 | 25 | /*------------------------ C7ZipCodecInfo ---------------------*/ 26 | C7ZipCodecInfo::C7ZipCodecInfo() 27 | { 28 | m_Name.clear(); 29 | memset(&m_ClassID,0,sizeof(GUID)); 30 | 31 | memset(&Encoder,0, sizeof(GUID)); 32 | EncoderAssigned = false; 33 | 34 | memset(&Decoder,0, sizeof(GUID)); 35 | DecoderAssigned = false; 36 | } 37 | 38 | C7ZipCodecInfo::~C7ZipCodecInfo() 39 | { 40 | } 41 | 42 | bool LoadCodecs(pU7ZipFunctions pFunctions, C7ZipObjectPtrArray & codecInfos) 43 | { 44 | if (pFunctions->v.CreateObject == NULL) 45 | return false; 46 | 47 | if (pFunctions->v.GetMethodProperty == NULL) 48 | return false; 49 | 50 | UInt32 numMethods = 0; 51 | RBOOLOK(pFunctions->v.GetNumberOfMethods(&numMethods)); 52 | 53 | for(UInt32 i = 0; i < numMethods; i++) 54 | { 55 | wstring name = L""; 56 | GUID classID; 57 | memset(&classID, 0, sizeof(GUID)); 58 | 59 | /* 60 | if(GetMethodPropertyString(pFunctions->v.GetMethodProperty, i, 61 | NMethodPropID::kName, name) != S_OK) 62 | continue; 63 | 64 | if (GetMethodPropertyGUID(pFunctions->v.GetMethodProperty, i, 65 | NMethodPropID::kID, classID) != S_OK) 66 | continue; 67 | */ 68 | 69 | GUID encoder, decoder; 70 | bool encoderIsAssigned, decoderIsAssigned; 71 | 72 | if (GetCoderClass(pFunctions->v.GetMethodProperty, i, 73 | NMethodPropID::kEncoder, encoder, encoderIsAssigned) != S_OK) 74 | continue; 75 | if (GetCoderClass(pFunctions->v.GetMethodProperty, i, 76 | NMethodPropID::kDecoder, decoder, decoderIsAssigned) != S_OK) 77 | continue; 78 | 79 | C7ZipCodecInfo * pInfo = new C7ZipCodecInfo(); 80 | pInfo->Functions = pFunctions; 81 | 82 | pInfo->m_Name = name; 83 | pInfo->m_ClassID = classID; 84 | 85 | pInfo->Encoder = encoder; 86 | pInfo->EncoderAssigned = encoderIsAssigned; 87 | 88 | pInfo->Decoder = decoder; 89 | pInfo->DecoderAssigned = decoderIsAssigned; 90 | 91 | pInfo->CodecIndex = i; 92 | codecInfos.push_back(pInfo); 93 | } 94 | 95 | return true; 96 | } 97 | -------------------------------------------------------------------------------- /src/7ZipArchiveOpenCallback.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(_OS2) 2 | #include "CPP/myWindows/StdAfx.h" 3 | #include "CPP/include_windows/windows.h" 4 | #endif 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "Common/ComTry.h" 13 | #include "Windows/PropVariant.h" 14 | using namespace NWindows; 15 | 16 | #include "stdlib.h" 17 | 18 | #include "lib7zip.h" 19 | #include "7ZipArchiveOpenCallback.h" 20 | #include "7ZipInStreamWrapper.h" 21 | 22 | /*--------------------C7ZipArchiveOpenCallback------------------*/ 23 | STDMETHODIMP C7ZipArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */) 24 | { 25 | return S_OK; 26 | } 27 | 28 | STDMETHODIMP C7ZipArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */) 29 | { 30 | return S_OK; 31 | } 32 | 33 | STDMETHODIMP C7ZipArchiveOpenCallback::CryptoGetTextPassword(BSTR *password) 34 | { 35 | if (!PasswordIsDefined) { 36 | return E_NEEDPASSWORD; 37 | } 38 | 39 | #ifdef _WIN32 40 | return StringToBstr(Password.c_str(), password); 41 | #else 42 | *password = ::SysAllocString(Password.c_str()); 43 | return S_OK; 44 | #endif 45 | } 46 | 47 | STDMETHODIMP C7ZipArchiveOpenCallback::GetProperty(PROPID propID, PROPVARIANT *value) 48 | { 49 | COM_TRY_BEGIN 50 | NCOM::CPropVariant prop; 51 | if (_subArchiveMode) 52 | switch(propID) 53 | { 54 | case kpidName: prop = _subArchiveName.c_str(); break; 55 | } 56 | else 57 | switch(propID) 58 | { 59 | case kpidName: 60 | { 61 | if (m_bMultiVolume) { 62 | prop = m_pMultiVolumes->GetFirstVolumeName().c_str(); 63 | } 64 | } 65 | break; 66 | case kpidIsDir: prop = false; break; 67 | case kpidSize: 68 | { 69 | if (m_bMultiVolume) { 70 | prop = m_pMultiVolumes->GetCurrentVolumeSize(); 71 | } 72 | } 73 | break; 74 | case kpidAttrib: prop = (UInt32)0; break; 75 | case kpidCTime: prop = 0; break; 76 | case kpidATime: prop = 0; break; 77 | case kpidMTime: prop = 0; break; 78 | } 79 | 80 | prop.Detach(value); 81 | return S_OK; 82 | COM_TRY_END 83 | } 84 | 85 | STDMETHODIMP C7ZipArchiveOpenCallback::GetStream(const wchar_t *name, IInStream **inStream) 86 | { 87 | C7ZipInStream * pInStream = NULL; 88 | if (m_bMultiVolume) { 89 | if (!m_pMultiVolumes->MoveToVolume(name)) 90 | return S_FALSE; 91 | 92 | pInStream = m_pMultiVolumes->OpenCurrentVolumeStream(); 93 | } else { 94 | return S_FALSE; 95 | } 96 | 97 | C7ZipInStreamWrapper * pArchiveStream = new C7ZipInStreamWrapper(pInStream); 98 | 99 | CMyComPtr inStreamTemp(pArchiveStream); 100 | *inStream = inStreamTemp.Detach(); 101 | return S_OK; 102 | } 103 | -------------------------------------------------------------------------------- /src/7ZipCompressCodecsInfo.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(_OS2) 2 | #include "CPP/myWindows/StdAfx.h" 3 | #include "CPP/include_windows/windows.h" 4 | #endif 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "Common/ComTry.h" 13 | #include "Windows/PropVariant.h" 14 | using namespace NWindows; 15 | 16 | #include "stdlib.h" 17 | 18 | #include "lib7zip.h" 19 | #include "HelperFuncs.h" 20 | #include "7ZipFunctions.h" 21 | #include "7ZipDllHandler.h" 22 | #include "7ZipCodecInfo.h" 23 | #include "7ZipCompressCodecsInfo.h" 24 | 25 | /*----------------------- C7ZipCompressCodecsInfo -------------------------*/ 26 | C7ZipCompressCodecsInfo::C7ZipCompressCodecsInfo(C7ZipLibrary * pLibrary) : 27 | m_pLibrary(pLibrary), 28 | m_CodecInfoArray(false) 29 | { 30 | InitData(); 31 | } 32 | 33 | C7ZipCompressCodecsInfo::~C7ZipCompressCodecsInfo() 34 | { 35 | } 36 | 37 | void C7ZipCompressCodecsInfo::InitData() 38 | { 39 | if (!m_pLibrary->IsInitialized()) 40 | return; 41 | 42 | const C7ZipObjectPtrArray & handlers = 43 | m_pLibrary->GetInternalObjectsArray(); 44 | 45 | for(C7ZipObjectPtrArray::const_iterator it = handlers.begin(); 46 | it != handlers.end(); it++) 47 | { 48 | C7ZipDllHandler * pHandler = dynamic_cast(*it); 49 | 50 | if (pHandler != NULL) 51 | { 52 | const C7ZipObjectPtrArray & codecs = pHandler->GetCodecInfoArray(); 53 | 54 | for(C7ZipObjectPtrArray::const_iterator itCodec = codecs.begin(); 55 | itCodec != codecs.end(); itCodec++) 56 | { 57 | m_CodecInfoArray.push_back(*itCodec); 58 | } 59 | } 60 | } 61 | } 62 | 63 | #if MY_VER_MAJOR >= 15 64 | HRESULT C7ZipCompressCodecsInfo::GetNumMethods(UInt32 *numMethods) 65 | #else 66 | HRESULT C7ZipCompressCodecsInfo::GetNumberOfMethods(UInt32 *numMethods) 67 | #endif 68 | { 69 | *numMethods = (UInt32)m_CodecInfoArray.size(); 70 | 71 | return S_OK; 72 | } 73 | 74 | HRESULT C7ZipCompressCodecsInfo::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) 75 | { 76 | C7ZipCodecInfo * pCodec = dynamic_cast(m_CodecInfoArray[index]); 77 | 78 | if (propID == NMethodPropID::kDecoderIsAssigned) 79 | { 80 | NWindows::NCOM::CPropVariant propVariant; 81 | propVariant = pCodec->DecoderAssigned; 82 | propVariant.Detach(value); 83 | return S_OK; 84 | } 85 | if (propID == NMethodPropID::kEncoderIsAssigned) 86 | { 87 | NWindows::NCOM::CPropVariant propVariant; 88 | propVariant = pCodec->EncoderAssigned; 89 | propVariant.Detach(value); 90 | return S_OK; 91 | } 92 | return pCodec->Functions->v.GetMethodProperty(pCodec->CodecIndex, propID, value); 93 | } 94 | 95 | HRESULT C7ZipCompressCodecsInfo::CreateDecoder(UInt32 index, const GUID *interfaceID, void **coder) 96 | { 97 | C7ZipCodecInfo * pCodec = dynamic_cast(m_CodecInfoArray[index]); 98 | 99 | if (pCodec->DecoderAssigned) 100 | return pCodec->Functions->v.CreateObject(&pCodec->Decoder, 101 | interfaceID, 102 | coder); 103 | return S_OK; 104 | } 105 | 106 | HRESULT C7ZipCompressCodecsInfo::CreateEncoder(UInt32 index, const GUID *interfaceID, void **coder) 107 | { 108 | C7ZipCodecInfo * pCodec = dynamic_cast(m_CodecInfoArray[index]); 109 | 110 | if (pCodec->EncoderAssigned) 111 | return pCodec->Functions->v.CreateObject(&pCodec->Encoder, 112 | interfaceID, 113 | coder); 114 | return S_OK; 115 | } 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lib7zip 2 | A library using 7z.dll/7z.so(from 7-Zip) to handle different archive types. lib7zip is based on 7zip/p7zip source code, but NOT including any source code from 7zip/p7zip. 3 | 4 | Tips 5 | ==== 6 | * Build lib7zip 7 | * Under UNIX/LINUX like system 8 | * Get a copy of p7zip source code, and extract to a folder 9 | * Define a env P7ZIP_SOURCE_DIR point to the extracted folder 10 | * cmake -DBUILD_SHARED_LIB=OFF -DP7ZIP_SOURCE_DIR=${P7ZIP_SOURCE_DIR} 11 | * Under windows 12 | * Get mingw from http://www.mingw.org 13 | * Get a copy of original 7zip source code, NOT the p7zip for linux 14 | * Define a env P7ZIP_SOURCE_DIR point to the extracted folder 15 | * cmake -DBUILD_SHARED_LIB=OFF -DP7ZIP_SOURCE_DIR=${P7ZIP_SOURCE_DIR} 16 | * Run lib7zip 17 | * Under UNIX/LINUX like system 18 | * install p7zip binary 19 | * find 7z.so path, export LD_LIBRARY_PATH= 20 | * Under Windows 21 | * install 7zip binary 22 | * copy 7z.dll to where your application existing 23 | 24 | > __Any time or any problem about lib7zip, please feel free to write me an email.__ 25 | 26 | > __Any feature or patch request, please also feel free to write me an email.__ 27 | 28 | Thanks 29 | ==== 30 | * Many thanks to _Joe_ who provide so many great patches 31 | * Many thanks to _Christoph_ who give so many great advises and patch. 32 | * Many thanks to _Christoph Thielecke_ to provide great patches for OS2 and dynamic library 33 | 34 | To Do 35 | ==== 36 | * Add Compress function to library 37 | 38 | Related Projects 39 | ==== 40 | * Python Binding created by Mark, http://github.com/harvimt/pylib7zip 41 | 42 | Change Log 43 | ==== 44 | 3.0.0 45 | ---- 46 | 1. move build system to cmake 47 | 2. fix bug when do signature detect for dmg files 48 | 3. fix bug of memory leaking when deal with sub archive 49 | 50 | 2.0.0 51 | ---- 52 | 1. Make the library compiling with latest p7zip 15.9.0 and 7zip 15.10.0 53 | 2. Fix bug in test7zipmulti 54 | 55 | 1.6.5 56 | ---- 57 | 1. Add new parameter bool fDetectFileTypeBySignature to OpenArchive, when fDetectFileTypeBySignature = true, lib7zip will using file signature instead file name extension to detect file type 58 | 2. remove out-of-dated visual studio files 59 | 60 | 1.6.4 61 | ---- 62 | 1. add AUTHORS COPYING file 63 | 2. add LIB7ZIP_ prefix to error code enum,break the old client, please update your code 64 | 3. add APIs SetLib7ZipLocale and GetLib7ZipLocale, client could use these API to force lib7zip locale, otherwise lib7zip will use current user's locale 65 | 4. add list of path to find 7z.so when 7z.so is not in users ld path 66 | 5. fix Mac OSX compile fail problem 67 | 68 | 1.6.3 69 | ---- 70 | 1. Add GetLastError to C7ZipLibrary and Error code define in lib7zip.h 71 | 2. open archive with password now work for archive created by 7za a -mhe -p, who encrypted the file names in archive 72 | 73 | 1.6.2 74 | ---- 75 | 1. Fixed broken windows built system 76 | 2. Fixed build script for windows 77 | 78 | 1.6.1 79 | ---- 80 | 1. Add OS2 support 81 | 2. create dynamic library along with static library 82 | 83 | 1.6.0 84 | ---- 85 | 1. Add Multi-Volume support 86 | 87 | 1.5.0 88 | ---- 89 | 1. Add Password support 90 | 91 | 1.4.1 92 | ---- 93 | 1. Add GetProperty functions to C7ZipArchive to retrieve archive properties 94 | 2. Add kpidSize to return Item umcompressed size, the same as GetSize returning 95 | 96 | 1.4.0 97 | ---- 98 | 1. Add patches from Christoph 99 | 2. make the test program works when no Test7Zip.7z found 100 | 3. Add functions to get more property about items in the archive 101 | 4. Tested on Mac OS X 102 | 5. Move source control to Mercurial for better distributed development 103 | 104 | 1.3.0 105 | ---- 106 | 1. Add patches from Joe, 107 | 2. make the library work with latest p7zip 9.20 108 | 109 | 1.0.2 110 | ---- 111 | 1. Add patches from Joe, 112 | 2. Add a method to get the compressed size 113 | 3. Add a method to expose whether the file is encrypted 114 | 4. Build scripts update 115 | 5. Small fix to make the lib working with the latest p7zip source 116 | 117 | 1.0.1 118 | ---- 119 | 1. First release, support both LINUX and windows platform. 120 | -------------------------------------------------------------------------------- /src/7ZipDllHandler.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(_OS2) 2 | #include "CPP/myWindows/StdAfx.h" 3 | #include "CPP/include_windows/windows.h" 4 | #endif 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "Common/ComTry.h" 13 | #include "Windows/PropVariant.h" 14 | #if MY_VER_MAJOR >= 15 15 | #include "CPP/Common/MyBuffer.h" 16 | #else 17 | #include "CPP/Common/Buffer.h" 18 | #endif 19 | 20 | 21 | using namespace NWindows; 22 | 23 | #include "lib7zip.h" 24 | 25 | #include "HelperFuncs.h" 26 | #include "7ZipFunctions.h" 27 | #include "7ZipDllHandler.h" 28 | #include "7ZipCodecInfo.h" 29 | #include "7ZipFormatInfo.h" 30 | 31 | #ifdef _WIN32_WCE 32 | #define myT(x) L##x 33 | #else 34 | #define myT(x) x 35 | #endif 36 | 37 | #include "OSFunctions.h" 38 | 39 | extern bool LoadCodecs(pU7ZipFunctions pFunctions, C7ZipObjectPtrArray & codecInfos); 40 | extern bool LoadFormats(pU7ZipFunctions pFunctions, C7ZipObjectPtrArray & formats); 41 | extern HRESULT Lib7ZipOpenArchive(C7ZipLibrary * pLibrary, 42 | C7ZipDllHandler * pHandler, 43 | C7ZipInStream * pInStream, 44 | C7ZipArchive ** ppArchive, 45 | const wstring & passwd, 46 | HRESULT * pResult, 47 | bool fCheckFileTypeBySignature); 48 | extern HRESULT Lib7ZipOpenMultiVolumeArchive(C7ZipLibrary * pLibrary, 49 | C7ZipDllHandler * pHandler, 50 | C7ZipMultiVolumes * pMultiVolumes, 51 | C7ZipArchive ** ppArchive, 52 | const wstring & passwd, 53 | HRESULT * pResult, 54 | bool fCheckFileTypeBySignature); 55 | 56 | /*------------------------------ C7ZipDllHandler ------------------------*/ 57 | C7ZipDllHandler::C7ZipDllHandler(C7ZipLibrary * pLibrary, void * pHandler) : 58 | m_pLibrary(pLibrary) 59 | , m_bInitialized(false) 60 | , m_pHandler(pHandler) 61 | { 62 | Initialize(); 63 | } 64 | 65 | C7ZipDllHandler::~C7ZipDllHandler() 66 | { 67 | Deinitialize(); 68 | } 69 | 70 | void C7ZipDllHandler::Initialize() 71 | { 72 | pU7ZipFunctions pFunctions = &m_Functions; 73 | 74 | pFunctions->v.GetMethodProperty = 75 | (GetMethodPropertyFunc)GetProcAddress((HMODULE)m_pHandler, myT("GetMethodProperty")); 76 | pFunctions->v.GetNumberOfMethods = 77 | (GetNumberOfMethodsFunc)GetProcAddress((HMODULE)m_pHandler, myT("GetNumberOfMethods")); 78 | pFunctions->v.GetNumberOfFormats = 79 | (GetNumberOfFormatsFunc)GetProcAddress((HMODULE)m_pHandler, myT("GetNumberOfFormats")); 80 | pFunctions->v.GetHandlerProperty = 81 | (GetHandlerPropertyFunc)GetProcAddress((HMODULE)m_pHandler, myT("GetHandlerProperty")); 82 | pFunctions->v.GetHandlerProperty2 = 83 | (GetHandlerPropertyFunc2)GetProcAddress((HMODULE)m_pHandler, myT("GetHandlerProperty2")); 84 | pFunctions->v.CreateObject = 85 | (CreateObjectFunc)GetProcAddress((HMODULE)m_pHandler, myT("CreateObject")); 86 | pFunctions->v.SetLargePageMode = 87 | (SetLargePageModeFunc)GetProcAddress((HMODULE)m_pHandler, myT("SetLargePageMode")); 88 | 89 | if (pFunctions->v.IsValid()) { 90 | m_bInitialized = LoadCodecs(pFunctions, m_CodecInfoArray); 91 | 92 | m_bInitialized |= LoadFormats(pFunctions, m_FormatInfoArray); 93 | } 94 | } 95 | 96 | void C7ZipDllHandler::Deinitialize() 97 | { 98 | Free7ZLibrary((HMODULE)m_pHandler); 99 | 100 | m_CodecInfoArray.clear(); 101 | m_FormatInfoArray.clear(); 102 | 103 | m_bInitialized = false; 104 | } 105 | 106 | bool C7ZipDllHandler::GetSupportedExts(WStringArray & exts) 107 | { 108 | if (!m_bInitialized) 109 | return false; 110 | 111 | for(C7ZipObjectPtrArray::iterator it = m_FormatInfoArray.begin(); it != m_FormatInfoArray.end(); it++) { 112 | C7ZipFormatInfo * pInfo = dynamic_cast(*it); 113 | 114 | for(WStringArray::iterator extIt = pInfo->Exts.begin(); extIt != pInfo->Exts.end(); extIt++) { 115 | exts.push_back(*extIt); 116 | } 117 | } 118 | 119 | return true; 120 | } 121 | 122 | bool C7ZipDllHandler::OpenArchive(C7ZipInStream * pInStream, C7ZipMultiVolumes * pMultiVolumes, 123 | C7ZipArchive ** ppArchive, const wstring & passwd, 124 | HRESULT * pResult, 125 | bool fCheckFileTypeBySignature) 126 | { 127 | if (pMultiVolumes != NULL) 128 | return Lib7ZipOpenMultiVolumeArchive(m_pLibrary, this, pMultiVolumes, ppArchive, 129 | passwd, pResult, fCheckFileTypeBySignature) == S_OK; 130 | else if (pInStream != NULL) 131 | return Lib7ZipOpenArchive(m_pLibrary, this, pInStream, ppArchive, 132 | passwd, pResult, fCheckFileTypeBySignature) == S_OK; 133 | 134 | return S_FALSE; 135 | } 136 | 137 | wstring C7ZipDllHandler::GetHandlerPath() const 138 | { 139 | #if defined(_WIN32) 140 | return ::GetHandlerPath((HMODULE)m_pHandler); 141 | #else 142 | return ::GetHandlerPath((HMODULE)m_Functions.v.CreateObject); 143 | #endif 144 | } 145 | -------------------------------------------------------------------------------- /src/OSFunctions_OS2.cpp: -------------------------------------------------------------------------------- 1 | #ifdef OS2 2 | 3 | #include 4 | #include "HelperFuncs.h" 5 | 6 | static HMODULE *hmod2; 7 | 8 | void *GetProcAddress (HMODULE hmod, const char *symbol) { 9 | void *addr = NULL; 10 | PFN ModuleAddr = 0; 11 | APIRET rc = 0; 12 | HMODULE hmod3 = *hmod2; 13 | //HMODULE hmod3 = hmod; 14 | std::cerr << "DosQueryProcAddr " << symbol << " from module hmod3: " << hmod2 << std::endl; 15 | char *symbol3 = strdup(symbol); 16 | //std::cerr << "DosQueryProcAddr (2) " << symbol2 << " from module hmod3: " << hmod2 << std::endl; 17 | 18 | /* Load DLL and get hmod with DosLoadModule*/ 19 | /* Get address for process in DLL */ 20 | rc = DosQueryProcAddr(hmod3, 0, (PSZ )symbol3, &ModuleAddr); 21 | /* 22 | return codes: 23 | 0 NO_ERROR 24 | 6 ERROR_INVALID_HANDLE 25 | 123 ERROR_INVALID_NAME 26 | 182 ERROR_INVALID_ORDINAL 27 | 65079 ERROR_ENTRY_IS_CALLGATE (this error code is not valid in OS/2 Warp PowerPC Edition) 28 | */ 29 | if(rc) { 30 | // error; 31 | #if defined(_OS2_LIBDEBUG) 32 | std::cerr << "DosQueryProcAddr of " << symbol << " from module at " << hmod2 << " failed. " << " (ret code: " << rc << ")" << std::endl; 33 | #endif 34 | } else { 35 | addr = (void *)ModuleAddr; 36 | #if defined(_OS2_LIBDEBUG) 37 | std::cerr << "DosQueryProcAddr " << symbol << " from module at " << hmod2 << " succeeded (addr: " << &ModuleAddr << " ). " << std::endl; 38 | #endif 39 | 40 | } 41 | return addr; 42 | } 43 | 44 | HMODULE Load7ZLibrary(const wstring & name) { 45 | unsigned char szErrorName[CCHMAXPATH]; 46 | unsigned char libname[20]; 47 | szErrorName[0]= '\0'; 48 | void *pHandler = NULL; 49 | HMODULE *hmod = (HMODULE *) calloc(1, sizeof(HMODULE)); 50 | APIRET rc; 51 | string tmpName = NarrowString(wstring(L".\\") + name + L".dll"); 52 | strncpy((char *)libname, tmpName.c_str(), 19); 53 | rc = DosLoadModule(szErrorName, CCHMAXPATH-1, libname, hmod); 54 | /* 55 | return codes: 56 | 0 NO_ERROR 57 | 2 ERROR_FILE_NOT_FOUND 58 | 3 ERROR_PATH_NOT_FOUND 59 | 4 ERROR_TOO_MANY_OPEN_FILES 60 | 5 ERROR_ACCESS_DENIED 61 | 8 ERROR_NOT_ENOUGH_MEMORY 62 | 11 ERROR_BAD_FORMAT 63 | 26 ERROR_NOT_DOS_DISK 64 | 32 ERROR_SHARING_VIOLATION 65 | 33 ERROR_LOCK_VIOLATION 66 | 36 ERROR_SHARING_BUFFER_EXCEEDED 67 | 95 ERROR_INTERRUPT 68 | 108 ERROR_DRIVE_LOCKED 69 | 123 ERROR_INVALID_NAME 70 | 127 ERROR_PROC_NOT_FOUND 71 | 180 ERROR_INVALID_SEGMENT_NUMBER 72 | 182 ERROR_INVALID_ORDINAL 73 | 190 ERROR_INVALID_MODULETYPE 74 | 191 ERROR_INVALID_EXE_SIGNATURE 75 | 192 ERROR_EXE_MARKED_INVALID 76 | 194 ERROR_ITERATED_DATA_EXCEEDS_64K 77 | 195 ERROR_INVALID_MINALLOCSIZE 78 | 196 ERROR_DYNLINK_FROM_INVALID_RING 79 | 198 ERROR_INVALID_SEGDPL 80 | 199 ERROR_AUTODATASEG_EXCEEDS_64K 81 | 201 ERROR_RELOCSRC_CHAIN_EXCEEDS_SEGLIMIT 82 | 206 ERROR_FILENAME_EXCED_RANGE 83 | 295 ERROR_INIT_ROUTINE_FAILED 84 | */ 85 | hmod2 = hmod; 86 | pHandler = hmod2; 87 | #if defined(_OS2_LIBDEBUG) 88 | std::cerr << "DosLoadModule: rc:" << rc << ", pHandler: " << pHandler << std::endl; 89 | #endif 90 | if (rc) { 91 | #if defined(_OS2_LIBDEBUG) 92 | std::cerr << "DosLoadModule: loading " << libname << " failed: " << szErrorName << ", (ret code: " << rc << ")" << std::endl; 93 | #endif 94 | pHandler = NULL; 95 | } else { 96 | #if defined(_OS2_LIBDEBUG) 97 | std::cerr << "DosLoadModule: loading " << libname << " succeeded. " << std::endl; 98 | #endif 99 | } 100 | 101 | return pHandler; 102 | } 103 | 104 | void Free7ZLibrary(HMODULE pModule) 105 | { 106 | APIRET rc=0; 107 | rc = DosFreeModule(pModule); 108 | if (rc) { 109 | #if defined(_OS2_LIBDEBUG) 110 | std::cerr << "DosFreeModule: unloading lib at " << pModule << " failed, (ret code: " << rc << ")" << std::endl; 111 | #endif 112 | } else { 113 | #if defined(_OS2_LIBDEBUG) 114 | std::cerr << "DosFreeModule: unloading lib at " << pModule << " succeeded. " << std::endl; 115 | #endif 116 | } 117 | free(hmod2); 118 | hmod2 = NULL; 119 | } 120 | 121 | wstring GetHandlerPath(void * pHandler) 122 | { 123 | HMODULE *handler = (HMODULE *)pHandler 124 | HMODULE hmod = *handler; 125 | 126 | char module_name[CCHMAXPATH]; 127 | char *result; 128 | int rc; 129 | module_name[0] = '\0'; 130 | 131 | /* 132 | return values 133 | 0 NO_ERROR 134 | 6 ERROR_INVALID_HANDLE 135 | 24 ERROR_BAD_LENGTH 136 | */ 137 | rc = DosQueryModuleName(*hmod2, sizeof module_name, module_name); 138 | 139 | if (rc ) { 140 | std::cerr << "DosQueryModuleName of " << handler << " failed: (ret: " << rc << ")"<< std::endl; 141 | } else { 142 | #if defined(_OS2_LIBDEBUG) 143 | std::cerr << "DosQueryModuleName of " << handler << " succeeded. " << std::endl; 144 | #endif 145 | } 146 | 147 | return WidenString(module_name); 148 | } 149 | 150 | bool LoadDllFromFolder(C7ZipDllHandler * pMainHandler, const wstring & wfolder_name, C7ZipObjectPtrArray & handlers) 151 | { 152 | #if defined(_OS2_LIBDEBUG) 153 | std::cerr << "LoadDllFromFolder do nothing on OS2 " << std::endl; 154 | #endif 155 | return true; 156 | } 157 | #endif //_OS2 158 | -------------------------------------------------------------------------------- /src/OSFunctions_UnixLike.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(OS2) 2 | 3 | #include "CPP/myWindows/StdAfx.h" 4 | #include "CPP/include_windows/windows.h" 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "Common/ComTry.h" 13 | #include "Windows/PropVariant.h" 14 | using namespace NWindows; 15 | 16 | #include "lib7zip.h" 17 | #include "HelperFuncs.h" 18 | #include "7ZipFunctions.h" 19 | #include "7ZipDllHandler.h" 20 | 21 | #include 22 | #include 23 | 24 | #ifndef _GNU_SOURCE 25 | #define _GNU_SOURCE 26 | #endif 27 | #include "dlfcn.h" 28 | #include "unistd.h" 29 | 30 | #ifdef __APPLE__ 31 | #include 32 | #endif 33 | 34 | #include "dirent.h" 35 | 36 | #include "OSFunctions_UnixLike.h" 37 | 38 | #if __APPLE__ && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9) 39 | int myselect(struct dirent * pDir ); 40 | #else 41 | int myselect(const struct dirent * pDir ); 42 | #endif //__APPLE__ 43 | 44 | static C7ZipObjectPtrArray * g_pHandlers = NULL; 45 | static C7ZipLibrary * g_pLibrary = NULL; 46 | 47 | bool LoadDllFromFolder(C7ZipDllHandler * pMainHandler, const wstring & wfolder_name, C7ZipObjectPtrArray & handlers) 48 | { 49 | g_pHandlers = &handlers; 50 | g_pLibrary = pMainHandler->GetLibrary(); 51 | 52 | string folder_name = NarrowString(wfolder_name); 53 | string mainHandlerPath = NarrowString(pMainHandler->GetHandlerPath()); 54 | string folderPath = mainHandlerPath + "/" + folder_name; 55 | 56 | char * current_dir = getcwd(NULL, 0); 57 | 58 | int result = chdir(folderPath.c_str()); 59 | 60 | struct dirent **namelist = NULL; 61 | 62 | if (result == 0) { 63 | scandir( ".", &namelist,myselect,alphasort ); 64 | } 65 | 66 | result = chdir(current_dir); 67 | 68 | free(current_dir); 69 | 70 | g_pHandlers = NULL; 71 | g_pLibrary = NULL; 72 | return true; 73 | } 74 | 75 | #if __APPLE__ && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9) 76 | int myselect(struct dirent * pDir ) 77 | #else 78 | int myselect(const struct dirent * pDir ) 79 | #endif //__APPLE__ 80 | { 81 | if ( NULL == pDir ) 82 | return 0; 83 | 84 | const char * szEntryName = pDir->d_name; 85 | 86 | if ( ( strcasecmp( szEntryName,"." ) == 0 ) || 87 | ( strcasecmp( szEntryName,".." ) == 0 ) ) 88 | { 89 | return 0; 90 | } 91 | 92 | DIR * pTmpDir = NULL; 93 | 94 | if ( NULL == ( pTmpDir = opendir(szEntryName) ) ) 95 | { 96 | if ( errno == ENOTDIR ) 97 | { 98 | char * current_path = getcwd(NULL, 0); 99 | string path = current_path; 100 | path += "/"; 101 | path += szEntryName; 102 | free(current_path); 103 | 104 | void * pHandler = dlopen(path.c_str(), RTLD_LAZY | RTLD_GLOBAL); 105 | 106 | if (pHandler != NULL) 107 | { 108 | C7ZipDllHandler * p7ZipHandler = new C7ZipDllHandler(g_pLibrary, pHandler); 109 | 110 | if (p7ZipHandler->IsInitialized()) 111 | { 112 | g_pHandlers->push_back(p7ZipHandler); 113 | } 114 | else 115 | { 116 | delete p7ZipHandler; 117 | } 118 | } 119 | } 120 | } 121 | else 122 | { 123 | closedir( pTmpDir ); 124 | 125 | (void)chdir( szEntryName ); 126 | 127 | struct dirent **namelist = NULL; 128 | 129 | scandir( ".",&namelist,myselect,alphasort ); 130 | 131 | (void)chdir( ".." ); 132 | } 133 | 134 | return 0; 135 | } 136 | 137 | wstring GetHandlerPath(void * pHandler) 138 | { 139 | Dl_info info; 140 | 141 | memset(&info, 0, sizeof(Dl_info)); 142 | 143 | if (dladdr((void *)pHandler,&info)) 144 | { 145 | if (info.dli_fname != NULL) 146 | { 147 | string path = info.dli_fname; 148 | 149 | size_t pos = path.rfind("/"); 150 | 151 | if (pos != string::npos) 152 | { 153 | return WidenString(path.substr(0, pos)); 154 | } 155 | } 156 | } 157 | 158 | return L"."; 159 | } 160 | 161 | HMODULE Load7ZLibrary(const wstring & name) 162 | { 163 | string tmpName = NarrowString(name + L".so"); 164 | 165 | HMODULE pHandler = dlopen(tmpName.c_str(), RTLD_LAZY | RTLD_GLOBAL); 166 | 167 | if (pHandler) 168 | return pHandler; 169 | 170 | size_t pos = tmpName.rfind("/"); 171 | 172 | if (pos != string::npos) 173 | { 174 | tmpName = tmpName.substr(pos + 1); 175 | } 176 | 177 | std::vector lib_search_pathlist; 178 | 179 | lib_search_pathlist.push_back("/usr/local/lib"); 180 | lib_search_pathlist.push_back("/usr/lib"); 181 | lib_search_pathlist.push_back("/usr/lib/p7zip"); 182 | lib_search_pathlist.push_back("/usr/local/lib/p7zip"); 183 | lib_search_pathlist.push_back("."); 184 | 185 | for(std::vector::iterator lib_search_pathlistIt = lib_search_pathlist.begin(); 186 | lib_search_pathlistIt != lib_search_pathlist.end(); 187 | lib_search_pathlistIt++) 188 | { 189 | string path_prefix = *lib_search_pathlistIt; 190 | path_prefix += "/"; 191 | path_prefix += tmpName; 192 | 193 | pHandler = dlopen(path_prefix.c_str(), RTLD_LAZY | RTLD_GLOBAL); 194 | if ( pHandler != NULL) 195 | break; 196 | } 197 | return pHandler; 198 | } 199 | 200 | void Free7ZLibrary(HMODULE pModule) 201 | { 202 | dlclose(pModule); 203 | } 204 | 205 | #endif 206 | -------------------------------------------------------------------------------- /src/7zipLibrary.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(_OS2) 2 | #include "CPP/myWindows/StdAfx.h" 3 | #include "CPP/include_windows/windows.h" 4 | #endif 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "Common/ComTry.h" 13 | #include "Windows/PropVariant.h" 14 | using namespace NWindows; 15 | 16 | #include "stdlib.h" 17 | 18 | #ifndef _WIN32_WCE 19 | #include 20 | #else 21 | #include 22 | #endif 23 | 24 | #if !defined(_WIN32) 25 | #ifndef _GNU_SOURCE 26 | #define _GNU_SOURCE 27 | #endif 28 | #include "dlfcn.h" 29 | #include "unistd.h" 30 | #endif 31 | 32 | #include "lib7zip.h" 33 | 34 | #include "HelperFuncs.h" 35 | #include "7ZipFunctions.h" 36 | #include "7ZipDllHandler.h" 37 | #include "OSFunctions.h" 38 | #include "7ZipArchiveOpenCallback.h" 39 | 40 | /*-------------- static functions ------------------------*/ 41 | extern bool LoadDllFromFolder(C7ZipDllHandler * pMainHandler, const wstring & folder_name, C7ZipObjectPtrArray & handlers); 42 | static lib7zip::ErrorCodeEnum HResultToErrorCode(HRESULT hr); 43 | 44 | /*------------------------ C7ZipLibrary ---------------------*/ 45 | 46 | C7ZipLibrary::C7ZipLibrary() : 47 | m_bInitialized(false) 48 | { 49 | } 50 | 51 | C7ZipLibrary::~C7ZipLibrary() 52 | { 53 | Deinitialize(); 54 | } 55 | 56 | void C7ZipLibrary::Deinitialize() 57 | { 58 | if (!m_bInitialized) 59 | return; 60 | 61 | m_InternalObjectsArray.clear(); 62 | 63 | m_bInitialized = false; 64 | } 65 | 66 | bool C7ZipLibrary::Initialize() 67 | { 68 | if (m_bInitialized) 69 | return true; 70 | 71 | void * pHandler = Load7ZLibrary(L"7z"); 72 | 73 | if (pHandler == NULL) 74 | return false; 75 | 76 | C7ZipDllHandler * p7ZipHandler = new C7ZipDllHandler(this, pHandler); 77 | 78 | if (p7ZipHandler->IsInitialized()) 79 | { 80 | m_InternalObjectsArray.push_back(p7ZipHandler); 81 | 82 | m_bInitialized = true; 83 | 84 | LoadDllFromFolder(p7ZipHandler, L"Codecs", m_InternalObjectsArray); 85 | LoadDllFromFolder(p7ZipHandler, L"Formats", m_InternalObjectsArray); 86 | } 87 | else 88 | { 89 | delete p7ZipHandler; 90 | m_bInitialized = false; 91 | } 92 | 93 | return m_bInitialized; 94 | } 95 | 96 | bool C7ZipLibrary::GetSupportedExts(WStringArray & exts) 97 | { 98 | exts.clear(); 99 | 100 | if (!m_bInitialized) 101 | return false; 102 | 103 | for(C7ZipObjectPtrArray::iterator it = m_InternalObjectsArray.begin(); 104 | it != m_InternalObjectsArray.end(); it++) 105 | { 106 | C7ZipDllHandler * pHandler = dynamic_cast(*it); 107 | 108 | if (pHandler != NULL) 109 | { 110 | pHandler->GetSupportedExts(exts); 111 | } 112 | } 113 | 114 | return true; 115 | } 116 | 117 | bool C7ZipLibrary::OpenArchive(C7ZipInStream * pInStream, C7ZipArchive ** ppArchive, 118 | const wstring & passwd, bool fCheckFileTypeBySignature) 119 | { 120 | if (!m_bInitialized) { 121 | m_LastError = lib7zip::LIB7ZIP_NOT_INITIALIZE; 122 | return false; 123 | } 124 | 125 | for(C7ZipObjectPtrArray::iterator it = m_InternalObjectsArray.begin(); 126 | it != m_InternalObjectsArray.end(); it++) 127 | { 128 | C7ZipDllHandler * pHandler = dynamic_cast(*it); 129 | HRESULT hr = S_OK; 130 | 131 | if (pHandler != NULL && pHandler->OpenArchive(pInStream, NULL, ppArchive, 132 | passwd, &hr, 133 | fCheckFileTypeBySignature)) 134 | { 135 | if (*ppArchive) 136 | (*ppArchive)->SetArchivePassword(passwd); 137 | m_LastError = HResultToErrorCode(hr); 138 | return true; 139 | } 140 | 141 | m_LastError = HResultToErrorCode(hr); 142 | 143 | if (m_LastError == lib7zip::LIB7ZIP_NEED_PASSWORD) 144 | return false; 145 | } 146 | 147 | m_LastError = lib7zip::LIB7ZIP_NOT_SUPPORTED_ARCHIVE; 148 | return false; 149 | } 150 | 151 | bool C7ZipLibrary::OpenArchive(C7ZipInStream * pInStream, C7ZipArchive ** ppArchive, bool fCheckFileTypeBySignature) 152 | { 153 | return OpenArchive(pInStream, ppArchive, L"", fCheckFileTypeBySignature); 154 | } 155 | 156 | bool C7ZipLibrary::OpenMultiVolumeArchive(C7ZipMultiVolumes * pMultiVolumes, C7ZipArchive ** ppArchive, 157 | const wstring & passwd, bool fCheckFileTypeBySignature) 158 | { 159 | if (!m_bInitialized) { 160 | m_LastError = lib7zip::LIB7ZIP_NOT_INITIALIZE; 161 | return false; 162 | } 163 | 164 | for(C7ZipObjectPtrArray::iterator it = m_InternalObjectsArray.begin(); 165 | it != m_InternalObjectsArray.end(); it++) 166 | { 167 | C7ZipDllHandler * pHandler = dynamic_cast(*it); 168 | HRESULT hr = S_OK; 169 | 170 | if (pHandler != NULL && pHandler->OpenArchive(NULL, pMultiVolumes, ppArchive, 171 | passwd, &hr, 172 | fCheckFileTypeBySignature)) 173 | { 174 | if (*ppArchive) 175 | (*ppArchive)->SetArchivePassword(passwd); 176 | m_LastError = HResultToErrorCode(hr); 177 | return true; 178 | } 179 | 180 | m_LastError = HResultToErrorCode(hr); 181 | 182 | if (m_LastError == lib7zip::LIB7ZIP_NEED_PASSWORD) 183 | return false; 184 | } 185 | 186 | m_LastError = lib7zip::LIB7ZIP_NOT_SUPPORTED_ARCHIVE; 187 | return false; 188 | } 189 | 190 | bool C7ZipLibrary::OpenMultiVolumeArchive(C7ZipMultiVolumes * pInStream, C7ZipArchive ** ppArchive, 191 | bool fCheckFileTypeBySignature) 192 | { 193 | return OpenMultiVolumeArchive(pInStream, ppArchive, L"", fCheckFileTypeBySignature); 194 | } 195 | 196 | static lib7zip::ErrorCodeEnum HResultToErrorCode(HRESULT hr) 197 | { 198 | switch(hr){ 199 | case S_OK: 200 | return lib7zip::LIB7ZIP_NO_ERROR; 201 | case E_NEEDPASSWORD: 202 | return lib7zip::LIB7ZIP_NEED_PASSWORD; 203 | case S_FALSE: 204 | case E_NOTIMPL: 205 | case E_NOINTERFACE: 206 | case E_ABORT: 207 | case E_FAIL: 208 | case STG_E_INVALIDFUNCTION: 209 | case E_OUTOFMEMORY: 210 | case E_INVALIDARG: 211 | default: 212 | return lib7zip::LIB7ZIP_UNKNOWN_ERROR; 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /src/7ZipFormatInfo.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(_OS2) 2 | #include "CPP/myWindows/StdAfx.h" 3 | #include "CPP/include_windows/windows.h" 4 | #endif 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "Common/ComTry.h" 13 | #include "Windows/PropVariant.h" 14 | 15 | #if MY_VER_MAJOR >= 15 16 | #include "CPP/Common/MyBuffer.h" 17 | #else 18 | #include "CPP/Common/Buffer.h" 19 | #endif 20 | 21 | #if MY_VER_MAJOR >= 15 22 | #define NArchiveEnumPrefix NArchive::NHandlerPropID 23 | #else 24 | #define NArchiveEnumPrefix NArchive 25 | #endif 26 | 27 | using namespace NWindows; 28 | 29 | #include "lib7zip.h" 30 | 31 | #include "HelperFuncs.h" 32 | #include "7ZipFunctions.h" 33 | #include "7ZipFormatInfo.h" 34 | 35 | #if MY_VER_MAJOR >= 15 36 | static bool ParseSignatures(const Byte *data, unsigned size, CObjectVector &signatures) 37 | { 38 | signatures.Clear(); 39 | while (size > 0) 40 | { 41 | unsigned len = *data++; 42 | size--; 43 | if (len > size) 44 | return false; 45 | signatures.AddNew().CopyFrom(data, len); 46 | data += len; 47 | size -= len; 48 | } 49 | return true; 50 | } 51 | #endif 52 | 53 | /*------------------------ C7ZipFormatInfo ---------------------*/ 54 | C7ZipFormatInfo::C7ZipFormatInfo() 55 | : m_StartSignature() 56 | , m_FinishSignature() 57 | { 58 | m_Name.clear(); 59 | memset(&m_ClassID,0,sizeof(GUID)); 60 | m_UpdateEnabled = false; 61 | m_KeepName = false; 62 | 63 | #if MY_VER_MAJOR < 15 64 | m_StartSignature.SetCapacity(0); 65 | m_FinishSignature.SetCapacity(0); 66 | #endif 67 | 68 | Exts.clear(); 69 | AddExts.clear(); 70 | } 71 | 72 | C7ZipFormatInfo::~C7ZipFormatInfo() 73 | { 74 | } 75 | 76 | bool LoadFormats(pU7ZipFunctions pFunctions, C7ZipObjectPtrArray & formats) 77 | { 78 | if (pFunctions->v.GetHandlerProperty == NULL && 79 | pFunctions->v.GetHandlerProperty2 == NULL) 80 | { 81 | return false; 82 | } 83 | 84 | UInt32 numFormats = 1; 85 | 86 | if (pFunctions->v.GetNumberOfFormats != NULL) 87 | { 88 | RBOOLOK(pFunctions->v.GetNumberOfFormats(&numFormats)); 89 | } 90 | 91 | if (pFunctions->v.GetHandlerProperty2 == NULL) 92 | numFormats = 1; 93 | 94 | for(UInt32 i = 0; i < numFormats; i++) 95 | { 96 | wstring name; 97 | bool updateEnabled = false; 98 | bool keepName = false; 99 | GUID classID; 100 | wstring ext, addExt; 101 | 102 | if (ReadStringProp(pFunctions->v.GetHandlerProperty, 103 | pFunctions->v.GetHandlerProperty2, i, NArchiveEnumPrefix::kName, name) != S_OK) 104 | continue; 105 | 106 | NWindows::NCOM::CPropVariant prop; 107 | if (ReadProp(pFunctions->v.GetHandlerProperty, pFunctions->v.GetHandlerProperty2, 108 | i, NArchiveEnumPrefix::kClassID, prop) != S_OK) 109 | continue; 110 | if (prop.vt != VT_BSTR) 111 | continue; 112 | 113 | classID = *(const GUID *)prop.bstrVal; 114 | 115 | if (ReadStringProp(pFunctions->v.GetHandlerProperty, pFunctions->v.GetHandlerProperty2, 116 | i, NArchiveEnumPrefix::kExtension, ext) != S_OK) 117 | continue; 118 | 119 | if (ReadStringProp(pFunctions->v.GetHandlerProperty, pFunctions->v.GetHandlerProperty2, 120 | i, NArchiveEnumPrefix::kAddExtension, addExt) != S_OK) 121 | continue; 122 | 123 | ReadBoolProp(pFunctions->v.GetHandlerProperty, pFunctions->v.GetHandlerProperty2, i, 124 | NArchiveEnumPrefix::kUpdate, updateEnabled); 125 | 126 | if (updateEnabled) 127 | { 128 | ReadBoolProp(pFunctions->v.GetHandlerProperty, pFunctions->v.GetHandlerProperty2, 129 | i, NArchiveEnumPrefix::kKeepName, keepName); 130 | } 131 | 132 | C7ZipFormatInfo * pInfo = new C7ZipFormatInfo(); 133 | 134 | #if MY_VER_MAJOR >= 15 135 | if (ReadProp(pFunctions->v.GetHandlerProperty, 136 | pFunctions->v.GetHandlerProperty2, i, NArchiveEnumPrefix::kSignature, prop) == S_OK) { 137 | #else 138 | if (ReadProp(pFunctions->v.GetHandlerProperty, 139 | pFunctions->v.GetHandlerProperty2, i, NArchiveEnumPrefix::kStartSignature, prop) == S_OK) { 140 | #endif 141 | if (prop.vt == VT_BSTR) { 142 | UINT len = ::SysStringByteLen(prop.bstrVal); 143 | #if MY_VER_MAJOR >= 15 144 | pInfo->m_StartSignature.CopyFrom((const Byte *)prop.bstrVal, len); 145 | #else 146 | pInfo->m_StartSignature.SetCapacity(len); 147 | memmove(pInfo->m_StartSignature, prop.bstrVal, len); 148 | #endif 149 | #if MY_VER_MAJOR >= 15 150 | if (len > 0) 151 | pInfo->Signatures.Add(pInfo->m_StartSignature); 152 | #endif 153 | } 154 | } 155 | 156 | #if MY_VER_MAJOR >= 15 157 | if (ReadProp(pFunctions->v.GetHandlerProperty, 158 | pFunctions->v.GetHandlerProperty2, i, NArchiveEnumPrefix::kMultiSignature, prop) == S_OK) { 159 | #else 160 | if (ReadProp(pFunctions->v.GetHandlerProperty, 161 | pFunctions->v.GetHandlerProperty2, i, NArchiveEnumPrefix::kFinishSignature, prop) == S_OK) { 162 | #endif 163 | if (prop.vt == VT_BSTR) { 164 | UINT len = ::SysStringByteLen(prop.bstrVal); 165 | #if MY_VER_MAJOR >= 15 166 | pInfo->m_FinishSignature.CopyFrom((const Byte *)prop.bstrVal, len); 167 | ParseSignatures(pInfo->m_FinishSignature, 168 | (unsigned)pInfo->m_FinishSignature.Size(), 169 | pInfo->Signatures); 170 | #else 171 | pInfo->m_FinishSignature.SetCapacity(len); 172 | memmove(pInfo->m_FinishSignature, prop.bstrVal, len); 173 | #endif 174 | } 175 | } 176 | 177 | #if MY_VER_MAJOR >= 15 178 | if (ReadProp(pFunctions->v.GetHandlerProperty, 179 | pFunctions->v.GetHandlerProperty2, i, 180 | NArchiveEnumPrefix::kSignatureOffset, prop) == S_OK) { 181 | if (prop.vt == VT_UI4) { 182 | pInfo->SignatureOffset = prop.ulVal; 183 | } 184 | else { 185 | pInfo->SignatureOffset = 0; 186 | } 187 | } 188 | else { 189 | pInfo->SignatureOffset = 0; 190 | } 191 | #endif 192 | pInfo->m_Name = name; 193 | pInfo->m_KeepName = keepName; 194 | pInfo->m_ClassID = classID; 195 | pInfo->m_UpdateEnabled = updateEnabled; 196 | 197 | SplitString(ext, pInfo->Exts); 198 | SplitString(addExt, pInfo->AddExts); 199 | 200 | pInfo->FormatIndex = i; 201 | formats.push_back(pInfo); 202 | } 203 | 204 | return true; 205 | } 206 | -------------------------------------------------------------------------------- /test/test7zipprops.cpp: -------------------------------------------------------------------------------- 1 | // Test7Zip.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "lib7zip.h" 6 | #include 7 | 8 | class TestInStream : public C7ZipInStream 9 | { 10 | private: 11 | FILE * m_pFile; 12 | std::string m_strFileName; 13 | wstring m_strFileExt; 14 | int m_nFileSize; 15 | public: 16 | TestInStream(std::string fileName, wstring ext) : 17 | m_strFileName(fileName), 18 | m_strFileExt(ext) 19 | { 20 | 21 | wprintf(L"fileName.c_str(): %s\n", fileName.c_str()); 22 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 23 | 24 | m_pFile = fopen(fileName.c_str(), "rb"); 25 | 26 | if (m_pFile) { 27 | fseek(m_pFile, 0, SEEK_END); 28 | m_nFileSize = ftell(m_pFile); 29 | fseek(m_pFile, 0, SEEK_SET); 30 | } 31 | else { 32 | wprintf(L"fileName.c_str(): %s cant open\n", fileName.c_str()); 33 | } 34 | } 35 | 36 | virtual ~TestInStream() 37 | { 38 | if (m_pFile) 39 | fclose(m_pFile); 40 | } 41 | 42 | public: 43 | virtual wstring GetExt() const 44 | { 45 | wprintf(L"GetExt:%ls\n", m_strFileExt.c_str()); 46 | return m_strFileExt; 47 | } 48 | 49 | virtual int Read(void *data, unsigned int size, unsigned int *processedSize) 50 | { 51 | if (!m_pFile) 52 | return 1; 53 | 54 | int count = fread(data, 1, size, m_pFile); 55 | wprintf(L"Read:%d %d\n", size, count); 56 | 57 | if (count >= 0) { 58 | if (processedSize != NULL) 59 | *processedSize = count; 60 | 61 | return 0; 62 | } 63 | 64 | return 1; 65 | } 66 | 67 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 68 | { 69 | if (!m_pFile) 70 | return 1; 71 | 72 | int result = fseek(m_pFile, (long)offset, seekOrigin); 73 | 74 | if (!result) { 75 | if (newPosition) 76 | *newPosition = ftell(m_pFile); 77 | 78 | return 0; 79 | } 80 | 81 | return result; 82 | } 83 | 84 | virtual int GetSize(unsigned __int64 * size) 85 | { 86 | if (size) 87 | *size = m_nFileSize; 88 | return 0; 89 | } 90 | }; 91 | 92 | const wchar_t * index_names[] = { 93 | L"kpidSize", 94 | L"kpidPackSize", //(Packed Size) 95 | L"kpidAttrib", //(Attributes) 96 | L"kpidCTime", //(Created) 97 | L"kpidATime", //(Accessed) 98 | L"kpidMTime", //(Modified) 99 | L"kpidSolid", //(Solid) 100 | L"kpidEncrypted", //(Encrypted) 101 | L"kpidUser", //(User) 102 | L"kpidGroup", //(Group) 103 | L"kpidComment", //(Comment) 104 | L"kpidPhySize", //(Physical Size) 105 | L"kpidHeadersSize", //(Headers Size) 106 | L"kpidChecksum", //(Checksum) 107 | L"kpidCharacts", //(Characteristics) 108 | L"kpidCreatorApp", //(Creator Application) 109 | L"kpidTotalSize", //(Total Size) 110 | L"kpidFreeSpace", //(Free Space) 111 | L"kpidClusterSize", //(Cluster Size) 112 | L"kpidVolumeName", //(Label) 113 | L"kpidPath", //(FullPath) 114 | L"kpidIsDir", //(IsDir) 115 | }; 116 | 117 | #ifdef _WIN32 118 | int _tmain(int argc, _TCHAR* argv[]) 119 | #else 120 | int main(int argc, char * argv[]) 121 | #endif 122 | { 123 | C7ZipLibrary lib; 124 | 125 | if (!lib.Initialize()) { 126 | wprintf(L"initialize fail!\n"); 127 | return 1; 128 | } 129 | 130 | const char * files[] = { 131 | "Test7ZipProp.tar", 132 | "testzip.zip", 133 | "Test7Zip.7z", 134 | "lib7zip-1.4.0.tar.gz", 135 | "testbzip.bz2", 136 | }; 137 | 138 | const wchar_t * files_ext[] = { 139 | L"tar", 140 | L"zip", 141 | L"7z", 142 | L"gz", 143 | L"bz2", 144 | }; 145 | 146 | C7ZipArchive * pArchive = NULL; 147 | 148 | for (int i=0; i < sizeof(files) / sizeof(const char *); i++) { 149 | TestInStream stream(files[i], files_ext[i]); 150 | 151 | if (lib.OpenArchive(&stream, &pArchive)) { 152 | unsigned int numItems = 0; 153 | 154 | //print archive properties 155 | for(lib7zip::PropertyIndexEnum index = lib7zip::PROP_INDEX_BEGIN; 156 | index < lib7zip::PROP_INDEX_END; 157 | index = (lib7zip::PropertyIndexEnum)(index + 1)) { 158 | wstring strVal = L""; 159 | unsigned __int64 val = 0; 160 | bool bVal = false; 161 | 162 | bool result = pArchive->GetUInt64Property(index, val); 163 | 164 | wprintf(L"\n\nGetArciveProperty:%d %ls\n", (int)index, 165 | index_names[(int)index]); 166 | 167 | wprintf(L"Archive UInt64 result:%ls val=%ld\n", 168 | result ? L"true" : L"false", 169 | val); 170 | 171 | result = pArchive->GetBoolProperty(index, bVal); 172 | 173 | wprintf(L"Archive Bool result:%ls val=%ls\n", 174 | result ? L"true" : L"false", 175 | bVal ? L"true" : L"false"); 176 | 177 | result = pArchive->GetStringProperty(index, strVal); 178 | 179 | wprintf(L"Archive String result:%ls val=%ls\n", 180 | result ? L"true" : L"false", 181 | strVal.c_str()); 182 | 183 | result = pArchive->GetFileTimeProperty(index, val); 184 | 185 | wprintf(L"Archive FileTime result:%ls val=%ld\n", 186 | result ? L"true" : L"false", 187 | val); 188 | } 189 | 190 | pArchive->GetItemCount(&numItems); 191 | 192 | wprintf(L"Contains Items:%d\n", numItems); 193 | 194 | for(unsigned int i = 0;i < numItems;i++) { 195 | C7ZipArchiveItem * pArchiveItem = NULL; 196 | 197 | if (pArchive->GetItemInfo(i, &pArchiveItem)) { 198 | wprintf(L"%d,%ls,%d\n", pArchiveItem->GetArchiveIndex(), 199 | pArchiveItem->GetFullPath().c_str(), 200 | pArchiveItem->IsDir()); 201 | 202 | wprintf(L"get all properties\n"); 203 | for(lib7zip::PropertyIndexEnum index = lib7zip::PROP_INDEX_BEGIN; 204 | index <= lib7zip::PROP_INDEX_END; 205 | index = (lib7zip::PropertyIndexEnum)(index + 1)) { 206 | wstring strVal = L""; 207 | unsigned __int64 val = 0; 208 | bool bVal = false; 209 | 210 | bool result = pArchiveItem->GetUInt64Property(index, val); 211 | 212 | wprintf(L"\n\nGetProperty:%d %ls\n", (int)index, 213 | index_names[(int)index]); 214 | 215 | wprintf(L"UInt64 result:%ls val=%ld\n", 216 | result ? L"true" : L"false", 217 | val); 218 | 219 | result = pArchiveItem->GetBoolProperty(index, bVal); 220 | 221 | wprintf(L"Bool result:%ls val=%ls\n", 222 | result ? L"true" : L"false", 223 | bVal ? L"true" : L"false"); 224 | 225 | result = pArchiveItem->GetStringProperty(index, strVal); 226 | 227 | wprintf(L"String result:%ls val=%ls\n", 228 | result ? L"true" : L"false", 229 | strVal.c_str()); 230 | 231 | result = pArchiveItem->GetFileTimeProperty(index, val); 232 | 233 | wprintf(L"FileTime result:%ls val=%ld\n", 234 | result ? L"true" : L"false", 235 | val); 236 | } 237 | } 238 | } 239 | } 240 | else { 241 | wprintf(L"open archive %s fail\n", files[i]); 242 | } 243 | } 244 | 245 | if (pArchive != NULL) 246 | delete pArchive; 247 | 248 | return 0; 249 | } 250 | -------------------------------------------------------------------------------- /src/lib7zip.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIB_7ZIP_H__ 2 | #define __LIB_7ZIP_H__ 3 | 4 | #define LIB_7ZIP_VER_MAJOR 3 5 | #define LIB_7ZIP_VER_MINOR 0 6 | #define LIB_7ZIP_VER_BUILD 1 7 | #define LIB_7ZIP_VERSION "3.0" 8 | #define LIB_7ZIP_7ZIP_VERSION "lib7Zip 3.0" 9 | #define LIB_7ZIP_DATE "2020-12" 10 | #define LIB_7ZIP_COPYRIGHT "Copyright (c) 2009-2020" 11 | #define LIB_7ZIP_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE 12 | 13 | #include 14 | #include 15 | 16 | #ifndef _WIN32 17 | #ifndef __int64 18 | #define __int64 long long int 19 | #endif 20 | #ifndef CLASS_E_CLASSNOTAVAILABLE 21 | #define CLASS_E_CLASSNOTAVAILABLE (0x80040111L) 22 | #endif 23 | #endif 24 | 25 | #define FILE_BEGIN 0 26 | #define FILE_CURRENT 1 27 | #define FILE_END 2 28 | 29 | #ifndef S_OK 30 | #define S_OK 0 31 | #endif 32 | typedef std::basic_string wstring; 33 | typedef std::basic_string string; 34 | 35 | typedef std::vector WStringArray; 36 | 37 | class C7ZipObject 38 | { 39 | public: 40 | C7ZipObject() {} 41 | virtual ~C7ZipObject() {} 42 | }; 43 | 44 | class C7ZipObjectPtrArray : public std::vector 45 | { 46 | public: 47 | C7ZipObjectPtrArray(bool auto_release = true); 48 | virtual ~C7ZipObjectPtrArray(); 49 | 50 | public: 51 | void clear(); 52 | 53 | private: 54 | bool m_bAutoRelease; 55 | }; 56 | 57 | namespace lib7zip { 58 | enum PropertyIndexEnum { 59 | PROP_INDEX_BEGIN, 60 | 61 | kpidPackSize = PROP_INDEX_BEGIN, //(Packed Size) 62 | kpidAttrib, //(Attributes) 63 | kpidCTime, //(Created) 64 | kpidATime, //(Accessed) 65 | kpidMTime, //(Modified) 66 | kpidSolid, //(Solid) 67 | kpidEncrypted, //(Encrypted) 68 | kpidUser, //(User) 69 | kpidGroup, //(Group) 70 | kpidComment, //(Comment) 71 | kpidPhySize, //(Physical Size) 72 | kpidHeadersSize, //(Headers Size) 73 | kpidChecksum, //(Checksum) 74 | kpidCharacts, //(Characteristics) 75 | kpidCreatorApp, //(Creator Application) 76 | kpidTotalSize, //(Total Size) 77 | kpidFreeSpace, //(Free Space) 78 | kpidClusterSize, //(Cluster Size) 79 | kpidVolumeName, //(Label) 80 | kpidPath, //(FullPath) 81 | kpidIsDir, //(IsDir) 82 | kpidSize, //(Uncompressed Size) 83 | 84 | PROP_INDEX_END 85 | }; 86 | 87 | enum ErrorCodeEnum { 88 | LIB7ZIP_ErrorCode_Begin, 89 | 90 | LIB7ZIP_NO_ERROR = LIB7ZIP_ErrorCode_Begin, 91 | LIB7ZIP_UNKNOWN_ERROR, 92 | LIB7ZIP_NOT_INITIALIZE, 93 | LIB7ZIP_NEED_PASSWORD, 94 | LIB7ZIP_NOT_SUPPORTED_ARCHIVE, 95 | 96 | LIB7ZIP_ErrorCode_End 97 | }; 98 | }; 99 | 100 | class C7ZipArchiveItem : public virtual C7ZipObject 101 | { 102 | public: 103 | C7ZipArchiveItem(); 104 | virtual ~C7ZipArchiveItem(); 105 | 106 | public: 107 | virtual wstring GetFullPath() const = 0; 108 | virtual unsigned __int64 GetSize() const = 0; 109 | virtual bool IsDir() const = 0; 110 | virtual bool IsEncrypted() const = 0; 111 | 112 | virtual unsigned int GetArchiveIndex() const = 0; 113 | 114 | virtual bool GetUInt64Property(lib7zip::PropertyIndexEnum propertyIndex, 115 | unsigned __int64 & val) const = 0; 116 | virtual bool GetBoolProperty(lib7zip::PropertyIndexEnum propertyIndex, 117 | bool & val) const = 0; 118 | virtual bool GetStringProperty(lib7zip::PropertyIndexEnum propertyIndex, 119 | wstring & val) const = 0; 120 | virtual bool GetFileTimeProperty(lib7zip::PropertyIndexEnum propertyIndex, 121 | unsigned __int64 & val) const = 0; 122 | virtual wstring GetArchiveItemPassword() const = 0; 123 | virtual void SetArchiveItemPassword(const wstring & password) = 0; 124 | virtual bool IsPasswordSet() const = 0; 125 | }; 126 | 127 | class C7ZipInStream 128 | { 129 | public: 130 | virtual wstring GetExt() const = 0; 131 | virtual int Read(void *data, unsigned int size, unsigned int *processedSize) = 0; 132 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) = 0; 133 | virtual int GetSize(unsigned __int64 * size) = 0; 134 | }; 135 | 136 | class C7ZipMultiVolumes 137 | { 138 | public: 139 | virtual wstring GetFirstVolumeName() = 0; 140 | virtual bool MoveToVolume(const wstring & volumeName) = 0; 141 | virtual unsigned __int64 GetCurrentVolumeSize() = 0; 142 | virtual C7ZipInStream * OpenCurrentVolumeStream() = 0; 143 | }; 144 | 145 | class C7ZipOutStream 146 | { 147 | public: 148 | virtual int Write(const void *data, unsigned int size, unsigned int *processedSize) = 0; 149 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) = 0; 150 | virtual int SetSize(unsigned __int64 size) = 0; 151 | }; 152 | 153 | class C7ZipArchive : public virtual C7ZipObject 154 | { 155 | public: 156 | C7ZipArchive(); 157 | virtual ~C7ZipArchive(); 158 | 159 | public: 160 | virtual bool GetItemCount(unsigned int * pNumItems) = 0; 161 | virtual bool GetItemInfo(unsigned int index, C7ZipArchiveItem ** ppArchiveItem) = 0; 162 | virtual bool Extract(unsigned int index, C7ZipOutStream * pOutStream) = 0; 163 | virtual bool Extract(unsigned int index, C7ZipOutStream * pOutStream, const wstring & pwd) = 0; 164 | virtual bool Extract(const C7ZipArchiveItem * pArchiveItem, C7ZipOutStream * pOutStream) = 0; 165 | virtual wstring GetArchivePassword() const = 0; 166 | virtual void SetArchivePassword(const wstring & password) = 0; 167 | virtual bool IsPasswordSet() const = 0; 168 | 169 | virtual void Close() = 0; 170 | 171 | virtual bool GetUInt64Property(lib7zip::PropertyIndexEnum propertyIndex, 172 | unsigned __int64 & val) const = 0; 173 | virtual bool GetBoolProperty(lib7zip::PropertyIndexEnum propertyIndex, 174 | bool & val) const = 0; 175 | virtual bool GetStringProperty(lib7zip::PropertyIndexEnum propertyIndex, 176 | wstring & val) const = 0; 177 | virtual bool GetFileTimeProperty(lib7zip::PropertyIndexEnum propertyIndex, 178 | unsigned __int64 & val) const = 0; 179 | }; 180 | 181 | class C7ZipLibrary 182 | { 183 | public: 184 | C7ZipLibrary(); 185 | ~C7ZipLibrary(); 186 | 187 | private: 188 | bool m_bInitialized; 189 | lib7zip::ErrorCodeEnum m_LastError; 190 | 191 | C7ZipObjectPtrArray m_InternalObjectsArray; 192 | 193 | public: 194 | bool Initialize(); 195 | void Deinitialize(); 196 | 197 | bool GetSupportedExts(WStringArray & exts); 198 | 199 | bool OpenArchive(C7ZipInStream * pInStream, 200 | C7ZipArchive ** ppArchive, 201 | bool fDetectFileTypeBySignature = false); 202 | bool OpenArchive(C7ZipInStream * pInStream, 203 | C7ZipArchive ** ppArchive, 204 | const wstring & pwd, 205 | bool fDetectFileTypeBySignature = false); 206 | bool OpenMultiVolumeArchive(C7ZipMultiVolumes * pVolumes, 207 | C7ZipArchive ** ppArchive, 208 | bool fDetectFileTypeBySignature = false); 209 | bool OpenMultiVolumeArchive(C7ZipMultiVolumes * pVolumes, 210 | C7ZipArchive ** ppArchive, 211 | const wstring & pwd, 212 | bool fDetectFileTypeBySignature = false); 213 | 214 | lib7zip::ErrorCodeEnum GetLastError() const { return m_LastError; } 215 | 216 | const C7ZipObjectPtrArray & GetInternalObjectsArray() { return m_InternalObjectsArray; } 217 | 218 | bool IsInitialized() const { return m_bInitialized; } 219 | }; 220 | 221 | //set locale used by lib7zip, if NULL or not set, lib7zip will use user default locale 222 | const char * GetLib7ZipLocale(); 223 | const char * SetLib7ZipLocale(const char * loc); 224 | 225 | #endif 226 | -------------------------------------------------------------------------------- /test/test_archive.cpp: -------------------------------------------------------------------------------- 1 | // Test7Zip.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "lib7zip.h" 6 | #include 7 | 8 | class TestInStream : public C7ZipInStream 9 | { 10 | private: 11 | FILE * m_pFile; 12 | std::string m_strFileName; 13 | wstring m_strFileExt; 14 | int m_nFileSize; 15 | public: 16 | TestInStream(std::string fileName) : 17 | m_strFileName(fileName), 18 | m_strFileExt(L"zip") 19 | { 20 | 21 | wprintf(L"fileName.c_str(): %s\n", fileName.c_str()); 22 | m_pFile = fopen(fileName.c_str(), "rb"); 23 | if (m_pFile) { 24 | fseek(m_pFile, 0, SEEK_END); 25 | m_nFileSize = ftell(m_pFile); 26 | fseek(m_pFile, 0, SEEK_SET); 27 | 28 | auto pos = m_strFileName.find_last_of("."); 29 | 30 | if (pos != m_strFileName.npos) { 31 | #ifdef _WIN32 32 | std::string tmp = m_strFileName.substr(pos + 1); 33 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 34 | LPWSTR lpszW = new WCHAR[nLen]; 35 | MultiByteToWideChar(CP_ACP, 0, 36 | tmp.c_str(), -1, lpszW, nLen); 37 | m_strFileExt = lpszW; 38 | // free the string 39 | delete[] lpszW; 40 | #else 41 | m_strFileExt = L"zip"; 42 | #endif 43 | } 44 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 45 | } 46 | else { 47 | wprintf(L"fileName.c_str(): %s cant open\n", fileName.c_str()); 48 | } 49 | } 50 | 51 | virtual ~TestInStream() 52 | { 53 | fclose(m_pFile); 54 | } 55 | 56 | public: 57 | virtual wstring GetExt() const 58 | { 59 | wprintf(L"GetExt:%ls\n", m_strFileExt.c_str()); 60 | return m_strFileExt; 61 | } 62 | 63 | virtual int Read(void *data, unsigned int size, unsigned int *processedSize) 64 | { 65 | if (!m_pFile) 66 | return 1; 67 | 68 | int count = fread(data, 1, size, m_pFile); 69 | wprintf(L"Read:%d %d\n", size, count); 70 | 71 | if (count >= 0) { 72 | if (processedSize != NULL) 73 | *processedSize = count; 74 | 75 | return 0; 76 | } 77 | 78 | return 1; 79 | } 80 | 81 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 82 | { 83 | if (!m_pFile) 84 | return 1; 85 | 86 | int result = fseek(m_pFile, (long)offset, seekOrigin); 87 | 88 | if (!result) { 89 | if (newPosition) 90 | *newPosition = ftell(m_pFile); 91 | 92 | return 0; 93 | } 94 | 95 | return result; 96 | } 97 | 98 | virtual int GetSize(unsigned __int64 * size) 99 | { 100 | if (size) 101 | *size = m_nFileSize; 102 | return 0; 103 | } 104 | }; 105 | 106 | class TestOutStream : public C7ZipOutStream 107 | { 108 | private: 109 | FILE * m_pFile; 110 | std::string m_strFileName; 111 | wstring m_strFileExt; 112 | int m_nFileSize; 113 | public: 114 | TestOutStream(std::string fileName) : 115 | m_strFileName(fileName), 116 | m_strFileExt(L"zip") 117 | { 118 | m_pFile = fopen(fileName.c_str(), "wb"); 119 | m_nFileSize = 0; 120 | 121 | auto pos = m_strFileName.find_last_of("."); 122 | 123 | if (pos != m_strFileName.npos) 124 | { 125 | #ifdef _WIN32 126 | std::string tmp = m_strFileName.substr(pos + 1); 127 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 128 | LPWSTR lpszW = new WCHAR[nLen]; 129 | MultiByteToWideChar(CP_ACP, 0, 130 | tmp.c_str(), -1, lpszW, nLen); 131 | m_strFileExt = lpszW; 132 | // free the string 133 | delete[] lpszW; 134 | #else 135 | m_strFileExt = L"zip"; 136 | #endif 137 | } 138 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 139 | } 140 | 141 | virtual ~TestOutStream() 142 | { 143 | fclose(m_pFile); 144 | } 145 | 146 | public: 147 | int GetFileSize() const 148 | { 149 | return m_nFileSize; 150 | } 151 | 152 | virtual int Write(const void *data, unsigned int size, unsigned int *processedSize) 153 | { 154 | int count = fwrite(data, 1, size, m_pFile); 155 | wprintf(L"Write:%d %d\n", size, count); 156 | 157 | if (count >= 0) 158 | { 159 | if (processedSize != NULL) 160 | *processedSize = count; 161 | 162 | m_nFileSize += count; 163 | return 0; 164 | } 165 | 166 | return 1; 167 | } 168 | 169 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 170 | { 171 | int result = fseek(m_pFile, (long)offset, seekOrigin); 172 | 173 | if (!result) 174 | { 175 | if (newPosition) 176 | *newPosition = ftell(m_pFile); 177 | 178 | return 0; 179 | } 180 | 181 | return result; 182 | } 183 | 184 | virtual int SetSize(unsigned __int64 size) 185 | { 186 | wprintf(L"SetFileSize:%ld\n", size); 187 | return 0; 188 | } 189 | }; 190 | 191 | const wchar_t * index_names[] = { 192 | L"kpidPackSize", //(Packed Size) 193 | L"kpidAttrib", //(Attributes) 194 | L"kpidCTime", //(Created) 195 | L"kpidATime", //(Accessed) 196 | L"kpidMTime", //(Modified) 197 | L"kpidSolid", //(Solid) 198 | L"kpidEncrypted", //(Encrypted) 199 | L"kpidUser", //(User) 200 | L"kpidGroup", //(Group) 201 | L"kpidComment", //(Comment) 202 | L"kpidPhySize", //(Physical Size) 203 | L"kpidHeadersSize", //(Headers Size) 204 | L"kpidChecksum", //(Checksum) 205 | L"kpidCharacts", //(Characteristics) 206 | L"kpidCreatorApp", //(Creator Application) 207 | L"kpidTotalSize", //(Total Size) 208 | L"kpidFreeSpace", //(Free Space) 209 | L"kpidClusterSize", //(Cluster Size) 210 | L"kpidVolumeName", //(Label) 211 | L"kpidPath", //(FullPath) 212 | L"kpidIsDir", //(IsDir) 213 | }; 214 | 215 | #ifdef _WIN32 216 | int _tmain(int argc, _TCHAR* argv[]) 217 | #else 218 | int main(int argc, char * argv[]) 219 | #endif 220 | { 221 | if (argc < 2) { 222 | wprintf(L"Usage: test_archive [archive name]\n"); 223 | return 1; 224 | } 225 | 226 | C7ZipLibrary lib; 227 | 228 | if (!lib.Initialize()) { 229 | wprintf(L"initialize fail!\n"); 230 | return 1; 231 | } 232 | 233 | WStringArray exts; 234 | 235 | if (!lib.GetSupportedExts(exts)) { 236 | wprintf(L"get supported exts fail\n"); 237 | return 1; 238 | } 239 | 240 | size_t size = exts.size(); 241 | 242 | for(size_t i = 0; i < size; i++) { 243 | wstring ext = exts[i]; 244 | 245 | for(size_t j = 0; j < ext.size(); j++) { 246 | wprintf(L"%c", (char)(ext[j] &0xFF)); 247 | } 248 | 249 | wprintf(L"\n"); 250 | } 251 | 252 | C7ZipArchive * pArchive = NULL; 253 | 254 | TestInStream stream(argv[1]); 255 | TestOutStream oStream("TestResult.txt"); 256 | if (lib.OpenArchive(&stream, &pArchive, true)) { 257 | unsigned int numItems = 0; 258 | 259 | pArchive->GetItemCount(&numItems); 260 | 261 | wprintf(L"%d\n", numItems); 262 | 263 | for(unsigned int i = 0;i < numItems;i++) { 264 | C7ZipArchiveItem * pArchiveItem = NULL; 265 | 266 | if (pArchive->GetItemInfo(i, &pArchiveItem)) { 267 | wprintf(L"%d,%ls,%d\n", pArchiveItem->GetArchiveIndex(), 268 | pArchiveItem->GetFullPath().c_str(), 269 | pArchiveItem->IsDir()); 270 | 271 | wprintf(L"get all properties\n"); 272 | for(lib7zip::PropertyIndexEnum index = lib7zip::kpidPackSize; 273 | index <= lib7zip::kpidIsDir; 274 | index = (lib7zip::PropertyIndexEnum)(index + 1)) { 275 | wstring strVal = L""; 276 | unsigned __int64 val = 0; 277 | bool bVal = false; 278 | 279 | bool result = pArchiveItem->GetUInt64Property(index, val); 280 | 281 | wprintf(L"\n\nGetProperty:%d %ls\n", (int)index, 282 | index_names[(int)index]); 283 | 284 | wprintf(L"UInt64 result:%ls val=%ld\n", 285 | result ? L"true" : L"false", 286 | val); 287 | 288 | result = pArchiveItem->GetBoolProperty(index, bVal); 289 | 290 | wprintf(L"Bool result:%ls val=%ls\n", 291 | result ? L"true" : L"false", 292 | bVal ? L"true" : L"false"); 293 | 294 | result = pArchiveItem->GetStringProperty(index, strVal); 295 | 296 | wprintf(L"String result:%ls val=%ls\n", 297 | result ? L"true" : L"false", 298 | strVal.c_str()); 299 | 300 | result = pArchiveItem->GetFileTimeProperty(index, val); 301 | 302 | wprintf(L"FileTime result:%ls val=%ld\n", 303 | result ? L"true" : L"false", 304 | val); 305 | } 306 | 307 | pArchive->Extract(pArchiveItem, &oStream); 308 | } //if 309 | }//for 310 | } 311 | else { 312 | wprintf(L"open archive %s fail\n", argv[1]); 313 | } 314 | 315 | if (pArchive != NULL) 316 | delete pArchive; 317 | 318 | return 0; 319 | } 320 | -------------------------------------------------------------------------------- /test/Test7Zip.cpp: -------------------------------------------------------------------------------- 1 | // Test7Zip.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "lib7zip.h" 6 | #include 7 | 8 | class TestInStream : public C7ZipInStream 9 | { 10 | private: 11 | FILE * m_pFile; 12 | std::string m_strFileName; 13 | wstring m_strFileExt; 14 | int m_nFileSize; 15 | public: 16 | TestInStream(std::string fileName) : 17 | m_strFileName(fileName), 18 | m_strFileExt(L"7z") 19 | { 20 | 21 | wprintf(L"fileName.c_str(): %s\n", fileName.c_str()); 22 | m_pFile = fopen(fileName.c_str(), "rb"); 23 | if (m_pFile) { 24 | fseek(m_pFile, 0, SEEK_END); 25 | m_nFileSize = ftell(m_pFile); 26 | fseek(m_pFile, 0, SEEK_SET); 27 | 28 | auto pos = m_strFileName.find_last_of("."); 29 | 30 | if (pos != m_strFileName.npos) { 31 | #ifdef _WIN32 32 | std::string tmp = m_strFileName.substr(pos + 1); 33 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 34 | LPWSTR lpszW = new WCHAR[nLen]; 35 | MultiByteToWideChar(CP_ACP, 0, 36 | tmp.c_str(), -1, lpszW, nLen); 37 | m_strFileExt = lpszW; 38 | // free the string 39 | delete[] lpszW; 40 | #else 41 | m_strFileExt = L"7z"; 42 | #endif 43 | } 44 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 45 | } 46 | else { 47 | wprintf(L"fileName.c_str(): %s cant open\n", fileName.c_str()); 48 | } 49 | } 50 | 51 | virtual ~TestInStream() 52 | { 53 | fclose(m_pFile); 54 | } 55 | 56 | public: 57 | virtual wstring GetExt() const 58 | { 59 | wprintf(L"GetExt:%ls\n", m_strFileExt.c_str()); 60 | return m_strFileExt; 61 | } 62 | 63 | virtual int Read(void *data, unsigned int size, unsigned int *processedSize) 64 | { 65 | if (!m_pFile) 66 | return 1; 67 | 68 | int count = fread(data, 1, size, m_pFile); 69 | wprintf(L"Read:%d %d\n", size, count); 70 | 71 | if (count >= 0) { 72 | if (processedSize != NULL) 73 | *processedSize = count; 74 | 75 | return 0; 76 | } 77 | 78 | return 1; 79 | } 80 | 81 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 82 | { 83 | if (!m_pFile) 84 | return 1; 85 | 86 | int result = fseek(m_pFile, (long)offset, seekOrigin); 87 | 88 | if (!result) { 89 | if (newPosition) 90 | *newPosition = ftell(m_pFile); 91 | 92 | return 0; 93 | } 94 | 95 | return result; 96 | } 97 | 98 | virtual int GetSize(unsigned __int64 * size) 99 | { 100 | if (size) 101 | *size = m_nFileSize; 102 | return 0; 103 | } 104 | }; 105 | 106 | class TestOutStream : public C7ZipOutStream 107 | { 108 | private: 109 | FILE * m_pFile; 110 | std::string m_strFileName; 111 | wstring m_strFileExt; 112 | int m_nFileSize; 113 | public: 114 | TestOutStream(std::string fileName) : 115 | m_strFileName(fileName), 116 | m_strFileExt(L"7z") 117 | { 118 | m_pFile = fopen(fileName.c_str(), "wb"); 119 | m_nFileSize = 0; 120 | 121 | auto pos = m_strFileName.find_last_of("."); 122 | 123 | if (pos != m_strFileName.npos) 124 | { 125 | #ifdef _WIN32 126 | std::string tmp = m_strFileName.substr(pos + 1); 127 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 128 | LPWSTR lpszW = new WCHAR[nLen]; 129 | MultiByteToWideChar(CP_ACP, 0, 130 | tmp.c_str(), -1, lpszW, nLen); 131 | m_strFileExt = lpszW; 132 | // free the string 133 | delete[] lpszW; 134 | #else 135 | m_strFileExt = L"7z"; 136 | #endif 137 | } 138 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 139 | } 140 | 141 | virtual ~TestOutStream() 142 | { 143 | fclose(m_pFile); 144 | } 145 | 146 | public: 147 | int GetFileSize() const 148 | { 149 | return m_nFileSize; 150 | } 151 | 152 | virtual int Write(const void *data, unsigned int size, unsigned int *processedSize) 153 | { 154 | int count = fwrite(data, 1, size, m_pFile); 155 | wprintf(L"Write:%d %d\n", size, count); 156 | 157 | if (count >= 0) 158 | { 159 | if (processedSize != NULL) 160 | *processedSize = count; 161 | 162 | m_nFileSize += count; 163 | return 0; 164 | } 165 | 166 | return 1; 167 | } 168 | 169 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 170 | { 171 | int result = fseek(m_pFile, (long)offset, seekOrigin); 172 | 173 | if (!result) 174 | { 175 | if (newPosition) 176 | *newPosition = ftell(m_pFile); 177 | 178 | return 0; 179 | } 180 | 181 | return result; 182 | } 183 | 184 | virtual int SetSize(unsigned __int64 size) 185 | { 186 | wprintf(L"SetFileSize:%ld\n", size); 187 | return 0; 188 | } 189 | }; 190 | 191 | const wchar_t * index_names[] = { 192 | L"kpidPackSize", //(Packed Size) 193 | L"kpidAttrib", //(Attributes) 194 | L"kpidCTime", //(Created) 195 | L"kpidATime", //(Accessed) 196 | L"kpidMTime", //(Modified) 197 | L"kpidSolid", //(Solid) 198 | L"kpidEncrypted", //(Encrypted) 199 | L"kpidUser", //(User) 200 | L"kpidGroup", //(Group) 201 | L"kpidComment", //(Comment) 202 | L"kpidPhySize", //(Physical Size) 203 | L"kpidHeadersSize", //(Headers Size) 204 | L"kpidChecksum", //(Checksum) 205 | L"kpidCharacts", //(Characteristics) 206 | L"kpidCreatorApp", //(Creator Application) 207 | L"kpidTotalSize", //(Total Size) 208 | L"kpidFreeSpace", //(Free Space) 209 | L"kpidClusterSize", //(Cluster Size) 210 | L"kpidVolumeName", //(Label) 211 | L"kpidPath", //(FullPath) 212 | L"kpidIsDir", //(IsDir) 213 | }; 214 | 215 | #ifdef _WIN32 216 | int _tmain(int argc, _TCHAR* argv[]) 217 | #else 218 | int main(int argc, char * argv[]) 219 | #endif 220 | { 221 | C7ZipLibrary lib; 222 | 223 | if (!lib.Initialize()) { 224 | wprintf(L"initialize fail!\n"); 225 | return 1; 226 | } 227 | 228 | WStringArray exts; 229 | 230 | if (!lib.GetSupportedExts(exts)) { 231 | wprintf(L"get supported exts fail\n"); 232 | return 1; 233 | } 234 | 235 | size_t size = exts.size(); 236 | 237 | for(size_t i = 0; i < size; i++) { 238 | wstring ext = exts[i]; 239 | 240 | for(size_t j = 0; j < ext.size(); j++) { 241 | wprintf(L"%c", (char)(ext[j] &0xFF)); 242 | } 243 | 244 | wprintf(L"\n"); 245 | } 246 | 247 | C7ZipArchive * pArchive = NULL; 248 | 249 | TestInStream stream("Test7Zip.7z"); 250 | TestOutStream oStream("TestResult.txt"); 251 | if (lib.OpenArchive(&stream, &pArchive)) { 252 | unsigned int numItems = 0; 253 | 254 | pArchive->GetItemCount(&numItems); 255 | 256 | wprintf(L"%d\n", numItems); 257 | 258 | for(unsigned int i = 0;i < numItems;i++) { 259 | C7ZipArchiveItem * pArchiveItem = NULL; 260 | 261 | if (pArchive->GetItemInfo(i, &pArchiveItem)) { 262 | wprintf(L"%d,%ls,%d\n", pArchiveItem->GetArchiveIndex(), 263 | pArchiveItem->GetFullPath().c_str(), 264 | pArchiveItem->IsDir()); 265 | 266 | wprintf(L"get all properties\n"); 267 | for(lib7zip::PropertyIndexEnum index = lib7zip::kpidPackSize; 268 | index <= lib7zip::kpidIsDir; 269 | index = (lib7zip::PropertyIndexEnum)(index + 1)) { 270 | wstring strVal = L""; 271 | unsigned __int64 val = 0; 272 | bool bVal = false; 273 | 274 | bool result = pArchiveItem->GetUInt64Property(index, val); 275 | 276 | wprintf(L"\n\nGetProperty:%d %ls\n", (int)index, 277 | index_names[(int)index]); 278 | 279 | wprintf(L"UInt64 result:%ls val=%ld\n", 280 | result ? L"true" : L"false", 281 | val); 282 | 283 | result = pArchiveItem->GetBoolProperty(index, bVal); 284 | 285 | wprintf(L"Bool result:%ls val=%ls\n", 286 | result ? L"true" : L"false", 287 | bVal ? L"true" : L"false"); 288 | 289 | result = pArchiveItem->GetStringProperty(index, strVal); 290 | 291 | wprintf(L"String result:%ls val=%ls\n", 292 | result ? L"true" : L"false", 293 | strVal.c_str()); 294 | 295 | result = pArchiveItem->GetFileTimeProperty(index, val); 296 | 297 | wprintf(L"FileTime result:%ls val=%ld\n", 298 | result ? L"true" : L"false", 299 | val); 300 | } 301 | 302 | //set archive password or item password 303 | pArchive->SetArchivePassword(L"test"); 304 | if (i==0) { 305 | //Or set password for each archive item 306 | //pArchiveItem->SetArchiveItemPassword(L"test"); 307 | pArchive->Extract(pArchiveItem, &oStream); 308 | } 309 | } //if 310 | }//for 311 | } 312 | else { 313 | wprintf(L"open archive Test7Zip.7z fail\n"); 314 | } 315 | 316 | if (pArchive != NULL) 317 | delete pArchive; 318 | 319 | return 0; 320 | } 321 | -------------------------------------------------------------------------------- /test/Test7ZipRar5.cpp: -------------------------------------------------------------------------------- 1 | // Test7Zip.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "lib7zip.h" 6 | #include 7 | 8 | class TestInStream : public C7ZipInStream 9 | { 10 | private: 11 | FILE * m_pFile; 12 | std::string m_strFileName; 13 | wstring m_strFileExt; 14 | int m_nFileSize; 15 | public: 16 | TestInStream(std::string fileName) : 17 | m_strFileName(fileName), 18 | m_strFileExt(L"rar") 19 | { 20 | 21 | wprintf(L"fileName.c_str(): %s\n", fileName.c_str()); 22 | m_pFile = fopen(fileName.c_str(), "rb"); 23 | if (m_pFile) { 24 | fseek(m_pFile, 0, SEEK_END); 25 | m_nFileSize = ftell(m_pFile); 26 | fseek(m_pFile, 0, SEEK_SET); 27 | 28 | auto pos = m_strFileName.find_last_of("."); 29 | 30 | if (pos != m_strFileName.npos) { 31 | #ifdef _WIN32 32 | std::string tmp = m_strFileName.substr(pos + 1); 33 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 34 | LPWSTR lpszW = new WCHAR[nLen]; 35 | MultiByteToWideChar(CP_ACP, 0, 36 | tmp.c_str(), -1, lpszW, nLen); 37 | m_strFileExt = lpszW; 38 | // free the string 39 | delete[] lpszW; 40 | #else 41 | m_strFileExt = L"rar"; 42 | #endif 43 | } 44 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 45 | } 46 | else { 47 | wprintf(L"fileName.c_str(): %s cant open\n", fileName.c_str()); 48 | } 49 | } 50 | 51 | virtual ~TestInStream() 52 | { 53 | fclose(m_pFile); 54 | } 55 | 56 | public: 57 | virtual wstring GetExt() const 58 | { 59 | wprintf(L"GetExt:%ls\n", m_strFileExt.c_str()); 60 | return m_strFileExt; 61 | } 62 | 63 | virtual int Read(void *data, unsigned int size, unsigned int *processedSize) 64 | { 65 | if (!m_pFile) 66 | return 1; 67 | 68 | int count = fread(data, 1, size, m_pFile); 69 | wprintf(L"Read:%d %d\n", size, count); 70 | 71 | if (count >= 0) { 72 | if (processedSize != NULL) 73 | *processedSize = count; 74 | 75 | return 0; 76 | } 77 | 78 | return 1; 79 | } 80 | 81 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 82 | { 83 | if (!m_pFile) 84 | return 1; 85 | 86 | int result = fseek(m_pFile, (long)offset, seekOrigin); 87 | 88 | if (!result) { 89 | if (newPosition) 90 | *newPosition = ftell(m_pFile); 91 | 92 | return 0; 93 | } 94 | 95 | return result; 96 | } 97 | 98 | virtual int GetSize(unsigned __int64 * size) 99 | { 100 | if (size) 101 | *size = m_nFileSize; 102 | return 0; 103 | } 104 | }; 105 | 106 | class TestOutStream : public C7ZipOutStream 107 | { 108 | private: 109 | FILE * m_pFile; 110 | std::string m_strFileName; 111 | wstring m_strFileExt; 112 | int m_nFileSize; 113 | public: 114 | TestOutStream(std::string fileName) : 115 | m_strFileName(fileName), 116 | m_strFileExt(L"rar") 117 | { 118 | m_pFile = fopen(fileName.c_str(), "wb"); 119 | m_nFileSize = 0; 120 | 121 | auto pos = m_strFileName.find_last_of("."); 122 | 123 | if (pos != m_strFileName.npos) 124 | { 125 | #ifdef _WIN32 126 | std::string tmp = m_strFileName.substr(pos + 1); 127 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 128 | LPWSTR lpszW = new WCHAR[nLen]; 129 | MultiByteToWideChar(CP_ACP, 0, 130 | tmp.c_str(), -1, lpszW, nLen); 131 | m_strFileExt = lpszW; 132 | // free the string 133 | delete[] lpszW; 134 | #else 135 | m_strFileExt = L"rar"; 136 | #endif 137 | } 138 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 139 | } 140 | 141 | virtual ~TestOutStream() 142 | { 143 | fclose(m_pFile); 144 | } 145 | 146 | public: 147 | int GetFileSize() const 148 | { 149 | return m_nFileSize; 150 | } 151 | 152 | virtual int Write(const void *data, unsigned int size, unsigned int *processedSize) 153 | { 154 | int count = fwrite(data, 1, size, m_pFile); 155 | wprintf(L"Write:%d %d\n", size, count); 156 | 157 | if (count >= 0) 158 | { 159 | if (processedSize != NULL) 160 | *processedSize = count; 161 | 162 | m_nFileSize += count; 163 | return 0; 164 | } 165 | 166 | return 1; 167 | } 168 | 169 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 170 | { 171 | int result = fseek(m_pFile, (long)offset, seekOrigin); 172 | 173 | if (!result) 174 | { 175 | if (newPosition) 176 | *newPosition = ftell(m_pFile); 177 | 178 | return 0; 179 | } 180 | 181 | return result; 182 | } 183 | 184 | virtual int SetSize(unsigned __int64 size) 185 | { 186 | wprintf(L"SetFileSize:%ld\n", size); 187 | return 0; 188 | } 189 | }; 190 | 191 | const wchar_t * index_names[] = { 192 | L"kpidPackSize", //(Packed Size) 193 | L"kpidAttrib", //(Attributes) 194 | L"kpidCTime", //(Created) 195 | L"kpidATime", //(Accessed) 196 | L"kpidMTime", //(Modified) 197 | L"kpidSolid", //(Solid) 198 | L"kpidEncrypted", //(Encrypted) 199 | L"kpidUser", //(User) 200 | L"kpidGroup", //(Group) 201 | L"kpidComment", //(Comment) 202 | L"kpidPhySize", //(Physical Size) 203 | L"kpidHeadersSize", //(Headers Size) 204 | L"kpidChecksum", //(Checksum) 205 | L"kpidCharacts", //(Characteristics) 206 | L"kpidCreatorApp", //(Creator Application) 207 | L"kpidTotalSize", //(Total Size) 208 | L"kpidFreeSpace", //(Free Space) 209 | L"kpidClusterSize", //(Cluster Size) 210 | L"kpidVolumeName", //(Label) 211 | L"kpidPath", //(FullPath) 212 | L"kpidIsDir", //(IsDir) 213 | }; 214 | 215 | #ifdef _WIN32 216 | int _tmain(int argc, _TCHAR* argv[]) 217 | #else 218 | int main(int argc, char * argv[]) 219 | #endif 220 | { 221 | C7ZipLibrary lib; 222 | 223 | if (!lib.Initialize()) { 224 | wprintf(L"initialize fail!\n"); 225 | return 1; 226 | } 227 | 228 | WStringArray exts; 229 | 230 | if (!lib.GetSupportedExts(exts)) { 231 | wprintf(L"get supported exts fail\n"); 232 | return 1; 233 | } 234 | 235 | size_t size = exts.size(); 236 | 237 | for(size_t i = 0; i < size; i++) { 238 | wstring ext = exts[i]; 239 | 240 | for(size_t j = 0; j < ext.size(); j++) { 241 | wprintf(L"%c", (char)(ext[j] &0xFF)); 242 | } 243 | 244 | wprintf(L"\n"); 245 | } 246 | 247 | C7ZipArchive * pArchive = NULL; 248 | 249 | TestInStream stream("TestRar5.rar"); 250 | TestOutStream oStream("TestResult.txt"); 251 | if (lib.OpenArchive(&stream, &pArchive, true)) { 252 | unsigned int numItems = 0; 253 | 254 | pArchive->GetItemCount(&numItems); 255 | 256 | wprintf(L"%d\n", numItems); 257 | 258 | for(unsigned int i = 0;i < numItems;i++) { 259 | C7ZipArchiveItem * pArchiveItem = NULL; 260 | 261 | if (pArchive->GetItemInfo(i, &pArchiveItem)) { 262 | wprintf(L"%d,%ls,%d\n", pArchiveItem->GetArchiveIndex(), 263 | pArchiveItem->GetFullPath().c_str(), 264 | pArchiveItem->IsDir()); 265 | 266 | wprintf(L"get all properties\n"); 267 | for(lib7zip::PropertyIndexEnum index = lib7zip::kpidPackSize; 268 | index <= lib7zip::kpidIsDir; 269 | index = (lib7zip::PropertyIndexEnum)(index + 1)) { 270 | wstring strVal = L""; 271 | unsigned __int64 val = 0; 272 | bool bVal = false; 273 | 274 | bool result = pArchiveItem->GetUInt64Property(index, val); 275 | 276 | wprintf(L"\n\nGetProperty:%d %ls\n", (int)index, 277 | index_names[(int)index]); 278 | 279 | wprintf(L"UInt64 result:%ls val=%ld\n", 280 | result ? L"true" : L"false", 281 | val); 282 | 283 | result = pArchiveItem->GetBoolProperty(index, bVal); 284 | 285 | wprintf(L"Bool result:%ls val=%ls\n", 286 | result ? L"true" : L"false", 287 | bVal ? L"true" : L"false"); 288 | 289 | result = pArchiveItem->GetStringProperty(index, strVal); 290 | 291 | wprintf(L"String result:%ls val=%ls\n", 292 | result ? L"true" : L"false", 293 | strVal.c_str()); 294 | 295 | result = pArchiveItem->GetFileTimeProperty(index, val); 296 | 297 | wprintf(L"FileTime result:%ls val=%ld\n", 298 | result ? L"true" : L"false", 299 | val); 300 | } 301 | 302 | //set archive password or item password 303 | pArchive->SetArchivePassword(L"test"); 304 | if (i==0) { 305 | //Or set password for each archive item 306 | //pArchiveItem->SetArchiveItemPassword(L"test"); 307 | pArchive->Extract(pArchiveItem, &oStream); 308 | } 309 | } //if 310 | }//for 311 | } 312 | else { 313 | wprintf(L"open archive Test7Rar5.rar fail\n"); 314 | } 315 | 316 | if (pArchive != NULL) 317 | delete pArchive; 318 | 319 | return 0; 320 | } 321 | -------------------------------------------------------------------------------- /test/Test7Zip2.cpp: -------------------------------------------------------------------------------- 1 | // Test7Zip.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "lib7zip.h" 6 | #include 7 | 8 | class TestInStream : public C7ZipInStream 9 | { 10 | private: 11 | FILE * m_pFile; 12 | std::string m_strFileName; 13 | wstring m_strFileExt; 14 | int m_nFileSize; 15 | public: 16 | TestInStream(std::string fileName) : 17 | m_strFileName(fileName), 18 | m_strFileExt(L"zip") 19 | { 20 | 21 | wprintf(L"fileName.c_str(): %s\n", fileName.c_str()); 22 | m_pFile = fopen(fileName.c_str(), "rb"); 23 | if (m_pFile) { 24 | fseek(m_pFile, 0, SEEK_END); 25 | m_nFileSize = ftell(m_pFile); 26 | fseek(m_pFile, 0, SEEK_SET); 27 | 28 | auto pos = m_strFileName.find_last_of("."); 29 | 30 | if (pos != m_strFileName.npos) { 31 | #ifdef _WIN32 32 | std::string tmp = m_strFileName.substr(pos + 1); 33 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 34 | LPWSTR lpszW = new WCHAR[nLen]; 35 | MultiByteToWideChar(CP_ACP, 0, 36 | tmp.c_str(), -1, lpszW, nLen); 37 | m_strFileExt = lpszW; 38 | // free the string 39 | delete[] lpszW; 40 | #else 41 | m_strFileExt = L"zip"; 42 | #endif 43 | } 44 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 45 | } 46 | else { 47 | wprintf(L"fileName.c_str(): %s cant open\n", fileName.c_str()); 48 | } 49 | } 50 | 51 | virtual ~TestInStream() 52 | { 53 | fclose(m_pFile); 54 | } 55 | 56 | public: 57 | virtual wstring GetExt() const 58 | { 59 | wprintf(L"GetExt:%ls\n", m_strFileExt.c_str()); 60 | return m_strFileExt; 61 | } 62 | 63 | virtual int Read(void *data, unsigned int size, unsigned int *processedSize) 64 | { 65 | if (!m_pFile) 66 | return 1; 67 | 68 | int count = fread(data, 1, size, m_pFile); 69 | wprintf(L"Read:%d %d\n", size, count); 70 | 71 | if (count >= 0) { 72 | if (processedSize != NULL) 73 | *processedSize = count; 74 | 75 | return 0; 76 | } 77 | 78 | return 1; 79 | } 80 | 81 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 82 | { 83 | if (!m_pFile) 84 | return 1; 85 | 86 | int result = fseek(m_pFile, (long)offset, seekOrigin); 87 | 88 | if (!result) { 89 | if (newPosition) 90 | *newPosition = ftell(m_pFile); 91 | 92 | return 0; 93 | } 94 | 95 | return result; 96 | } 97 | 98 | virtual int GetSize(unsigned __int64 * size) 99 | { 100 | if (size) 101 | *size = m_nFileSize; 102 | return 0; 103 | } 104 | }; 105 | 106 | class TestOutStream : public C7ZipOutStream 107 | { 108 | private: 109 | FILE * m_pFile; 110 | std::string m_strFileName; 111 | wstring m_strFileExt; 112 | int m_nFileSize; 113 | public: 114 | TestOutStream(std::string fileName) : 115 | m_strFileName(fileName), 116 | m_strFileExt(L"zip") 117 | { 118 | m_pFile = fopen(fileName.c_str(), "wb"); 119 | m_nFileSize = 0; 120 | 121 | auto pos = m_strFileName.find_last_of("."); 122 | 123 | if (pos != m_strFileName.npos) 124 | { 125 | #ifdef _WIN32 126 | std::string tmp = m_strFileName.substr(pos + 1); 127 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 128 | LPWSTR lpszW = new WCHAR[nLen]; 129 | MultiByteToWideChar(CP_ACP, 0, 130 | tmp.c_str(), -1, lpszW, nLen); 131 | m_strFileExt = lpszW; 132 | // free the string 133 | delete[] lpszW; 134 | #else 135 | m_strFileExt = L"zip"; 136 | #endif 137 | } 138 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 139 | } 140 | 141 | virtual ~TestOutStream() 142 | { 143 | fclose(m_pFile); 144 | } 145 | 146 | public: 147 | int GetFileSize() const 148 | { 149 | return m_nFileSize; 150 | } 151 | 152 | virtual int Write(const void *data, unsigned int size, unsigned int *processedSize) 153 | { 154 | int count = fwrite(data, 1, size, m_pFile); 155 | wprintf(L"Write:%d %d\n", size, count); 156 | 157 | if (count >= 0) 158 | { 159 | if (processedSize != NULL) 160 | *processedSize = count; 161 | 162 | m_nFileSize += count; 163 | return 0; 164 | } 165 | 166 | return 1; 167 | } 168 | 169 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 170 | { 171 | int result = fseek(m_pFile, (long)offset, seekOrigin); 172 | 173 | if (!result) 174 | { 175 | if (newPosition) 176 | *newPosition = ftell(m_pFile); 177 | 178 | return 0; 179 | } 180 | 181 | return result; 182 | } 183 | 184 | virtual int SetSize(unsigned __int64 size) 185 | { 186 | wprintf(L"SetFileSize:%ld\n", size); 187 | return 0; 188 | } 189 | }; 190 | 191 | const wchar_t * index_names[] = { 192 | L"kpidPackSize", //(Packed Size) 193 | L"kpidAttrib", //(Attributes) 194 | L"kpidCTime", //(Created) 195 | L"kpidATime", //(Accessed) 196 | L"kpidMTime", //(Modified) 197 | L"kpidSolid", //(Solid) 198 | L"kpidEncrypted", //(Encrypted) 199 | L"kpidUser", //(User) 200 | L"kpidGroup", //(Group) 201 | L"kpidComment", //(Comment) 202 | L"kpidPhySize", //(Physical Size) 203 | L"kpidHeadersSize", //(Headers Size) 204 | L"kpidChecksum", //(Checksum) 205 | L"kpidCharacts", //(Characteristics) 206 | L"kpidCreatorApp", //(Creator Application) 207 | L"kpidTotalSize", //(Total Size) 208 | L"kpidFreeSpace", //(Free Space) 209 | L"kpidClusterSize", //(Cluster Size) 210 | L"kpidVolumeName", //(Label) 211 | L"kpidPath", //(FullPath) 212 | L"kpidIsDir", //(IsDir) 213 | }; 214 | 215 | #ifdef _WIN32 216 | int _tmain(int argc, _TCHAR* argv[]) 217 | #else 218 | int main(int argc, char * argv[]) 219 | #endif 220 | { 221 | C7ZipLibrary lib; 222 | 223 | if (!lib.Initialize()) { 224 | wprintf(L"initialize fail!\n"); 225 | return 1; 226 | } 227 | 228 | WStringArray exts; 229 | 230 | if (!lib.GetSupportedExts(exts)) { 231 | wprintf(L"get supported exts fail\n"); 232 | return 1; 233 | } 234 | 235 | size_t size = exts.size(); 236 | 237 | for(size_t i = 0; i < size; i++) { 238 | wstring ext = exts[i]; 239 | 240 | for(size_t j = 0; j < ext.size(); j++) { 241 | wprintf(L"%c", (char)(ext[j] &0xFF)); 242 | } 243 | 244 | wprintf(L"\n"); 245 | } 246 | 247 | C7ZipArchive * pArchive = NULL; 248 | 249 | TestInStream stream("Test7Zip.zip"); 250 | TestOutStream oStream("TestResult.txt"); 251 | if (lib.OpenArchive(&stream, &pArchive, true)) { 252 | unsigned int numItems = 0; 253 | 254 | pArchive->GetItemCount(&numItems); 255 | 256 | wprintf(L"%d\n", numItems); 257 | 258 | for(unsigned int i = 0;i < numItems;i++) { 259 | C7ZipArchiveItem * pArchiveItem = NULL; 260 | 261 | if (pArchive->GetItemInfo(i, &pArchiveItem)) { 262 | wprintf(L"%d,%ls,%d\n", pArchiveItem->GetArchiveIndex(), 263 | pArchiveItem->GetFullPath().c_str(), 264 | pArchiveItem->IsDir()); 265 | 266 | wprintf(L"get all properties\n"); 267 | for(lib7zip::PropertyIndexEnum index = lib7zip::kpidPackSize; 268 | index <= lib7zip::kpidIsDir; 269 | index = (lib7zip::PropertyIndexEnum)(index + 1)) { 270 | wstring strVal = L""; 271 | unsigned __int64 val = 0; 272 | bool bVal = false; 273 | 274 | bool result = pArchiveItem->GetUInt64Property(index, val); 275 | 276 | wprintf(L"\n\nGetProperty:%d %ls\n", (int)index, 277 | index_names[(int)index]); 278 | 279 | wprintf(L"UInt64 result:%ls val=%ld\n", 280 | result ? L"true" : L"false", 281 | val); 282 | 283 | result = pArchiveItem->GetBoolProperty(index, bVal); 284 | 285 | wprintf(L"Bool result:%ls val=%ls\n", 286 | result ? L"true" : L"false", 287 | bVal ? L"true" : L"false"); 288 | 289 | result = pArchiveItem->GetStringProperty(index, strVal); 290 | 291 | wprintf(L"String result:%ls val=%ls\n", 292 | result ? L"true" : L"false", 293 | strVal.c_str()); 294 | 295 | result = pArchiveItem->GetFileTimeProperty(index, val); 296 | 297 | wprintf(L"FileTime result:%ls val=%ld\n", 298 | result ? L"true" : L"false", 299 | val); 300 | } 301 | 302 | //set archive password or item password 303 | pArchive->SetArchivePassword(L"test"); 304 | if (i==0) { 305 | //Or set password for each archive item 306 | //pArchiveItem->SetArchiveItemPassword(L"test"); 307 | pArchive->Extract(pArchiveItem, &oStream); 308 | } 309 | } //if 310 | }//for 311 | } 312 | else { 313 | wprintf(L"open archive Test7Zip.zip fail\n"); 314 | } 315 | 316 | if (pArchive != NULL) 317 | delete pArchive; 318 | 319 | return 0; 320 | } 321 | -------------------------------------------------------------------------------- /test/Test7ZipSignature.cpp: -------------------------------------------------------------------------------- 1 | // Test7Zip.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "lib7zip.h" 6 | #include 7 | 8 | class TestInStream : public C7ZipInStream 9 | { 10 | private: 11 | FILE * m_pFile; 12 | std::string m_strFileName; 13 | wstring m_strFileExt; 14 | int m_nFileSize; 15 | public: 16 | TestInStream(std::string fileName) : 17 | m_strFileName(fileName), 18 | m_strFileExt(L"7z") 19 | { 20 | 21 | wprintf(L"fileName.c_str(): %s\n", fileName.c_str()); 22 | m_pFile = fopen(fileName.c_str(), "rb"); 23 | if (m_pFile) { 24 | fseek(m_pFile, 0, SEEK_END); 25 | m_nFileSize = ftell(m_pFile); 26 | fseek(m_pFile, 0, SEEK_SET); 27 | 28 | auto pos = m_strFileName.find_last_of("."); 29 | 30 | if (pos != m_strFileName.npos) { 31 | #ifdef _WIN32 32 | std::string tmp = m_strFileName.substr(pos + 1); 33 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 34 | LPWSTR lpszW = new WCHAR[nLen]; 35 | MultiByteToWideChar(CP_ACP, 0, 36 | tmp.c_str(), -1, lpszW, nLen); 37 | m_strFileExt = lpszW; 38 | // free the string 39 | delete[] lpszW; 40 | #else 41 | m_strFileExt = L"7z"; 42 | #endif 43 | } 44 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 45 | } 46 | else { 47 | wprintf(L"fileName.c_str(): %s cant open\n", fileName.c_str()); 48 | } 49 | } 50 | 51 | virtual ~TestInStream() 52 | { 53 | fclose(m_pFile); 54 | } 55 | 56 | public: 57 | virtual wstring GetExt() const 58 | { 59 | wprintf(L"GetExt:%ls, but return 001, try to test signature match\n", m_strFileExt.c_str()); 60 | return L"001"; 61 | } 62 | 63 | virtual int Read(void *data, unsigned int size, unsigned int *processedSize) 64 | { 65 | if (!m_pFile) 66 | return 1; 67 | 68 | int count = fread(data, 1, size, m_pFile); 69 | wprintf(L"Read:%d %d\n", size, count); 70 | 71 | if (count >= 0) { 72 | if (processedSize != NULL) 73 | *processedSize = count; 74 | 75 | return 0; 76 | } 77 | 78 | return 1; 79 | } 80 | 81 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 82 | { 83 | if (!m_pFile) 84 | return 1; 85 | 86 | int result = fseek(m_pFile, (long)offset, seekOrigin); 87 | 88 | if (!result) { 89 | if (newPosition) 90 | *newPosition = ftell(m_pFile); 91 | 92 | return 0; 93 | } 94 | 95 | return result; 96 | } 97 | 98 | virtual int GetSize(unsigned __int64 * size) 99 | { 100 | if (size) 101 | *size = m_nFileSize; 102 | return 0; 103 | } 104 | }; 105 | 106 | class TestOutStream : public C7ZipOutStream 107 | { 108 | private: 109 | FILE * m_pFile; 110 | std::string m_strFileName; 111 | wstring m_strFileExt; 112 | int m_nFileSize; 113 | public: 114 | TestOutStream(std::string fileName) : 115 | m_strFileName(fileName), 116 | m_strFileExt(L"7z") 117 | { 118 | m_pFile = fopen(fileName.c_str(), "wb"); 119 | m_nFileSize = 0; 120 | 121 | auto pos = m_strFileName.find_last_of("."); 122 | 123 | if (pos != m_strFileName.npos) 124 | { 125 | #ifdef _WIN32 126 | std::string tmp = m_strFileName.substr(pos + 1); 127 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 128 | LPWSTR lpszW = new WCHAR[nLen]; 129 | MultiByteToWideChar(CP_ACP, 0, 130 | tmp.c_str(), -1, lpszW, nLen); 131 | m_strFileExt = lpszW; 132 | // free the string 133 | delete[] lpszW; 134 | #else 135 | m_strFileExt = L"7z"; 136 | #endif 137 | } 138 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 139 | } 140 | 141 | virtual ~TestOutStream() 142 | { 143 | fclose(m_pFile); 144 | } 145 | 146 | public: 147 | int GetFileSize() const 148 | { 149 | return m_nFileSize; 150 | } 151 | 152 | virtual int Write(const void *data, unsigned int size, unsigned int *processedSize) 153 | { 154 | int count = fwrite(data, 1, size, m_pFile); 155 | wprintf(L"Write:%d %d\n", size, count); 156 | 157 | if (count >= 0) 158 | { 159 | if (processedSize != NULL) 160 | *processedSize = count; 161 | 162 | m_nFileSize += count; 163 | return 0; 164 | } 165 | 166 | return 1; 167 | } 168 | 169 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 170 | { 171 | int result = fseek(m_pFile, (long)offset, seekOrigin); 172 | 173 | if (!result) 174 | { 175 | if (newPosition) 176 | *newPosition = ftell(m_pFile); 177 | 178 | return 0; 179 | } 180 | 181 | return result; 182 | } 183 | 184 | virtual int SetSize(unsigned __int64 size) 185 | { 186 | wprintf(L"SetFileSize:%ld\n", size); 187 | return 0; 188 | } 189 | }; 190 | 191 | const wchar_t * index_names[] = { 192 | L"kpidPackSize", //(Packed Size) 193 | L"kpidAttrib", //(Attributes) 194 | L"kpidCTime", //(Created) 195 | L"kpidATime", //(Accessed) 196 | L"kpidMTime", //(Modified) 197 | L"kpidSolid", //(Solid) 198 | L"kpidEncrypted", //(Encrypted) 199 | L"kpidUser", //(User) 200 | L"kpidGroup", //(Group) 201 | L"kpidComment", //(Comment) 202 | L"kpidPhySize", //(Physical Size) 203 | L"kpidHeadersSize", //(Headers Size) 204 | L"kpidChecksum", //(Checksum) 205 | L"kpidCharacts", //(Characteristics) 206 | L"kpidCreatorApp", //(Creator Application) 207 | L"kpidTotalSize", //(Total Size) 208 | L"kpidFreeSpace", //(Free Space) 209 | L"kpidClusterSize", //(Cluster Size) 210 | L"kpidVolumeName", //(Label) 211 | L"kpidPath", //(FullPath) 212 | L"kpidIsDir", //(IsDir) 213 | }; 214 | 215 | #ifdef _WIN32 216 | int _tmain(int argc, _TCHAR* argv[]) 217 | #else 218 | int main(int argc, char * argv[]) 219 | #endif 220 | { 221 | C7ZipLibrary lib; 222 | 223 | if (!lib.Initialize()) { 224 | wprintf(L"initialize fail!\n"); 225 | return 1; 226 | } 227 | 228 | WStringArray exts; 229 | 230 | if (!lib.GetSupportedExts(exts)) { 231 | wprintf(L"get supported exts fail\n"); 232 | return 1; 233 | } 234 | 235 | size_t size = exts.size(); 236 | 237 | for(size_t i = 0; i < size; i++) { 238 | wstring ext = exts[i]; 239 | 240 | for(size_t j = 0; j < ext.size(); j++) { 241 | wprintf(L"%c", (char)(ext[j] &0xFF)); 242 | } 243 | 244 | wprintf(L"\n"); 245 | } 246 | 247 | C7ZipArchive * pArchive = NULL; 248 | 249 | TestInStream stream("Test7Zip.7z"); 250 | TestOutStream oStream("TestResult.txt"); 251 | if (lib.OpenArchive(&stream, &pArchive, true)) { 252 | unsigned int numItems = 0; 253 | 254 | pArchive->GetItemCount(&numItems); 255 | 256 | wprintf(L"%d\n", numItems); 257 | 258 | for(unsigned int i = 0;i < numItems;i++) { 259 | C7ZipArchiveItem * pArchiveItem = NULL; 260 | 261 | if (pArchive->GetItemInfo(i, &pArchiveItem)) { 262 | wprintf(L"%d,%ls,%d\n", pArchiveItem->GetArchiveIndex(), 263 | pArchiveItem->GetFullPath().c_str(), 264 | pArchiveItem->IsDir()); 265 | 266 | wprintf(L"get all properties\n"); 267 | for(lib7zip::PropertyIndexEnum index = lib7zip::kpidPackSize; 268 | index <= lib7zip::kpidIsDir; 269 | index = (lib7zip::PropertyIndexEnum)(index + 1)) { 270 | wstring strVal = L""; 271 | unsigned __int64 val = 0; 272 | bool bVal = false; 273 | 274 | bool result = pArchiveItem->GetUInt64Property(index, val); 275 | 276 | wprintf(L"\n\nGetProperty:%d %ls\n", (int)index, 277 | index_names[(int)index]); 278 | 279 | wprintf(L"UInt64 result:%ls val=%ld\n", 280 | result ? L"true" : L"false", 281 | val); 282 | 283 | result = pArchiveItem->GetBoolProperty(index, bVal); 284 | 285 | wprintf(L"Bool result:%ls val=%ls\n", 286 | result ? L"true" : L"false", 287 | bVal ? L"true" : L"false"); 288 | 289 | result = pArchiveItem->GetStringProperty(index, strVal); 290 | 291 | wprintf(L"String result:%ls val=%ls\n", 292 | result ? L"true" : L"false", 293 | strVal.c_str()); 294 | 295 | result = pArchiveItem->GetFileTimeProperty(index, val); 296 | 297 | wprintf(L"FileTime result:%ls val=%ld\n", 298 | result ? L"true" : L"false", 299 | val); 300 | } 301 | 302 | //set archive password or item password 303 | pArchive->SetArchivePassword(L"test"); 304 | if (i==0) { 305 | //Or set password for each archive item 306 | //pArchiveItem->SetArchiveItemPassword(L"test"); 307 | pArchive->Extract(pArchiveItem, &oStream); 308 | } 309 | } //if 310 | }//for 311 | } 312 | else { 313 | wprintf(L"open archive Test7Zip.7z fail\n"); 314 | } 315 | 316 | if (pArchive != NULL) 317 | delete pArchive; 318 | 319 | return 0; 320 | } 321 | -------------------------------------------------------------------------------- /test/Test7ZipMulti.cpp: -------------------------------------------------------------------------------- 1 | // Test7Zip.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "lib7zip.h" 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | wstring widen( const string& str ) 14 | { 15 | std::wostringstream wstm ; 16 | wstm.imbue(std::locale("en_US.utf8")); 17 | const std::ctype& ctfacet = 18 | std::use_facet< std::ctype >( wstm.getloc() ) ; 19 | for( size_t i=0 ; i& ctfacet = 29 | std::use_facet< std::ctype >( stm.getloc() ) ; 30 | for( size_t i=0 ; i= 0) 79 | { 80 | if (processedSize != NULL) 81 | *processedSize = count; 82 | 83 | return 0; 84 | } 85 | 86 | return 1; 87 | } 88 | 89 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 90 | { 91 | wprintf(L"Seek\n"); 92 | int result = fseek(m_pFile, (long)offset, seekOrigin); 93 | wprintf(L"Seek:%ld %ld\n", offset, result); 94 | if (!result) 95 | { 96 | if (newPosition) 97 | *newPosition = ftell(m_pFile); 98 | 99 | return 0; 100 | } 101 | 102 | return result; 103 | } 104 | 105 | virtual int GetSize(unsigned __int64 * size) 106 | { 107 | wprintf(L"Size\n"); 108 | if (size) 109 | *size = m_nFileSize; 110 | return 0; 111 | } 112 | }; 113 | 114 | class TestMultiVolumes : public C7ZipMultiVolumes 115 | { 116 | private: 117 | FILE * m_pFile; 118 | wstring m_strFileName; 119 | int m_nFileSize; 120 | wstring m_strCurVolume; 121 | bool m_done; 122 | 123 | public: 124 | TestMultiVolumes(wstring fileName) : 125 | m_pFile(NULL), 126 | m_strFileName(fileName), 127 | m_done(false) 128 | { 129 | } 130 | 131 | virtual ~TestMultiVolumes() 132 | { 133 | if (m_pFile) 134 | fclose(m_pFile); 135 | } 136 | 137 | public: 138 | virtual wstring GetFirstVolumeName() { 139 | m_strCurVolume = m_strFileName; 140 | MoveToVolume(m_strCurVolume); 141 | return m_strCurVolume; 142 | } 143 | 144 | virtual bool MoveToVolume(const wstring& volumeName) { 145 | m_strCurVolume = volumeName; 146 | wprintf(L"move to volume:%ls\n", volumeName.c_str()); 147 | 148 | if (m_pFile) 149 | fclose(m_pFile); 150 | m_pFile = NULL; 151 | string f = narrow(volumeName); 152 | wprintf(L"narrow volume:%s\n", f.c_str()); 153 | 154 | m_pFile = fopen(f.c_str(), "rb"); 155 | 156 | if (!m_pFile) 157 | m_done = true; 158 | else { 159 | fseek(m_pFile, 0, SEEK_END); 160 | m_nFileSize = ftell(m_pFile); 161 | fseek(m_pFile, 0, SEEK_SET); 162 | } 163 | 164 | return !m_done; 165 | } 166 | 167 | virtual C7ZipInStream * OpenCurrentVolumeStream() { 168 | return new TestInStream(m_strCurVolume); 169 | } 170 | 171 | virtual unsigned __int64 GetCurrentVolumeSize() { 172 | wprintf(L"get current volume size:%ls\n", m_strCurVolume.c_str()); 173 | return m_nFileSize; 174 | } 175 | }; 176 | 177 | class TestOutStream : public C7ZipOutStream 178 | { 179 | private: 180 | FILE * m_pFile; 181 | std::string m_strFileName; 182 | wstring m_strFileExt; 183 | int m_nFileSize; 184 | public: 185 | TestOutStream(std::string fileName) : 186 | m_strFileName(fileName), 187 | m_strFileExt(L"7z") 188 | { 189 | m_pFile = fopen(fileName.c_str(), "wb"); 190 | m_nFileSize = 0; 191 | 192 | auto pos = m_strFileName.find_last_of("."); 193 | 194 | if (pos != m_strFileName.npos) 195 | { 196 | #ifdef _WIN32 197 | std::string tmp = m_strFileName.substr(pos + 1); 198 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 199 | LPWSTR lpszW = new WCHAR[nLen]; 200 | MultiByteToWideChar(CP_ACP, 0, 201 | tmp.c_str(), -1, lpszW, nLen); 202 | m_strFileExt = lpszW; 203 | // free the string 204 | delete[] lpszW; 205 | #else 206 | m_strFileExt = L"7z"; 207 | #endif 208 | } 209 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 210 | } 211 | 212 | virtual ~TestOutStream() 213 | { 214 | fclose(m_pFile); 215 | } 216 | 217 | public: 218 | int GetFileSize() const 219 | { 220 | return m_nFileSize; 221 | } 222 | 223 | virtual int Write(const void *data, unsigned int size, unsigned int *processedSize) 224 | { 225 | int count = fwrite(data, 1, size, m_pFile); 226 | wprintf(L"Write:%d %d\n", size, count); 227 | 228 | if (count >= 0) 229 | { 230 | if (processedSize != NULL) 231 | *processedSize = count; 232 | 233 | m_nFileSize += count; 234 | return 0; 235 | } 236 | 237 | return 1; 238 | } 239 | 240 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 241 | { 242 | int result = fseek(m_pFile, (long)offset, seekOrigin); 243 | 244 | if (!result) 245 | { 246 | if (newPosition) 247 | *newPosition = ftell(m_pFile); 248 | 249 | return 0; 250 | } 251 | 252 | return result; 253 | } 254 | 255 | virtual int SetSize(unsigned __int64 size) 256 | { 257 | wprintf(L"SetFileSize:%ld\n", size); 258 | return 0; 259 | } 260 | }; 261 | 262 | #ifdef _WIN32 263 | int _tmain(int argc, _TCHAR* argv[]) 264 | #else 265 | int main(int argc, char * argv[]) 266 | #endif 267 | { 268 | C7ZipLibrary lib; 269 | 270 | if (!lib.Initialize()) 271 | { 272 | wprintf(L"initialize fail!\n"); 273 | return 1; 274 | } 275 | 276 | WStringArray exts; 277 | 278 | if (!lib.GetSupportedExts(exts)) 279 | { 280 | wprintf(L"get supported exts fail\n"); 281 | return 1; 282 | } 283 | 284 | size_t size = exts.size(); 285 | 286 | for(size_t i = 0; i < size; i++) 287 | { 288 | wstring ext = exts[i]; 289 | 290 | for(size_t j = 0; j < ext.size(); j++) 291 | { 292 | wprintf(L"%c", (char)(ext[j] &0xFF)); 293 | } 294 | 295 | wprintf(L"\n"); 296 | } 297 | 298 | C7ZipArchive * pArchive = NULL; 299 | 300 | TestMultiVolumes volumes(L"test.7z.001"); 301 | TestOutStream oStream("TestMultiResult.txt"); 302 | if (lib.OpenMultiVolumeArchive(&volumes, &pArchive)) 303 | { 304 | unsigned int numItems = 0; 305 | 306 | pArchive->GetItemCount(&numItems); 307 | 308 | wprintf(L"%d\n", numItems); 309 | 310 | for(unsigned int i = 0;i < numItems;i++) 311 | { 312 | C7ZipArchiveItem * pArchiveItem = NULL; 313 | 314 | if (pArchive->GetItemInfo(i, &pArchiveItem)) 315 | { 316 | wprintf(L"%d,%ls,%d\n", pArchiveItem->GetArchiveIndex(), 317 | pArchiveItem->GetFullPath().c_str(), 318 | pArchiveItem->IsDir()); 319 | } 320 | //set archive password or item password 321 | pArchive->SetArchivePassword(L"test"); 322 | if (i==0) { 323 | //Or set password for each archive item 324 | //pArchiveItem->SetArchiveItemPassword(L"test"); 325 | pArchive->Extract(pArchiveItem, &oStream); 326 | } 327 | } 328 | } 329 | else 330 | { 331 | wprintf(L"open archive test.7z.001 fail\n"); 332 | } 333 | 334 | if (pArchive != NULL) 335 | delete pArchive; 336 | 337 | return 0; 338 | } 339 | -------------------------------------------------------------------------------- /src/7ZipArchiveItem.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(_OS2) 2 | #include "CPP/myWindows/StdAfx.h" 3 | #include "CPP/include_windows/windows.h" 4 | #endif 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "CPP/7zip/Common/FileStreams.h" 13 | 14 | #include "lib7zip.h" 15 | #include "HelperFuncs.h" 16 | 17 | const wchar_t *kEmptyFileAlias = L"[Content]"; 18 | 19 | class C7ZipArchiveItemImpl : public virtual C7ZipArchiveItem 20 | { 21 | public: 22 | C7ZipArchiveItemImpl(IInArchive * pInArchive, 23 | unsigned int nIndex); 24 | virtual ~C7ZipArchiveItemImpl(); 25 | 26 | public: 27 | virtual wstring GetFullPath() const; 28 | virtual UInt64 GetSize() const; 29 | virtual bool IsDir() const; 30 | virtual bool IsEncrypted() const; 31 | virtual unsigned int GetArchiveIndex() const; 32 | virtual wstring GetArchiveItemPassword() const; 33 | virtual void SetArchiveItemPassword(const wstring & password); 34 | bool IsPasswordSet() const; 35 | 36 | virtual bool GetUInt64Property(lib7zip::PropertyIndexEnum propertyIndex, 37 | unsigned __int64 & val) const; 38 | virtual bool GetBoolProperty(lib7zip::PropertyIndexEnum propertyIndex, 39 | bool & val) const; 40 | virtual bool GetStringProperty(lib7zip::PropertyIndexEnum propertyIndex, 41 | wstring & val) const; 42 | virtual bool GetFileTimeProperty(lib7zip::PropertyIndexEnum propertyIndex, 43 | unsigned __int64 & val) const; 44 | private: 45 | CMyComPtr m_pInArchive; 46 | unsigned int m_nIndex; 47 | wstring m_Password; 48 | }; 49 | 50 | C7ZipArchiveItemImpl::C7ZipArchiveItemImpl(IInArchive * pInArchive, 51 | unsigned int nIndex) : 52 | m_pInArchive(pInArchive), 53 | m_nIndex(nIndex) 54 | { 55 | } 56 | 57 | C7ZipArchiveItemImpl::~C7ZipArchiveItemImpl() 58 | { 59 | } 60 | 61 | wstring C7ZipArchiveItemImpl::GetFullPath() const 62 | { 63 | // Get Name 64 | NWindows::NCOM::CPropVariant prop; 65 | wstring fullPath = kEmptyFileAlias; 66 | 67 | if (!m_pInArchive->GetProperty(m_nIndex, kpidPath, &prop)) { 68 | if (prop.vt == VT_BSTR) 69 | fullPath = prop.bstrVal; 70 | } 71 | 72 | return fullPath; 73 | } 74 | 75 | UInt64 C7ZipArchiveItemImpl::GetSize() const 76 | { 77 | // Get uncompressed size 78 | NWindows::NCOM::CPropVariant prop; 79 | if (m_pInArchive->GetProperty(m_nIndex, kpidSize, &prop) != 0) 80 | return 0; 81 | 82 | UInt64 size = 0; 83 | 84 | if (prop.vt == VT_UI8 || prop.vt == VT_UI4) 85 | size = ConvertPropVariantToUInt64(prop); 86 | 87 | return size; 88 | } 89 | 90 | bool C7ZipArchiveItemImpl::IsEncrypted() const 91 | { 92 | // Check if encrypted (password protected) 93 | NWindows::NCOM::CPropVariant prop; 94 | bool isEncrypted = false; 95 | if (m_pInArchive->GetProperty(m_nIndex, kpidEncrypted, &prop) == 0 && prop.vt == VT_BOOL) 96 | isEncrypted = prop.bVal; 97 | return isEncrypted; 98 | } 99 | 100 | bool C7ZipArchiveItemImpl::IsDir() const 101 | { 102 | // Check IsDir 103 | NWindows::NCOM::CPropVariant prop; 104 | bool isDir = false; 105 | IsArchiveItemFolder(m_pInArchive, m_nIndex, isDir); 106 | 107 | return isDir; 108 | } 109 | 110 | unsigned int C7ZipArchiveItemImpl::GetArchiveIndex() const 111 | { 112 | return m_nIndex; 113 | } 114 | 115 | wstring C7ZipArchiveItemImpl::GetArchiveItemPassword() const 116 | { 117 | return m_Password; 118 | } 119 | 120 | void C7ZipArchiveItemImpl::SetArchiveItemPassword(const wstring & password) 121 | { 122 | m_Password = password; 123 | } 124 | 125 | bool C7ZipArchiveItemImpl::IsPasswordSet() const 126 | { 127 | return !(m_Password == L""); 128 | } 129 | 130 | 131 | bool C7ZipArchiveItemImpl::GetUInt64Property(lib7zip::PropertyIndexEnum propertyIndex, 132 | unsigned __int64 & val) const 133 | { 134 | int p7zip_index = 0; 135 | 136 | switch(propertyIndex) { 137 | case lib7zip::kpidSize: 138 | p7zip_index = kpidSize; 139 | break; 140 | case lib7zip::kpidPackSize: //(Packed Size) 141 | p7zip_index = kpidPackSize; 142 | break; 143 | case lib7zip::kpidAttrib: //(Attributes) 144 | p7zip_index = kpidAttrib; 145 | break; 146 | case lib7zip::kpidPhySize: //(Physical Size) 147 | p7zip_index = kpidPhySize; 148 | break; 149 | case lib7zip::kpidHeadersSize: //(Headers Size) 150 | p7zip_index = kpidHeadersSize; 151 | break; 152 | case lib7zip::kpidChecksum: //(Checksum) 153 | p7zip_index = kpidChecksum; 154 | break; 155 | case lib7zip::kpidTotalSize: //(Total Size) 156 | p7zip_index = kpidTotalSize; 157 | break; 158 | case lib7zip::kpidFreeSpace: //(Free Space) 159 | p7zip_index = kpidFreeSpace; 160 | break; 161 | case lib7zip::kpidClusterSize: //(Cluster Size) 162 | p7zip_index = kpidClusterSize; 163 | break; 164 | default: 165 | return false; 166 | } 167 | 168 | NWindows::NCOM::CPropVariant prop; 169 | 170 | if (m_pInArchive->GetProperty(m_nIndex, p7zip_index, &prop) != 0) 171 | return false; 172 | 173 | if (prop.vt == VT_UI8 || prop.vt == VT_UI4) { 174 | val = ConvertPropVariantToUInt64(prop); 175 | return true; 176 | } 177 | 178 | return false; 179 | } 180 | 181 | bool C7ZipArchiveItemImpl::GetBoolProperty(lib7zip::PropertyIndexEnum propertyIndex, 182 | bool & val) const 183 | { 184 | int p7zip_index = 0; 185 | 186 | switch(propertyIndex) { 187 | case lib7zip::kpidSolid: //(Solid) 188 | p7zip_index = kpidSolid; 189 | break; 190 | case lib7zip::kpidEncrypted: //(Encrypted) 191 | p7zip_index = kpidEncrypted; 192 | break; 193 | case lib7zip::kpidIsDir: //(IsDir) 194 | return IsArchiveItemFolder(m_pInArchive, m_nIndex, val) == S_OK; 195 | default: 196 | return false; 197 | } 198 | 199 | NWindows::NCOM::CPropVariant prop; 200 | 201 | if (m_pInArchive->GetProperty(m_nIndex, p7zip_index, &prop) == 0 && 202 | prop.vt == VT_BOOL) { 203 | val = prop.bVal; 204 | return true; 205 | } 206 | 207 | return false; 208 | } 209 | 210 | bool C7ZipArchiveItemImpl::GetStringProperty(lib7zip::PropertyIndexEnum propertyIndex, 211 | wstring & val) const 212 | { 213 | int p7zip_index = 0; 214 | 215 | switch(propertyIndex) { 216 | case lib7zip::kpidComment: //(Comment) 217 | p7zip_index = kpidComment; 218 | break; 219 | case lib7zip::kpidCharacts: //(Characteristics) 220 | p7zip_index = kpidCharacts; 221 | break; 222 | case lib7zip::kpidCreatorApp: //(Creator Application) 223 | p7zip_index = kpidCreatorApp; 224 | break; 225 | case lib7zip::kpidVolumeName: //(Label) 226 | p7zip_index = kpidVolumeName; 227 | break; 228 | case lib7zip::kpidPath: //(FullPath) 229 | p7zip_index = kpidPath; 230 | break; 231 | case lib7zip::kpidUser: //(User) 232 | p7zip_index = kpidUser; 233 | break; 234 | case lib7zip::kpidGroup: //(Group) 235 | p7zip_index = kpidGroup; 236 | break; 237 | default: 238 | return false; 239 | } 240 | 241 | NWindows::NCOM::CPropVariant prop; 242 | 243 | if (!m_pInArchive->GetProperty(m_nIndex, p7zip_index, &prop) && 244 | prop.vt == VT_BSTR) { 245 | val = prop.bstrVal; 246 | return true; 247 | } 248 | 249 | return false; 250 | } 251 | 252 | bool C7ZipArchiveItemImpl::GetFileTimeProperty(lib7zip::PropertyIndexEnum propertyIndex, 253 | unsigned __int64 & val) const 254 | { 255 | int p7zip_index = 0; 256 | 257 | switch(propertyIndex) { 258 | case lib7zip::kpidCTime: //(Created) 259 | p7zip_index = kpidCTime; 260 | break; 261 | case lib7zip::kpidATime: //(Accessed) 262 | p7zip_index = kpidATime; 263 | break; 264 | case lib7zip::kpidMTime: //(Modified) 265 | p7zip_index = kpidMTime; 266 | break; 267 | default: 268 | return false; 269 | } 270 | 271 | NWindows::NCOM::CPropVariant prop; 272 | 273 | if (m_pInArchive->GetProperty(m_nIndex, p7zip_index, &prop) != 0) 274 | return false; 275 | 276 | if (prop.vt == VT_FILETIME) { 277 | unsigned __int64 tmp_val = 0; 278 | memmove(&tmp_val, &prop.filetime, sizeof(unsigned __int64)); 279 | val = tmp_val; 280 | return true; 281 | } 282 | 283 | return false; 284 | } 285 | 286 | bool Create7ZipArchiveItem(C7ZipArchive * pArchive, 287 | IInArchive * pInArchive, 288 | unsigned int nIndex, 289 | C7ZipArchiveItem ** ppItem) 290 | { 291 | *ppItem = new C7ZipArchiveItemImpl(pInArchive, nIndex); 292 | 293 | return true; 294 | } 295 | 296 | /*-------------------- C7ZipArchiveItem ----------------------*/ 297 | C7ZipArchiveItem::C7ZipArchiveItem() 298 | { 299 | } 300 | 301 | C7ZipArchiveItem::~C7ZipArchiveItem() 302 | { 303 | } 304 | -------------------------------------------------------------------------------- /test/Test7ZipDmg.cpp: -------------------------------------------------------------------------------- 1 | // Test7Zip.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "lib7zip.h" 6 | #include 7 | 8 | class TestInStream : public C7ZipInStream 9 | { 10 | private: 11 | FILE * m_pFile; 12 | std::string m_strFileName; 13 | wstring m_strFileExt; 14 | int m_nFileSize; 15 | public: 16 | TestInStream(std::string fileName) : 17 | m_strFileName(fileName), 18 | m_strFileExt(L"7z") 19 | { 20 | 21 | wprintf(L"fileName.c_str(): %s\n", fileName.c_str()); 22 | m_pFile = fopen(fileName.c_str(), "rb"); 23 | if (m_pFile) { 24 | fseek(m_pFile, 0, SEEK_END); 25 | m_nFileSize = ftell(m_pFile); 26 | fseek(m_pFile, 0, SEEK_SET); 27 | 28 | auto pos = m_strFileName.find_last_of("."); 29 | 30 | if (pos != m_strFileName.npos) { 31 | #ifdef _WIN32 32 | std::string tmp = m_strFileName.substr(pos + 1); 33 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 34 | LPWSTR lpszW = new WCHAR[nLen]; 35 | MultiByteToWideChar(CP_ACP, 0, 36 | tmp.c_str(), -1, lpszW, nLen); 37 | m_strFileExt = lpszW; 38 | // free the string 39 | delete[] lpszW; 40 | #else 41 | m_strFileExt = L"7z"; 42 | #endif 43 | } 44 | // wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 45 | } 46 | else { 47 | wprintf(L"fileName.c_str(): %s cant open\n", fileName.c_str()); 48 | } 49 | } 50 | 51 | virtual ~TestInStream() 52 | { 53 | fclose(m_pFile); 54 | } 55 | 56 | public: 57 | virtual wstring GetExt() const 58 | { 59 | // wprintf(L"GetExt:%ls, but return 001, try to test signature match\n", m_strFileExt.c_str()); 60 | return L"001"; 61 | } 62 | 63 | virtual int Read(void *data, unsigned int size, unsigned int *processedSize) 64 | { 65 | if (!m_pFile) 66 | return 1; 67 | 68 | int count = fread(data, 1, size, m_pFile); 69 | 70 | if (count >= 0) { 71 | if (processedSize != NULL) 72 | *processedSize = count; 73 | 74 | return 0; 75 | } 76 | 77 | return 1; 78 | } 79 | 80 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 81 | { 82 | if (!m_pFile) 83 | return 1; 84 | 85 | int result = fseek(m_pFile, (long)offset, seekOrigin); 86 | 87 | if (!result) { 88 | if (newPosition) 89 | *newPosition = ftell(m_pFile); 90 | 91 | return 0; 92 | } 93 | 94 | return result; 95 | } 96 | 97 | virtual int GetSize(unsigned __int64 * size) 98 | { 99 | if (size) 100 | *size = m_nFileSize; 101 | return 0; 102 | } 103 | }; 104 | 105 | class TestOutStream : public C7ZipOutStream 106 | { 107 | private: 108 | FILE * m_pFile; 109 | std::string m_strFileName; 110 | wstring m_strFileExt; 111 | int m_nFileSize; 112 | public: 113 | TestOutStream(std::string fileName) : 114 | m_strFileName(fileName), 115 | m_strFileExt(L"7z") 116 | { 117 | m_pFile = fopen(fileName.c_str(), "wb"); 118 | m_nFileSize = 0; 119 | 120 | auto pos = m_strFileName.find_last_of("."); 121 | 122 | if (pos != m_strFileName.npos) 123 | { 124 | #ifdef _WIN32 125 | std::string tmp = m_strFileName.substr(pos + 1); 126 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 127 | LPWSTR lpszW = new WCHAR[nLen]; 128 | MultiByteToWideChar(CP_ACP, 0, 129 | tmp.c_str(), -1, lpszW, nLen); 130 | m_strFileExt = lpszW; 131 | // free the string 132 | delete[] lpszW; 133 | #else 134 | m_strFileExt = L"7z"; 135 | #endif 136 | } 137 | // wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 138 | } 139 | 140 | virtual ~TestOutStream() 141 | { 142 | fclose(m_pFile); 143 | } 144 | 145 | public: 146 | int GetFileSize() const 147 | { 148 | return m_nFileSize; 149 | } 150 | 151 | virtual int Write(const void *data, unsigned int size, unsigned int *processedSize) 152 | { 153 | int count = fwrite(data, 1, size, m_pFile); 154 | wprintf(L"Write:%d %d\n", size, count); 155 | 156 | if (count >= 0) 157 | { 158 | if (processedSize != NULL) 159 | *processedSize = count; 160 | 161 | m_nFileSize += count; 162 | return 0; 163 | } 164 | 165 | return 1; 166 | } 167 | 168 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 169 | { 170 | int result = fseek(m_pFile, (long)offset, seekOrigin); 171 | 172 | if (!result) 173 | { 174 | if (newPosition) 175 | *newPosition = ftell(m_pFile); 176 | 177 | return 0; 178 | } 179 | 180 | return result; 181 | } 182 | 183 | virtual int SetSize(unsigned __int64 size) 184 | { 185 | wprintf(L"SetFileSize:%ld\n", size); 186 | return 0; 187 | } 188 | }; 189 | 190 | const wchar_t * index_names[] = { 191 | L"kpidPackSize", //(Packed Size) 192 | L"kpidAttrib", //(Attributes) 193 | L"kpidCTime", //(Created) 194 | L"kpidATime", //(Accessed) 195 | L"kpidMTime", //(Modified) 196 | L"kpidSolid", //(Solid) 197 | L"kpidEncrypted", //(Encrypted) 198 | L"kpidUser", //(User) 199 | L"kpidGroup", //(Group) 200 | L"kpidComment", //(Comment) 201 | L"kpidPhySize", //(Physical Size) 202 | L"kpidHeadersSize", //(Headers Size) 203 | L"kpidChecksum", //(Checksum) 204 | L"kpidCharacts", //(Characteristics) 205 | L"kpidCreatorApp", //(Creator Application) 206 | L"kpidTotalSize", //(Total Size) 207 | L"kpidFreeSpace", //(Free Space) 208 | L"kpidClusterSize", //(Cluster Size) 209 | L"kpidVolumeName", //(Label) 210 | L"kpidPath", //(FullPath) 211 | L"kpidIsDir", //(IsDir) 212 | }; 213 | 214 | #ifdef _WIN32 215 | int _tmain(int argc, _TCHAR* argv[]) 216 | #else 217 | int main(int argc, char * argv[]) 218 | #endif 219 | { 220 | C7ZipLibrary lib; 221 | 222 | if (!lib.Initialize()) { 223 | wprintf(L"initialize fail!\n"); 224 | return 1; 225 | } 226 | 227 | WStringArray exts; 228 | 229 | if (!lib.GetSupportedExts(exts)) { 230 | wprintf(L"get supported exts fail\n"); 231 | return 1; 232 | } 233 | 234 | // size_t size = exts.size(); 235 | 236 | // for(size_t i = 0; i < size; i++) { 237 | // wstring ext = exts[i]; 238 | 239 | // for(size_t j = 0; j < ext.size(); j++) { 240 | // wprintf(L"%c", (char)(ext[j] &0xFF)); 241 | // } 242 | 243 | // wprintf(L"\n"); 244 | // } 245 | 246 | C7ZipArchive * pArchive = NULL; 247 | 248 | TestInStream stream("Test7zip.dmg"); 249 | TestOutStream oStream("TestResult.txt"); 250 | if (lib.OpenArchive(&stream, &pArchive, true)) { 251 | unsigned int numItems = 0; 252 | 253 | pArchive->GetItemCount(&numItems); 254 | 255 | wprintf(L"%d\n", numItems); 256 | 257 | for(unsigned int i = 0;i < numItems;i++) { 258 | C7ZipArchiveItem * pArchiveItem = NULL; 259 | 260 | if (pArchive->GetItemInfo(i, &pArchiveItem)) { 261 | // wprintf(L"%d,%ls,%d\n", pArchiveItem->GetArchiveIndex(), 262 | // pArchiveItem->GetFullPath().c_str(), 263 | // pArchiveItem->IsDir()); 264 | 265 | // wprintf(L"get all properties\n"); 266 | // for(lib7zip::PropertyIndexEnum index = lib7zip::kpidPackSize; 267 | // index <= lib7zip::kpidIsDir; 268 | // index = (lib7zip::PropertyIndexEnum)(index + 1)) { 269 | // wstring strVal = L""; 270 | // unsigned __int64 val = 0; 271 | // bool bVal = false; 272 | 273 | // bool result = pArchiveItem->GetUInt64Property(index, val); 274 | 275 | // wprintf(L"\n\nGetProperty:%d %ls\n", (int)index, 276 | // index_names[(int)index]); 277 | 278 | // wprintf(L"UInt64 result:%ls val=%ld\n", 279 | // result ? L"true" : L"false", 280 | // val); 281 | 282 | // result = pArchiveItem->GetBoolProperty(index, bVal); 283 | 284 | // wprintf(L"Bool result:%ls val=%ls\n", 285 | // result ? L"true" : L"false", 286 | // bVal ? L"true" : L"false"); 287 | 288 | // result = pArchiveItem->GetStringProperty(index, strVal); 289 | 290 | // wprintf(L"String result:%ls val=%ls\n", 291 | // result ? L"true" : L"false", 292 | // strVal.c_str()); 293 | 294 | // result = pArchiveItem->GetFileTimeProperty(index, val); 295 | 296 | // wprintf(L"FileTime result:%ls val=%ld\n", 297 | // result ? L"true" : L"false", 298 | // val); 299 | // } 300 | 301 | //set archive password or item password 302 | pArchive->SetArchivePassword(L"test"); 303 | if (i==0) { 304 | //Or set password for each archive item 305 | //pArchiveItem->SetArchiveItemPassword(L"test"); 306 | pArchive->Extract(pArchiveItem, &oStream); 307 | } 308 | } //if 309 | }//for 310 | } 311 | else { 312 | wprintf(L"open archive Test7Zip.7z fail\n"); 313 | } 314 | 315 | if (pArchive != NULL) 316 | delete pArchive; 317 | 318 | return 0; 319 | } 320 | -------------------------------------------------------------------------------- /src/HelperFuncs.cpp: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_CONFIG_H 2 | #include "config.h" 3 | #endif 4 | 5 | #define BUILD_LIB7ZIP 6 | #ifndef INITGUID 7 | #define INITGUID 8 | #endif 9 | 10 | #if !defined(_WIN32) && !defined(_OS2) 11 | #include "CPP/myWindows/StdAfx.h" 12 | #include "CPP/Windows/Defs.h" 13 | #include "CPP/7zip/MyVersion.h" 14 | #endif 15 | 16 | #include "C/7zVersion.h" 17 | #include "CPP/7zip/Archive/IArchive.h" 18 | #include "CPP/Windows/PropVariant.h" 19 | #include "CPP/Common/MyCom.h" 20 | #include "CPP/7zip/ICoder.h" 21 | #include "CPP/7zip/IPassword.h" 22 | #include "CPP/7zip/Common/FileStreams.h" 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "lib7zip.h" 32 | 33 | #include "OSFunctions.h" 34 | 35 | #if defined(_OS2) 36 | bool VARIANT_BOOLToBool(VARIANT_BOOL v) { return (v != VARIANT_FALSE); } 37 | #endif //_OS2 38 | 39 | #include "HelperFuncs.h" 40 | 41 | static const char * g_lib7zip_loc = NULL; 42 | 43 | HRESULT ReadProp( 44 | GetHandlerPropertyFunc getProp, 45 | GetHandlerPropertyFunc2 getProp2, 46 | UInt32 index, PROPID propID, NWindows::NCOM::CPropVariant &prop) 47 | { 48 | if (getProp2) 49 | return getProp2(index, propID, &prop);; 50 | return getProp(propID, &prop); 51 | } 52 | 53 | HRESULT ReadBoolProp( 54 | GetHandlerPropertyFunc getProp, 55 | GetHandlerPropertyFunc2 getProp2, 56 | UInt32 index, PROPID propID, bool &res) 57 | { 58 | NWindows::NCOM::CPropVariant prop; 59 | 60 | RINOK(ReadProp(getProp, getProp2, index, propID, prop)); 61 | if (prop.vt == VT_BOOL) 62 | res = VARIANT_BOOLToBool(prop.boolVal); 63 | else if (prop.vt != VT_EMPTY) 64 | return E_FAIL; 65 | return S_OK; 66 | } 67 | 68 | HRESULT ReadStringProp( 69 | GetHandlerPropertyFunc getProp, 70 | GetHandlerPropertyFunc2 getProp2, 71 | UInt32 index, PROPID propID, wstring &res) 72 | { 73 | NWindows::NCOM::CPropVariant prop; 74 | 75 | RINOK(ReadProp(getProp, getProp2, index, propID, prop)); 76 | if (prop.vt == VT_BSTR) 77 | res = prop.bstrVal; 78 | else if (prop.vt != VT_EMPTY) 79 | return E_FAIL; 80 | return S_OK; 81 | } 82 | 83 | void SplitString(const wstring &srcString, WStringArray &destStrings) 84 | { 85 | destStrings.clear(); 86 | wstring s; 87 | size_t len = srcString.length(); 88 | if (len == 0) 89 | return; 90 | for (size_t i = 0; i < len; i++) { 91 | wchar_t c = srcString[i]; 92 | if (c == L' ') { 93 | if (!s.empty()) { 94 | destStrings.push_back(s); 95 | s.clear(); 96 | } 97 | } 98 | else 99 | s += c; 100 | } 101 | if (!s.empty()) 102 | destStrings.push_back(s); 103 | } 104 | 105 | HRESULT GetCoderClass(GetMethodPropertyFunc getMethodProperty, UInt32 index, 106 | PROPID propId, GUID & clsId, bool &isAssigned) 107 | { 108 | NWindows::NCOM::CPropVariant prop; 109 | isAssigned = false; 110 | RINOK(getMethodProperty(index, propId, &prop)); 111 | if (prop.vt == VT_BSTR) { 112 | isAssigned = true; 113 | clsId = *(const GUID *)prop.bstrVal; 114 | } 115 | else if (prop.vt != VT_EMPTY) 116 | return E_FAIL; 117 | return S_OK; 118 | } 119 | 120 | HRESULT GetMethodPropertyString(GetMethodPropertyFunc getMethodProperty, UInt32 index, 121 | PROPID propId, wstring & val) 122 | { 123 | NWindows::NCOM::CPropVariant prop; 124 | RINOK(getMethodProperty(index, propId, &prop)); 125 | if (prop.vt == VT_BSTR) { 126 | val = prop.bstrVal; 127 | } 128 | else if (prop.vt != VT_EMPTY) 129 | return E_FAIL; 130 | return S_OK; 131 | } 132 | 133 | HRESULT GetMethodPropertyGUID(GetMethodPropertyFunc getMethodProperty, UInt32 index, 134 | PROPID propId, GUID & val) 135 | { 136 | NWindows::NCOM::CPropVariant prop; 137 | RINOK(getMethodProperty(index, propId, &prop)); 138 | if (prop.vt == VT_BSTR) { 139 | val = *(const GUID *)prop.bstrVal; 140 | } 141 | else if (prop.vt != VT_EMPTY) 142 | return E_FAIL; 143 | return S_OK; 144 | } 145 | 146 | #if MY_VER_MAJOR >= 15 147 | //after version 15, MyCharUpper defined inline in MyString.h 148 | #else 149 | #ifdef _WIN32 150 | inline wchar_t MyCharUpper(wchar_t c) LIB7ZIP_THROW 151 | { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); } 152 | #else 153 | inline wchar_t MyCharUpper(wchar_t c) LIB7ZIP_THROW 154 | { return toupper(c); } 155 | #endif 156 | #endif 157 | 158 | int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2) LIB7ZIP_THROW 159 | { 160 | for (;;) { 161 | wchar_t c1 = *s1++; 162 | wchar_t c2 = *s2++; 163 | if (c1 != c2) { 164 | wchar_t u1 = MyCharUpper(c1); 165 | wchar_t u2 = MyCharUpper(c2); 166 | if (u1 < u2) return -1; 167 | if (u1 > u2) return 1; 168 | } 169 | if (c1 == 0) return 0; 170 | } 171 | } 172 | 173 | void NormalizeDirPathPrefix(wstring & dirPath) 174 | { 175 | if (dirPath.empty()) 176 | return; 177 | if (dirPath.rfind(wchar_t(kDirDelimiter)) != dirPath.length() - 1) 178 | dirPath += wchar_t(kDirDelimiter); 179 | } 180 | 181 | HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, wstring &result) 182 | { 183 | NWindows::NCOM::CPropVariant prop; 184 | RINOK(archive->GetProperty(index, kpidPath, &prop)); 185 | if(prop.vt == VT_BSTR) 186 | result = prop.bstrVal; 187 | else if (prop.vt == VT_EMPTY) 188 | result.clear(); 189 | else 190 | return E_FAIL; 191 | return S_OK; 192 | } 193 | 194 | HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const wstring &defaultName, wstring &result) 195 | { 196 | RINOK(GetArchiveItemPath(archive, index, result)); 197 | if (result.empty()) { 198 | result = defaultName; 199 | NWindows::NCOM::CPropVariant prop; 200 | RINOK(archive->GetProperty(index, kpidExtension, &prop)); 201 | if (prop.vt == VT_BSTR) { 202 | result += L'.'; 203 | result += prop.bstrVal; 204 | } 205 | else if (prop.vt != VT_EMPTY) 206 | return E_FAIL; 207 | } 208 | return S_OK; 209 | } 210 | 211 | HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index, 212 | const FILETIME &defaultFileTime, FILETIME &fileTime) 213 | { 214 | #ifdef _WIN32 215 | NWindows::NCOM::CPropVariant prop; 216 | RINOK(archive->GetProperty(index, kpidMTime, &prop)); 217 | if (prop.vt == VT_FILETIME) 218 | fileTime = prop.filetime; 219 | else if (prop.vt == VT_EMPTY) 220 | fileTime = defaultFileTime; 221 | else 222 | return E_FAIL; 223 | #else 224 | fileTime = defaultFileTime; 225 | #endif 226 | 227 | return S_OK; 228 | } 229 | 230 | HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) 231 | { 232 | NWindows::NCOM::CPropVariant prop; 233 | RINOK(archive->GetProperty(index, propID, &prop)); 234 | if(prop.vt == VT_BOOL) 235 | result = VARIANT_BOOLToBool(prop.boolVal); 236 | else if (prop.vt == VT_EMPTY) 237 | result = false; 238 | else 239 | return E_FAIL; 240 | return S_OK; 241 | } 242 | 243 | HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) 244 | { 245 | #if MY_VER_MAJOR >= 9 || defined(_WIN32) || defined(_OS2) || MY_VER_MAJOR == 4 246 | return IsArchiveItemProp(archive, index, kpidIsDir, result); 247 | #else 248 | return IsArchiveItemProp(archive, index, kpidIsFolder, result); 249 | #endif 250 | } 251 | 252 | HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result) 253 | { 254 | return IsArchiveItemProp(archive, index, kpidIsAnti, result); 255 | } 256 | 257 | UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop) 258 | { 259 | switch (prop.vt) { 260 | case VT_UI1: return prop.bVal; 261 | case VT_UI2: return prop.uiVal; 262 | case VT_UI4: return prop.ulVal; 263 | case VT_UI8: return (UInt64)prop.uhVal.QuadPart; 264 | default: 265 | #if !defined(_WIN32_WCE) && !defined(BUILD_ANGSTROM) 266 | throw 151199; 267 | #else 268 | return 0; 269 | #endif 270 | } 271 | } 272 | 273 | HRESULT GetFilePathExt(const wstring & path, wstring & ext) 274 | { 275 | int dotPos = path.rfind(L'.'); 276 | if (dotPos >= 0) { 277 | ext = path.substr(dotPos + 1); 278 | return S_OK; 279 | } 280 | 281 | return E_FAIL; 282 | } 283 | 284 | wstring WidenString( const string& str ) 285 | { 286 | std::wostringstream wstm ; 287 | const char * loc = 288 | g_lib7zip_loc == NULL ? setlocale(LC_CTYPE, "") : g_lib7zip_loc; 289 | 290 | if (loc == NULL || strlen(loc) == 0) 291 | loc = "C"; 292 | 293 | try { 294 | wstm.imbue(std::locale(loc)); 295 | } 296 | catch(...) { 297 | wstm.imbue(std::locale("C")); 298 | } 299 | 300 | const std::ctype& ctfacet = 301 | std::use_facet< std::ctype >( wstm.getloc() ) ; 302 | for( size_t i=0 ; i& ctfacet = 312 | std::use_facet< std::ctype >( stm.getloc() ) ; 313 | for( size_t i=0 ; i 7 | 8 | class TestInStream : public C7ZipInStream 9 | { 10 | private: 11 | FILE * m_pFile; 12 | std::string m_strFileName; 13 | wstring m_strFileExt; 14 | int m_nFileSize; 15 | public: 16 | TestInStream(std::string fileName) : 17 | m_strFileName(fileName), 18 | m_strFileExt(L"7z") 19 | { 20 | 21 | wprintf(L"fileName.c_str(): %s\n", fileName.c_str()); 22 | m_pFile = fopen(fileName.c_str(), "rb"); 23 | if (m_pFile) { 24 | fseek(m_pFile, 0, SEEK_END); 25 | m_nFileSize = ftell(m_pFile); 26 | fseek(m_pFile, 0, SEEK_SET); 27 | 28 | auto pos = m_strFileName.find_last_of("."); 29 | 30 | if (pos != m_strFileName.npos) { 31 | #ifdef _WIN32 32 | std::string tmp = m_strFileName.substr(pos + 1); 33 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 34 | LPWSTR lpszW = new WCHAR[nLen]; 35 | MultiByteToWideChar(CP_ACP, 0, 36 | tmp.c_str(), -1, lpszW, nLen); 37 | m_strFileExt = lpszW; 38 | // free the string 39 | delete[] lpszW; 40 | #else 41 | m_strFileExt = L"7z"; 42 | #endif 43 | } 44 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 45 | } 46 | else { 47 | wprintf(L"fileName.c_str(): %s cant open\n", fileName.c_str()); 48 | } 49 | } 50 | 51 | virtual ~TestInStream() 52 | { 53 | fclose(m_pFile); 54 | } 55 | 56 | public: 57 | virtual wstring GetExt() const 58 | { 59 | wprintf(L"GetExt:%ls\n", m_strFileExt.c_str()); 60 | return m_strFileExt; 61 | } 62 | 63 | virtual int Read(void *data, unsigned int size, unsigned int *processedSize) 64 | { 65 | if (!m_pFile) 66 | return 1; 67 | 68 | int count = fread(data, 1, size, m_pFile); 69 | wprintf(L"Read:%d %d\n", size, count); 70 | 71 | if (count >= 0) { 72 | if (processedSize != NULL) 73 | *processedSize = count; 74 | 75 | return 0; 76 | } 77 | 78 | return 1; 79 | } 80 | 81 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 82 | { 83 | if (!m_pFile) 84 | return 1; 85 | 86 | int result = fseek(m_pFile, (long)offset, seekOrigin); 87 | 88 | if (!result) { 89 | if (newPosition) 90 | *newPosition = ftell(m_pFile); 91 | 92 | return 0; 93 | } 94 | 95 | return result; 96 | } 97 | 98 | virtual int GetSize(unsigned __int64 * size) 99 | { 100 | if (size) 101 | *size = m_nFileSize; 102 | return 0; 103 | } 104 | }; 105 | 106 | class TestOutStream : public C7ZipOutStream 107 | { 108 | private: 109 | FILE * m_pFile; 110 | std::string m_strFileName; 111 | wstring m_strFileExt; 112 | int m_nFileSize; 113 | public: 114 | TestOutStream(std::string fileName) : 115 | m_strFileName(fileName), 116 | m_strFileExt(L"7z") 117 | { 118 | m_pFile = fopen(fileName.c_str(), "wb"); 119 | m_nFileSize = 0; 120 | 121 | auto pos = m_strFileName.find_last_of("."); 122 | 123 | if (pos != m_strFileName.npos) 124 | { 125 | #ifdef _WIN32 126 | std::string tmp = m_strFileName.substr(pos + 1); 127 | int nLen = MultiByteToWideChar(CP_ACP, 0, tmp.c_str(), -1, NULL, NULL); 128 | LPWSTR lpszW = new WCHAR[nLen]; 129 | MultiByteToWideChar(CP_ACP, 0, 130 | tmp.c_str(), -1, lpszW, nLen); 131 | m_strFileExt = lpszW; 132 | // free the string 133 | delete[] lpszW; 134 | #else 135 | m_strFileExt = L"7z"; 136 | #endif 137 | } 138 | wprintf(L"Ext:%ls\n", m_strFileExt.c_str()); 139 | } 140 | 141 | virtual ~TestOutStream() 142 | { 143 | fclose(m_pFile); 144 | } 145 | 146 | public: 147 | int GetFileSize() const 148 | { 149 | return m_nFileSize; 150 | } 151 | 152 | virtual int Write(const void *data, unsigned int size, unsigned int *processedSize) 153 | { 154 | int count = fwrite(data, 1, size, m_pFile); 155 | wprintf(L"Write:%d %d\n", size, count); 156 | 157 | if (count >= 0) 158 | { 159 | if (processedSize != NULL) 160 | *processedSize = count; 161 | 162 | m_nFileSize += count; 163 | return 0; 164 | } 165 | 166 | return 1; 167 | } 168 | 169 | virtual int Seek(__int64 offset, unsigned int seekOrigin, unsigned __int64 *newPosition) 170 | { 171 | int result = fseek(m_pFile, (long)offset, seekOrigin); 172 | 173 | if (!result) 174 | { 175 | if (newPosition) 176 | *newPosition = ftell(m_pFile); 177 | 178 | return 0; 179 | } 180 | 181 | return result; 182 | } 183 | 184 | virtual int SetSize(unsigned __int64 size) 185 | { 186 | wprintf(L"SetFileSize:%ld\n", size); 187 | return 0; 188 | } 189 | }; 190 | 191 | const wchar_t * index_names[] = { 192 | L"kpidPackSize", //(Packed Size) 193 | L"kpidAttrib", //(Attributes) 194 | L"kpidCTime", //(Created) 195 | L"kpidATime", //(Accessed) 196 | L"kpidMTime", //(Modified) 197 | L"kpidSolid", //(Solid) 198 | L"kpidEncrypted", //(Encrypted) 199 | L"kpidUser", //(User) 200 | L"kpidGroup", //(Group) 201 | L"kpidComment", //(Comment) 202 | L"kpidPhySize", //(Physical Size) 203 | L"kpidHeadersSize", //(Headers Size) 204 | L"kpidChecksum", //(Checksum) 205 | L"kpidCharacts", //(Characteristics) 206 | L"kpidCreatorApp", //(Creator Application) 207 | L"kpidTotalSize", //(Total Size) 208 | L"kpidFreeSpace", //(Free Space) 209 | L"kpidClusterSize", //(Cluster Size) 210 | L"kpidVolumeName", //(Label) 211 | L"kpidPath", //(FullPath) 212 | L"kpidIsDir", //(IsDir) 213 | }; 214 | 215 | #ifdef _WIN32 216 | int _tmain(int argc, _TCHAR* argv[]) 217 | #else 218 | int main(int argc, char * argv[]) 219 | #endif 220 | { 221 | C7ZipLibrary lib; 222 | 223 | if (!lib.Initialize()) { 224 | wprintf(L"initialize fail!\n"); 225 | return 1; 226 | } 227 | 228 | WStringArray exts; 229 | 230 | if (!lib.GetSupportedExts(exts)) { 231 | wprintf(L"get supported exts fail\n"); 232 | return 1; 233 | } 234 | 235 | size_t size = exts.size(); 236 | 237 | for(size_t i = 0; i < size; i++) { 238 | wstring ext = exts[i]; 239 | 240 | for(size_t j = 0; j < ext.size(); j++) { 241 | wprintf(L"%c", (char)(ext[j] &0xFF)); 242 | } 243 | 244 | wprintf(L"\n"); 245 | } 246 | 247 | C7ZipArchive * pArchive = NULL; 248 | 249 | TestInStream stream("Test7ZipCryptFileName.7z"); 250 | 251 | if (!lib.OpenArchive(&stream, &pArchive)) { 252 | wprintf(L"open archive Test7ZipCryptFileName.7z without password, LastError(%X) == NEED_PASSWORD(%X)\n", 253 | lib.GetLastError(), lib7zip::LIB7ZIP_NEED_PASSWORD); 254 | } 255 | 256 | stream.Seek(0, FILE_BEGIN, NULL); 257 | 258 | if (lib.OpenArchive(&stream, &pArchive, wstring(L"hello"))) { 259 | unsigned int numItems = 0; 260 | 261 | pArchive->GetItemCount(&numItems); 262 | 263 | wprintf(L"%d, LastError=%X\n", numItems, lib.GetLastError()); 264 | 265 | wprintf(L"get all archive properties\n"); 266 | for(lib7zip::PropertyIndexEnum index = lib7zip::kpidPackSize; 267 | index <= lib7zip::kpidIsDir; 268 | index = (lib7zip::PropertyIndexEnum)(index + 1)) { 269 | wstring strVal = L""; 270 | unsigned __int64 val = 0; 271 | bool bVal = false; 272 | 273 | bool result = pArchive->GetUInt64Property(index, val); 274 | 275 | wprintf(L"\n\nGetProperty:%d %ls\n", (int)index, 276 | index_names[(int)index]); 277 | 278 | wprintf(L"UInt64 result:%ls val=%ld\n", 279 | result ? L"true" : L"false", 280 | val); 281 | 282 | result = pArchive->GetBoolProperty(index, bVal); 283 | 284 | wprintf(L"Bool result:%ls val=%ls\n", 285 | result ? L"true" : L"false", 286 | bVal ? L"true" : L"false"); 287 | 288 | result = pArchive->GetStringProperty(index, strVal); 289 | 290 | wprintf(L"String result:%ls val=%ls\n", 291 | result ? L"true" : L"false", 292 | strVal.c_str()); 293 | 294 | result = pArchive->GetFileTimeProperty(index, val); 295 | 296 | wprintf(L"FileTime result:%ls val=%ld\n", 297 | result ? L"true" : L"false", 298 | val); 299 | } 300 | 301 | wprintf(L"=============================================\n"); 302 | 303 | for(unsigned int i = 0;i < numItems;i++) { 304 | C7ZipArchiveItem * pArchiveItem = NULL; 305 | 306 | if (pArchive->GetItemInfo(i, &pArchiveItem)) { 307 | wprintf(L"%d,%ls,%d\n", pArchiveItem->GetArchiveIndex(), 308 | pArchiveItem->GetFullPath().c_str(), 309 | pArchiveItem->IsDir()); 310 | 311 | wprintf(L"get all properties\n"); 312 | for(lib7zip::PropertyIndexEnum index = lib7zip::kpidPackSize; 313 | index <= lib7zip::kpidIsDir; 314 | index = (lib7zip::PropertyIndexEnum)(index + 1)) { 315 | wstring strVal = L""; 316 | unsigned __int64 val = 0; 317 | bool bVal = false; 318 | 319 | bool result = pArchiveItem->GetUInt64Property(index, val); 320 | 321 | wprintf(L"\n\nGetProperty:%d %ls\n", (int)index, 322 | index_names[(int)index]); 323 | 324 | wprintf(L"UInt64 result:%ls val=%ld\n", 325 | result ? L"true" : L"false", 326 | val); 327 | 328 | result = pArchiveItem->GetBoolProperty(index, bVal); 329 | 330 | wprintf(L"Bool result:%ls val=%ls\n", 331 | result ? L"true" : L"false", 332 | bVal ? L"true" : L"false"); 333 | 334 | result = pArchiveItem->GetStringProperty(index, strVal); 335 | 336 | wprintf(L"String result:%ls val=%ls\n", 337 | result ? L"true" : L"false", 338 | strVal.c_str()); 339 | 340 | result = pArchiveItem->GetFileTimeProperty(index, val); 341 | 342 | wprintf(L"FileTime result:%ls val=%ld\n", 343 | result ? L"true" : L"false", 344 | val); 345 | } 346 | 347 | //set archive password or item password 348 | pArchive->SetArchivePassword(L"hello"); 349 | } //if 350 | }//for 351 | } 352 | else { 353 | wprintf(L"open archive Test7ZipCryptFileName.7z with password fail, LastError=%X\n", lib.GetLastError()); 354 | } 355 | 356 | if (pArchive != NULL) 357 | delete pArchive; 358 | 359 | return 0; 360 | } 361 | -------------------------------------------------------------------------------- /src/7ZipOpenArchive.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_WIN32) && !defined(_OS2) 2 | #include "CPP/myWindows/StdAfx.h" 3 | #include "CPP/include_windows/windows.h" 4 | #endif 5 | 6 | #include "C/7zVersion.h" 7 | #include "CPP/7zip/Archive/IArchive.h" 8 | #include "CPP/Windows/PropVariant.h" 9 | #include "CPP/Common/MyCom.h" 10 | #include "CPP/7zip/ICoder.h" 11 | #include "CPP/7zip/IPassword.h" 12 | #include "Common/ComTry.h" 13 | #include "Windows/PropVariant.h" 14 | 15 | #if MY_VER_MAJOR >= 15 16 | #include "CPP/Common/MyBuffer.h" 17 | #else 18 | #include "CPP/Common/Buffer.h" 19 | #endif 20 | 21 | using namespace NWindows; 22 | 23 | #include "lib7zip.h" 24 | 25 | #include "HelperFuncs.h" 26 | #include "7ZipFunctions.h" 27 | #include "7ZipDllHandler.h" 28 | #include "7ZipCodecInfo.h" 29 | #include "7ZipFormatInfo.h" 30 | #include "7ZipArchiveOpenCallback.h" 31 | #include "7ZipCompressCodecsInfo.h" 32 | #include "7ZipInStreamWrapper.h" 33 | 34 | const UInt64 kMaxCheckStartPosition = 1 << 22; 35 | 36 | extern bool Create7ZipArchive(C7ZipLibrary * pLibrary, 37 | const std::vector> & archives, 38 | IInArchive * pInArchive, C7ZipArchive ** pArchive); 39 | 40 | static bool ReadStream(CMyComPtr & inStream, Int64 offset, UINT32 seekOrigin, CByteBuffer & signature) 41 | { 42 | UInt64 savedPosition = 0; 43 | UInt64 newPosition = 0; 44 | #if MY_VER_MAJOR >= 15 45 | UInt32 readCount = signature.Size(); 46 | #else 47 | UInt32 readCount = signature.GetCapacity(); 48 | #endif 49 | unsigned char * buf = signature; 50 | 51 | if (S_OK != inStream->Seek(0, FILE_CURRENT, &savedPosition)) 52 | return false; 53 | 54 | if (S_OK != inStream->Seek(offset, seekOrigin, &newPosition)) { 55 | inStream->Seek(savedPosition, FILE_BEGIN, &newPosition); //restore pos 56 | return false; 57 | } 58 | 59 | while (readCount > 0) { 60 | UInt32 processedCount = 0; 61 | 62 | if (S_OK != inStream->Read(buf, readCount, &processedCount)) { 63 | inStream->Seek(savedPosition, FILE_BEGIN, &newPosition); //restore pos 64 | return false; 65 | } 66 | 67 | if (processedCount == 0) 68 | break; 69 | 70 | readCount -= processedCount; 71 | buf += processedCount; 72 | } 73 | 74 | inStream->Seek(savedPosition, FILE_BEGIN, &newPosition); //restore pos 75 | 76 | return readCount == 0; 77 | } 78 | 79 | static int CreateInArchive(pU7ZipFunctions pFunctions, 80 | const C7ZipObjectPtrArray & formatInfos, 81 | CMyComPtr & inStream, 82 | wstring ext, 83 | CMyComPtr & archive, 84 | bool fCheckFileTypeBySignature) 85 | { 86 | for (C7ZipObjectPtrArray::const_iterator it = formatInfos.begin(); 87 | it != formatInfos.end();it++) { 88 | const C7ZipFormatInfo * pInfo = dynamic_cast(*it); 89 | 90 | if (!fCheckFileTypeBySignature) { 91 | for(WStringArray::const_iterator extIt = pInfo->Exts.begin(); extIt != pInfo->Exts.end(); extIt++) { 92 | if (MyStringCompareNoCase((*extIt).c_str(), ext.c_str()) == 0) { 93 | return pFunctions->v.CreateObject(&pInfo->m_ClassID, 94 | &IID_IInArchive, (void **)&archive); 95 | } 96 | } 97 | } else { 98 | #if MY_VER_MAJOR >= 15 99 | if (pInfo->Signatures.Size() == 0 /*&& pInfo->m_FinishSignature.length() == 0*/) 100 | #else 101 | if (pInfo->m_StartSignature.GetCapacity() == 0 /*&& pInfo->m_FinishSignature.length() == 0*/) 102 | #endif 103 | continue; //no signature 104 | 105 | bool dmg_archive = false; 106 | for(WStringArray::const_iterator extIt = pInfo->Exts.begin(); extIt != pInfo->Exts.end(); extIt++) { 107 | if (MyStringCompareNoCase((*extIt).c_str(), L"dmg") == 0) { 108 | dmg_archive = true; 109 | break; 110 | } 111 | } 112 | 113 | #if MY_VER_MAJOR >= 15 114 | for(unsigned i = 0; i < pInfo->Signatures.Size(); i++) { 115 | CByteBuffer signature(pInfo->Signatures[i].Size()); 116 | CByteBuffer signatureEnd(pInfo->Signatures[i].Size()); 117 | 118 | if (!ReadStream(inStream, pInfo->SignatureOffset, FILE_BEGIN, signature)) 119 | continue; //unable to read signature 120 | 121 | if (dmg_archive) { 122 | ReadStream(inStream, -0x200, FILE_END, signatureEnd); 123 | } 124 | 125 | if (signature == pInfo->Signatures[i] 126 | || (dmg_archive && signatureEnd == pInfo->Signatures[i])) { 127 | return pFunctions->v.CreateObject(&pInfo->m_ClassID, 128 | &IID_IInArchive, (void **)&archive); 129 | } 130 | } 131 | #else 132 | CByteBuffer signature; 133 | signature.SetCapacity(pInfo->m_StartSignature.GetCapacity()); 134 | CByteBuffer signatureEnd; 135 | signatureEnd.SetCapacity(pInfo->m_StartSignature.GetCapacity()); 136 | 137 | if (!ReadStream(inStream, 0, FILE_BEGIN, signature)) 138 | continue; //unable to read signature 139 | 140 | if (dmg_archive) { 141 | ReadStream(inStream, -0x200, FILE_END, signatureEnd); 142 | } 143 | 144 | if (signature == pInfo->m_StartSignature || 145 | (dmg_archive && signatureEnd == pInfo->m_StartSignature)) { 146 | return pFunctions->v.CreateObject(&pInfo->m_ClassID, 147 | &IID_IInArchive, (void **)&archive); 148 | } 149 | #endif 150 | } //check file type by signature 151 | } 152 | 153 | return CLASS_E_CLASSNOTAVAILABLE; 154 | } 155 | 156 | static HRESULT InternalOpenArchive(C7ZipLibrary * pLibrary, 157 | C7ZipDllHandler * pHandler, 158 | C7ZipInStream * pInStream, 159 | C7ZipArchiveOpenCallback * pOpenCallBack, 160 | C7ZipArchive ** ppArchive, 161 | HRESULT * pResult, 162 | bool fCheckFileTypeBySignature); 163 | 164 | HRESULT Lib7ZipOpenArchive(C7ZipLibrary * pLibrary, 165 | C7ZipDllHandler * pHandler, 166 | C7ZipInStream * pInStream, 167 | C7ZipArchive ** ppArchive, 168 | const wstring & passwd, 169 | HRESULT * pResult, 170 | bool fCheckFileTypeBySignature) 171 | { 172 | C7ZipArchiveOpenCallback * pOpenCallBack = new C7ZipArchiveOpenCallback(NULL); 173 | 174 | if (passwd.length() > 0) { 175 | pOpenCallBack->PasswordIsDefined = true; 176 | pOpenCallBack->Password = passwd; 177 | } 178 | 179 | return InternalOpenArchive(pLibrary, pHandler, pInStream, 180 | pOpenCallBack, ppArchive, pResult, fCheckFileTypeBySignature); 181 | } 182 | 183 | HRESULT Lib7ZipOpenMultiVolumeArchive(C7ZipLibrary * pLibrary, 184 | C7ZipDllHandler * pHandler, 185 | C7ZipMultiVolumes * pMultiVolumes, 186 | C7ZipArchive ** ppArchive, 187 | const wstring & passwd, 188 | HRESULT * pResult, 189 | bool fCheckFileTypeBySignature) 190 | { 191 | wstring firstVolumeName = pMultiVolumes->GetFirstVolumeName(); 192 | 193 | if (!pMultiVolumes->MoveToVolume(firstVolumeName)) 194 | return false; 195 | 196 | C7ZipInStream * pInStream = pMultiVolumes->OpenCurrentVolumeStream(); 197 | 198 | if (pInStream == NULL) 199 | return false; 200 | 201 | C7ZipArchiveOpenCallback * pOpenCallBack = new C7ZipArchiveOpenCallback(pMultiVolumes); 202 | 203 | if (passwd.length() > 0) { 204 | pOpenCallBack->PasswordIsDefined = true; 205 | pOpenCallBack->Password = passwd; 206 | } 207 | 208 | return InternalOpenArchive(pLibrary, pHandler, pInStream, 209 | pOpenCallBack, ppArchive, pResult, fCheckFileTypeBySignature); 210 | } 211 | 212 | static HRESULT InternalOpenArchive(C7ZipLibrary * pLibrary, 213 | C7ZipDllHandler * pHandler, 214 | C7ZipInStream * pInStream, 215 | C7ZipArchiveOpenCallback * pOpenCallBack, 216 | C7ZipArchive ** ppArchive, 217 | HRESULT * pResult, 218 | bool fCheckFileTypeBySignature) 219 | { 220 | CMyComPtr archive = NULL; 221 | 222 | wstring extension = pInStream->GetExt(); 223 | 224 | C7ZipInStreamWrapper * pArchiveStream = new C7ZipInStreamWrapper(pInStream); 225 | 226 | CMyComPtr inStream(pArchiveStream); 227 | 228 | CMyComPtr openCallBack(pOpenCallBack); 229 | 230 | std::vector> archives; 231 | 232 | do { 233 | CMyComPtr setCompressCodecsInfo = NULL; 234 | CMyComPtr getStream = NULL; 235 | 236 | if (archive != NULL) { 237 | archives.push_back(archive); 238 | archive = NULL; 239 | } 240 | 241 | FAIL_RET(CreateInArchive(pHandler->GetFunctions(), 242 | pHandler->GetFormatInfoArray(), 243 | inStream, 244 | extension, 245 | archive, 246 | fCheckFileTypeBySignature), pResult); 247 | 248 | if (archive == NULL) 249 | return false; 250 | 251 | archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); 252 | 253 | if (setCompressCodecsInfo) { 254 | C7ZipCompressCodecsInfo * pCompressCodecsInfo = 255 | new C7ZipCompressCodecsInfo(pLibrary); 256 | RBOOLOK(setCompressCodecsInfo->SetCompressCodecsInfo(pCompressCodecsInfo)); 257 | } 258 | 259 | FAIL_RET(archive->Open(inStream, &kMaxCheckStartPosition, openCallBack), pResult); 260 | 261 | UInt32 mainSubfile; 262 | { 263 | NCOM::CPropVariant prop; 264 | FAIL_RET(archive->GetArchiveProperty(kpidMainSubfile, &prop), pResult); 265 | if (prop.vt == VT_UI4) 266 | mainSubfile = prop.ulVal; 267 | else { 268 | break; 269 | } 270 | 271 | UInt32 numItems; 272 | FAIL_RET(archive->GetNumberOfItems(&numItems), pResult); 273 | if (mainSubfile >= numItems) 274 | break; 275 | } 276 | 277 | if (archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream) 278 | break; 279 | 280 | CMyComPtr subSeqStream; 281 | if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream) 282 | break; 283 | 284 | inStream = NULL; 285 | if (subSeqStream.QueryInterface(IID_IInStream, &inStream) != S_OK || !inStream) 286 | break; 287 | 288 | wstring path; 289 | 290 | FAIL_RET(GetArchiveItemPath(archive, mainSubfile, path), pResult); 291 | 292 | CMyComPtr setSubArchiveName; 293 | 294 | openCallBack->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName); 295 | if (setSubArchiveName) { 296 | setSubArchiveName->SetSubArchiveName(path.c_str()); 297 | } 298 | 299 | FAIL_RET(GetFilePathExt(path, extension), pResult); 300 | } while(true); 301 | 302 | if (archive == NULL) 303 | return S_FALSE; 304 | 305 | return Create7ZipArchive(pLibrary, archives, archive, ppArchive) ? S_OK : S_FALSE; 306 | } 307 | -------------------------------------------------------------------------------- /src/7ZipArchive.cpp: -------------------------------------------------------------------------------- 1 | #ifdef S_OK 2 | #undef S_OK 3 | #endif 4 | 5 | #if !defined(_WIN32) && !defined(_OS2) 6 | #include "CPP/myWindows/StdAfx.h" 7 | #include "CPP/include_windows/windows.h" 8 | #endif 9 | 10 | #include "CPP/7zip/Archive/IArchive.h" 11 | #include "CPP/7zip/MyVersion.h" 12 | #include "CPP/Windows/PropVariant.h" 13 | #include "CPP/Common/MyCom.h" 14 | #include "CPP/7zip/ICoder.h" 15 | #include "CPP/7zip/IPassword.h" 16 | #include "CPP/7zip/Common/FileStreams.h" 17 | 18 | #include "lib7zip.h" 19 | 20 | #include "HelperFuncs.h" 21 | 22 | extern bool Create7ZipArchiveItem(C7ZipArchive * pArchive, 23 | IInArchive * pInArchive, 24 | unsigned int nIndex, 25 | C7ZipArchiveItem ** ppItem); 26 | 27 | class C7ZipOutStreamWrap: 28 | public IOutStream, 29 | public CMyUnknownImp 30 | { 31 | public: 32 | C7ZipOutStreamWrap(C7ZipOutStream * pOutStream) : m_pOutStream(pOutStream) {} 33 | virtual ~C7ZipOutStreamWrap() {} 34 | 35 | public: 36 | MY_UNKNOWN_IMP1(IOutStream) 37 | 38 | STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) 39 | { 40 | return m_pOutStream->Seek(offset, seekOrigin, newPosition); 41 | } 42 | 43 | #if MY_VER_MAJOR > 9 || (MY_VER_MAJOR == 9 && MY_VER_MINOR>=20) 44 | STDMETHOD(SetSize)(UInt64 newSize) 45 | #else 46 | STDMETHOD(SetSize)(Int64 newSize) 47 | #endif 48 | { 49 | return m_pOutStream->SetSize(newSize); 50 | } 51 | 52 | STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) 53 | { 54 | return m_pOutStream->Write(data, size, processedSize); 55 | } 56 | 57 | private: 58 | C7ZipOutStream * m_pOutStream; 59 | }; 60 | 61 | class CArchiveExtractCallback: 62 | public IArchiveExtractCallback, 63 | public ICryptoGetTextPassword, 64 | public CMyUnknownImp 65 | { 66 | public: 67 | MY_UNKNOWN_IMP1(ICryptoGetTextPassword) 68 | 69 | // IProgress 70 | STDMETHOD(SetTotal)(UInt64 size); 71 | STDMETHOD(SetCompleted)(const UInt64 *completeValue); 72 | 73 | // IArchiveExtractCallback 74 | STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode); 75 | STDMETHOD(PrepareOperation)(Int32 askExtractMode); 76 | STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); 77 | 78 | // ICryptoGetTextPassword 79 | STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword); 80 | 81 | virtual bool SetFileSymLinkAttrib() { 82 | return false; 83 | } 84 | 85 | private: 86 | C7ZipOutStreamWrap * _outFileStreamSpec; 87 | CMyComPtr _outFileStream; 88 | 89 | C7ZipOutStream * m_pOutStream; 90 | const C7ZipArchive * m_pArchive; 91 | const C7ZipArchiveItem * m_pItem; 92 | public: 93 | CArchiveExtractCallback(C7ZipOutStream * pOutStream,const C7ZipArchive * pArchive,const C7ZipArchiveItem * pItem) : 94 | m_pOutStream(pOutStream), 95 | m_pArchive(pArchive), 96 | m_pItem(pItem) 97 | { 98 | } 99 | }; 100 | 101 | class C7ZipArchiveImpl : public virtual C7ZipArchive 102 | { 103 | public: 104 | C7ZipArchiveImpl(C7ZipLibrary * pLibrary, IInArchive * pInArchive, 105 | const std::vector> & archives 106 | ); 107 | virtual ~C7ZipArchiveImpl(); 108 | 109 | public: 110 | virtual bool GetItemCount(unsigned int * pNumItems); 111 | virtual bool GetItemInfo(unsigned int index, C7ZipArchiveItem ** ppArchiveItem); 112 | virtual bool Extract(unsigned int index, C7ZipOutStream * pOutStream); 113 | virtual bool Extract(unsigned int index, C7ZipOutStream * pOutStream, const wstring & pwd); 114 | virtual bool Extract(const C7ZipArchiveItem * pArchiveItem, C7ZipOutStream * pOutStream); 115 | 116 | virtual void Close(); 117 | 118 | virtual bool Initialize(); 119 | 120 | virtual wstring GetArchivePassword() const; 121 | virtual void SetArchivePassword(const wstring & password); 122 | virtual bool IsPasswordSet() const; 123 | 124 | virtual bool GetUInt64Property(lib7zip::PropertyIndexEnum propertyIndex, 125 | unsigned __int64 & val) const; 126 | virtual bool GetBoolProperty(lib7zip::PropertyIndexEnum propertyIndex, 127 | bool & val) const; 128 | virtual bool GetStringProperty(lib7zip::PropertyIndexEnum propertyIndex, 129 | wstring & val) const; 130 | virtual bool GetFileTimeProperty(lib7zip::PropertyIndexEnum propertyIndex, 131 | unsigned __int64 & val) const; 132 | private: 133 | CMyComPtr m_pInArchive; 134 | C7ZipObjectPtrArray m_ArchiveItems; 135 | wstring m_Password; 136 | std::vector> m_Archives; 137 | }; 138 | 139 | C7ZipArchiveImpl::C7ZipArchiveImpl(C7ZipLibrary * pLibrary, IInArchive * pInArchive, 140 | const std::vector> & archives 141 | ) 142 | : m_pInArchive(pInArchive) 143 | , m_Archives(archives) 144 | { 145 | } 146 | 147 | C7ZipArchiveImpl::~C7ZipArchiveImpl() 148 | { 149 | m_pInArchive.Release(); 150 | 151 | for(auto archive : m_Archives) { 152 | archive.Release(); 153 | } 154 | } 155 | 156 | bool C7ZipArchiveImpl::GetItemCount(unsigned int * pNumItems) 157 | { 158 | *pNumItems = (unsigned int)m_ArchiveItems.size(); 159 | 160 | return true; 161 | } 162 | 163 | bool C7ZipArchiveImpl::GetItemInfo(unsigned int index, C7ZipArchiveItem ** ppArchiveItem) 164 | { 165 | if (index < m_ArchiveItems.size()) 166 | { 167 | *ppArchiveItem = dynamic_cast(m_ArchiveItems[(int)index]); 168 | 169 | return true; 170 | } 171 | 172 | *ppArchiveItem = NULL; 173 | return false; 174 | } 175 | 176 | bool C7ZipArchiveImpl::Extract(unsigned int index, C7ZipOutStream * pOutStream) 177 | { 178 | if (index < m_ArchiveItems.size()) 179 | { 180 | return Extract(dynamic_cast(m_ArchiveItems[(int)index]), pOutStream); 181 | } 182 | 183 | return false; 184 | } 185 | 186 | bool C7ZipArchiveImpl::Extract(unsigned int index, C7ZipOutStream * pOutStream, const wstring & pwd) 187 | { 188 | if (index < m_ArchiveItems.size()) 189 | { 190 | C7ZipArchiveItem * pItem = dynamic_cast(m_ArchiveItems[(int)index]); 191 | pItem->SetArchiveItemPassword(pwd); 192 | 193 | return Extract(pItem, pOutStream); 194 | } 195 | 196 | return false; 197 | } 198 | 199 | bool C7ZipArchiveImpl::Extract(const C7ZipArchiveItem * pArchiveItem, C7ZipOutStream * pOutStream) 200 | { 201 | CArchiveExtractCallback *extractCallbackSpec = 202 | new CArchiveExtractCallback(pOutStream, this, pArchiveItem); 203 | CMyComPtr extractCallback(extractCallbackSpec); 204 | 205 | UInt32 nArchiveIndex = pArchiveItem->GetArchiveIndex(); 206 | 207 | return m_pInArchive->Extract(&nArchiveIndex, 1, false, extractCallbackSpec) == S_OK; 208 | } 209 | 210 | void C7ZipArchiveImpl::Close() 211 | { 212 | m_pInArchive->Close(); 213 | } 214 | 215 | bool C7ZipArchiveImpl::Initialize() 216 | { 217 | UInt32 numItems = 0; 218 | 219 | RBOOLOK(m_pInArchive->GetNumberOfItems(&numItems)); 220 | 221 | for(UInt32 i = 0; i < numItems; i++) 222 | { 223 | C7ZipArchiveItem * pItem = NULL; 224 | 225 | if (Create7ZipArchiveItem(this, m_pInArchive, i, &pItem)) 226 | { 227 | m_ArchiveItems.push_back(pItem); 228 | } 229 | } 230 | 231 | return true; 232 | } 233 | 234 | wstring C7ZipArchiveImpl::GetArchivePassword() const 235 | { 236 | return m_Password; 237 | } 238 | 239 | void C7ZipArchiveImpl::SetArchivePassword(const wstring & password) 240 | { 241 | m_Password = password; 242 | } 243 | 244 | bool C7ZipArchiveImpl::IsPasswordSet() const 245 | { 246 | return !(m_Password == L""); 247 | } 248 | 249 | bool Create7ZipArchive(C7ZipLibrary * pLibrary, 250 | const std::vector> & archives, 251 | IInArchive * pInArchive, C7ZipArchive ** ppArchive) 252 | { 253 | C7ZipArchiveImpl * pArchive = new C7ZipArchiveImpl(pLibrary, pInArchive, archives); 254 | 255 | if (pArchive->Initialize()) 256 | { 257 | *ppArchive = pArchive; 258 | 259 | return true; 260 | } 261 | 262 | delete pArchive; 263 | *ppArchive = NULL; 264 | 265 | return false; 266 | } 267 | 268 | STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */) 269 | { 270 | return S_OK; 271 | } 272 | 273 | STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */) 274 | { 275 | return S_OK; 276 | } 277 | 278 | STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, 279 | ISequentialOutStream **outStream, Int32 askExtractMode) 280 | { 281 | if (askExtractMode != NArchive::NExtract::NAskMode::kExtract) 282 | return S_OK; 283 | 284 | 285 | _outFileStreamSpec = new C7ZipOutStreamWrap(m_pOutStream); 286 | CMyComPtr outStreamLoc(_outFileStreamSpec); 287 | 288 | _outFileStream = outStreamLoc; 289 | *outStream = outStreamLoc.Detach(); 290 | return S_OK; 291 | } 292 | 293 | STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) 294 | { 295 | return S_OK; 296 | } 297 | 298 | STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) 299 | { 300 | switch(operationResult) 301 | { 302 | case NArchive::NExtract::NOperationResult::kOK: 303 | break; 304 | default: 305 | { 306 | switch(operationResult) 307 | { 308 | default: 309 | break; 310 | } 311 | } 312 | } 313 | 314 | _outFileStream.Release(); 315 | 316 | return S_OK; 317 | } 318 | 319 | 320 | STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) 321 | { 322 | wstring strPassword(L""); 323 | 324 | if (m_pItem->IsPasswordSet()) 325 | strPassword = m_pItem->GetArchiveItemPassword(); 326 | else if (m_pArchive->IsPasswordSet()) 327 | strPassword = m_pArchive->GetArchivePassword(); 328 | 329 | #ifdef _WIN32 330 | return StringToBstr(strPassword.c_str(), password); 331 | #else 332 | *password = ::SysAllocString(strPassword.c_str()); 333 | 334 | return S_OK; 335 | #endif 336 | } 337 | 338 | bool C7ZipArchiveImpl::GetUInt64Property(lib7zip::PropertyIndexEnum propertyIndex, 339 | unsigned __int64 & val) const 340 | { 341 | int p7zip_index = 0; 342 | 343 | switch(propertyIndex) { 344 | case lib7zip::kpidSize: 345 | p7zip_index = kpidSize; 346 | break; 347 | case lib7zip::kpidPackSize: //(Packed Size) 348 | p7zip_index = kpidPackSize; 349 | break; 350 | case lib7zip::kpidAttrib: //(Attributes) 351 | p7zip_index = kpidAttrib; 352 | break; 353 | case lib7zip::kpidPhySize: //(Physical Size) 354 | p7zip_index = kpidPhySize; 355 | break; 356 | case lib7zip::kpidHeadersSize: //(Headers Size) 357 | p7zip_index = kpidHeadersSize; 358 | break; 359 | case lib7zip::kpidChecksum: //(Checksum) 360 | p7zip_index = kpidChecksum; 361 | break; 362 | case lib7zip::kpidTotalSize: //(Total Size) 363 | p7zip_index = kpidTotalSize; 364 | break; 365 | case lib7zip::kpidFreeSpace: //(Free Space) 366 | p7zip_index = kpidFreeSpace; 367 | break; 368 | case lib7zip::kpidClusterSize: //(Cluster Size) 369 | p7zip_index = kpidClusterSize; 370 | break; 371 | default: 372 | return false; 373 | } 374 | 375 | NWindows::NCOM::CPropVariant prop; 376 | 377 | if (m_pInArchive->GetArchiveProperty(p7zip_index, &prop) != 0) 378 | return false; 379 | 380 | if (prop.vt == VT_UI8 || prop.vt == VT_UI4) { 381 | val = ConvertPropVariantToUInt64(prop); 382 | return true; 383 | } 384 | 385 | return false; 386 | } 387 | 388 | bool C7ZipArchiveImpl::GetBoolProperty(lib7zip::PropertyIndexEnum propertyIndex, 389 | bool & val) const 390 | { 391 | int p7zip_index = 0; 392 | 393 | switch(propertyIndex) { 394 | case lib7zip::kpidSolid: //(Solid) 395 | p7zip_index = kpidSolid; 396 | break; 397 | case lib7zip::kpidEncrypted: //(Encrypted) 398 | p7zip_index = kpidEncrypted; 399 | break; 400 | default: 401 | return false; 402 | } 403 | 404 | NWindows::NCOM::CPropVariant prop; 405 | 406 | if (m_pInArchive->GetArchiveProperty(p7zip_index, &prop) == 0 && 407 | prop.vt == VT_BOOL) { 408 | val = prop.bVal; 409 | return true; 410 | } 411 | 412 | return false; 413 | } 414 | 415 | bool C7ZipArchiveImpl::GetStringProperty(lib7zip::PropertyIndexEnum propertyIndex, 416 | wstring & val) const 417 | { 418 | int p7zip_index = 0; 419 | 420 | switch(propertyIndex) { 421 | case lib7zip::kpidComment: //(Comment) 422 | p7zip_index = kpidComment; 423 | break; 424 | case lib7zip::kpidCharacts: //(Characteristics) 425 | p7zip_index = kpidCharacts; 426 | break; 427 | case lib7zip::kpidCreatorApp: //(Creator Application) 428 | p7zip_index = kpidCreatorApp; 429 | break; 430 | case lib7zip::kpidVolumeName: //(Label) 431 | p7zip_index = kpidVolumeName; 432 | break; 433 | case lib7zip::kpidPath: //(FullPath) 434 | p7zip_index = kpidPath; 435 | break; 436 | case lib7zip::kpidUser: //(User) 437 | p7zip_index = kpidUser; 438 | break; 439 | case lib7zip::kpidGroup: //(Group) 440 | p7zip_index = kpidGroup; 441 | break; 442 | default: 443 | return false; 444 | } 445 | 446 | NWindows::NCOM::CPropVariant prop; 447 | 448 | if (!m_pInArchive->GetArchiveProperty(p7zip_index, &prop) && 449 | prop.vt == VT_BSTR) { 450 | val = prop.bstrVal; 451 | return true; 452 | } 453 | 454 | return false; 455 | } 456 | 457 | bool C7ZipArchiveImpl::GetFileTimeProperty(lib7zip::PropertyIndexEnum propertyIndex, 458 | unsigned __int64 & val) const 459 | { 460 | int p7zip_index = 0; 461 | 462 | switch(propertyIndex) { 463 | case lib7zip::kpidCTime: //(Created) 464 | p7zip_index = kpidCTime; 465 | break; 466 | case lib7zip::kpidATime: //(Accessed) 467 | p7zip_index = kpidATime; 468 | break; 469 | case lib7zip::kpidMTime: //(Modified) 470 | p7zip_index = kpidMTime; 471 | break; 472 | default: 473 | return false; 474 | } 475 | 476 | NWindows::NCOM::CPropVariant prop; 477 | 478 | if (m_pInArchive->GetArchiveProperty(p7zip_index, &prop) != 0) 479 | return false; 480 | 481 | if (prop.vt == VT_FILETIME) { 482 | unsigned __int64 tmp_val = 0; 483 | memmove(&tmp_val, &prop.filetime, sizeof(unsigned __int64)); 484 | val = tmp_val; 485 | return true; 486 | } 487 | 488 | return false; 489 | } 490 | 491 | /*------------------- C7ZipArchive -----------*/ 492 | C7ZipArchive::C7ZipArchive() 493 | { 494 | } 495 | 496 | C7ZipArchive::~C7ZipArchive() 497 | { 498 | } 499 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | 374 | defined by the Mozilla Public License, v. 2.0. 375 | --------------------------------------------------------------------------------