Browse Source

Many fixes.

pull/1/head
Daniel Scharrer 15 years ago
parent
commit
bdfa8ddc9b
  1. 125
      CMakeLists.txt
  2. 106
      cmake/CompileCheck.cmake
  3. 22
      cmake/FindLZMA.cmake
  4. 47
      cmake/VersionScript.cmake
  5. 41
      cmake/VersionString.cmake
  6. 14
      cmake/clang-toolchain.cmake
  7. 3153
      cmake/cpplint.py
  8. 18
      cmake/ekopath-toolchain.cmake
  9. 78
      cmake/mingw32-toolchain.cmake
  10. 142
      src/InnoExtract.cpp
  11. 120
      src/crypto/ARC4.cpp
  12. 71
      src/crypto/ARC4.h
  13. 22
      src/crypto/Adler-32.cpp
  14. 5
      src/crypto/Adler-32.hpp
  15. 46
      src/crypto/IteratedHash.hpp
  16. 146
      src/crypto/SHA-1.cpp
  17. 2
      src/crypto/SHA-1.hpp
  18. 31
      src/loader/ExeReader.cpp
  19. 16
      src/loader/ExeReader.hpp
  20. 8
      src/loader/SetupLoader.cpp
  21. 16
      src/loader/SetupLoader.hpp
  22. 240
      src/misc/BitfieldConverter.hpp
  23. 189
      src/misc/test.cpp
  24. 5
      src/setup/FileEntry.cpp
  25. 2
      src/setup/FileEntry.hpp
  26. 4
      src/setup/FileLocationEntry.cpp
  27. 2
      src/setup/FileLocationEntry.hpp
  28. 24
      src/setup/SetupComponentEntry.cpp
  29. 33
      src/setup/SetupHeader.cpp
  30. 4
      src/setup/SetupHeader.hpp
  31. 2
      src/setup/SetupTypeEntry.cpp
  32. 139
      src/setup/Version.cpp
  33. 44
      src/setup/Version.hpp
  34. 9
      src/setup/WindowsVersion.cpp
  35. 2
      src/setup/WindowsVersion.hpp
  36. 8
      src/stream/BlockFilter.hpp
  37. 4
      src/stream/BlockReader.cpp
  38. 2
      src/stream/ChecksumFilter.hpp
  39. 2
      src/stream/ChunkReader.cpp
  40. 7
      src/stream/ChunkReader.hpp
  41. 23
      src/stream/InstructionFilter.hpp
  42. 14
      src/stream/LzmaFilter.cpp
  43. 2
      src/stream/LzmaFilter.hpp
  44. 29
      src/stream/SliceReader.cpp
  45. 8
      src/stream/SliceReader.hpp
  46. 16
      src/util/Endian.hpp
  47. 3
      src/util/Enum.hpp
  48. 4
      src/util/Flags.hpp
  49. 6
      src/util/LoadingUtils.cpp
  50. 44
      src/util/LoadingUtils.hpp
  51. 16
      src/util/StoredEnum.hpp
  52. 46
      src/util/Utils.hpp

125
CMakeLists.txt

@ -1,30 +1,74 @@
cmake_minimum_required(VERSION 2.6)
# For custom cmake modules.
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(CompileCheck)
include(VersionString) # TODO use this
# Force re-checking libraries if the compiler or compiler flags change.
if((NOT LAST_CMAKE_CXX_FLAGS STREQUAL CMAKE_CXX_FLAGS)
OR (NOT LAST_CMAKE_CXX_COMPILER STREQUAL CMAKE_CXX_COMPILER))
force_recheck_library(Boost)
unset(Boost_INCLUDE_DIR CACHE)
set(LAST_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE INTERNAL "The last C++ compiler flags.")
set(LAST_CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}" CACHE INTERNAL "The last C++ compiler.")
endif()
unset(LIBRARIES)
find_package(Boost REQUIRED COMPONENTS iostreams filesystem date_time)
check_link_library(Boost Boost_LIBRARIES)
list(APPEND LIBRARIES "${Boost_LIBRARIES}")
link_directories("${Boost_LIBRARY_DIRS}")
include_directories(SYSTEM "${Boost_INCLUDE_DIR}")
#find_package(ZLIB)
#if(ZLIB_FOUND)
# include_directories(SYSTEM "${ZLIB_INCLUDE_DIR}")
# list(APPEND LIBRARIES "${ZLIB_LIBRARIES}")
# add_definitions(-DHAVE_ZLIB)
#endif()
find_package(LZMA)
check_link_library(LZMA LZMA_LIBRARIES)
list(APPEND LIBRARIES "${LZMA_LIBRARIES}")
include_directories(SYSTEM "${LZMA_INCLUDE_DIR}")
# TODO make LZMA optional
# TODO debugging-only
add_cxxflag("-ggdb")
add_cxxflag("-O3")
# TODO should probably be supplied by the user
add_cxxflag("-march=native")
add_cxxflag("-Wl,--as-needed")
#find_package(BZip2)
#if(BZIP2_FOUND)
# include_directories(SYSTEM "${BZIP2_INCLUDE_DIR}")
# list(APPEND LIBRARIES "${BZIP2_LIBRARIES}")
# add_definitions(-DHAVE_BZIP2)
#endif()
add_cxxflag("-Wall")
add_cxxflag("-Wextra")
add_cxxflag("-Wformat=2")
add_cxxflag("-Wundef")
add_cxxflag("-Wpointer-arith")
add_cxxflag("-Wcast-qual")
add_cxxflag("-Woverloaded-virtual")
add_cxxflag("-Wlogical-op")
add_cxxflag("-Wliteral-conversion")
add_cxxflag("-Wshift-overflow")
add_cxxflag("-Woverflow")
add_cxxflag("-Wbool-conversions")
add_cxxflag("-Wconversion")
add_cxxflag("-Wsign-conversion")
add_cxxflag("-Wmissing-declarations")
add_cxxflag("-Wredundant-decls")
list(APPEND LIBRARIES -llzma)
if(DEBUG_EXTRA)
add_definitions(-D_GLIBCXX_DEBUG) # Runtime checks for STL containers.
add_cxxflag("-ftrapv") # to add checks for (undefined) signed integer overflow
add_cxxflag("-fcatch-undefined-behavior") # (clang)
add_cxxflag("-fbounds-checking")
else()
# -Wuninitialized causes too many false positives - thanks very much, gcc
add_cxxflag("-Wno-uninitialized")
endif()
list(APPEND CMAKE_CXX_FLAGS "-ggdb -O0 -march=native -Wl,--as-needed")
if(UNITY_BUILD)
add_cxxflag("-fwhole-program")
endif()
set(INNOEXTRACT_SOURCES
@ -69,7 +113,58 @@ set(INNOEXTRACT_SOURCES
src/InnoExtract.cpp
)
file(GLOB_RECURSE ALL_INCLUDES "${CMAKE_SOURCE_DIR}/src/*.hpp")
include_directories(src)
add_executable(innoextract ${INNOEXTRACT_SOURCES})
add_executable(innoextract ${INNOEXTRACT_SOURCES} ${ALL_INCLUDES})
target_link_libraries(innoextract ${LIBRARIES})
# Additional targets.
find_package(PythonInterp)
if(PYTHONINTERP_FOUND)
unset(STYLE_FILTER)
# Complains about any c-style cast -> too annoying.
set(STYLE_FILTER ${STYLE_FILTER},-readability/casting)
# Insists on including evrything in the .cpp file even if it is included in the header.
# This behaviour conflicts with orther tools.
set(STYLE_FILTER ${STYLE_FILTER},-build/include_what_you_use)
# Too many false positives and not very helpful error messages.
set(STYLE_FILTER ${STYLE_FILTER},-build/include_order)
# No thanks.
set(STYLE_FILTER ${STYLE_FILTER},-readability/streams)
# Ugh!
set(STYLE_FILTER ${STYLE_FILTER},-whitespace/tab)
# Yes it is!
set(STYLE_FILTER ${STYLE_FILTER},-whitespace/blank_line)
# Suggessts excessive indentation.
set(STYLE_FILTER ${STYLE_FILTER},-whitespace/labels)
# Don't tell me how to name my variables.
set(STYLE_FILTER ${STYLE_FILTER},-runtime/arrays)
# Why?
set(STYLE_FILTER ${STYLE_FILTER},-whitespace/todo)
set(STYLE_FILTER ${STYLE_FILTER},-readability/todo)
# TODO add copyright notices
set(STYLE_FILTER ${STYLE_FILTER},-legal/copyright)
# TODO split up main()
set(STYLE_FILTER ${STYLE_FILTER},-readability/fn_size)
add_custom_target(style
COMMAND cmake -E chdir "${CMAKE_SOURCE_DIR}" "${PYTHON_EXECUTABLE}" "${CMAKE_MODULE_PATH}/cpplint.py" "--filter=${STYLE_FILTER}" ${INNOEXTRACT_SOURCES} ${ALL_INCLUDES}
)
endif()

106
cmake/CompileCheck.cmake

@ -0,0 +1,106 @@
function(check_compiler_flag RESULT FLAG)
if(DEFINED CHECK_COMPILER_FLAG_${FLAG})
if(CHECK_COMPILER_FLAG_${FLAG})
set(${RESULT} "${FLAG}" PARENT_SCOPE)
else()
set(${RESULT} "" PARENT_SCOPE)
endif()
return()
endif()
set(compile_test_file "${CMAKE_CURRENT_BINARY_DIR}/compile_flag_test.cpp")
file(WRITE ${compile_test_file} "__attribute__((const)) int main(){ return 0; }\n")
try_compile(CHECK_COMPILER_FLAG ${CMAKE_BINARY_DIR} ${compile_test_file} COMPILE_DEFINITIONS "${FLAG}" OUTPUT_VARIABLE ERRORLOG)
string(REGEX MATCH "warning:" HAS_WARNING "${ERRORLOG}")
if(NOT CHECK_COMPILER_FLAG)
message(STATUS "Checking compiler flag: ${FLAG} - unsupported")
set(${RESULT} "" PARENT_SCOPE)
set("CHECK_COMPILER_FLAG_${FLAG}" 0 CACHE INTERNAL "...")
elseif(NOT HAS_WARNING STREQUAL "")
message(STATUS "Checking compiler flag: ${FLAG} - unsupported (warning)")
set(${RESULT} "" PARENT_SCOPE)
set("CHECK_COMPILER_FLAG_${FLAG}" 0 CACHE INTERNAL "...")
else()
message(STATUS "Checking compiler flag: ${FLAG}")
set(${RESULT} "${FLAG}" PARENT_SCOPE)
set("CHECK_COMPILER_FLAG_${FLAG}" 1 CACHE INTERNAL "...")
endif()
endfunction(check_compiler_flag)
function(add_cxxflag FLAG)
check_compiler_flag(RESULT "${FLAG}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RESULT}" PARENT_SCOPE)
endfunction(add_cxxflag)
function(try_link_library LIBRARY_NAME LIBRARY_FILE ERROR_VAR)
# See if we can link a simple program with the library using the configured c++ compiler.
set(link_test_file "${CMAKE_CURRENT_BINARY_DIR}/link_test.cpp")
file(WRITE ${link_test_file} "int main(){}\n")
if(CMAKE_THREAD_LIBS_INIT)
list(APPEND LIBRARY_FILE "${CMAKE_THREAD_LIBS_INIT}")
endif()
try_compile(CHECK_${LIBRARY_NAME}_LINK "${CMAKE_BINARY_DIR}" "${link_test_file}" CMAKE_FLAGS "-DLINK_LIBRARIES=${LIBRARY_FILE}" OUTPUT_VARIABLE ERRORLOG)
set(${ERROR_VAR} "${ERRORLOG}" PARENT_SCOPE)
endfunction(try_link_library)
##############################################################################
# Check that a a library actually works for the current configuration.
function(check_link_library LIBRARY_NAME LIBRARY_VARIABLE)
set(lib_current "${${LIBRARY_VARIABLE}}")
set(found_var "ARX_CLL_${LIBRARY_NAME}_FOUND")
set(working_var "ARX_CLL_${LIBRARY_NAME}_WORKING")
if(CHECK_${LIBRARY_NAME}_LINK)
set(lib_found "${${found_var}}")
set(lib_working "${${working_var}}")
if((lib_current STREQUAL lib_found) OR (lib_current STREQUAL lib_working))
set("${LIBRARY_VARIABLE}" "${lib_working}" PARENT_SCOPE)
return()
endif()
endif()
set("${found_var}" "${lib_current}" CACHE INTERNAL "...")
message(STATUS "Checking ${LIBRARY_NAME}: ${lib_current}")
# Check if we can link to the full path found by find_package.
try_link_library(${LIBRARY_NAME} "${lib_current}" ERRORLOG1)
if(CHECK_${LIBRARY_NAME}_LINK)
set("${working_var}" "${lib_current}" CACHE INTERNAL "...")
return()
endif()
# Check if the linker is smarter than cmake and try to link with only the library name.
string(REGEX REPLACE "(^|;)[^;]*/lib([^;/]*)\\.so" "\\1-l\\2" LIBRARY_FILE "${lib_current}")
try_link_library(${LIBRARY_NAME} "${LIBRARY_FILE}" ERRORLOG2)
if(CHECK_${LIBRARY_NAME}_LINK)
message(STATUS " -> using ${LIBRARY_FILE} instead")
set("${LIBRARY_VARIABLE}" "${LIBRARY_FILE}" PARENT_SCOPE)
set("${working_var}" "${LIBRARY_FILE}" CACHE INTERNAL "...")
return()
endif()
# Force cmake to search again, as the cached library doesn't work.
unset(FIND_PACKAGE_MESSAGE_DETAILS_${ARGV2} CACHE)
unset(FIND_PACKAGE_MESSAGE_DETAILS_${LIBRARY_NAME} CACHE)
message(FATAL_ERROR "\n${ERRORLOG1}\n\n${ERRORLOG2}\n\n!! No suitable (32- vs. 64-bit) version of ${LIBRARY_NAME} found; tried ${lib_current} and ${LIBRARY_FILE}\nusing compiler ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS}\n")
endfunction(check_link_library)
function(force_recheck_library LIBRARY_NAME)
unset(FIND_PACKAGE_MESSAGE_DETAILS_${ARGV1} CACHE)
unset(FIND_PACKAGE_MESSAGE_DETAILS_${LIBRARY_NAME} CACHE)
unset(CHECK_${LIBRARY_NAME}_LINK CACHE)
endfunction()

22
cmake/FindLZMA.cmake

@ -0,0 +1,22 @@
# Try to find the LZMA library and include path for lzma.h from xz-utils.
# Once done this will define
#
# LZMA_FOUND
# LZMA_INCLUDE_DIR - where to find lzma.h
# LZMA_LIBRARIES - liblzma.so
find_path(LZMA_INCLUDE_DIR lzma.h DOC "The directory where lzma.h resides")
find_library(LZMA_LIBRARY lzma DOC "The LZMA library")
mark_as_advanced(LZMA_INCLUDE_DIR)
mark_as_advanced(LZMA_LIBRARY)
# handle the QUIETLY and REQUIRED arguments and set LZMA_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LZMA DEFAULT_MSG LZMA_LIBRARY LZMA_INCLUDE_DIR)
if(LZMA_FOUND)
set(LZMA_LIBRARIES ${LZMA_LIBRARY})
endif(LZMA_FOUND)

47
cmake/VersionScript.cmake

@ -0,0 +1,47 @@
cmake_minimum_required(VERSION 2.8)
# CMake script that reads a VERSION file and the current git history and the calls configure_file().
# This is used by version_file() in VersionString.cmake
if((NOT DEFINED INPUT) OR (NOT DEFINED OUTPUT) OR (NOT DEFINED VERSION_FILE) OR (NOT DEFINED GIT_DIR))
message(SEND_ERROR "Invalid arguments.")
endif()
file(READ "${VERSION_FILE}" BASE_VERSION)
string(STRIP "${BASE_VERSION}" BASE_VERSION)
if(EXISTS "${GIT_DIR}")
file(READ "${GIT_DIR}/HEAD" GIT_HEAD)
string(STRIP "${GIT_HEAD}" GIT_HEAD)
unset(GIT_COMMIT)
if("${GIT_HEAD}" MATCHES "^ref\\:")
# Remove the first for characters from GIT_HEAD to get GIT_REF.
# We can't use a length of -1 for string(SUBSTRING) as cmake < 2.8.5 doesn't support it.
string(LENGTH "${GIT_HEAD}" GIT_HEAD_LENGTH)
math(EXPR GIT_REF_LENGTH "${GIT_HEAD_LENGTH} - 4")
string(SUBSTRING "${GIT_HEAD}" 4 ${GIT_REF_LENGTH} GIT_REF)
string(STRIP "${GIT_REF}" GIT_REF)
file(READ "${GIT_DIR}/${GIT_REF}" GIT_HEAD)
string(STRIP "${GIT_HEAD}" GIT_HEAD)
endif()
string(REGEX MATCH "[0-9A-Za-z]+" GIT_COMMIT "${GIT_HEAD}")
# Create variables for all prefixes of the git comit ID.
if(GIT_COMMIT)
string(TOLOWER "${GIT_COMMIT}" GIT_COMMIT)
string(LENGTH "${GIT_COMMIT}" GIT_COMMIT_LENGTH)
foreach(i RANGE "${GIT_COMMIT_LENGTH}")
string(SUBSTRING "${GIT_COMMIT}" 0 ${i} GIT_COMMIT_PREFIX_${i})
endforeach()
endif()
endif()
configure_file("${INPUT}" "${OUTPUT}" ESCAPE_QUOTES)

41
cmake/VersionString.cmake

@ -0,0 +1,41 @@
# Create a rule to generate a version string at compile time.
#
# SRC is processed using the configure_file() cmake command
# at build to produce DST with the following variable available:
#
# - BASE_VERSION: The contents of the file specified by VERSION_FILE.
# - GIT_COMMIT: The current git commit. This variable is not defined if there is no GIT_DIR directory.
# - SHORT_GIT_COMMIT: The first 10 characters of the git commit.
# For the exact syntax of SRC see the documentation of the configure_file() cmake command.
#
# The version file is regenerated whenever VERSION_FILE or the current commit changes.
function(version_file SRC DST VERSION_FILE GIT_DIR)
get_filename_component(ABS_SRC "${SRC}" ABSOLUTE)
get_filename_component(ABS_DST "${DST}" ABSOLUTE)
get_filename_component(ABS_VERSION_FILE "${VERSION_FILE}" ABSOLUTE)
get_filename_component(ABS_GIT_DIR "${GIT_DIR}" ABSOLUTE)
add_custom_command(
OUTPUT
"${DST}"
COMMAND
${CMAKE_COMMAND}
"-DINPUT=${ABS_SRC}"
"-DOUTPUT=${ABS_DST}"
"-DVERSION_FILE=${ABS_VERSION_FILE}"
"-DGIT_DIR=${ABS_GIT_DIR}"
-P "${CMAKE_MODULE_PATH}/VersionScript.cmake"
MAIN_DEPENDENCY
"${SRC}"
DEPENDS
"${GIT_DIR}/HEAD"
"${GIT_DIR}/logs/HEAD"
"${VERSION_FILE}"
"${CMAKE_MODULE_PATH}/VersionScript.cmake"
COMMENT ""
VERBATIM
)
endfunction(version_file)

14
cmake/clang-toolchain.cmake

@ -0,0 +1,14 @@
# Look for wine compilers
find_program(Clang clang)
mark_as_advanced(Clang)
find_program(ClangXX clang++)
mark_as_advanced(ClangXX)
if((NOT Clang) OR (NOT ClangXX))
message(FATAL_ERROR "clang not found (found: c compiler \"${Clang}\", c++ compiler \"${ClangXX}\")")
endif()
# which compilers to use for C and C++
set(CMAKE_C_COMPILER "${Clang}")
set(CMAKE_CXX_COMPILER "${ClangXX}")

3153
cmake/cpplint.py vendored

File diff suppressed because it is too large Load Diff

18
cmake/ekopath-toolchain.cmake

@ -0,0 +1,18 @@
# Look for wine compilers
find_program(Ekopath pathcc)
mark_as_advanced(Ekopath)
find_program(EkopathXX pathCC)
mark_as_advanced(EkopathXX)
if((NOT Ekopath) OR (NOT EkopathXX))
message(FATAL_ERROR "ekopath not found (found: c compiler \"${Ekopath}\", c++ compiler \"${EkopathXX}\")")
endif()
# which compilers to use for C and C++
set(CMAKE_C_COMPILER "${Ekopath}")
set(CMAKE_CXX_COMPILER "${EkopathXX}")
# tell cmake that ekopath supports -isystem
set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")

78
cmake/mingw32-toolchain.cmake

@ -0,0 +1,78 @@
# the name of the target operating system
set(CMAKE_SYSTEM_NAME Windows)
# Look for mingw32 compilers
if(DEFINED MINGW32_ROOT)
set(MinGW32_ROOT "${MINGW32_ROOT}" CACHE INTERNAL)
else()
find_path(MinGW32_ROOT mingw
PATH_SUFFIXES
i686-pc-mingw32
i586-pc-mingw32
i486-pc-mingw32
i386-pc-mingw32
i686-mingw32
i586-mingw32
i486-mingw32
i386-mingw32
mingw32
PATHS
/usr
/usr/local
)
endif()
mark_as_advanced(MinGW32_ROOT)
find_program(MinGW32_GCC NAMES
i686-pc-mingw32-gcc
i586-pc-mingw32-gcc
i486-pc-mingw32-gcc
i386-pc-mingw32-gcc
i686-mingw32-gcc
i586-mingw32-gcc
i486-mingw32-gcc
i386-mingw32-gcc
)
mark_as_advanced(MinGW32_GCC)
find_program(MinGW32_GXX NAMES
i686-pc-mingw32-g++
i586-pc-mingw32-g++
i486-pc-mingw32-g++
i386-pc-mingw32-g++
i686-mingw32-g++
i586-mingw32-g++
i486-mingw32-g++
i386-mingw32-g++
)
mark_as_advanced(MinGW32_GXX)
find_program(MinGW32_RC NAMES
i686-pc-mingw32-windres
i586-pc-mingw32-windres
i486-pc-mingw32-windres
i386-pc-mingw32-windres
i686-mingw32-windres
i586-mingw32-windres
i486-mingw32-windres
i386-mingw32-windres
)
mark_as_advanced(MinGW32_RC)
if((NOT MinGW32_GCC) OR (NOT MinGW32_GXX) OR (NOT MinGW32_RC) OR (NOT MinGW32_ROOT))
message(FATAL_ERROR "mingw32 not found (found gcc=\"${MinGW32_GCC}\", g++=\"${MinGW32_GXX}\" rc=\"${MinGW32_RC}\" root=\"${MinGW32_ROOT}\")")
endif()
# which compilers to use for C and C++
set(CMAKE_C_COMPILER "${MinGW32_GCC}")
set(CMAKE_CXX_COMPILER "${MinGW32_GXX}")
set(CMAKE_RC_COMPILER "${MinGW32_RC}")
# here is the target environment located
set(CMAKE_FIND_ROOT_PATH "${MinGW32_ROOT}")
# adjust the default behaviour of the find_xxx() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY FIRST)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE FIRST)

142
src/InnoExtract.cpp

@ -77,7 +77,7 @@ public:
if(progress_length > 10) {
size_t progress = ceil(progress_length * value);
size_t progress = size_t(ceil(float(progress_length) * value));
std::cout << '[';
for(size_t i = 0; i < progress; i++) {
@ -91,7 +91,8 @@ public:
}
std::cout << std::right << std::fixed << std::setprecision(1) << std::setfill(' ') << std::setw(5) << (value * 100) << "% " << label;
std::cout << std::right << std::fixed << std::setprecision(1) << std::setfill(' ')
<< std::setw(5) << (value * 100) << "% " << label;
std::cout.flush();
std::cout.flags(flags);
@ -99,7 +100,7 @@ public:
}
static void clear() {
std::cout << "\33[2K\r" ;
std::cout << "\33[2K\r";
}
};
@ -119,9 +120,9 @@ void discard(T & is, uint64_t bytes) {
char buf[1024];
while(bytes) {
size_t n = std::min<uint64_t>(bytes, ARRAY_SIZE(buf));
std::streamsize n = std::streamsize(std::min<uint64_t>(bytes, ARRAY_SIZE(buf)));
is.read(buf, n);
bytes -= n;
bytes -= uint64_t(n);
}
}
@ -133,7 +134,7 @@ struct FileLocationComparer {
const std::vector<FileLocationEntry> & locations;
FileLocationComparer(const std::vector<FileLocationEntry> & loc) : locations(loc) { }
explicit FileLocationComparer(const std::vector<FileLocationEntry> & loc) : locations(loc) { }
FileLocationComparer(const FileLocationComparer & o) : locations(o.locations) { }
bool operator()(size_t a, size_t b) {
@ -142,7 +143,8 @@ struct FileLocationComparer {
};
void printSetupItem(std::ostream & os, const SetupItem & item, const SetupHeader & header) {
static void printSetupItem(std::ostream & os, const SetupItem & item,
const SetupHeader & header) {
os << IfNotEmpty(" Componenets", item.components);
os << IfNotEmpty(" Tasks", item.tasks);
@ -157,7 +159,7 @@ void printSetupItem(std::ostream & os, const SetupItem & item, const SetupHeader
}
void print(std::ostream & os, const RunEntry & entry, const SetupHeader & header) {
static void print(std::ostream & os, const RunEntry & entry, const SetupHeader & header) {
os << " - " << Quoted(entry.name) << ':' << endl;
os << IfNotEmpty(" Parameters", entry.parameters);
@ -176,7 +178,7 @@ void print(std::ostream & os, const RunEntry & entry, const SetupHeader & header
}
std::ostream & operator<<(std::ostream & os, const Checksum & checksum) {
static std::ostream & operator<<(std::ostream & os, const Checksum & checksum) {
std::ios_base::fmtflags old = os.flags();
@ -220,7 +222,7 @@ static const char * magicNumbers[][2] = {
{ "BM", "bmp" },
};
const char * guessExtension(const string & data) {
static const char * guessExtension(const string & data) {
for(size_t i = 0; i < ARRAY_SIZE(magicNumbers); i++) {
@ -234,13 +236,14 @@ const char * guessExtension(const string & data) {
return "bin";
}
void dump(std::istream & is, const string & file) {
static void dump(std::istream & is, const string & file) {
// TODO stream
std::string data;
is >> BinaryString(data);
cout << "Resource: " << color::cyan << file << color::reset << ": " << color::white << data.length() << color::reset << " bytes" << endl;
cout << "Resource: " << color::cyan << file << color::reset << ": " << color::white
<< data.length() << color::reset << " bytes" << endl;
if(data.empty()) {
return;
@ -248,12 +251,14 @@ void dump(std::istream & is, const string & file) {
std::string filename = file + '.' + guessExtension(data);
std::ofstream ofs(filename.c_str(), std::ios_base::trunc | std::ios_base::binary | std::ios_base::out);
std::ofstream ofs(filename.c_str(), std::ios_base::trunc | std::ios_base::binary
| std::ios_base::out);
ofs << data;
};
void readWizardImageAndDecompressor(std::istream & is, const InnoVersion & version, const SetupHeader & header) {
static void readWizardImageAndDecompressor(std::istream & is, const InnoVersion & version,
const SetupHeader & header) {
cout << endl;
@ -264,8 +269,8 @@ void readWizardImageAndDecompressor(std::istream & is, const InnoVersion & versi
}
if(header.compressMethod == SetupHeader::BZip2
|| (header.compressMethod == SetupHeader::LZMA1 && version == INNO_VERSION(4, 1, 5))
|| (header.compressMethod == SetupHeader::Zlib && version >= INNO_VERSION(4, 2, 6))) {
|| (header.compressMethod == SetupHeader::LZMA1 && version == INNO_VERSION(4, 1, 5))
|| (header.compressMethod == SetupHeader::Zlib && version >= INNO_VERSION(4, 2, 6))) {
dump(is, "decompressor");
}
@ -290,29 +295,25 @@ int main(int argc, char * argv[]) {
return 1;
}
uint64_t fileSize = ifs.tellg();
if(!fileSize) {
LogError << "cannot read file or empty file";
return 1;
}
SetupLoader offsets;
offsets.load(ifs);
cout << std::boolalpha;
cout << "loaded offsets:" << endl;
cout << "- total size: " << color::cyan << PrintBytes(offsets.totalSize) << color::reset << endl;
if(offsets.exeOffset) {
cout << "- exe: @ " << color::cyan << PrintHex(offsets.exeOffset) << color::reset;
if(offsets.exeCompressedSize) {
cout << " compressed: " << color::cyan << PrintHex(offsets.exeCompressedSize) << color::reset;
cout << " compressed: " << color::cyan << PrintHex(offsets.exeCompressedSize)
<< color::reset;
}
cout << " uncompressed: " << color::cyan << PrintBytes(offsets.exeUncompressedSize) << color::reset << endl;
cout << " uncompressed: " << color::cyan << PrintBytes(offsets.exeUncompressedSize)
<< color::reset << endl;
cout << "- exe checksum: " << color::cyan << offsets.exeChecksum << color::reset << endl;
}
cout << IfNotZero("- message offset", PrintHex(offsets.messageOffset));
cout << "- header offset: " << color::cyan << PrintHex(offsets.headerOffset) << color::reset << endl;
cout << "- header offset: " << color::cyan << PrintHex(offsets.headerOffset)
<< color::reset << endl;
cout << IfNotZero("- data offset", PrintHex(offsets.dataOffset));
ifs.seekg(offsets.headerOffset);
@ -419,15 +420,21 @@ int main(int argc, char * argv[]) {
cout << IfNotZero("Slices per disk", header.slicesPerDisk);
cout << IfNot("Install mode", header.installMode, SetupHeader::NormalInstallMode);
cout << "Uninstall log mode: " << color::cyan << header.uninstallLogMode << color::reset << endl;
cout << "Uninstall log mode: " << color::cyan << header.uninstallLogMode
<< color::reset << endl;
cout << "Uninstall style: " << color::cyan << header.uninstallStyle << color::reset << endl;
cout << "Dir exists warning: " << color::cyan << header.dirExistsWarning << color::reset << endl;
cout << "Dir exists warning: " << color::cyan << header.dirExistsWarning
<< color::reset << endl;
cout << IfNot("Privileges required", header.privilegesRequired, SetupHeader::NoPrivileges);
cout << "Show language dialog: " << color::cyan << header.showLanguageDialog << color::reset << endl;
cout << IfNot("Danguage detection", header.languageDetectionMethod, SetupHeader::NoLanguageDetection);
cout << "Show language dialog: " << color::cyan << header.showLanguageDialog
<< color::reset << endl;
cout << IfNot("Danguage detection", header.languageDetectionMethod,
SetupHeader::NoLanguageDetection);
cout << "Compression: " << color::cyan << header.compressMethod << color::reset << endl;
cout << "Architectures allowed: " << color::cyan << header.architecturesAllowed << color::reset << endl;
cout << "Architectures installed in 64-bit mode: " << color::cyan << header.architecturesInstallIn64BitMode << color::reset << endl;
cout << "Architectures allowed: " << color::cyan << header.architecturesAllowed
<< color::reset << endl;
cout << "Architectures installed in 64-bit mode: " << color::cyan
<< header.architecturesInstallIn64BitMode << color::reset << endl;
if(header.options & SetupHeader::SignedUninstaller) {
cout << IfNotZero("Size before signing uninstaller", header.signedUninstallerOrigSize);
@ -435,7 +442,8 @@ int main(int argc, char * argv[]) {
}
cout << "Disable dir page: " << color::cyan << header.disableDirPage << color::reset << endl;
cout << "Disable program group page: " << color::cyan << header.disableProgramGroupPage << color::reset << endl;
cout << "Disable program group page: " << color::cyan << header.disableProgramGroupPage
<< color::reset << endl;
cout << IfNotZero("Uninstall display size", header.uninstallDisplaySize);
@ -467,7 +475,8 @@ int main(int argc, char * argv[]) {
cout << IfNotEmpty(" Info before text", entry.infoBeforeText);
cout << IfNotEmpty(" Info after text", entry.infoAfterText);
cout << " Language id: " << color::cyan << hex << entry.languageId << dec << color::reset << endl;
cout << " Language id: " << color::cyan << hex << entry.languageId << dec
<< color::reset << endl;
cout << IfNotZero(" Codepage", entry.codepage);
cout << IfNotZero(" Dialog font size", entry.dialogFontSize);
@ -498,21 +507,22 @@ int main(int argc, char * argv[]) {
LogWarning << "unexpected language index: " << entry.language;
}
int codepage;
if(entry.language == -1) {
uint32_t codepage;
if(entry.language < 0) {
codepage = version.codepage();
} else {
codepage = languages[entry.language].codepage;
codepage = languages[size_t(entry.language)].codepage;
}
string decoded;
toUtf8(entry.value, decoded, codepage);
cout << " - " << Quoted(entry.name);
if(entry.language == -1) {
if(entry.language < 0) {
cout << " (default) = ";
} else {
cout << " (" << color::cyan << languages[entry.language].name << color::reset << ") = ";
cout << " (" << color::cyan << languages[size_t(entry.language)].name
<< color::reset << ") = ";
}
cout << Quoted(decoded) << endl;
@ -663,7 +673,7 @@ int main(int argc, char * argv[]) {
} else {
cout << " - " << Quoted(entry.destination);
}
if(entry.location != -1) {
if(entry.location != uint32_t(-1)) {
cout << " (location: " << color::cyan << entry.location << color::reset << ')';
}
cout << endl;
@ -900,11 +910,11 @@ int main(int argc, char * argv[]) {
cout << " Timestamp: " << color::cyan << (t.tm_year + 1900)
<< '-' << std::setfill('0') << std::setw(2) << (t.tm_mon + 1)
<< '-' << std::setfill('0') << std::setw(2) << t.tm_mday
<< ' ' << std::setfill(' ') << std::setw(2) << t.tm_hour
<< ':' << std::setfill('0') << std::setw(2) << t.tm_min
<< ':' << std::setfill('0') << std::setw(2) << t.tm_sec
<< color::reset << " +" << entry.timestamp.tv_nsec << endl;
<< '-' << std::setfill('0') << std::setw(2) << t.tm_mday
<< ' ' << std::setfill(' ') << std::setw(2) << t.tm_hour
<< ':' << std::setfill('0') << std::setw(2) << t.tm_min
<< ':' << std::setfill('0') << std::setw(2) << t.tm_sec
<< color::reset << " +" << entry.timestamp.tv_nsec << endl;
cout << IfNotZero(" Options", entry.options);
@ -937,8 +947,12 @@ int main(int argc, char * argv[]) {
Chunks chunks;
for(size_t i = 0; i < locations.size(); i++) {
const FileLocationEntry & location = locations[i];
chunks[ChunkReader::Chunk(location.firstSlice, location.chunkOffset, location.chunkSize, location.options & FileLocationEntry::ChunkCompressed, location.options & FileLocationEntry::ChunkEncrypted)].push_back(i);
assert(header.compressMethod == SetupHeader::BZip2 || !(location.options & FileLocationEntry::BZipped));
chunks[ChunkReader::Chunk(location.firstSlice, location.chunkOffset, location.chunkSize,
location.options & FileLocationEntry::ChunkCompressed,
location.options & FileLocationEntry::ChunkEncrypted)
].push_back(i);
assert(header.compressMethod == SetupHeader::BZip2
|| !(location.options & FileLocationEntry::BZipped));
}
boost::shared_ptr<SliceReader> slice_reader;
@ -948,15 +962,17 @@ int main(int argc, char * argv[]) {
} else {
fs::path path(argv[1]);
slice_reader.reset(new SliceReader(path.parent_path().string() + '/', path.stem().string(), header.slicesPerDisk));
slice_reader.reset(new SliceReader(path.parent_path().string() + '/',
path.stem().string(), header.slicesPerDisk));
}
try {
BOOST_FOREACH(Chunks::value_type & chunk, chunks) {
cout << "[starting " << (chunk.first.compressed ? header.compressMethod : SetupHeader::Stored) << " chunk @ " << chunk.first.firstSlice << " + " << PrintHex(offsets.dataOffset) << " + "
<< PrintHex(chunk.first.chunkOffset) << ']' << std::endl;
cout << "[starting " << (chunk.first.compressed ? header.compressMethod : SetupHeader::Stored)
<< " chunk @ " << chunk.first.firstSlice << " + " << PrintHex(offsets.dataOffset)
<< " + " << PrintHex(chunk.first.chunkOffset) << ']' << std::endl;
std::sort(chunk.second.begin(), chunk.second.end(), FileLocationComparer(locations));
@ -987,7 +1003,8 @@ int main(int argc, char * argv[]) {
}
}
chunk_source.push(io::restrict(boost::ref(*slice_reader.get()), 0, chunk.first.chunkSize));
int64_t csize = int64_t(chunk.first.chunkSize);
chunk_source.push(io::restrict(boost::ref(*slice_reader.get()), 0, csize));
uint64_t offset = 0;
@ -1022,7 +1039,8 @@ int main(int argc, char * argv[]) {
Hasher hasher;
hasher.init(location.checksum.type);
io::restriction<chunk_stream_type> raw_src(chunk_source, 0, location.fileSize);
int64_t file_size = int64_t(location.fileSize);
io::restriction<chunk_stream_type> raw_src(chunk_source, 0, file_size);
io::filtering_istream file_source;
@ -1038,10 +1056,6 @@ int main(int argc, char * argv[]) {
file_source.push(raw_src);
//file_source.exceptions(std::ios_base::badbit | std::ios_base::failbit);
//discard(file, location.fileSize);
BOOST_FOREACH(size_t file_i, files_for_location[location_i]) {
if(!files[file_i].destination.empty()) {
std::ofstream ofs(files[file_i].destination.c_str());
@ -1054,7 +1068,7 @@ int main(int argc, char * argv[]) {
std::ostringstream oss;
float last_rate = 0;
int32_t last_milliseconds = 0;
int64_t last_milliseconds = 0;
boost::posix_time::ptime start(boost::posix_time::microsec_clock::universal_time());
@ -1066,23 +1080,24 @@ int main(int argc, char * argv[]) {
ofs.write(buffer, n);
total += n;
float new_status = size_t(1000.f * total / location.fileSize)
* (1 / 1000.f);
total += uint64_t(n);
float new_status = float(size_t(1000.f * float(total) / float(location.fileSize)))
* (1 / 1000.f);
if(status != new_status && new_status != 100.f) {
boost::posix_time::ptime now(boost::posix_time::microsec_clock::universal_time());
int32_t milliseconds = (now - start).total_milliseconds();
int64_t milliseconds = (now - start).total_milliseconds();
if(milliseconds - last_milliseconds > 200) {
last_milliseconds = milliseconds;
if(total >= 10 * 1024 && milliseconds > 0) {
float rate = 1000.f * total / milliseconds;
float rate = 1000.f * float(total) / float(milliseconds);
if(rate != last_rate) {
last_rate = rate;
oss.str(string()); // clear the buffer
oss << std::right << std::fixed << std::setfill(' ') << std::setw(8) << PrintBytes(rate) << "/s";
oss << std::right << std::fixed << std::setfill(' ') << std::setw(8)
<< PrintBytes(rate) << "/s";
}
}
@ -1093,7 +1108,6 @@ int main(int argc, char * argv[]) {
}
}
//io::copy(file_source, ofs, 8192);
break; // TODO ...
}
}

120
src/crypto/ARC4.cpp

@ -1,120 +0,0 @@
// arc4.cpp - written and placed in the public domain by Wei Dai
// The ARC4 algorithm was first revealed in an anonymous email to the
// cypherpunks mailing list. This file originally contained some
// code copied from this email. The code has since been rewritten in order
// to clarify the copyright status of this file. It should now be
// completely in the public domain.
#include "pch.h"
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include "arc4.h"
NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 {
void ARC4_TestInstantiations()
{
ARC4 x;
}
ARC4_Base::~ARC4_Base()
{
m_x = m_y = 0;
}
void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs &params)
{
AssertValidKeyLength(keyLen);
m_x = 1;
m_y = 0;
unsigned int i;
for (i=0; i<256; i++)
m_state[i] = i;
unsigned int keyIndex = 0, stateIndex = 0;
for (i=0; i<256; i++)
{
unsigned int a = m_state[i];
stateIndex += key[keyIndex] + a;
stateIndex &= 0xff;
m_state[i] = m_state[stateIndex];
m_state[stateIndex] = a;
if (++keyIndex >= keyLen)
keyIndex = 0;
}
int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes());
DiscardBytes(discardBytes);
}
template <class T>
static inline unsigned int MakeByte(T &x, T &y, byte *s)
{
unsigned int a = s[x];
y = (y+a) & 0xff;
unsigned int b = s[y];
s[x] = b;
s[y] = a;
x = (x+1) & 0xff;
return s[(a+b) & 0xff];
}
void ARC4_Base::GenerateBlock(byte *output, size_t size)
{
while (size--)
*output++ = MakeByte(m_x, m_y, m_state);
}
void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length)
{
if (length == 0)
return;
byte *const s = m_state;
unsigned int x = m_x;
unsigned int y = m_y;
if (inString == outString)
{
do
{
*outString++ ^= MakeByte(x, y, s);
} while (--length);
}
else
{
do
{
*outString++ = *inString++ ^ MakeByte(x, y, s);
}
while(--length);
}
m_x = x;
m_y = y;
}
void ARC4_Base::DiscardBytes(size_t length)
{
if (length == 0)
return;
byte *const s = m_state;
unsigned int x = m_x;
unsigned int y = m_y;
do
{
MakeByte(x, y, s);
}
while(--length);
m_x = x;
m_y = y;
}
}
NAMESPACE_END

71
src/crypto/ARC4.h

@ -1,71 +0,0 @@
#ifndef CRYPTOPP_ARC4_H
#define CRYPTOPP_ARC4_H
#include "strciphr.h"
NAMESPACE_BEGIN(CryptoPP)
namespace Weak1 {
//! _
class CRYPTOPP_NO_VTABLE ARC4_Base : public VariableKeyLength<16, 1, 256>, public RandomNumberGenerator, public SymmetricCipher, public SymmetricCipherDocumentation
{
public:
~ARC4_Base();
static const char *StaticAlgorithmName() {return "ARC4";}
void GenerateBlock(byte *output, size_t size);
void DiscardBytes(size_t n);
void ProcessData(byte *outString, const byte *inString, size_t length);
bool IsRandomAccess() const {return false;}
bool IsSelfInverting() const {return true;}
bool IsForwardTransformation() const {return true;}
typedef SymmetricCipherFinal<ARC4_Base> Encryption;
typedef SymmetricCipherFinal<ARC4_Base> Decryption;
protected:
void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
virtual unsigned int GetDefaultDiscardBytes() const {return 0;}
FixedSizeSecBlock<byte, 256> m_state;
byte m_x, m_y;
};
//! <a href="http://www.weidai.com/scan-mirror/cs.html#RC4">Alleged RC4</a>
DOCUMENTED_TYPEDEF(SymmetricCipherFinal<ARC4_Base>, ARC4)
//! _
class CRYPTOPP_NO_VTABLE MARC4_Base : public ARC4_Base
{
public:
static const char *StaticAlgorithmName() {return "MARC4";}
typedef SymmetricCipherFinal<MARC4_Base> Encryption;
typedef SymmetricCipherFinal<MARC4_Base> Decryption;
protected:
unsigned int GetDefaultDiscardBytes() const {return 256;}
};
//! Modified ARC4: it discards the first 256 bytes of keystream which may be weaker than the rest
DOCUMENTED_TYPEDEF(SymmetricCipherFinal<MARC4_Base>, MARC4)
}
#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1
namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak
#else
using namespace Weak1; // import Weak1 into CryptoPP with warning
#ifdef __GNUC__
#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning."
#else
#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.")
#endif
#endif
NAMESPACE_END
#endif

22
src/crypto/Adler-32.cpp

@ -6,10 +6,10 @@
void Adler32::update(const char * input, size_t length) {
const unsigned long BASE = 65521;
const uint_fast32_t BASE = 65521;
unsigned long s1 = this->s1;
unsigned long s2 = this->s2;
uint_fast32_t s1 = this->s1;
uint_fast32_t s2 = this->s2;
if(length % 8 != 0) {
@ -28,14 +28,14 @@ void Adler32::update(const char * input, size_t length) {
while(length > 0) {
s1 += uint8_t(input[0]); s2 += s1;
s1 += uint8_t(input[1]); s2 += s1;
s1 += uint8_t(input[2]); s2 += s1;
s1 += uint8_t(input[3]); s2 += s1;
s1 += uint8_t(input[4]); s2 += s1;
s1 += uint8_t(input[5]); s2 += s1;
s1 += uint8_t(input[6]); s2 += s1;
s1 += uint8_t(input[7]); s2 += s1;
s1 += uint8_t(input[0]), s2 += s1;
s1 += uint8_t(input[1]), s2 += s1;
s1 += uint8_t(input[2]), s2 += s1;
s1 += uint8_t(input[3]), s2 += s1;
s1 += uint8_t(input[4]), s2 += s1;
s1 += uint8_t(input[5]), s2 += s1;
s1 += uint8_t(input[6]), s2 += s1;
s1 += uint8_t(input[7]), s2 += s1;
length -= 8;
input += 8;

5
src/crypto/Adler-32.hpp

@ -2,13 +2,14 @@
#ifndef INNOEXTRACT_CRYPTO_ADLER32_HPP
#define INNOEXTRACT_CRYPTO_ADLER32_HPP
#include <stddef.h>
#include <stdint.h>
#include "crypto/Checksum.hpp"
//! ADLER-32 checksum calculations
//! ADLER-32 checksum calculations
struct Adler32 : public ChecksumBase<Adler32> {
void init() { s1 = 1; s2 = 0; }
void init() { s1 = 1, s2 = 0; }
void update(const char * data, size_t length);

46
src/crypto/IteratedHash.hpp

@ -15,13 +15,13 @@ inline bool isPowerOf2(const T & n) {
}
template <class T1, class T2>
inline T2 modPowerOf2(const T1 &a, const T2 &b) {
return T2(a) & (b-1);
inline T2 modPowerOf2(const T1 & a, const T2 & b) {
return T2(a) & (b - 1);
}
template <class T>
inline unsigned int getAlignmentOf() {
#if (_MSC_VER >= 1300)
#if defined(_MSC_VER) && _MSC_VER >= 1300
return __alignof(T);
#elif defined(__GNUC__)
return __alignof__(T);
@ -31,7 +31,8 @@ inline unsigned int getAlignmentOf() {
}
inline bool isAlignedOn(const void * p, unsigned int alignment) {
return alignment==1 || (isPowerOf2(alignment) ? modPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0);
return alignment == 1 || (isPowerOf2(alignment) ? modPowerOf2(size_t(p), alignment) == 0
: size_t(p) % alignment == 0);
}
template <class T>
@ -45,12 +46,12 @@ template<>
struct SafeShifter<true> {
template <class T>
static inline T RightShift(T value, unsigned int bits) {
static inline T RightShift(T, unsigned int) {
return 0;
}
template <class T>
static inline T LeftShift(T value, unsigned int bits) {
static inline T LeftShift(T, unsigned int) {
return 0;
}
};
@ -71,12 +72,12 @@ struct SafeShifter<false> {
template <unsigned int bits, class T>
inline T SafeRightShift(T value) {
return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
return SafeShifter<(bits >= (8 * sizeof(T)))>::RightShift(value, bits);
}
template <unsigned int bits, class T>
inline T SafeLeftShift(T value) {
return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
return SafeShifter<(bits >= (8 * sizeof(T)))>::LeftShift(value, bits);
}
template <class T>
@ -116,7 +117,7 @@ private:
template <class T>
void IteratedHash<T>::update(const char * input, size_t len) {
HashWord oldCountLo = countLo, oldCountHi = countHi;
HashWord oldCountLo = countLo;
if((countLo = oldCountLo + HashWord(len)) < oldCountLo) {
countHi++; // carry from low to high
@ -124,7 +125,7 @@ void IteratedHash<T>::update(const char * input, size_t len) {
countHi += HashWord(SafeRightShift<8 * sizeof(HashWord)>(len));
unsigned int num = modPowerOf2(oldCountLo, size_t(BlockSize));
size_t num = modPowerOf2(oldCountLo, size_t(BlockSize));
uint8_t * d = reinterpret_cast<uint8_t *>(data);
if(num != 0) { // process left over data
@ -155,7 +156,7 @@ void IteratedHash<T>::update(const char * input, size_t len) {
hash(data, BlockSize);
input += BlockSize;
len -= BlockSize;
} while (len >= BlockSize);
} while(len >= BlockSize);
}
}
@ -187,16 +188,16 @@ size_t IteratedHash<T>::hash(const HashWord * input, size_t length) {
template <class T>
void IteratedHash<T>::pad(unsigned int lastBlockSize, uint8_t padFirst) {
unsigned int num = modPowerOf2(countLo, size_t(BlockSize));
size_t num = modPowerOf2(countLo, size_t(BlockSize));
uint8_t * d = reinterpret_cast<uint8_t *>(data);
d[num++] = padFirst;
if(num <= lastBlockSize) {
memset(d + num, 0, lastBlockSize-num);
memset(d + num, 0, lastBlockSize - num);
} else {
memset(d+num, 0, BlockSize-num);
memset(d + num, 0, BlockSize - num);
hash(data, BlockSize);
memset(d, 0, lastBlockSize);
}
@ -206,7 +207,7 @@ template <class T> inline T rotlFixed(T x, unsigned int y) {
return T((x << y) | (x >> (sizeof(T) * 8 - y)));
}
#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)
#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)
template<> inline uint8_t rotlFixed<uint8_t>(uint8_t x, unsigned int y) {
return y ? _rotl8(x, y) : x;
@ -225,8 +226,9 @@ template<> inline uint32_t rotlFixed<uint32_t>(uint32_t x, unsigned int y) {
}
#endif
#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
// Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions
#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
// Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when
// using these instructions
template<> inline uint64_t rotlFixed<uint64_t>(uint64_t x, unsigned int y) {
return y ? _rotl64(x, y) : x;
}
@ -234,15 +236,15 @@ template<> inline uint64_t rotlFixed<uint64_t>(uint64_t x, unsigned int y) {
template <class T>
void IteratedHash<T>::finalize(char * digest) {
int order = ByteOrder::offset;
size_t order = ByteOrder::offset;
pad(BlockSize - 2 * sizeof(HashWord));
data[BlockSize / sizeof(HashWord) - 2 + order] = ByteOrder::byteSwapIfAlien(getBitCountLo());
data[BlockSize / sizeof(HashWord) - 1 - order] = ByteOrder::byteSwapIfAlien(getBitCountHi());
hash(data, BlockSize);
if(isAligned<HashWord>(digest) && HashSize % sizeof(HashWord) == 0) {
ByteOrder::byteSwapIfAlien(state, reinterpret_cast<HashWord *>(digest), HashSize);
} else {

146
src/crypto/SHA-1.cpp

@ -15,19 +15,25 @@ void Sha1Transform::init(HashWord * state) {
void Sha1Transform::transform(HashWord * state, const HashWord * data) {
#define blk0(i) (W[i] = data[i])
#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
#define blk1(i) (W[i & 15] = rotlFixed(W[(i + 13) & 15] ^ W[(i + 8) & 15] \
^ W[(i + 2) & 15] ^ W[i & 15], 1))
#define f1(x,y,z) (z^(x&(y^z)))
#define f2(x,y,z) (x^y^z)
#define f3(x,y,z) ((x&y)|(z&(x|y)))
#define f4(x,y,z) (x^y^z)
#define f1(x, y, z) (z ^ (x & (y ^ z)))
#define f2(x, y, z) (x ^ y ^ z)
#define f3(x, y, z) ((x & y) | (z & (x | y)))
#define f4(x, y, z) (x ^ y ^ z)
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
#define R0(v, w, x, y, z, i) z += f1(w, x, y) + blk0(i) + 0x5A827999 + rotlFixed(v, 5); \
w = rotlFixed(w, 30);
#define R1(v, w, x, y, z, i) z += f1(w, x, y) + blk1(i) + 0x5A827999 + rotlFixed(v, 5); \
w = rotlFixed(w, 30);
#define R2(v, w, x, y, z, i) z += f2(w, x, y) + blk1(i) + 0x6ED9EBA1 + rotlFixed(v, 5); \
w = rotlFixed(w, 30);
#define R3(v, w, x, y, z, i) z += f3(w, x, y) + blk1(i) + 0x8F1BBCDC + rotlFixed(v, 5); \
w = rotlFixed(w, 30);
#define R4(v, w, x, y, z, i) z += f4(w, x, y) + blk1(i) + 0xCA62C1D6 + rotlFixed(v, 5); \
w = rotlFixed(w, 30);
HashWord W[16];
@ -39,26 +45,106 @@ void Sha1Transform::transform(HashWord * state, const HashWord * data) {
HashWord e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
R0(a, b, c, d, e, 0);
R0(e, a, b, c, d, 1);
R0(d, e, a, b, c, 2);
R0(c, d, e, a, b, 3);
R0(b, c, d, e, a, 4);
R0(a, b, c, d, e, 5);
R0(e, a, b, c, d, 6);
R0(d, e, a, b, c, 7);
R0(c, d, e, a, b, 8);
R0(b, c, d, e, a, 9);
R0(a, b, c, d, e, 10);
R0(e, a, b, c, d, 11);
R0(d, e, a, b, c, 12);
R0(c, d, e, a, b, 13);
R0(b, c, d, e, a, 14);
R0(a, b, c, d, e, 15);
R1(e, a, b, c, d, 16);
R1(d, e, a, b, c, 17);
R1(c, d, e, a, b, 18);
R1(b, c, d, e, a, 19);
R2(a, b, c, d, e, 20);
R2(e, a, b, c, d, 21);
R2(d, e, a, b, c, 22);
R2(c, d, e, a, b, 23);
R2(b, c, d, e, a, 24);
R2(a, b, c, d, e, 25);
R2(e, a, b, c, d, 26);
R2(d, e, a, b, c, 27);
R2(c, d, e, a, b, 28);
R2(b, c, d, e, a, 29);
R2(a, b, c, d, e, 30);
R2(e, a, b, c, d, 31);
R2(d, e, a, b, c, 32);
R2(c, d, e, a, b, 33);
R2(b, c, d, e, a, 34);
R2(a, b, c, d, e, 35);
R2(e, a, b, c, d, 36);
R2(d, e, a, b, c, 37);
R2(c, d, e, a, b, 38);
R2(b, c, d, e, a, 39);
R3(a, b, c, d, e, 40);
R3(e, a, b, c, d, 41);
R3(d, e, a, b, c, 42);
R3(c, d, e, a, b, 43);
R3(b, c, d, e, a, 44);
R3(a, b, c, d, e, 45);
R3(e, a, b, c, d, 46);
R3(d, e, a, b, c, 47);
R3(c, d, e, a, b, 48);
R3(b, c, d, e, a, 49);
R3(a, b, c, d, e, 50);
R3(e, a, b, c, d, 51);
R3(d, e, a, b, c, 52);
R3(c, d, e, a, b, 53);
R3(b, c, d, e, a, 54);
R3(a, b, c, d, e, 55);
R3(e, a, b, c, d, 56);
R3(d, e, a, b, c, 57);
R3(c, d, e, a, b, 58);
R3(b, c, d, e, a, 59);
R4(a, b, c, d, e, 60);
R4(e, a, b, c, d, 61);
R4(d, e, a, b, c, 62);
R4(c, d, e, a, b, 63);
R4(b, c, d, e, a, 64);
R4(a, b, c, d, e, 65);
R4(e, a, b, c, d, 66);
R4(d, e, a, b, c, 67);
R4(c, d, e, a, b, 68);
R4(b, c, d, e, a, 69);
R4(a, b, c, d, e, 70);
R4(e, a, b, c, d, 71);
R4(d, e, a, b, c, 72);
R4(c, d, e, a, b, 73);
R4(b, c, d, e, a, 74);
R4(a, b, c, d, e, 75);
R4(e, a, b, c, d, 76);
R4(d, e, a, b, c, 77);
R4(c, d, e, a, b, 78);
R4(b, c, d, e, a, 79);
/* Add the working vars back into context.state[] */
state[0] += a;

2
src/crypto/SHA-1.hpp

@ -19,6 +19,6 @@ public:
static void transform(HashWord * digest, const HashWord * data);
};
typedef IteratedHash<Sha1Transform> Sha1;
typedef IteratedHash<Sha1Transform> Sha1;
#endif // INNOEXTRACT_CRYPTO_SHA1_HPP

31
src/loader/ExeReader.cpp

@ -14,9 +14,9 @@ namespace {
static const char PE_MAGIC[] = { 'P', 'E', 0, 0 };
inline bool getResourceTable(size_t & entry, size_t resource_offset) {
inline bool getResourceTable(uint32_t & entry, uint32_t resource_offset) {
bool is_table = (entry & (1 << 31));
bool is_table = (entry & (uint32_t(1) << 31));
entry &= ~(1 << 31), entry += resource_offset;
@ -44,7 +44,7 @@ struct ExeReader::CoffSection {
};
size_t ExeReader::findResourceEntry(std::istream & is, int needle) {
uint32_t ExeReader::findResourceEntry(std::istream & is, uint32_t needle) {
// skip: characteristics + timestamp + major version + minor version
if(is.seekg(4 + 4 + 2 + 2, std::ios_base::cur).fail()) {
@ -59,7 +59,7 @@ size_t ExeReader::findResourceEntry(std::istream & is, int needle) {
// Ignore named resource entries.
const size_t entry_size = 4 + 4; // id / string address + offset
const uint32_t entry_size = 4 + 4; // id / string address + offset
if(is.seekg(nbnames * entry_size, std::ios_base::cur).fail()) {
return 0;
}
@ -80,13 +80,13 @@ size_t ExeReader::findResourceEntry(std::istream & is, int needle) {
return 0;
}
bool ExeReader::loadSectionTable(std::istream & is, size_t peOffset,
bool ExeReader::loadSectionTable(std::istream & is, uint32_t peOffset,
const CoffFileHeader & coff, CoffSectionTable & table) {
// machine + nsections + creation time + symbol table offset + nsymbols
// + optional header size + characteristics
const size_t file_header_size = 2 + 2 + 4 + 4 + 4 + 2 + 2;
size_t section_table_offset = peOffset + sizeof(PE_MAGIC) + file_header_size
const uint32_t file_header_size = 2 + 2 + 4 + 4 + 4 + 2 + 2;
uint32_t section_table_offset = peOffset + uint32_t(sizeof(PE_MAGIC)) + file_header_size
+ coff.optional_header_size;
is.seekg(section_table_offset);
@ -110,7 +110,7 @@ bool ExeReader::loadSectionTable(std::istream & is, size_t peOffset,
return !is.fail();
}
size_t ExeReader::memoryAddressToFileOffset(const CoffSectionTable & sections, size_t memory) {
uint32_t ExeReader::memoryAddressToFileOffset(const CoffSectionTable & sections, uint32_t memory) {
for(CoffSectionTable::const_iterator i = sections.begin(); i != sections.end(); ++i) {
const CoffSection & section = *i;
@ -125,7 +125,8 @@ size_t ExeReader::memoryAddressToFileOffset(const CoffSectionTable & sections, s
return 0;
}
ExeReader::Resource ExeReader::findResource(std::istream & is, int name, int type, int language) {
ExeReader::Resource ExeReader::findResource(std::istream & is, uint32_t name,
uint32_t type, uint32_t language) {
Resource result;
result.offset = result.size = 0;
@ -166,7 +167,7 @@ ExeReader::Resource ExeReader::findResource(std::istream & is, int name, int typ
if(is.fail() || ndirectories < 3) {
return result;
}
const size_t directory_header_size = 4 + 4; // address + size
const uint32_t directory_header_size = 4 + 4; // address + size
is.seekg(2 * directory_header_size, std::ios_base::cur);
// Virtual memory address and size of the start of resource directory.
@ -181,25 +182,25 @@ ExeReader::Resource ExeReader::findResource(std::istream & is, int name, int typ
return result;
}
size_t resource_offset = memoryAddressToFileOffset(sections, resource_address);
uint32_t resource_offset = memoryAddressToFileOffset(sections, resource_address);
if(!resource_offset) {
return result;
}
is.seekg(resource_offset);
size_t type_offset = findResourceEntry(is, type);
uint32_t type_offset = findResourceEntry(is, type);
if(!getResourceTable(type_offset, resource_offset)) {
return result;
}
is.seekg(type_offset);
size_t name_offset = findResourceEntry(is, name);
uint32_t name_offset = findResourceEntry(is, name);
if(!getResourceTable(name_offset, resource_offset)) {
return result;
}
is.seekg(name_offset);
size_t leaf_offset = findResourceEntry(is, language);
uint32_t leaf_offset = findResourceEntry(is, language);
if(!leaf_offset || getResourceTable(leaf_offset, resource_offset)) {
return result;
}
@ -213,7 +214,7 @@ ExeReader::Resource ExeReader::findResource(std::istream & is, int name, int typ
return result;
}
size_t data_offset = memoryAddressToFileOffset(sections, data_address);
uint32_t data_offset = memoryAddressToFileOffset(sections, data_address);
if(!data_offset) {
return result;
}

16
src/loader/ExeReader.hpp

@ -2,7 +2,7 @@
#ifndef INNOEXTRACT_LOADER_EXEREADER_HPP
#define INNOEXTRACT_LOADER_EXEREADER_HPP
#include <stddef.h>
#include <stdint.h>
#include <istream>
#include <vector>
@ -16,9 +16,9 @@ public:
struct Resource {
size_t offset;
uint32_t offset;
size_t size;
uint32_t size;
};
@ -31,7 +31,8 @@ public:
* Find where a resource with a given ID is stored in a MS PE/COFF executable.
* @return The location of the resource or (0, 0) if the requested resource does not exist.
*/
static Resource findResource(std::istream & is, int name, int type = TypeData, int language = LanguageDefault);
static Resource findResource(std::istream & is, uint32_t name, uint32_t type = TypeData,
uint32_t language = LanguageDefault);
private:
@ -51,11 +52,12 @@ private:
* Remaining 31 bits: Offset to the CoffResourceTable CoffResourceLeaf relative to
* the directory start.
*/
static size_t findResourceEntry(std::istream & ifs, int id);
static uint32_t findResourceEntry(std::istream & ifs, uint32_t id);
static bool loadSectionTable(std::istream & ifs, size_t peOffset, const CoffFileHeader & coff, CoffSectionTable & table);
static bool loadSectionTable(std::istream & ifs, uint32_t peOffset,
const CoffFileHeader & coff, CoffSectionTable & table);
static size_t memoryAddressToFileOffset(const CoffSectionTable & sections, size_t memory);
static uint32_t memoryAddressToFileOffset(const CoffSectionTable & sections, uint32_t memory);
};

8
src/loader/SetupLoader.cpp

@ -16,7 +16,7 @@ namespace {
struct SetupLoaderVersion {
char magic[12];
unsigned char magic[12];
// Earliest known version with that ID.
InnoVersionConstant version;
@ -70,7 +70,7 @@ bool SetupLoader::loadFromExeResource(std::istream & is) {
return loadOffsetsAt(is, resource.offset);
}
bool SetupLoader::loadOffsetsAt(std::istream & is, size_t pos) {
bool SetupLoader::loadOffsetsAt(std::istream & is, uint32_t pos) {
if(is.seekg(pos).fail()) {
is.clear();
@ -107,7 +107,7 @@ bool SetupLoader::loadOffsetsAt(std::istream & is, size_t pos) {
}
}
totalSize = checksum.load<LittleEndian, uint32_t>(is);
(void)checksum.load<LittleEndian, uint32_t>(is);
exeOffset = checksum.load<LittleEndian, uint32_t>(is);
if(version >= INNO_VERSION(4, 1, 6)) {
@ -178,8 +178,6 @@ void SetupLoader::load(std::istream & is) {
* In that case, the setup headers start at the beginning of the file.
*/
totalSize = is.seekg(0, std::ios_base::end).tellg();
exeCompressedSize = exeUncompressedSize = exeOffset = 0; // No embedded setup exe.
messageOffset = 0; // No embedded messages.

16
src/loader/SetupLoader.hpp

@ -9,28 +9,26 @@
struct SetupLoader {
size_t totalSize; //!< Minimum expected size of the setup file
size_t exeOffset; //!< Offset of compressed setup.e32. 0 means there is no exe in this file.
size_t exeCompressedSize; //!< Size of setup.e32 after compression (0 = unknown)
size_t exeUncompressedSize; //!< Size of setup.e32 before compression
uint32_t exeOffset; //!< Offset of compressed setup.e32. 0 means there is no exe in this file.
uint32_t exeCompressedSize; //!< Size of setup.e32 after compression (0 = unknown)
uint32_t exeUncompressedSize; //!< Size of setup.e32 before compression
Checksum exeChecksum; //!< Checksum of setup.e32 before compression
size_t messageOffset;
uint32_t messageOffset;
/*!
* Offset of embedded setup-0.bin data (the setup headers)
* This points to a version string (see setup/Version.hpp) followed by a
* compressed block of headers (see stream/BlockReader.hpp and setup/SetupHeader.hpp)
*/
size_t headerOffset;
uint32_t headerOffset;
/*!
* Offset of embedded setup-1.bin data.
* If this is zero, the setup data is stored in seprarate files.
*/
size_t dataOffset;
uint32_t dataOffset;
/*!
* Try to find the setup loader offsets in the given file.
@ -43,7 +41,7 @@ private:
bool loadFromExeResource(std::istream & is);
bool loadOffsetsAt(std::istream & is, size_t pos);
bool loadOffsetsAt(std::istream & is, uint32_t pos);
};

240
src/misc/BitfieldConverter.hpp

@ -1,240 +0,0 @@
#include <boost/utility/enable_if.hpp>
#include <boost/integer.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/integer/static_min_max.hpp>
#include <boost/integer_traits.hpp>
namespace boost {
template <class T>
class integer_traits<const T> : public integer_traits<T> { };
}
template <size_t N, class Type = void, class Enable = void>
struct is_power_of_two {
static const bool value = false;
};
template <size_t N, class Type>
struct is_power_of_two<N, Type, typename boost::enable_if_c<(N & (N - 1)) == 0>::type> {
static const bool value = true;
typedef Type type;
};
template <size_t N, class Enable = void>
struct log_next_power_of_two {
static const size_t value = boost::static_log2<N>::value + 1;
};
template <size_t N>
struct log_next_power_of_two<N, typename boost::enable_if<is_power_of_two<N> >::type> {
static const size_t value = boost::static_log2<N>::value;
};
template <size_t N, class Enable = void>
struct next_power_of_two {
static const size_t value = size_t(1) << (boost::static_log2<N>::value + 1);
};
template <size_t N>
struct next_power_of_two<N, typename boost::enable_if<is_power_of_two<N> >::type> {
static const size_t value = N;
};
struct fast_integers {
private:
template <size_t Bits, class Dummy = void> struct _impl { };
template <class Dummy> struct _impl<8, Dummy> { typedef uint_fast8_t type; };
template <class Dummy> struct _impl<16, Dummy> { typedef uint_fast16_t type; };
template <class Dummy> struct _impl<32, Dummy> { typedef uint_fast32_t type; };
template <class Dummy> struct _impl<64, Dummy> { typedef uint_fast64_t type; };
template <class Dummy> struct _impl<128, Dummy> { typedef __uint128_t type; };
public:
template <size_t Bits>
struct bits : public _impl<boost::static_unsigned_max<8, next_power_of_two<Bits>::value>::value> { };
};
struct exact_integers {
private:
template <size_t Bits, class Dummy = void> struct _impl { };
template <class Dummy> struct _impl<8, Dummy> { typedef uint8_t type; };
template <class Dummy> struct _impl<16, Dummy> { typedef uint16_t type; };
template <class Dummy> struct _impl<32, Dummy> { typedef uint32_t type; };
template <class Dummy> struct _impl<64, Dummy> { typedef uint64_t type; };
template <class Dummy> struct _impl<128, Dummy> { typedef __uint128_t type; };
public:
template <size_t Bits>
struct bits : public _impl<boost::static_unsigned_max<8, next_power_of_two<Bits>::value>::value> { };
};
struct bitset_types {
template <size_t Bits>
struct bits {
typedef std::bitset<Bits> type;
};
};
/*!
* Converter that rearranges bits in an integer.
*
* Conversion is reduced to a minimal number of mask & shift operations at compile-time.
*
* Usage:
*
* bitset_converter&lt;&gt; is an empty converter list (cannot be used without adding at least one mappings).
* (list)::add::map&lt;from, to&gt maps the from'th input bit to the to'th output bit.
*
* Convenience function to add a continous region of mappings:
* bitset_converter&lt;&gt;::add::value&lt;to2&gt; is equivalent to bitset_converter&lt;&gt;::add::map&lt;0, to2&gt;
* (list)::add::map&lt;from, to&gt::add::value&lt;to2&gt; is equivalent to ::add::map&lt;from, to&gt::add::map&lt;from + 1, to2&gt;
*
* Inut bits without a corresponding "from" entry are ignored.
* Output bit without a corresponding "to" entry are always zero.
*
* The same input/output bit can appear in multiple mappings.
*
* Invoke the converter: (list)::convert(integer)
*
* Limitations:
*
* Input bits must fit in a native integer type provided by in_types::bits&lt;bits&gt;.
*
* Output bits must fit in an integer type selected by out_types::bits&lt;bits&gt;.
*
* Example:
*
* // Create a converter that swaps the first two bits, keeps the next one and ignores all others.
* typedef bitset_converter<>::add::map<0, 1>::add::map<1, 0>::add::value<2> Converter;
*
* // Convert something.
* Converter::convert(3);
*
*/
template <class out_types = fast_integers, class in_types = fast_integers>
struct bitset_converter {
private:
typedef ptrdiff_t shift_type;
typedef size_t index_type;
template <class Combiner, class Entry>
struct IterateEntries {
static const typename Combiner::type value = Combiner::template combine<Entry, (IterateEntries<Combiner, typename Entry::next>::value)>::value;
};
template <class Combiner> struct IterateEntries<Combiner, void> { static const typename Combiner::type value = Combiner::base; };
template <class Type, Type Base> struct Combiner { typedef Type type; static const Type base = Base; };
template<class Getter, class Type>
struct MaxCombiner : public Combiner<Type, boost::integer_traits<Type>::const_min> {
template <class Entry, Type accumulator>
struct combine { static const Type value = boost::static_signed_max<Getter::template get<Entry>::value, accumulator>::value; };
};
template<class Getter, class Type>
struct MinCombiner : public Combiner<Type, boost::integer_traits<Type>::const_max> {
template <class Entry, Type accumulator>
struct combine { static const Type value = boost::static_signed_min<Getter::template get<Entry>::value, accumulator>::value; };
};
struct ShiftGetter { template<class Entry> struct get { static const shift_type value = Entry::shift; }; };
struct FromGetter { template<class Entry> struct get { static const index_type value = Entry::from; }; };
struct ToGetter { template<class Entry> struct get { static const index_type value = Entry::to; }; };
template<shift_type Shift, class Type>
struct ShiftMaskCombiner : public Combiner<Type, Type(0)> {
template <class Entry, Type mask>
struct combine { static const Type value = mask | ( (Entry::shift == Shift) ? (Type(1) << Entry::from) : Type(0) ); };
};
template<class List>
struct Builder;
template<index_type From, index_type To, class Next = void>
struct Entry {
typedef Entry<From, To, Next> This;
static const index_type from = From;
static const index_type to = To;
typedef Next next;
static const shift_type shift = shift_type(from) - shift_type(to);
static const shift_type max_shift = IterateEntries<MaxCombiner<ShiftGetter, shift_type>, This>::value;
static const shift_type min_shift = IterateEntries<MinCombiner<ShiftGetter, shift_type>, This>::value;
static const index_type in_bits = IterateEntries<MaxCombiner<FromGetter, index_type>, This>::value + 1;
typedef typename in_types::template bits<in_bits>::type in_type;
static const index_type out_bits = IterateEntries<MaxCombiner<ToGetter, index_type>, This>::value + 1;
typedef typename out_types::template bits<out_bits>::type out_type;
template<shift_type Shift>
struct ShiftMask { static const in_type value = IterateEntries<ShiftMaskCombiner<Shift, in_type>, This>::value; };
template <shift_type Shift>
inline static typename boost::enable_if_c<(Shift >= shift_type(0)), out_type>::type evaluate(in_type value) {
return out_type((value & ShiftMask<Shift>::value) >> Shift);
}
template <shift_type Shift>
inline static typename boost::enable_if_c<(Shift < shift_type(0)), out_type>::type evaluate(in_type value) {
return out_type(value & ShiftMask<Shift>::value) << (-Shift);
}
template<shift_type Shift, class Enable = void>
struct NextShift { static const shift_type value = Shift + 1; };
template<shift_type Shift>
struct NextShift<Shift, typename boost::enable_if_c<Shift != max_shift && ShiftMask<Shift + 1>::value == in_type(0)>::type > {
static const shift_type value = NextShift<Shift + 1>::value;
};
template <shift_type Shift>
inline static typename boost::enable_if_c<(NextShift<Shift>::value != max_shift + 1), out_type>::type map(in_type value) {
return evaluate<Shift>(value) | (map<NextShift<Shift>::value>(value));
}
template <shift_type Shift>
inline static typename boost::enable_if_c<(NextShift<Shift>::value == max_shift + 1), out_type>::type map(in_type value) {
return evaluate<Shift>(value);
}
public:
typedef Builder<This> add;
static out_type convert(in_type value) {
return map<min_shift>(value);
}
};
template<class List>
struct Builder {
template<index_type From, index_type To>
struct map : public Entry<From, To, List> { };
template<index_type To, class Current = List>
struct value : public Entry<Current::from + 1, To, Current> { };
template<index_type To>
struct value<To, void> : public Entry<0, To> { };
};
public:
typedef Builder<void> add;
};

189
src/misc/test.cpp

@ -1,189 +0,0 @@
#include "src/SetupHeaderFormat.hpp"
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
using std::setfill;
using std::setw;
using std::hex;
using std::dec;
/*
template <size_t N>
void testlog() {
cout << " lnpot: " << setfill(' ') << setw(3) << log_next_power_of_two<N>::value;
}
template <>
void testlog<0>() {
cout << " lnpot: " << setfill(' ') << setw(3) << 0;
}
template <size_t N>
void test() {
cout << setfill(' ') << setw(5) << N;
cout << ' ' << hex << setfill('0') << setw(4) << N << dec;
cout << ": pot=" << is_power_of_two<N>::value;
cout << " npot: " << setfill(' ') << setw(5) << next_power_of_two<N>::value;
testlog<N>();
cout << " ebits: " << setfill(' ') << setw(3) << StoredEnumType<N>::bits;
cout << " rebits: " << setfill(' ') << setw(3) << (sizeof(typename StoredEnumType<N>::type) * 8);
cout << " fbits: " << setfill(' ') << setw(5) << StoredFlagType<N>::bits;
cout << " rfbits: " << setfill(' ') << setw(5) << (sizeof(typename StoredFlagType<N>::type) * 8);
cout << endl;
}
#define TEST0(D) test<0##D>();
#define TEST1(D) \
TEST0(D##0) \
TEST0(D##1) \
TEST0(D##2) \
TEST0(D##3) \
TEST0(D##4) \
TEST0(D##5) \
TEST0(D##6) \
TEST0(D##7) \
#define TEST2(D) \
TEST1(D##0) \
TEST1(D##1) \
TEST1(D##2) \
TEST1(D##3) \
TEST1(D##4) \
TEST1(D##5) \
TEST1(D##6) \
TEST1(D##7) \
#define TEST3(D) \
TEST2(D##0) \
TEST2(D##1) \
TEST2(D##2) \
TEST2(D##3) \
TEST2(D##4) \
TEST2(D##5) \
TEST2(D##6) \
TEST2(D##7) \
enum TestEnum {
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
TestEnum__End
};
ENUM_SIZE_AUTO(TestEnum);
STORED_ENUM_MAP(TestEnumMap, A,
A, // 0
B, // 1
C, // 2
D, // 2
E, // 2
F, // 2
G, // 2
H, // 2
I, // 2
J, // 2
K, // 2
L, // 2
M, // 2
N, // 2
O, // 2
P, // 2
Q, // 2
R, // 2
S, // 2
T, // 2
U, // 2
V, // 2
W, // 2
X, // 2
Y, // 2
Z, // 2
);
*/
volatile size_t i;
typedef BitsetConverter
::add::map<0, 0>
::add::map<1, 1>
::add::map<2, 2>
::add::map<3, 3>
::add::map<4, 4>
::add::map<5, 5>
::add::map<6, 6>
::add::map<7, 7>
::add::map<8, 8>
::add::map<9, 9>
::add::map<10, 10>
::add::map<11, 11>
::add::map<12, 12>
::add::map<13, 13>
::add::map<14, 14>
::add::map<15, 15>
::add::map<16, 16>
::add::map<17, 17>
::add::map<18, 18>
::add::map<19, 19>
::add::map<20, 20>
IdentityConverter;
static void test2(size_t i) {
size_t out = IdentityConverter::convert(i);
cout << i << " = " << std::bitset<64>(i) << " -> " << out << " = " << std::bitset<64>(out) << endl;
}
int main() {
//TEST3()
/*
test2(0);
test2(1);
test2(2);
test2(3);
test2(4);
test2(5);
test2(6);
test2(7);
test2(8);*/
return IdentityConverter::convert(i);
}

5
src/setup/FileEntry.cpp

@ -64,9 +64,10 @@ void FileEntry::load(std::istream & is, const InnoVersion & version) {
loadVersionData(is, version);
location = loadNumber<int32_t>(is, version.bits);
location = loadNumber<uint32_t>(is, version.bits);
attributes = loadNumber<uint32_t>(is, version.bits);
externalSize = (version >= INNO_VERSION(4, 0, 0)) ? loadNumber<uint64_t>(is) : loadNumber<uint32_t>(is);
externalSize = (version >= INNO_VERSION(4, 0, 0)) ? loadNumber<uint64_t>(is)
: loadNumber<uint32_t>(is);
if(version < INNO_VERSION(3, 0, 5)) {
FileCopyMode copyMode = StoredEnum<StoredFileCopyMode>(is).get();

2
src/setup/FileEntry.hpp

@ -63,7 +63,7 @@ struct FileEntry : public SetupItem {
std::string installFontName;
std::string strongAssemblyName;
int location; //!< index into the file location entry list
uint32_t location; //!< index into the file location entry list
uint32_t attributes;
uint64_t externalSize;

4
src/setup/FileLocationEntry.cpp

@ -44,7 +44,7 @@ void FileLocationEntry::load(std::istream & is, const InnoVersion & version) {
if(version.bits == 16) {
uint32_t date = loadNumber<uint32_t>(is); // milliseconds?
int32_t date = loadNumber<int32_t>(is); // milliseconds?
// TODO this seems to be off by a few years:
// expected ~ 2000-04-18, got 1991-07-28
@ -63,7 +63,7 @@ void FileLocationEntry::load(std::istream & is, const InnoVersion & version) {
filetime -= FILETIME_OFFSET;
timestamp.tv_sec = std::time_t(filetime / 10000000);
timestamp.tv_nsec = long(filetime % 10000000) * 100;
timestamp.tv_nsec = int32_t(filetime % 10000000) * 100;
}
fileVersionMS = loadNumber<uint32_t>(is);

2
src/setup/FileLocationEntry.hpp

@ -33,7 +33,7 @@ struct FileLocationEntry : public SetupItem {
size_t firstSlice;
size_t lastSlice;
size_t chunkOffset; //!< offset of the compressed chunk in firstSlice
uint32_t chunkOffset; //!< offset of the compressed chunk in firstSlice
uint64_t chunkSize; //! total compressed size of the chunk
uint64_t fileOffset; //!< offset of this file within the decompressed chunk

24
src/setup/SetupComponentEntry.cpp

@ -7,26 +7,26 @@
namespace {
STORED_FLAGS_MAP(StoredSetupComponentOptions0,
SetupComponentEntry::Fixed,
SetupComponentEntry::Restart,
SetupComponentEntry::DisableNoUninstallWarning,
SetupComponentEntry::Fixed,
SetupComponentEntry::Restart,
SetupComponentEntry::DisableNoUninstallWarning,
);
// starting with version 3.0.8
STORED_FLAGS_MAP(StoredSetupComponentOptions1,
SetupComponentEntry::Fixed,
SetupComponentEntry::Restart,
SetupComponentEntry::DisableNoUninstallWarning,
SetupComponentEntry::Exclusive,
SetupComponentEntry::Fixed,
SetupComponentEntry::Restart,
SetupComponentEntry::DisableNoUninstallWarning,
SetupComponentEntry::Exclusive,
);
// starting with version 4.2.3
STORED_FLAGS_MAP(StoredSetupComponentOptions2,
SetupComponentEntry::Fixed,
SetupComponentEntry::Restart,
SetupComponentEntry::DisableNoUninstallWarning,
SetupComponentEntry::Exclusive,
SetupComponentEntry::DontInheritCheck,
SetupComponentEntry::Fixed,
SetupComponentEntry::Restart,
SetupComponentEntry::DisableNoUninstallWarning,
SetupComponentEntry::Exclusive,
SetupComponentEntry::DontInheritCheck,
);
} // anonymous namespace

33
src/setup/SetupHeader.cpp

@ -157,13 +157,13 @@ void SetupHeader::load(std::istream & is, const InnoVersion & version) {
numRunEntries = loadNumber<uint32_t>(is, version.bits);
numUninstallRunEntries = loadNumber<uint32_t>(is, version.bits);
size_t licenseSize;
size_t infoBeforeSize;
size_t infoAfterSize;
int32_t licenseSize;
int32_t infoBeforeSize;
int32_t infoAfterSize;
if(version < INNO_VERSION(1, 3, 21)) {
licenseSize = loadNumber<uint32_t>(is, version.bits);
infoBeforeSize = loadNumber<uint32_t>(is, version.bits);
infoAfterSize = loadNumber<uint32_t>(is, version.bits);
licenseSize = loadNumber<int32_t>(is, version.bits);
infoBeforeSize = loadNumber<int32_t>(is, version.bits);
infoAfterSize = loadNumber<int32_t>(is, version.bits);
}
minVersion.load(is, version);
@ -183,7 +183,7 @@ void SetupHeader::load(std::istream & is, const InnoVersion & version) {
}
if(version < INNO_VERSION(4, 2, 0)) {
password.crc32 = loadNumber<int32_t>(is), password.type = Checksum::Crc32;
password.crc32 = loadNumber<uint32_t>(is), password.type = Checksum::Crc32;
} else if(version < INNO_VERSION(5, 3, 9)) {
is.read(password.md5, sizeof(password.md5)), password.type = Checksum::MD5;
} else {
@ -200,7 +200,7 @@ void SetupHeader::load(std::istream & is, const InnoVersion & version) {
slicesPerDisk = 1;
} else {
extraDiskSpaceRequired = loadNumber<int64_t>(is);
slicesPerDisk = loadNumber<int32_t>(is);
slicesPerDisk = loadNumber<uint32_t>(is);
}
if(version >= INNO_VERSION(2, 0, 0) && version < INNO_VERSION(5, 0, 0)) {
@ -266,7 +266,7 @@ void SetupHeader::load(std::istream & is, const InnoVersion & version) {
}
if(version >= INNO_VERSION(5, 2, 1) && version < INNO_VERSION(5, 3, 10)) {
signedUninstallerOrigSize = loadNumber<int32_t>(is);
signedUninstallerOrigSize = loadNumber<uint32_t>(is);
signedUninstallerHdrChecksum = loadNumber<uint32_t>(is);
} else {
signedUninstallerOrigSize = signedUninstallerHdrChecksum = 0;
@ -455,21 +455,21 @@ void SetupHeader::load(std::istream & is, const InnoVersion & version) {
}
if(version < INNO_VERSION(1, 3, 21)) {
if(licenseSize) {
if(licenseSize > 0) {
std::string temp;
temp.resize(licenseSize);
temp.resize(size_t(licenseSize));
is.read(&temp[0], licenseSize);
toUtf8(temp, licenseText);
}
if(infoBeforeSize) {
if(infoBeforeSize > 0) {
std::string temp;
temp.resize(infoBeforeSize);
temp.resize(size_t(infoBeforeSize));
is.read(&temp[0], infoBeforeSize);
toUtf8(temp, infoBeforeText);
}
if(infoAfterSize) {
if(infoAfterSize > 0) {
std::string temp;
temp.resize(infoAfterSize);
temp.resize(size_t(infoAfterSize));
is.read(&temp[0], infoAfterSize);
toUtf8(temp, infoAfterText);
}
@ -536,7 +536,8 @@ ENUM_NAMES(SetupHeader::Options, "Setup Option",
"back solid",
"overwrite uninst reg entries",
)
BOOST_STATIC_ASSERT(EnumSize<SetupHeader::Options::Enum>::value == EnumNames<SetupHeader::Options::Enum>::count);
BOOST_STATIC_ASSERT(EnumSize<SetupHeader::Options::Enum>::value
== EnumNames<SetupHeader::Options::Enum>::count);
ENUM_NAMES(SetupHeader::Architectures, "Architecture",
"unknown",

4
src/setup/SetupHeader.hpp

@ -152,7 +152,7 @@ struct SetupHeader {
Color wizardSmallImageBackColor;
Checksum password;
SetupSalt passwordSalt;
SetupSalt passwordSalt;
int64_t extraDiskSpaceRequired;
size_t slicesPerDisk;
@ -215,7 +215,7 @@ struct SetupHeader {
Architectures architecturesAllowed;
Architectures architecturesInstallIn64BitMode;
uint64_t signedUninstallerOrigSize;
uint32_t signedUninstallerOrigSize;
uint32_t signedUninstallerHdrChecksum;
AutoBoolean disableDirPage;

2
src/setup/SetupTypeEntry.cpp

@ -57,4 +57,4 @@ ENUM_NAMES(SetupTypeEntry::Type, "Setyp Type",
"default full",
"default compact",
"default custom",
)
)

139
src/setup/Version.cpp

@ -36,74 +36,74 @@ struct KnownSetupDataVersion {
};
const KnownSetupDataVersion knownSetupDataVersions[] = {
{ "Inno Setup Setup Data (1.3.21)", INNO_VERSION_EXT(1, 3, 21, 0) },
{ "Inno Setup Setup Data (1.3.25)", INNO_VERSION_EXT(1, 3, 25, 0) },
{ "Inno Setup Setup Data (2.0.0)", INNO_VERSION_EXT(2, 0, 0, 0) },
{ "Inno Setup Setup Data (2.0.1)", INNO_VERSION_EXT(2, 0, 1, 0) }, // or 2.0.2!
{ "Inno Setup Setup Data (2.0.5)", INNO_VERSION_EXT(2, 0, 5, 0) },
{ "Inno Setup Setup Data (2.0.6a)", INNO_VERSION_EXT(2, 0, 6, 0) },
{ "Inno Setup Setup Data (2.0.7)", INNO_VERSION_EXT(2, 0, 7, 0) },
{ "Inno Setup Setup Data (2.0.8)", INNO_VERSION_EXT(2, 0, 8, 0) },
{ "Inno Setup Setup Data (2.0.11)", INNO_VERSION_EXT(2, 0, 11, 0) },
{ "Inno Setup Setup Data (2.0.17)", INNO_VERSION_EXT(2, 0, 17, 0) },
{ "Inno Setup Setup Data (2.0.18)", INNO_VERSION_EXT(2, 0, 18, 0) },
{ "Inno Setup Setup Data (3.0.0a)", INNO_VERSION_EXT(3, 0, 0, 0) },
{ "Inno Setup Setup Data (3.0.1)", INNO_VERSION_EXT(3, 0, 1, 0) },
{ "Inno Setup Setup Data (3.0.3)", INNO_VERSION_EXT(3, 0, 3, 0) }, // or 3.0.4!
{ "Inno Setup Setup Data (3.0.5)", INNO_VERSION_EXT(3, 0, 5, 0) },
{ "My Inno Setup Extensions Setup Data (3.0.6.1)", INNO_VERSION_EXT(3, 0, 6, 1) },
{ "Inno Setup Setup Data (4.0.0a)", INNO_VERSION_EXT(4, 0, 0, 0) },
{ "Inno Setup Setup Data (4.0.1)", INNO_VERSION_EXT(4, 0, 1, 0) },
{ "Inno Setup Setup Data (4.0.3)", INNO_VERSION_EXT(4, 0, 3, 0) },
{ "Inno Setup Setup Data (4.0.5)", INNO_VERSION_EXT(4, 0, 5, 0) },
{ "Inno Setup Setup Data (4.0.9)", INNO_VERSION_EXT(4, 0, 9, 0) },
{ "Inno Setup Setup Data (4.0.10)", INNO_VERSION_EXT(4, 0, 10, 0) },
{ "Inno Setup Setup Data (4.0.11)", INNO_VERSION_EXT(4, 0, 11, 0) },
{ "Inno Setup Setup Data (4.1.0)", INNO_VERSION_EXT(4, 1, 0, 0) },
{ "Inno Setup Setup Data (4.1.2)", INNO_VERSION_EXT(4, 1, 2, 0) },
{ "Inno Setup Setup Data (4.1.3)", INNO_VERSION_EXT(4, 1, 3, 0) },
{ "Inno Setup Setup Data (4.1.4)", INNO_VERSION_EXT(4, 1, 4, 0) },
{ "Inno Setup Setup Data (4.1.5)", INNO_VERSION_EXT(4, 1, 5, 0) },
{ "Inno Setup Setup Data (4.1.6)", INNO_VERSION_EXT(4, 1, 6, 0) },
{ "Inno Setup Setup Data (4.1.8)", INNO_VERSION_EXT(4, 1, 8, 0) },
{ "Inno Setup Setup Data (4.2.0)", INNO_VERSION_EXT(4, 2, 0, 0) },
{ "Inno Setup Setup Data (4.2.1)", INNO_VERSION_EXT(4, 2, 1, 0) },
{ "Inno Setup Setup Data (4.2.2)", INNO_VERSION_EXT(4, 2, 2, 0) },
{ "Inno Setup Setup Data (4.2.3)", INNO_VERSION_EXT(4, 2, 3, 0) }, // or 4.2.4!
{ "Inno Setup Setup Data (4.2.5)", INNO_VERSION_EXT(4, 2, 5, 0) },
{ "Inno Setup Setup Data (4.2.6)", INNO_VERSION_EXT(4, 2, 6, 0) },
{ "Inno Setup Setup Data (5.0.0)", INNO_VERSION_EXT(5, 0, 0, 0) },
{ "Inno Setup Setup Data (5.0.1)", INNO_VERSION_EXT(5, 0, 1, 0) },
{ "Inno Setup Setup Data (5.0.3)", INNO_VERSION_EXT(5, 0, 3, 0) },
{ "Inno Setup Setup Data (5.0.4)", INNO_VERSION_EXT(5, 0, 4, 0) },
{ "Inno Setup Setup Data (5.1.0)", INNO_VERSION_EXT(5, 1, 0, 0) },
{ "Inno Setup Setup Data (5.1.2)", INNO_VERSION_EXT(5, 1, 2, 0) },
{ "Inno Setup Setup Data (5.1.7)", INNO_VERSION_EXT(5, 1, 7, 0) },
{ "Inno Setup Setup Data (5.1.10)", INNO_VERSION_EXT(5, 1, 10, 0) },
{ "Inno Setup Setup Data (5.1.13)", INNO_VERSION_EXT(5, 1, 13, 0) },
{ "Inno Setup Setup Data (5.2.0)", INNO_VERSION_EXT(5, 2, 0, 0) },
{ "Inno Setup Setup Data (5.2.1)", INNO_VERSION_EXT(5, 2, 1, 0) },
{ "Inno Setup Setup Data (5.2.3)", INNO_VERSION_EXT(5, 2, 3, 0) },
{ "Inno Setup Setup Data (5.2.5)", INNO_VERSION_EXT(5, 2, 5, 0) },
{ "Inno Setup Setup Data (5.2.5) (u)", INNO_VERSION_EXT(5, 2, 5, 0), true },
{ "Inno Setup Setup Data (5.3.0)", INNO_VERSION_EXT(5, 3, 0, 0) },
{ "Inno Setup Setup Data (5.3.0) (u)", INNO_VERSION_EXT(5, 3, 0, 0), true },
{ "Inno Setup Setup Data (5.3.3)", INNO_VERSION_EXT(5, 3, 3, 0) },
{ "Inno Setup Setup Data (5.3.3) (u)", INNO_VERSION_EXT(5, 3, 3, 0), true },
{ "Inno Setup Setup Data (5.3.5)", INNO_VERSION_EXT(5, 3, 5, 0) },
{ "Inno Setup Setup Data (5.3.5) (u)", INNO_VERSION_EXT(5, 3, 5, 0), true },
{ "Inno Setup Setup Data (5.3.6)", INNO_VERSION_EXT(5, 3, 6, 0) },
{ "Inno Setup Setup Data (5.3.6) (u)", INNO_VERSION_EXT(5, 3, 6, 0), true },
{ "Inno Setup Setup Data (5.3.7)", INNO_VERSION_EXT(5, 3, 7, 0) },
{ "Inno Setup Setup Data (5.3.7) (u)", INNO_VERSION_EXT(5, 3, 7, 0), true },
{ "Inno Setup Setup Data (5.3.8)", INNO_VERSION_EXT(5, 3, 8, 0) },
{ "Inno Setup Setup Data (5.3.8) (u)", INNO_VERSION_EXT(5, 3, 8, 0), true },
{ "Inno Setup Setup Data (5.3.9)", INNO_VERSION_EXT(5, 3, 9, 0) },
{ "Inno Setup Setup Data (5.3.9) (u)", INNO_VERSION_EXT(5, 3, 9, 0), true },
{ "Inno Setup Setup Data (5.3.10)", INNO_VERSION_EXT(5, 3, 10, 0) },
{ "Inno Setup Setup Data (5.3.10) (u)", INNO_VERSION_EXT(5, 3, 10, 0), true },
{ "Inno Setup Setup Data (5.4.2)", INNO_VERSION_EXT(5, 4, 2, 0) },
{ "Inno Setup Setup Data (5.4.2) (u)", INNO_VERSION_EXT(5, 4, 2, 0), true },
{ "Inno Setup Setup Data (1.3.21)", INNO_VERSION_EXT(1, 3, 21, 0), false },
{ "Inno Setup Setup Data (1.3.25)", INNO_VERSION_EXT(1, 3, 25, 0), false },
{ "Inno Setup Setup Data (2.0.0)", INNO_VERSION_EXT(2, 0, 0, 0), false },
{ "Inno Setup Setup Data (2.0.1)", INNO_VERSION_EXT(2, 0, 1, 0), false },
{ "Inno Setup Setup Data (2.0.5)", INNO_VERSION_EXT(2, 0, 5, 0), false },
{ "Inno Setup Setup Data (2.0.6a)", INNO_VERSION_EXT(2, 0, 6, 0), false },
{ "Inno Setup Setup Data (2.0.7)", INNO_VERSION_EXT(2, 0, 7, 0), false },
{ "Inno Setup Setup Data (2.0.8)", INNO_VERSION_EXT(2, 0, 8, 0), false },
{ "Inno Setup Setup Data (2.0.11)", INNO_VERSION_EXT(2, 0, 11, 0), false },
{ "Inno Setup Setup Data (2.0.17)", INNO_VERSION_EXT(2, 0, 17, 0), false },
{ "Inno Setup Setup Data (2.0.18)", INNO_VERSION_EXT(2, 0, 18, 0), false },
{ "Inno Setup Setup Data (3.0.0a)", INNO_VERSION_EXT(3, 0, 0, 0), false },
{ "Inno Setup Setup Data (3.0.1)", INNO_VERSION_EXT(3, 0, 1, 0), false },
{ "Inno Setup Setup Data (3.0.3)", INNO_VERSION_EXT(3, 0, 3, 0), false },
{ "Inno Setup Setup Data (3.0.5)", INNO_VERSION_EXT(3, 0, 5, 0), false },
{ "My Inno Setup Extensions Setup Data (3.0.6.1)", INNO_VERSION_EXT(3, 0, 6, 1), false },
{ "Inno Setup Setup Data (4.0.0a)", INNO_VERSION_EXT(4, 0, 0, 0), false },
{ "Inno Setup Setup Data (4.0.1)", INNO_VERSION_EXT(4, 0, 1, 0), false },
{ "Inno Setup Setup Data (4.0.3)", INNO_VERSION_EXT(4, 0, 3, 0), false },
{ "Inno Setup Setup Data (4.0.5)", INNO_VERSION_EXT(4, 0, 5, 0), false },
{ "Inno Setup Setup Data (4.0.9)", INNO_VERSION_EXT(4, 0, 9, 0), false },
{ "Inno Setup Setup Data (4.0.10)", INNO_VERSION_EXT(4, 0, 10, 0), false },
{ "Inno Setup Setup Data (4.0.11)", INNO_VERSION_EXT(4, 0, 11, 0), false },
{ "Inno Setup Setup Data (4.1.0)", INNO_VERSION_EXT(4, 1, 0, 0), false },
{ "Inno Setup Setup Data (4.1.2)", INNO_VERSION_EXT(4, 1, 2, 0), false },
{ "Inno Setup Setup Data (4.1.3)", INNO_VERSION_EXT(4, 1, 3, 0), false },
{ "Inno Setup Setup Data (4.1.4)", INNO_VERSION_EXT(4, 1, 4, 0), false },
{ "Inno Setup Setup Data (4.1.5)", INNO_VERSION_EXT(4, 1, 5, 0), false },
{ "Inno Setup Setup Data (4.1.6)", INNO_VERSION_EXT(4, 1, 6, 0), false },
{ "Inno Setup Setup Data (4.1.8)", INNO_VERSION_EXT(4, 1, 8, 0), false },
{ "Inno Setup Setup Data (4.2.0)", INNO_VERSION_EXT(4, 2, 0, 0), false },
{ "Inno Setup Setup Data (4.2.1)", INNO_VERSION_EXT(4, 2, 1, 0), false },
{ "Inno Setup Setup Data (4.2.2)", INNO_VERSION_EXT(4, 2, 2, 0), false },
{ "Inno Setup Setup Data (4.2.3)", INNO_VERSION_EXT(4, 2, 3, 0), false },
{ "Inno Setup Setup Data (4.2.5)", INNO_VERSION_EXT(4, 2, 5, 0), false },
{ "Inno Setup Setup Data (4.2.6)", INNO_VERSION_EXT(4, 2, 6, 0), false },
{ "Inno Setup Setup Data (5.0.0)", INNO_VERSION_EXT(5, 0, 0, 0), false },
{ "Inno Setup Setup Data (5.0.1)", INNO_VERSION_EXT(5, 0, 1, 0), false },
{ "Inno Setup Setup Data (5.0.3)", INNO_VERSION_EXT(5, 0, 3, 0), false },
{ "Inno Setup Setup Data (5.0.4)", INNO_VERSION_EXT(5, 0, 4, 0), false },
{ "Inno Setup Setup Data (5.1.0)", INNO_VERSION_EXT(5, 1, 0, 0), false },
{ "Inno Setup Setup Data (5.1.2)", INNO_VERSION_EXT(5, 1, 2, 0), false },
{ "Inno Setup Setup Data (5.1.7)", INNO_VERSION_EXT(5, 1, 7, 0), false },
{ "Inno Setup Setup Data (5.1.10)", INNO_VERSION_EXT(5, 1, 10, 0), false },
{ "Inno Setup Setup Data (5.1.13)", INNO_VERSION_EXT(5, 1, 13, 0), false },
{ "Inno Setup Setup Data (5.2.0)", INNO_VERSION_EXT(5, 2, 0, 0), false },
{ "Inno Setup Setup Data (5.2.1)", INNO_VERSION_EXT(5, 2, 1, 0), false },
{ "Inno Setup Setup Data (5.2.3)", INNO_VERSION_EXT(5, 2, 3, 0), false },
{ "Inno Setup Setup Data (5.2.5)", INNO_VERSION_EXT(5, 2, 5, 0), false },
{ "Inno Setup Setup Data (5.2.5) (u)", INNO_VERSION_EXT(5, 2, 5, 0), true },
{ "Inno Setup Setup Data (5.3.0)", INNO_VERSION_EXT(5, 3, 0, 0), false },
{ "Inno Setup Setup Data (5.3.0) (u)", INNO_VERSION_EXT(5, 3, 0, 0), true },
{ "Inno Setup Setup Data (5.3.3)", INNO_VERSION_EXT(5, 3, 3, 0), false },
{ "Inno Setup Setup Data (5.3.3) (u)", INNO_VERSION_EXT(5, 3, 3, 0), true },
{ "Inno Setup Setup Data (5.3.5)", INNO_VERSION_EXT(5, 3, 5, 0), false },
{ "Inno Setup Setup Data (5.3.5) (u)", INNO_VERSION_EXT(5, 3, 5, 0), true },
{ "Inno Setup Setup Data (5.3.6)", INNO_VERSION_EXT(5, 3, 6, 0), false },
{ "Inno Setup Setup Data (5.3.6) (u)", INNO_VERSION_EXT(5, 3, 6, 0), true },
{ "Inno Setup Setup Data (5.3.7)", INNO_VERSION_EXT(5, 3, 7, 0), false },
{ "Inno Setup Setup Data (5.3.7) (u)", INNO_VERSION_EXT(5, 3, 7, 0), true },
{ "Inno Setup Setup Data (5.3.8)", INNO_VERSION_EXT(5, 3, 8, 0), false },
{ "Inno Setup Setup Data (5.3.8) (u)", INNO_VERSION_EXT(5, 3, 8, 0), true },
{ "Inno Setup Setup Data (5.3.9)", INNO_VERSION_EXT(5, 3, 9, 0), false },
{ "Inno Setup Setup Data (5.3.9) (u)", INNO_VERSION_EXT(5, 3, 9, 0), true },
{ "Inno Setup Setup Data (5.3.10)", INNO_VERSION_EXT(5, 3, 10, 0), false },
{ "Inno Setup Setup Data (5.3.10) (u)", INNO_VERSION_EXT(5, 3, 10, 0), true },
{ "Inno Setup Setup Data (5.4.2)", INNO_VERSION_EXT(5, 4, 2, 0), false },
{ "Inno Setup Setup Data (5.4.2) (u)", INNO_VERSION_EXT(5, 4, 2, 0), true },
};
using std::cout;
using std::string;
@ -140,7 +140,8 @@ void InnoVersion::load(std::istream & is) {
if(legacyVersion[0] == 'i' && legacyVersion[sizeof(legacyVersion) - 1] == '\x1a') {
cout << "found legacy version: \"" << safestring(legacyVersion, sizeof(legacyVersion) - 1) << '"' << endl;
cout << "found legacy version: \""
<< safestring(legacyVersion, sizeof(legacyVersion) - 1) << '"' << endl;
for(size_t i = 0; i < ARRAY_SIZE(knownLegacySetupDataVersions); i++) {
if(!memcmp(legacyVersion, knownLegacySetupDataVersions[i].name, sizeof(legacyVersion))) {

44
src/setup/Version.hpp

@ -15,24 +15,28 @@ struct InnoVersion {
InnoVersionConstant version;
char bits; // 16 or 32
uint8_t bits; // 16 or 32
bool unicode;
bool known;
inline InnoVersion() : known(false) { };
inline InnoVersion() : known(false) { }
inline InnoVersion(InnoVersionConstant _version, bool _unicode = false, bool _known = false, char _bits = 32) : version(_version), unicode(_unicode), known(_known), bits(_bits) { };
inline InnoVersion(InnoVersionConstant _version, bool _unicode = false,
bool _known = false, uint8_t _bits = 32)
: version(_version), bits(_bits), unicode(_unicode), known(_known) { }
inline InnoVersion(char a, char b, char c, char d = 0, bool _unicode = false, bool _known = false, char _bits = 32) : version(INNO_VERSION_EXT(a, b, c, d)), unicode(_unicode), known(_known), bits(_bits) { };
inline InnoVersion(uint8_t a, uint8_t b, uint8_t c, uint8_t d = 0, bool _unicode = false,
bool _known = false, uint8_t _bits = 32)
: version(INNO_VERSION_EXT(a, b, c, d)), bits(_bits), unicode(_unicode), known(_known) { }
inline int a() const { return version >> 24; }
inline int b() const { return (version >> 16) & 0xff; }
inline int c() const { return (version >> 8) & 0xff; }
inline int d() const { return version & 0xff; }
inline unsigned int a() const { return version >> 24; }
inline unsigned int b() const { return (version >> 16) & 0xff; }
inline unsigned int c() const { return (version >> 8) & 0xff; }
inline unsigned int d() const { return version & 0xff; }
void load(std::istream & is);
@ -44,12 +48,24 @@ struct InnoVersion {
};
inline bool operator==(const InnoVersion & a, const InnoVersion & b) { return a.version == b.version; }
inline bool operator!=(const InnoVersion & a, const InnoVersion & b) { return !operator==(a, b); }
inline bool operator< (const InnoVersion & a, const InnoVersion & b) { return a.version < b.version; }
inline bool operator> (const InnoVersion & a, const InnoVersion & b) { return operator< (b, a); }
inline bool operator<=(const InnoVersion & a, const InnoVersion & b) { return !operator> (a, b); }
inline bool operator>=(const InnoVersion & a, const InnoVersion & b) { return !operator< (a, b); }
inline bool operator==(const InnoVersion & a, const InnoVersion & b) {
return a.version == b.version;
}
inline bool operator!=(const InnoVersion & a, const InnoVersion & b) {
return !operator==(a, b);
}
inline bool operator< (const InnoVersion & a, const InnoVersion & b) {
return a.version < b.version;
}
inline bool operator> (const InnoVersion & a, const InnoVersion & b) {
return operator< (b, a);
}
inline bool operator<=(const InnoVersion & a, const InnoVersion & b) {
return !operator> (a, b);
}
inline bool operator>=(const InnoVersion & a, const InnoVersion & b) {
return !operator< (a, b);
}
inline bool operator==(const InnoVersion & a, InnoVersionConstant b) { return a.version == b; }
inline bool operator!=(const InnoVersion & a, InnoVersionConstant b) { return !operator==(a, b); }

9
src/setup/WindowsVersion.cpp

@ -94,6 +94,7 @@ std::ostream & operator<<(std::ostream & os, const WindowsVersion::Version & v)
if(v.build) {
os << v.build;
}
return os;
}
std::ostream & operator<<(std::ostream & os, const WindowsVersion & v) {
@ -117,10 +118,10 @@ std::ostream & operator<<(std::ostream & os, const WindowsVersion & v) {
os << ')';
}
if(v.ntServicePack.major || v.ntServicePack.minor) {
os << " service pack " << v.ntServicePack.major;
if(v.ntServicePack.minor) {
os << '.' << v.ntServicePack.minor;
}
os << " service pack " << v.ntServicePack.major;
if(v.ntServicePack.minor) {
os << '.' << v.ntServicePack.minor;
}
}
return os;
}

2
src/setup/WindowsVersion.hpp

@ -57,7 +57,7 @@ struct WindowsVersion {
return !(*this == o);
}
const static WindowsVersion none;
static const WindowsVersion none;
};

8
src/stream/BlockFilter.hpp

@ -52,13 +52,13 @@ public:
std::streamsize nread = boost::iostreams::read(src, temp, sizeof(temp));
if(nread == EOF) {
return false;
} else if(nread != sizeof(temp)) {
} else if(nread != sizeof(temp)) {
throw block_error("unexpected block end");
}
std::memcpy(&blockCrc32, temp, sizeof(blockCrc32));
blockCrc32 = LittleEndian::byteSwapIfAlien(blockCrc32);
length = boost::iostreams::read(src, buffer, sizeof(buffer));
length = size_t(boost::iostreams::read(src, buffer, sizeof(buffer)));
if(length == size_t(EOF)) {
throw block_error("unexpected block end");
}
@ -78,7 +78,7 @@ public:
template<typename Source>
std::streamsize read(Source & src, char * dest, std::streamsize n) {
size_t read = 0;
std::streamsize read = 0;
while(n) {
if(pos == length && !read_chunk(src)) {
@ -89,7 +89,7 @@ public:
std::copy(buffer + pos, buffer + pos + size, dest + read);
pos += size, n -= size, read += size;
pos += size_t(size), n -= size, read += size;
}
return read;

4
src/stream/BlockReader.cpp

@ -41,7 +41,7 @@ std::istream * BlockReader::get(std::istream & base, const InnoVersion & version
Crc32 actualCrc;
actualCrc.init();
uint64_t storedSize;
uint32_t storedSize;
BlockCompression compression;
if(version >= INNO_VERSION(4, 0, 9)) {
@ -61,7 +61,7 @@ std::istream * BlockReader::get(std::istream & base, const InnoVersion & version
}
// Add the size of a CRC32 checksum for each 4KiB subblock.
storedSize += ceildiv(storedSize, 4096) * 4;
storedSize += uint32_t(ceildiv<uint64_t>(storedSize, 4096) * 4);
}
if(actualCrc.finalize() != expectedCrc) {

2
src/stream/ChecksumFilter.hpp

@ -29,7 +29,7 @@ public:
std::streamsize nread = boost::iostreams::read(src, dest, n);
if(nread != EOF) {
hasher->update(dest, nread);
hasher->update(dest, size_t(nread));
}
return nread;

2
src/stream/ChunkReader.cpp

@ -5,7 +5,7 @@
const char chunkId[4] = { 'z', 'l', 'b', 0x1a };
ChunkReader::Chunk::Chunk(size_t _firstSlice, size_t _chunkOffset, uint64_t _chunkSize,
ChunkReader::Chunk::Chunk(size_t _firstSlice, uint32_t _chunkOffset, uint64_t _chunkSize,
bool _compressed, bool _encrypted)
: firstSlice(_firstSlice), chunkOffset(_chunkOffset), chunkSize(_chunkSize),
compressed(_compressed), encrypted(_encrypted) { }

7
src/stream/ChunkReader.hpp

@ -21,19 +21,20 @@ public:
struct Chunk {
size_t firstSlice; //!< Slice where the chunk starts.
size_t chunkOffset; //!< Offset of the compressed chunk in firstSlice.
uint32_t chunkOffset; //!< Offset of the compressed chunk in firstSlice.
uint64_t chunkSize; //! Total compressed size of the chunk.
bool compressed;
bool encrypted;
Chunk(size_t firstSlice, size_t chunkOffset, uint64_t chunkSize, bool compressed, bool encrypted);
Chunk(size_t firstSlice, uint32_t chunkOffset, uint64_t chunkSize,
bool compressed, bool encrypted);
bool operator<(const Chunk & o) const;
bool operator==(const Chunk & o) const;
};
ChunkReader(uint64_t _storedSize) : storedSize(_storedSize) { }
explicit ChunkReader(uint64_t _storedSize) : storedSize(_storedSize) { }
uint64_t chunkDecompressedBytesRead;
uint64_t chunkCompressedBytesLeft;

23
src/stream/InstructionFilter.hpp

@ -92,7 +92,7 @@ private:
template<typename Source>
std::streamsize call_instruction_decoder_4108::read(Source & src, char * dest, std::streamsize n) {
for(size_t i = 0; i < n; i++, addr_offset++) {
for(std::streamsize i = 0; i < n; i++, addr_offset++) {
int byte = boost::iostreams::get(src);
if(byte == EOF) { return i ? i : EOF; }
@ -107,13 +107,13 @@ std::streamsize call_instruction_decoder_4108::read(Source & src, char * dest, s
}
} else {
addr += byte;
byte = addr;
addr += uint8_t(byte);
byte = uint8_t(addr);
addr >>= 8;
addr_bytes_left--;
}
*dest++ = uint8_t(byte);
*dest++ = char(uint8_t(byte));
}
return n;
@ -127,16 +127,17 @@ std::streamsize call_instruction_decoder_5200::read(Source & src, char * dest, s
//! Total number of filtered bytes read and written to dest.
#define total_read (n - (end - dest))
#define flush(N) { \
#define flush(N) \
{ \
if((N) > 0) { \
flush_bytes = (N); \
size_t buffer_i = 0; \
do { \
if(dest == end) { \
memmove(buffer, buffer + buffer_i, flush_bytes); \
memmove(buffer, buffer + buffer_i, size_t(flush_bytes)); \
return total_read; \
} \
*dest++ = buffer[buffer_i++]; \
*dest++ = char(buffer[buffer_i++]); \
} while(--flush_bytes); \
} \
} (void)0
@ -153,7 +154,7 @@ std::streamsize call_instruction_decoder_5200::read(Source & src, char * dest, s
int byte = boost::iostreams::get(src);
if(byte == EOF) { return total_read ? total_read : EOF; }
if(byte == boost::iostreams::WOULD_BLOCK) { return total_read; }
*dest++ = byte;
*dest++ = char(byte);
offset++;
if(byte != 0xe8 && byte != 0xe9) {
// Not a CALL or JMP instruction.
@ -175,10 +176,10 @@ std::streamsize call_instruction_decoder_5200::read(Source & src, char * dest, s
char * dst = reinterpret_cast<char *>(buffer + 4 + flush_bytes);
std::streamsize nread = boost::iostreams::read(src, dst, -flush_bytes);
if(nread == EOF) {
flush(4 + flush_bytes);
flush(int8_t(4 + flush_bytes));
return total_read ? total_read : EOF;
}
flush_bytes += nread, offset += nread;
flush_bytes = int8_t(flush_bytes + nread), offset += uint32_t(nread);
if(flush_bytes) { return total_read; }
// Verify that the high byte of the address is 0x00 or 00xff.
@ -196,7 +197,7 @@ std::streamsize call_instruction_decoder_5200::read(Source & src, char * dest, s
// of the original relative address is likely to be the sign extension
// of bit 23, so if bit 23 is set, toggle all bits in the high byte.
if(rel & 0x800000) {
buffer[3] = ~buffer[3];
buffer[3] = uint8_t(~buffer[3]);
}
}

14
src/stream/LzmaFilter.cpp

@ -18,7 +18,7 @@ static lzma_stream * init_raw_lzma_stream(lzma_vli filter, lzma_options_lzma & o
*strm = tmp;
strm->allocator = NULL;
const lzma_filter filters[2] = { { filter, &options }, { LZMA_VLI_UNKNOWN } };
const lzma_filter filters[2] = { { filter, &options }, { LZMA_VLI_UNKNOWN, NULL } };
lzma_ret ret = lzma_raw_decoder(strm, filters);
if(ret != LZMA_OK) {
delete strm;
@ -35,14 +35,14 @@ bool lzma_decompressor_impl_base::filter(const char * & begin_in, const char * e
lzma_stream * strm = static_cast<lzma_stream *>(stream);
strm->next_in = reinterpret_cast<const uint8_t *>(begin_in);
strm->avail_in = end_in - begin_in;
strm->avail_in = size_t(end_in - begin_in);
strm->next_out = reinterpret_cast<uint8_t *>(begin_out);
strm->avail_out = end_out - begin_out;
strm->avail_out = size_t(end_out - begin_out);
lzma_ret ret = lzma_code(strm, LZMA_RUN);
begin_in = reinterpret_cast<const char *>(strm->next_in);
begin_in = reinterpret_cast<const char *>(strm->next_in);
begin_out = reinterpret_cast<char *>(strm->next_out);
if(ret != LZMA_OK && ret != LZMA_STREAM_END && ret != LZMA_BUF_ERROR) {
@ -77,7 +77,7 @@ bool inno_lzma1_decompressor_impl::filter(const char * & begin_in, const char *
lzma_options_lzma options;
uint8_t properties = header[0];
uint8_t properties = uint8_t(header[0]);
if(properties > (9 * 5 * 5)) {
throw lzma_error("inno lzma1 property error", LZMA_FORMAT_ERROR);
}
@ -94,7 +94,7 @@ bool inno_lzma1_decompressor_impl::filter(const char * & begin_in, const char *
}
return lzma_decompressor_impl_base::filter(begin_in, end_in, begin_out, end_out, flush);
}
}
bool inno_lzma2_decompressor_impl::filter(const char * & begin_in, const char * end_in,
char * & begin_out, char * end_out, bool flush) {
@ -108,7 +108,7 @@ bool inno_lzma2_decompressor_impl::filter(const char * & begin_in, const char *
lzma_options_lzma options;
uint8_t prop = *begin_in++;
uint8_t prop = uint8_t(*begin_in++);
if(prop > 40) {
throw lzma_error("inno lzma2 property error", LZMA_FORMAT_ERROR);
}

2
src/stream/LzmaFilter.hpp

@ -49,7 +49,7 @@ public:
bool filter(const char * & begin_in, const char * end_in,
char * & begin_out, char * end_out, bool flush);
inline void close() { lzma_decompressor_impl_base::close(); nread = 0; }
inline void close() { lzma_decompressor_impl_base::close(), nread = 0; }
private:

29
src/stream/SliceReader.cpp

@ -4,6 +4,7 @@
#include <stdint.h>
#include <sstream>
#include <cstring>
#include <limits>
#include "util/LoadingUtils.hpp"
#include "util/Output.hpp"
@ -20,20 +21,20 @@ const char sliceIds[][8] = {
} // anonymous namespace
SliceReader::SliceReader(const string & setupFile, size_t _dataOffset)
SliceReader::SliceReader(const string & setupFile, uint32_t _dataOffset)
: dir(), lastDir(), baseFile(), dataOffset(_dataOffset), slicesPerDisk(1),
currentSlice(0) {
ifs.open(setupFile.c_str(), std::ios_base::binary | std::ios_base::in | std::ios_base::ate);
sliceSize = ifs.tellg();
if(sliceSize < dataOffset) {
sliceSize = uint32_t(std::min<std::streampos>(ifs.tellg(), std::numeric_limits<int32_t>::max()));
if(ifs.seekg(dataOffset).fail()) {
ifs.close();
} else {
ifs.seekg(dataOffset);
}
}
SliceReader::SliceReader(const std::string & _dir, const std::string & _baseFile, size_t _slicesPerDisk)
SliceReader::SliceReader(const std::string & _dir, const std::string & _baseFile,
size_t _slicesPerDisk)
: dir(_dir), lastDir(_dir), baseFile(_baseFile), dataOffset(0), slicesPerDisk(_slicesPerDisk),
currentSlice(0) { }
@ -55,14 +56,14 @@ bool SliceReader::openFile(const std::string & file) {
std::cout << color::cyan << "\33[2K\r[slice] opening " << file << color::reset << std::endl;
ifs.close();;
ifs.close();
ifs.open(file.c_str(), std::ios_base::in | std::ios_base::binary | std::ios_base::ate);
if(ifs.fail()) {
return false;
}
size_t fileSize = ifs.tellg();
std::streampos fileSize = ifs.tellg();
ifs.seekg(0);
char magic[8];
@ -85,7 +86,7 @@ bool SliceReader::openFile(const std::string & file) {
}
sliceSize = loadNumber<uint32_t>(ifs);
if(ifs.fail() || sliceSize > fileSize) {
if(ifs.fail() || std::streampos(sliceSize) > fileSize) {
LogError << "[slice] bad slice size: " << sliceSize << " > " << fileSize;
ifs.close();
return false;
@ -146,7 +147,7 @@ bool SliceReader::open(size_t slice, const std::string & file) {
return false;
}
bool SliceReader::seek(size_t slice, size_t offset) {
bool SliceReader::seek(size_t slice, uint32_t offset) {
if(!seek(slice)) {
return false;
@ -165,9 +166,7 @@ bool SliceReader::seek(size_t slice, size_t offset) {
std::streamsize SliceReader::read(char * buffer, std::streamsize bytes) {
size_t nread = 0;
std::streamsize requested = bytes;
std::streamsize nread = 0;
if(!seek(currentSlice)) {
return nread;
@ -175,12 +174,12 @@ std::streamsize SliceReader::read(char * buffer, std::streamsize bytes) {
while(bytes > 0) {
std::streamsize remaining = sliceSize - ifs.tellg();
std::streamsize remaining = std::streamsize(sliceSize - size_t(ifs.tellg()));
if(!remaining) {
if(!seek(currentSlice + 1)) {
return nread;
}
remaining = sliceSize - ifs.tellg();
remaining = std::streamsize(sliceSize - size_t(ifs.tellg()));
}
std::streamsize read = ifs.read(buffer, std::min(remaining, bytes)).gcount();

8
src/stream/SliceReader.hpp

@ -11,12 +11,12 @@ class SliceReader : public boost::iostreams::source {
std::string dir;
std::string lastDir;
std::string baseFile;
const size_t dataOffset;
const uint32_t dataOffset;
const size_t slicesPerDisk;
size_t currentSlice;
std::string sliceFile;
size_t sliceSize;
uint32_t sliceSize;
std::ifstream ifs;
@ -25,7 +25,7 @@ class SliceReader : public boost::iostreams::source {
public:
SliceReader(const std::string & setupFile, size_t dataOffset);
SliceReader(const std::string & setupFile, uint32_t dataOffset);
/*!
* if Ver>=4107 then baseFile := PathChangeExt(PathExtractName(SetupLdrOriginalFilename), '')
@ -33,7 +33,7 @@ public:
*/
SliceReader(const std::string & dir, const std::string & baseFile, size_t slicesPerDisk);
bool seek(size_t slice, size_t offset);
bool seek(size_t slice, uint32_t offset);
std::streamsize read(char * buffer, std::streamsize bytes);

16
src/util/Endian.hpp

@ -9,25 +9,25 @@ inline uint8_t byteSwap(uint8_t value) {
}
inline int8_t byteSwap(int8_t value) {
return byteSwap(uint8_t(value));
return int8_t(byteSwap(uint8_t(value)));
}
inline uint16_t byteSwap(uint16_t value) {
#if defined(_MSC_VER) && _MSC_VER >= 1300
return _byteswap_ushort(value);
#else
return (uint16_t(uint8_t(value)) << 8) | uint8_t(value >> 8);
return uint16_t((uint16_t(uint8_t(value)) << 8) | uint8_t(value >> 8));
#endif
}
inline int16_t byteSwap(int16_t value) {
return byteSwap(uint16_t(value));
return int16_t(byteSwap(uint16_t(value)));
}
inline uint32_t byteSwap(uint32_t value) {
#if defined(__GNUC__)
return __builtin_bswap32(value);
#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
#elif defined(_MSC_VER) && (_MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL)))
return _byteswap_ulong(value);
#else
return (uint32_t(byteSwap(uint16_t(value))) << 16) | byteSwap(uint16_t(value >> 16));
@ -35,7 +35,7 @@ inline uint32_t byteSwap(uint32_t value) {
}
inline int32_t byteSwap(int32_t value) {
return byteSwap(uint32_t(value));
return int32_t(byteSwap(uint32_t(value)));
}
inline uint64_t byteSwap(uint64_t value) {
@ -49,7 +49,7 @@ inline uint64_t byteSwap(uint64_t value) {
}
inline int64_t byteSwap(int64_t value) {
return byteSwap(uint64_t(value));
return int64_t(byteSwap(uint64_t(value)));
}
template <class T>
@ -103,9 +103,9 @@ struct BigEndian : public Endianness<BOOST_BYTE_ORDER == 4321> {
};
#ifdef BOOST_LITTLE_ENDIAN
#if defined(BOOST_LITTLE_ENDIAN)
typedef LittleEndian NativeEndian;
#elif BOOLST_BIG_ENDIAN
#elif defined(BOOST_BIG_ENDIAN)
typedef BigEndian NativeEndian;
#else
#error "Unsupported host endianness."

3
src/util/Enum.hpp

@ -31,7 +31,8 @@ struct EnumNames {
#define ENUM_NAMES(Enum, Name, ...) \
const char * EnumNames<GetEnum<Enum>::type>::name = (Name); \
const char * EnumNames<GetEnum<Enum>::type>::names[] = { __VA_ARGS__ }; \
const size_t EnumNames<GetEnum<Enum>::type>::count = ARRAY_SIZE(EnumNames<GetEnum<Enum>::type>::names); \
const size_t EnumNames<GetEnum<Enum>::type>::count = \
ARRAY_SIZE(EnumNames<GetEnum<Enum>::type>::names); \
std::ostream & operator<<(std::ostream & os, GetEnum<Enum>::type value) { \
if(value < EnumNames<GetEnum<Enum>::type>::count) { \
return os << EnumNames<GetEnum<Enum>::type>::names[value]; \

4
src/util/Flags.hpp

@ -10,7 +10,9 @@
// loosely based on QFlags from Qt
template <typename Enum>
struct EnumSize { private: static const size_t value = 42; };
struct EnumSize {
static const size_t value;
};
/*!
* A typesafe way to define flags as a combination of enum values.

6
src/util/LoadingUtils.cpp

@ -37,12 +37,12 @@ iconv_t getConverter(uint32_t codepage) {
void BinaryString::loadInto(std::istream & is, std::string & target) {
size_t length = loadNumber<uint32_t>(is);
if(is.fail()) {
int32_t length = loadNumber<int32_t>(is);
if(is.fail() || length < 0) {
return;
}
target.resize(length);
target.resize(size_t(length));
is.read(&target[0], length);
}

44
src/util/LoadingUtils.hpp

@ -7,6 +7,10 @@
#include <iostream>
#include <string>
#include <limits>
#include <boost/integer/static_min_max.hpp>
#include <boost/integer.hpp>
#include "util/Endian.hpp"
struct BinaryString {
@ -30,7 +34,8 @@ struct EncodedString {
std::string & data;
uint32_t codepage;
inline EncodedString(std::string & target, uint32_t _codepage) : data(target), codepage(_codepage) { }
inline EncodedString(std::string & target, uint32_t _codepage)
: data(target), codepage(_codepage) { }
static void loadInto(std::istream & is, std::string & target, uint32_t codepage);
@ -61,24 +66,25 @@ inline T loadNumber(std::istream & is) {
return LittleEndian::byteSwapIfAlien(load<T>(is));
}
template <class Base, size_t Bits, bool Signed = std::numeric_limits<Base>::is_signed>
struct compatible_integer { typedef void type; };
template <class Base>
struct compatible_integer<Base, 8, false> { typedef uint8_t type; };
template <class Base>
struct compatible_integer<Base, 8, true> { typedef int8_t type; };
template <class Base>
struct compatible_integer<Base, 16, false> { typedef uint16_t type; };
template <class Base>
struct compatible_integer<Base, 16, true> { typedef int16_t type; };
template <class Base>
struct compatible_integer<Base, 32, false> { typedef uint32_t type; };
template <class Base>
struct compatible_integer<Base, 32, true> { typedef int32_t type; };
template <class Base>
struct compatible_integer<Base, 64, false> { typedef uint64_t type; };
template <class Base>
struct compatible_integer<Base, 64, true> { typedef int64_t type; };
template <class Base, size_t Bits,
bool Signed = std::numeric_limits<Base>::is_signed>
struct compatible_integer {
typedef void type;
};
template <class Base, size_t Bits>
struct compatible_integer<Base, Bits, false> {
typedef typename boost::uint_t<
boost::static_unsigned_min<Bits, sizeof(Base) * 8>::value
>::exact type;
};
template <class Base, size_t Bits>
struct compatible_integer<Base, Bits, true> {
typedef typename boost::int_t<
boost::static_unsigned_min<Bits, sizeof(Base) * 8>::value
>::exact type;
};
template <class T>
T loadNumber(std::istream & is, size_t bits) {

16
src/util/StoredEnum.hpp

@ -98,14 +98,19 @@ public:
inline std::bitset<size> getBitSet() const {
static const size_t ulong_size = sizeof(unsigned long) * 8;
// Make `make style` shut up since we really need unsigned long here.
#define stored_enum_concat_(a, b, c, d) a##b c##d
typedef stored_enum_concat_(unsi, gned, lo, ng) ulong_type;
#undef stored_enum_concat_
static const size_t ulong_size = sizeof(ulong_type) * 8;
BOOST_STATIC_ASSERT(base_size % ulong_size == 0 || base_size < ulong_size);
std::bitset<size> result(0);
for(size_t i = 0; i < count; i++) {
for(size_t j = 0; j < ceildiv(base_size, ulong_size); j++) {
result |= std::bitset<size>(static_cast<unsigned long>(bits[i] >> (j * ulong_size)))
result |= std::bitset<size>(static_cast<ulong_type>(bits[i] >> (j * ulong_size)))
<< ((i * base_size) + (j * ulong_size));
}
}
@ -138,7 +143,8 @@ public:
}
if(bits) {
LogWarning << "unexpected " << EnumNames<enum_type>::name << " flags: " << std::hex << bits << std::dec;
LogWarning << "unexpected " << EnumNames<enum_type>::name << " flags: "
<< std::hex << bits << std::dec;
}
return result;
@ -166,7 +172,7 @@ public:
size_t bits;
StoredFlagReader(std::istream & _is) : is(_is), pos(0), result(0), bits(0) { };
explicit StoredFlagReader(std::istream & _is) : is(_is), pos(0), result(0), bits(0) { }
void add(enum_type flag) {
@ -195,7 +201,7 @@ class StoredFlagReader<Flags<Enum> > : public StoredFlagReader<Enum> {
public:
StoredFlagReader(std::istream & is) : StoredFlagReader<Enum>(is) { };
explicit StoredFlagReader(std::istream & is) : StoredFlagReader<Enum>(is) { }
};

46
src/util/Utils.hpp

@ -2,6 +2,7 @@
#ifndef INNOEXTRACT_UTIL_UTILS_HPP
#define INNOEXTRACT_UTIL_UTILS_HPP
#include <stdint.h>
#include <iostream>
#include <string>
@ -23,9 +24,10 @@ struct Quoted {
const std::string & str;
Quoted(const std::string & _str) : str(_str) { }
explicit Quoted(const std::string & _str) : str(_str) { }
};
inline std::ostream & operator<<(std::ostream & os, const Quoted & q) {
color::shell_command prev = color::current;
os << '"' << color::green;
@ -33,7 +35,8 @@ inline std::ostream & operator<<(std::ostream & os, const Quoted & q) {
unsigned char c = (unsigned char)*i;
if(c < ' ' && c != '\t' && c != '\r' && c != '\n') {
std::ios_base::fmtflags old = os.flags();
os << color::red << '<' << std::hex << std::setfill('0') << std::setw(2) << int(c) << '>' << color::green;
os << color::red << '<' << std::hex << std::setfill('0') << std::setw(2)
<< int(c) << '>' << color::green;
os.setf(old, std::ios_base::basefield);
} else {
os << *i;
@ -47,13 +50,16 @@ struct IfNotEmpty {
const std::string & name;
const std::string & value;
IfNotEmpty(const std::string & _name, const std::string & _value) : name(_name), value(_value) { }
IfNotEmpty(const std::string & _name, const std::string & _value)
: name(_name), value(_value) { }
};
inline std::ostream & operator<<(std::ostream & os, const IfNotEmpty & s) {
if(s.value.length() > 100) {
color::shell_command prev = color::current;
return os << s.name << ": " << color::white << s.value.length() << prev << " bytes" << std::endl;
return os << s.name << ": " << color::white << s.value.length() << prev
<< " bytes" << std::endl;
} else if(!s.value.empty()) {
return os << s.name << ": " << Quoted(s.value) << std::endl;
} else {
@ -68,9 +74,11 @@ struct _IfNot {
const T value;
const T excluded;
_IfNot(const std::string & _name, T _value, T _excluded) : name(_name), value(_value), excluded(_excluded) { }
_IfNot(const std::string & _name, T _value, T _excluded)
: name(_name), value(_value), excluded(_excluded) { }
};
template <class T>
inline std::ostream & operator<<(std::ostream & os, const _IfNot<T> & s) {
if(s.value != s.excluded) {
@ -80,18 +88,20 @@ inline std::ostream & operator<<(std::ostream & os, const _IfNot<T> & s) {
return os;
}
}
template <class T>
_IfNot<T> IfNot(const std::string & name, T value, T excluded) {
return _IfNot<T>(name, value, excluded);
}
template <class T>
_IfNot<T> IfNotZero(const std::string & name, T value) {
return _IfNot<T>(name, value, T(0));
}
template <class A, class B>
inline A ceildiv(A num, B denom) {
return A((num + (denom - 1)) / denom);
template <typename T>
inline T ceildiv(T num, T denom) {
return (num + (denom - T(1))) / denom;
}
template <class T>
@ -99,12 +109,13 @@ struct _PrintHex {
T value;
_PrintHex(T data) : value(data) { }
explicit _PrintHex(T data) : value(data) { }
bool operator==(const _PrintHex & o) const { return value == o.value; }
bool operator!=(const _PrintHex & o) const { return value != o.value; }
};
template <class T>
inline std::ostream & operator<<(std::ostream & os, const _PrintHex<T> & s) {
@ -115,6 +126,7 @@ inline std::ostream & operator<<(std::ostream & os, const _PrintHex<T> & s) {
os.setf(old, std::ios_base::basefield);
return os;
}
template <class T>
_PrintHex<T> PrintHex(T value) {
return _PrintHex<T>(value);
@ -133,36 +145,38 @@ struct _PrintBytes {
T value;
_PrintBytes(T data) : value(data) { }
explicit _PrintBytes(T data) : value(data) { }
bool operator==(const _PrintBytes & o) const { return value == o.value; }
bool operator!=(const _PrintBytes & o) const { return value != o.value; }
};
template <class T>
inline std::ostream & operator<<(std::ostream & os, const _PrintBytes<T> & s) {
int precision = os.precision();
std::streamsize precision = os.precision();
size_t frac = 0;
size_t whole = s.value;
size_t frac = size_t(1024 * (s.value - T(uint64_t(s.value))));
uint64_t whole = uint64_t(s.value);
size_t i = 0;
while((whole & ~0x3ff) && i < ARRAY_SIZE(byteSizeUnits) - 1) {
while(whole > 1024 && i < ARRAY_SIZE(byteSizeUnits) - 1) {
frac = (whole & 0x3ff), whole >>= 10;
frac = whole % 1024, whole /= 1024;
i++;
}
float num = whole + (frac / 1024.f);
float num = float(whole) + (float(frac) / 1024.f);
os << std::setprecision(3) << num << ' ' << byteSizeUnits[i];
os.precision(precision);
return os;
}
template <class T>
_PrintBytes<T> PrintBytes(T value) {
return _PrintBytes<T>(value);

Loading…
Cancel
Save