├── .github └── workflows │ ├── ci.yml │ └── codeql.yml ├── .mailmap ├── .travis.yml ├── CHANGELOG ├── CMakeLists.txt ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── VERSION ├── cmake ├── BuildType.cmake ├── CXXVersionCheck.cmake ├── CompileCheck.cmake ├── CreateSourceGroups.cmake ├── Doxygen.cmake ├── FilterList.cmake ├── FindLZMA.cmake ├── Findiconv.cmake ├── PrintConfiguration.cmake ├── StyleCheck.cmake ├── UseStaticLibs.cmake ├── VersionScript.cmake ├── VersionString.cmake ├── check │ ├── cxx11-alignof.cpp │ ├── cxx11-std-codecvt_utf8_utf16.cpp │ └── cxx11-std-unique_ptr.cpp └── cpplint.py ├── doc ├── Doxyfile.in ├── innoextract.1.in └── update-copyright-years └── src ├── cli ├── debug.cpp ├── debug.hpp ├── extract.cpp ├── extract.hpp ├── gog.cpp ├── gog.hpp ├── goggalaxy.cpp ├── goggalaxy.hpp └── main.cpp ├── configure.hpp.in ├── crypto ├── adler32.cpp ├── adler32.hpp ├── arc4.cpp ├── arc4.hpp ├── checksum.cpp ├── checksum.hpp ├── crc32.cpp ├── crc32.hpp ├── hasher.cpp ├── hasher.hpp ├── iteratedhash.hpp ├── md5.cpp ├── md5.hpp ├── pbkdf2.cpp ├── pbkdf2.hpp ├── sha1.cpp ├── sha1.hpp ├── sha256.cpp ├── sha256.hpp ├── xchacha20.cpp └── xchacha20.hpp ├── index.hpp ├── loader ├── exereader.cpp ├── exereader.hpp ├── offsets.cpp └── offsets.hpp ├── release.cpp.in ├── release.hpp ├── setup ├── component.cpp ├── component.hpp ├── data.cpp ├── data.hpp ├── delete.cpp ├── delete.hpp ├── directory.cpp ├── directory.hpp ├── expression.cpp ├── expression.hpp ├── file.cpp ├── file.hpp ├── filename.cpp ├── filename.hpp ├── header.cpp ├── header.hpp ├── icon.cpp ├── icon.hpp ├── info.cpp ├── info.hpp ├── ini.cpp ├── ini.hpp ├── item.cpp ├── item.hpp ├── language.cpp ├── language.hpp ├── message.cpp ├── message.hpp ├── permission.cpp ├── permission.hpp ├── registry.cpp ├── registry.hpp ├── run.cpp ├── run.hpp ├── task.cpp ├── task.hpp ├── type.cpp ├── type.hpp ├── version.cpp ├── version.hpp ├── windows.cpp └── windows.hpp ├── stream ├── block.cpp ├── block.hpp ├── checksum.hpp ├── chunk.cpp ├── chunk.hpp ├── exefilter.hpp ├── file.cpp ├── file.hpp ├── lzma.cpp ├── lzma.hpp ├── restrict.hpp ├── slice.cpp └── slice.hpp └── util ├── align.hpp ├── ansi.hpp ├── boostfs_compat.hpp ├── console.cpp ├── console.hpp ├── encoding.cpp ├── encoding.hpp ├── endian.hpp ├── enum.hpp ├── flags.hpp ├── fstream.hpp ├── load.cpp ├── load.hpp ├── log.cpp ├── log.hpp ├── math.hpp ├── output.hpp ├── process.cpp ├── process.hpp ├── storedenum.hpp ├── test.cpp ├── test.hpp ├── time.cpp ├── time.hpp ├── types.hpp ├── unique_ptr.hpp ├── windows.cpp └── windows.hpp /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | schedule: 9 | - cron: '21 11 * * 5' 10 | 11 | jobs: 12 | 13 | linux: 14 | name: Linux build 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: Update 21 | run: sudo apt-get update 22 | 23 | - name: Dependencies 24 | run: sudo apt-get install build-essential cmake libboost-all-dev liblzma-dev 25 | 26 | - name: Configure 27 | run: cmake --version && cmake -B ${{github.workspace}}/build -Werror=dev -Werror=deprecated -DCONTINUOUS_INTEGRATION=1 28 | 29 | - name: Build 30 | run: cmake --build ${{github.workspace}}/build 31 | 32 | - name: Check Style 33 | run: cmake --build ${{github.workspace}}/build --target style 34 | 35 | macos: 36 | name: macOS build 37 | runs-on: macos-latest 38 | 39 | steps: 40 | - uses: actions/checkout@v4 41 | 42 | - name: Update 43 | run: brew update 44 | 45 | - name: Workaround for Python install isssues - https://github.com/actions/runner-images/issues/8838 46 | run: brew install python@3 || brew link --overwrite python@3 47 | 48 | - name: Dependencies 49 | env: 50 | HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 51 | run: brew install boost xz 52 | 53 | - name: Configure 54 | run: cmake --version && cmake -B ${{github.workspace}}/build -Werror=dev -Werror=deprecated -DCONTINUOUS_INTEGRATION=1 55 | 56 | - name: Build 57 | run: cmake --build ${{github.workspace}}/build 58 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL 2 | 3 | on: 4 | schedule: 5 | - cron: '21 11 * * 5' 6 | 7 | jobs: 8 | 9 | cpp: 10 | name: C++ analysis 11 | runs-on: ubuntu-latest 12 | permissions: 13 | actions: read 14 | contents: read 15 | security-events: write 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4 20 | 21 | - name: Update 22 | run: sudo apt-get update 23 | 24 | - name: Dependencies 25 | run: sudo apt-get install build-essential cmake libboost-all-dev liblzma-dev 26 | 27 | - name: Initialize CodeQL 28 | uses: github/codeql-action/init@v3 29 | with: 30 | languages: cpp 31 | 32 | - name: Configure 33 | run: cmake -B ${{github.workspace}}/build 34 | 35 | - name: Build 36 | run: cmake --build ${{github.workspace}}/build 37 | 38 | - name: Perform CodeQL Analysis 39 | uses: github/codeql-action/analyze@v3 40 | 41 | python: 42 | name: Python analysis 43 | runs-on: ubuntu-latest 44 | permissions: 45 | actions: read 46 | contents: read 47 | security-events: write 48 | 49 | steps: 50 | - name: Checkout repository 51 | uses: actions/checkout@v4 52 | 53 | - name: Initialize CodeQL 54 | uses: github/codeql-action/init@v3 55 | with: 56 | languages: python 57 | 58 | - name: Perform CodeQL Analysis 59 | uses: github/codeql-action/analyze@v3 60 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | # 2 | # This list is used by git-shortlog to fix a few botched name translations 3 | # in the git archive, either because the author's full name was messed up 4 | # and/or not always written the same way, making contributions from the 5 | # same person appearing not to be so. 6 | # 7 | 8 | Daniel Scharrer 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | matrix: 3 | include: 4 | - os: linux 5 | sudo: required 6 | compiler: gcc 7 | - os: osx 8 | compiler: clang 9 | addons: 10 | apt: 11 | packages: 12 | - build-essential 13 | - cmake 14 | - libboost-all-dev 15 | - liblzma-dev 16 | before_install: 17 | - if [ "$TRAVIS_OS_NAME" = osx ] ; then brew update ; fi 18 | - if [ "$TRAVIS_OS_NAME" = osx ] ; then brew unlink python@2 ; fi 19 | - if [ "$TRAVIS_OS_NAME" = osx ] ; then brew upgrade cmake boost ; fi 20 | - if [ "$TRAVIS_OS_NAME" = osx ] ; then brew install xz ; fi 21 | script: 22 | - mkdir build 23 | - cd build 24 | - cmake --version 25 | - cmake .. -Werror=dev -Werror=deprecated -DCONTINUOUS_INTEGRATION=1 26 | - make -j1 27 | branches: 28 | only: 29 | - master 30 | notifications: 31 | email: 32 | recipients: 33 | - daniel@constexpr.org 34 | on_success: change 35 | on_failure: always 36 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | Contributions of all kinds are welcome as [GitHub pull requests](https://github.com/dscharrer/innoextract/pulls) or as patches mailed to daniel@constexpr.org. 3 | 4 | If you are planning to implement a larger feature and intend to get it merged, please contact me **first** at daniel@constexpr.org or on the [GitHub issue tracker](https://github.com/dscharrer/innoextract/issues) to discuss the planned changes in order to avoid duplicating work or having to re-do the changes in a way that fits with the project. 5 | 6 | There is no official code style guide, but please try to match the style of the existing code and git commit messages. 7 | 8 | All contributions must be licensed under the zlib license detailed in the LICENSE file. 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (C) 2011-2020 Daniel Scharrer 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the author(s) be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | innoextract 1.10-dev 2 | 3 | Known working Inno Setup versions: 4 | Inno Setup 1.2.10 to 6.3.3 5 | 6 | Bug tracker: 7 | https://innoextract.constexpr.org/issues 8 | -------------------------------------------------------------------------------- /cmake/CreateSourceGroups.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Accepts a variable holding the source files 3 | # and creates source groups (for VS, Xcode etc) 4 | # that replicate the folder hierarchy on disk 5 | function(create_source_groups source_files_variable) 6 | foreach(source_file ${${source_files_variable}}) 7 | string( REPLACE ${CMAKE_CURRENT_SOURCE_DIR} "" relative_directory "${source_file}") 8 | string( REGEX REPLACE "[\\\\/][^\\\\/]*$" "" relative_directory "${relative_directory}") 9 | string( REGEX REPLACE "^[\\\\/]" "" relative_directory "${relative_directory}") 10 | if( WIN32 ) 11 | string( REGEX REPLACE "/" "\\\\" relative_directory "${relative_directory}" ) 12 | endif( WIN32 ) 13 | source_group( "${relative_directory}" FILES ${source_file} ) 14 | endforeach() 15 | endfunction() 16 | -------------------------------------------------------------------------------- /cmake/Doxygen.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (C) 2011-2017 Daniel Scharrer 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the author(s) be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | 20 | find_package(Doxygen) 21 | 22 | include(VersionString) 23 | 24 | # Add a target that runs Doxygen on a configured Doxyfile 25 | # 26 | # Parameters: 27 | # - TARGET_NAME the name of the target to add 28 | # - DOXYFILE_IN the raw Doxyfile 29 | # - VERSION_FILE VERSION file to be used by version_file() 30 | # - GIT_DIR .git directory to be used by version_file() 31 | # - OUT_DIR Doxygen output directory 32 | # 33 | # For the exact syntax of config options in DOXYFILE_IN see the documentation of the 34 | # configure_file() cmake command. 35 | # 36 | # Available variables are those provided by version_file() as well as 37 | # DOXYGEN_OUTPUT_DIR, which is set to OUT_DIR. 38 | # 39 | function(add_doxygen_target TARGET_NAME DOXYFILE_IN VERSION_FILE GIT_DIR OUT_DIR) 40 | 41 | if(NOT DOXYGEN_EXECUTABLE) 42 | return() 43 | endif() 44 | 45 | set(doxyfile "${PROJECT_BINARY_DIR}/Doxyfile.${TARGET_NAME}") 46 | set(defines "-DDOXYGEN_OUTPUT_DIR=${OUT_DIR}") 47 | 48 | version_file("${DOXYFILE_IN}" "${doxyfile}" "${VERSION_FILE}" "${GIT_DIR}" "${defines}") 49 | 50 | add_custom_target(${TARGET_NAME} 51 | COMMAND "${CMAKE_COMMAND}" -E make_directory "${OUT_DIR}" 52 | COMMAND ${DOXYGEN_EXECUTABLE} "${doxyfile}" 53 | DEPENDS "${doxyfile}" 54 | WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" 55 | COMMENT "Building doxygen documentation." 56 | VERBATIM 57 | SOURCES "${DOXYFILE_IN}" 58 | ) 59 | 60 | endfunction(add_doxygen_target) 61 | -------------------------------------------------------------------------------- /cmake/FilterList.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (C) 2013-2016 Daniel Scharrer 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the author(s) be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | 20 | # Filter a list with conditional ites 21 | # 22 | # Supported syntax: 23 | # 24 | # item 25 | # 26 | # item if CONDITION_VARIABLE 27 | # 28 | # CONDITION_VARIABLE { 29 | # item1 30 | # item2 31 | # } 32 | # 33 | # Conditions cannot be nested. 34 | # 35 | # The list specified by LIST_NAM Ewill be modifed in place. 36 | # An optional second parameter can be given to specify the name of a list that 37 | # should receive all items, even those whose conditions evaluated to false, 38 | # but not syntactic elements such as 'if', '{', '}' and condition variables. 39 | # 40 | function(filter_list LIST_NAME) 41 | 42 | set(TOKEN_IF "if") 43 | set(TOKEN_GROUP_BEGIN "{") 44 | set(TOKEN_GROUP_END "}") 45 | 46 | set(filtered) 47 | set(all) 48 | 49 | # the item from the previous iteration 50 | set(last_item "") 51 | 52 | # current syntax state: 53 | # 0 - start 54 | # 1 - after 'if', expected condition variable 55 | # 2 - inside block (true) 56 | # 3 - inside block (false) 57 | set(mode 0) 58 | 59 | foreach(item IN LISTS ${LIST_NAME}) 60 | 61 | if(mode EQUAL 1) 62 | 63 | # Handle condition variables 64 | set(condition ${${item}}) 65 | if(condition) 66 | list(APPEND filtered ${last_item}) 67 | endif() 68 | set(mode 0) 69 | set(last_item "") 70 | 71 | elseif(item STREQUAL TOKEN_IF) 72 | 73 | if(NOT mode EQUAL 0) 74 | message(FATAL_ERROR "bad filter_list syntax: IF inside { } block is forbidden") 75 | endif() 76 | 77 | # Handle condition start 78 | if(last_item STREQUAL "") 79 | message(FATAL_ERROR "bad filter_list syntax: IF without preceding item") 80 | endif() 81 | set(mode 1) 82 | 83 | elseif(item STREQUAL TOKEN_GROUP_BEGIN) 84 | 85 | if(NOT mode EQUAL 0) 86 | message(FATAL_ERROR "bad filter_list syntax: cannot nest { } blocks") 87 | endif() 88 | 89 | if(last_item STREQUAL "") 90 | message(FATAL_ERROR "bad filter_list syntax: { without preceding item") 91 | endif() 92 | 93 | set(condition ${${last_item}}) 94 | if(condition) 95 | set(mode 2) 96 | else() 97 | set(mode 3) 98 | endif() 99 | set(last_item "") 100 | 101 | else() 102 | 103 | # Handle unconditional items 104 | if(NOT last_item STREQUAL "" AND NOT mode EQUAL 3) 105 | list(APPEND filtered ${last_item}) 106 | endif() 107 | 108 | if(item STREQUAL TOKEN_GROUP_END) 109 | 110 | if(mode EQUAL 0) 111 | message(FATAL_ERROR "bad filter_list syntax: } without open block") 112 | endif() 113 | 114 | set(mode 0) 115 | set(last_item) 116 | 117 | else() 118 | 119 | list(APPEND all ${item}) 120 | set(last_item ${item}) 121 | 122 | endif() 123 | 124 | endif() 125 | 126 | endforeach() 127 | 128 | if(mode EQUAL 1) 129 | message(FATAL_ERROR "bad filter_list syntax: unexpected end, expected condition") 130 | elseif(mode EQUAL 2 OR mode EQUAL 3) 131 | message(FATAL_ERROR "bad filter_list syntax: unexpected end, expected }") 132 | endif() 133 | 134 | if(last_item) 135 | list(APPEND filtered ${last_item}) 136 | endif() 137 | 138 | list(SORT filtered) 139 | list(REMOVE_DUPLICATES filtered) 140 | set(${LIST_NAME} ${filtered} PARENT_SCOPE) 141 | 142 | if(ARGC GREATER 1) 143 | list(SORT all) 144 | list(REMOVE_DUPLICATES all) 145 | set(${ARGV1} ${all} PARENT_SCOPE) 146 | endif() 147 | 148 | endfunction() 149 | -------------------------------------------------------------------------------- /cmake/FindLZMA.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (C) 2011-2019 Daniel Scharrer 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the author(s) be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | 20 | # Try to find the LZMA library and include path for lzma.h from xz-utils. 21 | # Once done this will define 22 | # 23 | # LZMA_FOUND 24 | # LZMA_INCLUDE_DIR Where to find lzma.h 25 | # LZMA_LIBRARIES The liblzma library 26 | # LZMA_DEFINITIONS Definitions to use when compiling code that uses liblzma 27 | # 28 | # Typical usage could be something like: 29 | # find_package(LZMA REQUIRED) 30 | # include_directories(SYSTEM ${LZMA_INCLUDE_DIR}) 31 | # add_definitions(${LZMA_DEFINITIONS}) 32 | # ... 33 | # target_link_libraries(myexe ${LZMA_LIBRARIES}) 34 | # 35 | # The following additional options can be defined before the find_package() call: 36 | # LZMA_USE_STATIC_LIBS Statically link against liblzma (default: OFF) 37 | 38 | if(UNIX) 39 | find_package(PkgConfig QUIET) 40 | pkg_check_modules(_PC_LZMA liblzma) 41 | endif() 42 | 43 | include(UseStaticLibs) 44 | 45 | foreach(static IN ITEMS 1 0) 46 | 47 | if(static) 48 | use_static_libs(LZMA _PC_LZMA) 49 | endif() 50 | 51 | find_path(LZMA_INCLUDE_DIR lzma.h 52 | HINTS 53 | ${_PC_LZMA_INCLUDE_DIRS} 54 | DOC "The directory where lzma.h resides" 55 | ) 56 | mark_as_advanced(LZMA_INCLUDE_DIR) 57 | 58 | # Prefer libraries in the same prefix as the include files 59 | string(REGEX REPLACE "(.*)/include/?" "\\1" LZMA_BASE_DIR ${LZMA_INCLUDE_DIR}) 60 | 61 | find_library(LZMA_LIBRARY lzma liblzma 62 | PATHS 63 | ${_PC_LZMA_LIBRARY_DIRS} 64 | "${LZMA_BASE_DIR}/lib" 65 | DOC "The LZMA library" 66 | ) 67 | mark_as_advanced(LZMA_LIBRARY) 68 | 69 | if(static) 70 | use_static_libs_restore() 71 | endif() 72 | 73 | if(LZMA_LIBRARY OR STRICT_USE) 74 | break() 75 | endif() 76 | 77 | endforeach() 78 | 79 | set(LZMA_DEFINITIONS) 80 | if(WIN32 AND LZMA_USE_STATIC_LIBS) 81 | set(LZMA_DEFINITIONS -DLZMA_API_STATIC) 82 | endif() 83 | 84 | # handle the QUIETLY and REQUIRED arguments and set LZMA_FOUND to TRUE if 85 | # all listed variables are TRUE 86 | include(FindPackageHandleStandardArgs) 87 | find_package_handle_standard_args(LZMA DEFAULT_MSG LZMA_LIBRARY LZMA_INCLUDE_DIR) 88 | 89 | if(LZMA_FOUND) 90 | set(LZMA_LIBRARIES ${LZMA_LIBRARY}) 91 | endif(LZMA_FOUND) 92 | -------------------------------------------------------------------------------- /cmake/Findiconv.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (C) 2012-2019 Daniel Scharrer 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the author(s) be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | 20 | # Try to find the iconv library and include path for iconv.h. 21 | # Once done this will define 22 | # 23 | # ICONV_FOUND 24 | # iconv_INCLUDE_DIR Where to find iconv.h 25 | # iconv_LIBRARIES The libiconv library or empty if none was found 26 | # iconv_DEFINITIONS Definitions to use when compiling code that uses iconv 27 | # 28 | # An empty iconv_LIBRARIES is not an error as iconv is often included in the system libc. 29 | # 30 | # Typical usage could be something like: 31 | # find_package(iconv REQUIRED) 32 | # include_directories(SYSTEM ${iconv_INCLUDE_DIR}) 33 | # add_definitions(${iconv_DEFINITIONS}) 34 | # ... 35 | # target_link_libraries(myexe ${iconv_LIBRARIES}) 36 | # 37 | # The following additional options can be defined before the find_package() call: 38 | # iconv_USE_STATIC_LIBS Statically link against libiconv (default: OFF) 39 | 40 | include(UseStaticLibs) 41 | 42 | foreach(static IN ITEMS 1 0) 43 | 44 | if(static) 45 | use_static_libs(iconv) 46 | endif() 47 | 48 | if(APPLE) 49 | # Prefer local iconv.h location over the system iconv.h location as /opt/local/include 50 | # may be added to the include path by other libraries, resulting in the #include 51 | # statements finding the local copy while we will link agains the system lib. 52 | # This way we always find both include file and library in /opt/local/ if there is one. 53 | find_path(iconv_INCLUDE_DIR iconv.h 54 | PATHS /opt/local/include 55 | DOC "The directory where iconv.h resides" 56 | NO_CMAKE_SYSTEM_PATH 57 | ) 58 | endif(APPLE) 59 | 60 | find_path(iconv_INCLUDE_DIR iconv.h 61 | PATHS /opt/local/include 62 | DOC "The directory where iconv.h resides" 63 | ) 64 | mark_as_advanced(iconv_INCLUDE_DIR) 65 | 66 | # Prefer libraries in the same prefix as the include files 67 | string(REGEX REPLACE "(.*)/include/?" "\\1" iconv_BASE_DIR ${iconv_INCLUDE_DIR}) 68 | 69 | find_library(iconv_LIBRARY iconv libiconv 70 | HINTS "${iconv_BASE_DIR}/lib" 71 | PATHS /opt/local/lib 72 | DOC "The iconv library" 73 | ) 74 | mark_as_advanced(iconv_LIBRARY) 75 | 76 | if(static) 77 | use_static_libs_restore() 78 | endif() 79 | 80 | if(iconv_LIBRARY OR STRICT_USE) 81 | break() 82 | endif() 83 | 84 | endforeach() 85 | 86 | set(iconv_DEFINITIONS) 87 | if(WIN32 AND iconv_USE_STATIC_LIBS) 88 | set(iconv_DEFINITIONS -DLIBICONV_STATIC -DUSING_STATIC_LIBICONV) 89 | endif() 90 | 91 | # handle the QUIETLY and REQUIRED arguments and set iconv_FOUND to TRUE if 92 | # all listed variables are TRUE 93 | include(FindPackageHandleStandardArgs) 94 | find_package_handle_standard_args(iconv DEFAULT_MSG iconv_INCLUDE_DIR) 95 | 96 | # For some reason, find_package_... uppercases it's first argument. Nice! 97 | if(ICONV_FOUND) 98 | set(iconv_LIBRARIES) 99 | if(iconv_LIBRARY) 100 | list(APPEND iconv_LIBRARIES ${iconv_LIBRARY}) 101 | endif() 102 | endif(ICONV_FOUND) 103 | -------------------------------------------------------------------------------- /cmake/PrintConfiguration.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (C) 2013 Daniel Scharrer 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the author(s) be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | 20 | function(print_configuration TITLE) 21 | 22 | set(str "") 23 | 24 | set(print_first 0) 25 | 26 | set(mode 0) 27 | 28 | foreach(arg IN LISTS ARGN) 29 | 30 | if(arg STREQUAL "FIRST") 31 | set(print_first 1) 32 | else() 33 | 34 | if(mode EQUAL 0) 35 | 36 | if(${arg}) 37 | set(mode 1) 38 | else() 39 | set(mode 2) 40 | endif() 41 | 42 | else() 43 | 44 | if(mode EQUAL 1 AND NOT arg STREQUAL "") 45 | 46 | if(str STREQUAL "") 47 | set(str "${arg}") 48 | else() 49 | set(str "${str}, ${arg}") 50 | endif() 51 | 52 | if(print_first) 53 | break() 54 | endif() 55 | 56 | endif() 57 | 58 | set(mode 0) 59 | 60 | endif() 61 | 62 | endif() 63 | 64 | endforeach() 65 | 66 | if(str STREQUAL "") 67 | set(str "(none)") 68 | endif() 69 | 70 | message(" - ${TITLE}: ${str}") 71 | 72 | endfunction() 73 | -------------------------------------------------------------------------------- /cmake/StyleCheck.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (C) 2013-2018 Daniel Scharrer 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the author(s) be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | 20 | if(CMAKE_VERSION VERSION_LESS 3.12) 21 | find_package(PythonInterp) 22 | set(Python_Interpreter_FOUND ${PYTHONINTERP_FOUND}) 23 | set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) 24 | else() 25 | find_package(Python COMPONENTS Interpreter) 26 | endif() 27 | 28 | set(STYLE_FILTER) 29 | 30 | # Complains about any c-style cast -> too annoying. 31 | set(STYLE_FILTER ${STYLE_FILTER},-readability/casting) 32 | 33 | # Insists on including evrything in the .cpp file even if it is included in the header. 34 | set(STYLE_FILTER ${STYLE_FILTER},-build/include_what_you_use) 35 | 36 | # Too many false positives and not very helpful error messages. 37 | set(STYLE_FILTER ${STYLE_FILTER},-build/include_order) 38 | 39 | # No thanks. 40 | set(STYLE_FILTER ${STYLE_FILTER},-readability/streams) 41 | 42 | # Ugh! 43 | set(STYLE_FILTER ${STYLE_FILTER},-whitespace/tab) 44 | 45 | # Yes it is! 46 | set(STYLE_FILTER ${STYLE_FILTER},-whitespace/blank_line) 47 | 48 | # Suggessts excessive indentation. 49 | set(STYLE_FILTER ${STYLE_FILTER},-whitespace/labels) 50 | 51 | # Disallows brace on new line after long class memeber init list 52 | set(STYLE_FILTER ${STYLE_FILTER},-whitespace/braces) 53 | 54 | # Don't tell me how to name my variables. 55 | set(STYLE_FILTER ${STYLE_FILTER},-runtime/arrays) 56 | 57 | # Why? 58 | set(STYLE_FILTER ${STYLE_FILTER},-whitespace/todo) 59 | set(STYLE_FILTER ${STYLE_FILTER},-readability/todo) 60 | 61 | # Annoyting to use with boost::program_options 62 | set(STYLE_FILTER ${STYLE_FILTER},-whitespace/semicolon) 63 | 64 | get_filename_component(STYLE_CHECK_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 65 | set(STYLE_CHECK_SCRIPT "${STYLE_CHECK_DIR}/cpplint.py") 66 | 67 | # Add a target that runs cpplint.py 68 | # 69 | # Parameters: 70 | # - TARGET_NAME the name of the target to add 71 | # - SOURCES_LIST a complete list of source and include files to check 72 | function(add_style_check_target TARGET_NAME SOURCES_LIST PROJECT) 73 | 74 | if(NOT Python_Interpreter_FOUND) 75 | return() 76 | endif() 77 | 78 | list(SORT SOURCES_LIST) 79 | list(REMOVE_DUPLICATES SOURCES_LIST) 80 | 81 | add_custom_target(${TARGET_NAME} 82 | COMMAND "${CMAKE_COMMAND}" -E chdir 83 | "${PROJECT_SOURCE_DIR}" 84 | "${Python_EXECUTABLE}" 85 | "${STYLE_CHECK_SCRIPT}" 86 | "--filter=${STYLE_FILTER}" 87 | "--project=${PROJECT}" 88 | ${SOURCES_LIST} 89 | DEPENDS ${SOURCES_LIST} ${STYLE_CHECK_SCRIPT} 90 | COMMENT "Checking code style." 91 | VERBATIM 92 | ) 93 | 94 | endfunction(add_style_check_target) 95 | -------------------------------------------------------------------------------- /cmake/UseStaticLibs.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (C) 2013-2019 Daniel Scharrer 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the author(s) be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | 20 | macro(use_static_libs ID) 21 | if(${ID}_USE_STATIC_LIBS) 22 | set(_UseStaticLibs_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) 23 | if(WIN32) 24 | set(CMAKE_FIND_LIBRARY_SUFFIXES _a.lib .lib .a) 25 | else() 26 | set(CMAKE_FIND_LIBRARY_SUFFIXES .a) 27 | endif() 28 | if(ARGC GREATER 1) 29 | set(prefix "${ARGV1}") 30 | set(${prefix}_LIBRARIES "${${prefix}_STATIC_LIBRARIES}") 31 | set(${prefix}_LIBRARY_DIRS "${${prefix}_STATIC_LIBRARY_DIRS}") 32 | set(${prefix}_LDFLAGS "${${prefix}_STATIC_LDFLAGS}") 33 | set(${prefix}_LDFLAGS_OTHER "${${prefix}_STATIC_LDFLAGS_OTHER}") 34 | set(${prefix}_INCLUDE_DIRS "${${prefix}_STATIC_INCLUDE_DIRS}") 35 | set(${prefix}_CFLAGS "${${prefix}_STATIC_CFLAGS}") 36 | set(${prefix}_CFLAGS_OTHER "${${prefix}_STATIC_CFLAGS_OTHER}") 37 | endif() 38 | endif() 39 | endmacro() 40 | 41 | macro(use_static_libs_restore) 42 | if(DEFINED _UseStaticLibs_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) 43 | set(CMAKE_FIND_LIBRARY_SUFFIXES ${_UseStaticLibs_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) 44 | unset(_UseStaticLibs_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) 45 | endif() 46 | endmacro() 47 | 48 | macro(has_static_libs PREFIX LIBS) 49 | if(WIN32) 50 | # On Windows we can't really tell import libraries from proper static libraries. 51 | set(${PREFIX}_HAS_STATIC_LIBS ${${PREFIX}_USE_STATIC_LIBS}) 52 | else() 53 | set(${PREFIX}_HAS_STATIC_LIBS 0) 54 | foreach(lib IN LISTS ${LIBS}) 55 | if(TARGET ${lib}) 56 | get_target_property(target_type ${lib} TYPE) 57 | if(target_type STREQUAL STATIC_LIBRARY) 58 | set(${PREFIX}_HAS_STATIC_LIBS 1) 59 | break() 60 | endif() 61 | endif() 62 | if(lib MATCHES "\\.a$") 63 | set(${PREFIX}_HAS_STATIC_LIBS 1) 64 | break() 65 | endif() 66 | endforeach() 67 | endif() 68 | endmacro() 69 | -------------------------------------------------------------------------------- /cmake/VersionScript.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (C) 2011-2020 Daniel Scharrer 3 | # 4 | # This software is provided 'as-is', without any express or implied 5 | # warranty. In no event will the author(s) be held liable for any damages 6 | # arising from the use of this software. 7 | # 8 | # Permission is granted to anyone to use this software for any purpose, 9 | # including commercial applications, and to alter it and redistribute it 10 | # freely, subject to the following restrictions: 11 | # 12 | # 1. The origin of this software must not be misrepresented; you must not 13 | # claim that you wrote the original software. If you use this software 14 | # in a product, an acknowledgment in the product documentation would be 15 | # appreciated but is not required. 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 3. This notice may not be removed or altered from any source distribution. 19 | 20 | cmake_minimum_required(VERSION 2.8...3.19) 21 | 22 | # CMake script that reads a VERSION file and the current git history and the calls configure_file(). 23 | # This is used by version_file() in VersionString.cmake 24 | 25 | if((NOT DEFINED INPUT) OR (NOT DEFINED OUTPUT) OR (NOT DEFINED VERSION_SOURCES) OR (NOT DEFINED GIT_DIR)) 26 | message(SEND_ERROR "Invalid arguments.") 27 | endif() 28 | 29 | get_filename_component(VERSION_SCRIPT_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 30 | include("${VERSION_SCRIPT_DIR}/VersionString.cmake") 31 | 32 | # configure_file doesn't handle newlines correctly - pre-escape variables 33 | macro(_version_escape var string) 34 | # Escape the escape character and quotes 35 | string(REGEX REPLACE "([\\\\\"])" "\\\\\\1" ${var} "${string}") 36 | # Pull newlines out of string 37 | string(REGEX REPLACE "\n" "\\\\n\"\n\t\"" ${var} "${${var}}") 38 | endmacro() 39 | 40 | set(var "") 41 | foreach(arg IN LISTS VERSION_SOURCES) 42 | if(var STREQUAL "") 43 | set(var ${arg}) 44 | else() 45 | parse_version_file(${var} "${arg}" ON) 46 | set(var "") 47 | endif() 48 | endforeach() 49 | 50 | # Check for a git directory and fill in the git commit hash if one exists. 51 | unset(GIT_COMMIT) 52 | if(NOT GIT_DIR STREQUAL "") 53 | 54 | unset(git_head) 55 | 56 | if(GIT_COMMAND) 57 | execute_process( 58 | COMMAND "${GIT_COMMAND}" "--git-dir=${GIT_DIR}" "rev-parse" "HEAD" 59 | RESULT_VARIABLE result 60 | OUTPUT_VARIABLE git_head 61 | ) 62 | if(NOT "${result}" EQUAL 0) 63 | unset(git_head) 64 | endif() 65 | endif() 66 | 67 | if(NOT git_head AND EXISTS "${GIT_DIR}/HEAD") 68 | 69 | file(READ "${GIT_DIR}/HEAD" git_head) 70 | 71 | if(git_head MATCHES "^[ \t\r\n]*ref\\:(.*)$") 72 | 73 | # Remove the first for characters from git_head to get git_ref. 74 | # We can't use a length of -1 for string(SUBSTRING) as cmake < 2.8.5 doesn't support it. 75 | string(LENGTH "${git_head}" git_head_length) 76 | math(EXPR git_ref_length "${git_head_length} - 4") 77 | string(SUBSTRING "${git_head}" 4 ${git_ref_length} git_ref) 78 | string(STRIP "${git_ref}" git_ref) 79 | 80 | unset(git_head) 81 | if(EXISTS "${GIT_DIR}/${git_ref}") 82 | file(READ "${GIT_DIR}/${git_ref}" git_head) 83 | elseif(EXISTS "${GIT_DIR}/packed-refs") 84 | file(READ "${GIT_DIR}/packed-refs" git_refs) 85 | string(REGEX REPLACE "[^0-9A-Za-z]" "\\\\\\0" git_ref "${git_ref}") 86 | string(REGEX MATCH "[^\r\n]* ${git_ref}( [^\r\n])?" git_head "${git_refs}") 87 | endif() 88 | 89 | endif() 90 | 91 | endif() 92 | 93 | # Create variables for all prefixes of the git comit ID. 94 | string(REGEX MATCH "[0-9A-Za-z]+" git_commit "${git_head}") 95 | string(LENGTH "${git_commit}" git_commit_length) 96 | if(NOT git_commit_length LESS 40) 97 | string(TOLOWER "${git_commit}" GIT_COMMIT) 98 | foreach(i RANGE 20) 99 | string(SUBSTRING "${GIT_COMMIT}" 0 ${i} GIT_COMMIT_PREFIX_${i}) 100 | set(GIT_SUFFIX_${i} " + ${GIT_COMMIT_PREFIX_${i}}") 101 | endforeach() 102 | else() 103 | message(WARNING "Git repository detected, but could not determine HEAD") 104 | endif() 105 | 106 | endif() 107 | 108 | configure_file("${INPUT}" "${OUTPUT}") 109 | -------------------------------------------------------------------------------- /cmake/check/cxx11-alignof.cpp: -------------------------------------------------------------------------------- 1 | int main() { 2 | return alignof(int) != 1; 3 | } 4 | -------------------------------------------------------------------------------- /cmake/check/cxx11-std-codecvt_utf8_utf16.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | std::codecvt_utf8_utf16 codecvt; 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /cmake/check/cxx11-std-unique_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | std::unique_ptr ptr(new char); 5 | return !ptr; 6 | } 7 | -------------------------------------------------------------------------------- /doc/update-copyright-years: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | copyright='Daniel Scharrer' 4 | 5 | die() { 6 | printf '%s\n' "$1" 7 | exit 1 8 | } 9 | 10 | if [ -z "$1" ] || [ ! -d "$1" ] 11 | then repo="$(git rev-parse --show-toplevel)" 12 | else repo="$1" ; shift 13 | fi 14 | [ -d "$repo/.git" ] || die "$1 is not a git repository" 15 | 16 | if [ -z "$1" ] 17 | then last_tag="$(git --git-dir="$repo/.git" rev-list --tags --max-count=1)" 18 | else last_tag="$1" 19 | fi 20 | [ -z "$last_tag" ] && die "Could not determine last tag" 21 | last_tag_name="$(git --git-dir="$repo/.git" describe --tags "$last_tag")" 22 | printf 'Updating files modified since %s\n' "$last_tag_name" 23 | 24 | files="$(git --git-dir="$repo/.git" diff --name-only "$last_tag" HEAD | tr '\n' ' ')" 25 | eval "set -- LICENSE COPYING $files" 26 | 27 | for file ; do 28 | path="$repo/$file" 29 | [ -f "$path" ] || continue # File was deleted 30 | 31 | case "$file" in 32 | *.yml|.*) 33 | # Never try to update the copyright year for these files 34 | continue ;; 35 | esac 36 | 37 | c="$(grep -P "(^|[^a-zA-Z0-9_])Copyright( \\([cC]\\))? (\\d{4}\\-)?\\d{4} $copyright" "$path")" 38 | 39 | if [ -z "$c" ] ; then 40 | case "$file" in 41 | cmake/*.cpp|*CMakeLists.txt|*.md|*.1|*.in|LICENSE.*) 42 | # These files don't have to contain copyright information 43 | ;; 44 | *.*|scripts/*) 45 | c="$(grep -P "(^|[^a-zA-Z0-9_])Copyright( \([cC]\))?[ \:].*public domain" "$path")" 46 | [ -z "$c" ] && printf 'No copyright info found in %s, skipping\n' "$file" ;; 47 | esac 48 | continue 49 | fi 50 | 51 | if [ "$(printf '%s\n' "$c" | wc -l)" -gt 1 ] ; then 52 | printf 'Multiple copyright lines found in %s, skipping\n' "$file" 53 | continue 54 | fi 55 | 56 | s='\(^.*Copyright\( ([cC])\)\? \([0-9]\{4\}\-\)\?\)\([0-9]\{4\}\)\( '"$copyright"'.*$\)' 57 | old_year="$(printf '%s\n' "$c" | sed "s/$s/\\4/")" 58 | if [ -z "$old_year" ] || printf '%s\n' "$old_year" | grep -P '[^0-9]' > /dev/null ; then 59 | printf 'Could not determine new copyright year for %s, skipping\n' "$file" 60 | continue 61 | fi 62 | 63 | case "$file" in 64 | COPYING|LICENSE) 65 | new_year="$(git --git-dir="$repo/.git" log -1 --format=%cd --date=short)" ;; 66 | *) 67 | new_year="$(git --git-dir="$repo/.git" log -1 --format=%cd --date=short -- "$file")" 68 | esac 69 | new_year="${new_year%%-*}" 70 | if [ -z "$new_year" ] || printf '%s\n' "$new_year" | grep -P '[^0-9]' > /dev/null ; then 71 | printf 'Could not determine new copyright year for %s, skipping\n' "$file" 72 | continue 73 | fi 74 | 75 | [ "$new_year" = "$old_year" ] && continue 76 | 77 | if [ ! "$new_year" -gt "$old_year" ] ; then 78 | printf 'Copyright downgrade in %s: %s→%s, skipping\n' "$file" "$old_year" "$new_year" 79 | continue 80 | fi 81 | 82 | first_year="$(printf '%s\n' "$c" | sed "s/$s/\\3/")" 83 | if [ -z "$first_year" ] ; then 84 | replacement="$old_year-$new_year" 85 | old="$old_year" 86 | new="$old_year-$new_year" 87 | else 88 | replacement="$new_year" 89 | old="$first_year$old_year" 90 | new="$first_year$new_year" 91 | fi 92 | 93 | printf '%s: %s → %s\n' "$file" "$old" "$new" 94 | sed -i "s/$s/\\1$replacement\\5/" "$path" 95 | 96 | done 97 | -------------------------------------------------------------------------------- /src/cli/debug.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Debug output functions. 25 | */ 26 | #ifndef INNOEXTRACT_CLI_DEBUG_HPP 27 | #define INNOEXTRACT_CLI_DEBUG_HPP 28 | 29 | #include 30 | 31 | #include "configure.hpp" 32 | 33 | #include "cli/extract.hpp" 34 | 35 | #ifdef DEBUG 36 | 37 | namespace loader { struct offsets; } 38 | namespace setup { struct info; } 39 | 40 | void print_offsets(const loader::offsets & offsets); 41 | void print_info(const setup::info & info); 42 | 43 | void dump_headers(std::istream & is, const loader::offsets & offsets, const extract_options & o); 44 | 45 | #endif // DEBUG 46 | 47 | #endif // INNOEXTRACT_CLI_DEBUG_HPP 48 | -------------------------------------------------------------------------------- /src/cli/extract.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Routines to extract/list files from an Inno Setup archive. 25 | */ 26 | #ifndef INNOEXTRACT_CLI_EXTRACT_HPP 27 | #define INNOEXTRACT_CLI_EXTRACT_HPP 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | #include "setup/filename.hpp" 37 | 38 | struct format_error : public std::runtime_error { 39 | explicit format_error(const std::string & reason) : std::runtime_error(reason) { } 40 | }; 41 | 42 | enum CollisionAction { 43 | OverwriteCollisions, 44 | RenameCollisions, 45 | RenameAllCollisions, 46 | ErrorOnCollisions 47 | }; 48 | 49 | struct extract_options { 50 | 51 | bool quiet; 52 | bool silent; 53 | 54 | bool warn_unused; //!< Warn if there are unused files 55 | 56 | bool list_sizes; //!< Show size information for files 57 | bool list_checksums; //!< Show checksum information for files 58 | 59 | bool data_version; //!< Print the data version 60 | #ifdef DEBUG 61 | bool dump_headers; //!< Dump setup headers 62 | #endif 63 | bool list; //!< List files 64 | bool test; //!< Test files (but don't extract) 65 | bool extract; //!< Extract files 66 | bool list_languages; //!< List available languages 67 | bool gog_game_id; //!< Show the GOG.com game id 68 | bool show_password; //!< Show password check information 69 | bool check_password; //!< Abort if the provided password is incorrect 70 | 71 | bool preserve_file_times; //!< Set timestamps of extracted files 72 | bool local_timestamps; //!< Use local timezone for setting timestamps 73 | 74 | bool gog; //!< Try to extract additional archives used in GOG.com installers 75 | bool gog_galaxy; //!< Try to re-assemble GOG Galaxy files 76 | 77 | bool extract_unknown; //!< Try to extract unknown Inno Setup versions 78 | 79 | bool extract_temp; //!< Extract temporary files 80 | bool language_only; //!< Extract files not associated with any language 81 | std::string language; //!< Extract only files for this language 82 | std::vector include; //!< Extract only files matching these patterns 83 | 84 | boost::uint32_t codepage; 85 | 86 | setup::filename_map filenames; 87 | CollisionAction collisions; 88 | std::string default_language; 89 | 90 | std::string password; 91 | 92 | boost::filesystem::path output_dir; 93 | 94 | extract_options() 95 | : quiet(false) 96 | , silent(false) 97 | , warn_unused(false) 98 | , list_sizes(false) 99 | , list_checksums(false) 100 | , data_version(false) 101 | , list(false) 102 | , test(false) 103 | , extract(false) 104 | , list_languages(false) 105 | , gog_game_id(false) 106 | , show_password(false) 107 | , check_password(false) 108 | , preserve_file_times(false) 109 | , local_timestamps(false) 110 | , gog(false) 111 | , gog_galaxy(false) 112 | , extract_unknown(false) 113 | , extract_temp(false) 114 | , language_only(false) 115 | , collisions(OverwriteCollisions) 116 | { } 117 | 118 | }; 119 | 120 | void process_file(const boost::filesystem::path & installer, const extract_options & o); 121 | 122 | #endif // INNOEXTRACT_CLI_EXTRACT_HPP 123 | -------------------------------------------------------------------------------- /src/cli/gog.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2018 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * GOG.com-specific extensions. 25 | */ 26 | #ifndef INNOEXTRACT_CLI_GOG_HPP 27 | #define INNOEXTRACT_CLI_GOG_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | namespace setup { struct info; } 35 | 36 | struct extract_options; 37 | 38 | namespace gog { 39 | 40 | //! \return the GOG.com game ID for this installer or an empty string 41 | std::string get_game_id(const setup::info & info); 42 | 43 | void probe_bin_files(const extract_options & o, const setup::info & info, 44 | const boost::filesystem::path & setup_file, bool external); 45 | 46 | } // namespace gog 47 | 48 | #endif // INNOEXTRACT_CLI_GOG_HPP 49 | -------------------------------------------------------------------------------- /src/cli/goggalaxy.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * GOG.com-specific extensions. 25 | */ 26 | #ifndef INNOEXTRACT_CLI_GOGGALAXY_HPP 27 | #define INNOEXTRACT_CLI_GOGGALAXY_HPP 28 | 29 | namespace setup { struct info; } 30 | 31 | namespace gog { 32 | 33 | /*! 34 | * For some GOG installers, some application files are shipped in GOG Galaxy format: 35 | * Thse files are split into one or more parts and then individually compressed. 36 | * The parts are decompressed and reassembled by pre-/post-install scripts. 37 | * This function parses the arguments to those scripts so that we can re-assemble them ourselves. 38 | * 39 | * The first part of a multi-part file has a before_install script that configures the output filename 40 | * as well as the number of parts in the file and a checksum for the whole file. 41 | * 42 | * Each part (including the first) has an after_install script with a checksum for the decompressed 43 | * part as well as compressed and decompressed sizes. 44 | * 45 | * Additionally, language constrained are also parsed from check scripts and added to the language list. 46 | */ 47 | void parse_galaxy_files(setup::info & info, bool force); 48 | 49 | } // namespace gog 50 | 51 | #endif // INNOEXTRACT_CLI_GOGGALAXY_HPP 52 | 53 | -------------------------------------------------------------------------------- /src/configure.hpp.in: -------------------------------------------------------------------------------- 1 | 2 | #ifndef INNOEXTRACT_CONFIGURE_HPP 3 | #define INNOEXTRACT_CONFIGURE_HPP 4 | 5 | // Console functions 6 | #cmakedefine01 INNOEXTRACT_HAVE_ISATTY 7 | #cmakedefine01 INNOEXTRACT_HAVE_IOCTL 8 | 9 | // Time functions 10 | #cmakedefine01 INNOEXTRACT_HAVE_TIMEGM 11 | #cmakedefine01 INNOEXTRACT_HAVE_GMTIME_R 12 | 13 | // File functions 14 | #cmakedefine01 INNOEXTRACT_HAVE_UTIMENSAT 15 | #cmakedefine01 INNOEXTRACT_HAVE_DYNAMIC_UTIMENSAT 16 | #cmakedefine01 INNOEXTRACT_HAVE_AT_FDCWD 17 | #cmakedefine01 INNOEXTRACT_HAVE_UTIMES 18 | 19 | // Shared functions 20 | #cmakedefine01 INNOEXTRACT_HAVE_DLSYM 21 | 22 | // Endianness 23 | #cmakedefine01 INNOEXTRACT_HAVE_BUILTIN_BSWAP16 24 | #cmakedefine01 INNOEXTRACT_HAVE_BUILTIN_BSWAP32 25 | #cmakedefine01 INNOEXTRACT_HAVE_BUILTIN_BSWAP64 26 | #cmakedefine01 INNOEXTRACT_HAVE_BSWAP_16 27 | #cmakedefine01 INNOEXTRACT_HAVE_BSWAP_32 28 | #cmakedefine01 INNOEXTRACT_HAVE_BSWAP_64 29 | 30 | // C++11 functionality 31 | #cmakedefine01 INNOEXTRACT_HAVE_ALIGNOF 32 | #cmakedefine01 INNOEXTRACT_HAVE_STD_CODECVT_UTF8_UTF16 33 | #cmakedefine01 INNOEXTRACT_HAVE_STD_UNIQUE_PTR 34 | 35 | // Optional dependencies 36 | #cmakedefine01 INNOEXTRACT_HAVE_DECRYPTION 37 | #cmakedefine01 INNOEXTRACT_HAVE_LZMA 38 | #cmakedefine01 INNOEXTRACT_HAVE_ICONV 39 | #cmakedefine01 INNOEXTRACT_HAVE_WIN32_CONV 40 | #cmakedefine01 INNOEXTRACT_HAVE_BUILTIN_CONV 41 | 42 | // Process functions 43 | #cmakedefine01 INNOEXTRACT_HAVE_POSIX_SPAWNP 44 | #cmakedefine01 INNOEXTRACT_HAVE_UNISTD_ENVIRON 45 | #cmakedefine01 INNOEXTRACT_HAVE_FORK 46 | #cmakedefine01 INNOEXTRACT_HAVE_EXECVP 47 | #cmakedefine01 INNOEXTRACT_HAVE_WAITPID 48 | 49 | #endif // INNOEXTRACT_CONFIGURE_HPP 50 | -------------------------------------------------------------------------------- /src/crypto/adler32.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | // Taken from Crypto++ and modified to fit the project. 22 | // adler32.cpp - written and placed in the public domain by Wei Dai 23 | 24 | #include "crypto/adler32.hpp" 25 | 26 | #include "util/test.hpp" 27 | 28 | namespace crypto { 29 | 30 | void adler32::update(const char * data, size_t length) { 31 | 32 | const boost::uint_fast32_t base = 65521; 33 | 34 | boost::uint_fast32_t s1 = boost::uint16_t(state); 35 | boost::uint_fast32_t s2 = boost::uint16_t(state >> 16); 36 | 37 | if(length % 8 != 0) { 38 | 39 | do { 40 | s1 += boost::uint8_t(*data++); 41 | s2 += s1; 42 | length--; 43 | } while(length % 8 != 0); 44 | 45 | if(s1 >= base) { 46 | s1 -= base; 47 | } 48 | 49 | s2 %= base; 50 | } 51 | 52 | while(length > 0) { 53 | 54 | s1 += boost::uint8_t(data[0]), s2 += s1; 55 | s1 += boost::uint8_t(data[1]), s2 += s1; 56 | s1 += boost::uint8_t(data[2]), s2 += s1; 57 | s1 += boost::uint8_t(data[3]), s2 += s1; 58 | s1 += boost::uint8_t(data[4]), s2 += s1; 59 | s1 += boost::uint8_t(data[5]), s2 += s1; 60 | s1 += boost::uint8_t(data[6]), s2 += s1; 61 | s1 += boost::uint8_t(data[7]), s2 += s1; 62 | 63 | length -= 8; 64 | data += 8; 65 | 66 | if(s1 >= base) { 67 | s1 -= base; 68 | } 69 | 70 | if(length % 0x8000 == 0) { 71 | s2 %= base; 72 | } 73 | } 74 | 75 | state = (boost::uint32_t(s2) << 16) | boost::uint16_t(s1); 76 | 77 | } 78 | 79 | INNOEXTRACT_TEST(adler32, 80 | 81 | adler32 checksum; 82 | checksum.init(); 83 | checksum.update(testdata, testlen); 84 | test("checksum", checksum.finalize() == 0xb8a36c4a); 85 | 86 | ) 87 | 88 | } // namespace crypto 89 | -------------------------------------------------------------------------------- /src/crypto/adler32.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Adler-32 checksum routines. 25 | */ 26 | #ifndef INNOEXTRACT_CRYPTO_ADLER32_HPP 27 | #define INNOEXTRACT_CRYPTO_ADLER32_HPP 28 | 29 | #include 30 | 31 | #include 32 | 33 | #include "crypto/checksum.hpp" 34 | 35 | namespace crypto { 36 | 37 | //! Adler-32 checksum calculations 38 | struct adler32 : public checksum_base { 39 | 40 | void init() { state = 1; } 41 | 42 | void update(const char * data, size_t length); 43 | 44 | boost::uint32_t finalize() const { return state; } 45 | 46 | private: 47 | 48 | boost::uint32_t state; 49 | 50 | }; 51 | 52 | } // namespace crypto 53 | 54 | #endif // INNOEXTRACT_CRYPTO_ADLER32_HPP 55 | -------------------------------------------------------------------------------- /src/crypto/arc4.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Alledged RC4 en-/decryption routines. 25 | */ 26 | #ifndef INNOEXTRACT_CRYPTO_ARC4_HPP 27 | #define INNOEXTRACT_CRYPTO_ARC4_HPP 28 | 29 | #include 30 | 31 | #include 32 | 33 | #include "configure.hpp" 34 | 35 | #if INNOEXTRACT_HAVE_DECRYPTION 36 | 37 | namespace crypto { 38 | 39 | //! Alledged RC4 en-/decryption calculation 40 | struct arc4 { 41 | 42 | void init(const char * key, size_t length); 43 | 44 | void discard(size_t length); 45 | 46 | void crypt(const char * in, char * out, size_t length); 47 | 48 | private: 49 | 50 | void update(); 51 | 52 | boost::uint8_t state[256]; 53 | size_t a, b; 54 | 55 | }; 56 | 57 | } // namespace crypto 58 | 59 | #endif // INNOEXTRACT_HAVE_DECRYPTION 60 | 61 | #endif // INNOEXTRACT_CRYPTO_ARC4_HPP 62 | -------------------------------------------------------------------------------- /src/crypto/checksum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "crypto/checksum.hpp" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | namespace crypto { 31 | 32 | bool checksum::operator==(const checksum & other) const { 33 | 34 | if(other.type != type) { 35 | return false; 36 | } 37 | 38 | switch(type) { 39 | case None: return true; 40 | case Adler32: return (adler32 == other.adler32); 41 | case CRC32: return (crc32 == other.crc32); 42 | case MD5: return !memcmp(md5, other.md5, sizeof(md5)); 43 | case SHA1: return !memcmp(sha1, other.sha1, sizeof(sha1)); 44 | case SHA256: return !memcmp(sha256, other.sha256, sizeof(sha256)); 45 | default: return false; 46 | }; 47 | } 48 | 49 | } // namespace crypto 50 | 51 | NAMES(crypto::checksum_type, "Checksum Type", 52 | "None", 53 | "Adler32", 54 | "CRC32", 55 | "MD5", 56 | "SHA-1", 57 | "SHA-256", 58 | "PBKDF2-SHA256+XChaCha20" 59 | ) 60 | 61 | std::ostream & operator<<(std::ostream & os, const crypto::checksum & checksum) { 62 | 63 | std::ios_base::fmtflags old_fmtflags = os.flags(); 64 | 65 | os << checksum.type << ' '; 66 | 67 | switch(checksum.type) { 68 | case crypto::None: { 69 | os << "(no checksum)"; 70 | break; 71 | } 72 | case crypto::Adler32: { 73 | os << "0x" << std::hex << std::setw(8) << checksum.adler32; 74 | break; 75 | } 76 | case crypto::CRC32: { 77 | os << "0x" << std::hex << std::setw(8) << checksum.crc32; 78 | break; 79 | } 80 | case crypto::MD5: { 81 | for(size_t i = 0; i < size_t(boost::size(checksum.md5)); i++) { 82 | os << std::setfill('0') << std::hex << std::setw(2) << int(boost::uint8_t(checksum.md5[i])); 83 | } 84 | break; 85 | } 86 | case crypto::SHA1: { 87 | for(size_t i = 0; i < size_t(boost::size(checksum.sha1)); i++) { 88 | os << std::setfill('0') << std::hex << std::setw(2) << int(boost::uint8_t(checksum.sha1[i])); 89 | } 90 | break; 91 | } 92 | case crypto::SHA256: { 93 | for(size_t i = 0; i < size_t(boost::size(checksum.sha1)); i++) { 94 | os << std::setfill('0') << std::hex << std::setw(2) << int(boost::uint8_t(checksum.sha1[i])); 95 | } 96 | break; 97 | } 98 | case crypto::PBKDF2_SHA256_XChaCha20: { 99 | for(size_t i = 0; i < size_t(boost::size(checksum.check)); i++) { 100 | os << std::setfill('0') << std::hex << std::setw(2) << int(boost::uint8_t(checksum.check[i])); 101 | } 102 | break; 103 | } 104 | } 105 | 106 | os.setf(old_fmtflags, std::ios_base::basefield); 107 | 108 | return os; 109 | } 110 | -------------------------------------------------------------------------------- /src/crypto/checksum.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Checksum structures and utilities. 25 | */ 26 | #ifndef INNOEXTRACT_CRYPTO_CHECKSUM_HPP 27 | #define INNOEXTRACT_CRYPTO_CHECKSUM_HPP 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "util/endian.hpp" 36 | #include "util/enum.hpp" 37 | #include "util/types.hpp" 38 | 39 | namespace crypto { 40 | 41 | enum checksum_type { 42 | None, 43 | Adler32, 44 | CRC32, 45 | MD5, 46 | SHA1, 47 | SHA256, 48 | PBKDF2_SHA256_XChaCha20 49 | }; 50 | 51 | struct checksum { 52 | 53 | union { 54 | boost::uint32_t adler32; 55 | boost::uint32_t crc32; 56 | char md5[16]; 57 | char sha1[20]; 58 | char sha256[32]; 59 | char check[4]; 60 | }; 61 | 62 | checksum_type type; 63 | 64 | bool operator==(const checksum & other) const; 65 | bool operator!=(const checksum & other) const { return !(*this == other); } 66 | 67 | }; 68 | 69 | template 70 | class checksum_base : public util::static_polymorphic { 71 | 72 | public: 73 | 74 | /*! 75 | * Load the data and process it. 76 | * Data is processed as-is and then converted according to Endianness. 77 | */ 78 | template 79 | T load(std::istream & is) { 80 | char buffer[sizeof(T)]; 81 | is.read(buffer, std::streamsize(sizeof(buffer))); 82 | this->impl().update(buffer, sizeof(buffer)); 83 | return Endianness::template load(buffer); 84 | } 85 | 86 | /*! 87 | * Load the data and process it. 88 | * Data is processed as-is and then converted if the host endianness is not little_endian. 89 | */ 90 | template 91 | T load(std::istream & is) { 92 | return load(is); 93 | } 94 | 95 | }; 96 | 97 | } // namespace crypto 98 | 99 | NAMED_ENUM(crypto::checksum_type) 100 | 101 | std::ostream & operator<<(std::ostream & os, const crypto::checksum & checksum); 102 | 103 | #endif // INNOEXTRACT_CRYPTO_CHECKSUM_HPP 104 | -------------------------------------------------------------------------------- /src/crypto/crc32.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * CRC32 checksum routines. 25 | */ 26 | #ifndef INNOEXTRACT_CRYPTO_CRC32_HPP 27 | #define INNOEXTRACT_CRYPTO_CRC32_HPP 28 | 29 | #include 30 | 31 | #include "crypto/checksum.hpp" 32 | 33 | namespace crypto { 34 | 35 | //! CRC32 checksum calculation 36 | struct crc32 : public checksum_base { 37 | 38 | void init() { crc = CRC32_NEGL; } 39 | 40 | void update(const char * data, size_t length); 41 | 42 | boost::uint32_t finalize() const { return crc ^ CRC32_NEGL; } 43 | 44 | private: 45 | 46 | static const boost::uint32_t CRC32_NEGL = 0xffffffffl; 47 | 48 | boost::uint32_t crc; 49 | }; 50 | 51 | } // namespace crypto 52 | 53 | #endif // INNOEXTRACT_CRYPTO_CRC32_HPP 54 | -------------------------------------------------------------------------------- /src/crypto/hasher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "crypto/hasher.hpp" 22 | 23 | namespace crypto { 24 | 25 | hasher::hasher(checksum_type type) : active_type(type) { 26 | 27 | switch(active_type) { 28 | case crypto::None: break; 29 | case crypto::Adler32: adler32.init(); break; 30 | case crypto::CRC32: crc32.init(); break; 31 | case crypto::MD5: md5.init(); break; 32 | case crypto::SHA1: sha1.init(); break; 33 | case crypto::SHA256: sha256.init(); break; 34 | case crypto::PBKDF2_SHA256_XChaCha20: break; 35 | }; 36 | 37 | } 38 | 39 | void hasher::update(const char * data, size_t size) { 40 | 41 | switch(active_type) { 42 | case crypto::None: break; 43 | case crypto::Adler32: adler32.update(data, size); break; 44 | case crypto::CRC32: crc32.update(data, size); break; 45 | case crypto::MD5: md5.update(data, size); break; 46 | case crypto::SHA1: sha1.update(data, size); break; 47 | case crypto::SHA256: sha256.update(data, size); break; 48 | case crypto::PBKDF2_SHA256_XChaCha20: break; 49 | }; 50 | 51 | } 52 | 53 | checksum hasher::finalize() { 54 | 55 | checksum result; 56 | 57 | result.type = active_type; 58 | 59 | switch(active_type) { 60 | case crypto::None: break; 61 | case crypto::Adler32: result.adler32 = adler32.finalize(); break; 62 | case crypto::CRC32: result.crc32 = crc32.finalize(); break; 63 | case crypto::MD5: md5.finalize(result.md5); break; 64 | case crypto::SHA1: sha1.finalize(result.sha1); break; 65 | case crypto::SHA256: sha256.finalize(result.sha256); break; 66 | case crypto::PBKDF2_SHA256_XChaCha20: break; 67 | }; 68 | 69 | return result; 70 | } 71 | 72 | } // namespace crypto 73 | -------------------------------------------------------------------------------- /src/crypto/hasher.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Utility to hash data with a configurable hash function. 25 | */ 26 | #ifndef INNOEXTRACT_CRYPTO_HASHER_HPP 27 | #define INNOEXTRACT_CRYPTO_HASHER_HPP 28 | 29 | #include "crypto/adler32.hpp" 30 | #include "crypto/checksum.hpp" 31 | #include "crypto/crc32.hpp" 32 | #include "crypto/md5.hpp" 33 | #include "crypto/sha1.hpp" 34 | #include "crypto/sha256.hpp" 35 | #include "util/enum.hpp" 36 | 37 | struct checksum_uninitialized_error { }; 38 | 39 | namespace crypto { 40 | 41 | class hasher : checksum_base { 42 | 43 | public: 44 | 45 | explicit hasher(checksum_type type); 46 | 47 | void update(const char * data, size_t size); 48 | 49 | checksum finalize(); 50 | 51 | private: 52 | 53 | checksum_type active_type; 54 | 55 | union { 56 | crypto::adler32 adler32; 57 | crypto::crc32 crc32; 58 | crypto::md5 md5; 59 | crypto::sha1 sha1; 60 | crypto::sha256 sha256; 61 | }; 62 | 63 | }; 64 | 65 | } // namespace crypto 66 | 67 | #endif // INNOEXTRACT_CRYPTO_HASHER_HPP; 68 | -------------------------------------------------------------------------------- /src/crypto/md5.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2015 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * MD5 hashing routines. 25 | */ 26 | #ifndef INNOEXTRACT_CRYPTO_MD5_HPP 27 | #define INNOEXTRACT_CRYPTO_MD5_HPP 28 | 29 | #include 30 | 31 | #include "crypto/iteratedhash.hpp" 32 | #include "util/endian.hpp" 33 | 34 | namespace crypto { 35 | 36 | class md5_transform { 37 | 38 | public: 39 | 40 | typedef boost::uint32_t hash_word; 41 | typedef util::little_endian byte_order; 42 | enum constants { 43 | offset = 0, 44 | block_size = 64, 45 | hash_size = 16, 46 | }; 47 | 48 | static void init(hash_word * state); 49 | 50 | static void transform(hash_word * state, const hash_word * data); 51 | 52 | }; 53 | 54 | typedef iterated_hash md5; 55 | 56 | } // namespace crypto 57 | 58 | #endif // INNOEXTRACT_CRYPTO_MD5_HPP 59 | -------------------------------------------------------------------------------- /src/crypto/pbkdf2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | // Based on Inno Setup's PBKDF2.pas 22 | 23 | #include "crypto/pbkdf2.hpp" 24 | 25 | #include 26 | 27 | #include "crypto/sha1.hpp" 28 | #include "crypto/sha256.hpp" 29 | #include "util/test.hpp" 30 | 31 | namespace crypto { 32 | 33 | INNOEXTRACT_TEST(pbkdf2, 34 | 35 | // Testcase from Inno Setup's TestPBKDF2SHA256 36 | // which is based on https://stackoverflow.com/a/5136918/301485 and https://en.wikipedia.org/wiki/PBKDF2 37 | 38 | char buffer[40]; 39 | 40 | const char * password0 = "password"; 41 | const char * salt0 = "salt"; 42 | const boost::uint8_t key0[] = { 43 | 0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, 0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, 44 | 0xa8, 0x65, 0x48, 0xc9, 0x2c, 0xcc, 0x35, 0x48, 0x08, 0x05, 0x98, 0x7c, 0xb7, 0x0b, 0xe1, 0x7b 45 | }; 46 | pbkdf2::derive(password0, std::strlen(password0), salt0, std::strlen(salt0), 1, buffer, 32); 47 | test_equals("sha256.single", buffer, key0, sizeof(key0)); 48 | const boost::uint8_t key1[] = { 49 | 0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, 0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, 50 | 0x96, 0x28, 0x93, 0xa0, 0x01, 0xce, 0x4e, 0x11, 0xa4, 0x96, 0x38, 0x73, 0xaa, 0x98, 0x13, 0x4a 51 | }; 52 | pbkdf2::derive(password0, std::strlen(password0), salt0, std::strlen(salt0), 4096, buffer, 32); 53 | test_equals("sha256.multiple", buffer, key1, sizeof(key1)); 54 | 55 | const char * password1 = "passwordPASSWORDpassword"; 56 | const char * salt1 = "saltSALTsaltSALTsaltSALTsaltSALTsalt"; 57 | const boost::uint8_t key2[] = { 58 | 0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, 0x32, 0xd8, 59 | 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf, 0x2b, 0x17, 0x34, 0x7e, 60 | 0xbc, 0x18, 0x00, 0x18, 0x1c, 0x4e, 0x2a, 0x1f, 0xb8, 0xdd, 61 | 0x53, 0xe1, 0xc6, 0x35, 0x51, 0x8c, 0x7d, 0xac, 0x47, 0xe9 62 | }; 63 | pbkdf2::derive(password1, std::strlen(password1), salt1, std::strlen(salt1), 4096, buffer, 40); 64 | test_equals("sha256.longkey", buffer, key2, sizeof(key2)); 65 | 66 | const char * password2 = "pass\0word"; 67 | const char * salt2 = "sa\0lt"; 68 | const boost::uint8_t key3[] = { 69 | 0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89, 0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87 70 | }; 71 | pbkdf2::derive(password2, 9, salt2, 5, 4096, buffer, 16); 72 | test_equals("sha256.evilpassword", buffer, key3, sizeof(key3)); 73 | 74 | const char * password3 = "plnlrtfpijpuhqylxbgqiiyipieyxvfsavzgxbbcfusqkozwpngsyejqlmjsytrmd"; 75 | const boost::uint8_t salt3[] = { 76 | 0xa0, 0x09, 0xc1, 0xa4, 0x85, 0x91, 0x2c, 0x6a, 0xe6, 0x30, 0xd3, 0xe7, 0x44, 0x24, 0x0b, 0x04 77 | }; 78 | const boost::uint8_t key4[] = { 79 | 0x28, 0x86, 0x9b, 0x5f, 0x31, 0xae, 0x29, 0x23, 0x6f, 0x16, 0x4c, 0x5c, 0xb3, 0x3e, 0x2e, 0x3b 80 | }; 81 | pbkdf2::derive(password3, std::strlen(password3), reinterpret_cast(salt3), 82 | sizeof(salt3), 1000, buffer, 16); 83 | test_equals("sha256.longpassword", buffer, key4, sizeof(key4)); 84 | 85 | ) 86 | 87 | } // namespace crypto 88 | -------------------------------------------------------------------------------- /src/crypto/sha1.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * SHA-1 hashing routines. 25 | */ 26 | #ifndef INNOEXTRACT_CRYPTO_SHA1_HPP 27 | #define INNOEXTRACT_CRYPTO_SHA1_HPP 28 | 29 | #include 30 | 31 | #include "crypto/iteratedhash.hpp" 32 | #include "util/endian.hpp" 33 | 34 | namespace crypto { 35 | 36 | class sha1_transform { 37 | 38 | public: 39 | 40 | typedef boost::uint32_t hash_word; 41 | typedef util::big_endian byte_order; 42 | enum constants { 43 | offset = 1, 44 | block_size = 64, 45 | hash_size = 20, 46 | }; 47 | 48 | static void init(hash_word * state); 49 | 50 | static void transform(hash_word * state, const hash_word * data); 51 | }; 52 | 53 | typedef iterated_hash sha1; 54 | 55 | } // namespace crypto 56 | 57 | #endif // INNOEXTRACT_CRYPTO_SHA1_HPP 58 | -------------------------------------------------------------------------------- /src/crypto/sha256.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * SHA-256 hashing routines. 25 | */ 26 | #ifndef INNOEXTRACT_CRYPTO_SHA256_HPP 27 | #define INNOEXTRACT_CRYPTO_SHA256_HPP 28 | 29 | #include 30 | 31 | #include "crypto/iteratedhash.hpp" 32 | #include "util/endian.hpp" 33 | 34 | namespace crypto { 35 | 36 | class sha256_transform { 37 | 38 | public: 39 | 40 | typedef boost::uint32_t hash_word; 41 | typedef util::big_endian byte_order; 42 | enum constants { 43 | offset = 1, 44 | block_size = 64, 45 | hash_size = 32, 46 | }; 47 | 48 | static void init(hash_word * state); 49 | 50 | static void transform(hash_word * state, const hash_word * data); 51 | }; 52 | 53 | typedef iterated_hash sha256; 54 | 55 | } // namespace crypto 56 | 57 | #endif // INNOEXTRACT_CRYPTO_SHA256_HPP 58 | -------------------------------------------------------------------------------- /src/crypto/xchacha20.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * ChaCha20 en-/decryption routines. 25 | */ 26 | #ifndef INNOEXTRACT_CRYPTO_XCHACHA20_HPP 27 | #define INNOEXTRACT_CRYPTO_XCHACHA20_HPP 28 | 29 | #include 30 | 31 | #include 32 | 33 | #include "configure.hpp" 34 | 35 | #if INNOEXTRACT_HAVE_DECRYPTION 36 | 37 | namespace crypto { 38 | 39 | //! ChaCha20 en-/decryption calculation 40 | struct xchacha20 { 41 | 42 | enum constants { 43 | key_size = 32, 44 | nonce_size = 24, 45 | }; 46 | 47 | typedef boost::uint32_t word; 48 | 49 | void init(const char key[key_size], const char nonce[nonce_size]); 50 | 51 | void discard(size_t length); 52 | 53 | void crypt(const char * in, char * out, size_t length); 54 | 55 | private: 56 | 57 | void update(); 58 | 59 | static void derive_subkey(const char key[key_size], const char nonce[16], char subkey[key_size]); 60 | 61 | static void init_state(word state[16], const char key[key_size]); 62 | 63 | static void run_rounds(word keystream[16]); 64 | 65 | static void increment_count(word state[16], size_t increment = 1); 66 | 67 | word state[16]; 68 | word keystream[16]; 69 | boost::uint8_t pos; 70 | 71 | #ifdef INNOEXTRACT_BUILD_TESTS 72 | friend struct xchacha20_test; 73 | #endif 74 | }; 75 | 76 | } // namespace crypto 77 | 78 | #endif // INNOEXTRACT_HAVE_DECRYPTION 79 | 80 | #endif // INNOEXTRACT_CRYPTO_XCHACHA20_HPP 81 | -------------------------------------------------------------------------------- /src/index.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #ifndef INNOEXTRACT_INDEX_HPP 22 | #define INNOEXTRACT_INDEX_HPP 23 | 24 | /*! 25 | * \mainpage innoextract Developer Documentation 26 | * 27 | * To find out about how Inno Setup files are structured, start at \ref loader::offsets. 28 | * 29 | */ 30 | 31 | #endif // INNOEXTRACT_INDEX_HPP 32 | -------------------------------------------------------------------------------- /src/loader/exereader.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Functions to find resources in Windows executables. 25 | */ 26 | #ifndef INNOEXTRACT_LOADER_EXEREADER_HPP 27 | #define INNOEXTRACT_LOADER_EXEREADER_HPP 28 | 29 | #include 30 | 31 | #include 32 | 33 | namespace loader { 34 | 35 | /*! 36 | * \brief Minimal NE/LE/PE parser that can find resources by ID in binary (exe/dll) files 37 | * 38 | * This implementation is optimized to look for exactly one resource. 39 | */ 40 | class exe_reader { 41 | 42 | public: 43 | 44 | //! Position and size of a resource entry 45 | struct resource { 46 | 47 | boost::uint32_t offset; //!< File offset of the resource data in bytes 48 | 49 | boost::uint32_t size; //!< Size of the resource data in bytes 50 | 51 | operator bool() { return offset != 0; } 52 | bool operator!() { return offset == 0; } 53 | 54 | }; 55 | 56 | enum resource_id { 57 | NameVersionInfo = 1, 58 | TypeCursor = 1, 59 | TypeBitmap = 2, 60 | TypeIcon = 3, 61 | TypeMenu = 4, 62 | TypeDialog = 5, 63 | TypeString = 6, 64 | TypeFontDir = 7, 65 | TypeFont = 8, 66 | TypeAccelerator = 9, 67 | TypeData = 10, 68 | TypeMessageTable = 11, 69 | TypeGroupCursor = 12, 70 | TypeGroupIcon = 14, 71 | TypeVersion = 16, 72 | TypeDlgInclude = 17, 73 | TypePlugPlay = 19, 74 | TypeVXD = 20, 75 | TypeAniCursor = 21, 76 | TypeAniIcon = 22, 77 | TypeHTML = 23, 78 | Default = boost::uint32_t(-1) 79 | }; 80 | 81 | /*! 82 | * \brief Find where a resource with a given ID is stored in a NE or PE binary. 83 | * 84 | * Resources are addressed using a (name, type, language) tuple. 85 | * 86 | * \param is a seekable stream of the binary containing the resource 87 | * \param name the user-defined name of the resource 88 | * \param type the type of the resource 89 | * \param language the localised variant of the resource 90 | * 91 | * \return the location of the resource or `(0, 0)` if the requested resource does not exist. 92 | */ 93 | static resource find_resource(std::istream & is, boost::uint32_t name, 94 | boost::uint32_t type = TypeData, 95 | boost::uint32_t language = Default); 96 | 97 | enum file_version { 98 | FileVersionUnknown = boost::uint64_t(-1) 99 | }; 100 | 101 | /*! 102 | * \brief Get the file version number of a NE, LE or PE binary. 103 | * 104 | * \param is a seekable stream of the binary file containing the resource 105 | * 106 | * \return the file version number or FileVersionUnknown. 107 | */ 108 | static boost::uint64_t get_file_version(std::istream & is); 109 | 110 | }; 111 | 112 | } // namespace loader 113 | 114 | #endif // INNOEXTRACT_LOADER_EXEREADER_HPP 115 | -------------------------------------------------------------------------------- /src/release.cpp.in: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "release.hpp" 22 | 23 | /* 24 | * \file 25 | * 26 | * This file is automatically processed by cmake if the version or commit id changes. 27 | * For the exact syntax see the documentation of the configure_file() cmake command. 28 | * For available variables see cmake/VersionString.cmake. 29 | */ 30 | 31 | #if ${VERSION_COUNT} != 5 32 | #error "Configure error - the VERSION file should specify exactly two lines!" 33 | #endif 34 | 35 | #if ${LICENSE_COUNT} < 3 36 | #error "Configure error - the LICENSE file should specify at least three lines!" 37 | #endif 38 | 39 | const char innoextract_name[] = "${VERSION_0_NAME}"; 40 | 41 | const char innoextract_version[] = "${VERSION_0_STRING}${VERSION_SUFFIX}${GIT_SUFFIX_7}"; 42 | 43 | const char innosetup_versions[] = "${VERSION_2}"; 44 | 45 | const char innoextract_bugs[] = "${VERSION_4}"; 46 | 47 | const char innoextract_copyright[] = "${LICENSE_0_LINE}"; 48 | 49 | const char innoextract_license[] = "${LICENSE_TAIL}"; 50 | -------------------------------------------------------------------------------- /src/release.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2015 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Strings describing the innoextract version. 25 | */ 26 | #ifndef INNOEXTRACT_RELEASE_HPP 27 | #define INNOEXTRACT_RELEASE_HPP 28 | 29 | //! Name of the program being built 30 | extern const char innoextract_name[]; 31 | 32 | //! Name + version of the program being built 33 | extern const char innoextract_version[]; 34 | 35 | //! Range of supported Inno Setup versions 36 | extern const char innosetup_versions[]; 37 | 38 | //! Bug tracker URL 39 | extern const char innoextract_bugs[]; 40 | 41 | //! Copyright line for the current program 42 | extern const char innoextract_copyright[]; 43 | 44 | //! License text for the current program 45 | extern const char innoextract_license[]; 46 | 47 | #endif // INNOEXTRACT_RELEASE_HPP 48 | -------------------------------------------------------------------------------- /src/setup/component.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/component.hpp" 22 | 23 | #include "setup/info.hpp" 24 | #include "setup/version.hpp" 25 | #include "util/load.hpp" 26 | #include "util/storedenum.hpp" 27 | 28 | namespace setup { 29 | 30 | namespace { 31 | 32 | STORED_FLAGS_MAP(stored_component_flags_0, 33 | component_entry::Fixed, 34 | component_entry::Restart, 35 | component_entry::DisableNoUninstallWarning, 36 | ); 37 | 38 | // starting with version 3.0.8 39 | STORED_FLAGS_MAP(stored_component_flags_1, 40 | component_entry::Fixed, 41 | component_entry::Restart, 42 | component_entry::DisableNoUninstallWarning, 43 | component_entry::Exclusive, 44 | ); 45 | 46 | // starting with version 4.2.3 47 | STORED_FLAGS_MAP(stored_component_flags_2, 48 | component_entry::Fixed, 49 | component_entry::Restart, 50 | component_entry::DisableNoUninstallWarning, 51 | component_entry::Exclusive, 52 | component_entry::DontInheritCheck, 53 | ); 54 | 55 | } // anonymous namespace 56 | 57 | void component_entry::load(std::istream & is, const info & i) { 58 | 59 | is >> util::encoded_string(name, i.codepage); 60 | is >> util::encoded_string(description, i.codepage); 61 | is >> util::encoded_string(types, i.codepage); 62 | if(i.version >= INNO_VERSION(4, 0, 1)) { 63 | is >> util::encoded_string(languages, i.codepage); 64 | } else { 65 | languages.clear(); 66 | } 67 | if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) { 68 | is >> util::encoded_string(check, i.codepage); 69 | } else { 70 | check.clear(); 71 | } 72 | if(i.version >= INNO_VERSION(4, 0, 0)) { 73 | extra_disk_pace_required = util::load(is); 74 | } else { 75 | extra_disk_pace_required = util::load(is); 76 | } 77 | if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(3, 0, 3))) { 78 | level = util::load(is); 79 | } else { 80 | level = 0; 81 | } 82 | if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(3, 0, 4))) { 83 | used = util::load_bool(is); 84 | } else { 85 | used = true; 86 | } 87 | 88 | winver.load(is, i.version); 89 | 90 | if(i.version >= INNO_VERSION(4, 2, 3)) { 91 | options = stored_flags(is).get(); 92 | } else if(i.version >= INNO_VERSION(3, 0, 8) || 93 | (i.version.is_isx() && i.version >= INNO_VERSION_EXT(3, 0, 6, 1))) { 94 | options = stored_flags(is).get(); 95 | } else { 96 | options = stored_flags(is).get(); 97 | } 98 | 99 | if(i.version >= INNO_VERSION(4, 0, 0)) { 100 | size = util::load(is); 101 | } else if(i.version >= INNO_VERSION(2, 0, 0) || 102 | (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) { 103 | size = util::load(is); 104 | } 105 | } 106 | 107 | } // namespace setup 108 | 109 | NAMES(setup::component_entry::flags, "Setup Component Option", 110 | "fixed", 111 | "restart", 112 | "disable no uninstall warning", 113 | "exclusive", 114 | "don't inherit check", 115 | ) 116 | -------------------------------------------------------------------------------- /src/setup/component.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for setup components stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_COMPONENT_HPP 27 | #define INNOEXTRACT_SETUP_COMPONENT_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include "setup/windows.hpp" 35 | #include "util/enum.hpp" 36 | #include "util/flags.hpp" 37 | 38 | namespace setup { 39 | 40 | struct info; 41 | 42 | struct component_entry { 43 | 44 | // introduced in 2.0.0 45 | 46 | FLAGS(flags, 47 | Fixed, 48 | Restart, 49 | DisableNoUninstallWarning, 50 | Exclusive, 51 | DontInheritCheck 52 | ); 53 | 54 | std::string name; 55 | std::string description; 56 | std::string types; 57 | std::string languages; 58 | std::string check; 59 | 60 | boost::uint64_t extra_disk_pace_required; 61 | 62 | int level; 63 | bool used; 64 | 65 | windows_version_range winver; 66 | 67 | flags options; 68 | 69 | boost::uint64_t size; 70 | 71 | void load(std::istream & is, const info & i); 72 | 73 | }; 74 | 75 | } // namespace setup 76 | 77 | NAMED_FLAGS(setup::component_entry::flags) 78 | 79 | #endif // INNOEXTRACT_SETUP_COMPONENT_HPP 80 | -------------------------------------------------------------------------------- /src/setup/data.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for file content entries stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_DATA_HPP 27 | #define INNOEXTRACT_SETUP_DATA_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include "crypto/checksum.hpp" 35 | #include "stream/chunk.hpp" 36 | #include "stream/file.hpp" 37 | #include "util/enum.hpp" 38 | #include "util/flags.hpp" 39 | 40 | namespace setup { 41 | 42 | struct info; 43 | 44 | struct data_entry { 45 | 46 | FLAGS(flags, 47 | 48 | VersionInfoValid, 49 | VersionInfoNotValid, 50 | TimeStampInUTC, 51 | IsUninstallerExe, 52 | CallInstructionOptimized, 53 | Touch, 54 | ChunkEncrypted, 55 | ChunkCompressed, 56 | SolidBreak, 57 | Sign, 58 | SignOnce, 59 | 60 | // obsolete: 61 | BZipped 62 | ); 63 | 64 | stream::chunk chunk; 65 | 66 | stream::file file; 67 | 68 | boost::uint64_t uncompressed_size; 69 | 70 | boost::int64_t timestamp; 71 | boost::uint32_t timestamp_nsec; 72 | 73 | boost::uint64_t file_version; 74 | 75 | flags options; 76 | 77 | enum sign_mode { 78 | NoSetting, 79 | Yes, 80 | Once, 81 | Check 82 | }; 83 | sign_mode sign; 84 | 85 | /*! 86 | * Load one data entry. 87 | * 88 | * \note This function may not be thread-safe on all operating systems. 89 | */ 90 | void load(std::istream & is, const info & i); 91 | 92 | }; 93 | 94 | } // namespace setup 95 | 96 | NAMED_FLAGS(setup::data_entry::flags) 97 | NAMED_ENUM(setup::data_entry::sign_mode) 98 | 99 | #endif // INNOEXTRACT_SETUP_DATA_HPP 100 | -------------------------------------------------------------------------------- /src/setup/delete.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/delete.hpp" 22 | 23 | #include "setup/info.hpp" 24 | #include "setup/version.hpp" 25 | #include "util/load.hpp" 26 | #include "util/storedenum.hpp" 27 | 28 | namespace setup { 29 | 30 | namespace { 31 | 32 | STORED_ENUM_MAP(delete_target_type_map, delete_entry::Files, 33 | delete_entry::Files, 34 | delete_entry::FilesAndSubdirs, 35 | delete_entry::DirIfEmpty, 36 | ); 37 | 38 | } // anonymous namespace 39 | 40 | void delete_entry::load(std::istream & is, const info & i) { 41 | 42 | if(i.version < INNO_VERSION(1, 3, 0)) { 43 | (void)util::load(is); // uncompressed size of the entry 44 | } 45 | 46 | is >> util::encoded_string(name, i.codepage, i.header.lead_bytes); 47 | 48 | load_condition_data(is, i); 49 | 50 | load_version_data(is, i.version); 51 | 52 | type = stored_enum(is).get(); 53 | } 54 | 55 | } // namespace setup 56 | 57 | NAMES(setup::delete_entry::target_type, "Delete Type", 58 | "files", 59 | "files and subdirs", 60 | "dir if empty", 61 | ) 62 | -------------------------------------------------------------------------------- /src/setup/delete.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for deletion entries stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_DELETE_HPP 27 | #define INNOEXTRACT_SETUP_DELETE_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include "setup/item.hpp" 33 | #include "util/enum.hpp" 34 | 35 | namespace setup { 36 | 37 | struct info; 38 | 39 | struct delete_entry : public item { 40 | 41 | enum target_type { 42 | Files, 43 | FilesAndSubdirs, 44 | DirIfEmpty, 45 | }; 46 | 47 | std::string name; 48 | 49 | target_type type; 50 | 51 | void load(std::istream & is, const info & i); 52 | 53 | }; 54 | 55 | } // namespace setup 56 | 57 | NAMED_ENUM(setup::delete_entry::target_type) 58 | 59 | #endif // INNOEXTRACT_SETUP_DELETE_HPP 60 | -------------------------------------------------------------------------------- /src/setup/directory.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/directory.hpp" 22 | 23 | #include "setup/info.hpp" 24 | #include "setup/version.hpp" 25 | #include "util/load.hpp" 26 | #include "util/storedenum.hpp" 27 | 28 | namespace setup { 29 | 30 | namespace { 31 | 32 | STORED_FLAGS_MAP(stored_inno_directory_options_0, 33 | directory_entry::NeverUninstall, 34 | directory_entry::DeleteAfterInstall, 35 | directory_entry::AlwaysUninstall, 36 | ); 37 | 38 | // starting with version 5.2.0 39 | STORED_FLAGS_MAP(stored_inno_directory_options_1, 40 | directory_entry::NeverUninstall, 41 | directory_entry::DeleteAfterInstall, 42 | directory_entry::AlwaysUninstall, 43 | directory_entry::SetNtfsCompression, 44 | directory_entry::UnsetNtfsCompression, 45 | ); 46 | 47 | } // anonymous namespace 48 | 49 | void directory_entry::load(std::istream & is, const info & i) { 50 | 51 | if(i.version < INNO_VERSION(1, 3, 0)) { 52 | (void)util::load(is); // uncompressed size of the entry 53 | } 54 | 55 | is >> util::encoded_string(name, i.codepage, i.header.lead_bytes); 56 | 57 | load_condition_data(is, i); 58 | 59 | if(i.version >= INNO_VERSION(4, 0, 11) && i.version < INNO_VERSION(4, 1, 0)) { 60 | is >> util::binary_string(permissions); 61 | } else { 62 | permissions.clear(); 63 | } 64 | 65 | if(i.version >= INNO_VERSION(2, 0, 11)) { 66 | attributes = util::load(is); 67 | } else { 68 | attributes = 0; 69 | } 70 | 71 | load_version_data(is, i.version); 72 | 73 | if(i.version >= INNO_VERSION(4, 1, 0)) { 74 | permission = util::load(is); 75 | } else { 76 | permission = boost::int16_t(-1); 77 | } 78 | 79 | if(i.version >= INNO_VERSION(5, 2, 0)) { 80 | options = stored_flags(is).get(); 81 | } else if(i.version.bits() != 16) { 82 | options = stored_flags(is).get(); 83 | } else { 84 | options = stored_flags(is).get(); 85 | } 86 | 87 | } 88 | 89 | } // namespace setup 90 | 91 | NAMES(setup::directory_entry::flags, "Directory Option", 92 | "never uninstall", 93 | "delete after install", 94 | "always uninstall", 95 | "set NTFS compression", 96 | "unset NTFS compression", 97 | ) 98 | -------------------------------------------------------------------------------- /src/setup/directory.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for directory entries stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_DIRECTORY_HPP 27 | #define INNOEXTRACT_SETUP_DIRECTORY_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include "setup/item.hpp" 35 | #include "util/enum.hpp" 36 | #include "util/flags.hpp" 37 | 38 | namespace setup { 39 | 40 | struct info; 41 | 42 | struct directory_entry : public item { 43 | 44 | FLAGS(flags, 45 | NeverUninstall, 46 | DeleteAfterInstall, 47 | AlwaysUninstall, 48 | SetNtfsCompression, 49 | UnsetNtfsCompression 50 | ); 51 | 52 | std::string name; 53 | std::string permissions; 54 | 55 | boost::uint32_t attributes; 56 | 57 | boost::int16_t permission; //!< index into the permission entry list 58 | 59 | flags options; 60 | 61 | void load(std::istream & is, const info & i); 62 | 63 | }; 64 | 65 | } // namespace setup 66 | 67 | NAMED_FLAGS(setup::directory_entry::flags) 68 | 69 | #endif // INNOEXTRACT_SETUP_DIRECTORY_HPP 70 | -------------------------------------------------------------------------------- /src/setup/expression.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Functions to evaluation Inno Setup boolean expressions. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_EXPRESSION_HPP 27 | #define INNOEXTRACT_SETUP_EXPRESSION_HPP 28 | 29 | #include 30 | 31 | namespace setup { 32 | 33 | /* 34 | * Determine if the given expression is satisfied with (only) the given test variable set to true 35 | */ 36 | bool expression_match(const std::string & test, const std::string & expression); 37 | 38 | bool is_simple_expression(const std::string & expression); 39 | 40 | } // namespace setup 41 | 42 | #endif // INNOEXTRACT_SETUP_EXPRESSION_HPP 43 | -------------------------------------------------------------------------------- /src/setup/file.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for file entries stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_FILE_HPP 27 | #define INNOEXTRACT_SETUP_FILE_HPP 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "crypto/checksum.hpp" 36 | #include "setup/item.hpp" 37 | #include "util/enum.hpp" 38 | #include "util/flags.hpp" 39 | 40 | namespace setup { 41 | 42 | struct info; 43 | 44 | struct file_entry : public item { 45 | 46 | FLAGS(flags, 47 | 48 | ConfirmOverwrite, 49 | NeverUninstall, 50 | RestartReplace, 51 | DeleteAfterInstall, 52 | RegisterServer, 53 | RegisterTypeLib, 54 | SharedFile, 55 | CompareTimeStamp, 56 | FontIsNotTrueType, 57 | SkipIfSourceDoesntExist, 58 | OverwriteReadOnly, 59 | OverwriteSameVersion, 60 | CustomDestName, 61 | OnlyIfDestFileExists, 62 | NoRegError, 63 | UninsRestartDelete, 64 | OnlyIfDoesntExist, 65 | IgnoreVersion, 66 | PromptIfOlder, 67 | DontCopy, 68 | UninsRemoveReadOnly, 69 | RecurseSubDirsExternal, 70 | ReplaceSameVersionIfContentsDiffer, 71 | DontVerifyChecksum, 72 | UninsNoSharedFilePrompt, 73 | CreateAllSubDirs, 74 | Bits32, 75 | Bits64, 76 | ExternalSizePreset, 77 | SetNtfsCompression, 78 | UnsetNtfsCompression, 79 | GacInstall, 80 | 81 | // obsolete options: 82 | IsReadmeFile 83 | ); 84 | 85 | enum file_type { 86 | UserFile, 87 | UninstExe, 88 | RegSvrExe, 89 | }; 90 | 91 | enum file_attributes { 92 | ReadOnly = 0x1 93 | }; 94 | 95 | std::string source; 96 | std::string destination; 97 | std::string install_font_name; 98 | std::string strong_assembly_name; 99 | 100 | boost::uint32_t location; //!< index into the data entry list 101 | boost::uint32_t attributes; 102 | boost::uint64_t external_size; 103 | 104 | boost::int16_t permission; //!< index into the permission entry list 105 | 106 | flags options; 107 | 108 | file_type type; 109 | 110 | // Information about GOG Galaxy multi-part files 111 | // These are not used in normal Inno Setup installers 112 | std::vector additional_locations; 113 | crypto::checksum checksum; 114 | boost::uint64_t size; 115 | 116 | void load(std::istream & is, const info & i); 117 | 118 | }; 119 | 120 | } // namespace setup 121 | 122 | NAMED_FLAGS(setup::file_entry::flags) 123 | NAMED_ENUM(setup::file_entry::file_type) 124 | 125 | #endif // INNOEXTRACT_SETUP_FILE_HPP 126 | -------------------------------------------------------------------------------- /src/setup/filename.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Map for converting between stored filenames and output filenames. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_FILENAME_HPP 27 | #define INNOEXTRACT_SETUP_FILENAME_HPP 28 | 29 | #include 30 | #include 31 | 32 | namespace setup { 33 | 34 | //! Separator to use for output paths. 35 | #if defined(_WIN32) 36 | static const char path_sep = '\\'; 37 | #else 38 | static const char path_sep = '/'; 39 | #endif 40 | 41 | /*! 42 | * Map to convert between raw windows file paths stored in the setup file (which can 43 | * contain variables) and output filenames. 44 | */ 45 | class filename_map : public std::map { 46 | 47 | std::string lookup(const std::string & key) const; 48 | 49 | bool lowercase; 50 | bool expand; 51 | 52 | typedef std::string::const_iterator it; 53 | 54 | std::string expand_variables(it & begin, it end, bool close = false) const; 55 | static std::string shorten_path(const std::string & path); 56 | 57 | public: 58 | 59 | filename_map() : lowercase(false), expand(false) { } 60 | 61 | std::string convert(std::string path) const; 62 | 63 | //! Set if paths should be converted to lower-case. 64 | void set_lowercase(bool enable) { lowercase = enable; } 65 | 66 | //! Set if paths should be converted to lower-case. 67 | bool is_lowercase() const { return lowercase; } 68 | 69 | //! Set if variables should be expanded and path separators converted. 70 | void set_expand(bool enable) { expand = enable; } 71 | 72 | }; 73 | 74 | } // namespace setup 75 | 76 | #endif // INNOEXTRACT_SETUP_FILENAME_HPP 77 | -------------------------------------------------------------------------------- /src/setup/icon.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/icon.hpp" 22 | 23 | #include "setup/info.hpp" 24 | #include "setup/version.hpp" 25 | #include "util/load.hpp" 26 | #include "util/storedenum.hpp" 27 | 28 | namespace setup { 29 | 30 | namespace { 31 | 32 | STORED_ENUM_MAP(stored_close_setting, icon_entry::NoSetting, 33 | icon_entry::NoSetting, 34 | icon_entry::CloseOnExit, 35 | icon_entry::DontCloseOnExit, 36 | ); 37 | 38 | } // anonymous namespace 39 | 40 | void icon_entry::load(std::istream & is, const info & i) { 41 | 42 | if(i.version < INNO_VERSION(1, 3, 0)) { 43 | (void)util::load(is); // uncompressed size of the entry 44 | } 45 | 46 | is >> util::encoded_string(name, i.codepage, i.header.lead_bytes); 47 | is >> util::encoded_string(filename, i.codepage, i.header.lead_bytes); 48 | is >> util::encoded_string(parameters, i.codepage, i.header.lead_bytes); 49 | is >> util::encoded_string(working_dir, i.codepage, i.header.lead_bytes); 50 | is >> util::encoded_string(icon_file, i.codepage, i.header.lead_bytes); 51 | is >> util::encoded_string(comment, i.codepage); 52 | 53 | load_condition_data(is, i); 54 | 55 | if(i.version >= INNO_VERSION(5, 3, 5)) { 56 | is >> util::encoded_string(app_user_model_id, i.codepage); 57 | } else { 58 | app_user_model_id.clear(); 59 | } 60 | 61 | if(i.version >= INNO_VERSION(6, 1, 0)) { 62 | const size_t guid_size = 16; 63 | app_user_model_toast_activator_clsid.resize(guid_size); 64 | is.read(&app_user_model_toast_activator_clsid[0], std::streamsize(guid_size)); 65 | } else { 66 | app_user_model_toast_activator_clsid.clear(); 67 | } 68 | 69 | load_version_data(is, i.version); 70 | 71 | icon_index = util::load(is, i.version.bits()); 72 | 73 | if(i.version >= INNO_VERSION(1, 3, 24)) { 74 | show_command = util::load(is); 75 | } else { 76 | show_command = 1; 77 | } 78 | if(i.version >= INNO_VERSION(1, 3, 15)) { 79 | close_on_exit = stored_enum(is).get(); 80 | } else { 81 | close_on_exit = NoSetting; 82 | } 83 | 84 | if(i.version >= INNO_VERSION(2, 0, 7)) { 85 | hotkey = util::load(is); 86 | } else { 87 | hotkey = 0; 88 | } 89 | 90 | stored_flag_reader flagreader(is, i.version.bits()); 91 | 92 | flagreader.add(NeverUninstall); 93 | if(i.version < INNO_VERSION(1, 3, 26)) { 94 | flagreader.add(RunMinimized); 95 | } 96 | flagreader.add(CreateOnlyIfFileExists); 97 | if(i.version.bits() != 16) { 98 | flagreader.add(UseAppPaths); 99 | } 100 | if(i.version >= INNO_VERSION(5, 0, 3) && i.version < INNO_VERSION(6, 3, 0)) { 101 | flagreader.add(FolderShortcut); 102 | } 103 | if(i.version >= INNO_VERSION(5, 4, 2)) { 104 | flagreader.add(ExcludeFromShowInNewInstall); 105 | } 106 | if(i.version >= INNO_VERSION(5, 5, 0)) { 107 | flagreader.add(PreventPinning); 108 | } 109 | if(i.version >= INNO_VERSION(6, 1, 0)) { 110 | flagreader.add(HasAppUserModelToastActivatorCLSID); 111 | } 112 | 113 | options = flagreader.finalize(); 114 | } 115 | 116 | } // namespace setup 117 | 118 | NAMES(setup::icon_entry::flags, "Icon Option", 119 | "never uninstall", 120 | "create only if file exists", 121 | "use app paths", 122 | "folder shortcut", 123 | "exclude from show in new install", 124 | "prevent pinning", 125 | "run minimized", 126 | ) 127 | 128 | NAMES(setup::icon_entry::close_setting, "Close on Exit", 129 | "no setting", 130 | "close on exit", 131 | "don't close on exit", 132 | ) 133 | -------------------------------------------------------------------------------- /src/setup/icon.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for menu/desktop shortcuts stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_ICON_HPP 27 | #define INNOEXTRACT_SETUP_ICON_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include "setup/item.hpp" 35 | #include "util/enum.hpp" 36 | #include "util/flags.hpp" 37 | 38 | namespace setup { 39 | 40 | struct info; 41 | 42 | struct icon_entry : public item { 43 | 44 | FLAGS(flags, 45 | NeverUninstall, 46 | CreateOnlyIfFileExists, 47 | UseAppPaths, 48 | FolderShortcut, 49 | ExcludeFromShowInNewInstall, 50 | PreventPinning, 51 | HasAppUserModelToastActivatorCLSID, 52 | // obsolete options: 53 | RunMinimized 54 | ); 55 | 56 | enum close_setting { 57 | NoSetting, 58 | CloseOnExit, 59 | DontCloseOnExit, 60 | }; 61 | 62 | std::string name; 63 | std::string filename; 64 | std::string parameters; 65 | std::string working_dir; 66 | std::string icon_file; 67 | std::string comment; 68 | std::string app_user_model_id; 69 | std::string app_user_model_toast_activator_clsid; 70 | 71 | int icon_index; 72 | 73 | int show_command; 74 | 75 | close_setting close_on_exit; 76 | 77 | boost::uint16_t hotkey; 78 | 79 | flags options; 80 | 81 | void load(std::istream & is, const info & i); 82 | 83 | }; 84 | 85 | } // namespace setup 86 | 87 | NAMED_FLAGS(setup::icon_entry::flags) 88 | NAMED_ENUM(setup::icon_entry::close_setting) 89 | 90 | #endif // INNOEXTRACT_SETUP_ICON_HPP 91 | -------------------------------------------------------------------------------- /src/setup/ini.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/ini.hpp" 22 | 23 | #include 24 | 25 | #include "setup/info.hpp" 26 | #include "setup/version.hpp" 27 | #include "util/load.hpp" 28 | #include "util/storedenum.hpp" 29 | 30 | namespace setup { 31 | 32 | namespace { 33 | 34 | STORED_FLAGS_MAP(stored_ini_flags, 35 | ini_entry::CreateKeyIfDoesntExist, 36 | ini_entry::UninsDeleteEntry, 37 | ini_entry::UninsDeleteEntireSection, 38 | ini_entry::UninsDeleteSectionIfEmpty, 39 | ini_entry::HasValue, 40 | ); 41 | 42 | } // anonymous namespace 43 | 44 | void ini_entry::load(std::istream & is, const info & i) { 45 | 46 | if(i.version < INNO_VERSION(1, 3, 0)) { 47 | (void)util::load(is); // uncompressed size of the entry 48 | } 49 | 50 | is >> util::encoded_string(inifile, i.codepage, i.header.lead_bytes); 51 | if(inifile.empty()) { 52 | inifile = "{windows}/WIN.INI"; 53 | } 54 | is >> util::encoded_string(section, i.codepage, i.header.lead_bytes); 55 | is >> util::encoded_string(key, i.codepage); 56 | is >> util::encoded_string(value, i.codepage, i.header.lead_bytes); 57 | 58 | load_condition_data(is, i); 59 | 60 | load_version_data(is, i.version); 61 | 62 | if(i.version.bits() != 16) { 63 | options = stored_flags(is).get(); 64 | } else { 65 | options = stored_flags(is).get(); 66 | } 67 | } 68 | 69 | } // namespace setup 70 | 71 | NAMES(setup::ini_entry::flags, "Ini Option", 72 | "create key if doesn't exist", 73 | "uninstall delete entry", 74 | "uninstall delete section", 75 | "uninstall delete section if empty", 76 | "has value", 77 | ) 78 | -------------------------------------------------------------------------------- /src/setup/ini.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for .ini entries stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_INI_HPP 27 | #define INNOEXTRACT_SETUP_INI_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include "setup/item.hpp" 33 | #include "util/enum.hpp" 34 | #include "util/flags.hpp" 35 | 36 | namespace setup { 37 | 38 | struct info; 39 | 40 | struct ini_entry : public item { 41 | 42 | FLAGS(flags, 43 | CreateKeyIfDoesntExist, 44 | UninsDeleteEntry, 45 | UninsDeleteEntireSection, 46 | UninsDeleteSectionIfEmpty, 47 | HasValue 48 | ); 49 | 50 | std::string inifile; 51 | std::string section; 52 | std::string key; 53 | std::string value; 54 | 55 | flags options; 56 | 57 | void load(std::istream & is, const info & i); 58 | 59 | }; 60 | 61 | } // namespace setup 62 | 63 | NAMED_FLAGS(setup::ini_entry::flags) 64 | 65 | #endif // INNOEXTRACT_SETUP_INI_HPP 66 | -------------------------------------------------------------------------------- /src/setup/item.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/item.hpp" 22 | 23 | #include "setup/info.hpp" 24 | #include "setup/version.hpp" 25 | #include "util/load.hpp" 26 | 27 | namespace setup { 28 | 29 | void item::load_condition_data(std::istream & is, const info & i) { 30 | 31 | if(i.version >= INNO_VERSION(2, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 8))) { 32 | is >> util::encoded_string(components, i.codepage); 33 | } else { 34 | components.clear(); 35 | } 36 | if(i.version >= INNO_VERSION(2, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 17))) { 37 | is >> util::encoded_string(tasks, i.codepage); 38 | } else { 39 | tasks.clear(); 40 | } 41 | if(i.version >= INNO_VERSION(4, 0, 1)) { 42 | is >> util::encoded_string(languages, i.codepage); 43 | } else { 44 | languages.clear(); 45 | } 46 | if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) { 47 | is >> util::encoded_string(check, i.codepage); 48 | } else { 49 | check.clear(); 50 | } 51 | 52 | if(i.version >= INNO_VERSION(4, 1, 0)) { 53 | is >> util::encoded_string(after_install, i.codepage); 54 | is >> util::encoded_string(before_install, i.codepage); 55 | } else { 56 | after_install.clear(), before_install.clear(); 57 | } 58 | 59 | } 60 | 61 | } // namespace setup 62 | -------------------------------------------------------------------------------- /src/setup/item.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for setup items stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_ITEM_HPP 27 | #define INNOEXTRACT_SETUP_ITEM_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include "setup/windows.hpp" 33 | 34 | namespace setup { 35 | 36 | struct info; 37 | struct version; 38 | 39 | struct item { 40 | 41 | std::string components; 42 | std::string tasks; 43 | std::string languages; 44 | std::string check; 45 | 46 | std::string after_install; 47 | std::string before_install; 48 | 49 | windows_version_range winver; 50 | 51 | protected: 52 | 53 | void load_condition_data(std::istream & is, const info & i); 54 | 55 | void load_version_data(std::istream & is, const version & version) { 56 | winver.load(is, version); 57 | } 58 | 59 | }; 60 | 61 | } // namespace setup 62 | 63 | #endif // INNOEXTRACT_SETUP_ITEM_HPP 64 | -------------------------------------------------------------------------------- /src/setup/language.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for language entries stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_LANGUAGE_HPP 27 | #define INNOEXTRACT_SETUP_LANGUAGE_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include "util/encoding.hpp" 35 | 36 | namespace setup { 37 | 38 | struct info; 39 | 40 | struct language_entry { 41 | 42 | // introduced in 2.0.1 43 | 44 | std::string name; 45 | std::string language_name; 46 | std::string dialog_font; 47 | std::string title_font; 48 | std::string welcome_font; 49 | std::string copyright_font; 50 | std::string data; 51 | std::string license_text; 52 | std::string info_before; 53 | std::string info_after; 54 | 55 | boost::uint32_t language_id; 56 | boost::uint32_t codepage; 57 | size_t dialog_font_size; 58 | size_t dialog_font_standard_height; 59 | size_t title_font_size; 60 | size_t welcome_font_size; 61 | size_t copyright_font_size; 62 | 63 | bool right_to_left; 64 | 65 | void load(std::istream & is, const info & i); 66 | 67 | void decode(util::codepage_id cp); 68 | 69 | }; 70 | 71 | } // namespace setup 72 | 73 | #endif // INNOEXTRACT_SETUP_LANGUAGE_HPP 74 | -------------------------------------------------------------------------------- /src/setup/message.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/message.hpp" 22 | 23 | #include 24 | 25 | #include "setup/info.hpp" 26 | #include "setup/language.hpp" 27 | #include "setup/version.hpp" 28 | #include "util/encoding.hpp" 29 | #include "util/load.hpp" 30 | #include "util/log.hpp" 31 | 32 | namespace setup { 33 | 34 | void message_entry::load(std::istream & is, const info & i) { 35 | 36 | is >> util::encoded_string(name, i.codepage); 37 | is >> util::binary_string(value); 38 | 39 | language = util::load(is); 40 | 41 | boost::uint32_t codepage; 42 | if(language < 0) { 43 | codepage = i.codepage; 44 | } else if(size_t(language) >= i.languages.size()) { 45 | if(!i.languages.empty()) { 46 | log_warning << "Language index out of bounds: " << language; 47 | } 48 | value.clear(); 49 | return; 50 | } else { 51 | codepage = i.languages[size_t(language)].codepage; 52 | } 53 | 54 | util::to_utf8(value, codepage); 55 | } 56 | 57 | } // namespace setup 58 | -------------------------------------------------------------------------------- /src/setup/message.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for custom localized messages stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_MESSAGE_HPP 27 | #define INNOEXTRACT_SETUP_MESSAGE_HPP 28 | 29 | #include 30 | #include 31 | 32 | namespace setup { 33 | 34 | struct info; 35 | 36 | struct message_entry { 37 | 38 | // introduced in 4.2.1 39 | 40 | // UTF-8 encoded name. 41 | std::string name; 42 | 43 | // Value encoded in the codepage specified at language index. 44 | std::string value; 45 | 46 | // Index into the default language entry list or -1. 47 | int language; 48 | 49 | void load(std::istream & is, const info & i); 50 | 51 | }; 52 | 53 | } // namespace setup 54 | 55 | #endif // INNOEXTRACT_SETUP_MESSAGE_HPP 56 | -------------------------------------------------------------------------------- /src/setup/permission.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/permission.hpp" 22 | 23 | #include "util/load.hpp" 24 | 25 | namespace setup { 26 | 27 | void permission_entry::load(std::istream & is, const info & /* i */) { 28 | 29 | is >> util::binary_string(permissions); // an array of TGrantPermissionEntry's 30 | 31 | } 32 | 33 | } // namespace setup 34 | -------------------------------------------------------------------------------- /src/setup/permission.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for permission entries stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_PERMISSION_HPP 27 | #define INNOEXTRACT_SETUP_PERMISSION_HPP 28 | 29 | #include 30 | #include 31 | 32 | namespace setup { 33 | 34 | struct info; 35 | 36 | struct permission_entry { 37 | 38 | // introduced in 4.1.0 39 | 40 | std::string permissions; 41 | 42 | void load(std::istream & is, const info & i); 43 | 44 | }; 45 | 46 | } // namespace setup 47 | 48 | #endif // INNOEXTRACT_SETUP_PERMISSION_HPP 49 | -------------------------------------------------------------------------------- /src/setup/registry.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for Windows registry entries stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_REGISTRY_HPP 27 | #define INNOEXTRACT_SETUP_REGISTRY_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include "setup/item.hpp" 33 | #include "setup/windows.hpp" 34 | #include "util/enum.hpp" 35 | #include "util/flags.hpp" 36 | 37 | namespace setup { 38 | 39 | struct info; 40 | 41 | struct registry_entry : public item { 42 | 43 | FLAGS(flags, 44 | CreateValueIfDoesntExist, 45 | UninsDeleteValue, 46 | UninsClearValue, 47 | UninsDeleteEntireKey, 48 | UninsDeleteEntireKeyIfEmpty, 49 | PreserveStringType, 50 | DeleteKey, 51 | DeleteValue, 52 | NoError, 53 | DontCreateKey, 54 | Bits32, 55 | Bits64 56 | ); 57 | 58 | enum hive_name { 59 | HKCR, 60 | HKCU, 61 | HKLM, 62 | HKU, 63 | HKPD, 64 | HKCC, 65 | HKDD, 66 | Unset, 67 | }; 68 | 69 | enum value_type { 70 | None, 71 | String, 72 | ExpandString, 73 | DWord, 74 | Binary, 75 | MultiString, 76 | QWord, 77 | }; 78 | 79 | std::string key; 80 | std::string name; // empty string means (Default) key 81 | std::string value; 82 | 83 | std::string permissions; 84 | 85 | hive_name hive; 86 | 87 | int permission; //!< index into the permission entry list 88 | 89 | value_type type; 90 | 91 | flags options; 92 | 93 | void load(std::istream & is, const info & i); 94 | 95 | }; 96 | 97 | } // namespace setup 98 | 99 | NAMED_FLAGS(setup::registry_entry::flags) 100 | NAMED_ENUM(setup::registry_entry::hive_name) 101 | NAMED_ENUM(setup::registry_entry::value_type) 102 | 103 | #endif // INNOEXTRACT_SETUP_REGISTRY_HPP 104 | -------------------------------------------------------------------------------- /src/setup/run.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/run.hpp" 22 | 23 | #include 24 | 25 | #include "setup/info.hpp" 26 | #include "setup/version.hpp" 27 | #include "util/load.hpp" 28 | #include "util/storedenum.hpp" 29 | 30 | namespace setup { 31 | 32 | namespace { 33 | 34 | STORED_ENUM_MAP(stored_run_wait_condition, run_entry::WaitUntilTerminated, 35 | run_entry::WaitUntilTerminated, 36 | run_entry::NoWait, 37 | run_entry::WaitUntilIdle, 38 | ); 39 | 40 | } // anonymous namespace 41 | 42 | void run_entry::load(std::istream & is, const info & i) { 43 | 44 | if(i.version < INNO_VERSION(1, 3, 0)) { 45 | (void)util::load(is); // uncompressed size of the entry 46 | } 47 | 48 | is >> util::encoded_string(name, i.codepage, i.header.lead_bytes); 49 | is >> util::encoded_string(parameters, i.codepage, i.header.lead_bytes); 50 | is >> util::encoded_string(working_dir, i.codepage, i.header.lead_bytes); 51 | if(i.version >= INNO_VERSION(1, 3, 9)) { 52 | is >> util::encoded_string(run_once_id, i.codepage); 53 | } else { 54 | run_once_id.clear(); 55 | } 56 | if(i.version >= INNO_VERSION(2, 0, 2)) { 57 | is >> util::encoded_string(status_message, i.codepage); 58 | } else { 59 | status_message.clear(); 60 | } 61 | if(i.version >= INNO_VERSION(5, 1, 13)) { 62 | is >> util::encoded_string(verb, i.codepage); 63 | } else { 64 | verb.clear(); 65 | } 66 | if(i.version >= INNO_VERSION(2, 0, 0) || i.version.is_isx()) { 67 | is >> util::encoded_string(description, i.codepage); 68 | } 69 | 70 | load_condition_data(is, i); 71 | 72 | load_version_data(is, i.version); 73 | 74 | if(i.version >= INNO_VERSION(1, 3, 24)) { 75 | show_command = util::load(is); 76 | } else { 77 | show_command = 0; 78 | } 79 | 80 | wait = stored_enum(is).get(); 81 | 82 | stored_flag_reader flagreader(is, i.version.bits()); 83 | 84 | if(i.version >= INNO_VERSION(1, 2, 3)) { 85 | flagreader.add(ShellExec); 86 | } 87 | if(i.version >= INNO_VERSION(1, 3, 9) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 8))) { 88 | flagreader.add(SkipIfDoesntExist); 89 | } 90 | if(i.version >= INNO_VERSION(2, 0, 0)) { 91 | flagreader.add(PostInstall); 92 | flagreader.add(Unchecked); 93 | flagreader.add(SkipIfSilent); 94 | flagreader.add(SkipIfNotSilent); 95 | } 96 | if(i.version >= INNO_VERSION(2, 0, 8)) { 97 | flagreader.add(HideWizard); 98 | } 99 | if(i.version >= INNO_VERSION(5, 1, 10)) { 100 | flagreader.add(Bits32); 101 | flagreader.add(Bits64); 102 | } 103 | if(i.version >= INNO_VERSION(5, 2, 0)) { 104 | flagreader.add(RunAsOriginalUser); 105 | } 106 | if(i.version >= INNO_VERSION(6, 1, 0)) { 107 | flagreader.add(DontLogParameters); 108 | } 109 | if(i.version >= INNO_VERSION(6, 3, 0)) { 110 | flagreader.add(LogOutput); 111 | } 112 | 113 | options = flagreader.finalize(); 114 | } 115 | 116 | } // namespace setup 117 | 118 | NAMES(setup::run_entry::flags, "Run Option", 119 | "shell exec", 120 | "skip if doesn't exist", 121 | "post install", 122 | "unchecked", 123 | "skip if silent", 124 | "skip if not silent", 125 | "hide wizard", 126 | "32 bit", 127 | "64 bit", 128 | "run as original user", 129 | "don't log parameters", 130 | "log output", 131 | ) 132 | 133 | NAMES(setup::run_entry::wait_condition, "Run Wait Type", 134 | "wait until terminated", 135 | "no wait", 136 | "wait until idle", 137 | ) 138 | -------------------------------------------------------------------------------- /src/setup/run.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for custom command entries stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_RUN_HPP 27 | #define INNOEXTRACT_SETUP_RUN_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include "setup/item.hpp" 33 | #include "util/enum.hpp" 34 | #include "util/flags.hpp" 35 | 36 | namespace setup { 37 | 38 | struct info; 39 | 40 | struct run_entry : public item { 41 | 42 | FLAGS(flags, 43 | ShellExec, 44 | SkipIfDoesntExist, 45 | PostInstall, 46 | Unchecked, 47 | SkipIfSilent, 48 | SkipIfNotSilent, 49 | HideWizard, 50 | Bits32, 51 | Bits64, 52 | RunAsOriginalUser, 53 | DontLogParameters, 54 | LogOutput 55 | ); 56 | 57 | enum wait_condition { 58 | WaitUntilTerminated, 59 | NoWait, 60 | WaitUntilIdle, 61 | }; 62 | 63 | std::string name; 64 | std::string parameters; 65 | std::string working_dir; 66 | std::string run_once_id; 67 | std::string status_message; 68 | std::string verb; 69 | std::string description; 70 | 71 | int show_command; 72 | 73 | wait_condition wait; 74 | 75 | flags options; 76 | 77 | void load(std::istream & is, const info & i); 78 | 79 | }; 80 | 81 | } // namespace setup 82 | 83 | NAMED_FLAGS(setup::run_entry::flags) 84 | NAMED_ENUM(setup::run_entry::wait_condition) 85 | 86 | #endif // INNOEXTRACT_SETUP_RUN_HPP 87 | -------------------------------------------------------------------------------- /src/setup/task.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/task.hpp" 22 | 23 | #include 24 | 25 | #include "setup/info.hpp" 26 | #include "setup/version.hpp" 27 | #include "util/load.hpp" 28 | #include "util/storedenum.hpp" 29 | 30 | namespace setup { 31 | 32 | void task_entry::load(std::istream & is, const info & i) { 33 | 34 | is >> util::encoded_string(name, i.codepage); 35 | is >> util::encoded_string(description, i.codepage); 36 | is >> util::encoded_string(group_description, i.codepage); 37 | is >> util::encoded_string(components, i.codepage); 38 | if(i.version >= INNO_VERSION(4, 0, 1)) { 39 | is >> util::encoded_string(languages, i.codepage); 40 | } else { 41 | languages.clear(); 42 | } 43 | if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) { 44 | is >> util::encoded_string(check, i.codepage); 45 | } else { 46 | check.clear(); 47 | } 48 | if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(3, 0, 3))) { 49 | level = util::load(is); 50 | } else { 51 | level = 0; 52 | } 53 | if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(3, 0, 4))) { 54 | used = util::load_bool(is); 55 | } else { 56 | used = true; 57 | } 58 | 59 | winver.load(is, i.version); 60 | 61 | stored_flag_reader flagreader(is); 62 | 63 | flagreader.add(Exclusive); 64 | flagreader.add(Unchecked); 65 | if(i.version >= INNO_VERSION(2, 0, 5)) { 66 | flagreader.add(Restart); 67 | } 68 | if(i.version >= INNO_VERSION(2, 0, 6)) { 69 | flagreader.add(CheckedOnce); 70 | } 71 | if(i.version >= INNO_VERSION(4, 2, 3)) { 72 | flagreader.add(DontInheritCheck); 73 | } 74 | 75 | options = flagreader.finalize(); 76 | } 77 | 78 | } // namespace setup 79 | 80 | NAMES(setup::task_entry::flags, "Setup Task Option", 81 | "exclusive", 82 | "unchecked", 83 | "restart", 84 | "checked once", 85 | "don't inherit check", 86 | ) 87 | -------------------------------------------------------------------------------- /src/setup/task.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for setup tasks stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_TASK_HPP 27 | #define INNOEXTRACT_SETUP_TASK_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include "setup/windows.hpp" 33 | #include "util/enum.hpp" 34 | #include "util/flags.hpp" 35 | 36 | namespace setup { 37 | 38 | struct info; 39 | 40 | struct task_entry { 41 | 42 | // introduced in 2.0.0 43 | 44 | FLAGS(flags, 45 | Exclusive, 46 | Unchecked, 47 | Restart, 48 | CheckedOnce, 49 | DontInheritCheck 50 | ); 51 | 52 | std::string name; 53 | std::string description; 54 | std::string group_description; 55 | std::string components; 56 | std::string languages; 57 | std::string check; 58 | 59 | int level; 60 | bool used; 61 | 62 | windows_version_range winver; 63 | 64 | flags options; 65 | 66 | void load(std::istream & is, const info & i); 67 | 68 | }; 69 | 70 | } // namespace setup 71 | 72 | NAMED_FLAGS(setup::task_entry::flags) 73 | 74 | #endif // INNOEXTRACT_SETUP_TASK_HPP 75 | -------------------------------------------------------------------------------- /src/setup/type.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "setup/type.hpp" 22 | 23 | #include "setup/info.hpp" 24 | #include "setup/version.hpp" 25 | #include "util/load.hpp" 26 | #include "util/storedenum.hpp" 27 | 28 | namespace setup { 29 | 30 | namespace { 31 | 32 | FLAGS(type_flags, 33 | CustomSetupType 34 | ); 35 | 36 | STORED_FLAGS_MAP(stored_type_flags, 37 | CustomSetupType, 38 | ); 39 | 40 | STORED_ENUM_MAP(stored_setup_type, type_entry::User, 41 | type_entry::User, 42 | type_entry::DefaultFull, 43 | type_entry::DefaultCompact, 44 | type_entry::DefaultCustom, 45 | ); 46 | 47 | } // anonymous namespace 48 | 49 | } // namespace setup 50 | 51 | NAMED_FLAGS(setup::type_flags) 52 | 53 | namespace setup { 54 | 55 | void type_entry::load(std::istream & is, const info & i) { 56 | 57 | USE_FLAG_NAMES(setup::type_flags) 58 | 59 | is >> util::encoded_string(name, i.codepage); 60 | is >> util::encoded_string(description, i.codepage); 61 | if(i.version >= INNO_VERSION(4, 0, 1)) { 62 | is >> util::encoded_string(languages, i.codepage); 63 | } else { 64 | languages.clear(); 65 | } 66 | if(i.version >= INNO_VERSION(4, 0, 0) || (i.version.is_isx() && i.version >= INNO_VERSION(1, 3, 24))) { 67 | is >> util::encoded_string(check, i.codepage); 68 | } else { 69 | check.clear(); 70 | } 71 | 72 | winver.load(is, i.version); 73 | 74 | type_flags options = stored_flags(is).get(); 75 | custom_type = ((options & CustomSetupType) != 0); 76 | 77 | if(i.version >= INNO_VERSION(4, 0, 3)) { 78 | type = stored_enum(is).get(); 79 | } else { 80 | type = User; 81 | } 82 | 83 | if(i.version >= INNO_VERSION(4, 0, 0)) { 84 | size = util::load(is); 85 | } else { 86 | size = util::load(is); 87 | } 88 | } 89 | 90 | } // namespace setup 91 | 92 | NAMES(setup::type_flags, "Setyp Type Option", 93 | "is custom", 94 | ) 95 | 96 | NAMES(setup::type_entry::setup_type, "Setyp Type", 97 | "user", 98 | "default full", 99 | "default compact", 100 | "default custom", 101 | ) 102 | -------------------------------------------------------------------------------- /src/setup/type.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for setup types stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_TYPE_HPP 27 | #define INNOEXTRACT_SETUP_TYPE_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include "setup/windows.hpp" 35 | #include "util/enum.hpp" 36 | #include "util/flags.hpp" 37 | 38 | namespace setup { 39 | 40 | struct info; 41 | 42 | struct type_entry { 43 | 44 | // introduced in 2.0.0 45 | 46 | enum setup_type { 47 | User, 48 | DefaultFull, 49 | DefaultCompact, 50 | DefaultCustom 51 | }; 52 | 53 | std::string name; 54 | std::string description; 55 | std::string languages; 56 | std::string check; 57 | 58 | windows_version_range winver; 59 | 60 | bool custom_type; 61 | 62 | setup_type type; 63 | 64 | boost::uint64_t size; 65 | 66 | void load(std::istream & is, const info & i); 67 | 68 | }; 69 | 70 | } // namespace setup 71 | 72 | NAMED_ENUM(setup::type_entry::setup_type) 73 | 74 | #endif // INNOEXTRACT_SETUP_TYPE_HPP 75 | -------------------------------------------------------------------------------- /src/setup/version.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Inno Setup version number utilities. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_VERSION_HPP 27 | #define INNOEXTRACT_SETUP_VERSION_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include "util/flags.hpp" 35 | 36 | namespace setup { 37 | 38 | struct version_error : public std::exception { }; 39 | 40 | typedef boost::uint32_t version_constant; 41 | #define INNO_VERSION_EXT(a, b, c, d) ( \ 42 | (::setup::version_constant(a) << 24) \ 43 | | (::setup::version_constant(b) << 16) \ 44 | | (::setup::version_constant(c) << 8) \ 45 | | (::setup::version_constant(d) << 0) \ 46 | ) 47 | #define INNO_VERSION(a, b, c) INNO_VERSION_EXT(a, b, c, 0) 48 | 49 | struct version { 50 | 51 | FLAGS(flags, 52 | Bits16, 53 | Unicode, 54 | ISX 55 | ); 56 | 57 | version_constant value; 58 | 59 | flags variant; 60 | 61 | bool known; 62 | 63 | version() : value(0), variant(0), known(false) { } 64 | 65 | version(version_constant v, flags type = 0, bool is_known = false) 66 | : value(v), variant(type), known(is_known) { } 67 | 68 | 69 | version(boost::uint8_t a, boost::uint8_t b, boost::uint8_t c, boost::uint8_t d = 0, 70 | flags type = 0, bool is_known = false) 71 | : value(INNO_VERSION_EXT(a, b, c, d)), variant(type), known(is_known) { } 72 | 73 | unsigned int a() const { return value >> 24; } 74 | unsigned int b() const { return (value >> 16) & 0xff; } 75 | unsigned int c() const { return (value >> 8) & 0xff; } 76 | unsigned int d() const { return value & 0xff; } 77 | 78 | void load(std::istream & is); 79 | 80 | boost::uint16_t bits() const { return (variant & Bits16) ? 16 : 32; } 81 | bool is_unicode() const { return (variant & Unicode) != 0; } 82 | bool is_isx() const { return (variant & ISX) != 0; } 83 | 84 | //! \return true if the version stored might not be correct 85 | bool is_ambiguous() const; 86 | 87 | operator version_constant() const { 88 | return value; 89 | } 90 | 91 | version_constant next(); 92 | 93 | }; 94 | 95 | std::ostream & operator<<(std::ostream & os, const version & version); 96 | 97 | } // namespace setup 98 | 99 | #endif // INNOEXTRACT_SETUP_VERSION_HPP 100 | -------------------------------------------------------------------------------- /src/setup/windows.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Structures for Windows version numbers stored in Inno Setup files. 25 | */ 26 | #ifndef INNOEXTRACT_SETUP_WINDOWS_HPP 27 | #define INNOEXTRACT_SETUP_WINDOWS_HPP 28 | 29 | #include 30 | 31 | namespace setup { 32 | 33 | struct version; 34 | 35 | struct windows_version { 36 | 37 | struct data { 38 | 39 | unsigned major; 40 | unsigned minor; 41 | unsigned build; 42 | 43 | bool operator==(const data & o) const { 44 | return (build == o.build && major == o.major && minor == o.minor); 45 | } 46 | 47 | bool operator!=(const data & o) const { 48 | return !(*this == o); 49 | } 50 | 51 | void load(std::istream & is, const version & version); 52 | 53 | }; 54 | 55 | data win_version; 56 | data nt_version; 57 | 58 | struct service_pack { 59 | 60 | unsigned major; 61 | unsigned minor; 62 | 63 | bool operator==(const service_pack & o) const { 64 | return (major == o.major && minor == o.minor); 65 | } 66 | 67 | bool operator!=(const service_pack & o) const { 68 | return !(*this == o); 69 | } 70 | 71 | }; 72 | 73 | service_pack nt_service_pack; 74 | 75 | void load(std::istream & is, const version & version); 76 | 77 | bool operator==(const windows_version & o) const { 78 | return (win_version == o.win_version 79 | && nt_version == o.nt_version 80 | && nt_service_pack == o.nt_service_pack); 81 | } 82 | 83 | bool operator!=(const windows_version & o) const { 84 | return !(*this == o); 85 | } 86 | 87 | static const windows_version none; 88 | 89 | }; 90 | 91 | struct windows_version_range { 92 | 93 | windows_version begin; 94 | windows_version end; 95 | 96 | void load(std::istream & is, const version & version); 97 | 98 | }; 99 | 100 | std::ostream & operator<<(std::ostream & os, const windows_version::data & version); 101 | std::ostream & operator<<(std::ostream & os, const windows_version & version); 102 | 103 | } // namespace setup 104 | 105 | #endif // INNOEXTRACT_SETUP_WINDOWS_HPP 106 | -------------------------------------------------------------------------------- /src/stream/block.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Wrapper to read, checksum and decompress header blocks. 25 | * 26 | * Thse blocks are used to store the setup headers (\ref setup). 27 | */ 28 | #ifndef INNOEXTRACT_STREAM_BLOCK_HPP 29 | #define INNOEXTRACT_STREAM_BLOCK_HPP 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include "util/unique_ptr.hpp" 36 | 37 | namespace setup { struct version; } 38 | 39 | namespace stream { 40 | 41 | //! Error thrown by \ref chunk_reader::get or the returned stream if there was a problem. 42 | struct block_error : public std::ios_base::failure { 43 | 44 | explicit block_error(const std::string & msg) : std::ios_base::failure(msg) { } 45 | 46 | }; 47 | 48 | /*! 49 | * Wrapper to read compressed and checksumed block of data used to store setup headers. 50 | * 51 | * The decompressed headers are parsed in \ref setup::info, which also uses this class. 52 | */ 53 | class block_reader { 54 | 55 | public: 56 | 57 | typedef std::istream type; 58 | typedef util::unique_ptr::type pointer; 59 | 60 | /*! 61 | * Wrap an input stream to read and decompress setup header blocks. 62 | * 63 | * Only one wrapper can be used at the same time for each \c base. 64 | * 65 | * \param base The input stream for the main setup files. 66 | * It must already be positioned at start of the block stream. 67 | * The first block stream starts directly after the \ref setup::version 68 | * identifier whose position is given by 69 | * \ref loader::offsets::header_offset. 70 | * A second block stream directly follows the first one and contains 71 | * the \ref setup::data_entry "data entries". 72 | * \param version The version of the setup data. 73 | * 74 | * \throws block_error if the block stream header checksum was invalid, 75 | * or if the block compression is not supported by this build. 76 | * 77 | * \return a pointer to a non-seekable input stream for the uncompressed headers. 78 | * Reading from this stream may throw a \ref block_error if a block checksum 79 | * was invalid. 80 | */ 81 | static pointer get(std::istream & base, const setup::version & version); 82 | 83 | }; 84 | 85 | } // namespace stream 86 | 87 | #endif // INNOEXTRACT_STREAM_BLOCK_HPP 88 | -------------------------------------------------------------------------------- /src/stream/checksum.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Filter to be used with boost::iostreams for calculating a \ref crypto::checksum. 25 | */ 26 | #ifndef INNOEXTRACT_STREAM_CHECKSUM_HPP 27 | #define INNOEXTRACT_STREAM_CHECKSUM_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include "crypto/checksum.hpp" 33 | #include "crypto/hasher.hpp" 34 | 35 | namespace stream { 36 | 37 | /*! 38 | * Filters to be used with boost::iostreams for calculating a \ref crypto::checksum. 39 | * 40 | * An internal checksum state is updated as bytes are read and the final checksum is 41 | * written to the given checksum object when the end of the source stream is reached. 42 | */ 43 | class checksum_filter : public boost::iostreams::multichar_input_filter { 44 | 45 | private: 46 | 47 | typedef boost::iostreams::multichar_input_filter base_type; 48 | 49 | public: 50 | 51 | typedef base_type::char_type char_type; 52 | typedef base_type::category category; 53 | 54 | /*! 55 | * \param dest Location to store the final checksum at. 56 | * \param type The type of checksum to calculate. 57 | */ 58 | checksum_filter(crypto::checksum * dest, crypto::checksum_type type) 59 | : hasher(type) 60 | , output(dest) 61 | { } 62 | 63 | template 64 | std::streamsize read(Source & src, char * dest, std::streamsize n) { 65 | 66 | std::streamsize nread = boost::iostreams::read(src, dest, n); 67 | 68 | if(nread > 0) { 69 | hasher.update(dest, size_t(nread)); 70 | } else if(output) { 71 | *output = hasher.finalize(); 72 | output = NULL; 73 | } 74 | 75 | return nread; 76 | } 77 | 78 | private: 79 | 80 | crypto::hasher hasher; 81 | 82 | crypto::checksum * output; 83 | 84 | }; 85 | 86 | } // namespace stream 87 | 88 | #endif // INNOEXTRACT_STREAM_CHECKSUM_HPP 89 | -------------------------------------------------------------------------------- /src/stream/file.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "stream/file.hpp" 22 | 23 | #include 24 | #include 25 | 26 | #include "stream/checksum.hpp" 27 | #include "stream/exefilter.hpp" 28 | #include "stream/restrict.hpp" 29 | 30 | namespace io = boost::iostreams; 31 | 32 | namespace stream { 33 | 34 | bool file::operator<(const stream::file & o) const { 35 | 36 | if(offset != o.offset) { 37 | return (offset < o.offset); 38 | } else if(size != o.size) { 39 | return (size < o.size); 40 | } else if(filter != o.filter) { 41 | return (filter < o.filter); 42 | } 43 | 44 | return false; 45 | } 46 | 47 | bool file::operator==(const file & o) const { 48 | return (offset == o.offset 49 | && size == o.size 50 | && filter == o.filter); 51 | } 52 | 53 | 54 | file_reader::pointer file_reader::get(base_type & base, const file & file, 55 | crypto::checksum * checksum) { 56 | 57 | util::unique_ptr::type result(new io::filtering_istream); 58 | 59 | if(file.filter == ZlibFilter) { 60 | result->push(io::zlib_decompressor(), 8192); 61 | } 62 | 63 | if(checksum) { 64 | result->push(stream::checksum_filter(checksum, file.checksum.type), 8192); 65 | } 66 | 67 | switch(file.filter) { 68 | case NoFilter: break; 69 | case InstructionFilter4108: result->push(stream::inno_exe_decoder_4108(), 8192); break; 70 | case InstructionFilter5200: result->push(stream::inno_exe_decoder_5200(false), 8192); break; 71 | case InstructionFilter5309: result->push(stream::inno_exe_decoder_5200(true), 8192); break; 72 | case ZlibFilter: /* applied *after* calculating the checksum */ break; 73 | } 74 | 75 | result->push(stream::restrict(base, file.size)); 76 | 77 | result->exceptions(std::ios_base::badbit); 78 | 79 | return pointer(result.release()); 80 | } 81 | 82 | } // namespace stream 83 | -------------------------------------------------------------------------------- /src/stream/file.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2018 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Wrapper to read a single file from a chunk (\ref stream::chunk_reader). 25 | */ 26 | #ifndef INNOEXTRACT_STREAM_FILE_HPP 27 | #define INNOEXTRACT_STREAM_FILE_HPP 28 | 29 | #include 30 | 31 | #include 32 | 33 | #include "crypto/checksum.hpp" 34 | #include "util/unique_ptr.hpp" 35 | 36 | namespace stream { 37 | 38 | enum compression_filter { 39 | NoFilter, 40 | InstructionFilter4108, 41 | InstructionFilter5200, 42 | InstructionFilter5309, 43 | ZlibFilter, 44 | }; 45 | 46 | /*! 47 | * Information specifying a single file inside a compressed chunk. 48 | * 49 | * This data is stored in \ref setup::data_entry "data entries". 50 | * 51 | * Files specified by this struct can be read using \ref file_reader. 52 | */ 53 | struct file { 54 | 55 | boost::uint64_t offset; //!< Offset of this file within the decompressed chunk. 56 | boost::uint64_t size; //!< Pre-filter size of this file in the decompressed chunk. 57 | 58 | crypto::checksum checksum; //!< Checksum for the file. 59 | 60 | compression_filter filter; //!< Additional filter used before compression. 61 | 62 | bool operator<(const file & o) const; 63 | bool operator==(const file & o) const; 64 | 65 | }; 66 | 67 | /*! 68 | * Wrapper to read a single file from a \ref chunk_reader. 69 | * Restrics the stream to the file size and applies the appropriate filters. 70 | */ 71 | class file_reader { 72 | 73 | typedef boost::iostreams::chain base_type; 74 | 75 | public: 76 | 77 | typedef std::istream type; 78 | typedef util::unique_ptr::type pointer; 79 | typedef file file_t; 80 | 81 | /*! 82 | * Wrap a \ref chunk_reader to read a single file. 83 | * 84 | * Only one wrapper can be used at the same time for each \c base. 85 | * 86 | * \param base The chunk reader containing the file. 87 | * It must already be positioned at the file's offset. 88 | * \param file Information specifying the file to read. 89 | * \param checksum Optional pointer to a checksum that is updated as the file is read. 90 | * The type of the checksum will be the same as that stored in the file 91 | * struct. 92 | * 93 | * \return a pointer to a non-seekable input stream for the requested file. 94 | */ 95 | static pointer get(base_type & base, const file_t & file, crypto::checksum * checksum); 96 | 97 | }; 98 | 99 | } // namespace stream 100 | 101 | #endif // INNOEXTRACT_STREAM_FILE_HPP 102 | -------------------------------------------------------------------------------- /src/stream/restrict.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Wrapper class for a boost::iostreams-compatible source that can be used to restrict 25 | * sources to appear smaller than they really are. 26 | */ 27 | #ifndef INNOEXTRACT_STREAM_RESTRICT_HPP 28 | #define INNOEXTRACT_STREAM_RESTRICT_HPP 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | namespace stream { 35 | 36 | //! Like boost::iostreams::restriction, but always has a 64-bit counter. 37 | template 38 | class restricted_source : public boost::iostreams::source { 39 | 40 | BaseSource & base; //!< The base source to read from. 41 | boost::uint64_t remaining; //!< Number of bytes remaining in the restricted source. 42 | 43 | public: 44 | 45 | restricted_source(const restricted_source & o) 46 | : base(o.base), remaining(o.remaining) { } 47 | 48 | restricted_source(BaseSource & source, boost::uint64_t size) 49 | : base(source), remaining(size) { } 50 | 51 | std::streamsize read(char * buffer, std::streamsize bytes) { 52 | 53 | if(bytes <= 0) { 54 | return 0; 55 | } 56 | 57 | // Restrict the number of bytes to read 58 | bytes = std::streamsize(std::min(boost::uint64_t(bytes), remaining)); 59 | if(bytes == 0) { 60 | return -1; // End of the restricted source reached 61 | } 62 | 63 | std::streamsize nread = boost::iostreams::read(base, buffer, bytes); 64 | 65 | // Remember how many bytes were read so far 66 | if(nread > 0) { 67 | remaining -= std::min(boost::uint64_t(nread), remaining); 68 | } 69 | 70 | return nread; 71 | } 72 | 73 | }; 74 | 75 | /*! 76 | * Restricts a source to a specific size from the current position and makes 77 | * it non-seekable. 78 | * 79 | * Like boost::iostreams::restrict, but always has a 64-bit counter. 80 | */ 81 | template 82 | restricted_source restrict(BaseSource & source, boost::uint64_t size) { 83 | return restricted_source(source, size); 84 | } 85 | 86 | } // namespace stream 87 | 88 | #endif // INNOEXTRACT_STREAM_RESTRICT_HPP 89 | -------------------------------------------------------------------------------- /src/util/align.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Utility functions for dealing with alignment of objects. 25 | */ 26 | #ifndef INNOEXTRACT_UTIL_ALIGN_HPP 27 | #define INNOEXTRACT_UTIL_ALIGN_HPP 28 | 29 | #include 30 | 31 | #include "util/math.hpp" 32 | 33 | #include "configure.hpp" 34 | 35 | namespace util { 36 | 37 | //! Get the alignment of a type. 38 | template 39 | unsigned int alignment_of() { 40 | #if INNOEXTRACT_HAVE_ALIGNOF 41 | return alignof(T); 42 | #elif defined(_MSC_VER) && _MSC_VER >= 1300 43 | return __alignof(T); 44 | #elif defined(__GNUC__) 45 | return __alignof__(T); 46 | #else 47 | return sizeof(T); 48 | #endif 49 | } 50 | 51 | //! Check if a pointer has aparticular alignment. 52 | inline bool is_aligned_on(const void * p, size_t alignment) { 53 | return alignment == 1 54 | || (is_power_of_2(alignment) ? mod_power_of_2(size_t(p), alignment) == 0 55 | : size_t(p) % alignment == 0); 56 | } 57 | 58 | //! Check if a pointer is aligned for a specific type. 59 | template 60 | bool is_aligned(const void * p) { 61 | return is_aligned_on(p, alignment_of()); 62 | } 63 | 64 | } // namespace util 65 | 66 | #endif // INNOEXTRACT_UTIL_ALIGN_HPP 67 | -------------------------------------------------------------------------------- /src/util/boostfs_compat.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Compatibility functions for older Boost.Filesystem versions. 25 | */ 26 | #ifndef INNOEXTRACT_UTIL_BOOSTFS_COMPAT_HPP 27 | #define INNOEXTRACT_UTIL_BOOSTFS_COMPAT_HPP 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | namespace util { 35 | 36 | inline const std::string & as_string(const std::string & path) { 37 | return path; 38 | } 39 | 40 | inline const std::string as_string(const boost::filesystem::path & path) { 41 | return path.string(); 42 | } 43 | 44 | } // namespace util 45 | 46 | #endif // INNOEXTRACT_UTIL_BOOSTFS_COMPAT_HPP 47 | -------------------------------------------------------------------------------- /src/util/enum.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Utilities to associate strings with enum values. 25 | */ 26 | #ifndef INNOEXTRACT_UTIL_ENUM_HPP 27 | #define INNOEXTRACT_UTIL_ENUM_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include "util/console.hpp" 36 | #include "util/flags.hpp" 37 | 38 | template 39 | struct get_enum { 40 | typedef Enum type; 41 | }; 42 | template 43 | struct get_enum< flags > { 44 | typedef Enum type; 45 | }; 46 | 47 | template 48 | struct enum_names { 49 | 50 | const size_t count; 51 | 52 | const char * name; 53 | 54 | const char * names[1]; 55 | 56 | }; 57 | 58 | #define NAMED_ENUM(Enum) \ 59 | template <> struct enum_names::type> { \ 60 | enum { named = 1 }; \ 61 | static const char * name; \ 62 | static const char * names[]; \ 63 | static const size_t count; \ 64 | }; 65 | 66 | #define NAMED_FLAGS(Flags) \ 67 | FLAGS_OVERLOADS(Flags) \ 68 | NAMED_ENUM(Flags) 69 | 70 | #define NAMES(Enum, Name, ...) \ 71 | const char * enum_names::type>::name = (Name); \ 72 | const char * enum_names::type>::names[] = { __VA_ARGS__ }; \ 73 | const size_t enum_names::type>::count \ 74 | = size_t(boost::size(enum_names::type>::names)); 75 | 76 | #define USE_ENUM_NAMES(Enum) \ 77 | (void)enum_names::type>::count; \ 78 | (void)enum_names::type>::name; \ 79 | (void)enum_names::type>::names; 80 | 81 | #define USE_FLAG_NAMES(Flags) \ 82 | USE_FLAGS_OVERLOADS(Flags) \ 83 | USE_ENUM_NAMES(Flags) 84 | 85 | template 86 | typename boost::enable_if_c::named, std::ostream &>::type 87 | operator<<(std::ostream & os, Enum value) { 88 | if(value >= Enum(0)) { 89 | size_t i = size_t(value); 90 | if(i < enum_names::count) { 91 | return os << enum_names::names[value]; 92 | } 93 | } 94 | return os << "(unknown:" << int(value) << ')'; 95 | } 96 | 97 | template 98 | std::ostream & operator<<(std::ostream & os, flags _flags) { 99 | color::shell_command prev = color::current; 100 | if(_flags) { 101 | bool first = true; 102 | for(size_t i = 0; i < flags::bits; i++) { 103 | if(_flags & Enum(i)) { 104 | if(first) { 105 | first = false; 106 | } else { 107 | os << color::dim_white << ", " << prev; 108 | } 109 | os << Enum(i); 110 | } 111 | } 112 | return os; 113 | } else { 114 | return os << color::dim_white << "(none)" << prev; 115 | } 116 | } 117 | 118 | #endif // INNOEXTRACT_UTIL_ENUM_HPP 119 | -------------------------------------------------------------------------------- /src/util/fstream.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * boost::filesystem::{i,o,}fstream doesn't support unicode names on windows 25 | * Implement our own wrapper using boost::iostreams. 26 | */ 27 | #ifndef INNOEXTRACT_UTIL_FSTREAM_HPP 28 | #define INNOEXTRACT_UTIL_FSTREAM_HPP 29 | 30 | #if !defined(_WIN32) 31 | 32 | #include 33 | 34 | namespace util { 35 | 36 | typedef boost::filesystem::ifstream ifstream; 37 | typedef boost::filesystem::ofstream ofstream; 38 | typedef boost::filesystem::fstream fstream; 39 | 40 | } // namespace util 41 | 42 | #else // if defined(_WIN32) 43 | 44 | #include 45 | #include 46 | #include 47 | 48 | namespace util { 49 | 50 | /*! 51 | * {i,o,}fstream implementation with support for Unicode filenames. 52 | * Create a subclass instead of a typedef to force boost::filesystem::path parameters. 53 | */ 54 | template 55 | class path_fstream : public boost::iostreams::stream { 56 | 57 | private: // disallow copying 58 | 59 | path_fstream(const path_fstream &); 60 | const path_fstream & operator=(const path_fstream &); 61 | 62 | typedef boost::filesystem::path path; 63 | typedef boost::iostreams::stream base; 64 | 65 | Device & device() { return **this; } 66 | 67 | void fix_open_mode(std::ios_base::openmode mode); 68 | 69 | public: 70 | 71 | path_fstream() : base(Device()) { } 72 | 73 | explicit path_fstream(const path & p) : base(p) { } 74 | 75 | path_fstream(const path & p, std::ios_base::openmode mode) : base(p, mode) { 76 | fix_open_mode(mode); 77 | } 78 | 79 | void open(const path & p) { 80 | base::close(); 81 | base::open(p); 82 | } 83 | 84 | void open(const path & p, std::ios_base::openmode mode) { 85 | base::close(); 86 | base::open(p, mode); 87 | fix_open_mode(mode); 88 | } 89 | 90 | bool is_open() { 91 | return device().is_open(); // return the real open state, not base::is_open() 92 | } 93 | 94 | virtual ~path_fstream() { } 95 | }; 96 | 97 | template <> 98 | inline void path_fstream 99 | ::fix_open_mode(std::ios_base::openmode mode) { 100 | if((mode & std::ios_base::ate) && is_open()) { 101 | seekg(0, std::ios_base::end); 102 | } 103 | } 104 | 105 | template <> 106 | inline void path_fstream 107 | ::fix_open_mode(std::ios_base::openmode mode) { 108 | if((mode & std::ios_base::ate) && is_open()) { 109 | seekp(0, std::ios_base::end); 110 | } 111 | } 112 | 113 | template <> 114 | inline void path_fstream 115 | ::fix_open_mode(std::ios_base::openmode mode) { 116 | if((mode & std::ios_base::ate) && is_open()) { 117 | seekg(0, std::ios_base::end); 118 | seekp(0, std::ios_base::end); 119 | } 120 | } 121 | 122 | typedef path_fstream ifstream; 123 | typedef path_fstream ofstream; 124 | typedef path_fstream fstream; 125 | 126 | } // namespace util 127 | 128 | #endif // defined(_WIN32) 129 | 130 | #endif // INNOEXTRACT_UTIL_FSTREAM_HPP 131 | -------------------------------------------------------------------------------- /src/util/load.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2020 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "util/load.hpp" 22 | 23 | #include 24 | 25 | #include 26 | 27 | namespace util { 28 | 29 | void binary_string::load(std::istream & is, std::string & target) { 30 | 31 | boost::uint32_t length = util::load(is); 32 | if(is.fail()) { 33 | return; 34 | } 35 | 36 | target.clear(); 37 | 38 | while(length) { 39 | char buffer[10 * 1024]; 40 | boost::uint32_t buf_size = std::min(length, boost::uint32_t(sizeof(buffer))); 41 | is.read(buffer, std::streamsize(buf_size)); 42 | target.append(buffer, buf_size); 43 | length -= buf_size; 44 | } 45 | } 46 | 47 | void binary_string::skip(std::istream & is) { 48 | 49 | boost::uint32_t length = util::load(is); 50 | if(is.fail()) { 51 | return; 52 | } 53 | 54 | discard(is, length); 55 | } 56 | 57 | void encoded_string::load(std::istream & is, std::string & target, codepage_id codepage, 58 | const std::bitset<256> * lead_bytes) { 59 | binary_string::load(is, target); 60 | to_utf8(target, codepage, lead_bytes); 61 | } 62 | 63 | unsigned to_unsigned(const char * chars, size_t count) { 64 | #if BOOST_VERSION < 105200 65 | return boost::lexical_cast(std::string(chars, count)); 66 | #else 67 | return boost::lexical_cast(chars, count); 68 | #endif 69 | } 70 | 71 | } // namespace util 72 | -------------------------------------------------------------------------------- /src/util/log.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "util/log.hpp" 22 | 23 | #include 24 | 25 | #include "util/console.hpp" 26 | 27 | bool logger::debug = false; 28 | bool logger::quiet = false; 29 | 30 | size_t logger::total_errors = 0; 31 | size_t logger::total_warnings = 0; 32 | 33 | logger::~logger() { 34 | 35 | color::shell_command previous = color::current; 36 | progress::clear(); 37 | 38 | switch(level) { 39 | case Debug: std::cout << color::cyan << buffer.str() << previous << "\n"; break; 40 | case Info: std::cout << color::white << buffer.str() << previous << "\n"; break; 41 | case Warning: { 42 | std::cerr << color::yellow << "Warning: " << buffer.str() << previous << "\n"; 43 | total_warnings++; 44 | break; 45 | } 46 | case Error: { 47 | std::cerr << color::red << buffer.str() << previous << "\n"; 48 | total_errors++; 49 | break; 50 | } 51 | } 52 | 53 | } 54 | 55 | std::streambuf * warning_suppressor::set_streambuf(std::streambuf * streambuf) { 56 | return std::cerr.rdbuf(streambuf); 57 | } 58 | 59 | void warning_suppressor::flush() { 60 | restore(); 61 | std::cerr << buffer.str(); 62 | logger::total_warnings += warnings; 63 | logger::total_errors += errors; 64 | } 65 | -------------------------------------------------------------------------------- /src/util/log.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2019 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Logging functions. 25 | */ 26 | #ifndef INNOEXTRACT_UTIL_LOG_HPP 27 | #define INNOEXTRACT_UTIL_LOG_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #ifdef DEBUG 35 | #define debug(...) \ 36 | if(::logger::debug) \ 37 | ::logger(::logger::Debug) << __VA_ARGS__ 38 | #else 39 | #define debug(...) 40 | #endif 41 | 42 | #define log_info \ 43 | if(!::logger::quiet) \ 44 | ::logger(::logger::Info) 45 | #define log_warning ::logger(::logger::Warning) 46 | #define log_error ::logger(::logger::Error) 47 | 48 | /*! 49 | * logger class that allows longging via the stream operator. 50 | */ 51 | class logger : private boost::noncopyable { 52 | 53 | public: 54 | 55 | enum log_level { 56 | Debug, 57 | Info, 58 | Warning, 59 | Error 60 | }; 61 | 62 | private: 63 | 64 | const log_level level; 65 | 66 | std::ostringstream buffer; //! Buffer for the log message excluding level, file and line. 67 | 68 | public: 69 | 70 | static size_t total_warnings; //! Total number of \ref log_warning uses so far. 71 | static size_t total_errors; //! Total number of \ref log_error uses so far. 72 | 73 | static bool debug; //! Is \ref debug output enabled? 74 | static bool quiet; //! Is \ref log_info disabled? 75 | 76 | /*! 77 | * Construct a log line output stream. 78 | * 79 | * You probably don't want to use this directly - use \ref debug, \ref log_info, 80 | * \ref log_warning and \ref log_error instead. 81 | */ 82 | explicit logger(log_level _level) : level(_level) { } 83 | 84 | template 85 | logger & operator<<(const T & i) { 86 | buffer << i; 87 | return *this; 88 | } 89 | 90 | ~logger(); 91 | 92 | }; 93 | 94 | class warning_storage { 95 | 96 | protected: 97 | 98 | 99 | public: 100 | 101 | }; 102 | 103 | class warning_suppressor : public warning_storage { 104 | 105 | std::ostringstream buffer; 106 | std::streambuf * streambuf; 107 | size_t warnings; 108 | size_t errors; 109 | 110 | static std::streambuf * set_streambuf(std::streambuf * streambuf); 111 | 112 | public: 113 | 114 | warning_suppressor() 115 | : streambuf(set_streambuf(buffer.rdbuf())) 116 | , warnings(logger::total_warnings) 117 | , errors(logger::total_errors) 118 | { } 119 | 120 | ~warning_suppressor() { 121 | restore(); 122 | } 123 | 124 | void restore() { 125 | 126 | if(!streambuf) { 127 | return; 128 | } 129 | 130 | set_streambuf(streambuf); 131 | streambuf = NULL; 132 | 133 | size_t new_warnings = logger::total_warnings - warnings; 134 | size_t new_errors = logger::total_errors - errors; 135 | logger::total_warnings = warnings; 136 | logger::total_errors = errors; 137 | warnings = new_warnings; 138 | errors = new_errors; 139 | 140 | } 141 | 142 | void flush(); 143 | 144 | operator bool() { 145 | return buffer.tellp() != std::ostringstream::pos_type(0); 146 | } 147 | 148 | }; 149 | 150 | #endif // INNOEXTRACT_UTIL_LOG_HPP 151 | -------------------------------------------------------------------------------- /src/util/math.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Math helper functions. 25 | */ 26 | #ifndef INNOEXTRACT_UTIL_MATH_HPP 27 | #define INNOEXTRACT_UTIL_MATH_HPP 28 | 29 | #ifdef _MSC_VER 30 | #include 31 | #endif 32 | 33 | namespace util { 34 | 35 | //! Divide by a number and round up the result. 36 | template 37 | T ceildiv(T num, T denom) { 38 | return (num + (denom - T(1))) / denom; 39 | } 40 | 41 | //! Check if an integer is a power of two. 42 | template 43 | bool is_power_of_2(const T & n) { 44 | return n > 0 && (n & (n - 1)) == 0; 45 | } 46 | 47 | //! Calculate a % b where b is always a power of two. 48 | template 49 | T2 mod_power_of_2(const T1 & a, const T2 & b) { 50 | return T2(a) & (b - 1); 51 | } 52 | 53 | namespace detail { 54 | 55 | template 56 | struct safe_shifter { 57 | 58 | template 59 | static T right_shift(T /* value */, unsigned int /* bits */) { 60 | return 0; 61 | } 62 | 63 | template 64 | static T left_shift(T /* value */, unsigned int /* bits */) { 65 | return 0; 66 | } 67 | 68 | }; 69 | 70 | template <> 71 | struct safe_shifter { 72 | 73 | template 74 | static T right_shift(T value, unsigned int bits) { 75 | return value >> bits; 76 | } 77 | 78 | template 79 | static T left_shift(T value, unsigned int bits) { 80 | return value << bits; 81 | } 82 | 83 | }; 84 | 85 | } // namespace detail 86 | 87 | //! Right-shift a value without shifting past the size of the type or return 0. 88 | template 89 | T safe_right_shift(T value) { 90 | return detail::safe_shifter<(bits >= (8 * sizeof(T)))>::right_shift(value, bits); 91 | } 92 | 93 | //! Left-shift a value without shifting past the size of the type or return 0. 94 | template 95 | T safe_left_shift(T value) { 96 | return detail::safe_shifter<(bits >= (8 * sizeof(T)))>::left_shift(value, bits); 97 | } 98 | 99 | //! Rotate left. 100 | template T rotl_fixed(T x, unsigned int y) { 101 | return T((x << y) | (x >> (sizeof(T) * 8 - y))); 102 | } 103 | 104 | //! Rotate right. 105 | template T rotr_fixed(T x, unsigned int y) { 106 | return T((x >> y) | (x << (sizeof(T) * 8 - y))); 107 | } 108 | 109 | #if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) 110 | 111 | template <> 112 | inline boost::uint8_t rotl_fixed(boost::uint8_t x, unsigned int y) { 113 | return y ? _rotl8(x, y) : x; 114 | } 115 | 116 | template <> 117 | inline boost::uint16_t rotl_fixed(boost::uint16_t x, unsigned int y) { 118 | return y ? _rotl16(x, y) : x; 119 | } 120 | 121 | #endif 122 | 123 | #ifdef _MSC_VER 124 | template <> 125 | inline boost::uint32_t rotl_fixed(boost::uint32_t x, unsigned int y) { 126 | return y ? _lrotl(x, y) : x; 127 | } 128 | #endif 129 | 130 | #if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) 131 | template <> 132 | inline boost::uint64_t rotl_fixed(boost::uint64_t x, unsigned int y) { 133 | return y ? _rotl64(x, y) : x; 134 | } 135 | #endif 136 | 137 | } // namespace util 138 | 139 | #endif // INNOEXTRACT_UTIL_MATH_HPP 140 | -------------------------------------------------------------------------------- /src/util/process.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013-2015 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #ifndef INNOEXTRACT_UTIL_PROCESS_HPP 22 | #define INNOEXTRACT_UTIL_PROCESS_HPP 23 | 24 | #include 25 | 26 | namespace util { 27 | 28 | /*! 29 | * \brief Start a program and wait for it to finish 30 | * 31 | * The executable's standard output/error is discarded. 32 | * 33 | * \param args program arguments. The first argument is the program name/path and 34 | * the last argument must be NULL. 35 | * 36 | * \return the programs exit code or a negative value on error. 37 | */ 38 | int run(const char * const args[]); 39 | 40 | } // namespace util 41 | 42 | #endif // INNOEXTRACT_UTIL_PROCESS_HPP 43 | -------------------------------------------------------------------------------- /src/util/test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | #include "util/test.hpp" 22 | 23 | #include "configure.hpp" 24 | 25 | #if INNOEXTRACT_HAVE_ISATTY 26 | #include 27 | #endif 28 | 29 | namespace { 30 | 31 | bool test_verbose = false; 32 | bool test_progress = false; 33 | int test_failed = 0; 34 | 35 | } // anonymous namewspace 36 | 37 | Testsuite * Testsuite::tests = NULL; 38 | 39 | Testsuite::Testsuite(const char * suitename) : name(suitename) { 40 | next = tests; 41 | tests = this; 42 | } 43 | 44 | int Testsuite::run_all() { 45 | 46 | int count = 0; 47 | for(Testsuite * test = tests; test; test = test->next) { 48 | count++; 49 | } 50 | int len = 2; 51 | int r = count; 52 | while(r >= 10) { 53 | len++; 54 | r /= 10; 55 | } 56 | 57 | int i = 0; 58 | for(Testsuite * test = tests; test; test = test->next) { 59 | i++; 60 | if(test_verbose || test_progress) { 61 | std::printf("%*d/%d [%s]", len, i, count, test->name); 62 | if(test_verbose) { 63 | std::printf("\n"); 64 | } 65 | } 66 | try { 67 | test->run(); 68 | } catch(...) { 69 | test_failed++; 70 | if(test_progress) { 71 | std::printf("\r\x1b[K"); 72 | } 73 | std::fprintf(stderr, "%s: EXCEPTION\n", test->name); 74 | } 75 | } 76 | 77 | if(test_progress) { 78 | std::printf("\r\x1b[K"); 79 | } 80 | if(test_failed == 0) { 81 | std::printf("all %d test suites passed\n", count); 82 | } 83 | 84 | return test_failed > 0 ? 1 : 0; 85 | } 86 | 87 | void Testsuite::test(const char * testcase, bool ok) { 88 | if(!ok) { 89 | test_failed++; 90 | } 91 | if(test_progress) { 92 | std::printf("\r\x1b[K"); 93 | } 94 | if(!ok || test_verbose) { 95 | std::fprintf(ok ? stdout : stderr, "%s.%s: %s\n", name, testcase, ok ? "ok" : "FAILED"); 96 | } 97 | } 98 | 99 | int main(int argc, const char * argv[]) { 100 | 101 | (void)testdata, (void)testlen; 102 | 103 | if((argc > 1 && std::strcmp(argv[1], "--verbose") == 0) || \ 104 | (argc > 1 && argv[1][0] == '-' && argv[1][1] != '-' && std::strchr(argv[1], 'v')) || \ 105 | (std::getenv("VERBOSE") && std::strcmp(std::getenv("VERBOSE"), "0") != 0)) { 106 | test_verbose = true; 107 | } else { 108 | #if INNOEXTRACT_HAVE_ISATTY 109 | test_progress = isatty(1) && isatty(2); 110 | #endif 111 | if(test_progress) { 112 | char * term = std::getenv("TERM"); 113 | if(!term || !std::strcmp(term, "dumb")) { 114 | test_progress = false; // Terminal does not support escape sequences 115 | } 116 | } 117 | } 118 | 119 | return Testsuite::run_all(); 120 | } 121 | -------------------------------------------------------------------------------- /src/util/test.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Test utility functions. 25 | */ 26 | #ifndef INNOEXTRACT_UTIL_TEST_HPP 27 | #define INNOEXTRACT_UTIL_TEST_HPP 28 | 29 | #ifdef INNOEXTRACT_BUILD_TESTS 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | static const char * testdata = "The dhole (pronounced \"dole\") is also known as the Asiatic wild dog," 37 | " red dog, and whistling dog. It is about the size of a German shepherd but" 38 | " looks more like a long-legged fox. This highly elusive and skilled jumper" 39 | " is classified with wolves, coyotes, jackals, and foxes in the taxonomic" 40 | " family Canidae."; 41 | static const size_t testlen = std::strlen(testdata); 42 | 43 | struct Testsuite { 44 | 45 | explicit Testsuite(const char * suitename); 46 | virtual ~Testsuite() { } 47 | 48 | static int run_all(); 49 | 50 | void test(const char * testcase, bool ok); 51 | 52 | inline void test_equals(const char * testcase, const void * a, const void * b, size_t count) { 53 | test(testcase, std::memcmp(a, b, count) == 0); 54 | } 55 | 56 | virtual void run() = 0; 57 | 58 | private: 59 | 60 | static Testsuite * tests; 61 | Testsuite * next; 62 | 63 | protected: 64 | 65 | const char * name; 66 | 67 | }; 68 | 69 | #define INNOEXTRACT_TEST(Name, ...) \ 70 | struct Name ## _test : public Testsuite { \ 71 | Name ## _test() : Testsuite(# Name) { (void)testdata, (void)testlen; } \ 72 | void run(); \ 73 | } test_ ## Name; \ 74 | void Name ## _test::run() { __VA_ARGS__ } 75 | 76 | #else 77 | 78 | #define INNOEXTRACT_TEST(Name, ...) 79 | 80 | #endif // INNOEXTRACT_BUILD_TESTS 81 | 82 | #endif // INNOEXTRACT_UTIL_TEST_HPP 83 | -------------------------------------------------------------------------------- /src/util/time.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Time parsing, formatting, onversion and filetime manipulation functions. 25 | */ 26 | #ifndef INNOEXTRACT_UTIL_TIME_HPP 27 | #define INNOEXTRACT_UTIL_TIME_HPP 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | namespace util { 36 | 37 | typedef boost::int64_t time; 38 | 39 | /*! 40 | * Convert UTC clock time to a timestamp 41 | * 42 | * \note This function may not be thread-safe on all operating systems. 43 | */ 44 | time parse_time(std::tm tm); 45 | 46 | /*! 47 | * Convert a timestamp to UTC clock time 48 | * 49 | * \note This function may not be thread-safe on all operating systems. 50 | */ 51 | std::tm format_time(time t); 52 | 53 | /*! 54 | * Convert a timestamp to local time 55 | * 56 | * \note This function may not be thread-safe on all operating systems. 57 | */ 58 | time to_local_time(time t); 59 | 60 | /*! 61 | * Set the local timezone used by to_local_time 62 | * 63 | * \note This function is not thread-safe. 64 | */ 65 | void set_local_timezone(std::string timezone); 66 | 67 | /*! 68 | * Set a file's access, creation and modification times. 69 | * 70 | * \note Not all operating systems support file creation times. 71 | * 72 | * \param path The file to the file to set the times for. 73 | * This file will not be created if it doesn't exist already. 74 | * \param sec File time to set (in seconds). 75 | * \param nsec Sub-second component of the file time to set (in nanoseconds). 76 | * 77 | * \note The actual file time precision depends on the operating system and filesystem. 78 | * If the available file time precision is too low to represent the given timestamp, 79 | * it will be silently truncated to the available precision. 80 | * 81 | * \return \c true if the file time was changed, \c false otherwise. 82 | */ 83 | bool set_file_time(const boost::filesystem::path & path, time sec, boost::uint32_t nsec); 84 | 85 | } // namespace util 86 | 87 | #endif // INNOEXTRACT_UTIL_TIME_HPP 88 | -------------------------------------------------------------------------------- /src/util/types.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Utility functions for dealing with types. 25 | */ 26 | #ifndef INNOEXTRACT_UTIL_TYPES_HPP 27 | #define INNOEXTRACT_UTIL_TYPES_HPP 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | namespace util { 36 | 37 | #if BOOST_VERSION < 104200 38 | 39 | template 40 | struct uint_t { }; 41 | template <> 42 | struct uint_t<8> : public boost::uint_t<8> { typedef boost::uint8_t exact; }; 43 | template <> 44 | struct uint_t<16> : public boost::uint_t<16> { typedef boost::uint16_t exact; }; 45 | template <> 46 | struct uint_t<32> : public boost::uint_t<32> { typedef boost::uint32_t exact; }; 47 | template <> 48 | struct uint_t<64> { typedef boost::uint64_t exact; }; 49 | 50 | template 51 | struct int_t { }; 52 | template <> 53 | struct int_t<8> : public boost::int_t<8> { typedef boost::int8_t exact; }; 54 | template <> 55 | struct int_t<16> : public boost::int_t<16> { typedef boost::int16_t exact; }; 56 | template <> 57 | struct int_t<32> : public boost::int_t<32> { typedef boost::int32_t exact; }; 58 | template <> 59 | struct int_t<64> { typedef boost::int64_t exact; }; 60 | 61 | #else 62 | 63 | using boost::uint_t; 64 | using boost::int_t; 65 | 66 | #endif 67 | 68 | /*! 69 | * Get an with a specific bit size and signedness, 70 | * but with no more bits than the original. 71 | */ 72 | template ::is_signed> 74 | struct compatible_integer { 75 | typedef void type; 76 | }; 77 | template 78 | struct compatible_integer { 79 | typedef typename uint_t< 80 | boost::static_unsigned_min::value 81 | >::exact type; 82 | }; 83 | template 84 | struct compatible_integer { 85 | typedef typename int_t< 86 | boost::static_unsigned_min::value 87 | >::exact type; 88 | }; 89 | 90 | //! CRTP helper class to hide the ugly static casts needed to get to the derived class. 91 | template 92 | class static_polymorphic { 93 | 94 | protected: 95 | 96 | typedef Impl impl_type; 97 | 98 | impl_type & impl() { return *static_cast(this); } 99 | 100 | const impl_type & impl() const { return *static_cast(this); } 101 | 102 | }; 103 | 104 | } // namespace util 105 | 106 | #endif // INNOEXTRACT_UTIL_TYPES_HPP 107 | -------------------------------------------------------------------------------- /src/util/unique_ptr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Wrapper to select std::unique_ptr if available, std::auto_ptr otherwise. 25 | */ 26 | #ifndef INNOEXTRACT_UTIL_UNIQUE_PTR_HPP 27 | #define INNOEXTRACT_UTIL_UNIQUE_PTR_HPP 28 | 29 | #include 30 | 31 | #include "configure.hpp" 32 | 33 | namespace util { 34 | 35 | //! Get a std::unique_ptr or std::auto_ptr for the given type. 36 | template 37 | struct unique_ptr { 38 | #if INNOEXTRACT_HAVE_STD_UNIQUE_PTR 39 | typedef std::unique_ptr type; 40 | #else 41 | typedef std::auto_ptr type; 42 | #endif 43 | }; 44 | 45 | } // namespace util 46 | 47 | #endif // INNOEXTRACT_UTIL_UNIQUE_PTR_HPP 48 | -------------------------------------------------------------------------------- /src/util/windows.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013-2014 Daniel Scharrer 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the author(s) be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | /*! 22 | * \file 23 | * 24 | * Compatibility wrapper to work around deficiencies in Microsoft® Windows™. 25 | * Mostly deals with converting between UTF-8 and UTF-16 input/output. 26 | * More precisely: 27 | * - Converts wide char command-line arguments to UTF-8 and calls utf8_main(). 28 | * - Sets an UTF-8 locale for boost::filesystem::path. 29 | * This makes everything in boost::filesystem UTF-8 aware, except for {i,o,}fstream. 30 | * For those, there are UTF-8 aware implementations in util/fstream.hpp 31 | * - Converts UTF-8 to UTF-16 in std::cout and std::cerr if attached to a console 32 | * - Interprets ANSI escape sequences in std::cout and std::cerr if attached to a console 33 | * - Provides a Windows implementation of \c isatty() 34 | */ 35 | #ifndef INNOEXTRACT_UTIL_WINDOWS_HPP 36 | #define INNOEXTRACT_UTIL_WINDOWS_HPP 37 | 38 | #if defined(_WIN32) 39 | 40 | //! Program entry point that will always receive UTF-8 encoded arguments 41 | int utf8_main(int argc, char * argv[]); 42 | 43 | //! We define our own wrapper main(), so rename the real one 44 | #define main utf8_main 45 | 46 | namespace util { 47 | 48 | //! isatty() replacement (only works for fd 0, 1 and 2) 49 | int isatty(int fd); 50 | 51 | //! Determine the buffer width of the current console - replacement for ioctl(TIOCGWINSZ) 52 | int console_width(); 53 | 54 | } // namespace util 55 | 56 | using util::isatty; 57 | 58 | #endif // defined(_WIN32) 59 | 60 | #endif // INNOEXTRACT_UTIL_WINDOWS_HPP 61 | --------------------------------------------------------------------------------